diff --git a/[refs] b/[refs] index eb3174283d07..e0e7ce1904e0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7100e505b76b4e2efd88b2459d1a932214e29f8a +refs/heads/master: 24214449b00b94328e239d3c35cda3e6fe0f931b diff --git a/trunk/.mailmap b/trunk/.mailmap index 658003aa9446..2909c33bc54e 100644 --- a/trunk/.mailmap +++ b/trunk/.mailmap @@ -111,7 +111,6 @@ Uwe Kleine-König Uwe Kleine-König Uwe Kleine-König Valdis Kletnieks -Viresh Kumar Takashi YOSHII Yusuke Goda Gustavo Padovan diff --git a/trunk/Documentation/ABI/testing/sysfs-block-rssd b/trunk/Documentation/ABI/testing/sysfs-block-rssd index beef30c046b0..679ce3543122 100644 --- a/trunk/Documentation/ABI/testing/sysfs-block-rssd +++ b/trunk/Documentation/ABI/testing/sysfs-block-rssd @@ -1,5 +1,26 @@ +What: /sys/block/rssd*/registers +Date: March 2012 +KernelVersion: 3.3 +Contact: Asai Thambi S P +Description: This is a read-only file. Dumps below driver information and + hardware registers. + - S ACTive + - Command Issue + - Completed + - PORT IRQ STAT + - HOST IRQ STAT + - Allocated + - Commands in Q + What: /sys/block/rssd*/status Date: April 2012 KernelVersion: 3.4 Contact: Asai Thambi S P Description: This is a read-only file. Indicates the status of the device. + +What: /sys/block/rssd*/flags +Date: May 2012 +KernelVersion: 3.5 +Contact: Asai Thambi S P +Description: This is a read-only file. Dumps the flags in port and driver + data structure diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-iio b/trunk/Documentation/ABI/testing/sysfs-bus-iio index cfedf63cce15..5bc8a476c15e 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-iio +++ b/trunk/Documentation/ABI/testing/sysfs-bus-iio @@ -219,7 +219,6 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale @@ -274,7 +273,6 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available What: /sys/.../iio:deviceX/in_voltageX_scale_available What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available -What: /sys/.../iio:deviceX/out_altvoltageX_scale_available What: /sys/.../iio:deviceX/in_capacitance_scale_available KernelVersion: 2.635 Contact: linux-iio@vger.kernel.org @@ -300,19 +298,14 @@ Description: gives the 3dB frequency of the filter in Hz. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled, no bias etc.) output voltage for channel Y. The number must always be specified and unique if the output corresponds to a single channel. - While DAC like devices typically use out_voltage, - a continuous frequency generating device, such as - a DDS or PLL should use out_altvoltage. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY&Z_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -323,8 +316,6 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -339,8 +330,6 @@ Description: What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available -What: /sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available -What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -349,8 +338,6 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -359,24 +346,6 @@ Description: normal operation. Y may be suppressed if all outputs are controlled together. -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency -KernelVersion: 3.4.0 -Contact: linux-iio@vger.kernel.org -Description: - Output frequency for channel Y in Hz. The number must always be - specified and unique if the output corresponds to a single - channel. - -What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase -KernelVersion: 3.4.0 -Contact: linux-iio@vger.kernel.org -Description: - Phase in radians of one frequency/clock output Y - (out_altvoltageY) relative to another frequency/clock output - (out_altvoltageZ) of the device X. The number must always be - specified and unique if the output corresponds to a single - channel. - What: /sys/bus/iio/devices/iio:deviceX/events KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org diff --git a/trunk/Documentation/ABI/testing/sysfs-class-mtd b/trunk/Documentation/ABI/testing/sysfs-class-mtd index 938ef71e2035..db1ad7e34fc3 100644 --- a/trunk/Documentation/ABI/testing/sysfs-class-mtd +++ b/trunk/Documentation/ABI/testing/sysfs-class-mtd @@ -142,14 +142,13 @@ KernelVersion: 3.4 Contact: linux-mtd@lists.infradead.org Description: This allows the user to examine and adjust the criteria by which - mtd returns -EUCLEAN from mtd_read() and mtd_read_oob(). If the - maximum number of bit errors that were corrected on any single - region comprising an ecc step (as reported by the driver) equals - or exceeds this value, -EUCLEAN is returned. Otherwise, absent - an error, 0 is returned. Higher layers (e.g., UBI) use this - return code as an indication that an erase block may be - degrading and should be scrutinized as a candidate for being - marked as bad. + mtd returns -EUCLEAN from mtd_read(). If the maximum number of + bit errors that were corrected on any single region comprising + an ecc step (as reported by the driver) equals or exceeds this + value, -EUCLEAN is returned. Otherwise, absent an error, 0 is + returned. Higher layers (e.g., UBI) use this return code as an + indication that an erase block may be degrading and should be + scrutinized as a candidate for being marked as bad. The initial value may be specified by the flash device driver. If not, then the default value is ecc_strength. @@ -168,7 +167,7 @@ Description: block degradation, but high enough to avoid the consequences of a persistent return value of -EUCLEAN on devices where sticky bitflips occur. Note that if bitflip_threshold exceeds - ecc_strength, -EUCLEAN is never returned by the read operations. + ecc_strength, -EUCLEAN is never returned by mtd_read(). Conversely, if bitflip_threshold is zero, -EUCLEAN is always returned, absent a hard error. diff --git a/trunk/Documentation/ABI/testing/sysfs-power b/trunk/Documentation/ABI/testing/sysfs-power index 217772615d02..31725ffeeb3a 100644 --- a/trunk/Documentation/ABI/testing/sysfs-power +++ b/trunk/Documentation/ABI/testing/sysfs-power @@ -231,16 +231,3 @@ Description: Reads from this file return a string consisting of the names of wakeup sources created with the help of /sys/power/wake_lock that are inactive at the moment, separated with spaces. - -What: /sys/power/pm_print_times -Date: May 2012 -Contact: Sameer Nanda -Description: - The /sys/power/pm_print_times file allows user space to - control whether the time taken by devices to suspend and - resume is printed. These prints are useful for hunting down - devices that take too long to suspend or resume. - - Writing a "1" enables this printing while writing a "0" - disables it. The default value is "0". Reading from this file - will display the current value. diff --git a/trunk/Documentation/DocBook/media/v4l/controls.xml b/trunk/Documentation/DocBook/media/v4l/controls.xml index cda0dfb6769a..676bc46f9c52 100644 --- a/trunk/Documentation/DocBook/media/v4l/controls.xml +++ b/trunk/Documentation/DocBook/media/v4l/controls.xml @@ -3988,7 +3988,7 @@ interface and may change in the future. from RGB to Y'CbCr color space. - + diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt.xml index e58934c92895..f5ac15ed0549 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt.xml @@ -986,13 +986,13 @@ http://www.thedirks.org/winnov/ V4L2_PIX_FMT_Y4 'Y04 ' - Old 4-bit greyscale format. Only the most significant 4 bits of each byte are used, + Old 4-bit greyscale format. Only the least significant 4 bits of each byte are used, the other bits are set to 0. V4L2_PIX_FMT_Y6 'Y06 ' - Old 6-bit greyscale format. Only the most significant 6 bits of each byte are used, + Old 6-bit greyscale format. Only the least significant 6 bits of each byte are used, the other bits are set to 0. diff --git a/trunk/Documentation/DocBook/media/v4l/v4l2.xml b/trunk/Documentation/DocBook/media/v4l/v4l2.xml index 008c2d73a484..015c561754b7 100644 --- a/trunk/Documentation/DocBook/media/v4l/v4l2.xml +++ b/trunk/Documentation/DocBook/media/v4l/v4l2.xml @@ -560,7 +560,6 @@ and discussions on the V4L mailing list. &sub-g-tuner; &sub-log-status; &sub-overlay; - &sub-prepare-buf; &sub-qbuf; &sub-querybuf; &sub-querycap; @@ -568,6 +567,7 @@ and discussions on the V4L mailing list. &sub-query-dv-preset; &sub-query-dv-timings; &sub-querystd; + &sub-prepare-buf; &sub-reqbufs; &sub-s-hw-freq-seek; &sub-streamon; diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml index a2474ecb574a..765549ff8a71 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml @@ -108,9 +108,10 @@ information. /> - struct v4l2_format + __u32 format - Filled in by the application, preserved by the driver. + Filled in by the application, preserved by the driver. + See . __u32 diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml index 98a856f9ec30..e8714aa16433 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml @@ -89,7 +89,7 @@ &v4l2-event-frame-sync; - frame_sync + frame Event data for event V4L2_EVENT_FRAME_SYNC. diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 0a4b90fcf2da..e3d5afcdafbb 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml @@ -284,6 +284,13 @@ These controls are described in . + + V4L2_CTRL_CLASS_JPEG + 0x9d0000 + The class containing JPEG compression controls. +These controls are described in . + diff --git a/trunk/Documentation/RCU/checklist.txt b/trunk/Documentation/RCU/checklist.txt index fc103d7a0474..5c8d74968090 100644 --- a/trunk/Documentation/RCU/checklist.txt +++ b/trunk/Documentation/RCU/checklist.txt @@ -162,9 +162,9 @@ over a rather long period of time, but improvements are always welcome! when publicizing a pointer to a structure that can be traversed by an RCU read-side critical section. -5. If call_rcu(), or a related primitive such as call_rcu_bh(), - call_rcu_sched(), or call_srcu() is used, the callback function - must be written to be called from softirq context. In particular, +5. If call_rcu(), or a related primitive such as call_rcu_bh() or + call_rcu_sched(), is used, the callback function must be + written to be called from softirq context. In particular, it cannot block. 6. Since synchronize_rcu() can block, it cannot be called from @@ -202,12 +202,11 @@ over a rather long period of time, but improvements are always welcome! updater uses call_rcu_sched() or synchronize_sched(), then the corresponding readers must disable preemption, possibly by calling rcu_read_lock_sched() and rcu_read_unlock_sched(). - If the updater uses synchronize_srcu() or call_srcu(), - the the corresponding readers must use srcu_read_lock() and - srcu_read_unlock(), and with the same srcu_struct. The rules for - the expedited primitives are the same as for their non-expedited - counterparts. Mixing things up will result in confusion and - broken kernels. + If the updater uses synchronize_srcu(), the the corresponding + readers must use srcu_read_lock() and srcu_read_unlock(), + and with the same srcu_struct. The rules for the expedited + primitives are the same as for their non-expedited counterparts. + Mixing things up will result in confusion and broken kernels. One exception to this rule: rcu_read_lock() and rcu_read_unlock() may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh() @@ -334,14 +333,14 @@ over a rather long period of time, but improvements are always welcome! victim CPU from ever going offline.) 14. SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), - synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu()) - may only be invoked from process context. Unlike other forms of - RCU, it -is- permissible to block in an SRCU read-side critical - section (demarked by srcu_read_lock() and srcu_read_unlock()), - hence the "SRCU": "sleepable RCU". Please note that if you - don't need to sleep in read-side critical sections, you should be - using RCU rather than SRCU, because RCU is almost always faster - and easier to use than is SRCU. + synchronize_srcu(), and synchronize_srcu_expedited()) may only + be invoked from process context. Unlike other forms of RCU, it + -is- permissible to block in an SRCU read-side critical section + (demarked by srcu_read_lock() and srcu_read_unlock()), hence the + "SRCU": "sleepable RCU". Please note that if you don't need + to sleep in read-side critical sections, you should be using + RCU rather than SRCU, because RCU is almost always faster and + easier to use than is SRCU. If you need to enter your read-side critical section in a hardirq or exception handler, and then exit that same read-side @@ -354,8 +353,8 @@ over a rather long period of time, but improvements are always welcome! cleanup_srcu_struct(). These are passed a "struct srcu_struct" that defines the scope of a given SRCU domain. Once initialized, the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() - synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu(). - A given synchronize_srcu() waits only for SRCU read-side critical + synchronize_srcu(), and synchronize_srcu_expedited(). A given + synchronize_srcu() waits only for SRCU read-side critical sections governed by srcu_read_lock() and srcu_read_unlock() calls that have been passed the same srcu_struct. This property is what makes sleeping read-side critical sections tolerable -- @@ -375,7 +374,7 @@ over a rather long period of time, but improvements are always welcome! requiring SRCU's read-side deadlock immunity or low read-side realtime latency. - Note that, rcu_assign_pointer() relates to SRCU just as it does + Note that, rcu_assign_pointer() relates to SRCU just as they do to other forms of RCU. 15. The whole point of call_rcu(), synchronize_rcu(), and friends diff --git a/trunk/Documentation/RCU/rcubarrier.txt b/trunk/Documentation/RCU/rcubarrier.txt index 38428c125135..e439a0edee22 100644 --- a/trunk/Documentation/RCU/rcubarrier.txt +++ b/trunk/Documentation/RCU/rcubarrier.txt @@ -79,6 +79,8 @@ complete. Pseudo-code using rcu_barrier() is as follows: 2. Execute rcu_barrier(). 3. Allow the module to be unloaded. +Quick Quiz #1: Why is there no srcu_barrier()? + The rcutorture module makes use of rcu_barrier in its exit function as follows: @@ -160,7 +162,7 @@ for any pre-existing callbacks to complete. Then lines 55-62 print status and do operation-specific cleanup, and then return, permitting the module-unload operation to be completed. -Quick Quiz #1: Is there any other situation where rcu_barrier() might +Quick Quiz #2: Is there any other situation where rcu_barrier() might be required? Your module might have additional complications. For example, if your @@ -240,7 +242,7 @@ reaches zero, as follows: 4 complete(&rcu_barrier_completion); 5 } -Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes +Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes immediately (thus incrementing rcu_barrier_cpu_count to the value one), but the other CPU's rcu_barrier_func() invocations are delayed for a full grace period? Couldn't this result in @@ -257,7 +259,12 @@ so that your module may be safely unloaded. Answers to Quick Quizzes -Quick Quiz #1: Is there any other situation where rcu_barrier() might +Quick Quiz #1: Why is there no srcu_barrier()? + +Answer: Since there is no call_srcu(), there can be no outstanding SRCU + callbacks. Therefore, there is no need to wait for them. + +Quick Quiz #2: Is there any other situation where rcu_barrier() might be required? Answer: Interestingly enough, rcu_barrier() was not originally @@ -271,7 +278,7 @@ Answer: Interestingly enough, rcu_barrier() was not originally implementing rcutorture, and found that rcu_barrier() solves this problem as well. -Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes +Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes immediately (thus incrementing rcu_barrier_cpu_count to the value one), but the other CPU's rcu_barrier_func() invocations are delayed for a full grace period? Couldn't this result in diff --git a/trunk/Documentation/RCU/torture.txt b/trunk/Documentation/RCU/torture.txt index 7dce8a17eac2..4ddf3913fd8c 100644 --- a/trunk/Documentation/RCU/torture.txt +++ b/trunk/Documentation/RCU/torture.txt @@ -174,20 +174,11 @@ torture_type The type of RCU to test, with string values as follows: and synchronize_rcu_bh_expedited(). "srcu": srcu_read_lock(), srcu_read_unlock() and - call_srcu(). - - "srcu_sync": srcu_read_lock(), srcu_read_unlock() and synchronize_srcu(). "srcu_expedited": srcu_read_lock(), srcu_read_unlock() and synchronize_srcu_expedited(). - "srcu_raw": srcu_read_lock_raw(), srcu_read_unlock_raw(), - and call_srcu(). - - "srcu_raw_sync": srcu_read_lock_raw(), srcu_read_unlock_raw(), - and synchronize_srcu(). - "sched": preempt_disable(), preempt_enable(), and call_rcu_sched(). diff --git a/trunk/Documentation/RCU/whatisRCU.txt b/trunk/Documentation/RCU/whatisRCU.txt index 69ee188515e7..6bbe8dcdc3da 100644 --- a/trunk/Documentation/RCU/whatisRCU.txt +++ b/trunk/Documentation/RCU/whatisRCU.txt @@ -833,9 +833,9 @@ sched: Critical sections Grace period Barrier SRCU: Critical sections Grace period Barrier - srcu_read_lock synchronize_srcu srcu_barrier - srcu_read_unlock call_srcu - srcu_read_lock_raw synchronize_srcu_expedited + srcu_read_lock synchronize_srcu N/A + srcu_read_unlock synchronize_srcu_expedited + srcu_read_lock_raw srcu_read_unlock_raw srcu_dereference diff --git a/trunk/Documentation/arm/SPEAr/overview.txt b/trunk/Documentation/arm/SPEAr/overview.txt index 65610bf52ebf..57aae7765c74 100644 --- a/trunk/Documentation/arm/SPEAr/overview.txt +++ b/trunk/Documentation/arm/SPEAr/overview.txt @@ -60,4 +60,4 @@ Introduction Document Author --------------- - Viresh Kumar , (c) 2010-2012 ST Microelectronics + Viresh Kumar , (c) 2010-2012 ST Microelectronics diff --git a/trunk/Documentation/device-mapper/verity.txt b/trunk/Documentation/device-mapper/verity.txt index 9884681535ee..32e48797a14f 100644 --- a/trunk/Documentation/device-mapper/verity.txt +++ b/trunk/Documentation/device-mapper/verity.txt @@ -7,39 +7,39 @@ This target is read-only. Construction Parameters ======================= - + - This is the type of the on-disk hash format. + This is the version number of the on-disk format. 0 is the original format used in the Chromium OS. - The salt is appended when hashing, digests are stored continuously and - the rest of the block is padded with zeros. + The salt is appended when hashing, digests are stored continuously and + the rest of the block is padded with zeros. 1 is the current format that should be used for new devices. - The salt is prepended when hashing and each digest is - padded with zeros to the power of two. + The salt is prepended when hashing and each digest is + padded with zeros to the power of two. - This is the device containing data, the integrity of which needs to be + This is the device containing the data the integrity of which needs to be checked. It may be specified as a path, like /dev/sdaX, or a device number, :. - This is the device that supplies the hash tree data. It may be + This is the device that that supplies the hash tree data. It may be specified similarly to the device path and may be the same device. If the - same device is used, the hash_start should be outside the configured - dm-verity device. + same device is used, the hash_start should be outside of the dm-verity + configured device size. - The block size on a data device in bytes. - Each block corresponds to one digest on the hash device. + The block size on a data device. Each block corresponds to one digest on + the hash device. - The size of a hash block in bytes. + The size of a hash block. The number of data blocks on the data device. Additional blocks are @@ -65,7 +65,7 @@ Construction Parameters Theory of operation =================== -dm-verity is meant to be set up as part of a verified boot path. This +dm-verity is meant to be setup as part of a verified boot path. This may be anything ranging from a boot using tboot or trustedgrub to just booting from a known-good device (like a USB drive or CD). @@ -73,20 +73,20 @@ When a dm-verity device is configured, it is expected that the caller has been authenticated in some way (cryptographic signatures, etc). After instantiation, all hashes will be verified on-demand during disk access. If they cannot be verified up to the root node of the -tree, the root hash, then the I/O will fail. This should detect +tree, the root hash, then the I/O will fail. This should identify tampering with any data on the device and the hash data. Cryptographic hashes are used to assert the integrity of the device on a -per-block basis. This allows for a lightweight hash computation on first read -into the page cache. Block hashes are stored linearly, aligned to the nearest -block size. +per-block basis. This allows for a lightweight hash computation on first read +into the page cache. Block hashes are stored linearly-aligned to the nearest +block the size of a page. Hash Tree --------- Each node in the tree is a cryptographic hash. If it is a leaf node, the hash -of some data block on disk is calculated. If it is an intermediary node, -the hash of a number of child nodes is calculated. +is of some block data on disk. If it is an intermediary node, then the hash is +of a number of child nodes. Each entry in the tree is a collection of neighboring nodes that fit in one block. The number is determined based on block_size and the size of the @@ -110,23 +110,63 @@ alg = sha256, num_blocks = 32768, block_size = 4096 On-disk format ============== -The verity kernel code does not read the verity metadata on-disk header. -It only reads the hash blocks which directly follow the header. -It is expected that a user-space tool will verify the integrity of the -verity header. +Below is the recommended on-disk format. The verity kernel code does not +read the on-disk header. It only reads the hash blocks which directly +follow the header. It is expected that a user-space tool will verify the +integrity of the verity_header and then call dmsetup with the correct +parameters. Alternatively, the header can be omitted and the dmsetup +parameters can be passed via the kernel command-line in a rooted chain +of trust where the command-line is verified. -Alternatively, the header can be omitted and the dmsetup parameters can -be passed via the kernel command-line in a rooted chain of trust where -the command-line is verified. +The on-disk format is especially useful in cases where the hash blocks +are on a separate partition. The magic number allows easy identification +of the partition contents. Alternatively, the hash blocks can be stored +in the same partition as the data to be verified. In such a configuration +the filesystem on the partition would be sized a little smaller than +the full-partition, leaving room for the hash blocks. + +struct superblock { + uint8_t signature[8] + "verity\0\0"; + + uint8_t version; + 1 - current format + + uint8_t data_block_bits; + log2(data block size) + + uint8_t hash_block_bits; + log2(hash block size) + + uint8_t pad1[1]; + zero padding + + uint16_t salt_size; + big-endian salt size + + uint8_t pad2[2]; + zero padding + + uint32_t data_blocks_hi; + big-endian high 32 bits of the 64-bit number of data blocks + + uint32_t data_blocks_lo; + big-endian low 32 bits of the 64-bit number of data blocks + + uint8_t algorithm[16]; + cryptographic algorithm + + uint8_t salt[384]; + salt (the salt size is specified above) + + uint8_t pad3[88]; + zero padding to 512-byte boundary +} Directly following the header (and with sector number padded to the next hash block boundary) are the hash blocks which are stored a depth at a time (starting from the root), sorted in order of increasing index. -The full specification of kernel parameters and on-disk metadata format -is available at the cryptsetup project's wiki page - http://code.google.com/p/cryptsetup/wiki/DMVerity - Status ====== V (for Valid) is returned if every check performed so far was valid. @@ -134,22 +174,21 @@ If any check failed, C (for Corruption) is returned. Example ======= -Set up a device: - # dmsetup create vroot --readonly --table \ - "0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\ + +Setup a device: + dmsetup create vroot --table \ + "0 2097152 "\ + "verity 1 /dev/sda1 /dev/sda2 4096 4096 2097152 1 "\ "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ "1234000000000000000000000000000000000000000000000000000000000000" A command line tool veritysetup is available to compute or verify -the hash tree or activate the kernel device. This is available from -the cryptsetup upstream repository http://code.google.com/p/cryptsetup/ -(as a libcryptsetup extension). - -Create hash on the device: - # veritysetup format /dev/sda1 /dev/sda2 - ... - Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 - -Activate the device: - # veritysetup create vroot /dev/sda1 /dev/sda2 \ - 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 +the hash tree or activate the kernel driver. This is available from +the LVM2 upstream repository and may be supplied as a package called +device-mapper-verity-tools: + git://sources.redhat.com/git/lvm2 + http://sourceware.org/git/?p=lvm2.git + http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/verity?cvsroot=lvm2 + +veritysetup -a vroot /dev/sda1 /dev/sda2 \ + 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 diff --git a/trunk/Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt b/trunk/Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt deleted file mode 100644 index ae8af1694e95..000000000000 --- a/trunk/Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt +++ /dev/null @@ -1,93 +0,0 @@ -Pinctrl-based I2C Bus Mux - -This binding describes an I2C bus multiplexer that uses pin multiplexing to -route the I2C signals, and represents the pin multiplexing configuration -using the pinctrl device tree bindings. - - +-----+ +-----+ - | dev | | dev | - +------------------------+ +-----+ +-----+ - | SoC | | | - | /----|------+--------+ - | +---+ +------+ | child bus A, on first set of pins - | |I2C|---|Pinmux| | - | +---+ +------+ | child bus B, on second set of pins - | \----|------+--------+--------+ - | | | | | - +------------------------+ +-----+ +-----+ +-----+ - | dev | | dev | | dev | - +-----+ +-----+ +-----+ - -Required properties: -- compatible: i2c-mux-pinctrl -- i2c-parent: The phandle of the I2C bus that this multiplexer's master-side - port is connected to. - -Also required are: - -* Standard pinctrl properties that specify the pin mux state for each child - bus. See ../pinctrl/pinctrl-bindings.txt. - -* Standard I2C mux properties. See mux.txt in this directory. - -* I2C child bus nodes. See mux.txt in this directory. - -For each named state defined in the pinctrl-names property, an I2C child bus -will be created. I2C child bus numbers are assigned based on the index into -the pinctrl-names property. - -The only exception is that no bus will be created for a state named "idle". If -such a state is defined, it must be the last entry in pinctrl-names. For -example: - - pinctrl-names = "ddc", "pta", "idle" -> ddc = bus 0, pta = bus 1 - pinctrl-names = "ddc", "idle", "pta" -> Invalid ("idle" not last) - pinctrl-names = "idle", "ddc", "pta" -> Invalid ("idle" not last) - -Whenever an access is made to a device on a child bus, the relevant pinctrl -state will be programmed into hardware. - -If an idle state is defined, whenever an access is not being made to a device -on a child bus, the idle pinctrl state will be programmed into hardware. - -If an idle state is not defined, the most recently used pinctrl state will be -left programmed into hardware whenever no access is being made of a device on -a child bus. - -Example: - - i2cmux { - compatible = "i2c-mux-pinctrl"; - #address-cells = <1>; - #size-cells = <0>; - - i2c-parent = <&i2c1>; - - pinctrl-names = "ddc", "pta", "idle"; - pinctrl-0 = <&state_i2cmux_ddc>; - pinctrl-1 = <&state_i2cmux_pta>; - pinctrl-2 = <&state_i2cmux_idle>; - - i2c@0 { - reg = <0>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom { - compatible = "eeprom"; - reg = <0x50>; - }; - }; - - i2c@1 { - reg = <1>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom { - compatible = "eeprom"; - reg = <0x50>; - }; - }; - }; - diff --git a/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt b/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt index 0b96e5737d3a..a00c94ccbdee 100644 --- a/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt +++ b/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt @@ -2,7 +2,6 @@ Required properties: - compatible : "fsl,mma8450". -- reg: the I2C address of MMA8450 Example: diff --git a/trunk/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/trunk/Documentation/devicetree/bindings/mfd/mc13xxx.txt index baf07987ae68..19f6af47a792 100644 --- a/trunk/Documentation/devicetree/bindings/mfd/mc13xxx.txt +++ b/trunk/Documentation/devicetree/bindings/mfd/mc13xxx.txt @@ -46,8 +46,8 @@ Examples: ecspi@70010000 { /* ECSPI1 */ fsl,spi-num-chipselects = <2>; - cs-gpios = <&gpio4 24 0>, /* GPIO4_24 */ - <&gpio4 25 0>; /* GPIO4_25 */ + cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */ + <&gpio3 25 0>; /* GPIO4_25 */ status = "okay"; pmic: mc13892@0 { diff --git a/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt b/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt index d2802d4717bc..645f5eaadb3f 100644 --- a/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt +++ b/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt @@ -17,46 +17,18 @@ Required properties: device need to be present. The definition for each of these nodes is defined using the standard binding for regulators found at Documentation/devicetree/bindings/regulator/regulator.txt. - The regulator is matched with the regulator-compatible. - The valid regulator-compatible values are: + The valid names for regulators are: tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1, vaux2, vaux33, vmmc tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8 -- xxx-supply: Input voltage supply regulator. - These entries are require if regulators are enabled for a device. Missing of these - properties can cause the regulator registration fails. - If some of input supply is powered through battery or always-on supply then - also it is require to have these parameters with proper node handle of always - on power supply. - tps65910: - vcc1-supply: VDD1 input. - vcc2-supply: VDD2 input. - vcc3-supply: VAUX33 and VMMC input. - vcc4-supply: VAUX1 and VAUX2 input. - vcc5-supply: VPLL and VDAC input. - vcc6-supply: VDIG1 and VDIG2 input. - vcc7-supply: VRTC input. - vccio-supply: VIO input. - tps65911: - vcc1-supply: VDD1 input. - vcc2-supply: VDD2 input. - vcc3-supply: LDO6, LDO7 and LDO8 input. - vcc4-supply: LDO5 input. - vcc5-supply: LDO3 and LDO4 input. - vcc6-supply: LDO1 and LDO2 input. - vcc7-supply: VRTC input. - vccio-supply: VIO input. - Optional properties: - ti,vmbch-threshold: (tps65911) main battery charged threshold comparator. (see VMBCH_VSEL in TPS65910 datasheet) - ti,vmbch2-threshold: (tps65911) main battery discharged threshold comparator. (see VMBCH_VSEL in TPS65910 datasheet) -- ti,en-ck32k-xtal: enable external 32-kHz crystal oscillator (see CK32K_CTRL - in TPS6591X datasheet) - ti,en-gpio-sleep: enable sleep control for gpios There should be 9 entries here, one for each gpio. @@ -84,110 +56,74 @@ Example: ti,en-gpio-sleep = <0 0 1 0 0 0 0 0 0>; - vcc1-supply = <®_parent>; - vcc2-supply = <&some_reg>; - vcc3-supply = <...>; - vcc4-supply = <...>; - vcc5-supply = <...>; - vcc6-supply = <...>; - vcc7-supply = <...>; - vccio-supply = <...>; - regulators { - #address-cells = <1>; - #size-cells = <0>; - - vdd1_reg: regulator@0 { - regulator-compatible = "vdd1"; - reg = <0>; + vdd1_reg: vdd1 { regulator-min-microvolt = < 600000>; regulator-max-microvolt = <1500000>; regulator-always-on; regulator-boot-on; ti,regulator-ext-sleep-control = <0>; }; - vdd2_reg: regulator@1 { - regulator-compatible = "vdd2"; - reg = <1>; + vdd2_reg: vdd2 { regulator-min-microvolt = < 600000>; regulator-max-microvolt = <1500000>; regulator-always-on; regulator-boot-on; ti,regulator-ext-sleep-control = <4>; }; - vddctrl_reg: regulator@2 { - regulator-compatible = "vddctrl"; - reg = <2>; + vddctrl_reg: vddctrl { regulator-min-microvolt = < 600000>; regulator-max-microvolt = <1400000>; regulator-always-on; regulator-boot-on; ti,regulator-ext-sleep-control = <0>; }; - vio_reg: regulator@3 { - regulator-compatible = "vio"; - reg = <3>; + vio_reg: vio { regulator-min-microvolt = <1500000>; regulator-max-microvolt = <1800000>; regulator-always-on; regulator-boot-on; ti,regulator-ext-sleep-control = <1>; }; - ldo1_reg: regulator@4 { - regulator-compatible = "ldo1"; - reg = <4>; + ldo1_reg: ldo1 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3300000>; ti,regulator-ext-sleep-control = <0>; }; - ldo2_reg: regulator@5 { - regulator-compatible = "ldo2"; - reg = <5>; + ldo2_reg: ldo2 { regulator-min-microvolt = <1050000>; regulator-max-microvolt = <1050000>; ti,regulator-ext-sleep-control = <0>; }; - ldo3_reg: regulator@6 { - regulator-compatible = "ldo3"; - reg = <6>; + ldo3_reg: ldo3 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3300000>; ti,regulator-ext-sleep-control = <0>; }; - ldo4_reg: regulator@7 { - regulator-compatible = "ldo4"; - reg = <7>; + ldo4_reg: ldo4 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3300000>; regulator-always-on; ti,regulator-ext-sleep-control = <0>; }; - ldo5_reg: regulator@8 { - regulator-compatible = "ldo5"; - reg = <8>; + ldo5_reg: ldo5 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3300000>; ti,regulator-ext-sleep-control = <0>; }; - ldo6_reg: regulator@9 { - regulator-compatible = "ldo6"; - reg = <9>; + ldo6_reg: ldo6 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; ti,regulator-ext-sleep-control = <0>; }; - ldo7_reg: regulator@10 { - regulator-compatible = "ldo7"; - reg = <10>; + ldo7_reg: ldo7 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-always-on; regulator-boot-on; ti,regulator-ext-sleep-control = <1>; }; - ldo8_reg: regulator@11 { - regulator-compatible = "ldo8"; - reg = <11>; + ldo8_reg: ldo8 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3300000>; regulator-always-on; diff --git a/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index fea541ee8b34..c7e404b3ef05 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -29,6 +29,6 @@ esdhc@70008000 { compatible = "fsl,imx51-esdhc"; reg = <0x70008000 0x4000>; interrupts = <2>; - cd-gpios = <&gpio1 6 0>; /* GPIO1_6 */ - wp-gpios = <&gpio1 5 0>; /* GPIO1_5 */ + cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */ + wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */ }; diff --git a/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt b/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt index 4616fc28ee86..7ab9e1a2d8be 100644 --- a/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -19,6 +19,6 @@ ethernet@83fec000 { reg = <0x83fec000 0x4000>; interrupts = <87>; phy-mode = "mii"; - phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */ + phy-reset-gpios = <&gpio1 14 0>; /* GPIO2_14 */ local-mac-address = [00 04 9F 01 1B B9]; }; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt index a4119f6422d9..82b43f915857 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt @@ -1626,5 +1626,3 @@ MX6Q_PAD_SD2_DAT3__PCIE_CTRL_MUX_11 1587 MX6Q_PAD_SD2_DAT3__GPIO_1_12 1588 MX6Q_PAD_SD2_DAT3__SJC_DONE 1589 MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 1590 -MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID 1591 -MX6Q_PAD_GPIO_1__ANATOP_USBOTG_ID 1592 diff --git a/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt index 4fae41d54798..2f5b6b1ba15f 100644 --- a/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt +++ b/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt @@ -10,7 +10,6 @@ Optional properties: If this property is missing, the default assumed is Active low. - gpio-open-drain: GPIO is open drain type. If this property is missing then default assumption is false. --vin-supply: Input supply name. Any property defined as part of the core regulator binding, defined in regulator.txt, can also be used. @@ -30,5 +29,4 @@ Example: enable-active-high; regulator-boot-on; gpio-open-drain; - vin-supply = <&parent_reg>; }; diff --git a/trunk/Documentation/devicetree/bindings/regulator/regulator.txt b/trunk/Documentation/devicetree/bindings/regulator/regulator.txt index 66ece3f87bbc..5b7a408acdaa 100644 --- a/trunk/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/trunk/Documentation/devicetree/bindings/regulator/regulator.txt @@ -10,11 +10,6 @@ Optional properties: - regulator-always-on: boolean, regulator should never be disabled - regulator-boot-on: bootloader/firmware enabled regulator - -supply: phandle to the parent supply/regulator node -- regulator-ramp-delay: ramp delay for regulator(in uV/uS) -- regulator-compatible: If a regulator chip contains multiple - regulators, and if the chip's binding contains a child node that - describes each regulator, then this property indicates which regulator - this child node is intended to configure. Example: diff --git a/trunk/Documentation/devicetree/bindings/regulator/tps65217.txt b/trunk/Documentation/devicetree/bindings/regulator/tps65217.txt deleted file mode 100644 index 0487e9675ba0..000000000000 --- a/trunk/Documentation/devicetree/bindings/regulator/tps65217.txt +++ /dev/null @@ -1,91 +0,0 @@ -TPS65217 family of regulators - -Required properties: -- compatible: "ti,tps65217" -- reg: I2C slave address -- regulators: list of regulators provided by this controller, must be named - after their hardware counterparts: dcdc[1-3] and ldo[1-4] -- regulators: This is the list of child nodes that specify the regulator - initialization data for defined regulators. Not all regulators for the given - device need to be present. The definition for each of these nodes is defined - using the standard binding for regulators found at - Documentation/devicetree/bindings/regulator/regulator.txt. - - The valid names for regulators are: - tps65217: dcdc1, dcdc2, dcdc3, ldo1, ldo2, ldo3 and ldo4 - -Each regulator is defined using the standard binding for regulators. - -Example: - - tps: tps@24 { - compatible = "ti,tps65217"; - - regulators { - #address-cells = <1>; - #size-cells = <0>; - - dcdc1_reg: regulator@0 { - reg = <0>; - regulator-compatible = "dcdc1"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - - dcdc2_reg: regulator@1 { - reg = <1>; - regulator-compatible = "dcdc2"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - dcdc3_reg: regulator@2 { - reg = <2>; - regulator-compatible = "dcdc3"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo1_reg: regulator@3 { - reg = <3>; - regulator-compatible = "ldo1"; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo2_reg: regulator@4 { - reg = <4>; - regulator-compatible = "ldo2"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo3_reg: regulator@5 { - reg = <5>; - regulator-compatible = "ldo3"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo4_reg: regulator@6 { - reg = <6>; - regulator-compatible = "ldo4"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt b/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt index d156e1b5db12..0fcabaa3baa3 100644 --- a/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt +++ b/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt @@ -6,17 +6,8 @@ Required properties: - interrupts: the interrupt outputs of the controller - #gpio-cells: number of cells to describe a GPIO - gpio-controller: mark the device as a GPIO controller -- regulators: list of regulators provided by this controller, must have - property "regulator-compatible" to match their hardware counterparts: - sm[0-2], ldo[0-9] and ldo_rtc -- sm0-supply: The input supply for the SM0. -- sm1-supply: The input supply for the SM1. -- sm2-supply: The input supply for the SM2. -- vinldo01-supply: The input supply for the LDO1 and LDO2 -- vinldo23-supply: The input supply for the LDO2 and LDO3 -- vinldo4-supply: The input supply for the LDO4 -- vinldo678-supply: The input supply for the LDO6, LDO7 and LDO8 -- vinldo9-supply: The input supply for the LDO9 +- regulators: list of regulators provided by this controller, must be named + after their hardware counterparts: sm[0-2], ldo[0-9] and ldo_rtc Each regulator is defined using the standard binding for regulators. @@ -30,113 +21,75 @@ Example: #gpio-cells = <2>; gpio-controller; - sm0-supply = <&some_reg>; - sm1-supply = <&some_reg>; - sm2-supply = <&some_reg>; - vinldo01-supply = <...>; - vinldo23-supply = <...>; - vinldo4-supply = <...>; - vinldo678-supply = <...>; - vinldo9-supply = <...>; - regulators { - #address-cells = <1>; - #size-cells = <0>; - - sm0_reg: regulator@0 { - reg = <0>; - regulator-compatible = "sm0"; + sm0_reg: sm0 { regulator-min-microvolt = < 725000>; regulator-max-microvolt = <1500000>; regulator-boot-on; regulator-always-on; }; - sm1_reg: regulator@1 { - reg = <1>; - regulator-compatible = "sm1"; + sm1_reg: sm1 { regulator-min-microvolt = < 725000>; regulator-max-microvolt = <1500000>; regulator-boot-on; regulator-always-on; }; - sm2_reg: regulator@2 { - reg = <2>; - regulator-compatible = "sm2"; + sm2_reg: sm2 { regulator-min-microvolt = <3000000>; regulator-max-microvolt = <4550000>; regulator-boot-on; regulator-always-on; }; - ldo0_reg: regulator@3 { - reg = <3>; - regulator-compatible = "ldo0"; + ldo0_reg: ldo0 { regulator-name = "PCIE CLK"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; - ldo1_reg: regulator@4 { - reg = <4>; - regulator-compatible = "ldo1"; + ldo1_reg: ldo1 { regulator-min-microvolt = < 725000>; regulator-max-microvolt = <1500000>; }; - ldo2_reg: regulator@5 { - reg = <5>; - regulator-compatible = "ldo2"; + ldo2_reg: ldo2 { regulator-min-microvolt = < 725000>; regulator-max-microvolt = <1500000>; }; - ldo3_reg: regulator@6 { - reg = <6>; - regulator-compatible = "ldo3"; + ldo3_reg: ldo3 { regulator-min-microvolt = <1250000>; regulator-max-microvolt = <3300000>; }; - ldo4_reg: regulator@7 { - reg = <7>; - regulator-compatible = "ldo4"; + ldo4_reg: ldo4 { regulator-min-microvolt = <1700000>; regulator-max-microvolt = <2475000>; }; - ldo5_reg: regulator@8 { - reg = <8>; - regulator-compatible = "ldo5"; + ldo5_reg: ldo5 { regulator-min-microvolt = <1250000>; regulator-max-microvolt = <3300000>; }; - ldo6_reg: regulator@9 { - reg = <9>; - regulator-compatible = "ldo6"; + ldo6_reg: ldo6 { regulator-min-microvolt = <1250000>; regulator-max-microvolt = <3300000>; }; - ldo7_reg: regulator@10 { - reg = <10>; - regulator-compatible = "ldo7"; + ldo7_reg: ldo7 { regulator-min-microvolt = <1250000>; regulator-max-microvolt = <3300000>; }; - ldo8_reg: regulator@11 { - reg = <11>; - regulator-compatible = "ldo8"; + ldo8_reg: ldo8 { regulator-min-microvolt = <1250000>; regulator-max-microvolt = <3300000>; }; - ldo9_reg: regulator@12 { - reg = <12>; - regulator-compatible = "ldo9"; + ldo9_reg: ldo9 { regulator-min-microvolt = <1250000>; regulator-max-microvolt = <3300000>; }; diff --git a/trunk/Documentation/devicetree/bindings/regulator/twl-regulator.txt b/trunk/Documentation/devicetree/bindings/regulator/twl-regulator.txt index 658749b90b97..0c3395d55ac1 100644 --- a/trunk/Documentation/devicetree/bindings/regulator/twl-regulator.txt +++ b/trunk/Documentation/devicetree/bindings/regulator/twl-regulator.txt @@ -15,6 +15,7 @@ For twl6030 regulators/LDOs - "ti,twl6030-vusb" for VUSB LDO - "ti,twl6030-v1v8" for V1V8 LDO - "ti,twl6030-v2v1" for V2V1 LDO + - "ti,twl6030-clk32kg" for CLK32KG RESOURCE - "ti,twl6030-vdd1" for VDD1 SMPS - "ti,twl6030-vdd2" for VDD2 SMPS - "ti,twl6030-vdd3" for VDD3 SMPS diff --git a/trunk/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/trunk/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index 4256a6df9b79..9841057d112b 100644 --- a/trunk/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/trunk/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -17,6 +17,6 @@ ecspi@70010000 { reg = <0x70010000 0x4000>; interrupts = <36>; fsl,spi-num-chipselects = <2>; - cs-gpios = <&gpio3 24 0>, /* GPIO3_24 */ - <&gpio3 25 0>; /* GPIO3_25 */ + cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */ + <&gpio3 25 0>; /* GPIO4_25 */ }; diff --git a/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt b/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt index db4d3af3643c..6eab91747a86 100644 --- a/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -3,7 +3,6 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. This isn't an exhaustive list, but you should add new prefixes to it before using them to avoid name-space collisions. -ad Avionic Design GmbH adi Analog Devices, Inc. amcc Applied Micro Circuits Corporation (APM, formally AMCC) apm Applied Micro Circuits Corporation (APM) diff --git a/trunk/Documentation/hwmon/coretemp b/trunk/Documentation/hwmon/coretemp index c86b50c03ea8..84d46c0c71a3 100644 --- a/trunk/Documentation/hwmon/coretemp +++ b/trunk/Documentation/hwmon/coretemp @@ -6,9 +6,7 @@ Supported chips: Prefix: 'coretemp' CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), - 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield), - 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom), - 0x36 (Cedar Trail Atom) + 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield) Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide http://softwarecommunity.intel.com/Wiki/Mobility/720.htm @@ -54,17 +52,6 @@ Some information comes from ark.intel.com Process Processor TjMax(C) -22nm Core i5/i7 Processors - i7 3920XM, 3820QM, 3720QM, 3667U, 3520M 105 - i5 3427U, 3360M/3320M 105 - i7 3770/3770K 105 - i5 3570/3570K, 3550, 3470/3450 105 - i7 3770S 103 - i5 3570S/3550S, 3475S/3470S/3450S 103 - i7 3770T 94 - i5 3570T 94 - i5 3470T 91 - 32nm Core i3/i5/i7 Processors i7 660UM/640/620, 640LM/620, 620M, 610E 105 i5 540UM/520/430, 540M/520/450/430 105 @@ -78,11 +65,6 @@ Process Processor TjMax(C) U3400 105 P4505/P4500 90 -32nm Atom Processors - Z2460 90 - D2700/2550/2500 100 - N2850/2800/2650/2600 100 - 45nm Xeon Processors 5400 Quad-Core X5492, X5482, X5472, X5470, X5460, X5450 85 E5472, E5462, E5450/40/30/20/10/05 85 @@ -103,8 +85,6 @@ Process Processor TjMax(C) N475/470/455/450 100 N280/270 90 330/230 125 - E680/660/640/620 90 - E680T/660T/640T/620T 110 45nm Core2 Processors Solo ULV SU3500/3300 100 diff --git a/trunk/Documentation/kdump/kdump.txt b/trunk/Documentation/kdump/kdump.txt index 13f1aa09b938..506c7390c2b9 100644 --- a/trunk/Documentation/kdump/kdump.txt +++ b/trunk/Documentation/kdump/kdump.txt @@ -86,7 +86,7 @@ There is also a gitweb interface available at http://www.kernel.org/git/?p=utils/kernel/kexec/kexec-tools.git More information about kexec-tools can be found at -http://horms.net/projects/kexec/ +http://www.kernel.org/pub/linux/utils/kernel/kexec/README.html 3) Unpack the tarball with the tar command, as follows: diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 12783fa833c3..c45513d806ab 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -2367,11 +2367,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Set maximum number of finished RCU callbacks to process in one batch. - rcutree.fanout_leaf= [KNL,BOOT] - Increase the number of CPUs assigned to each - leaf rcu_node structure. Useful for very large - systems. - rcutree.qhimark= [KNL,BOOT] Set threshold of queued RCU callbacks over which batch limiting is disabled. @@ -2548,15 +2543,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. sched_debug [KNL] Enables verbose scheduler debug messages. - skew_tick= [KNL] Offset the periodic timer tick per cpu to mitigate - xtime_lock contention on larger systems, and/or RCU lock - contention on all systems with CONFIG_MAXSMP set. - Format: { "0" | "1" } - 0 -- disable. (may be 1 via CONFIG_CMDLINE="skew_tick=1" - 1 -- enable. - Note: increases power consumption, thus should only be - enabled if running jitter sensitive (HPC/RT) workloads. - security= [SECURITY] Choose a security module to enable at boot. If this boot parameter is not specified, only the first security module asking for security registration will be diff --git a/trunk/Documentation/networking/stmmac.txt b/trunk/Documentation/networking/stmmac.txt index 5cb9a1972460..ab1e8d7004c5 100644 --- a/trunk/Documentation/networking/stmmac.txt +++ b/trunk/Documentation/networking/stmmac.txt @@ -10,8 +10,8 @@ Currently this network device driver is for all STM embedded MAC/GMAC (i.e. 7xxx/5xxx SoCs), SPEAr (arm), Loongson1B (mips) and XLINX XC2V3000 FF1152AMT0221 D1215994A VIRTEX FPGA board. -DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether -MAC 10/100 Universal version 4.0 have been used for developing this driver. +DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether MAC 10/100 +Universal version 4.0 have been used for developing this driver. This driver supports both the platform bus and PCI. @@ -54,27 +54,27 @@ net_device structure enabling the scatter/gather feature. When one or more packets are received, an interrupt happens. The interrupts are not queued so the driver has to scan all the descriptors in the ring during the receive process. -This is based on NAPI so the interrupt handler signals only if there is work -to be done, and it exits. +This is based on NAPI so the interrupt handler signals only if there is work to be +done, and it exits. Then the poll method will be scheduled at some future point. The incoming packets are stored, by the DMA, in a list of pre-allocated socket buffers in order to avoid the memcpy (Zero-copy). 4.3) Timer-Driver Interrupt -Instead of having the device that asynchronously notifies the frame receptions, -the driver configures a timer to generate an interrupt at regular intervals. -Based on the granularity of the timer, the frames that are received by the -device will experience different levels of latency. Some NICs have dedicated -timer device to perform this task. STMMAC can use either the RTC device or the -TMU channel 2 on STLinux platforms. +Instead of having the device that asynchronously notifies the frame receptions, the +driver configures a timer to generate an interrupt at regular intervals. +Based on the granularity of the timer, the frames that are received by the device +will experience different levels of latency. Some NICs have dedicated timer +device to perform this task. STMMAC can use either the RTC device or the TMU +channel 2 on STLinux platforms. The timers frequency can be passed to the driver as parameter; when change it, take care of both hardware capability and network stability/performance impact. -Several performance tests on STM platforms showed this optimisation allows to -spare the CPU while having the maximum throughput. +Several performance tests on STM platforms showed this optimisation allows to spare +the CPU while having the maximum throughput. 4.4) WOL -Wake up on Lan feature through Magic and Unicast frames are supported for the -GMAC core. +Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC +core. 4.5) DMA descriptors Driver handles both normal and enhanced descriptors. The latter has been only @@ -106,8 +106,7 @@ Several driver's information can be passed through the platform These are included in the include/linux/stmmac.h header file and detailed below as well: -struct plat_stmmacenet_data { - char *phy_bus_name; + struct plat_stmmacenet_data { int bus_id; int phy_addr; int interface; @@ -125,24 +124,19 @@ struct plat_stmmacenet_data { void (*bus_setup)(void __iomem *ioaddr); int (*init)(struct platform_device *pdev); void (*exit)(struct platform_device *pdev); - void *custom_cfg; - void *custom_data; void *bsp_priv; }; Where: - o phy_bus_name: phy bus name to attach to the stmmac. o bus_id: bus identifier. o phy_addr: the physical address can be passed from the platform. If it is set to -1 the driver will automatically detect it at run-time by probing all the 32 addresses. o interface: PHY device's interface. o mdio_bus_data: specific platform fields for the MDIO bus. - o dma_cfg: internal DMA parameters - o pbl: the Programmable Burst Length is maximum number of beats to + o pbl: the Programmable Burst Length is maximum number of beats to be transferred in one DMA transaction. GMAC also enables the 4xPBL by default. - o fixed_burst/mixed_burst/burst_len o clk_csr: fixed CSR Clock range selection. o has_gmac: uses the GMAC core. o enh_desc: if sets the MAC will use the enhanced descriptor structure. @@ -166,9 +160,8 @@ Where: this is sometime necessary on some platforms (e.g. ST boxes) where the HW needs to have set some PIO lines or system cfg registers. - o custom_cfg/custom_data: this is a custom configuration that can be passed - while initialising the resources. - o bsp_priv: another private poiter. + o custom_cfg: this is a custom configuration that can be passed while + initialising the resources. For MDIO bus The we have: @@ -187,6 +180,7 @@ Where: o irqs: list of IRQs, one per PHY. o probed_phy_irq: if irqs is NULL, use this for probed PHY. + For DMA engine we have the following internal fields that should be tuned according to the HW capabilities. diff --git a/trunk/Documentation/power/devices.txt b/trunk/Documentation/power/devices.txt index 504dfe4d52eb..872815cd41d3 100644 --- a/trunk/Documentation/power/devices.txt +++ b/trunk/Documentation/power/devices.txt @@ -583,10 +583,9 @@ for the given device during all power transitions, instead of the respective subsystem-level callbacks. Specifically, if a device's pm_domain pointer is not NULL, the ->suspend() callback from the object pointed to by it will be executed instead of its subsystem's (e.g. bus type's) ->suspend() callback and -analogously for all of the remaining callbacks. In other words, power -management domain callbacks, if defined for the given device, always take -precedence over the callbacks provided by the device's subsystem (e.g. bus -type). +anlogously for all of the remaining callbacks. In other words, power management +domain callbacks, if defined for the given device, always take precedence over +the callbacks provided by the device's subsystem (e.g. bus type). The support for device power management domains is only relevant to platforms needing to use the same device driver power management callbacks in many @@ -599,7 +598,7 @@ it into account in any way. Device Low Power (suspend) States --------------------------------- Device low-power states aren't standard. One device might only handle -"on" and "off", while another might support a dozen different versions of +"on" and "off, while another might support a dozen different versions of "on" (how many engines are active?), plus a state that gets back to "on" faster than from a full "off". diff --git a/trunk/Documentation/power/swsusp.txt b/trunk/Documentation/power/swsusp.txt index 92341b84250d..ac190cf1963e 100644 --- a/trunk/Documentation/power/swsusp.txt +++ b/trunk/Documentation/power/swsusp.txt @@ -33,11 +33,6 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state echo platform > /sys/power/disk; echo disk > /sys/power/state -. If you would like to write hibernation image to swap and then suspend -to RAM (provided your platform supports it), you can try - -echo suspend > /sys/power/disk; echo disk > /sys/power/state - . If you have SATA disks, you'll need recent kernels with SATA suspend support. For suspend and resume to work, make sure your disk drivers are built into kernel -- not modules. [There's way to make diff --git a/trunk/Documentation/prctl/no_new_privs.txt b/trunk/Documentation/prctl/no_new_privs.txt deleted file mode 100644 index f7be84fba910..000000000000 --- a/trunk/Documentation/prctl/no_new_privs.txt +++ /dev/null @@ -1,57 +0,0 @@ -The execve system call can grant a newly-started program privileges that -its parent did not have. The most obvious examples are setuid/setgid -programs and file capabilities. To prevent the parent program from -gaining these privileges as well, the kernel and user code must be -careful to prevent the parent from doing anything that could subvert the -child. For example: - - - The dynamic loader handles LD_* environment variables differently if - a program is setuid. - - - chroot is disallowed to unprivileged processes, since it would allow - /etc/passwd to be replaced from the point of view of a process that - inherited chroot. - - - The exec code has special handling for ptrace. - -These are all ad-hoc fixes. The no_new_privs bit (since Linux 3.5) is a -new, generic mechanism to make it safe for a process to modify its -execution environment in a manner that persists across execve. Any task -can set no_new_privs. Once the bit is set, it is inherited across fork, -clone, and execve and cannot be unset. With no_new_privs set, execve -promises not to grant the privilege to do anything that could not have -been done without the execve call. For example, the setuid and setgid -bits will no longer change the uid or gid; file capabilities will not -add to the permitted set, and LSMs will not relax constraints after -execve. - -To set no_new_privs, use prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0). - -Be careful, though: LSMs might also not tighten constraints on exec -in no_new_privs mode. (This means that setting up a general-purpose -service launcher to set no_new_privs before execing daemons may -interfere with LSM-based sandboxing.) - -Note that no_new_privs does not prevent privilege changes that do not -involve execve. An appropriately privileged task can still call -setuid(2) and receive SCM_RIGHTS datagrams. - -There are two main use cases for no_new_privs so far: - - - Filters installed for the seccomp mode 2 sandbox persist across - execve and can change the behavior of newly-executed programs. - Unprivileged users are therefore only allowed to install such filters - if no_new_privs is set. - - - By itself, no_new_privs can be used to reduce the attack surface - available to an unprivileged user. If everything running with a - given uid has no_new_privs set, then that uid will be unable to - escalate its privileges by directly attacking setuid, setgid, and - fcap-using binaries; it will need to compromise something without the - no_new_privs bit set first. - -In the future, other potentially dangerous kernel features could become -available to unprivileged tasks if no_new_privs is set. In principle, -several options to unshare(2) and clone(2) would be safe when -no_new_privs is set, and no_new_privs + chroot is considerable less -dangerous than chroot by itself. diff --git a/trunk/Documentation/stable_kernel_rules.txt b/trunk/Documentation/stable_kernel_rules.txt index 4a7b54bd37e8..f0ab5cf28fca 100644 --- a/trunk/Documentation/stable_kernel_rules.txt +++ b/trunk/Documentation/stable_kernel_rules.txt @@ -12,12 +12,6 @@ Rules on what kind of patches are accepted, and which ones are not, into the marked CONFIG_BROKEN), an oops, a hang, data corruption, a real security issue, or some "oh, that's not good" issue. In short, something critical. - - Serious issues as reported by a user of a distribution kernel may also - be considered if they fix a notable performance or interactivity issue. - As these fixes are not as obvious and have a higher risk of a subtle - regression they should only be submitted by a distribution kernel - maintainer and include an addendum linking to a bugzilla entry if it - exists and additional information on the user-visible impact. - New device IDs and quirks are also accepted. - No "theoretical race condition" issues, unless an explanation of how the race can be exploited is also provided. diff --git a/trunk/Documentation/virtual/kvm/api.txt b/trunk/Documentation/virtual/kvm/api.txt index 2c9948379469..930126698a0f 100644 --- a/trunk/Documentation/virtual/kvm/api.txt +++ b/trunk/Documentation/virtual/kvm/api.txt @@ -1930,23 +1930,6 @@ The "pte_enc" field provides a value that can OR'ed into the hash PTE's RPN field (ie, it needs to be shifted left by 12 to OR it into the hash PTE second double word). -4.75 KVM_IRQFD - -Capability: KVM_CAP_IRQFD -Architectures: x86 -Type: vm ioctl -Parameters: struct kvm_irqfd (in) -Returns: 0 on success, -1 on error - -Allows setting an eventfd to directly trigger a guest interrupt. -kvm_irqfd.fd specifies the file descriptor to use as the eventfd and -kvm_irqfd.gsi specifies the irqchip pin toggled by this event. When -an event is tiggered on the eventfd, an interrupt is injected into -the guest using the specified gsi pin. The irqfd is removed using -the KVM_IRQFD_FLAG_DEASSIGN flag, specifying both kvm_irqfd.fd -and kvm_irqfd.gsi. - - 5. The kvm_run structure ------------------------ diff --git a/trunk/Documentation/vm/frontswap.txt b/trunk/Documentation/vm/frontswap.txt deleted file mode 100644 index 37067cf455f4..000000000000 --- a/trunk/Documentation/vm/frontswap.txt +++ /dev/null @@ -1,278 +0,0 @@ -Frontswap provides a "transcendent memory" interface for swap pages. -In some environments, dramatic performance savings may be obtained because -swapped pages are saved in RAM (or a RAM-like device) instead of a swap disk. - -(Note, frontswap -- and cleancache (merged at 3.0) -- are the "frontends" -and the only necessary changes to the core kernel for transcendent memory; -all other supporting code -- the "backends" -- is implemented as drivers. -See the LWN.net article "Transcendent memory in a nutshell" for a detailed -overview of frontswap and related kernel parts: -https://lwn.net/Articles/454795/ ) - -Frontswap is so named because it can be thought of as the opposite of -a "backing" store for a swap device. The storage is assumed to be -a synchronous concurrency-safe page-oriented "pseudo-RAM device" conforming -to the requirements of transcendent memory (such as Xen's "tmem", or -in-kernel compressed memory, aka "zcache", or future RAM-like devices); -this pseudo-RAM device is not directly accessible or addressable by the -kernel and is of unknown and possibly time-varying size. The driver -links itself to frontswap by calling frontswap_register_ops to set the -frontswap_ops funcs appropriately and the functions it provides must -conform to certain policies as follows: - -An "init" prepares the device to receive frontswap pages associated -with the specified swap device number (aka "type"). A "store" will -copy the page to transcendent memory and associate it with the type and -offset associated with the page. A "load" will copy the page, if found, -from transcendent memory into kernel memory, but will NOT remove the page -from from transcendent memory. An "invalidate_page" will remove the page -from transcendent memory and an "invalidate_area" will remove ALL pages -associated with the swap type (e.g., like swapoff) and notify the "device" -to refuse further stores with that swap type. - -Once a page is successfully stored, a matching load on the page will normally -succeed. So when the kernel finds itself in a situation where it needs -to swap out a page, it first attempts to use frontswap. If the store returns -success, the data has been successfully saved to transcendent memory and -a disk write and, if the data is later read back, a disk read are avoided. -If a store returns failure, transcendent memory has rejected the data, and the -page can be written to swap as usual. - -If a backend chooses, frontswap can be configured as a "writethrough -cache" by calling frontswap_writethrough(). In this mode, the reduction -in swap device writes is lost (and also a non-trivial performance advantage) -in order to allow the backend to arbitrarily "reclaim" space used to -store frontswap pages to more completely manage its memory usage. - -Note that if a page is stored and the page already exists in transcendent memory -(a "duplicate" store), either the store succeeds and the data is overwritten, -or the store fails AND the page is invalidated. This ensures stale data may -never be obtained from frontswap. - -If properly configured, monitoring of frontswap is done via debugfs in -the /sys/kernel/debug/frontswap directory. The effectiveness of -frontswap can be measured (across all swap devices) with: - -failed_stores - how many store attempts have failed -loads - how many loads were attempted (all should succeed) -succ_stores - how many store attempts have succeeded -invalidates - how many invalidates were attempted - -A backend implementation may provide additional metrics. - -FAQ - -1) Where's the value? - -When a workload starts swapping, performance falls through the floor. -Frontswap significantly increases performance in many such workloads by -providing a clean, dynamic interface to read and write swap pages to -"transcendent memory" that is otherwise not directly addressable to the kernel. -This interface is ideal when data is transformed to a different form -and size (such as with compression) or secretly moved (as might be -useful for write-balancing for some RAM-like devices). Swap pages (and -evicted page-cache pages) are a great use for this kind of slower-than-RAM- -but-much-faster-than-disk "pseudo-RAM device" and the frontswap (and -cleancache) interface to transcendent memory provides a nice way to read -and write -- and indirectly "name" -- the pages. - -Frontswap -- and cleancache -- with a fairly small impact on the kernel, -provides a huge amount of flexibility for more dynamic, flexible RAM -utilization in various system configurations: - -In the single kernel case, aka "zcache", pages are compressed and -stored in local memory, thus increasing the total anonymous pages -that can be safely kept in RAM. Zcache essentially trades off CPU -cycles used in compression/decompression for better memory utilization. -Benchmarks have shown little or no impact when memory pressure is -low while providing a significant performance improvement (25%+) -on some workloads under high memory pressure. - -"RAMster" builds on zcache by adding "peer-to-peer" transcendent memory -support for clustered systems. Frontswap pages are locally compressed -as in zcache, but then "remotified" to another system's RAM. This -allows RAM to be dynamically load-balanced back-and-forth as needed, -i.e. when system A is overcommitted, it can swap to system B, and -vice versa. RAMster can also be configured as a memory server so -many servers in a cluster can swap, dynamically as needed, to a single -server configured with a large amount of RAM... without pre-configuring -how much of the RAM is available for each of the clients! - -In the virtual case, the whole point of virtualization is to statistically -multiplex physical resources acrosst the varying demands of multiple -virtual machines. This is really hard to do with RAM and efforts to do -it well with no kernel changes have essentially failed (except in some -well-publicized special-case workloads). -Specifically, the Xen Transcendent Memory backend allows otherwise -"fallow" hypervisor-owned RAM to not only be "time-shared" between multiple -virtual machines, but the pages can be compressed and deduplicated to -optimize RAM utilization. And when guest OS's are induced to surrender -underutilized RAM (e.g. with "selfballooning"), sudden unexpected -memory pressure may result in swapping; frontswap allows those pages -to be swapped to and from hypervisor RAM (if overall host system memory -conditions allow), thus mitigating the potentially awful performance impact -of unplanned swapping. - -A KVM implementation is underway and has been RFC'ed to lkml. And, -using frontswap, investigation is also underway on the use of NVM as -a memory extension technology. - -2) Sure there may be performance advantages in some situations, but - what's the space/time overhead of frontswap? - -If CONFIG_FRONTSWAP is disabled, every frontswap hook compiles into -nothingness and the only overhead is a few extra bytes per swapon'ed -swap device. If CONFIG_FRONTSWAP is enabled but no frontswap "backend" -registers, there is one extra global variable compared to zero for -every swap page read or written. If CONFIG_FRONTSWAP is enabled -AND a frontswap backend registers AND the backend fails every "store" -request (i.e. provides no memory despite claiming it might), -CPU overhead is still negligible -- and since every frontswap fail -precedes a swap page write-to-disk, the system is highly likely -to be I/O bound and using a small fraction of a percent of a CPU -will be irrelevant anyway. - -As for space, if CONFIG_FRONTSWAP is enabled AND a frontswap backend -registers, one bit is allocated for every swap page for every swap -device that is swapon'd. This is added to the EIGHT bits (which -was sixteen until about 2.6.34) that the kernel already allocates -for every swap page for every swap device that is swapon'd. (Hugh -Dickins has observed that frontswap could probably steal one of -the existing eight bits, but let's worry about that minor optimization -later.) For very large swap disks (which are rare) on a standard -4K pagesize, this is 1MB per 32GB swap. - -When swap pages are stored in transcendent memory instead of written -out to disk, there is a side effect that this may create more memory -pressure that can potentially outweigh the other advantages. A -backend, such as zcache, must implement policies to carefully (but -dynamically) manage memory limits to ensure this doesn't happen. - -3) OK, how about a quick overview of what this frontswap patch does - in terms that a kernel hacker can grok? - -Let's assume that a frontswap "backend" has registered during -kernel initialization; this registration indicates that this -frontswap backend has access to some "memory" that is not directly -accessible by the kernel. Exactly how much memory it provides is -entirely dynamic and random. - -Whenever a swap-device is swapon'd frontswap_init() is called, -passing the swap device number (aka "type") as a parameter. -This notifies frontswap to expect attempts to "store" swap pages -associated with that number. - -Whenever the swap subsystem is readying a page to write to a swap -device (c.f swap_writepage()), frontswap_store is called. Frontswap -consults with the frontswap backend and if the backend says it does NOT -have room, frontswap_store returns -1 and the kernel swaps the page -to the swap device as normal. Note that the response from the frontswap -backend is unpredictable to the kernel; it may choose to never accept a -page, it could accept every ninth page, or it might accept every -page. But if the backend does accept a page, the data from the page -has already been copied and associated with the type and offset, -and the backend guarantees the persistence of the data. In this case, -frontswap sets a bit in the "frontswap_map" for the swap device -corresponding to the page offset on the swap device to which it would -otherwise have written the data. - -When the swap subsystem needs to swap-in a page (swap_readpage()), -it first calls frontswap_load() which checks the frontswap_map to -see if the page was earlier accepted by the frontswap backend. If -it was, the page of data is filled from the frontswap backend and -the swap-in is complete. If not, the normal swap-in code is -executed to obtain the page of data from the real swap device. - -So every time the frontswap backend accepts a page, a swap device read -and (potentially) a swap device write are replaced by a "frontswap backend -store" and (possibly) a "frontswap backend loads", which are presumably much -faster. - -4) Can't frontswap be configured as a "special" swap device that is - just higher priority than any real swap device (e.g. like zswap, - or maybe swap-over-nbd/NFS)? - -No. First, the existing swap subsystem doesn't allow for any kind of -swap hierarchy. Perhaps it could be rewritten to accomodate a hierarchy, -but this would require fairly drastic changes. Even if it were -rewritten, the existing swap subsystem uses the block I/O layer which -assumes a swap device is fixed size and any page in it is linearly -addressable. Frontswap barely touches the existing swap subsystem, -and works around the constraints of the block I/O subsystem to provide -a great deal of flexibility and dynamicity. - -For example, the acceptance of any swap page by the frontswap backend is -entirely unpredictable. This is critical to the definition of frontswap -backends because it grants completely dynamic discretion to the -backend. In zcache, one cannot know a priori how compressible a page is. -"Poorly" compressible pages can be rejected, and "poorly" can itself be -defined dynamically depending on current memory constraints. - -Further, frontswap is entirely synchronous whereas a real swap -device is, by definition, asynchronous and uses block I/O. The -block I/O layer is not only unnecessary, but may perform "optimizations" -that are inappropriate for a RAM-oriented device including delaying -the write of some pages for a significant amount of time. Synchrony is -required to ensure the dynamicity of the backend and to avoid thorny race -conditions that would unnecessarily and greatly complicate frontswap -and/or the block I/O subsystem. That said, only the initial "store" -and "load" operations need be synchronous. A separate asynchronous thread -is free to manipulate the pages stored by frontswap. For example, -the "remotification" thread in RAMster uses standard asynchronous -kernel sockets to move compressed frontswap pages to a remote machine. -Similarly, a KVM guest-side implementation could do in-guest compression -and use "batched" hypercalls. - -In a virtualized environment, the dynamicity allows the hypervisor -(or host OS) to do "intelligent overcommit". For example, it can -choose to accept pages only until host-swapping might be imminent, -then force guests to do their own swapping. - -There is a downside to the transcendent memory specifications for -frontswap: Since any "store" might fail, there must always be a real -slot on a real swap device to swap the page. Thus frontswap must be -implemented as a "shadow" to every swapon'd device with the potential -capability of holding every page that the swap device might have held -and the possibility that it might hold no pages at all. This means -that frontswap cannot contain more pages than the total of swapon'd -swap devices. For example, if NO swap device is configured on some -installation, frontswap is useless. Swapless portable devices -can still use frontswap but a backend for such devices must configure -some kind of "ghost" swap device and ensure that it is never used. - -5) Why this weird definition about "duplicate stores"? If a page - has been previously successfully stored, can't it always be - successfully overwritten? - -Nearly always it can, but no, sometimes it cannot. Consider an example -where data is compressed and the original 4K page has been compressed -to 1K. Now an attempt is made to overwrite the page with data that -is non-compressible and so would take the entire 4K. But the backend -has no more space. In this case, the store must be rejected. Whenever -frontswap rejects a store that would overwrite, it also must invalidate -the old data and ensure that it is no longer accessible. Since the -swap subsystem then writes the new data to the read swap device, -this is the correct course of action to ensure coherency. - -6) What is frontswap_shrink for? - -When the (non-frontswap) swap subsystem swaps out a page to a real -swap device, that page is only taking up low-value pre-allocated disk -space. But if frontswap has placed a page in transcendent memory, that -page may be taking up valuable real estate. The frontswap_shrink -routine allows code outside of the swap subsystem to force pages out -of the memory managed by frontswap and back into kernel-addressable memory. -For example, in RAMster, a "suction driver" thread will attempt -to "repatriate" pages sent to a remote machine back to the local machine; -this is driven using the frontswap_shrink mechanism when memory pressure -subsides. - -7) Why does the frontswap patch create the new include file swapfile.h? - -The frontswap code depends on some swap-subsystem-internal data -structures that have, over the years, moved back and forth between -static and global. This seemed a reasonable compromise: Define -them as global but declare them in a new include file that isn't -included by the large number of source files that include swap.h. - -Dan Magenheimer, last updated April 9, 2012 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index fe643e7b9df6..55f0fda602ec 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -579,7 +579,7 @@ F: drivers/net/appletalk/ F: net/appletalk/ ARASAN COMPACT FLASH PATA CONTROLLER -M: Viresh Kumar +M: Viresh Kumar L: linux-ide@vger.kernel.org S: Maintained F: include/linux/pata_arasan_cf_data.h @@ -1077,7 +1077,7 @@ F: drivers/media/video/s5p-fimc/ ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT M: Kyungmin Park M: Kamil Debski -M: Jeongtae Park +M: Jeongtae Park L: linux-arm-kernel@lists.infradead.org L: linux-media@vger.kernel.org S: Maintained @@ -1646,11 +1646,11 @@ S: Maintained F: drivers/gpio/gpio-bt8xx.c BTRFS FILE SYSTEM -M: Chris Mason +M: Chris Mason L: linux-btrfs@vger.kernel.org W: http://btrfs.wiki.kernel.org/ Q: http://patchwork.kernel.org/project/linux-btrfs/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git S: Maintained F: Documentation/filesystems/btrfs.txt F: fs/btrfs/ @@ -1743,10 +1743,10 @@ F: include/linux/can/platform/ CAPABILITIES M: Serge Hallyn L: linux-security-module@vger.kernel.org -S: Supported +S: Supported F: include/linux/capability.h F: security/capability.c -F: security/commoncap.c +F: security/commoncap.c F: kernel/capability.c CELL BROADBAND ENGINE ARCHITECTURE @@ -1800,9 +1800,6 @@ F: include/linux/cfag12864b.h CFG80211 and NL80211 M: Johannes Berg L: linux-wireless@vger.kernel.org -W: http://wireless.kernel.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git S: Maintained F: include/linux/nl80211.h F: include/net/cfg80211.h @@ -2149,11 +2146,11 @@ S: Orphan F: drivers/net/wan/pc300* CYTTSP TOUCHSCREEN DRIVER -M: Javier Martinez Canillas -L: linux-input@vger.kernel.org -S: Maintained -F: drivers/input/touchscreen/cyttsp* -F: include/linux/input/cyttsp.h +M: Javier Martinez Canillas +L: linux-input@vger.kernel.org +S: Maintained +F: drivers/input/touchscreen/cyttsp* +F: include/linux/input/cyttsp.h DAMA SLAVE for AX.25 M: Joerg Reuter @@ -2273,7 +2270,7 @@ F: include/linux/device-mapper.h F: include/linux/dm-*.h DIOLAN U2C-12 I2C DRIVER -M: Guenter Roeck +M: Guenter Roeck L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/busses/i2c-diolan-u2c.c @@ -2933,13 +2930,6 @@ F: Documentation/power/freezing-of-tasks.txt F: include/linux/freezer.h F: kernel/freezer.c -FRONTSWAP API -M: Konrad Rzeszutek Wilk -L: linux-kernel@vger.kernel.org -S: Maintained -F: mm/frontswap.c -F: include/linux/frontswap.h - FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS M: David Howells L: linux-cachefs@redhat.com @@ -3148,7 +3138,7 @@ F: drivers/tty/hvc/ HARDWARE MONITORING M: Jean Delvare -M: Guenter Roeck +M: Guenter Roeck L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ @@ -3433,14 +3423,13 @@ S: Supported F: drivers/idle/i7300_idle.c IEEE 802.15.4 SUBSYSTEM -M: Alexander Smirnov M: Dmitry Eremin-Solenikov +M: Sergey Lapin L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://apps.sourceforge.net/trac/linux-zigbee T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git S: Maintained F: net/ieee802154/ -F: net/mac802154/ F: drivers/ieee802154/ IIO SUBSYSTEM AND DRIVERS @@ -4107,8 +4096,6 @@ F: drivers/scsi/53c700* LED SUBSYSTEM M: Bryan Wu M: Richard Purdie -L: linux-leds@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git S: Maintained F: drivers/leds/ F: include/linux/leds.h @@ -4353,8 +4340,7 @@ MAC80211 M: Johannes Berg L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git S: Maintained F: Documentation/networking/mac80211-injection.txt F: include/net/mac80211.h @@ -4365,8 +4351,7 @@ M: Stefano Brivio M: Mattias Nissler L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git S: Maintained F: net/mac80211/rc80211_pid* @@ -4426,13 +4411,6 @@ S: Orphan F: drivers/video/matrox/matroxfb_* F: include/linux/matroxfb.h -MAX16065 HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/max16065 -F: drivers/hwmon/max16065.c - MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: "Hans J. Koch" L: lm-sensors@lm-sensors.org @@ -4655,8 +4633,8 @@ L: netfilter@vger.kernel.org L: coreteam@netfilter.org W: http://www.netfilter.org/ W: http://www.iptables.org/ -T: git git://1984.lsi.us.es/nf -T: git git://1984.lsi.us.es/nf-next +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git S: Supported F: include/linux/netfilter* F: include/linux/netfilter/ @@ -4858,7 +4836,6 @@ M: Kevin Hilman L: linux-omap@vger.kernel.org S: Maintained F: arch/arm/*omap*/*pm* -F: drivers/cpufreq/omap-cpufreq.c OMAP POWERDOMAIN/CLOCKDOMAIN SOC ADAPTATION LAYER SUPPORT M: Rajendra Nayak @@ -5172,7 +5149,7 @@ F: drivers/leds/leds-pca9532.c F: include/linux/leds-pca9532.h PCA9541 I2C BUS MASTER SELECTOR DRIVER -M: Guenter Roeck +M: Guenter Roeck L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/muxes/i2c-mux-pca9541.c @@ -5192,7 +5169,7 @@ S: Maintained F: drivers/firmware/pcdp.* PCI ERROR RECOVERY -M: Linas Vepstas +M: Linas Vepstas L: linux-pci@vger.kernel.org S: Supported F: Documentation/PCI/pci-error-recovery.txt @@ -5298,7 +5275,7 @@ S: Maintained F: drivers/pinctrl/ PIN CONTROLLER - ST SPEAR -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -5322,7 +5299,7 @@ F: drivers/video/fb-puv3.c F: drivers/rtc/rtc-puv3.c PMBUS HARDWARE MONITORING DRIVERS -M: Guenter Roeck +M: Guenter Roeck L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ W: http://www.roeck-us.net/linux/drivers/ @@ -5565,7 +5542,7 @@ F: Documentation/networking/LICENSE.qla3xxx F: drivers/net/ethernet/qlogic/qla3xxx.* QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER -M: Jitendra Kalsaria +M: Anirban Chakraborty M: Sony Chacko M: linux-driver@qlogic.com L: netdev@vger.kernel.org @@ -5573,6 +5550,7 @@ S: Supported F: drivers/net/ethernet/qlogic/qlcnic/ QLOGIC QLGE 10Gb ETHERNET DRIVER +M: Anirban Chakraborty M: Jitendra Kalsaria M: Ron Mercer M: linux-driver@qlogic.com @@ -5717,9 +5695,6 @@ F: include/linux/remoteproc.h RFKILL M: Johannes Berg L: linux-wireless@vger.kernel.org -W: http://wireless.kernel.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git S: Maintained F: Documentation/rfkill.txt F: net/rfkill/ @@ -5874,7 +5849,7 @@ S: Maintained F: drivers/tty/serial SYNOPSYS DESIGNWARE DMAC DRIVER -M: Viresh Kumar +M: Viresh Kumar S: Maintained F: include/linux/dw_dmac.h F: drivers/dma/dw_dmac_regs.h @@ -5910,7 +5885,7 @@ M: Ingo Molnar M: Peter Zijlstra T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core S: Maintained -F: kernel/sched/ +F: kernel/sched* F: include/linux/sched.h SCORE ARCHITECTURE @@ -6022,7 +5997,7 @@ S: Maintained F: drivers/mmc/host/sdhci-s3c.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-mmc@vger.kernel.org S: Maintained @@ -6378,7 +6353,7 @@ S: Maintained F: include/linux/compiler.h SPEAR PLATFORM SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6387,7 +6362,7 @@ S: Maintained F: arch/arm/plat-spear/ SPEAR13XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6396,7 +6371,7 @@ S: Maintained F: arch/arm/mach-spear13xx/ SPEAR3XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6407,7 +6382,7 @@ F: arch/arm/mach-spear3xx/ SPEAR6XX MACHINE SUPPORT M: Rajeev Kumar M: Shiraz Hashim -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -6415,7 +6390,7 @@ S: Maintained F: arch/arm/mach-spear6xx/ SPEAR CLOCK FRAMEWORK SUPPORT -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -7316,11 +7291,11 @@ F: Documentation/DocBook/uio-howto.tmpl F: drivers/uio/ F: include/linux/uio*.h -UTIL-LINUX PACKAGE +UTIL-LINUX-NG PACKAGE M: Karel Zak -L: util-linux@vger.kernel.org -W: http://en.wikipedia.org/wiki/Util-linux -T: git git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git +L: util-linux-ng@vger.kernel.org +W: http://kernel.org/~kzak/util-linux-ng/ +T: git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git S: Maintained UVESAFB DRIVER @@ -7422,7 +7397,7 @@ F: include/linux/vlynq.h VME SUBSYSTEM M: Martyn Welch -M: Manohar Vanga +M: Manohar Vanga M: Greg Kroah-Hartman L: devel@driverdev.osuosl.org S: Maintained diff --git a/trunk/Makefile b/trunk/Makefile index 4bb09e1b1230..0d718ede9ea5 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Saber-toothed Squirrel # *DOCUMENTATION* @@ -561,8 +561,6 @@ else KBUILD_CFLAGS += -O2 endif -include $(srctree)/arch/$(SRCARCH)/Makefile - ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -573,6 +571,8 @@ KBUILD_CFLAGS += $(call cc-option,-fno-reorder-blocks,) \ $(call cc-option,-fno-partial-inlining) endif +include $(srctree)/arch/$(SRCARCH)/Makefile + ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index a91009c61870..b649c5904a4f 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -7,6 +7,7 @@ config ARM select HAVE_IDE if PCI || ISA || PCMCIA select HAVE_DMA_ATTRS select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7) + select CMA if (CPU_V6 || CPU_V6K || CPU_V7) select HAVE_MEMBLOCK select RTC_LIB select SYS_SUPPORTS_APM_EMULATION @@ -293,7 +294,6 @@ config ARCH_VERSATILE select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB - select NEED_MACH_IO_H if PCI select PLAT_VERSATILE select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_FPGA_IRQ @@ -589,7 +589,6 @@ config ARCH_ORION5X select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS - select NEED_MACH_IO_H select PLAT_ORION help Support for the following Marvell Orion 5x series SoCs: diff --git a/trunk/arch/arm/boot/dts/db8500.dtsi b/trunk/arch/arm/boot/dts/db8500.dtsi index ec2be92b270d..4ad5160018cb 100644 --- a/trunk/arch/arm/boot/dts/db8500.dtsi +++ b/trunk/arch/arm/boot/dts/db8500.dtsi @@ -206,74 +206,62 @@ // DB8500_REGULATOR_VAPE db8500_vape_reg: db8500_vape { - regulator-compatible = "db8500_vape"; regulator-name = "db8500-vape"; regulator-always-on; }; // DB8500_REGULATOR_VARM db8500_varm_reg: db8500_varm { - regulator-compatible = "db8500_varm"; regulator-name = "db8500-varm"; }; // DB8500_REGULATOR_VMODEM db8500_vmodem_reg: db8500_vmodem { - regulator-compatible = "db8500_vmodem"; regulator-name = "db8500-vmodem"; }; // DB8500_REGULATOR_VPLL db8500_vpll_reg: db8500_vpll { - regulator-compatible = "db8500_vpll"; regulator-name = "db8500-vpll"; }; // DB8500_REGULATOR_VSMPS1 db8500_vsmps1_reg: db8500_vsmps1 { - regulator-compatible = "db8500_vsmps1"; regulator-name = "db8500-vsmps1"; }; // DB8500_REGULATOR_VSMPS2 db8500_vsmps2_reg: db8500_vsmps2 { - regulator-compatible = "db8500_vsmps2"; regulator-name = "db8500-vsmps2"; }; // DB8500_REGULATOR_VSMPS3 db8500_vsmps3_reg: db8500_vsmps3 { - regulator-compatible = "db8500_vsmps3"; regulator-name = "db8500-vsmps3"; }; // DB8500_REGULATOR_VRF1 db8500_vrf1_reg: db8500_vrf1 { - regulator-compatible = "db8500_vrf1"; regulator-name = "db8500-vrf1"; }; // DB8500_REGULATOR_SWITCH_SVAMMDSP db8500_sva_mmdsp_reg: db8500_sva_mmdsp { - regulator-compatible = "db8500_sva_mmdsp"; regulator-name = "db8500-sva-mmdsp"; }; // DB8500_REGULATOR_SWITCH_SVAMMDSPRET db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret { - regulator-compatible = "db8500_sva_mmdsp_ret"; regulator-name = "db8500-sva-mmdsp-ret"; }; // DB8500_REGULATOR_SWITCH_SVAPIPE db8500_sva_pipe_reg: db8500_sva_pipe { - regulator-compatible = "db8500_sva_pipe"; regulator-name = "db8500_sva_pipe"; }; // DB8500_REGULATOR_SWITCH_SIAMMDSP db8500_sia_mmdsp_reg: db8500_sia_mmdsp { - regulator-compatible = "db8500_sia_mmdsp"; regulator-name = "db8500_sia_mmdsp"; }; @@ -284,45 +272,38 @@ // DB8500_REGULATOR_SWITCH_SIAPIPE db8500_sia_pipe_reg: db8500_sia_pipe { - regulator-compatible = "db8500_sia_pipe"; regulator-name = "db8500-sia-pipe"; }; // DB8500_REGULATOR_SWITCH_SGA db8500_sga_reg: db8500_sga { - regulator-compatible = "db8500_sga"; regulator-name = "db8500-sga"; vin-supply = <&db8500_vape_reg>; }; // DB8500_REGULATOR_SWITCH_B2R2_MCDE db8500_b2r2_mcde_reg: db8500_b2r2_mcde { - regulator-compatible = "db8500_b2r2_mcde"; regulator-name = "db8500-b2r2-mcde"; vin-supply = <&db8500_vape_reg>; }; // DB8500_REGULATOR_SWITCH_ESRAM12 db8500_esram12_reg: db8500_esram12 { - regulator-compatible = "db8500_esram12"; regulator-name = "db8500-esram12"; }; // DB8500_REGULATOR_SWITCH_ESRAM12RET db8500_esram12_ret_reg: db8500_esram12_ret { - regulator-compatible = "db8500_esram12_ret"; regulator-name = "db8500-esram12-ret"; }; // DB8500_REGULATOR_SWITCH_ESRAM34 db8500_esram34_reg: db8500_esram34 { - regulator-compatible = "db8500_esram34"; regulator-name = "db8500-esram34"; }; // DB8500_REGULATOR_SWITCH_ESRAM34RET db8500_esram34_ret_reg: db8500_esram34_ret { - regulator-compatible = "db8500_esram34_ret"; regulator-name = "db8500-esram34-ret"; }; }; @@ -337,7 +318,6 @@ // supplies to the display/camera ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { - regulator-compatible = "ab8500_ldo_aux1"; regulator-name = "V-DISPLAY"; regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2900000>; @@ -348,7 +328,6 @@ // supplies to the on-board eMMC ab8500_ldo_aux2_reg: ab8500_ldo_aux2 { - regulator-compatible = "ab8500_ldo_aux2"; regulator-name = "V-eMMC1"; regulator-min-microvolt = <1100000>; regulator-max-microvolt = <3300000>; @@ -356,7 +335,6 @@ // supply for VAUX3; SDcard slots ab8500_ldo_aux3_reg: ab8500_ldo_aux3 { - regulator-compatible = "ab8500_ldo_aux3"; regulator-name = "V-MMC-SD"; regulator-min-microvolt = <1100000>; regulator-max-microvolt = <3300000>; @@ -364,49 +342,41 @@ // supply for v-intcore12; VINTCORE12 LDO ab8500_ldo_initcore_reg: ab8500_ldo_initcore { - regulator-compatible = "ab8500_ldo_initcore"; regulator-name = "V-INTCORE"; }; // supply for tvout; gpadc; TVOUT LDO ab8500_ldo_tvout_reg: ab8500_ldo_tvout { - regulator-compatible = "ab8500_ldo_tvout"; regulator-name = "V-TVOUT"; }; // supply for ab8500-usb; USB LDO ab8500_ldo_usb_reg: ab8500_ldo_usb { - regulator-compatible = "ab8500_ldo_usb"; regulator-name = "dummy"; }; // supply for ab8500-vaudio; VAUDIO LDO ab8500_ldo_audio_reg: ab8500_ldo_audio { - regulator-compatible = "ab8500_ldo_audio"; regulator-name = "V-AUD"; }; // supply for v-anamic1 VAMic1-LDO ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 { - regulator-compatible = "ab8500_ldo_anamic1"; regulator-name = "V-AMIC1"; }; // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1 ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 { - regulator-compatible = "ab8500_ldo_amamic2"; regulator-name = "V-AMIC2"; }; // supply for v-dmic; VDMIC LDO ab8500_ldo_dmic_reg: ab8500_ldo_dmic { - regulator-compatible = "ab8500_ldo_dmic"; regulator-name = "V-DMIC"; }; // supply for U8500 CSI/DSI; VANA LDO ab8500_ldo_ana_reg: ab8500_ldo_ana { - regulator-compatible = "ab8500_ldo_ana"; regulator-name = "V-CSI/DSI"; }; }; diff --git a/trunk/arch/arm/boot/dts/mmp2-brownstone.dts b/trunk/arch/arm/boot/dts/mmp2-brownstone.dts index c9b4f27d191e..153a4b2d12b5 100644 --- a/trunk/arch/arm/boot/dts/mmp2-brownstone.dts +++ b/trunk/arch/arm/boot/dts/mmp2-brownstone.dts @@ -11,7 +11,7 @@ /include/ "mmp2.dtsi" / { - model = "Marvell MMP2 Brownstone Development Board"; + model = "Marvell MMP2 Aspenite Development Board"; compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; chosen { @@ -19,7 +19,7 @@ }; memory { - reg = <0x00000000 0x08000000>; + reg = <0x00000000 0x04000000>; }; soc { diff --git a/trunk/arch/arm/boot/dts/omap2.dtsi b/trunk/arch/arm/boot/dts/omap2.dtsi index 581cb081cb0f..f2ab4ea7cc0e 100644 --- a/trunk/arch/arm/boot/dts/omap2.dtsi +++ b/trunk/arch/arm/boot/dts/omap2.dtsi @@ -44,8 +44,6 @@ compatible = "ti,omap2-intc"; interrupt-controller; #interrupt-cells = <1>; - ti,intc-size = <96>; - reg = <0x480FE000 0x1000>; }; uart1: serial@4806a000 { diff --git a/trunk/arch/arm/boot/dts/spear1310-evb.dts b/trunk/arch/arm/boot/dts/spear1310-evb.dts index dd4358bc26e2..8314e4171884 100644 --- a/trunk/arch/arm/boot/dts/spear1310-evb.dts +++ b/trunk/arch/arm/boot/dts/spear1310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr1310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear1310.dtsi b/trunk/arch/arm/boot/dts/spear1310.dtsi index 419ea7413d23..9e61da404d57 100644 --- a/trunk/arch/arm/boot/dts/spear1310.dtsi +++ b/trunk/arch/arm/boot/dts/spear1310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr1310 SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear1340-evb.dts b/trunk/arch/arm/boot/dts/spear1340-evb.dts index c9a54e06fb68..0d8472e5ab9f 100644 --- a/trunk/arch/arm/boot/dts/spear1340-evb.dts +++ b/trunk/arch/arm/boot/dts/spear1340-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr1340 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear1340.dtsi b/trunk/arch/arm/boot/dts/spear1340.dtsi index d71fe2a68f09..a26fc47a55e8 100644 --- a/trunk/arch/arm/boot/dts/spear1340.dtsi +++ b/trunk/arch/arm/boot/dts/spear1340.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr1340 SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear13xx.dtsi b/trunk/arch/arm/boot/dts/spear13xx.dtsi index f7b84aced654..1f8e1e1481df 100644 --- a/trunk/arch/arm/boot/dts/spear13xx.dtsi +++ b/trunk/arch/arm/boot/dts/spear13xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr13xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -43,8 +43,8 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 6 0x04 - 0 7 0x04>; + interrupts = <0 8 0x04 + 0 9 0x04>; }; L2: l2-cache { @@ -119,8 +119,8 @@ gmac0: eth@e2000000 { compatible = "st,spear600-gmac"; reg = <0xe2000000 0x8000>; - interrupts = <0 33 0x4 - 0 34 0x4>; + interrupts = <0 23 0x4 + 0 24 0x4>; interrupt-names = "macirq", "eth_wake_irq"; status = "disabled"; }; @@ -202,7 +202,6 @@ kbd@e0300000 { compatible = "st,spear300-kbd"; reg = <0xe0300000 0x1000>; - interrupts = <0 52 0x4>; status = "disabled"; }; @@ -225,7 +224,7 @@ serial@e0000000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xe0000000 0x1000>; - interrupts = <0 35 0x4>; + interrupts = <0 36 0x4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/spear300-evb.dts b/trunk/arch/arm/boot/dts/spear300-evb.dts index d71b8d581e3d..fc82b1a26458 100644 --- a/trunk/arch/arm/boot/dts/spear300-evb.dts +++ b/trunk/arch/arm/boot/dts/spear300-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear300.dtsi b/trunk/arch/arm/boot/dts/spear300.dtsi index ed3627c116cc..01c5e358fdb2 100644 --- a/trunk/arch/arm/boot/dts/spear300.dtsi +++ b/trunk/arch/arm/boot/dts/spear300.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear310-evb.dts b/trunk/arch/arm/boot/dts/spear310-evb.dts index b00544e0cd5d..dc5e2d445a93 100644 --- a/trunk/arch/arm/boot/dts/spear310-evb.dts +++ b/trunk/arch/arm/boot/dts/spear310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear310.dtsi b/trunk/arch/arm/boot/dts/spear310.dtsi index 62fc4fb3e5f9..e47081c494d9 100644 --- a/trunk/arch/arm/boot/dts/spear310.dtsi +++ b/trunk/arch/arm/boot/dts/spear310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear320-evb.dts b/trunk/arch/arm/boot/dts/spear320-evb.dts index e4e912f95024..6308fa3bec1e 100644 --- a/trunk/arch/arm/boot/dts/spear320-evb.dts +++ b/trunk/arch/arm/boot/dts/spear320-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -15,8 +15,8 @@ /include/ "spear320.dtsi" / { - model = "ST SPEAr320 Evaluation Board"; - compatible = "st,spear320-evb", "st,spear320"; + model = "ST SPEAr300 Evaluation Board"; + compatible = "st,spear300-evb", "st,spear300"; #address-cells = <1>; #size-cells = <1>; @@ -26,7 +26,7 @@ ahb { pinmux@b3000000 { - st,pinmux-mode = <4>; + st,pinmux-mode = <3>; pinctrl-names = "default"; pinctrl-0 = <&state_default>; diff --git a/trunk/arch/arm/boot/dts/spear320.dtsi b/trunk/arch/arm/boot/dts/spear320.dtsi index 1f49d69595a0..5372ca399b1f 100644 --- a/trunk/arch/arm/boot/dts/spear320.dtsi +++ b/trunk/arch/arm/boot/dts/spear320.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear3xx.dtsi b/trunk/arch/arm/boot/dts/spear3xx.dtsi index 3a8bb5736928..91072553963f 100644 --- a/trunk/arch/arm/boot/dts/spear3xx.dtsi +++ b/trunk/arch/arm/boot/dts/spear3xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr3xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear600.dtsi b/trunk/arch/arm/boot/dts/spear600.dtsi index a3c36e47d7ef..089f0a42c50e 100644 --- a/trunk/arch/arm/boot/dts/spear600.dtsi +++ b/trunk/arch/arm/boot/dts/spear600.dtsi @@ -181,7 +181,6 @@ timer@f0000000 { compatible = "st,spear-timer"; reg = <0xf0000000 0x400>; - interrupt-parent = <&vic0>; interrupts = <16>; }; }; diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index aa07f5938f05..9d7eb530f95f 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -366,8 +366,8 @@ static int __dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, struct safe_buffer *buf; unsigned long off; - dev_dbg(dev, "%s(dma=%#x,sz=%zx,dir=%x)\n", - __func__, addr, sz, dir); + dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n", + __func__, addr, off, sz, dir); buf = find_safe_buffer_dev(dev, addr, __func__); if (!buf) @@ -377,8 +377,8 @@ static int __dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, BUG_ON(buf->direction != dir); - dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x off=%#lx) mapped to %p (dma=%#x)\n", - __func__, buf->ptr, virt_to_dma(dev, buf->ptr), off, + dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", + __func__, buf->ptr, virt_to_dma(dev, buf->ptr), buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); @@ -406,8 +406,8 @@ static int __dmabounce_sync_for_device(struct device *dev, dma_addr_t addr, struct safe_buffer *buf; unsigned long off; - dev_dbg(dev, "%s(dma=%#x,sz=%zx,dir=%x)\n", - __func__, addr, sz, dir); + dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n", + __func__, addr, off, sz, dir); buf = find_safe_buffer_dev(dev, addr, __func__); if (!buf) @@ -417,8 +417,8 @@ static int __dmabounce_sync_for_device(struct device *dev, dma_addr_t addr, BUG_ON(buf->direction != dir); - dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x off=%#lx) mapped to %p (dma=%#x)\n", - __func__, buf->ptr, virt_to_dma(dev, buf->ptr), off, + dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", + __func__, buf->ptr, virt_to_dma(dev, buf->ptr), buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); diff --git a/trunk/arch/arm/configs/omap2plus_defconfig b/trunk/arch/arm/configs/omap2plus_defconfig index 11828e632532..9854ff4279e0 100644 --- a/trunk/arch/arm/configs/omap2plus_defconfig +++ b/trunk/arch/arm/configs/omap2plus_defconfig @@ -176,6 +176,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y CONFIG_USB_LIBUSUAL=y diff --git a/trunk/arch/arm/include/asm/atomic.h b/trunk/arch/arm/include/asm/atomic.h index c79f61faa3a5..68374ba6a943 100644 --- a/trunk/arch/arm/include/asm/atomic.h +++ b/trunk/arch/arm/include/asm/atomic.h @@ -243,7 +243,7 @@ typedef struct { #define ATOMIC64_INIT(i) { (i) } -static inline u64 atomic64_read(const atomic64_t *v) +static inline u64 atomic64_read(atomic64_t *v) { u64 result; diff --git a/trunk/arch/arm/include/asm/domain.h b/trunk/arch/arm/include/asm/domain.h index 6ddbe446425e..3d2220498abc 100644 --- a/trunk/arch/arm/include/asm/domain.h +++ b/trunk/arch/arm/include/asm/domain.h @@ -60,13 +60,13 @@ #ifndef __ASSEMBLY__ #ifdef CONFIG_CPU_USE_DOMAINS -static inline void set_domain(unsigned val) -{ - asm volatile( - "mcr p15, 0, %0, c3, c0 @ set domain" - : : "r" (val)); - isb(); -} +#define set_domain(x) \ + do { \ + __asm__ __volatile__( \ + "mcr p15, 0, %0, c3, c0 @ set domain" \ + : : "r" (x)); \ + isb(); \ + } while (0) #define modify_domain(dom,type) \ do { \ @@ -78,8 +78,8 @@ static inline void set_domain(unsigned val) } while (0) #else -static inline void set_domain(unsigned val) { } -static inline void modify_domain(unsigned dom, unsigned type) { } +#define set_domain(x) do { } while (0) +#define modify_domain(dom,type) do { } while (0) #endif /* diff --git a/trunk/arch/arm/include/asm/futex.h b/trunk/arch/arm/include/asm/futex.h index e42cf597f6e6..7be54690aeec 100644 --- a/trunk/arch/arm/include/asm/futex.h +++ b/trunk/arch/arm/include/asm/futex.h @@ -19,7 +19,6 @@ " .long 1b, 4f, 2b, 4f\n" \ " .popsection\n" \ " .pushsection .fixup,\"ax\"\n" \ - " .align 2\n" \ "4: mov %0, " err_reg "\n" \ " b 3b\n" \ " .popsection" diff --git a/trunk/arch/arm/include/asm/hardware/sp810.h b/trunk/arch/arm/include/asm/hardware/sp810.h index 6b9b077d86b3..e0d1c0cfa548 100644 --- a/trunk/arch/arm/include/asm/hardware/sp810.h +++ b/trunk/arch/arm/include/asm/hardware/sp810.h @@ -4,7 +4,7 @@ * ARM PrimeXsys System Controller SP810 header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index af7b0bda3355..b79f8e97f775 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 +#define TIF_SYSCALL_RESTARTSYS 10 #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ @@ -163,9 +164,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS) /* Checks for any syscall work in entry-common.S */ -#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ + _TIF_SYSCALL_RESTARTSYS) /* * Change these and you break ASM code in entry-common.S diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 0d1851ca6eb9..437f0c426517 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -495,7 +495,6 @@ ENDPROC(__und_usr) * The out of line fixup for the ldrt above. */ .pushsection .fixup, "ax" - .align 2 4: mov pc, r9 .popsection .pushsection __ex_table,"a" diff --git a/trunk/arch/arm/kernel/kprobes-test-arm.c b/trunk/arch/arm/kernel/kprobes-test-arm.c index 38c1a3b103a0..ba32b393b3f0 100644 --- a/trunk/arch/arm/kernel/kprobes-test-arm.c +++ b/trunk/arch/arm/kernel/kprobes-test-arm.c @@ -187,8 +187,8 @@ void kprobe_arm_test_cases(void) TEST_BF_R ("mov pc, r",0,2f,"") TEST_BF_RR("mov pc, r",0,2f,", asl r",1,0,"") TEST_BB( "sub pc, pc, #1b-2b+8") -#if __LINUX_ARM_ARCH__ == 6 && !defined(CONFIG_CPU_V7) - TEST_BB( "sub pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before and after ARMv6 */ +#if __LINUX_ARM_ARCH__ >= 6 + TEST_BB( "sub pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before ARMv6 */ #endif TEST_BB_R( "sub pc, pc, r",14, 1f-2f+8,"") TEST_BB_R( "rsb pc, r",14,1f-2f+8,", pc") diff --git a/trunk/arch/arm/kernel/kprobes-thumb.c b/trunk/arch/arm/kernel/kprobes-thumb.c index 6123daf397a7..8f96ec778e8d 100644 --- a/trunk/arch/arm/kernel/kprobes-thumb.c +++ b/trunk/arch/arm/kernel/kprobes-thumb.c @@ -660,7 +660,7 @@ static const union decode_item t32_table_1111_100x[] = { /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ - DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, + DECODE_EMULATEX (0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, REGS(PC, NOSPPCX, 0, 0, 0)), /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index a02eada3aa5d..186c8cb982c5 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -503,7 +503,7 @@ __hw_perf_event_init(struct perf_event *event) event_requires_mode_exclusion(&event->attr)) { pr_debug("ARM performance counters do not support " "mode exclusion\n"); - return -EOPNOTSUPP; + return -EPERM; } /* diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index 14e38261cd31..5700a7ae7f0b 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -917,6 +918,8 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); + if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS)) + scno = __NR_restart_syscall - __NR_SYSCALL_BASE; if (!test_thread_flag(TIF_SYSCALL_TRACE)) return scno; diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 536c5d6b340b..fd2392a17ac1 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -27,7 +27,6 @@ */ #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) -#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) /* * With EABI, the syscall number has to be loaded into r7. @@ -47,18 +46,6 @@ const unsigned long sigreturn_codes[7] = { MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, }; -/* - * Either we support OABI only, or we have EABI with the OABI - * compat layer enabled. In the later case we don't know if - * user space is EABI or not, and if not we must not clobber r7. - * Always using the OABI syscall solves that issue and works for - * all those cases. - */ -const unsigned long syscall_restart_code[2] = { - SWI_SYS_RESTART, /* swi __NR_restart_syscall */ - 0xe49df004, /* ldr pc, [sp], #4 */ -}; - /* * atomically swap in the new signal mask, and wait for a signal. */ @@ -605,12 +592,10 @@ static void do_signal(struct pt_regs *regs, int syscall) case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: + case -ERESTART_RESTARTBLOCK: regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_pc = restart_addr; break; - case -ERESTART_RESTARTBLOCK: - regs->ARM_r0 = -EINTR; - break; } } @@ -626,12 +611,14 @@ static void do_signal(struct pt_regs *regs, int syscall) * debugger has chosen to restart at a different PC. */ if (regs->ARM_pc == restart_addr) { - if (retval == -ERESTARTNOHAND + if (retval == -ERESTARTNOHAND || + retval == -ERESTART_RESTARTBLOCK || (retval == -ERESTARTSYS && !(ka.sa.sa_flags & SA_RESTART))) { regs->ARM_r0 = -EINTR; regs->ARM_pc = continue_addr; } + clear_thread_flag(TIF_SYSCALL_RESTARTSYS); } handle_signal(signr, &ka, &info, regs); @@ -645,29 +632,8 @@ static void do_signal(struct pt_regs *regs, int syscall) * ignore the restart. */ if (retval == -ERESTART_RESTARTBLOCK - && regs->ARM_pc == continue_addr) { - if (thumb_mode(regs)) { - regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; - regs->ARM_pc -= 2; - } else { -#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) - regs->ARM_r7 = __NR_restart_syscall; - regs->ARM_pc -= 4; -#else - u32 __user *usp; - - regs->ARM_sp -= 4; - usp = (u32 __user *)regs->ARM_sp; - - if (put_user(regs->ARM_pc, usp) == 0) { - regs->ARM_pc = KERN_RESTART_CODE; - } else { - regs->ARM_sp += 4; - force_sigsegv(0, current); - } -#endif - } - } + && regs->ARM_pc == restart_addr) + set_thread_flag(TIF_SYSCALL_RESTARTSYS); } restore_saved_sigmask(); diff --git a/trunk/arch/arm/kernel/signal.h b/trunk/arch/arm/kernel/signal.h index 6fcfe8398aa4..5ff067b7c752 100644 --- a/trunk/arch/arm/kernel/signal.h +++ b/trunk/arch/arm/kernel/signal.h @@ -8,7 +8,5 @@ * published by the Free Software Foundation. */ #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) -#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) extern const unsigned long sigreturn_codes[7]; -extern const unsigned long syscall_restart_code[2]; diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 3647170e9a16..4928d89758f4 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -820,8 +820,6 @@ void __init early_trap_init(void *vectors_base) */ memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), sigreturn_codes, sizeof(sigreturn_codes)); - memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE), - syscall_restart_code, sizeof(syscall_restart_code)); flush_icache_range(vectors, vectors + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 36ff15bbfdd4..43a31fb06318 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -183,9 +183,7 @@ SECTIONS } #endif -#ifdef CONFIG_SMP PERCPU_SECTION(L1_CACHE_BYTES) -#endif #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ diff --git a/trunk/arch/arm/mach-dove/include/mach/bridge-regs.h b/trunk/arch/arm/mach-dove/include/mach/bridge-regs.h index f953bb54aa9d..226949dc4ac0 100644 --- a/trunk/arch/arm/mach-dove/include/mach/bridge-regs.h +++ b/trunk/arch/arm/mach-dove/include/mach/bridge-regs.h @@ -50,6 +50,5 @@ #define POWER_MANAGEMENT (BRIDGE_VIRT_BASE | 0x011c) #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) -#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300) #endif diff --git a/trunk/arch/arm/mach-dove/include/mach/dove.h b/trunk/arch/arm/mach-dove/include/mach/dove.h index d52b0ef313b7..ad1165d488c1 100644 --- a/trunk/arch/arm/mach-dove/include/mach/dove.h +++ b/trunk/arch/arm/mach-dove/include/mach/dove.h @@ -78,7 +78,6 @@ /* North-South Bridge */ #define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x20000) -#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x20000) /* Cryptographic Engine */ #define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x30000) diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index 6f6d13f91e4c..573be57d3d28 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -212,7 +212,7 @@ config MACH_SMDKV310 select EXYNOS_DEV_SYSMMU select EXYNOS4_DEV_AHCI select SAMSUNG_DEV_KEYPAD - select EXYNOS_DEV_DMA + select EXYNOS4_DEV_DMA select SAMSUNG_DEV_PWM select EXYNOS4_DEV_USB_OHCI select EXYNOS4_SETUP_FIMD0 @@ -264,7 +264,7 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_ONENAND select S5P_DEV_TV select EXYNOS_DEV_SYSMMU - select EXYNOS_DEV_DMA + select EXYNOS4_DEV_DMA select EXYNOS_DEV_DRM select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 @@ -303,7 +303,7 @@ config MACH_NURI select S5P_DEV_MFC select S5P_DEV_USB_EHCI select S5P_SETUP_MIPIPHY - select EXYNOS_DEV_DMA + select EXYNOS4_DEV_DMA select EXYNOS_DEV_DRM select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMD0 @@ -341,7 +341,7 @@ config MACH_ORIGEN select SAMSUNG_DEV_PWM select EXYNOS_DEV_DRM select EXYNOS_DEV_SYSMMU - select EXYNOS_DEV_DMA + select EXYNOS4_DEV_DMA select EXYNOS4_DEV_USB_OHCI select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_SDHCI diff --git a/trunk/arch/arm/mach-exynos/pm_domains.c b/trunk/arch/arm/mach-exynos/pm_domains.c index 373c3c00d24c..e9fafcf163de 100644 --- a/trunk/arch/arm/mach-exynos/pm_domains.c +++ b/trunk/arch/arm/mach-exynos/pm_domains.c @@ -119,9 +119,7 @@ static __init void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd) { if (pdev->dev.bus) { - if (!pm_genpd_add_device(&pd->pd, &pdev->dev)) - pm_genpd_dev_need_restore(&pdev->dev, true); - else + if (pm_genpd_add_device(&pd->pd, &pdev->dev)) pr_info("%s: error in adding %s device to %s power" "domain\n", __func__, dev_name(&pdev->dev), pd->name); @@ -153,12 +151,9 @@ static __init int exynos4_pm_init_power_domain(void) if (of_have_populated_dt()) return exynos_pm_dt_parse_domains(); - for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++) { - struct exynos_pm_domain *pd = exynos4_pm_domains[idx]; - int on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN; - - pm_genpd_init(&pd->pd, NULL, !on); - } + for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++) + pm_genpd_init(&exynos4_pm_domains[idx]->pd, NULL, + exynos4_pm_domains[idx]->is_off); #ifdef CONFIG_S5P_DEV_FIMD0 exynos_pm_add_dev_to_genpd(&s5p_device_fimd0, &exynos4_pd_lcd0); diff --git a/trunk/arch/arm/mach-highbank/Makefile b/trunk/arch/arm/mach-highbank/Makefile index ded4652ada80..f8437dd238c2 100644 --- a/trunk/arch/arm/mach-highbank/Makefile +++ b/trunk/arch/arm/mach-highbank/Makefile @@ -1,8 +1,4 @@ -obj-y := clock.o highbank.o system.o smc.o - -plus_sec := $(call as-instr,.arch_extension sec,+sec) -AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) - +obj-y := clock.o highbank.o system.o obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/trunk/arch/arm/mach-highbank/core.h b/trunk/arch/arm/mach-highbank/core.h index 141ed5171826..d8e2d0be64ac 100644 --- a/trunk/arch/arm/mach-highbank/core.h +++ b/trunk/arch/arm/mach-highbank/core.h @@ -8,4 +8,3 @@ extern void highbank_lluart_map_io(void); static inline void highbank_lluart_map_io(void) {} #endif -extern void highbank_smc1(int fn, int arg); diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c index 8777612b1a42..410a112bb52e 100644 --- a/trunk/arch/arm/mach-highbank/highbank.c +++ b/trunk/arch/arm/mach-highbank/highbank.c @@ -85,24 +85,10 @@ const static struct of_device_id irq_match[] = { {} }; -#ifdef CONFIG_CACHE_L2X0 -static void highbank_l2x0_disable(void) -{ - /* Disable PL310 L2 Cache controller */ - highbank_smc1(0x102, 0x0); -} -#endif - static void __init highbank_init_irq(void) { of_irq_init(irq_match); - -#ifdef CONFIG_CACHE_L2X0 - /* Enable PL310 L2 Cache controller */ - highbank_smc1(0x102, 0x1); l2x0_of_init(0, ~0UL); - outer_cache.disable = highbank_l2x0_disable; -#endif } static void __init highbank_timer_init(void) diff --git a/trunk/arch/arm/mach-highbank/smc.S b/trunk/arch/arm/mach-highbank/smc.S deleted file mode 100644 index 407d17baaaa9..000000000000 --- a/trunk/arch/arm/mach-highbank/smc.S +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copied from omap44xx-smc.S Copyright (C) 2010 Texas Instruments, Inc. - * Copyright 2012 Calxeda, 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 - -/* - * This is common routine to manage secure monitor API - * used to modify the PL310 secure registers. - * 'r0' contains the value to be modified and 'r12' contains - * the monitor API number. - * Function signature : void highbank_smc1(u32 fn, u32 arg) - */ - -ENTRY(highbank_smc1) - stmfd sp!, {r4-r11, lr} - mov r12, r0 - mov r0, r1 - dsb - smc #0 - ldmfd sp!, {r4-r11, pc} -ENDPROC(highbank_smc1) diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index eff4db5de0dd..0021f726b153 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -477,7 +477,6 @@ config MACH_MX31_3DS select IMX_HAVE_PLATFORM_IMX2_WDT select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_KEYPAD - select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_IPU_CORE select IMX_HAVE_PLATFORM_MXC_EHCI diff --git a/trunk/arch/arm/mach-imx/clk-imx1.c b/trunk/arch/arm/mach-imx/clk-imx1.c index 516ddee1948e..0f0beb580b73 100644 --- a/trunk/arch/arm/mach-imx/clk-imx1.c +++ b/trunk/arch/arm/mach-imx/clk-imx1.c @@ -108,7 +108,8 @@ int __init mx1_clocks_init(unsigned long fref) clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0"); clk_register_clkdev(clk[clko], "clko", NULL); - mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); + mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), + MX1_TIM1_INT); return 0; } diff --git a/trunk/arch/arm/mach-imx/clk-imx21.c b/trunk/arch/arm/mach-imx/clk-imx21.c index ea13e61bd5f3..4e4f384ee8dd 100644 --- a/trunk/arch/arm/mach-imx/clk-imx21.c +++ b/trunk/arch/arm/mach-imx/clk-imx21.c @@ -180,7 +180,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL); clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL); - mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); - + mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), + MX21_INT_GPT1); return 0; } diff --git a/trunk/arch/arm/mach-imx/clk-imx25.c b/trunk/arch/arm/mach-imx/clk-imx25.c index fdd8cc87c9fe..d9833bb5fd61 100644 --- a/trunk/arch/arm/mach-imx/clk-imx25.c +++ b/trunk/arch/arm/mach-imx/clk-imx25.c @@ -243,6 +243,6 @@ int __init mx25_clocks_init(void) clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma"); clk_register_clkdev(clk[iim_ipg], "iim", NULL); - mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); + mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); return 0; } diff --git a/trunk/arch/arm/mach-imx/clk-imx27.c b/trunk/arch/arm/mach-imx/clk-imx27.c index 295cbd7c08dc..50a7ebd8d1b2 100644 --- a/trunk/arch/arm/mach-imx/clk-imx27.c +++ b/trunk/arch/arm/mach-imx/clk-imx27.c @@ -263,7 +263,8 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0"); clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1"); - mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); + mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), + MX27_INT_GPT1); clk_prepare_enable(clk[emi_ahb_gate]); diff --git a/trunk/arch/arm/mach-imx/clk-imx31.c b/trunk/arch/arm/mach-imx/clk-imx31.c index c9a06d800f8e..a854b9cae5ea 100644 --- a/trunk/arch/arm/mach-imx/clk-imx31.c +++ b/trunk/arch/arm/mach-imx/clk-imx31.c @@ -175,7 +175,8 @@ int __init mx31_clocks_init(unsigned long fref) mx31_revision(); clk_disable_unprepare(clk[iim_gate]); - mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); + mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), + MX31_INT_GPT); return 0; } diff --git a/trunk/arch/arm/mach-imx/clk-imx35.c b/trunk/arch/arm/mach-imx/clk-imx35.c index c6422fb10bae..a9e60bf7dd75 100644 --- a/trunk/arch/arm/mach-imx/clk-imx35.c +++ b/trunk/arch/arm/mach-imx/clk-imx35.c @@ -201,6 +201,7 @@ int __init mx35_clocks_init() pr_err("i.MX35 clk %d: register failed with %ld\n", i, PTR_ERR(clk[i])); + clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); @@ -263,20 +264,14 @@ int __init mx35_clocks_init() clk_prepare_enable(clk[iim_gate]); clk_prepare_enable(clk[emi_gate]); - /* - * SCC is needed to boot via mmc after a watchdog reset. The clock code - * before conversion to common clk also enabled UART1 (which isn't - * handled here and not needed for mmc) and IIM (which is enabled - * unconditionally above). - */ - clk_prepare_enable(clk[scc_gate]); - imx_print_silicon_rev("i.MX35", mx35_revision()); #ifdef CONFIG_MXC_USE_EPIT - epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); + epit_timer_init(&epit1_clk, + MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); #else - mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); + mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), + MX35_INT_GPT); #endif return 0; diff --git a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c index a2200c77bf70..fcd94f3b0f0e 100644 --- a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c @@ -104,12 +104,12 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, main_bus_sel, ARRAY_SIZE(main_bus_sel)); - clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, + clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCDR, 1, 1, per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); - clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, + clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCDR, 1, 0, per_root_sel, ARRAY_SIZE(per_root_sel)); clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); @@ -172,7 +172,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12); clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16); - clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per_root", MXC_CCM_CCGR2, 18); + clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", MXC_CCM_CCGR2, 18); clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); @@ -366,7 +366,8 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_b_podf], 166250000); /* System timer */ - mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT); + mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), + MX51_INT_GPT); clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX51", mx51_revision()); @@ -451,7 +452,8 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_b_podf], 200000000); /* System timer */ - mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT); + mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), + MX53_INT_GPT); clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX53", mx53_revision()); diff --git a/trunk/arch/arm/mach-imx/clk-imx6q.c b/trunk/arch/arm/mach-imx/clk-imx6q.c index e1a17ac7b3b4..cab02d0a15d6 100644 --- a/trunk/arch/arm/mach-imx/clk-imx6q.c +++ b/trunk/arch/arm/mach-imx/clk-imx6q.c @@ -122,6 +122,10 @@ static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; +static const char * const clks_init_on[] __initconst = { + "mmdc_ch0_axi", "mmdc_ch1_axi", "usboh3", +}; + enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, pll3_pfd0_720m, pll3_pfd1_540m, pll3_pfd2_508m, pll3_pfd3_454m, @@ -152,20 +156,16 @@ enum mx6q_clks { ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3, usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, - ssi2_ipg, ssi3_ipg, rom, - clk_max + ssi2_ipg, ssi3_ipg, clk_max }; static struct clk *clk[clk_max]; -static enum mx6q_clks const clks_init_on[] __initconst = { - mmdc_ch0_axi, rom, -}; - int __init mx6q_clocks_init(void) { struct device_node *np; void __iomem *base; + struct clk *c; int i, irq; clk[dummy] = imx_clk_fixed("dummy", 0); @@ -365,7 +365,6 @@ int __init mx6q_clocks_init(void) clk[gpmi_bch] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); - clk[rom] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); @@ -425,14 +424,21 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[ahb], "ahb", NULL); clk_register_clkdev(clk[cko1], "cko1", NULL); - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) - clk_prepare_enable(clk[clks_init_on[i]]); + for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) { + c = clk_get_sys(clks_init_on[i], NULL); + if (IS_ERR(c)) { + pr_err("%s: failed to get clk %s", __func__, + clks_init_on[i]); + return PTR_ERR(c); + } + clk_prepare_enable(c); + } np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); WARN_ON(!base); irq = irq_of_parse_and_map(np, 0); - mxc_timer_init(base, irq); + mxc_timer_init(NULL, base, irq); return 0; } diff --git a/trunk/arch/arm/mach-imx/clk-pllv2.c b/trunk/arch/arm/mach-imx/clk-pllv2.c index 0440379e3628..4685919deb63 100644 --- a/trunk/arch/arm/mach-imx/clk-pllv2.c +++ b/trunk/arch/arm/mach-imx/clk-pllv2.c @@ -74,15 +74,30 @@ struct clk_pllv2 { void __iomem *base; }; -static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, - u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) +static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) { long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dbl; + unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; + void __iomem *pllbase; s64 temp; + struct clk_pllv2 *pll = to_clk_pllv2(hw); + + pllbase = pll->base; + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; + if (pll_hfsm == 0) { + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + } else { + dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); + } pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; mfi = (mfi <= 5) ? 5 : mfi; @@ -108,30 +123,18 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, return temp; } -static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, +static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u32 dp_op, dp_mfd, dp_mfn, dp_ctl; - void __iomem *pllbase; struct clk_pllv2 *pll = to_clk_pllv2(hw); - - pllbase = pll->base; - - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - - return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn); -} - -static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, - u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn) -{ u32 reg; + void __iomem *pllbase; long mfi, pdf, mfn, mfd = 999999; s64 temp64; unsigned long quad_parent_rate; + unsigned long pll_hfsm, dp_ctl; + + pllbase = pll->base; quad_parent_rate = 4 * parent_rate; pdf = mfi = -1; @@ -141,41 +144,25 @@ static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, return -EINVAL; pdf--; - temp64 = rate * (pdf + 1) - quad_parent_rate * mfi; - do_div(temp64, quad_parent_rate / 1000000); + temp64 = rate * (pdf+1) - quad_parent_rate * mfi; + do_div(temp64, quad_parent_rate/1000000); mfn = (long)temp64; - reg = mfi << 4 | pdf; - - *dp_op = reg; - *dp_mfd = mfd; - *dp_mfn = mfn; - - return 0; -} - -static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_pllv2 *pll = to_clk_pllv2(hw); - void __iomem *pllbase; - u32 dp_ctl, dp_op, dp_mfd, dp_mfn; - int ret; - - pllbase = pll->base; - - - ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn); - if (ret) - return ret; - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); /* use dpdck0_2 */ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - - __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP); - __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN); + pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; + if (pll_hfsm == 0) { + reg = mfi << 4 | pdf; + __raw_writel(reg, pllbase + MXC_PLL_DP_OP); + __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); + } else { + reg = mfi << 4 | pdf; + __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); + __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); + __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); + } return 0; } @@ -183,11 +170,7 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { - u32 dp_op, dp_mfd, dp_mfn; - - __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); - return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, - dp_op, dp_mfd, dp_mfn); + return rate; } static int clk_pllv2_prepare(struct clk_hw *hw) diff --git a/trunk/arch/arm/mach-imx/crm-regs-imx5.h b/trunk/arch/arm/mach-imx/crm-regs-imx5.h index 5e3f1f0f4cab..5e11ba7daee2 100644 --- a/trunk/arch/arm/mach-imx/crm-regs-imx5.h +++ b/trunk/arch/arm/mach-imx/crm-regs-imx5.h @@ -23,7 +23,7 @@ #define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) #define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) #define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) -#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR) +#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) /* PLL Register Offsets */ #define MXC_PLL_DP_CTL 0x00 diff --git a/trunk/arch/arm/mach-imx/hotplug.c b/trunk/arch/arm/mach-imx/hotplug.c index 20ed2d56c1af..89493abd497c 100644 --- a/trunk/arch/arm/mach-imx/hotplug.c +++ b/trunk/arch/arm/mach-imx/hotplug.c @@ -12,7 +12,6 @@ #include #include -#include #include int platform_cpu_kill(unsigned int cpu) @@ -20,44 +19,6 @@ int platform_cpu_kill(unsigned int cpu) return 1; } -static inline void cpu_enter_lowpower(void) -{ - unsigned int v; - - flush_cache_all(); - asm volatile( - "mcr p15, 0, %1, c7, c5, 0\n" - " mcr p15, 0, %1, c7, c10, 4\n" - /* - * Turn off coherency - */ - " mrc p15, 0, %0, c1, c0, 1\n" - " bic %0, %0, %3\n" - " mcr p15, 0, %0, c1, c0, 1\n" - " mrc p15, 0, %0, c1, c0, 0\n" - " bic %0, %0, %2\n" - " mcr p15, 0, %0, c1, c0, 0\n" - : "=&r" (v) - : "r" (0), "Ir" (CR_C), "Ir" (0x40) - : "cc"); -} - -static inline void cpu_leave_lowpower(void) -{ - unsigned int v; - - asm volatile( - "mrc p15, 0, %0, c1, c0, 0\n" - " orr %0, %0, %1\n" - " mcr p15, 0, %0, c1, c0, 0\n" - " mrc p15, 0, %0, c1, c0, 1\n" - " orr %0, %0, %2\n" - " mcr p15, 0, %0, c1, c0, 1\n" - : "=&r" (v) - : "Ir" (CR_C), "Ir" (0x40) - : "cc"); -} - /* * platform-specific code to shutdown a CPU * @@ -65,10 +26,9 @@ static inline void cpu_leave_lowpower(void) */ void platform_cpu_die(unsigned int cpu) { - cpu_enter_lowpower(); + flush_cache_all(); imx_enable_cpu(cpu, false); cpu_do_idle(); - cpu_leave_lowpower(); /* We should never return from idle */ panic("cpu %d unexpectedly exit from shutdown\n", cpu); diff --git a/trunk/arch/arm/mach-imx/mach-cpuimx35.c b/trunk/arch/arm/mach-imx/mach-cpuimx35.c index 6450303f1a7a..c515f8ede1a1 100644 --- a/trunk/arch/arm/mach-imx/mach-cpuimx35.c +++ b/trunk/arch/arm/mach-imx/mach-cpuimx35.c @@ -70,6 +70,7 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x48), + .type = "tsc2007", .platform_data = &tsc2007_info, .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), }, diff --git a/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c b/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c index 1e09de50cbcd..ac50f1671e38 100644 --- a/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -142,6 +142,7 @@ static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x49), + .type = "tsc2007", .platform_data = &tsc2007_info, }, }; diff --git a/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index ba09552fe5fe..dff82eb57cd9 100644 --- a/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -116,8 +116,6 @@ static const int visstrim_m10_pins[] __initconst = { PB23_PF_USB_PWR, PB24_PF_USB_OC, /* CSI */ - TVP5150_RSTN | GPIO_GPIO | GPIO_OUT, - TVP5150_PWDN | GPIO_GPIO | GPIO_OUT, PB10_PF_CSI_D0, PB11_PF_CSI_D1, PB12_PF_CSI_D2, @@ -149,24 +147,6 @@ static struct gpio visstrim_m10_version_gpios[] = { { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" }, }; -static const struct gpio visstrim_m10_gpios[] __initconst = { - { - .gpio = TVP5150_RSTN, - .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH, - .label = "tvp5150_rstn", - }, - { - .gpio = TVP5150_PWDN, - .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, - .label = "tvp5150_pwdn", - }, - { - .gpio = OTG_PHY_CS_GPIO, - .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, - .label = "usbotg_cs", - }, -}; - /* Camera */ static int visstrim_camera_power(struct device *dev, int on) { @@ -210,6 +190,13 @@ static void __init visstrim_camera_init(void) struct platform_device *pdev; int dma; + /* Initialize tvp5150 gpios */ + mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT); + mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT); + gpio_set_value(TVP5150_RSTN, 1); + gpio_set_value(TVP5150_PWDN, 0); + ndelay(1); + gpio_set_value(TVP5150_PWDN, 1); ndelay(1); gpio_set_value(TVP5150_RSTN, 0); @@ -390,6 +377,10 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { /* USB OTG */ static int otg_phy_init(struct platform_device *pdev) { + gpio_set_value(OTG_PHY_CS_GPIO, 0); + + mdelay(10); + return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); } @@ -444,11 +435,6 @@ static void __init visstrim_m10_board_init(void) if (ret) pr_err("Failed to setup pins (%d)\n", ret); - ret = gpio_request_array(visstrim_m10_gpios, - ARRAY_SIZE(visstrim_m10_gpios)); - if (ret) - pr_err("Failed to request gpios (%d)\n", ret); - imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata); imx27_add_imx_uart0(&uart_pdata); diff --git a/trunk/arch/arm/mach-imx/mach-mx21ads.c b/trunk/arch/arm/mach-imx/mach-mx21ads.c index 3e7401fca76c..d14bbe949a4f 100644 --- a/trunk/arch/arm/mach-imx/mach-mx21ads.c +++ b/trunk/arch/arm/mach-imx/mach-mx21ads.c @@ -32,7 +32,7 @@ * Memory-mapped I/O on MX21ADS base board */ #define MX21ADS_MMIO_BASE_ADDR 0xf5000000 -#define MX21ADS_MMIO_SIZE 0xc00000 +#define MX21ADS_MMIO_SIZE SZ_16M #define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \ (MX21ADS_MMIO_BASE_ADDR + (offset)) diff --git a/trunk/arch/arm/mach-imx/mm-imx3.c b/trunk/arch/arm/mach-imx/mm-imx3.c index a8983b9778d1..967ed5b35a45 100644 --- a/trunk/arch/arm/mach-imx/mm-imx3.c +++ b/trunk/arch/arm/mach-imx/mm-imx3.c @@ -86,7 +86,6 @@ static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size, void __init imx3_init_l2x0(void) { -#ifdef CONFIG_CACHE_L2X0 void __iomem *l2x0_base; void __iomem *clkctl_base; @@ -116,7 +115,6 @@ void __init imx3_init_l2x0(void) } l2x0_init(l2x0_base, 0x00030024, 0x00000000); -#endif } #ifdef CONFIG_SOC_IMX31 @@ -181,8 +179,6 @@ void __init imx31_soc_init(void) mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); - pinctrl_provide_dummies(); - if (to_version == 1) { strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin", strlen(imx31_sdma_pdata.fw_name)); diff --git a/trunk/arch/arm/mach-imx/mm-imx5.c b/trunk/arch/arm/mach-imx/mm-imx5.c index 1d003053d562..feeee17da96b 100644 --- a/trunk/arch/arm/mach-imx/mm-imx5.c +++ b/trunk/arch/arm/mach-imx/mm-imx5.c @@ -202,8 +202,6 @@ void __init imx51_soc_init(void) mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); - pinctrl_provide_dummies(); - /* i.mx51 has the i.mx35 type sdma */ imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); diff --git a/trunk/arch/arm/mach-kirkwood/board-iconnect.c b/trunk/arch/arm/mach-kirkwood/board-iconnect.c index b0d3cc49269d..2222c5739519 100644 --- a/trunk/arch/arm/mach-kirkwood/board-iconnect.c +++ b/trunk/arch/arm/mach-kirkwood/board-iconnect.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-kirkwood/common.c b/trunk/arch/arm/mach-kirkwood/common.c index f261cd242643..25fb3fd418ef 100644 --- a/trunk/arch/arm/mach-kirkwood/common.c +++ b/trunk/arch/arm/mach-kirkwood/common.c @@ -159,7 +159,6 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, gate_fn->gate.flags = clk_gate_flags; gate_fn->gate.lock = lock; gate_fn->gate.hw.init = &init; - gate_fn->fn = fn; /* ops is the gate ops, but with our disable function */ if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { @@ -194,11 +193,9 @@ static struct clk __init *kirkwood_register_gate_fn(const char *name, bit_idx, 0, &gating_lock, fn); } -static struct clk *ge0, *ge1; - void __init kirkwood_clk_init(void) { - struct clk *runit, *sata0, *sata1, *usb0, *sdio; + struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, @@ -260,9 +257,6 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) orion_ge00_init(eth_data, GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, IRQ_KIRKWOOD_GE00_ERR); - /* The interface forgets the MAC address assigned by u-boot if - the clock is turned off, so claim the clk now. */ - clk_prepare_enable(ge0); } @@ -274,7 +268,6 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) orion_ge01_init(eth_data, GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, IRQ_KIRKWOOD_GE01_ERR); - clk_prepare_enable(ge1); } diff --git a/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index a115142f8690..3eee37a3b501 100644 --- a/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -38,7 +38,6 @@ #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) -#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300) #define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) #define L2_WRITETHROUGH 0x00000010 diff --git a/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h index c5b68510776b..fede3d503efa 100644 --- a/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -80,7 +80,6 @@ #define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) #define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) -#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x20000) #define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000) diff --git a/trunk/arch/arm/mach-mmp/include/mach/gpio-pxa.h b/trunk/arch/arm/mach-mmp/include/mach/gpio-pxa.h new file mode 100644 index 000000000000..0e135a599f3e --- /dev/null +++ b/trunk/arch/arm/mach-mmp/include/mach/gpio-pxa.h @@ -0,0 +1,29 @@ +#ifndef __ASM_MACH_GPIO_PXA_H +#define __ASM_MACH_GPIO_PXA_H + +#include +#include +#include + +#define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000) + +#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) +#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x))) + +#define gpio_to_bank(gpio) ((gpio) >> 5) + +/* NOTE: these macros are defined here to make optimization of + * gpio_{get,set}_value() to work when 'gpio' is a constant. + * Usage of these macros otherwise is no longer recommended, + * use generic GPIO API whenever possible. + */ +#define GPIO_bit(gpio) (1 << ((gpio) & 0x1f)) + +#define GPLR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x00) +#define GPDR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x0c) +#define GPSR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x18) +#define GPCR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x24) + +#include + +#endif /* __ASM_MACH_GPIO_PXA_H */ diff --git a/trunk/arch/arm/mach-mmp/irq.c b/trunk/arch/arm/mach-mmp/irq.c index e60c7d98922b..fcfe0e3bd701 100644 --- a/trunk/arch/arm/mach-mmp/irq.c +++ b/trunk/arch/arm/mach-mmp/irq.c @@ -241,7 +241,6 @@ void __init mmp2_init_icu(void) icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE; icu_data[1].nr_irqs = 2; - icu_data[1].cascade_irq = 4; icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs, icu_data[1].virq_base, 0, @@ -250,7 +249,6 @@ void __init mmp2_init_icu(void) icu_data[2].reg_status = mmp_icu_base + 0x154; icu_data[2].reg_mask = mmp_icu_base + 0x16c; icu_data[2].nr_irqs = 2; - icu_data[2].cascade_irq = 5; icu_data[2].virq_base = IRQ_MMP2_RTC_BASE; icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs, icu_data[2].virq_base, 0, @@ -259,7 +257,6 @@ void __init mmp2_init_icu(void) icu_data[3].reg_status = mmp_icu_base + 0x180; icu_data[3].reg_mask = mmp_icu_base + 0x17c; icu_data[3].nr_irqs = 3; - icu_data[3].cascade_irq = 9; icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE; icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs, icu_data[3].virq_base, 0, @@ -268,7 +265,6 @@ void __init mmp2_init_icu(void) icu_data[4].reg_status = mmp_icu_base + 0x158; icu_data[4].reg_mask = mmp_icu_base + 0x170; icu_data[4].nr_irqs = 5; - icu_data[4].cascade_irq = 17; icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE; icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs, icu_data[4].virq_base, 0, @@ -277,7 +273,6 @@ void __init mmp2_init_icu(void) icu_data[5].reg_status = mmp_icu_base + 0x15c; icu_data[5].reg_mask = mmp_icu_base + 0x174; icu_data[5].nr_irqs = 15; - icu_data[5].cascade_irq = 35; icu_data[5].virq_base = IRQ_MMP2_MISC_BASE; icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs, icu_data[5].virq_base, 0, @@ -286,7 +281,6 @@ void __init mmp2_init_icu(void) icu_data[6].reg_status = mmp_icu_base + 0x160; icu_data[6].reg_mask = mmp_icu_base + 0x178; icu_data[6].nr_irqs = 2; - icu_data[6].cascade_irq = 51; icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE; icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs, icu_data[6].virq_base, 0, @@ -295,7 +289,6 @@ void __init mmp2_init_icu(void) icu_data[7].reg_status = mmp_icu_base + 0x188; icu_data[7].reg_mask = mmp_icu_base + 0x184; icu_data[7].nr_irqs = 2; - icu_data[7].cascade_irq = 55; icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE; icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs, icu_data[7].virq_base, 0, diff --git a/trunk/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h b/trunk/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h index eb187e0e059b..c64dbb96dbad 100644 --- a/trunk/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h +++ b/trunk/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h @@ -31,6 +31,5 @@ #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) -#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300) #endif diff --git a/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h index e807c4c52a0b..3674497162e3 100644 --- a/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h +++ b/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h @@ -42,7 +42,6 @@ #define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000 #define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000 #define MV78XX0_CORE_REGS_VIRT_BASE 0xfe400000 -#define MV78XX0_CORE_REGS_PHYS_BASE 0xfe400000 #define MV78XX0_CORE_REGS_SIZE SZ_16K #define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20)) @@ -60,7 +59,6 @@ * Core-specific peripheral registers. */ #define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE) -#define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE) /* * Register Map diff --git a/trunk/arch/arm/mach-mxs/mach-apx4devkit.c b/trunk/arch/arm/mach-mxs/mach-apx4devkit.c index f5f061757deb..5e90b9dcdef8 100644 --- a/trunk/arch/arm/mach-mxs/mach-apx4devkit.c +++ b/trunk/arch/arm/mach-mxs/mach-apx4devkit.c @@ -205,16 +205,6 @@ static int apx4devkit_phy_fixup(struct phy_device *phy) return 0; } -static void __init apx4devkit_fec_phy_clk_enable(void) -{ - struct clk *clk; - - /* Enable fec phy clock */ - clk = clk_get_sys("enet_out", NULL); - if (!IS_ERR(clk)) - clk_prepare_enable(clk); -} - static void __init apx4devkit_init(void) { mx28_soc_init(); @@ -235,7 +225,6 @@ static void __init apx4devkit_init(void) phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK, apx4devkit_phy_fixup); - apx4devkit_fec_phy_clk_enable(); mx28_add_fec(0, &mx28_fec_pdata); mx28_add_mxs_mmc(0, &apx4devkit_mmc_pdata); diff --git a/trunk/arch/arm/mach-omap2/board-flash.c b/trunk/arch/arm/mach-omap2/board-flash.c index 53c39d239d6e..70a81f900bb5 100644 --- a/trunk/arch/arm/mach-omap2/board-flash.c +++ b/trunk/arch/arm/mach-omap2/board-flash.c @@ -97,6 +97,11 @@ __init board_onenand_init(struct mtd_partition *onenand_parts, gpmc_onenand_init(&board_onenand_data); } +#else +void +__init board_onenand_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs) +{ +} #endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */ #if defined(CONFIG_MTD_NAND_OMAP2) || \ diff --git a/trunk/arch/arm/mach-omap2/board-n8x0.c b/trunk/arch/arm/mach-omap2/board-n8x0.c index 2c5d0ed75285..8ca14e88a31a 100644 --- a/trunk/arch/arm/mach-omap2/board-n8x0.c +++ b/trunk/arch/arm/mach-omap2/board-n8x0.c @@ -83,9 +83,11 @@ static struct musb_hdrc_config musb_config = { }; static struct musb_hdrc_platform_data tusb_data = { -#ifdef CONFIG_USB_GADGET_MUSB_HDRC +#if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, -#else +#elif defined(CONFIG_USB_MUSB_PERIPHERAL) + .mode = MUSB_PERIPHERAL, +#else /* defined(CONFIG_USB_MUSB_HOST) */ .mode = MUSB_HOST, #endif .set_power = tusb_set_power, diff --git a/trunk/arch/arm/mach-omap2/board-omap3beagle.c b/trunk/arch/arm/mach-omap2/board-omap3beagle.c index 580fd17208da..79c6909eeb78 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3beagle.c +++ b/trunk/arch/arm/mach-omap2/board-omap3beagle.c @@ -81,13 +81,13 @@ static u8 omap3_beagle_version; static struct { int mmc1_gpio_wp; int usb_pwr_level; - int dvi_pd_gpio; + int reset_gpio; int usr_button_gpio; int mmc_caps; } beagle_config = { .mmc1_gpio_wp = -EINVAL, .usb_pwr_level = GPIOF_OUT_INIT_LOW, - .dvi_pd_gpio = -EINVAL, + .reset_gpio = 129, .usr_button_gpio = 4, .mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, }; @@ -126,21 +126,21 @@ static void __init omap3_beagle_init_rev(void) printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX; beagle_config.mmc1_gpio_wp = 29; - beagle_config.dvi_pd_gpio = 170; + beagle_config.reset_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 6: printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3; beagle_config.mmc1_gpio_wp = 23; - beagle_config.dvi_pd_gpio = 170; + beagle_config.reset_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 5: printk(KERN_INFO "OMAP3 Beagle Rev: C4\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; beagle_config.mmc1_gpio_wp = 23; - beagle_config.dvi_pd_gpio = 170; + beagle_config.reset_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 0: @@ -274,9 +274,11 @@ static int beagle_twl_gpio_setup(struct device *dev, if (r) pr_err("%s: unable to configure nDVI_PWR_EN\n", __func__); - - beagle_config.dvi_pd_gpio = gpio + 2; - + r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, + "DVI_LDO_EN"); + if (r) + pr_err("%s: unable to configure DVI_LDO_EN\n", + __func__); } else { /* * REVISIT: need ehci-omap hooks for external VBUS @@ -285,7 +287,7 @@ static int beagle_twl_gpio_setup(struct device *dev, if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) pr_err("%s: unable to configure EHCI_nOC\n", __func__); } - dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; + dvi_panel.power_down_gpio = beagle_config.reset_gpio; gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level, "nEN_USB_PWR"); @@ -497,7 +499,7 @@ static void __init omap3_beagle_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_beagle_init_rev(); - if (gpio_is_valid(beagle_config.mmc1_gpio_wp)) + if (beagle_config.mmc1_gpio_wp != -EINVAL) omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); mmc[0].caps = beagle_config.mmc_caps; omap_hsmmc_init(mmc); @@ -508,13 +510,15 @@ static void __init omap3_beagle_init(void) platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); - if (gpio_is_valid(beagle_config.dvi_pd_gpio)) - omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); omap_display_init(&beagle_dss_data); omap_serial_init(); omap_sdrc_init(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); + omap_mux_init_gpio(170, OMAP_PIN_INPUT); + /* REVISIT leave DVI powered down until it's needed ... */ + gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); + usb_musb_init(NULL); usbhs_init(&usbhs_bdata); omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, diff --git a/trunk/arch/arm/mach-omap2/board-overo.c b/trunk/arch/arm/mach-omap2/board-overo.c index 779734d8ba37..8fa2fc3a4c3c 100644 --- a/trunk/arch/arm/mach-omap2/board-overo.c +++ b/trunk/arch/arm/mach-omap2/board-overo.c @@ -494,8 +494,8 @@ static void __init overo_init(void) regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - overo_i2c_init(); omap_hsmmc_init(mmc); + overo_i2c_init(); omap_display_init(&overo_dss_data); omap_serial_init(); omap_sdrc_init(mt46h32m32lf6_sdrc_params, diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index df2534de3361..ff53deccecab 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -144,6 +144,7 @@ static struct lis3lv02d_platform_data rx51_lis3lv02d_data = { .release_resources = lis302_release, .st_min_limits = {-32, 3, 3}, .st_max_limits = {-3, 32, 32}, + .irq2 = OMAP_GPIO_IRQ(LIS302_IRQ2_GPIO), }; #endif @@ -1029,6 +1030,7 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = { { I2C_BOARD_INFO("lis3lv02d", 0x1d), .platform_data = &rx51_lis3lv02d_data, + .irq = OMAP_GPIO_IRQ(LIS302_IRQ1_GPIO), }, #endif }; @@ -1054,10 +1056,6 @@ static int __init rx51_i2c_init(void) omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata); omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); -#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) - rx51_lis3lv02d_data.irq2 = gpio_to_irq(LIS302_IRQ2_GPIO); - rx51_peripherals_i2c_board_info_3[0].irq = gpio_to_irq(LIS302_IRQ1_GPIO); -#endif omap_register_i2c_bus(3, 400, rx51_peripherals_i2c_board_info_3, ARRAY_SIZE(rx51_peripherals_i2c_board_info_3)); return 0; diff --git a/trunk/arch/arm/mach-omap2/clock3xxx_data.c b/trunk/arch/arm/mach-omap2/clock3xxx_data.c index 1efdec236ae8..4e1a3b0e8cc8 100644 --- a/trunk/arch/arm/mach-omap2/clock3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/clock3xxx_data.c @@ -3514,7 +3514,7 @@ int __init omap3xxx_clk_init(void) struct omap_clk *c; u32 cpu_clkflg = 0; - if (soc_is_am35xx()) { + if (cpu_is_omap3517()) { cpu_mask = RATE_IN_34XX; cpu_clkflg = CK_AM35XX; } else if (cpu_is_omap3630()) { diff --git a/trunk/arch/arm/mach-omap2/clock44xx_data.c b/trunk/arch/arm/mach-omap2/clock44xx_data.c index ba6f9a0a43e9..2172f6603848 100644 --- a/trunk/arch/arm/mach-omap2/clock44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clock44xx_data.c @@ -84,7 +84,6 @@ static struct clk slimbus_clk = { static struct clk sys_32k_ck = { .name = "sys_32k_ck", - .clkdm_name = "prm_clkdm", .rate = 32768, .ops = &clkops_null, }; @@ -513,7 +512,6 @@ static struct clk ddrphy_ck = { .name = "ddrphy_ck", .parent = &dpll_core_m2_ck, .ops = &clkops_null, - .clkdm_name = "l3_emif_clkdm", .fixed_div = 2, .recalc = &omap_fixed_divisor_recalc, }; @@ -771,7 +769,6 @@ static const struct clksel dpll_mpu_m2_div[] = { static struct clk dpll_mpu_m2_ck = { .name = "dpll_mpu_m2_ck", .parent = &dpll_mpu_ck, - .clkdm_name = "cm_clkdm", .clksel = dpll_mpu_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, @@ -1152,7 +1149,6 @@ static const struct clksel l3_div_div[] = { static struct clk l3_div_ck = { .name = "l3_div_ck", .parent = &div_core_ck, - .clkdm_name = "cm_clkdm", .clksel = l3_div_div, .clksel_reg = OMAP4430_CM_CLKSEL_CORE, .clksel_mask = OMAP4430_CLKSEL_L3_MASK, @@ -2828,7 +2824,6 @@ static const struct clksel trace_clk_div_div[] = { static struct clk trace_clk_div_ck = { .name = "trace_clk_div_ck", .parent = &pmd_trace_clk_mux_ck, - .clkdm_name = "emu_sys_clkdm", .clksel = trace_clk_div_div, .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL, .clksel_mask = OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK, @@ -3417,12 +3412,9 @@ int __init omap4xxx_clk_init(void) if (cpu_is_omap443x()) { cpu_mask = RATE_IN_4430; cpu_clkflg = CK_443X; - } else if (cpu_is_omap446x() || cpu_is_omap447x()) { + } else if (cpu_is_omap446x()) { cpu_mask = RATE_IN_4460 | RATE_IN_4430; cpu_clkflg = CK_446X | CK_443X; - - if (cpu_is_omap447x()) - pr_warn("WARNING: OMAP4470 clock data incomplete!\n"); } else { return 0; } diff --git a/trunk/arch/arm/mach-omap2/clockdomain.h b/trunk/arch/arm/mach-omap2/clockdomain.h index 6227e9505c2d..f7b58609bad8 100644 --- a/trunk/arch/arm/mach-omap2/clockdomain.h +++ b/trunk/arch/arm/mach-omap2/clockdomain.h @@ -31,16 +31,12 @@ * * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) - * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is - * active whenever the MPU is active. True for interconnects and - * the WKUP clockdomains. */ #define CLKDM_CAN_FORCE_SLEEP (1 << 0) #define CLKDM_CAN_FORCE_WAKEUP (1 << 1) #define CLKDM_CAN_ENABLE_AUTO (1 << 2) #define CLKDM_CAN_DISABLE_AUTO (1 << 3) #define CLKDM_NO_AUTODEPS (1 << 4) -#define CLKDM_ACTIVE_WITH_MPU (1 << 5) #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) diff --git a/trunk/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/trunk/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c index 4972219653ce..839145e1cfbe 100644 --- a/trunk/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -88,5 +88,4 @@ struct clockdomain wkup_common_clkdm = { .name = "wkup_clkdm", .pwrdm = { .name = "wkup_pwrdm" }, .dep_bit = OMAP_EN_WKUP_SHIFT, - .flags = CLKDM_ACTIVE_WITH_MPU, }; diff --git a/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c b/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c index 7f2133abe7d3..c53425847493 100644 --- a/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -381,7 +381,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = { .cm_inst = OMAP4430_PRM_WKUP_CM_INST, .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, - .flags = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU, + .flags = CLKDM_CAN_HWSUP, }; static struct clockdomain emu_sys_44xx_clkdm = { diff --git a/trunk/arch/arm/mach-omap2/cm.h b/trunk/arch/arm/mach-omap2/cm.h index f24e3f7a2bbc..a7bc096bd407 100644 --- a/trunk/arch/arm/mach-omap2/cm.h +++ b/trunk/arch/arm/mach-omap2/cm.h @@ -22,15 +22,4 @@ */ #define MAX_MODULE_READY_TIME 2000 -/* - * MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for - * the PRCM to request that a module enter the inactive state in the - * case of OMAP2 & 3. In the case of OMAP4 this is the max duration - * in microseconds for the module to reach the inactive state from - * a functional state. - * XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during - * kernel init. - */ -#define MAX_MODULE_DISABLE_TIME 5000 - #endif diff --git a/trunk/arch/arm/mach-omap2/cminst44xx.c b/trunk/arch/arm/mach-omap2/cminst44xx.c index 1a39945d9ff8..8c86d294b1a3 100644 --- a/trunk/arch/arm/mach-omap2/cminst44xx.c +++ b/trunk/arch/arm/mach-omap2/cminst44xx.c @@ -313,9 +313,9 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_off omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == CLKCTRL_IDLEST_DISABLED), - MAX_MODULE_DISABLE_TIME, i); + MAX_MODULE_READY_TIME, i); - return (i < MAX_MODULE_DISABLE_TIME) ? 0 : -EBUSY; + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; } /** diff --git a/trunk/arch/arm/mach-omap2/display.c b/trunk/arch/arm/mach-omap2/display.c index 5fb47a14f4ba..54d49ddb9b81 100644 --- a/trunk/arch/arm/mach-omap2/display.c +++ b/trunk/arch/arm/mach-omap2/display.c @@ -271,9 +271,9 @@ static struct platform_device *create_simple_dss_pdev(const char *pdev_name, goto err; } - r = platform_device_add(pdev); + r = omap_device_register(pdev); if (r) { - pr_err("Could not register platform_device for %s\n", pdev_name); + pr_err("Could not register omap_device for %s\n", pdev_name); goto err; } diff --git a/trunk/arch/arm/mach-omap2/dsp.c b/trunk/arch/arm/mach-omap2/dsp.c index 88ffa1e645cd..845309f146fe 100644 --- a/trunk/arch/arm/mach-omap2/dsp.c +++ b/trunk/arch/arm/mach-omap2/dsp.c @@ -20,9 +20,6 @@ #include #include - -#include - #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #ifdef CONFIG_BRIDGE_DVFS diff --git a/trunk/arch/arm/mach-omap2/id.c b/trunk/arch/arm/mach-omap2/id.c index 00486a8564fd..0389b3264abe 100644 --- a/trunk/arch/arm/mach-omap2/id.c +++ b/trunk/arch/arm/mach-omap2/id.c @@ -246,17 +246,6 @@ void __init omap3xxx_check_features(void) omap_features |= OMAP3_HAS_SDRC; - /* - * am35x fixups: - * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as - * reserved and therefore return 0 when read. Unfortunately, - * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to - * mean that a feature is present even though it isn't so clear - * the incorrectly set feature bits. - */ - if (soc_is_am35xx()) - omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP); - /* * TODO: Get additional info (where applicable) * e.g. Size of L2 cache. diff --git a/trunk/arch/arm/mach-omap2/irq.c b/trunk/arch/arm/mach-omap2/irq.c index 6038a8c84b74..fdc4303be563 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -149,7 +149,6 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) ct->chip.irq_ack = omap_mask_ack_irq; ct->chip.irq_mask = irq_gc_mask_disable_reg; ct->chip.irq_unmask = irq_gc_unmask_enable_reg; - ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE; ct->regs.enable = INTC_MIR_CLEAR0; ct->regs.disable = INTC_MIR_SET0; diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index 9fe6829f4c16..80e55c5c9998 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -41,7 +41,6 @@ #include "control.h" #include "mux.h" #include "prm.h" -#include "common.h" #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ #define OMAP_MUX_BASE_SZ 0x5ca @@ -218,7 +217,8 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, return -ENODEV; } -int __init omap_mux_get_by_name(const char *muxname, +static int __init +omap_mux_get_by_name(const char *muxname, struct omap_mux_partition **found_partition, struct omap_mux **found_mux) { diff --git a/trunk/arch/arm/mach-omap2/mux.h b/trunk/arch/arm/mach-omap2/mux.h index 471e62a74a16..69fe060a0b75 100644 --- a/trunk/arch/arm/mach-omap2/mux.h +++ b/trunk/arch/arm/mach-omap2/mux.h @@ -59,7 +59,6 @@ #define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN #define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4) -#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0) /* Flags for omapX_mux_init */ #define OMAP_PACKAGE_MASK 0xffff @@ -226,18 +225,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads); */ void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state); -int omap_mux_get_by_name(const char *muxname, - struct omap_mux_partition **found_partition, - struct omap_mux **found_mux); #else -static inline int omap_mux_get_by_name(const char *muxname, - struct omap_mux_partition **found_partition, - struct omap_mux **found_mux) -{ - return 0; -} - static inline int omap_mux_init_gpio(int gpio, int val) { return 0; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index 2d710f50fca2..bf86f7e8f91f 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -530,7 +530,7 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v); if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) - _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v); + _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); /* XXX test pwrdm_get_wken for this hwmod's subsystem */ @@ -1124,18 +1124,15 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * - * Ensure that the OCP_SYSCONFIG register for the IP block represented - * by @oh is set to indicate to the PRCM that the IP block is active. - * Usually this means placing the module into smart-idle mode and - * smart-standby, but if there is a bug in the automatic idle handling - * for the IP block, it may need to be placed into the force-idle or - * no-idle variants of these modes. No return value. + * If module is marked as SWSUP_SIDLE, force the module out of slave + * idle; otherwise, configure it for smart-idle. If module is marked + * as SWSUP_MSUSPEND, force the module out of master standby; + * otherwise, configure it for smart-standby. No return value. */ static void _enable_sysc(struct omap_hwmod *oh) { u8 idlemode, sf; u32 v; - bool clkdm_act; if (!oh->class->sysc) return; @@ -1144,16 +1141,8 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - clkdm_act = ((oh->clkdm && - oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) || - (oh->_clk && oh->_clk->clkdm && - oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU)); - if (clkdm_act && !(oh->class->sysc->idlemodes & - (SIDLE_SMART | SIDLE_SMART_WKUP))) - idlemode = HWMOD_IDLEMODE_FORCE; - else - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? - HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; + idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? + HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; _set_slave_idlemode(oh, idlemode, &v); } @@ -1219,13 +1208,8 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ - if (oh->flags & HWMOD_SWSUP_SIDLE || - !(oh->class->sysc->idlemodes & - (SIDLE_SMART | SIDLE_SMART_WKUP))) - idlemode = HWMOD_IDLEMODE_FORCE; - else - idlemode = HWMOD_IDLEMODE_SMART; + idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? + HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; _set_slave_idlemode(oh, idlemode, &v); } diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index b7bcba5221ba..950454a3fa31 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -393,7 +393,8 @@ static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0004, .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -853,11 +854,6 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .name = "dss_hdmi", .class = &omap44xx_hdmi_hwmod_class, .clkdm_name = "l3_dss_clkdm", - /* - * HDMI audio requires to use no-idle mode. Hence, - * set idle mode by software. - */ - .flags = HWMOD_SWSUP_SIDLE, .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", @@ -1928,7 +1924,7 @@ static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = { static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" }, + { .role = "prcm_clk", .clk = "mcbsp1_sync_mux_ck" }, }; static struct omap_hwmod omap44xx_mcbsp1_hwmod = { @@ -1963,7 +1959,7 @@ static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = { static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" }, + { .role = "prcm_clk", .clk = "mcbsp2_sync_mux_ck" }, }; static struct omap_hwmod omap44xx_mcbsp2_hwmod = { @@ -1998,7 +1994,7 @@ static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = { static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" }, + { .role = "prcm_clk", .clk = "mcbsp3_sync_mux_ck" }, }; static struct omap_hwmod omap44xx_mcbsp3_hwmod = { @@ -2033,7 +2029,7 @@ static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = { static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = { { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" }, + { .role = "prcm_clk", .clk = "mcbsp4_sync_mux_ck" }, }; static struct omap_hwmod omap44xx_mcbsp4_hwmod = { @@ -3864,7 +3860,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = { }; /* usb_host_fs -> l3_main_2 */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_usb_host_fs__l3_main_2 = { +static struct omap_hwmod_ocp_if omap44xx_usb_host_fs__l3_main_2 = { .master = &omap44xx_usb_host_fs_hwmod, .slave = &omap44xx_l3_main_2_hwmod, .clk = "l3_div_ck", @@ -3922,7 +3918,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = { }; /* aess -> l4_abe */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_aess__l4_abe = { +static struct omap_hwmod_ocp_if omap44xx_aess__l4_abe = { .master = &omap44xx_aess_hwmod, .slave = &omap44xx_l4_abe_hwmod, .clk = "ocp_abe_iclk", @@ -4013,7 +4009,7 @@ static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = { }; /* l4_abe -> aess */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = { +static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess = { .master = &omap44xx_l4_abe_hwmod, .slave = &omap44xx_aess_hwmod, .clk = "ocp_abe_iclk", @@ -4031,7 +4027,7 @@ static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = { }; /* l4_abe -> aess (dma) */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess_dma = { +static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess_dma = { .master = &omap44xx_l4_abe_hwmod, .slave = &omap44xx_aess_hwmod, .clk = "ocp_abe_iclk", @@ -5857,7 +5853,7 @@ static struct omap_hwmod_addr_space omap44xx_usb_host_fs_addrs[] = { }; /* l4_cfg -> usb_host_fs */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = { +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_fs = { .master = &omap44xx_l4_cfg_hwmod, .slave = &omap44xx_usb_host_fs_hwmod, .clk = "l4_div_ck", @@ -6014,13 +6010,13 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_iva__l3_main_2, &omap44xx_l3_main_1__l3_main_2, &omap44xx_l4_cfg__l3_main_2, - /* &omap44xx_usb_host_fs__l3_main_2, */ + &omap44xx_usb_host_fs__l3_main_2, &omap44xx_usb_host_hs__l3_main_2, &omap44xx_usb_otg_hs__l3_main_2, &omap44xx_l3_main_1__l3_main_3, &omap44xx_l3_main_2__l3_main_3, &omap44xx_l4_cfg__l3_main_3, - /* &omap44xx_aess__l4_abe, */ + &omap44xx_aess__l4_abe, &omap44xx_dsp__l4_abe, &omap44xx_l3_main_1__l4_abe, &omap44xx_mpu__l4_abe, @@ -6029,8 +6025,8 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_cfg__l4_wkup, &omap44xx_mpu__mpu_private, &omap44xx_l4_cfg__ocp_wp_noc, - /* &omap44xx_l4_abe__aess, */ - /* &omap44xx_l4_abe__aess_dma, */ + &omap44xx_l4_abe__aess, + &omap44xx_l4_abe__aess_dma, &omap44xx_l3_main_2__c2c, &omap44xx_l4_wkup__counter_32k, &omap44xx_l4_cfg__ctrl_module_core, @@ -6136,7 +6132,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__uart2, &omap44xx_l4_per__uart3, &omap44xx_l4_per__uart4, - /* &omap44xx_l4_cfg__usb_host_fs, */ + &omap44xx_l4_cfg__usb_host_fs, &omap44xx_l4_cfg__usb_host_hs, &omap44xx_l4_cfg__usb_otg_hs, &omap44xx_l4_cfg__usb_tll_hs, diff --git a/trunk/arch/arm/mach-omap2/omap_l3_smx.c b/trunk/arch/arm/mach-omap2/omap_l3_smx.c index acc216491b8a..a05a62f9ee5b 100644 --- a/trunk/arch/arm/mach-omap2/omap_l3_smx.c +++ b/trunk/arch/arm/mach-omap2/omap_l3_smx.c @@ -155,11 +155,10 @@ static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3, u8 multi = error & L3_ERROR_LOG_MULTI; u32 address = omap3_l3_decode_addr(error_addr); - pr_err("%s seen by %s %s at address %x\n", + WARN(true, "%s seen by %s %s at address %x\n", omap3_l3_code_string(code), omap3_l3_initiator_string(initid), multi ? "Multiple Errors" : "", address); - WARN_ON(1); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-omap2/omap_phy_internal.c b/trunk/arch/arm/mach-omap2/omap_phy_internal.c index d52651a05daa..4c90477e6f82 100644 --- a/trunk/arch/arm/mach-omap2/omap_phy_internal.c +++ b/trunk/arch/arm/mach-omap2/omap_phy_internal.c @@ -239,15 +239,21 @@ void am35x_set_mode(u8 musb_mode) devconf2 &= ~CONF2_OTGMODE; switch (musb_mode) { +#ifdef CONFIG_USB_MUSB_HDRC_HCD case MUSB_HOST: /* Force VBUS valid, ID = 0 */ devconf2 |= CONF2_FORCE_HOST; break; +#endif +#ifdef CONFIG_USB_GADGET_MUSB_HDRC case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ devconf2 |= CONF2_FORCE_DEVICE; break; +#endif +#ifdef CONFIG_USB_MUSB_OTG case MUSB_OTG: /* Don't override the VBUS/ID comparators */ devconf2 |= CONF2_NO_OVERRIDE; break; +#endif default: pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); } diff --git a/trunk/arch/arm/mach-omap2/pm34xx.c b/trunk/arch/arm/mach-omap2/pm34xx.c index 3a595e899724..a34023d0ca7c 100644 --- a/trunk/arch/arm/mach-omap2/pm34xx.c +++ b/trunk/arch/arm/mach-omap2/pm34xx.c @@ -724,7 +724,6 @@ int __init omap3_pm_init(void) ret = request_irq(omap_prcm_event_to_irq("io"), _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io", omap3_pm_init); - enable_irq(omap_prcm_event_to_irq("io")); if (ret) { pr_err("pm: Failed to request pm_io irq\n"); diff --git a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c index 21cb74003a56..9ce765407ad5 100644 --- a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "common.h" #include @@ -304,15 +303,8 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask) static int __init omap3xxx_prcm_init(void) { - int ret = 0; - - if (cpu_is_omap34xx()) { - ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); - if (!ret) - irq_set_status_flags(omap_prcm_event_to_irq("io"), - IRQ_NOAUTOEN); - } - - return ret; + if (cpu_is_omap34xx()) + return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + return 0; } subsys_initcall(omap3xxx_prcm_init); diff --git a/trunk/arch/arm/mach-omap2/serial.c b/trunk/arch/arm/mach-omap2/serial.c index c1b93c752d70..292d4aaca068 100644 --- a/trunk/arch/arm/mach-omap2/serial.c +++ b/trunk/arch/arm/mach-omap2/serial.c @@ -57,7 +57,6 @@ struct omap_uart_state { struct list_head node; struct omap_hwmod *oh; - struct omap_device_pad default_omap_uart_pads[2]; }; static LIST_HEAD(uart_list); @@ -127,70 +126,11 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX - -#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28 -static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN], - tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata; - -static void __init -omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata, - struct omap_uart_state *uart) -{ - uart->default_omap_uart_pads[0].name = rx_pad_name; - uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX | - OMAP_DEVICE_PAD_WAKEUP; - uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT | - OMAP_MUX_MODE0; - uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0; - uart->default_omap_uart_pads[1].name = tx_pad_name; - uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT | - OMAP_MUX_MODE0; - bdata->pads = uart->default_omap_uart_pads; - bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads); -} - -static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, - struct omap_uart_state *uart) +static void omap_serial_fill_default_pads(struct omap_board_data *bdata) { - struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL; - struct omap_mux *rx_mux = NULL, *tx_mux = NULL; - char *rx_fmt, *tx_fmt; - int uart_nr = bdata->id + 1; - - if (bdata->id != 2) { - rx_fmt = "uart%d_rx.uart%d_rx"; - tx_fmt = "uart%d_tx.uart%d_tx"; - } else { - rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx"; - tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx"; - } - - snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt, - uart_nr, uart_nr); - snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt, - uart_nr, uart_nr); - - if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 && - omap_mux_get_by_name - (tx_pad_name, &tx_partition, &tx_mux) >= 0) { - u16 tx_mode, rx_mode; - - tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset); - rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset); - - /* - * Check if uart is used in default tx/rx mode i.e. in mux mode0 - * if yes then configure rx pin for wake up capability - */ - if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode)) - omap_serial_fill_uart_tx_rx_pads(bdata, uart); - } } #else -static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, - struct omap_uart_state *uart) -{ -} +static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} #endif static char *cmdline_find_option(char *str) @@ -347,7 +287,8 @@ void __init omap_serial_board_init(struct omap_uart_port_info *info) bdata.pads = NULL; bdata.pads_cnt = 0; - omap_serial_check_wakeup(&bdata, uart); + if (cpu_is_omap44xx() || cpu_is_omap34xx()) + omap_serial_fill_default_pads(&bdata); if (!info) omap_serial_init_port(&bdata, NULL); diff --git a/trunk/arch/arm/mach-omap2/twl-common.c b/trunk/arch/arm/mach-omap2/twl-common.c index 43a979075338..119d5a910f3a 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.c +++ b/trunk/arch/arm/mach-omap2/twl-common.c @@ -32,7 +32,6 @@ #include "twl-common.h" #include "pm.h" #include "voltage.h" -#include "mux.h" static struct i2c_board_info __initdata pmic_i2c_board_info = { .addr = 0x48, @@ -78,7 +77,6 @@ void __init omap4_pmic_init(const char *pmic_type, struct twl6040_platform_data *twl6040_data, int twl6040_irq) { /* PMIC part*/ - omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); strncpy(omap4_i2c1_board_info[0].type, pmic_type, sizeof(omap4_i2c1_board_info[0].type)); omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N; diff --git a/trunk/arch/arm/mach-omap2/usb-musb.c b/trunk/arch/arm/mach-omap2/usb-musb.c index c4a576856661..b19d1b43c12e 100644 --- a/trunk/arch/arm/mach-omap2/usb-musb.c +++ b/trunk/arch/arm/mach-omap2/usb-musb.c @@ -41,10 +41,12 @@ static struct musb_hdrc_config musb_config = { }; static struct musb_hdrc_platform_data musb_plat = { -#ifdef CONFIG_USB_GADGET_MUSB_HDRC +#ifdef CONFIG_USB_MUSB_OTG .mode = MUSB_OTG, -#else +#elif defined(CONFIG_USB_MUSB_HDRC_HCD) .mode = MUSB_HOST, +#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) + .mode = MUSB_PERIPHERAL, #endif /* .clock is set dynamically */ .config = &musb_config, diff --git a/trunk/arch/arm/mach-omap2/usb-tusb6010.c b/trunk/arch/arm/mach-omap2/usb-tusb6010.c index 805bea6edf17..db84a46ce7fd 100644 --- a/trunk/arch/arm/mach-omap2/usb-tusb6010.c +++ b/trunk/arch/arm/mach-omap2/usb-tusb6010.c @@ -300,7 +300,7 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, printk(error, 3, status); return status; } - tusb_resources[2].start = gpio_to_irq(irq); + tusb_resources[2].start = irq + IH_GPIO_BASE; /* set up memory timings ... can speed them up later */ if (!ps_refclk) { diff --git a/trunk/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/trunk/arch/arm/mach-orion5x/include/mach/bridge-regs.h index 11a3c1e9801f..96484bcd34ca 100644 --- a/trunk/arch/arm/mach-orion5x/include/mach/bridge-regs.h +++ b/trunk/arch/arm/mach-orion5x/include/mach/bridge-regs.h @@ -35,5 +35,5 @@ #define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x204) #define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE | 0x300) -#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE | 0x300) + #endif diff --git a/trunk/arch/arm/mach-orion5x/include/mach/io.h b/trunk/arch/arm/mach-orion5x/include/mach/io.h deleted file mode 100644 index 1aa5d0a50a0b..000000000000 --- a/trunk/arch/arm/mach-orion5x/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/arm/mach-orion5x/include/mach/io.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_IO_H -#define __ASM_ARCH_IO_H - -#include -#include - -#define IO_SPACE_LIMIT SZ_2M -static inline void __iomem *__io(unsigned long addr) -{ - return (void __iomem *)(addr + ORION5X_PCIE_IO_VIRT_BASE); -} - -#define __io(a) __io(a) -#endif diff --git a/trunk/arch/arm/mach-orion5x/include/mach/orion5x.h b/trunk/arch/arm/mach-orion5x/include/mach/orion5x.h index 683e085ce162..2745f5d95b3f 100644 --- a/trunk/arch/arm/mach-orion5x/include/mach/orion5x.h +++ b/trunk/arch/arm/mach-orion5x/include/mach/orion5x.h @@ -82,7 +82,6 @@ #define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2100) #define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x20000) -#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x20000) #define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x30000) diff --git a/trunk/arch/arm/mach-pxa/hx4700.c b/trunk/arch/arm/mach-pxa/hx4700.c index d3de84b0dcbe..d09da6a746b8 100644 --- a/trunk/arch/arm/mach-pxa/hx4700.c +++ b/trunk/arch/arm/mach-pxa/hx4700.c @@ -127,11 +127,7 @@ static unsigned long hx4700_pin_config[] __initdata = { GPIO19_SSP2_SCLK, GPIO86_SSP2_RXD, GPIO87_SSP2_TXD, - GPIO88_GPIO | MFP_LPM_DRIVE_HIGH, /* TSC2046_CS */ - - /* BQ24022 Regulator */ - GPIO72_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_nCHARGE_EN */ - GPIO96_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_ISET2 */ + GPIO88_GPIO, /* HX4700 specific input GPIOs */ GPIO12_GPIO | WAKEUP_ON_EDGE_RISE, /* ASIC3_IRQ */ @@ -139,10 +135,6 @@ static unsigned long hx4700_pin_config[] __initdata = { GPIO14_GPIO, /* nWLAN_IRQ */ /* HX4700 specific output GPIOs */ - GPIO61_GPIO | MFP_LPM_DRIVE_HIGH, /* W3220_nRESET */ - GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* ASIC3_nRESET */ - GPIO81_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_GP_nRESET */ - GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_HW_nRESET */ GPIO102_GPIO | MFP_LPM_DRIVE_LOW, /* SYNAPTICS_POWER_ON */ GPIO10_GPIO, /* GSM_IRQ */ @@ -880,19 +872,14 @@ static struct gpio global_gpios[] = { { GPIO110_HX4700_LCD_LVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_LVDD" }, { GPIO111_HX4700_LCD_AVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_AVDD" }, { GPIO32_HX4700_RS232_ON, GPIOF_OUT_INIT_HIGH, "RS232_ON" }, - { GPIO61_HX4700_W3220_nRESET, GPIOF_OUT_INIT_HIGH, "W3220_nRESET" }, { GPIO71_HX4700_ASIC3_nRESET, GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" }, - { GPIO81_HX4700_CPU_GP_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_GP_nRESET" }, { GPIO82_HX4700_EUART_RESET, GPIOF_OUT_INIT_HIGH, "EUART_RESET" }, - { GPIO116_HX4700_CPU_HW_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_HW_nRESET" }, }; static void __init hx4700_init(void) { int ret; - PCFR = PCFR_GPR_EN | PCFR_OPDE; - pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config)); gpio_set_wake(GPIO12_HX4700_ASIC3_IRQ, 1); ret = gpio_request_array(ARRAY_AND_SIZE(global_gpios)); diff --git a/trunk/arch/arm/mach-s3c24xx/clock-s3c2440.c b/trunk/arch/arm/mach-s3c24xx/clock-s3c2440.c index cb2883d553b5..414364eb426c 100644 --- a/trunk/arch/arm/mach-s3c24xx/clock-s3c2440.c +++ b/trunk/arch/arm/mach-s3c24xx/clock-s3c2440.c @@ -106,7 +106,7 @@ static struct clk s3c2440_clk_cam_upll = { static struct clk s3c2440_clk_ac97 = { .name = "ac97", .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2440_CLKCON_AC97, + .ctrlbit = S3C2440_CLKCON_CAMERA, }; static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) diff --git a/trunk/arch/arm/mach-shmobile/Kconfig b/trunk/arch/arm/mach-shmobile/Kconfig index df33909205e2..f31383c32f9c 100644 --- a/trunk/arch/arm/mach-shmobile/Kconfig +++ b/trunk/arch/arm/mach-shmobile/Kconfig @@ -186,12 +186,6 @@ config SH_TIMER_TMU help This enables build of the TMU timer driver. -config EM_TIMER_STI - bool "STI timer driver" - default y - help - This enables build of the STI timer driver. - endmenu config SH_CLK_CPG diff --git a/trunk/arch/arm/mach-shmobile/board-armadillo800eva.c b/trunk/arch/arm/mach-shmobile/board-armadillo800eva.c index 9bd135531d76..9e37026ef9dd 100644 --- a/trunk/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/trunk/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -779,7 +779,6 @@ DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva") .init_irq = r8a7740_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = eva_init, - .init_late = shmobile_init_late, .timer = &shmobile_timer, .dt_compat = eva_boards_compat_dt, MACHINE_END diff --git a/trunk/arch/arm/mach-shmobile/board-kzm9d.c b/trunk/arch/arm/mach-shmobile/board-kzm9d.c index 6a33cf393428..7bc5e7d39f9b 100644 --- a/trunk/arch/arm/mach-shmobile/board-kzm9d.c +++ b/trunk/arch/arm/mach-shmobile/board-kzm9d.c @@ -80,7 +80,6 @@ DT_MACHINE_START(KZM9D_DT, "kzm9d") .init_irq = emev2_init_irq, .handle_irq = gic_handle_irq, .init_machine = kzm9d_add_standard_devices, - .init_late = shmobile_init_late, .timer = &shmobile_timer, .dt_compat = kzm9d_boards_compat_dt, MACHINE_END diff --git a/trunk/arch/arm/mach-shmobile/board-kzm9g.c b/trunk/arch/arm/mach-shmobile/board-kzm9g.c index c0ae815e7beb..d8e33b682832 100644 --- a/trunk/arch/arm/mach-shmobile/board-kzm9g.c +++ b/trunk/arch/arm/mach-shmobile/board-kzm9g.c @@ -455,7 +455,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g") .init_irq = sh73a0_init_irq, .handle_irq = gic_handle_irq, .init_machine = kzm_init, - .init_late = shmobile_init_late, .timer = &shmobile_timer, .dt_compat = kzm9g_boards_compat_dt, MACHINE_END diff --git a/trunk/arch/arm/mach-shmobile/board-mackerel.c b/trunk/arch/arm/mach-shmobile/board-mackerel.c index 150122a44630..b577f7c44678 100644 --- a/trunk/arch/arm/mach-shmobile/board-mackerel.c +++ b/trunk/arch/arm/mach-shmobile/board-mackerel.c @@ -1512,9 +1512,6 @@ static void __init mackerel_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); - /* SDHI0 PORT172 card-detect IRQ26 */ - gpio_request(GPIO_FN_IRQ26_172, NULL); - #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* enable SDHI1 */ gpio_request(GPIO_FN_SDHICMD1, NULL); diff --git a/trunk/arch/arm/mach-shmobile/clock-sh73a0.c b/trunk/arch/arm/mach-shmobile/clock-sh73a0.c index 3946c4ba2aa8..472d1f5361e5 100644 --- a/trunk/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/trunk/arch/arm/mach-shmobile/clock-sh73a0.c @@ -475,9 +475,9 @@ static struct clk *late_main_clks[] = { enum { MSTP001, MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, - MSTP219, MSTP218, + MSTP219, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, - MSTP331, MSTP329, MSTP325, MSTP323, + MSTP331, MSTP329, MSTP325, MSTP323, MSTP318, MSTP314, MSTP313, MSTP312, MSTP311, MSTP303, MSTP302, MSTP301, MSTP300, MSTP411, MSTP410, MSTP403, @@ -497,7 +497,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */ - [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ @@ -509,6 +508,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */ [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ + [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */ [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */ [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ @@ -552,7 +552,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ - CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ @@ -564,6 +563,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ diff --git a/trunk/arch/arm/mach-shmobile/intc-r8a7779.c b/trunk/arch/arm/mach-shmobile/intc-r8a7779.c index f04fad4ec4fb..550b23df4fd4 100644 --- a/trunk/arch/arm/mach-shmobile/intc-r8a7779.c +++ b/trunk/arch/arm/mach-shmobile/intc-r8a7779.c @@ -35,9 +35,6 @@ #define INT2SMSKCR3 0xfe7822ac #define INT2SMSKCR4 0xfe7822b0 -#define INT2NTSR0 0xfe700060 -#define INT2NTSR1 0xfe700064 - static int r8a7779_set_wake(struct irq_data *data, unsigned int on) { return 0; /* always allow wakeup */ @@ -52,10 +49,6 @@ void __init r8a7779_init_irq(void) gic_init(0, 29, gic_dist_base, gic_cpu_base); gic_arch_extn.irq_set_wake = r8a7779_set_wake; - /* route all interrupts to ARM */ - __raw_writel(0xffffffff, INT2NTSR0); - __raw_writel(0x3fffffff, INT2NTSR1); - /* unmask all known interrupts in INTCS2 */ __raw_writel(0xfffffff0, INT2SMSKCR0); __raw_writel(0xfff7ffff, INT2SMSKCR1); diff --git a/trunk/arch/arm/mach-shmobile/platsmp.c b/trunk/arch/arm/mach-shmobile/platsmp.c index fde0d23121dc..bacdd667e3b1 100644 --- a/trunk/arch/arm/mach-shmobile/platsmp.c +++ b/trunk/arch/arm/mach-shmobile/platsmp.c @@ -22,20 +22,10 @@ #include #include -#ifdef CONFIG_ARCH_SH73A0 #define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2() || \ of_machine_is_compatible("renesas,sh73a0")) -#else -#define is_sh73a0() (0) -#endif - #define is_r8a7779() machine_is_marzen() - -#ifdef CONFIG_ARCH_EMEV2 #define is_emev2() of_machine_is_compatible("renesas,emev2") -#else -#define is_emev2() (0) -#endif static unsigned int __init shmobile_smp_get_core_count(void) { diff --git a/trunk/arch/arm/mach-shmobile/setup-sh7372.c b/trunk/arch/arm/mach-shmobile/setup-sh7372.c index fafce9ce8218..6a4bd582c028 100644 --- a/trunk/arch/arm/mach-shmobile/setup-sh7372.c +++ b/trunk/arch/arm/mach-shmobile/setup-sh7372.c @@ -484,7 +484,7 @@ static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { }, }; -#define SH7372_CHCLR (0x220 - 0x20) +#define SH7372_CHCLR 0x220 static const struct sh_dmae_channel sh7372_dmae_channels[] = { { diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/debug-macro.S b/trunk/arch/arm/mach-spear13xx/include/mach/debug-macro.S index 9e3ae6bfe50d..ea1564609bd4 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-spear13xx/include/mach/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header spear13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/dma.h b/trunk/arch/arm/mach-spear13xx/include/mach/dma.h index d50bdb605925..383ab04dc6c9 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/dma.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/dma.h @@ -4,7 +4,7 @@ * DMA information for SPEAr13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/generic.h b/trunk/arch/arm/mach-spear13xx/include/mach/generic.h index dac57fd0cdfd..6d8c45b9f298 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/generic.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/generic.h @@ -4,7 +4,7 @@ * spear13xx machine family generic header file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/gpio.h b/trunk/arch/arm/mach-spear13xx/include/mach/gpio.h index 85f176311f63..cd6f4f86a56b 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/gpio.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/irqs.h b/trunk/arch/arm/mach-spear13xx/include/mach/irqs.h index 271a62b4cd31..f542a24aa5f2 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/irqs.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/irqs.h @@ -4,7 +4,7 @@ * IRQ helper macros for spear13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/spear.h b/trunk/arch/arm/mach-spear13xx/include/mach/spear.h index 65f27def239b..30c57ef72686 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/spear.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/spear.h @@ -4,7 +4,7 @@ * spear13xx Machine family specific definition * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/timex.h b/trunk/arch/arm/mach-spear13xx/include/mach/timex.h index 3a58b8284a6a..31af3e8d976e 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/timex.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/timex.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family specific timex definitions * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/uncompress.h b/trunk/arch/arm/mach-spear13xx/include/mach/uncompress.h index 70fe72f05dea..c7840896ae6e 100644 --- a/trunk/arch/arm/mach-spear13xx/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-spear13xx/include/mach/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/spear1310.c b/trunk/arch/arm/mach-spear13xx/spear1310.c index 732d29bc7330..fefd15b2f380 100644 --- a/trunk/arch/arm/mach-spear13xx/spear1310.c +++ b/trunk/arch/arm/mach-spear13xx/spear1310.c @@ -4,7 +4,7 @@ * SPEAr1310 machine source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/spear1340.c b/trunk/arch/arm/mach-spear13xx/spear1340.c index 81e4ed76ad06..ee38cbc56869 100644 --- a/trunk/arch/arm/mach-spear13xx/spear1340.c +++ b/trunk/arch/arm/mach-spear13xx/spear1340.c @@ -4,7 +4,7 @@ * SPEAr1340 machine source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear13xx/spear13xx.c b/trunk/arch/arm/mach-spear13xx/spear13xx.c index cf936b106e27..50b349ae863d 100644 --- a/trunk/arch/arm/mach-spear13xx/spear13xx.c +++ b/trunk/arch/arm/mach-spear13xx/spear13xx.c @@ -4,7 +4,7 @@ * SPEAr13XX machines common source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/trunk/arch/arm/mach-spear3xx/include/mach/debug-macro.S index 0a6381fad5d9..590519f10d6e 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-spear3xx/include/mach/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header spear3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/generic.h b/trunk/arch/arm/mach-spear3xx/include/mach/generic.h index ce19113ca791..4a95b9453c2a 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/generic.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family generic header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/gpio.h b/trunk/arch/arm/mach-spear3xx/include/mach/gpio.h index 2ac74c6db7f1..451b2081bfc9 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/gpio.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/irqs.h b/trunk/arch/arm/mach-spear3xx/include/mach/irqs.h index 803de76f5f36..51bd62a0254c 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -4,7 +4,7 @@ * IRQ helper macros for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/trunk/arch/arm/mach-spear3xx/include/mach/misc_regs.h index 6309bf68d6f8..18e2ac576f25 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/misc_regs.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/misc_regs.h @@ -4,7 +4,7 @@ * Miscellaneous registers definitions for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/spear.h b/trunk/arch/arm/mach-spear3xx/include/mach/spear.h index 8cca95193d4d..51eb953148a9 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/spear.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/spear.h @@ -4,7 +4,7 @@ * SPEAr3xx Machine family specific definition * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/timex.h b/trunk/arch/arm/mach-spear3xx/include/mach/timex.h index 9f5d08bd0c44..a38cc9de876f 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/timex.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/timex.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family specific timex definitions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/include/mach/uncompress.h b/trunk/arch/arm/mach-spear3xx/include/mach/uncompress.h index b909b011f7c8..53ba8bbc0dfa 100644 --- a/trunk/arch/arm/mach-spear3xx/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-spear3xx/include/mach/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/spear300.c b/trunk/arch/arm/mach-spear3xx/spear300.c index 0f882ecb7d81..f74a05bdb829 100644 --- a/trunk/arch/arm/mach-spear3xx/spear300.c +++ b/trunk/arch/arm/mach-spear3xx/spear300.c @@ -4,7 +4,7 @@ * SPEAr300 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/spear310.c b/trunk/arch/arm/mach-spear3xx/spear310.c index bbcf4571d361..84dfb0900747 100644 --- a/trunk/arch/arm/mach-spear3xx/spear310.c +++ b/trunk/arch/arm/mach-spear3xx/spear310.c @@ -4,7 +4,7 @@ * SPEAr310 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/spear320.c b/trunk/arch/arm/mach-spear3xx/spear320.c index 88d483bcd66a..a88fa841d29d 100644 --- a/trunk/arch/arm/mach-spear3xx/spear320.c +++ b/trunk/arch/arm/mach-spear3xx/spear320.c @@ -4,7 +4,7 @@ * SPEAr320 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear3xx/spear3xx.c b/trunk/arch/arm/mach-spear3xx/spear3xx.c index 66db5f13af84..f22419ed74a8 100644 --- a/trunk/arch/arm/mach-spear3xx/spear3xx.c +++ b/trunk/arch/arm/mach-spear3xx/spear3xx.c @@ -4,7 +4,7 @@ * SPEAr3XX machines common source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -87,7 +87,7 @@ void __init spear3xx_map_io(void) static void __init spear3xx_timer_init(void) { - char pclk_name[] = "pll3_clk"; + char pclk_name[] = "pll3_48m_clk"; struct clk *gpt_clk, *pclk; spear3xx_clk_init(); diff --git a/trunk/arch/arm/mach-spear6xx/include/mach/gpio.h b/trunk/arch/arm/mach-spear6xx/include/mach/gpio.h index d42cefc0356d..3a789dbb69f7 100644 --- a/trunk/arch/arm/mach-spear6xx/include/mach/gpio.h +++ b/trunk/arch/arm/mach-spear6xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr6xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/trunk/arch/arm/mach-spear6xx/include/mach/misc_regs.h index c34acc201d34..179e45774b3a 100644 --- a/trunk/arch/arm/mach-spear6xx/include/mach/misc_regs.h +++ b/trunk/arch/arm/mach-spear6xx/include/mach/misc_regs.h @@ -4,7 +4,7 @@ * Miscellaneous registers definitions for SPEAr6xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/mach-spear6xx/spear6xx.c b/trunk/arch/arm/mach-spear6xx/spear6xx.c index 9af67d003c62..2e2e3596583e 100644 --- a/trunk/arch/arm/mach-spear6xx/spear6xx.c +++ b/trunk/arch/arm/mach-spear6xx/spear6xx.c @@ -423,7 +423,7 @@ void __init spear6xx_map_io(void) static void __init spear6xx_timer_init(void) { - char pclk_name[] = "pll3_clk"; + char pclk_name[] = "pll3_48m_clk"; struct clk *gpt_clk, *pclk; spear6xx_clk_init(); diff --git a/trunk/arch/arm/mach-tegra/reset.c b/trunk/arch/arm/mach-tegra/reset.c index 5beb7ebe2948..4d6a2ee99c3b 100644 --- a/trunk/arch/arm/mach-tegra/reset.c +++ b/trunk/arch/arm/mach-tegra/reset.c @@ -33,7 +33,7 @@ static bool is_enabled; -static void __init tegra_cpu_reset_handler_enable(void) +static void tegra_cpu_reset_handler_enable(void) { void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE); void __iomem *evp_cpu_reset = diff --git a/trunk/arch/arm/mach-ux500/board-mop500.c b/trunk/arch/arm/mach-ux500/board-mop500.c index 4fd93f5c49ec..9c74ac545849 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.c +++ b/trunk/arch/arm/mach-ux500/board-mop500.c @@ -580,12 +580,43 @@ static void ux500_uart0_reset(void) udelay(1); } +/* This needs to be referenced by callbacks */ +struct pinctrl *u0_p; +struct pinctrl_state *u0_def; +struct pinctrl_state *u0_sleep; + +static void ux500_uart0_init(void) +{ + int ret; + + if (IS_ERR(u0_p) || IS_ERR(u0_def)) + return; + + ret = pinctrl_select_state(u0_p, u0_def); + if (ret) + pr_err("could not set UART0 defstate\n"); +} + +static void ux500_uart0_exit(void) +{ + int ret; + + if (IS_ERR(u0_p) || IS_ERR(u0_sleep)) + return; + + ret = pinctrl_select_state(u0_p, u0_sleep); + if (ret) + pr_err("could not set UART0 idlestate\n"); +} + static struct amba_pl011_data uart0_plat = { #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, .dma_rx_param = &uart0_dma_cfg_rx, .dma_tx_param = &uart0_dma_cfg_tx, #endif + .init = ux500_uart0_init, + .exit = ux500_uart0_exit, .reset = ux500_uart0_reset, }; @@ -607,7 +638,28 @@ static struct amba_pl011_data uart2_plat = { static void __init mop500_uart_init(struct device *parent) { - db8500_add_uart0(parent, &uart0_plat); + struct amba_device *uart0_device; + + uart0_device = db8500_add_uart0(parent, &uart0_plat); + if (uart0_device) { + u0_p = pinctrl_get(&uart0_device->dev); + if (IS_ERR(u0_p)) + dev_err(&uart0_device->dev, + "could not get UART0 pinctrl\n"); + else { + u0_def = pinctrl_lookup_state(u0_p, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(u0_def)) { + dev_err(&uart0_device->dev, + "could not get UART0 defstate\n"); + } + u0_sleep = pinctrl_lookup_state(u0_p, + PINCTRL_STATE_SLEEP); + if (IS_ERR(u0_sleep)) + dev_err(&uart0_device->dev, + "could not get UART0 idlestate\n"); + } + } db8500_add_uart1(parent, &uart1_plat); db8500_add_uart2(parent, &uart2_plat); } @@ -625,6 +677,11 @@ static struct platform_device *snowball_platform_devs[] __initdata = { &ab8500_device, }; +static struct platform_device *snowball_of_platform_devs[] __initdata = { + &snowball_led_dev, + &snowball_key_dev, +}; + static void __init mop500_init_machine(void) { struct device *parent = NULL; @@ -764,11 +821,6 @@ MACHINE_END #ifdef CONFIG_MACH_UX500_DT -static struct platform_device *snowball_of_platform_devs[] __initdata = { - &snowball_led_dev, - &snowball_key_dev, -}; - struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires DMA and call-back bindings. */ OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat), @@ -786,8 +838,6 @@ struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL), OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL), OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL), - /* Requires device name bindings. */ - OF_DEV_AUXDATA("stericsson,nmk_pinctrl", 0, "pinctrl-db8500", NULL), {}, }; diff --git a/trunk/arch/arm/mach-ux500/timer.c b/trunk/arch/arm/mach-ux500/timer.c index 66e7f00884ab..741e71feca78 100644 --- a/trunk/arch/arm/mach-ux500/timer.c +++ b/trunk/arch/arm/mach-ux500/timer.c @@ -63,10 +63,8 @@ static void __init ux500_timer_init(void) /* TODO: Once MTU has been DT:ed place code above into else. */ if (of_have_populated_dt()) { -#ifdef CONFIG_OF np = of_find_matching_node(NULL, prcmu_timer_of_match); if (!np) -#endif goto dt_fail; tmp_base = of_iomap(np, 0); diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index cd8ea3588f93..cf4687ee2a7b 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -169,13 +169,26 @@ static struct map_desc versatile_io_desc[] __initdata = { .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), .length = VERSATILE_PCI_CFG_BASE_SIZE, .type = MT_DEVICE - }, { - .virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0, + }, +#if 0 + { + .virtual = VERSATILE_PCI_VIRT_MEM_BASE0, .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), - .length = IO_SPACE_LIMIT, + .length = SZ_16M, + .type = MT_DEVICE + }, { + .virtual = VERSATILE_PCI_VIRT_MEM_BASE1, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), + .length = SZ_16M, + .type = MT_DEVICE + }, { + .virtual = VERSATILE_PCI_VIRT_MEM_BASE2, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2), + .length = SZ_16M, .type = MT_DEVICE }, #endif +#endif }; void __init versatile_map_io(void) diff --git a/trunk/arch/arm/mach-versatile/include/mach/hardware.h b/trunk/arch/arm/mach-versatile/include/mach/hardware.h index 408e58da46c6..4d4973dd8fba 100644 --- a/trunk/arch/arm/mach-versatile/include/mach/hardware.h +++ b/trunk/arch/arm/mach-versatile/include/mach/hardware.h @@ -29,9 +29,8 @@ */ #define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul #define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul -#define VERSATILE_PCI_VIRT_MEM_BASE0 (void __iomem *)PCIO_BASE -/* macro to get at MMIO space when running virtually */ +/* macro to get at IO space when running virtually */ #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) #define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n)) diff --git a/trunk/arch/arm/mach-versatile/include/mach/io.h b/trunk/arch/arm/mach-versatile/include/mach/io.h deleted file mode 100644 index 0406513be7d8..000000000000 --- a/trunk/arch/arm/mach-versatile/include/mach/io.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/io.h - * - * Copyright (C) 2003 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define PCIO_BASE 0xeb000000ul - -#define __io(a) ((a) + PCIO_BASE) - -#endif diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index e95bf84cc837..15c6a00000ec 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -169,18 +169,11 @@ static struct pci_ops pci_versatile_ops = { .write = versatile_write_config, }; -static struct resource io_port = { - .name = "PCI", - .start = 0, - .end = IO_SPACE_LIMIT, - .flags = IORESOURCE_IO, -}; - static struct resource io_mem = { .name = "PCI I/O space", .start = VERSATILE_PCI_MEM_BASE0, .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }; static struct resource non_mem = { @@ -207,12 +200,6 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) "memory region (%d)\n", ret); goto out; } - ret = request_resource(&ioport_resource, &io_port); - if (ret) { - printk(KERN_ERR "PCI: unable to allocate I/O " - "port region (%d)\n", ret); - goto out; - } ret = request_resource(&iomem_resource, &non_mem); if (ret) { printk(KERN_ERR "PCI: unable to allocate non-prefetchable " @@ -231,7 +218,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource_offset(&sys->resources, &io_port, sys->io_offset); + pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); @@ -262,7 +249,6 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) if (nr == 0) { sys->mem_offset = 0; - sys->io_offset = 0; ret = pci_versatile_setup_resources(sys); if (ret < 0) { printk("pci_versatile_setup: resources... oops?\n"); @@ -339,6 +325,7 @@ void __init pci_versatile_preinit(void) static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; + int devslot = PCI_SLOT(dev->devfn); /* slot, pin, irq * 24 1 27 diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index 655878bcc96d..ea6b43154090 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -228,7 +228,7 @@ static pte_t **consistent_pte; #define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M -static unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE; +unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE; void __init init_consistent_dma_size(unsigned long size) { @@ -268,8 +268,10 @@ static int __init consistent_init(void) unsigned long base = consistent_base; unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT; - if (IS_ENABLED(CONFIG_CMA) && !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) +#ifndef CONFIG_ARM_DMA_USE_IOMMU + if (cpu_architecture() >= CPU_ARCH_ARMv6) return 0; +#endif consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL); if (!consistent_pte) { @@ -321,7 +323,7 @@ static struct arm_vmregion_head coherent_head = { .vm_list = LIST_HEAD_INIT(coherent_head.vm_list), }; -static size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8; +size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8; static int __init early_coherent_pool(char *p) { @@ -340,7 +342,7 @@ static int __init coherent_init(void) struct page *page; void *ptr; - if (!IS_ENABLED(CONFIG_CMA)) + if (cpu_architecture() < CPU_ARCH_ARMv6) return 0; ptr = __alloc_from_contiguous(NULL, size, prot, &page); @@ -702,7 +704,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, if (arch_is_coherent() || nommu()) addr = __alloc_simple_buffer(dev, size, gfp, &page); - else if (!IS_ENABLED(CONFIG_CMA)) + else if (cpu_architecture() < CPU_ARCH_ARMv6) addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); else if (gfp & GFP_ATOMIC) addr = __alloc_from_pool(dev, size, &page, caller); @@ -771,7 +773,7 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, if (arch_is_coherent() || nommu()) { __dma_free_buffer(page, size); - } else if (!IS_ENABLED(CONFIG_CMA)) { + } else if (cpu_architecture() < CPU_ARCH_ARMv6) { __dma_free_remap(cpu_addr, size); __dma_free_buffer(page, size); } else { @@ -1067,7 +1069,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t return NULL; while (count) { - int j, order = __fls(count); + int j, order = __ffs(count); pages[i] = alloc_pages(gfp | __GFP_NOWARN, order); while (!pages[i] && order) @@ -1091,7 +1093,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t while (--i) if (pages[i]) __free_pages(pages[i], 0); - if (array_size <= PAGE_SIZE) + if (array_size < PAGE_SIZE) kfree(pages); else vfree(pages); @@ -1106,7 +1108,7 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t s for (i = 0; i < count; i++) if (pages[i]) __free_pages(pages[i], 0); - if (array_size <= PAGE_SIZE) + if (array_size < PAGE_SIZE) kfree(pages); else vfree(pages); diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index f54d59219764..c21d06c7dd7e 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -212,7 +212,7 @@ EXPORT_SYMBOL(arm_dma_zone_size); * allocations. This must be the smallest DMA mask in the system, * so a successful GFP_DMA allocation will always satisfy this. */ -phys_addr_t arm_dma_limit; +u32 arm_dma_limit; static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, unsigned long dma_size) diff --git a/trunk/arch/arm/mm/mm.h b/trunk/arch/arm/mm/mm.h index 2e8a1efdf7b8..93dc0c17cdcb 100644 --- a/trunk/arch/arm/mm/mm.h +++ b/trunk/arch/arm/mm/mm.h @@ -62,9 +62,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page #endif #ifdef CONFIG_ZONE_DMA -extern phys_addr_t arm_dma_limit; +extern u32 arm_dma_limit; #else -#define arm_dma_limit ((phys_addr_t)~0) +#define arm_dma_limit ((u32)~0) #endif extern phys_addr_t arm_lowmem_limit; diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index cf4528d51774..e5dad60b558b 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -791,79 +791,6 @@ void __init iotable_init(struct map_desc *io_desc, int nr) } } -#ifndef CONFIG_ARM_LPAE - -/* - * The Linux PMD is made of two consecutive section entries covering 2MB - * (see definition in include/asm/pgtable-2level.h). However a call to - * create_mapping() may optimize static mappings by using individual - * 1MB section mappings. This leaves the actual PMD potentially half - * initialized if the top or bottom section entry isn't used, leaving it - * open to problems if a subsequent ioremap() or vmalloc() tries to use - * the virtual space left free by that unused section entry. - * - * Let's avoid the issue by inserting dummy vm entries covering the unused - * PMD halves once the static mappings are in place. - */ - -static void __init pmd_empty_section_gap(unsigned long addr) -{ - struct vm_struct *vm; - - vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm)); - vm->addr = (void *)addr; - vm->size = SECTION_SIZE; - vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; - vm->caller = pmd_empty_section_gap; - vm_area_add_early(vm); -} - -static void __init fill_pmd_gaps(void) -{ - struct vm_struct *vm; - unsigned long addr, next = 0; - pmd_t *pmd; - - /* we're still single threaded hence no lock needed here */ - for (vm = vmlist; vm; vm = vm->next) { - if (!(vm->flags & VM_ARM_STATIC_MAPPING)) - continue; - addr = (unsigned long)vm->addr; - if (addr < next) - continue; - - /* - * Check if this vm starts on an odd section boundary. - * If so and the first section entry for this PMD is free - * then we block the corresponding virtual address. - */ - if ((addr & ~PMD_MASK) == SECTION_SIZE) { - pmd = pmd_off_k(addr); - if (pmd_none(*pmd)) - pmd_empty_section_gap(addr & PMD_MASK); - } - - /* - * Then check if this vm ends on an odd section boundary. - * If so and the second section entry for this PMD is empty - * then we block the corresponding virtual address. - */ - addr += vm->size; - if ((addr & ~PMD_MASK) == SECTION_SIZE) { - pmd = pmd_off_k(addr) + 1; - if (pmd_none(*pmd)) - pmd_empty_section_gap(addr); - } - - /* no need to look at any vm entry until we hit the next PMD */ - next = (addr + PMD_SIZE - 1) & PMD_MASK; - } -} - -#else -#define fill_pmd_gaps() do { } while (0) -#endif - static void * __initdata vmalloc_min = (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); @@ -1145,7 +1072,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc) */ if (mdesc->map_io) mdesc->map_io(); - fill_pmd_gaps(); /* * Finally flush the caches and tlb to ensure that we're in a diff --git a/trunk/arch/arm/net/bpf_jit_32.c b/trunk/arch/arm/net/bpf_jit_32.c index c641fb685017..62135849f48b 100644 --- a/trunk/arch/arm/net/bpf_jit_32.c +++ b/trunk/arch/arm/net/bpf_jit_32.c @@ -762,11 +762,6 @@ static int build_body(struct jit_ctx *ctx) update_on_xread(ctx); emit(ARM_MOV_R(r_A, r_X), ctx); break; - case BPF_S_ANC_ALU_XOR_X: - /* A ^= X */ - update_on_xread(ctx); - emit(ARM_EOR_R(r_A, r_A, r_X), ctx); - break; case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol) */ ctx->seen |= SEEN_SKB; diff --git a/trunk/arch/arm/net/bpf_jit_32.h b/trunk/arch/arm/net/bpf_jit_32.h index 7fa2f7d3cb90..99ae5e3f46d2 100644 --- a/trunk/arch/arm/net/bpf_jit_32.h +++ b/trunk/arch/arm/net/bpf_jit_32.h @@ -68,8 +68,6 @@ #define ARM_INST_CMP_R 0x01500000 #define ARM_INST_CMP_I 0x03500000 -#define ARM_INST_EOR_R 0x00200000 - #define ARM_INST_LDRB_I 0x05d00000 #define ARM_INST_LDRB_R 0x07d00000 #define ARM_INST_LDRH_I 0x01d000b0 @@ -134,8 +132,6 @@ #define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm) #define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) -#define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm) - #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ | (off)) #define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ diff --git a/trunk/arch/arm/plat-mxc/epit.c b/trunk/arch/arm/plat-mxc/epit.c index 88726f4dbbfa..9129c9e7d532 100644 --- a/trunk/arch/arm/plat-mxc/epit.c +++ b/trunk/arch/arm/plat-mxc/epit.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -202,16 +201,8 @@ static int __init epit_clockevent_init(struct clk *timer_clk) return 0; } -void __init epit_timer_init(void __iomem *base, int irq) +void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { - struct clk *timer_clk; - - timer_clk = clk_get_sys("imx-epit.0", NULL); - if (IS_ERR(timer_clk)) { - pr_err("i.MX epit: unable to get clk\n"); - return; - } - clk_prepare_enable(timer_clk); timer_base = base; diff --git a/trunk/arch/arm/plat-mxc/include/mach/common.h b/trunk/arch/arm/plat-mxc/include/mach/common.h index e429ca1b814a..cf663d84e7c1 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/common.h +++ b/trunk/arch/arm/plat-mxc/include/mach/common.h @@ -54,8 +54,8 @@ extern void imx50_soc_init(void); extern void imx51_soc_init(void); extern void imx53_soc_init(void); extern void imx51_init_late(void); -extern void epit_timer_init(void __iomem *base, int irq); -extern void mxc_timer_init(void __iomem *, int); +extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); +extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx25_clocks_init(void); diff --git a/trunk/arch/arm/plat-mxc/include/mach/mx2_cam.h b/trunk/arch/arm/plat-mxc/include/mach/mx2_cam.h index 3c080a32dbf5..7ded6f1f74bc 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/mx2_cam.h +++ b/trunk/arch/arm/plat-mxc/include/mach/mx2_cam.h @@ -23,7 +23,6 @@ #ifndef __MACH_MX2_CAM_H_ #define __MACH_MX2_CAM_H_ -#define MX2_CAMERA_SWAP16 (1 << 0) #define MX2_CAMERA_EXT_VSYNC (1 << 1) #define MX2_CAMERA_CCIR (1 << 2) #define MX2_CAMERA_CCIR_INTERLACE (1 << 3) @@ -31,7 +30,6 @@ #define MX2_CAMERA_GATED_CLOCK (1 << 5) #define MX2_CAMERA_INV_DATA (1 << 6) #define MX2_CAMERA_PCLK_SAMPLE_RISING (1 << 7) -#define MX2_CAMERA_PACK_DIR_MSB (1 << 8) /** * struct mx2_camera_platform_data - optional platform data for mx2_camera diff --git a/trunk/arch/arm/plat-mxc/time.c b/trunk/arch/arm/plat-mxc/time.c index 00e8e659e667..99f958ca6cb8 100644 --- a/trunk/arch/arm/plat-mxc/time.c +++ b/trunk/arch/arm/plat-mxc/time.c @@ -58,7 +58,6 @@ /* MX31, MX35, MX25, MX5 */ #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ #define V2_TCTL_CLK_IPG (1 << 6) -#define V2_TCTL_CLK_PER (2 << 6) #define V2_TCTL_FRR (1 << 9) #define V2_IR 0x0c #define V2_TSTAT 0x08 @@ -281,21 +280,22 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) return 0; } -void __init mxc_timer_init(void __iomem *base, int irq) +void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { uint32_t tctl_val; - struct clk *timer_clk; struct clk *timer_ipg_clk; - timer_clk = clk_get_sys("imx-gpt.0", "per"); - if (IS_ERR(timer_clk)) { - pr_err("i.MX timer: unable to get clk\n"); - return; - } + if (!timer_clk) { + timer_clk = clk_get_sys("imx-gpt.0", "per"); + if (IS_ERR(timer_clk)) { + pr_err("i.MX timer: unable to get clk\n"); + return; + } - timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg"); - if (!IS_ERR(timer_ipg_clk)) - clk_prepare_enable(timer_ipg_clk); + timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg"); + if (!IS_ERR(timer_ipg_clk)) + clk_prepare_enable(timer_ipg_clk); + } clk_prepare_enable(timer_clk); @@ -309,7 +309,7 @@ void __init mxc_timer_init(void __iomem *base, int irq) __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ if (timer_is_v2()) - tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; + tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; else tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; diff --git a/trunk/arch/arm/plat-omap/clock.c b/trunk/arch/arm/plat-omap/clock.c index 706b7e29397f..62ec5c452792 100644 --- a/trunk/arch/arm/plat-omap/clock.c +++ b/trunk/arch/arm/plat-omap/clock.c @@ -461,7 +461,6 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused) struct clk *c; struct clk *pa; - mutex_lock(&clocks_mutex); seq_printf(s, "%-30s %-30s %-10s %s\n", "clock-name", "parent-name", "rate", "use-count"); @@ -470,7 +469,6 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused) seq_printf(s, "%-30s %-30s %-10lu %d\n", c->name, pa ? pa->name : "none", c->rate, c->usecount); } - mutex_unlock(&clocks_mutex); return 0; } diff --git a/trunk/arch/arm/plat-omap/include/plat/cpu.h b/trunk/arch/arm/plat-omap/include/plat/cpu.h index de6c0a08f461..297245dba66e 100644 --- a/trunk/arch/arm/plat-omap/include/plat/cpu.h +++ b/trunk/arch/arm/plat-omap/include/plat/cpu.h @@ -252,6 +252,8 @@ IS_AM_SUBCLASS(335x, 0x335) * cpu_is_omap2423(): True for OMAP2423 * cpu_is_omap2430(): True for OMAP2430 * cpu_is_omap3430(): True for OMAP3430 + * cpu_is_omap3505(): True for OMAP3505 + * cpu_is_omap3517(): True for OMAP3517 */ #define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff) @@ -275,6 +277,8 @@ IS_OMAP_TYPE(2422, 0x2422) IS_OMAP_TYPE(2423, 0x2423) IS_OMAP_TYPE(2430, 0x2430) IS_OMAP_TYPE(3430, 0x3430) +IS_OMAP_TYPE(3505, 0x3517) +IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap310() 0 #define cpu_is_omap730() 0 @@ -289,6 +293,12 @@ IS_OMAP_TYPE(3430, 0x3430) #define cpu_is_omap2422() 0 #define cpu_is_omap2423() 0 #define cpu_is_omap2430() 0 +#define cpu_is_omap3503() 0 +#define cpu_is_omap3515() 0 +#define cpu_is_omap3525() 0 +#define cpu_is_omap3530() 0 +#define cpu_is_omap3505() 0 +#define cpu_is_omap3517() 0 #define cpu_is_omap3430() 0 #define cpu_is_omap3630() 0 @@ -340,6 +350,12 @@ IS_OMAP_TYPE(3430, 0x3430) #if defined(CONFIG_ARCH_OMAP3) # undef cpu_is_omap3430 +# undef cpu_is_omap3503 +# undef cpu_is_omap3515 +# undef cpu_is_omap3525 +# undef cpu_is_omap3530 +# undef cpu_is_omap3505 +# undef cpu_is_omap3517 # undef cpu_is_ti81xx # undef cpu_is_ti816x # undef cpu_is_ti814x @@ -347,6 +363,19 @@ IS_OMAP_TYPE(3430, 0x3430) # undef cpu_is_am33xx # undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() +# define cpu_is_omap3503() (cpu_is_omap3430() && \ + (!omap3_has_iva()) && \ + (!omap3_has_sgx())) +# define cpu_is_omap3515() (cpu_is_omap3430() && \ + (!omap3_has_iva()) && \ + (omap3_has_sgx())) +# define cpu_is_omap3525() (cpu_is_omap3430() && \ + (!omap3_has_sgx()) && \ + (omap3_has_iva())) +# define cpu_is_omap3530() (cpu_is_omap3430()) +# define cpu_is_omap3517() is_omap3517() +# define cpu_is_omap3505() (cpu_is_omap3517() && \ + !omap3_has_sgx()) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti81xx() is_ti81xx() @@ -395,6 +424,10 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8)) #define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8)) +#define OMAP3517_CLASS 0x35170034 +#define OMAP3517_REV_ES1_0 OMAP3517_CLASS +#define OMAP3517_REV_ES1_1 (OMAP3517_CLASS | (0x1 << 8)) + #define TI816X_CLASS 0x81600034 #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) diff --git a/trunk/arch/arm/plat-omap/include/plat/mmc.h b/trunk/arch/arm/plat-omap/include/plat/mmc.h index 5493bd95da5e..a7754a886d42 100644 --- a/trunk/arch/arm/plat-omap/include/plat/mmc.h +++ b/trunk/arch/arm/plat-omap/include/plat/mmc.h @@ -172,7 +172,8 @@ struct omap_mmc_platform_data { extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); @@ -184,6 +185,7 @@ static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) { } + #endif extern int omap_msdi_reset(struct omap_hwmod *oh); diff --git a/trunk/arch/arm/plat-orion/common.c b/trunk/arch/arm/plat-orion/common.c index c1793786aea9..61fd837624a8 100644 --- a/trunk/arch/arm/plat-orion/common.c +++ b/trunk/arch/arm/plat-orion/common.c @@ -582,7 +582,7 @@ void __init orion_spi_1_init(unsigned long mapbase) * Watchdog ****************************************************************************/ static struct resource orion_wdt_resource = - DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x28); + DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28); static struct platform_device orion_wdt_device = { .name = "orion_wdt", diff --git a/trunk/arch/arm/plat-pxa/ssp.c b/trunk/arch/arm/plat-pxa/ssp.c index 584c9bf8ed2d..58b79809d20c 100644 --- a/trunk/arch/arm/plat-pxa/ssp.c +++ b/trunk/arch/arm/plat-pxa/ssp.c @@ -193,7 +193,6 @@ static const struct platform_device_id ssp_id_table[] = { { "pxa25x-nssp", PXA25x_NSSP }, { "pxa27x-ssp", PXA27x_SSP }, { "pxa168-ssp", PXA168_SSP }, - { "pxa910-ssp", PXA910_SSP }, { }, }; diff --git a/trunk/arch/arm/plat-samsung/adc.c b/trunk/arch/arm/plat-samsung/adc.c index b1e05ccff3ac..33ecd0c9f0c3 100644 --- a/trunk/arch/arm/plat-samsung/adc.c +++ b/trunk/arch/arm/plat-samsung/adc.c @@ -157,12 +157,10 @@ int s3c_adc_start(struct s3c_adc_client *client, return -EINVAL; } - spin_lock_irqsave(&adc->lock, flags); - - if (client->is_ts && adc->ts_pend) { - spin_unlock_irqrestore(&adc->lock, flags); + if (client->is_ts && adc->ts_pend) return -EAGAIN; - } + + spin_lock_irqsave(&adc->lock, flags); client->channel = channel; client->nr_samples = nr_samples; diff --git a/trunk/arch/arm/plat-samsung/devs.c b/trunk/arch/arm/plat-samsung/devs.c index 6303974c2ee0..1d214cb9d770 100644 --- a/trunk/arch/arm/plat-samsung/devs.c +++ b/trunk/arch/arm/plat-samsung/devs.c @@ -126,8 +126,7 @@ struct platform_device s3c_device_adc = { #ifdef CONFIG_CPU_S3C2440 static struct resource s3c_camif_resource[] = { [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF), - [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C), - [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P), + [1] = DEFINE_RES_IRQ(IRQ_CAM), }; struct platform_device s3c_device_camif = { diff --git a/trunk/arch/arm/plat-samsung/include/plat/map-s3c.h b/trunk/arch/arm/plat-samsung/include/plat/map-s3c.h index c0c70a895ca8..7d048759b772 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/map-s3c.h +++ b/trunk/arch/arm/plat-samsung/include/plat/map-s3c.h @@ -22,7 +22,7 @@ #define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG #define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) -#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00100000) +#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000) #define S3C2410_PA_UART (0x50000000) #define S3C24XX_PA_UART S3C2410_PA_UART diff --git a/trunk/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/trunk/arch/arm/plat-samsung/include/plat/watchdog-reset.h index bc4db9b04e36..f19aff19205c 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/watchdog-reset.h +++ b/trunk/arch/arm/plat-samsung/include/plat/watchdog-reset.h @@ -25,7 +25,7 @@ static inline void arch_wdt_reset(void) __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ - if (!IS_ERR(s3c2410_wdtclk)) + if (s3c2410_wdtclk) clk_enable(s3c2410_wdtclk); /* put initial values into count and data */ diff --git a/trunk/arch/arm/plat-samsung/s5p-clock.c b/trunk/arch/arm/plat-samsung/s5p-clock.c index 48a159911037..031a61899bef 100644 --- a/trunk/arch/arm/plat-samsung/s5p-clock.c +++ b/trunk/arch/arm/plat-samsung/s5p-clock.c @@ -37,7 +37,6 @@ struct clk clk_ext_xtal_mux = { struct clk clk_xusbxti = { .name = "xusbxti", .id = -1, - .rate = 24000000, }; struct clk s5p_clk_27m = { diff --git a/trunk/arch/arm/plat-spear/include/plat/debug-macro.S b/trunk/arch/arm/plat-spear/include/plat/debug-macro.S index 75b05ad0fbad..ab3de721c5db 100644 --- a/trunk/arch/arm/plat-spear/include/plat/debug-macro.S +++ b/trunk/arch/arm/plat-spear/include/plat/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header for spear platform * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/include/plat/pl080.h b/trunk/arch/arm/plat-spear/include/plat/pl080.h index 2bc6b54460a8..e14a3e4932f9 100644 --- a/trunk/arch/arm/plat-spear/include/plat/pl080.h +++ b/trunk/arch/arm/plat-spear/include/plat/pl080.h @@ -4,7 +4,7 @@ * DMAC pl080 definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/include/plat/shirq.h b/trunk/arch/arm/plat-spear/include/plat/shirq.h index 88a7fbd24793..03ed8b585dcf 100644 --- a/trunk/arch/arm/plat-spear/include/plat/shirq.h +++ b/trunk/arch/arm/plat-spear/include/plat/shirq.h @@ -4,7 +4,7 @@ * SPEAr platform shared irq layer header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/include/plat/timex.h b/trunk/arch/arm/plat-spear/include/plat/timex.h index ef95e5b780bd..914d09dd50fd 100644 --- a/trunk/arch/arm/plat-spear/include/plat/timex.h +++ b/trunk/arch/arm/plat-spear/include/plat/timex.h @@ -4,7 +4,7 @@ * SPEAr platform specific timex definitions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/include/plat/uncompress.h b/trunk/arch/arm/plat-spear/include/plat/uncompress.h index 2ce6cb17a98b..6dd455bafdfd 100644 --- a/trunk/arch/arm/plat-spear/include/plat/uncompress.h +++ b/trunk/arch/arm/plat-spear/include/plat/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/pl080.c b/trunk/arch/arm/plat-spear/pl080.c index 12cf27f935f9..a56a067717c1 100644 --- a/trunk/arch/arm/plat-spear/pl080.c +++ b/trunk/arch/arm/plat-spear/pl080.c @@ -4,7 +4,7 @@ * DMAC pl080 definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/restart.c b/trunk/arch/arm/plat-spear/restart.c index 4f990115b1bd..ea0a61302b7e 100644 --- a/trunk/arch/arm/plat-spear/restart.c +++ b/trunk/arch/arm/plat-spear/restart.c @@ -4,7 +4,7 @@ * SPEAr platform specific restart functions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/plat-spear/shirq.c b/trunk/arch/arm/plat-spear/shirq.c index 853e891e1184..961fb7261243 100644 --- a/trunk/arch/arm/plat-spear/shirq.c +++ b/trunk/arch/arm/plat-spear/shirq.c @@ -4,7 +4,7 @@ * SPEAr platform shared irq layer source file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/avr32/kernel/signal.c b/trunk/arch/avr32/kernel/signal.c index d552a854dacc..c140f9b41dce 100644 --- a/trunk/arch/avr32/kernel/signal.c +++ b/trunk/arch/avr32/kernel/signal.c @@ -300,7 +300,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) syscall = 1; - if (ti->flags & _TIF_SIGPENDING) + if (ti->flags & _TIF_SIGPENDING)) do_signal(regs, syscall); if (ti->flags & _TIF_NOTIFY_RESUME) { diff --git a/trunk/arch/blackfin/kernel/process.c b/trunk/arch/blackfin/kernel/process.c index 62bcea7dcc6d..2e3994b20169 100644 --- a/trunk/arch/blackfin/kernel/process.c +++ b/trunk/arch/blackfin/kernel/process.c @@ -173,7 +173,7 @@ asmlinkage int bfin_clone(struct pt_regs *regs) unsigned long newsp; #ifdef __ARCH_SYNC_CORE_DCACHE - if (current->nr_cpus_allowed == num_possible_cpus()) + if (current->rt.nr_cpus_allowed == num_possible_cpus()) set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id())); #endif diff --git a/trunk/arch/h8300/include/asm/pgtable.h b/trunk/arch/h8300/include/asm/pgtable.h index 62ef17676b40..a09230a08e02 100644 --- a/trunk/arch/h8300/include/asm/pgtable.h +++ b/trunk/arch/h8300/include/asm/pgtable.h @@ -70,7 +70,4 @@ extern int is_in_rom(unsigned long); #define VMALLOC_END 0xffffffff #define arch_enter_lazy_cpu_mode() do {} while (0) - -#include - #endif /* _H8300_PGTABLE_H */ diff --git a/trunk/arch/h8300/include/asm/uaccess.h b/trunk/arch/h8300/include/asm/uaccess.h index 8725d1ad4272..356068cd0879 100644 --- a/trunk/arch/h8300/include/asm/uaccess.h +++ b/trunk/arch/h8300/include/asm/uaccess.h @@ -100,6 +100,7 @@ extern int __put_user_bad(void); break; \ default: \ __gu_err = __get_user_bad(); \ + __gu_val = 0; \ break; \ } \ (x) = __gu_val; \ @@ -158,6 +159,4 @@ clear_user(void *to, unsigned long n) return 0; } -#define __clear_user clear_user - #endif /* _H8300_UACCESS_H */ diff --git a/trunk/arch/h8300/kernel/setup.c b/trunk/arch/h8300/kernel/setup.c index d0b1607f2711..68d651081bd3 100644 --- a/trunk/arch/h8300/kernel/setup.c +++ b/trunk/arch/h8300/kernel/setup.c @@ -35,7 +35,6 @@ #include #include #include -#include #if defined(__H8300H__) #define CPU "H8/300H" @@ -55,6 +54,7 @@ unsigned long memory_end; char __initdata command_line[COMMAND_LINE_SIZE]; +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; extern char _target_name[]; extern void h8300_gpio_init(void); @@ -119,9 +119,9 @@ void __init setup_arch(char **cmdline_p) memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS; #endif - init_mm.start_code = (unsigned long) _stext; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; + init_mm.start_code = (unsigned long) &_stext; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) 0; #if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT) @@ -134,12 +134,15 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "H8/300 series support by Yoshinori Sato \n"); #ifdef DEBUG - printk(KERN_DEBUG "KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p " - "BSS=0x%p-0x%p\n", _stext, _etext, _sdata, _edata, __bss_start, - __bss_stop); - printk(KERN_DEBUG "KERNEL -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx " - "STACK=0x%06lx-0x%p\n", __bss_stop, memory_start, memory_start, - memory_end, memory_end, &_ramend); + printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " + "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, + (int) &_sdata, (int) &_edata, + (int) &_sbss, (int) &_ebss); + printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " + "STACK=0x%06x-0x%06x\n", + (int) &_ebss, (int) memory_start, + (int) memory_start, (int) memory_end, + (int) memory_end, (int) &_ramend); #endif #ifdef CONFIG_DEFAULT_CMDLINE diff --git a/trunk/arch/h8300/kernel/signal.c b/trunk/arch/h8300/kernel/signal.c index 5adaadaf9218..fca10378701b 100644 --- a/trunk/arch/h8300/kernel/signal.c +++ b/trunk/arch/h8300/kernel/signal.c @@ -447,7 +447,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -static void do_signal(struct pt_regs *regs) +statis void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; diff --git a/trunk/arch/h8300/kernel/time.c b/trunk/arch/h8300/kernel/time.c index e0f74191d553..32263a138aa6 100644 --- a/trunk/arch/h8300/kernel/time.c +++ b/trunk/arch/h8300/kernel/time.c @@ -27,7 +27,6 @@ #include #include -#include #include #define TICK_SIZE (tick_nsec / 1000) diff --git a/trunk/arch/h8300/mm/init.c b/trunk/arch/h8300/mm/init.c index 981e25094b1a..973369c32a95 100644 --- a/trunk/arch/h8300/mm/init.c +++ b/trunk/arch/h8300/mm/init.c @@ -36,7 +36,6 @@ #include #include #include -#include #undef DEBUG @@ -124,6 +123,7 @@ void __init mem_init(void) int codek = 0, datak = 0, initk = 0; /* DAVIDM look at setup memory map generically with reserved area */ unsigned long tmp; + extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end; extern unsigned long _ramend, _ramstart; unsigned long len = &_ramend - &_ramstart; unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */ @@ -142,9 +142,9 @@ void __init mem_init(void) /* this will put all memory onto the freelists */ totalram_pages = free_all_bootmem(); - codek = (_etext - _stext) >> 10; - datak = (__bss_stop - _sdata) >> 10; - initk = (__init_begin - __init_end) >> 10; + codek = (&_etext - &_stext) >> 10; + datak = (&_ebss - &_sdata) >> 10; + initk = (&__init_begin - &__init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n", @@ -178,21 +178,22 @@ free_initmem(void) { #ifdef CONFIG_RAMKERNEL unsigned long addr; + extern char __init_begin, __init_end; /* * the following code should be cool even if these sections * are not page aligned. */ - addr = PAGE_ALIGN((unsigned long)(__init_begin)); + addr = PAGE_ALIGN((unsigned long)(&__init_begin)); /* next to check that the page we free is not a partial page */ - for (; addr + PAGE_SIZE < (unsigned long)__init_end; addr +=PAGE_SIZE) { + for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); totalram_pages++; } printk(KERN_INFO "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", - (addr - PAGE_ALIGN((long) __init_begin)) >> 10, - (int)(PAGE_ALIGN((unsigned long)__init_begin)), + (addr - PAGE_ALIGN((long) &__init_begin)) >> 10, + (int)(PAGE_ALIGN((unsigned long)(&__init_begin))), (int)(addr - PAGE_SIZE)); #endif } diff --git a/trunk/arch/hexagon/kernel/smp.c b/trunk/arch/hexagon/kernel/smp.c index 149fbefc1a4d..f7264621e58d 100644 --- a/trunk/arch/hexagon/kernel/smp.c +++ b/trunk/arch/hexagon/kernel/smp.c @@ -180,7 +180,9 @@ void __cpuinit start_secondary(void) notify_cpu_starting(cpu); + ipi_call_lock(); set_cpu_online(cpu, true); + ipi_call_unlock(); local_irq_enable(); diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 963d2db53bfa..1113b8aba07f 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -382,6 +382,7 @@ smp_callin (void) set_numa_node(cpu_to_node_map[cpuid]); set_numa_mem(local_memory_node(cpu_to_node_map[cpuid])); + ipi_call_lock_irq(); spin_lock(&vector_lock); /* Setup the per cpu irq handling data structures */ __setup_vector_irq(cpuid); @@ -389,6 +390,7 @@ smp_callin (void) set_cpu_online(cpuid, true); per_cpu(cpu_state, cpuid) = CPU_ONLINE; spin_unlock(&vector_lock); + ipi_call_unlock_irq(); smp_setup_percpu_timer(); diff --git a/trunk/arch/m32r/boot/compressed/Makefile b/trunk/arch/m32r/boot/compressed/Makefile index 01729c2979ba..177716b1d613 100644 --- a/trunk/arch/m32r/boot/compressed/Makefile +++ b/trunk/arch/m32r/boot/compressed/Makefile @@ -43,9 +43,9 @@ endif OBJCOPYFLAGS += -R .empty_zero_page -suffix-$(CONFIG_KERNEL_GZIP) = gz -suffix-$(CONFIG_KERNEL_BZIP2) = bz2 -suffix-$(CONFIG_KERNEL_LZMA) = lzma +suffix_$(CONFIG_KERNEL_GZIP) = gz +suffix_$(CONFIG_KERNEL_BZIP2) = bz2 +suffix_$(CONFIG_KERNEL_LZMA) = lzma $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE $(call if_changed,ld) diff --git a/trunk/arch/m32r/boot/compressed/misc.c b/trunk/arch/m32r/boot/compressed/misc.c index 28a09529f206..370d60881977 100644 --- a/trunk/arch/m32r/boot/compressed/misc.c +++ b/trunk/arch/m32r/boot/compressed/misc.c @@ -28,7 +28,7 @@ static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; #ifdef CONFIG_KERNEL_BZIP2 -void *memset(void *s, int c, size_t n) +static void *memset(void *s, int c, size_t n) { char *ss = s; @@ -39,16 +39,6 @@ void *memset(void *s, int c, size_t n) #endif #ifdef CONFIG_KERNEL_GZIP -void *memcpy(void *dest, const void *src, size_t n) -{ - char *d = dest; - const char *s = src; - while (n--) - *d++ = *s++; - - return dest; -} - #define BOOT_HEAP_SIZE 0x10000 #include "../../../../lib/decompress_inflate.c" #endif diff --git a/trunk/arch/m32r/include/asm/ptrace.h b/trunk/arch/m32r/include/asm/ptrace.h index 4313aa62b51b..527527584dd0 100644 --- a/trunk/arch/m32r/include/asm/ptrace.h +++ b/trunk/arch/m32r/include/asm/ptrace.h @@ -113,6 +113,9 @@ struct pt_regs { #define PTRACE_OLDSETOPTIONS 21 +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + #ifdef __KERNEL__ #include /* M32R_PSW_BSM, M32R_PSW_BPM */ diff --git a/trunk/arch/m32r/include/asm/smp.h b/trunk/arch/m32r/include/asm/smp.h index c689b828dfe2..cf7829a61551 100644 --- a/trunk/arch/m32r/include/asm/smp.h +++ b/trunk/arch/m32r/include/asm/smp.h @@ -79,6 +79,11 @@ static __inline__ int cpu_number_map(int cpu) return cpu; } +static __inline__ unsigned int num_booting_cpus(void) +{ + return cpumask_weight(&cpu_callout_map); +} + extern void smp_send_timer(void); extern unsigned long send_IPI_mask_phys(const cpumask_t*, int, int); diff --git a/trunk/arch/m32r/kernel/ptrace.c b/trunk/arch/m32r/kernel/ptrace.c index 51f5e9aa4901..4c03361537aa 100644 --- a/trunk/arch/m32r/kernel/ptrace.c +++ b/trunk/arch/m32r/kernel/ptrace.c @@ -591,16 +591,17 @@ void user_enable_single_step(struct task_struct *child) if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) != sizeof(insn)) - return; + return -EIO; compute_next_pc(insn, pc, &next_pc, child); if (next_pc & 0x80000000) - return; + return -EIO; if (embed_debug_trap(child, next_pc)) - return; + return -EIO; invalidate_cache(); + return 0; } void user_disable_single_step(struct task_struct *child) diff --git a/trunk/arch/m32r/kernel/signal.c b/trunk/arch/m32r/kernel/signal.c index d0f60b97bbc5..f3fb2c029cfc 100644 --- a/trunk/arch/m32r/kernel/signal.c +++ b/trunk/arch/m32r/kernel/signal.c @@ -286,7 +286,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, case -ERESTARTNOINTR: regs->r0 = regs->orig_r0; if (prev_insn(regs) < 0) - return; + return -EFAULT; } } diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 147120128260..cac5b6be572a 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -7,8 +7,6 @@ config M68K select GENERIC_IRQ_SHOW select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS select GENERIC_CPU_DEVICES - select GENERIC_STRNCPY_FROM_USER if MMU - select GENERIC_STRNLEN_USER if MMU select FPU if MMU select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE diff --git a/trunk/arch/m68k/include/asm/Kbuild b/trunk/arch/m68k/include/asm/Kbuild index eafa2539a8ee..1a922fad76f7 100644 --- a/trunk/arch/m68k/include/asm/Kbuild +++ b/trunk/arch/m68k/include/asm/Kbuild @@ -1,4 +1,2 @@ include include/asm-generic/Kbuild.asm header-y += cachectl.h - -generic-y += word-at-a-time.h diff --git a/trunk/arch/m68k/include/asm/m528xsim.h b/trunk/arch/m68k/include/asm/m528xsim.h index 497c31c803ff..d63b99ff7ff7 100644 --- a/trunk/arch/m68k/include/asm/m528xsim.h +++ b/trunk/arch/m68k/include/asm/m528xsim.h @@ -86,7 +86,7 @@ /* * QSPI module. */ -#define MCFQSPI_BASE (MCF_IPSBAR + 0x340) +#define MCFQSPI_IOBASE (MCF_IPSBAR + 0x340) #define MCFQSPI_SIZE 0x40 #define MCFQSPI_CS0 147 diff --git a/trunk/arch/m68k/include/asm/uaccess_mm.h b/trunk/arch/m68k/include/asm/uaccess_mm.h index 472c891a4aee..9c80cd515b20 100644 --- a/trunk/arch/m68k/include/asm/uaccess_mm.h +++ b/trunk/arch/m68k/include/asm/uaccess_mm.h @@ -379,15 +379,12 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n) #define copy_from_user(to, from, n) __copy_from_user(to, from, n) #define copy_to_user(to, from, n) __copy_to_user(to, from, n) -#define user_addr_max() \ - (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) - -extern long strncpy_from_user(char *dst, const char __user *src, long count); -extern __must_check long strlen_user(const char __user *str); -extern __must_check long strnlen_user(const char __user *str, long n); - +long strncpy_from_user(char *dst, const char __user *src, long count); +long strnlen_user(const char __user *src, long n); unsigned long __clear_user(void __user *to, unsigned long n); #define clear_user __clear_user +#define strlen_user(str) strnlen_user(str, 32767) + #endif /* _M68K_UACCESS_H */ diff --git a/trunk/arch/m68k/kernel/ptrace.c b/trunk/arch/m68k/kernel/ptrace.c index 1bc10e62b9af..8b4a2222e658 100644 --- a/trunk/arch/m68k/kernel/ptrace.c +++ b/trunk/arch/m68k/kernel/ptrace.c @@ -286,7 +286,7 @@ asmlinkage void syscall_trace(void) } } -#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) +#ifdef CONFIG_COLDFIRE asmlinkage int syscall_trace_enter(void) { int ret = 0; diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 707f0573ec6b..d7deb7fc7eb5 100644 --- a/trunk/arch/m68k/kernel/time.c +++ b/trunk/arch/m68k/kernel/time.c @@ -85,7 +85,7 @@ void __init time_init(void) mach_sched_init(timer_interrupt); } -#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET +#ifdef CONFIG_M68KCLASSIC u32 arch_gettimeoffset(void) { @@ -108,4 +108,4 @@ static int __init rtc_init(void) module_init(rtc_init); -#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */ +#endif /* CONFIG_M68KCLASSIC */ diff --git a/trunk/arch/m68k/lib/uaccess.c b/trunk/arch/m68k/lib/uaccess.c index 5e97f2ee7c11..5664386338da 100644 --- a/trunk/arch/m68k/lib/uaccess.c +++ b/trunk/arch/m68k/lib/uaccess.c @@ -103,6 +103,80 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from, } EXPORT_SYMBOL(__generic_copy_to_user); +/* + * Copy a null terminated string from userspace. + */ +long strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res; + char c; + + if (count <= 0) + return count; + + asm volatile ("\n" + "1: "MOVES".b (%2)+,%4\n" + " move.b %4,(%1)+\n" + " jeq 2f\n" + " subq.l #1,%3\n" + " jne 1b\n" + "2: sub.l %3,%0\n" + "3:\n" + " .section .fixup,\"ax\"\n" + " .even\n" + "10: move.l %5,%0\n" + " jra 3b\n" + " .previous\n" + "\n" + " .section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,10b\n" + " .previous" + : "=d" (res), "+a" (dst), "+a" (src), "+r" (count), "=&d" (c) + : "i" (-EFAULT), "0" (count)); + + return res; +} +EXPORT_SYMBOL(strncpy_from_user); + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 on exception, a value greater than N if too long + */ +long strnlen_user(const char __user *src, long n) +{ + char c; + long res; + + asm volatile ("\n" + "1: subq.l #1,%1\n" + " jmi 3f\n" + "2: "MOVES".b (%0)+,%2\n" + " tst.b %2\n" + " jne 1b\n" + " jra 4f\n" + "\n" + "3: addq.l #1,%0\n" + "4: sub.l %4,%0\n" + "5:\n" + " .section .fixup,\"ax\"\n" + " .even\n" + "20: sub.l %0,%0\n" + " jra 5b\n" + " .previous\n" + "\n" + " .section __ex_table,\"a\"\n" + " .align 4\n" + " .long 2b,20b\n" + " .previous\n" + : "=&a" (res), "+d" (n), "=&d" (c) + : "0" (src), "r" (src)); + + return res; +} +EXPORT_SYMBOL(strnlen_user); + /* * Zero Userspace */ diff --git a/trunk/arch/m68k/platform/68328/timers.c b/trunk/arch/m68k/platform/68328/timers.c index f4dc9b295609..c801c172b822 100644 --- a/trunk/arch/m68k/platform/68328/timers.c +++ b/trunk/arch/m68k/platform/68328/timers.c @@ -53,7 +53,6 @@ #endif static u32 m68328_tick_cnt; -static irq_handler_t timer_interrupt; /***************************************************************************/ @@ -63,7 +62,7 @@ static irqreturn_t hw_tick(int irq, void *dummy) TSTAT &= 0; m68328_tick_cnt += TICKS_PER_JIFFY; - return timer_interrupt(irq, dummy); + return arch_timer_interrupt(irq, dummy); } /***************************************************************************/ @@ -100,7 +99,7 @@ static struct clocksource m68328_clk = { /***************************************************************************/ -void hw_timer_init(irq_handler_t handler) +void hw_timer_init(void) { /* disable timer 1 */ TCTL = 0; @@ -116,7 +115,6 @@ void hw_timer_init(irq_handler_t handler) /* Enable timer 1 */ TCTL |= TCTL_TEN; clocksource_register_hz(&m68328_clk, TICKS_PER_JIFFY*HZ); - timer_interrupt = handler; } /***************************************************************************/ diff --git a/trunk/arch/m68k/platform/68360/config.c b/trunk/arch/m68k/platform/68360/config.c index 9877cefad1e7..255fc03913e9 100644 --- a/trunk/arch/m68k/platform/68360/config.c +++ b/trunk/arch/m68k/platform/68360/config.c @@ -35,7 +35,6 @@ extern void m360_cpm_reset(void); #define OSCILLATOR (unsigned long int)33000000 #endif -static irq_handler_t timer_interrupt; unsigned long int system_clock; extern QUICC *pquicc; @@ -53,7 +52,7 @@ static irqreturn_t hw_tick(int irq, void *dummy) pquicc->timer_ter1 = 0x0002; /* clear timer event */ - return timer_interrupt(irq, dummy); + return arch_timer_interrupt(irq, dummy); } static struct irqaction m68360_timer_irq = { @@ -62,7 +61,7 @@ static struct irqaction m68360_timer_irq = { .handler = hw_tick, }; -void hw_timer_init(irq_handler_t handler) +void hw_timer_init(void) { unsigned char prescaler; unsigned short tgcr_save; @@ -95,8 +94,6 @@ void hw_timer_init(irq_handler_t handler) pquicc->timer_ter1 = 0x0003; /* clear timer events */ - timer_interrupt = handler; - /* enable timer 1 interrupt in CIMR */ setup_irq(CPMVEC_TIMER1, &m68360_timer_irq); diff --git a/trunk/arch/m68k/platform/coldfire/clk.c b/trunk/arch/m68k/platform/coldfire/clk.c index 44da406897e5..9f1260c5e2ad 100644 --- a/trunk/arch/m68k/platform/coldfire/clk.c +++ b/trunk/arch/m68k/platform/coldfire/clk.c @@ -42,11 +42,4 @@ unsigned long clk_get_rate(struct clk *clk) return MCF_CLK; } EXPORT_SYMBOL(clk_get_rate); - -struct clk *devm_clk_get(struct device *dev, const char *id) -{ - return NULL; -} -EXPORT_SYMBOL(devm_clk_get); - /***************************************************************************/ diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index b3e10fdd3898..09ab87ee6fef 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -288,7 +288,6 @@ config MIPS_MALTA select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_CPU_MIPS64_R1 - select SYS_HAS_CPU_MIPS64_R2 select SYS_HAS_CPU_NEVADA select SYS_HAS_CPU_RM7000 select SYS_HAS_EARLY_PRINTK @@ -1424,7 +1423,6 @@ config CPU_SB1 config CPU_CAVIUM_OCTEON bool "Cavium Octeon processor" depends on SYS_HAS_CPU_CAVIUM_OCTEON - select ARCH_SPARSEMEM_ENABLE select CPU_HAS_PREFETCH select CPU_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_SMP diff --git a/trunk/arch/mips/bcm47xx/Kconfig b/trunk/arch/mips/bcm47xx/Kconfig index b311be45a720..6210b8d84109 100644 --- a/trunk/arch/mips/bcm47xx/Kconfig +++ b/trunk/arch/mips/bcm47xx/Kconfig @@ -21,7 +21,6 @@ config BCM47XX_BCMA select BCMA select BCMA_HOST_SOC select BCMA_DRIVER_MIPS - select BCMA_HOST_PCI if PCI select BCMA_DRIVER_PCI_HOSTMODE if PCI default y help diff --git a/trunk/arch/mips/bcm63xx/dev-pcmcia.c b/trunk/arch/mips/bcm63xx/dev-pcmcia.c index a551bab5ecb9..de4d917fd54d 100644 --- a/trunk/arch/mips/bcm63xx/dev-pcmcia.c +++ b/trunk/arch/mips/bcm63xx/dev-pcmcia.c @@ -79,11 +79,11 @@ static int __init config_pcmcia_cs(unsigned int cs, return ret; } -static const struct { +static const __initdata struct { unsigned int cs; unsigned int base; unsigned int size; -} pcmcia_cs[3] __initconst = { +} pcmcia_cs[3] = { { .cs = MPI_CS_PCMCIA_COMMON, .base = BCM_PCMCIA_COMMON_BASE_PA, diff --git a/trunk/arch/mips/cavium-octeon/Kconfig b/trunk/arch/mips/cavium-octeon/Kconfig index 2f4f6d5e05b6..f9e275a50d98 100644 --- a/trunk/arch/mips/cavium-octeon/Kconfig +++ b/trunk/arch/mips/cavium-octeon/Kconfig @@ -82,6 +82,10 @@ config CAVIUM_OCTEON_LOCK_L2_MEMCPY help Lock the kernel's implementation of memcpy() into L2. +config ARCH_SPARSEMEM_ENABLE + def_bool y + select SPARSEMEM_STATIC + config IOMMU_HELPER bool diff --git a/trunk/arch/mips/cavium-octeon/smp.c b/trunk/arch/mips/cavium-octeon/smp.c index ee1fb9f7f517..4b93048044eb 100644 --- a/trunk/arch/mips/cavium-octeon/smp.c +++ b/trunk/arch/mips/cavium-octeon/smp.c @@ -185,6 +185,7 @@ static void __cpuinit octeon_init_secondary(void) octeon_init_cvmcount(); octeon_irq_setup_secondary(); + raw_local_irq_enable(); } /** @@ -232,7 +233,6 @@ static void octeon_smp_finish(void) /* to generate the first CPU timer interrupt */ write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); - local_irq_enable(); } /** diff --git a/trunk/arch/mips/include/asm/bitops.h b/trunk/arch/mips/include/asm/bitops.h index 82ad35ce2b45..2e1ad4c652b7 100644 --- a/trunk/arch/mips/include/asm/bitops.h +++ b/trunk/arch/mips/include/asm/bitops.h @@ -17,6 +17,7 @@ #include #include #include +#include #include /* sigh ... */ #include #include diff --git a/trunk/arch/mips/include/asm/cmpxchg.h b/trunk/arch/mips/include/asm/cmpxchg.h index eee10dc07ac1..285a41fa0b18 100644 --- a/trunk/arch/mips/include/asm/cmpxchg.h +++ b/trunk/arch/mips/include/asm/cmpxchg.h @@ -8,7 +8,6 @@ #ifndef __ASM_CMPXCHG_H #define __ASM_CMPXCHG_H -#include #include #include diff --git a/trunk/arch/mips/include/asm/cpu.h b/trunk/arch/mips/include/asm/cpu.h index 95e40c1e8ed1..f9fa2a479dd0 100644 --- a/trunk/arch/mips/include/asm/cpu.h +++ b/trunk/arch/mips/include/asm/cpu.h @@ -94,7 +94,6 @@ #define PRID_IMP_24KE 0x9600 #define PRID_IMP_74K 0x9700 #define PRID_IMP_1004K 0x9900 -#define PRID_IMP_M14KC 0x9c00 /* * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE @@ -261,12 +260,12 @@ enum cpu_type_enum { */ CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, - CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC, + CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, /* * MIPS64 class processors */ - CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, + CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2, CPU_XLR, CPU_XLP, @@ -289,7 +288,7 @@ enum cpu_type_enum { #define MIPS_CPU_ISA_M64R2 0x00000100 #define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \ - MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2) + MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 ) #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \ MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2) diff --git a/trunk/arch/mips/include/asm/gic.h b/trunk/arch/mips/include/asm/gic.h index 991b659e2548..86548da650e7 100644 --- a/trunk/arch/mips/include/asm/gic.h +++ b/trunk/arch/mips/include/asm/gic.h @@ -206,7 +206,7 @@ #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 #define GIC_VPE_EIC_SS(intr) \ - (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr)) + (GIC_EIC_SHADOW_SET_BASE + (4 * intr)) #define GIC_VPE_EIC_VEC_BASE 0x0800 #define GIC_VPE_EIC_VEC(intr) \ @@ -330,17 +330,6 @@ struct gic_intr_map { #define GIC_FLAG_TRANSPARENT 0x02 }; -/* - * This is only used in EIC mode. This helps to figure out which - * shared interrupts we need to process when we get a vector interrupt. - */ -#define GIC_MAX_SHARED_INTR 0x5 -struct gic_shared_intr_map { - unsigned int num_shared_intr; - unsigned int intr_list[GIC_MAX_SHARED_INTR]; - unsigned int local_intr_mask; -}; - extern void gic_init(unsigned long gic_base_addr, unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, unsigned int intrmap_size, unsigned int irqbase); @@ -349,7 +338,5 @@ extern unsigned int gic_get_int(void); extern void gic_send_ipi(unsigned int intr); extern unsigned int plat_ipi_call_int_xlate(unsigned int); extern unsigned int plat_ipi_resched_int_xlate(unsigned int); -extern void gic_bind_eic_interrupt(int irq, int set); -extern unsigned int gic_get_timer_pending(void); #endif /* _ASM_GICREGS_H */ diff --git a/trunk/arch/mips/include/asm/inst.h b/trunk/arch/mips/include/asm/inst.h index ab84064283db..7ebfc392e58d 100644 --- a/trunk/arch/mips/include/asm/inst.h +++ b/trunk/arch/mips/include/asm/inst.h @@ -251,7 +251,7 @@ struct f_format { /* FPU register format */ unsigned int func : 6; }; -struct ma_format { /* FPU multiply and add format (MIPS IV) */ +struct ma_format { /* FPU multipy and add format (MIPS IV) */ unsigned int opcode : 6; unsigned int fr : 5; unsigned int ft : 5; @@ -324,7 +324,7 @@ struct f_format { /* FPU register format */ unsigned int opcode : 6; }; -struct ma_format { /* FPU multiply and add format (MIPS IV) */ +struct ma_format { /* FPU multipy and add format (MIPS IV) */ unsigned int fmt : 2; unsigned int func : 4; unsigned int fd : 5; diff --git a/trunk/arch/mips/include/asm/io.h b/trunk/arch/mips/include/asm/io.h index 29d9c23c20c7..a58f22998a86 100644 --- a/trunk/arch/mips/include/asm/io.h +++ b/trunk/arch/mips/include/asm/io.h @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/include/asm/irq.h b/trunk/arch/mips/include/asm/irq.h index 78dbb8a86da2..fb698dc09bc9 100644 --- a/trunk/arch/mips/include/asm/irq.h +++ b/trunk/arch/mips/include/asm/irq.h @@ -136,7 +136,6 @@ extern void free_irqno(unsigned int irq); * IE7. Since R2 their number has to be read from the c0_intctl register. */ #define CP0_LEGACY_COMPARE_IRQ 7 -#define CP0_LEGACY_PERFCNT_IRQ 7 extern int cp0_compare_irq; extern int cp0_compare_irq_shift; diff --git a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index fdcd78ca1b03..94d4faad29a1 100644 --- a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -99,7 +99,7 @@ #define CKCTL_6368_USBH_CLK_EN (1 << 15) #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) #define CKCTL_6368_NAND_CLK_EN (1 << 17) -#define CKCTL_6368_IPSEC_CLK_EN (1 << 18) +#define CKCTL_6368_IPSEC_CLK_EN (1 << 17) #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ CKCTL_6368_SWPKT_SAR_EN | \ diff --git a/trunk/arch/mips/include/asm/mips-boards/maltaint.h b/trunk/arch/mips/include/asm/mips-boards/maltaint.h index 5447d9fc4219..d11aa02a956a 100644 --- a/trunk/arch/mips/include/asm/mips-boards/maltaint.h +++ b/trunk/arch/mips/include/asm/mips-boards/maltaint.h @@ -86,16 +86,6 @@ #define GIC_CPU_INT4 4 /* . */ #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ -/* MALTA GIC local interrupts */ -#define GIC_INT_TMR (GIC_CPU_INT5) -#define GIC_INT_PERFCTR (GIC_CPU_INT5) - -/* GIC constants */ -/* Add 2 to convert non-eic hw int # to eic vector # */ -#define GIC_CPU_TO_VEC_OFFSET (2) -/* If we map an intr to pin X, GIC will actually generate vector X+1 */ -#define GIC_PIN_TO_VEC_OFFSET (1) - #define GIC_EXT_INTR(x) x /* External Interrupts used for IPI */ diff --git a/trunk/arch/mips/include/asm/mipsmtregs.h b/trunk/arch/mips/include/asm/mipsmtregs.h index e71ff4c317f2..c9420aa97e32 100644 --- a/trunk/arch/mips/include/asm/mipsmtregs.h +++ b/trunk/arch/mips/include/asm/mipsmtregs.h @@ -48,7 +48,7 @@ #define CP0_VPECONF0 $1, 2 #define CP0_VPECONF1 $1, 3 #define CP0_YQMASK $1, 4 -#define CP0_VPESCHEDULE $1, 5 +#define CP0_VPESCHEDULE $1, 5 #define CP0_VPESCHEFBK $1, 6 #define CP0_TCSTATUS $2, 1 #define CP0_TCBIND $2, 2 diff --git a/trunk/arch/mips/include/asm/switch_to.h b/trunk/arch/mips/include/asm/switch_to.h index 4f8ddba8c360..5d33621b5658 100644 --- a/trunk/arch/mips/include/asm/switch_to.h +++ b/trunk/arch/mips/include/asm/switch_to.h @@ -22,7 +22,7 @@ struct task_struct; * switch_to(n) should switch tasks to task nr n, first * checking that n isn't the current task, in which case it does nothing. */ -extern asmlinkage void *resume(void *last, void *next, void *next_ti, u32 __usedfpu); +extern asmlinkage void *resume(void *last, void *next, void *next_ti); extern unsigned int ll_bit; extern struct task_struct *ll_task; @@ -66,13 +66,11 @@ do { \ #define switch_to(prev, next, last) \ do { \ - u32 __usedfpu; \ __mips_mt_fpaff_switch_to(prev); \ if (cpu_has_dsp) \ __save_dsp(prev); \ __clear_software_ll_bit(); \ - __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \ - (last) = resume(prev, next, task_thread_info(next), __usedfpu); \ + (last) = resume(prev, next, task_thread_info(next)); \ } while (0) #define finish_arch_switch(prev) \ diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index ca97e0ecb64b..e2eca7d10598 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -60,8 +60,6 @@ struct thread_info { register struct thread_info *__current_thread_info __asm__("$28"); #define current_thread_info() __current_thread_info -#endif /* !__ASSEMBLY__ */ - /* thread information allocation */ #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT) #define THREAD_SIZE_ORDER (1) @@ -87,6 +85,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define STACK_WARN (THREAD_SIZE / 8) +#endif /* !__ASSEMBLY__ */ + #define PREEMPT_ACTIVE 0x10000000 /* diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index f4630e1082ab..6ae7ce4ac63e 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -4,7 +4,7 @@ * Copyright (C) xxxx the Anonymous * Copyright (C) 1994 - 2006 Ralf Baechle * Copyright (C) 2003, 2004 Maciej W. Rozycki - * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc. + * Copyright (C) 2001, 2004 MIPS Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -199,7 +199,6 @@ void __init check_wait(void) cpu_wait = rm7k_wait_irqoff; break; - case CPU_M14KC: case CPU_24K: case CPU_34K: case CPU_1004K: @@ -811,10 +810,6 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_5KC; __cpu_name[cpu] = "MIPS 5Kc"; break; - case PRID_IMP_5KE: - c->cputype = CPU_5KE; - __cpu_name[cpu] = "MIPS 5KE"; - break; case PRID_IMP_20KC: c->cputype = CPU_20KC; __cpu_name[cpu] = "MIPS 20Kc"; @@ -836,10 +831,6 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_74K; __cpu_name[cpu] = "MIPS 74Kc"; break; - case PRID_IMP_M14KC: - c->cputype = CPU_M14KC; - __cpu_name[cpu] = "MIPS M14Kc"; - break; case PRID_IMP_1004K: c->cputype = CPU_1004K; __cpu_name[cpu] = "MIPS 1004Kc"; diff --git a/trunk/arch/mips/kernel/mips_ksyms.c b/trunk/arch/mips/kernel/mips_ksyms.c index 3fc1691110dc..57ba13edb03a 100644 --- a/trunk/arch/mips/kernel/mips_ksyms.c +++ b/trunk/arch/mips/kernel/mips_ksyms.c @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05, 12 by Ralf Baechle + * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. */ #include @@ -34,12 +34,6 @@ EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(kernel_thread); -/* - * Functions that operate on entire pages. Mostly used by memory management. - */ -EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(copy_page); - /* * Userspace access stuff. */ diff --git a/trunk/arch/mips/kernel/octeon_switch.S b/trunk/arch/mips/kernel/octeon_switch.S index 0441f54b2a6a..ce89c8061708 100644 --- a/trunk/arch/mips/kernel/octeon_switch.S +++ b/trunk/arch/mips/kernel/octeon_switch.S @@ -31,7 +31,7 @@ /* * task_struct *resume(task_struct *prev, task_struct *next, - * struct thread_info *next_ti, int usedfpu) + * struct thread_info *next_ti) */ .align 7 LEAF(resume) diff --git a/trunk/arch/mips/kernel/perf_event_mipsxx.c b/trunk/arch/mips/kernel/perf_event_mipsxx.c index eb5e394a4650..f29099b104c4 100644 --- a/trunk/arch/mips/kernel/perf_event_mipsxx.c +++ b/trunk/arch/mips/kernel/perf_event_mipsxx.c @@ -162,6 +162,11 @@ static unsigned int counters_total_to_per_cpu(unsigned int counters) return counters >> vpe_shift(); } +static unsigned int counters_per_cpu_to_total(unsigned int counters) +{ + return counters << vpe_shift(); +} + #else /* !CONFIG_MIPS_MT_SMP */ #define vpe_id() 0 diff --git a/trunk/arch/mips/kernel/r2300_switch.S b/trunk/arch/mips/kernel/r2300_switch.S index 9c51be5a163a..293898391e67 100644 --- a/trunk/arch/mips/kernel/r2300_switch.S +++ b/trunk/arch/mips/kernel/r2300_switch.S @@ -43,7 +43,7 @@ /* * task_struct *resume(task_struct *prev, task_struct *next, - * struct thread_info *next_ti, int usedfpu) + * struct thread_info *next_ti) ) */ LEAF(resume) mfc0 t1, CP0_STATUS @@ -51,9 +51,18 @@ LEAF(resume) cpu_save_nonscratch a0 sw ra, THREAD_REG31(a0) - beqz a3, 1f + /* + * check if we need to save FPU registers + */ + lw t3, TASK_THREAD_INFO(a0) + lw t0, TI_FLAGS(t3) + li t1, _TIF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 - PTR_L t3, TASK_THREAD_INFO(a0) + and t0, t0, t1 + sw t0, TI_FLAGS(t3) /* * clear saved user stack CU1 bit diff --git a/trunk/arch/mips/kernel/r4k_switch.S b/trunk/arch/mips/kernel/r4k_switch.S index 42d2a3938420..9414f9354469 100644 --- a/trunk/arch/mips/kernel/r4k_switch.S +++ b/trunk/arch/mips/kernel/r4k_switch.S @@ -41,7 +41,7 @@ /* * task_struct *resume(task_struct *prev, task_struct *next, - * struct thread_info *next_ti, int usedfpu) + * struct thread_info *next_ti) */ .align 5 LEAF(resume) @@ -53,10 +53,16 @@ /* * check if we need to save FPU registers */ + PTR_L t3, TASK_THREAD_INFO(a0) + LONG_L t0, TI_FLAGS(t3) + li t1, _TIF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 - beqz a3, 1f + and t0, t0, t1 + LONG_S t0, TI_FLAGS(t3) - PTR_L t3, TASK_THREAD_INFO(a0) /* * clear saved user stack CU1 bit */ diff --git a/trunk/arch/mips/kernel/smp-bmips.c b/trunk/arch/mips/kernel/smp-bmips.c index 8e393b8443f7..3046e2986006 100644 --- a/trunk/arch/mips/kernel/smp-bmips.c +++ b/trunk/arch/mips/kernel/smp-bmips.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -196,6 +197,13 @@ static void bmips_init_secondary(void) write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); #endif + + /* make sure there won't be a timer interrupt for a little while */ + write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); + + irq_enable_hazard(); + set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); + irq_enable_hazard(); } /* @@ -204,13 +212,6 @@ static void bmips_init_secondary(void) static void bmips_smp_finish(void) { pr_info("SMP: CPU%d is running\n", smp_processor_id()); - - /* make sure there won't be a timer interrupt for a little while */ - write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); - - irq_enable_hazard(); - set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); - irq_enable_hazard(); } /* diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index 1268392f1d27..48650c818040 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -122,21 +122,13 @@ asmlinkage __cpuinit void start_secondary(void) notify_cpu_starting(cpu); - set_cpu_online(cpu, true); - + mp_ops->smp_finish(); set_cpu_sibling_map(cpu); cpu_set(cpu, cpu_callin_map); synchronise_count_slave(); - /* - * irq will be enabled in ->smp_finish(), enabling it too early - * is dangerous. - */ - WARN_ON_ONCE(!irqs_disabled()); - mp_ops->smp_finish(); - cpu_idle(); } @@ -204,6 +196,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) while (!cpu_isset(cpu, cpu_callin_map)) udelay(100); + set_cpu_online(cpu, true); + return 0; } diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 15b5f3cfd20c..f5dd38f1d015 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -322,7 +322,7 @@ int __init smtc_build_cpu_map(int start_cpu_slot) /* * Common setup before any secondaries are started - * Make sure all CPUs are in a sensible state before we boot any of the + * Make sure all CPU's are in a sensible state before we boot any of the * secondaries. * * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly @@ -340,12 +340,12 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) /* * TCContext gets an offset from the base of the IPIQ array * to be used in low-level code to detect the presence of - * an active IPI queue. + * an active IPI queue */ write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); /* Bind tc to vpe */ write_tc_c0_tcbind(vpe); - /* In general, all TCs should have the same cpu_data indications. */ + /* In general, all TCs should have the same cpu_data indications */ memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ if (cpu_data[0].cputype == CPU_34K || @@ -358,8 +358,8 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) } /* - * Tweak to get Count registes in as close a sync as possible. The - * value seems good for 34K-class cores. + * Tweak to get Count registes in as close a sync as possible. + * Value seems good for 34K-class cores. */ #define CP0_SKEW 8 @@ -615,6 +615,7 @@ void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) void smtc_init_secondary(void) { + local_irq_enable(); } void smtc_smp_finish(void) @@ -630,8 +631,6 @@ void smtc_smp_finish(void) if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id)) write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); - local_irq_enable(); - printk("TC %d going on-line as CPU %d\n", cpu_data[smp_processor_id()].tc_id, smp_processor_id()); } diff --git a/trunk/arch/mips/kernel/sync-r4k.c b/trunk/arch/mips/kernel/sync-r4k.c index 842d55e411fd..99f913c8d7a6 100644 --- a/trunk/arch/mips/kernel/sync-r4k.c +++ b/trunk/arch/mips/kernel/sync-r4k.c @@ -111,6 +111,7 @@ void __cpuinit synchronise_count_master(void) void __cpuinit synchronise_count_slave(void) { int i; + unsigned long flags; unsigned int initcount; int ncpus; @@ -122,6 +123,8 @@ void __cpuinit synchronise_count_slave(void) return; #endif + local_irq_save(flags); + /* * Not every cpu is online at the time this gets called, * so we first wait for the master to say everyone is ready @@ -151,5 +154,7 @@ void __cpuinit synchronise_count_slave(void) } /* Arrange for an interrupt in a short while */ write_c0_compare(read_c0_count() + COUNTON); + + local_irq_restore(flags); } #undef NR_LOOPS diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index c3c293543703..2d0c2a277f52 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -132,9 +132,6 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) unsigned long ra = regs->regs[31]; unsigned long pc = regs->cp0_epc; - if (!task) - task = current; - if (raw_show_trace || !__kernel_text_address(pc)) { show_raw_backtrace(sp); return; @@ -1252,7 +1249,6 @@ static inline void parity_protection_init(void) break; case CPU_5KC: - case CPU_5KE: write_c0_ecc(0x80000000); back_to_back_c0_hazard(); /* Set the PE bit (bit 31) in the c0_errctl register. */ @@ -1502,7 +1498,6 @@ extern void flush_tlb_handlers(void); * Timer interrupt */ int cp0_compare_irq; -EXPORT_SYMBOL_GPL(cp0_compare_irq); int cp0_compare_irq_shift; /* @@ -1602,7 +1597,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) cp0_perfcount_irq = -1; } else { cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; - cp0_compare_irq_shift = CP0_LEGACY_PERFCNT_IRQ; + cp0_compare_irq_shift = cp0_compare_irq; cp0_perfcount_irq = -1; } diff --git a/trunk/arch/mips/kernel/vmlinux.lds.S b/trunk/arch/mips/kernel/vmlinux.lds.S index df243a64f430..924da5eb7031 100644 --- a/trunk/arch/mips/kernel/vmlinux.lds.S +++ b/trunk/arch/mips/kernel/vmlinux.lds.S @@ -1,6 +1,5 @@ #include #include -#include #include #undef mips @@ -73,7 +72,7 @@ SECTIONS .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ - INIT_TASK_DATA(THREAD_SIZE) + INIT_TASK_DATA(PAGE_SIZE) NOSAVE_DATA CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) diff --git a/trunk/arch/mips/mm/Makefile b/trunk/arch/mips/mm/Makefile index fd6203f14f1f..4aa20280613e 100644 --- a/trunk/arch/mips/mm/Makefile +++ b/trunk/arch/mips/mm/Makefile @@ -3,8 +3,8 @@ # obj-y += cache.o dma-default.o extable.o fault.o \ - gup.o init.o mmap.o page.o page-funcs.o \ - tlbex.o tlbex-fault.o uasm.o + gup.o init.o mmap.o page.o tlbex.o \ + tlbex-fault.o uasm.o obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT) += pgtable-64.o diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index f092c265dc63..5109be96d98d 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -977,7 +977,7 @@ static void __cpuinit probe_pcache(void) c->icache.linesz = 2 << lsize; else c->icache.linesz = lsize; - c->icache.sets = 32 << (((config1 >> 22) + 1) & 7); + c->icache.sets = 64 << ((config1 >> 22) & 7); c->icache.ways = 1 + ((config1 >> 16) & 7); icache_size = c->icache.sets * @@ -997,7 +997,7 @@ static void __cpuinit probe_pcache(void) c->dcache.linesz = 2 << lsize; else c->dcache.linesz= lsize; - c->dcache.sets = 32 << (((config1 >> 13) + 1) & 7); + c->dcache.sets = 64 << ((config1 >> 13) & 7); c->dcache.ways = 1 + ((config1 >> 7) & 7); dcache_size = c->dcache.sets * @@ -1051,7 +1051,6 @@ static void __cpuinit probe_pcache(void) case CPU_R14000: break; - case CPU_M14KC: case CPU_24K: case CPU_34K: case CPU_74K: diff --git a/trunk/arch/mips/mm/page-funcs.S b/trunk/arch/mips/mm/page-funcs.S deleted file mode 100644 index 48a6b38ff13e..000000000000 --- a/trunk/arch/mips/mm/page-funcs.S +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - * - * Micro-assembler generated clear_page/copy_page functions. - * - * Copyright (C) 2012 MIPS Technologies, Inc. - * Copyright (C) 2012 Ralf Baechle - */ -#include -#include - -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS -#define cpu_clear_page_function_name clear_page_cpu -#define cpu_copy_page_function_name copy_page_cpu -#else -#define cpu_clear_page_function_name clear_page -#define cpu_copy_page_function_name copy_page -#endif - -/* - * Maximum sizes: - * - * R4000 128 bytes S-cache: 0x058 bytes - * R4600 v1.7: 0x05c bytes - * R4600 v2.0: 0x060 bytes - * With prefetching, 16 word strides 0x120 bytes - */ -EXPORT(__clear_page_start) -LEAF(cpu_clear_page_function_name) -1: j 1b /* Dummy, will be replaced. */ - .space 288 -END(cpu_clear_page_function_name) -EXPORT(__clear_page_end) - -/* - * Maximum sizes: - * - * R4000 128 bytes S-cache: 0x11c bytes - * R4600 v1.7: 0x080 bytes - * R4600 v2.0: 0x07c bytes - * With prefetching, 16 word strides 0x540 bytes - */ -EXPORT(__copy_page_start) -LEAF(cpu_copy_page_function_name) -1: j 1b /* Dummy, will be replaced. */ - .space 1344 -END(cpu_copy_page_function_name) -EXPORT(__copy_page_end) diff --git a/trunk/arch/mips/mm/page.c b/trunk/arch/mips/mm/page.c index 98f530e18216..cc0b626858b3 100644 --- a/trunk/arch/mips/mm/page.c +++ b/trunk/arch/mips/mm/page.c @@ -6,7 +6,6 @@ * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 2007 Maciej W. Rozycki * Copyright (C) 2008 Thiemo Seufer - * Copyright (C) 2012 MIPS Technologies, Inc. */ #include #include @@ -72,6 +71,45 @@ static struct uasm_reloc __cpuinitdata relocs[5]; #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) #define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) +/* + * Maximum sizes: + * + * R4000 128 bytes S-cache: 0x058 bytes + * R4600 v1.7: 0x05c bytes + * R4600 v2.0: 0x060 bytes + * With prefetching, 16 word strides 0x120 bytes + */ + +static u32 clear_page_array[0x120 / 4]; + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +void clear_page_cpu(void *page) __attribute__((alias("clear_page_array"))); +#else +void clear_page(void *page) __attribute__((alias("clear_page_array"))); +#endif + +EXPORT_SYMBOL(clear_page); + +/* + * Maximum sizes: + * + * R4000 128 bytes S-cache: 0x11c bytes + * R4600 v1.7: 0x080 bytes + * R4600 v2.0: 0x07c bytes + * With prefetching, 16 word strides 0x540 bytes + */ +static u32 copy_page_array[0x540 / 4]; + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +void +copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array"))); +#else +void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); +#endif + +EXPORT_SYMBOL(copy_page); + + static int pref_bias_clear_store __cpuinitdata; static int pref_bias_copy_load __cpuinitdata; static int pref_bias_copy_store __cpuinitdata; @@ -244,15 +282,10 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off) } } -extern u32 __clear_page_start; -extern u32 __clear_page_end; -extern u32 __copy_page_start; -extern u32 __copy_page_end; - void __cpuinit build_clear_page(void) { int off; - u32 *buf = &__clear_page_start; + u32 *buf = (u32 *)&clear_page_array; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; int i; @@ -323,17 +356,17 @@ void __cpuinit build_clear_page(void) uasm_i_jr(&buf, RA); uasm_i_nop(&buf); - BUG_ON(buf > &__clear_page_end); + BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array)); uasm_resolve_relocs(relocs, labels); pr_debug("Synthesized clear page handler (%u instructions).\n", - (u32)(buf - &__clear_page_start)); + (u32)(buf - clear_page_array)); pr_debug("\t.set push\n"); pr_debug("\t.set noreorder\n"); - for (i = 0; i < (buf - &__clear_page_start); i++) - pr_debug("\t.word 0x%08x\n", (&__clear_page_start)[i]); + for (i = 0; i < (buf - clear_page_array); i++) + pr_debug("\t.word 0x%08x\n", clear_page_array[i]); pr_debug("\t.set pop\n"); } @@ -394,7 +427,7 @@ static inline void build_copy_store_pref(u32 **buf, int off) void __cpuinit build_copy_page(void) { int off; - u32 *buf = &__copy_page_start; + u32 *buf = (u32 *)©_page_array; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; int i; @@ -562,23 +595,21 @@ void __cpuinit build_copy_page(void) uasm_i_jr(&buf, RA); uasm_i_nop(&buf); - BUG_ON(buf > &__copy_page_end); + BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array)); uasm_resolve_relocs(relocs, labels); pr_debug("Synthesized copy page handler (%u instructions).\n", - (u32)(buf - &__copy_page_start)); + (u32)(buf - copy_page_array)); pr_debug("\t.set push\n"); pr_debug("\t.set noreorder\n"); - for (i = 0; i < (buf - &__copy_page_start); i++) - pr_debug("\t.word 0x%08x\n", (&__copy_page_start)[i]); + for (i = 0; i < (buf - copy_page_array); i++) + pr_debug("\t.word 0x%08x\n", copy_page_array[i]); pr_debug("\t.set pop\n"); } #ifdef CONFIG_SIBYTE_DMA_PAGEOPS -extern void clear_page_cpu(void *page); -extern void copy_page_cpu(void *to, void *from); /* * Pad descriptors to cacheline, since each is exclusively owned by a diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index 03eb0ef91580..0bc485b3cd60 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -9,7 +9,6 @@ * Copyright (C) 2005, 2007, 2008, 2009 Maciej W. Rozycki * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 2008, 2009 Cavium Networks, Inc. - * Copyright (C) 2011 MIPS Technologies, Inc. * * ... and the days got worse and worse and now you see * I've gone completly out of my mind. @@ -495,7 +494,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, case CPU_R14000: case CPU_4KC: case CPU_4KEC: - case CPU_M14KC: case CPU_SB1: case CPU_SB1A: case CPU_4KSC: diff --git a/trunk/arch/mips/mti-malta/malta-pci.c b/trunk/arch/mips/mti-malta/malta-pci.c index 284dea54faf5..bf80921f2f56 100644 --- a/trunk/arch/mips/mti-malta/malta-pci.c +++ b/trunk/arch/mips/mti-malta/malta-pci.c @@ -241,9 +241,8 @@ void __init mips_pcibios_init(void) return; } - /* Change start address to avoid conflicts with ACPI and SMB devices */ - if (controller->io_resource->start < 0x00002000UL) - controller->io_resource->start = 0x00002000UL; + if (controller->io_resource->start < 0x00001000UL) /* FIXME */ + controller->io_resource->start = 0x00001000UL; iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ ioport_resource.end = controller->io_resource->end; @@ -254,7 +253,7 @@ void __init mips_pcibios_init(void) } /* Enable PCI 2.1 compatibility in PIIX4 */ -static void __devinit quirk_dlcsetup(struct pci_dev *dev) +static void __init quirk_dlcsetup(struct pci_dev *dev) { u8 odlc, ndlc; (void) pci_read_config_byte(dev, 0x82, &odlc); diff --git a/trunk/arch/mips/mti-malta/malta-setup.c b/trunk/arch/mips/mti-malta/malta-setup.c index 2e28f653f66d..b7f37d4982fa 100644 --- a/trunk/arch/mips/mti-malta/malta-setup.c +++ b/trunk/arch/mips/mti-malta/malta-setup.c @@ -111,7 +111,7 @@ static void __init pci_clock_check(void) unsigned int __iomem *jmpr_p = (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; - static const int pciclocks[] __initconst = { + static const int pciclocks[] __initdata = { 33, 20, 25, 30, 12, 16, 37, 10 }; int pciclock = pciclocks[jmpr]; diff --git a/trunk/arch/mips/netlogic/xlp/setup.c b/trunk/arch/mips/netlogic/xlp/setup.c index b3df7c2aad1e..acb677a1227c 100644 --- a/trunk/arch/mips/netlogic/xlp/setup.c +++ b/trunk/arch/mips/netlogic/xlp/setup.c @@ -82,10 +82,8 @@ void __init prom_free_prom_memory(void) void xlp_mmu_init(void) { - /* enable extended TLB and Large Fixed TLB */ write_c0_config6(read_c0_config6() | 0x24); - - /* set page mask of Fixed TLB in config7 */ + current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; write_c0_config7(PM_DEFAULT_MASK >> (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); } @@ -102,10 +100,6 @@ void __init prom_init(void) nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); #ifdef CONFIG_SMP nlm_wakeup_secondary_cpus(0xffffffff); - - /* update TLB size after waking up threads */ - current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; - register_smp_ops(&nlm_smp_ops); #endif } diff --git a/trunk/arch/mips/oprofile/common.c b/trunk/arch/mips/oprofile/common.c index b6e378211a2c..d1f2d4c52d42 100644 --- a/trunk/arch/mips/oprofile/common.c +++ b/trunk/arch/mips/oprofile/common.c @@ -78,7 +78,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) switch (current_cpu_type()) { case CPU_5KC: - case CPU_M14KC: case CPU_20KC: case CPU_24K: case CPU_25KF: diff --git a/trunk/arch/mips/oprofile/op_model_mipsxx.c b/trunk/arch/mips/oprofile/op_model_mipsxx.c index 4d80a856048d..baba3bcaa3c2 100644 --- a/trunk/arch/mips/oprofile/op_model_mipsxx.c +++ b/trunk/arch/mips/oprofile/op_model_mipsxx.c @@ -322,10 +322,6 @@ static int __init mipsxx_init(void) op_model_mipsxx_ops.num_counters = counters; switch (current_cpu_type()) { - case CPU_M14KC: - op_model_mipsxx_ops.cpu_type = "mips/M14Kc"; - break; - case CPU_20KC: op_model_mipsxx_ops.cpu_type = "mips/20K"; break; diff --git a/trunk/arch/mips/pci/fixup-fuloong2e.c b/trunk/arch/mips/pci/fixup-fuloong2e.c index 0857ab8c3919..d5d4c018fb04 100644 --- a/trunk/arch/mips/pci/fixup-fuloong2e.c +++ b/trunk/arch/mips/pci/fixup-fuloong2e.c @@ -48,7 +48,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -static void __devinit loongson2e_nec_fixup(struct pci_dev *pdev) +static void __init loongson2e_nec_fixup(struct pci_dev *pdev) { unsigned int val; @@ -60,7 +60,7 @@ static void __devinit loongson2e_nec_fixup(struct pci_dev *pdev) pci_write_config_dword(pdev, 0xe4, 1 << 5); } -static void __devinit loongson2e_686b_func0_fixup(struct pci_dev *pdev) +static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev) { unsigned char c; @@ -135,7 +135,7 @@ static void __devinit loongson2e_686b_func0_fixup(struct pci_dev *pdev) printk(KERN_INFO"via686b fix: ISA bridge done\n"); } -static void __devinit loongson2e_686b_func1_fixup(struct pci_dev *pdev) +static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev) { printk(KERN_INFO"via686b fix: IDE\n"); @@ -168,19 +168,19 @@ static void __devinit loongson2e_686b_func1_fixup(struct pci_dev *pdev) printk(KERN_INFO"via686b fix: IDE done\n"); } -static void __devinit loongson2e_686b_func2_fixup(struct pci_dev *pdev) +static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev) { /* irq routing */ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10); } -static void __devinit loongson2e_686b_func3_fixup(struct pci_dev *pdev) +static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev) { /* irq routing */ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11); } -static void __devinit loongson2e_686b_func5_fixup(struct pci_dev *pdev) +static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev) { unsigned int val; unsigned char c; diff --git a/trunk/arch/mips/pci/fixup-lemote2f.c b/trunk/arch/mips/pci/fixup-lemote2f.c index a7b917dcf604..4b9768d5d729 100644 --- a/trunk/arch/mips/pci/fixup-lemote2f.c +++ b/trunk/arch/mips/pci/fixup-lemote2f.c @@ -96,21 +96,21 @@ int pcibios_plat_dev_init(struct pci_dev *dev) } /* CS5536 SPEC. fixup */ -static void __devinit loongson_cs5536_isa_fixup(struct pci_dev *pdev) +static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev) { /* the uart1 and uart2 interrupt in PIC is enabled as default */ pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1); pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1); } -static void __devinit loongson_cs5536_ide_fixup(struct pci_dev *pdev) +static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev) { /* setting the mutex pin as IDE function */ pci_write_config_dword(pdev, PCI_IDE_CFG_REG, CS5536_IDE_FLASH_SIGNATURE); } -static void __devinit loongson_cs5536_acc_fixup(struct pci_dev *pdev) +static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) { /* enable the AUDIO interrupt in PIC */ pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); @@ -118,14 +118,14 @@ static void __devinit loongson_cs5536_acc_fixup(struct pci_dev *pdev) pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); } -static void __devinit loongson_cs5536_ohci_fixup(struct pci_dev *pdev) +static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev) { /* enable the OHCI interrupt in PIC */ /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1); } -static void __devinit loongson_cs5536_ehci_fixup(struct pci_dev *pdev) +static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) { u32 hi, lo; @@ -137,7 +137,7 @@ static void __devinit loongson_cs5536_ehci_fixup(struct pci_dev *pdev) pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000); } -static void __devinit loongson_nec_fixup(struct pci_dev *pdev) +static void __init loongson_nec_fixup(struct pci_dev *pdev) { unsigned int val; diff --git a/trunk/arch/mips/pci/fixup-malta.c b/trunk/arch/mips/pci/fixup-malta.c index 70073c98ed32..0f48498bc231 100644 --- a/trunk/arch/mips/pci/fixup-malta.c +++ b/trunk/arch/mips/pci/fixup-malta.c @@ -49,10 +49,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -static void __devinit malta_piix_func0_fixup(struct pci_dev *pdev) +static void __init malta_piix_func0_fixup(struct pci_dev *pdev) { unsigned char reg_val; - static int piixirqmap[16] __devinitdata = { /* PIIX PIRQC[A:D] irq mappings */ + static int piixirqmap[16] __initdata = { /* PIIX PIRQC[A:D] irq mappings */ 0, 0, 0, 3, 4, 5, 6, 7, 0, 9, 10, 11, @@ -83,7 +83,7 @@ static void __devinit malta_piix_func0_fixup(struct pci_dev *pdev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, malta_piix_func0_fixup); -static void __devinit malta_piix_func1_fixup(struct pci_dev *pdev) +static void __init malta_piix_func1_fixup(struct pci_dev *pdev) { unsigned char reg_val; diff --git a/trunk/arch/mips/pci/fixup-mpc30x.c b/trunk/arch/mips/pci/fixup-mpc30x.c index 8e4f8288eca2..e08f49cb6875 100644 --- a/trunk/arch/mips/pci/fixup-mpc30x.c +++ b/trunk/arch/mips/pci/fixup-mpc30x.c @@ -22,13 +22,13 @@ #include -static const int internal_func_irqs[] __initconst = { +static const int internal_func_irqs[] __initdata = { VRC4173_CASCADE_IRQ, VRC4173_AC97_IRQ, VRC4173_USB_IRQ, }; -static const int irq_tab_mpc30x[] __initconst = { +static const int irq_tab_mpc30x[] __initdata = { [12] = VRC4173_PCMCIA1_IRQ, [13] = VRC4173_PCMCIA2_IRQ, [29] = MQ200_IRQ, diff --git a/trunk/arch/mips/pci/fixup-sb1250.c b/trunk/arch/mips/pci/fixup-sb1250.c index d02900a72916..f0bb9146e6c0 100644 --- a/trunk/arch/mips/pci/fixup-sb1250.c +++ b/trunk/arch/mips/pci/fixup-sb1250.c @@ -15,7 +15,7 @@ * Set the BCM1250, etc. PCI host bridge's TRDY timeout * to the finite max. */ -static void __devinit quirk_sb1250_pci(struct pci_dev *dev) +static void __init quirk_sb1250_pci(struct pci_dev *dev) { pci_write_config_byte(dev, 0x40, 0xff); } @@ -25,7 +25,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI, /* * The BCM1250, etc. PCI/HT bridge reports as a host bridge. */ -static void __devinit quirk_sb1250_ht(struct pci_dev *dev) +static void __init quirk_sb1250_ht(struct pci_dev *dev) { dev->class = PCI_CLASS_BRIDGE_PCI << 8; } @@ -35,7 +35,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT, /* * Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max. */ -static void __devinit quirk_sp1011(struct pci_dev *dev) +static void __init quirk_sp1011(struct pci_dev *dev) { pci_write_config_byte(dev, 0x64, 0xff); } diff --git a/trunk/arch/mips/pci/ops-tx4927.c b/trunk/arch/mips/pci/ops-tx4927.c index bc13e29d2bb3..a1e7e6d80c8c 100644 --- a/trunk/arch/mips/pci/ops-tx4927.c +++ b/trunk/arch/mips/pci/ops-tx4927.c @@ -495,7 +495,7 @@ irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id) } #ifdef CONFIG_TOSHIBA_FPCIB0 -static void __devinit tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) +static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) { struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus); diff --git a/trunk/arch/mips/pci/pci-ip27.c b/trunk/arch/mips/pci/pci-ip27.c index fdc24440294c..0fbe4c0c170a 100644 --- a/trunk/arch/mips/pci/pci-ip27.c +++ b/trunk/arch/mips/pci/pci-ip27.c @@ -212,7 +212,7 @@ static inline void pci_enable_swapping(struct pci_dev *dev) bridge->b_widget.w_tflush; /* Flush */ } -static void __devinit pci_fixup_ioc3(struct pci_dev *d) +static void __init pci_fixup_ioc3(struct pci_dev *d) { pci_disable_swapping(d); } diff --git a/trunk/arch/mips/pci/pci-lantiq.c b/trunk/arch/mips/pci/pci-lantiq.c index 075d87acd12a..ea453532a33c 100644 --- a/trunk/arch/mips/pci/pci-lantiq.c +++ b/trunk/arch/mips/pci/pci-lantiq.c @@ -129,7 +129,7 @@ static int __devinit ltq_pci_startup(struct platform_device *pdev) /* setup reset gpio used by pci */ reset_gpio = of_get_named_gpio(node, "gpio-reset", 0); - if (gpio_is_valid(reset_gpio)) + if (reset_gpio > 0) devm_gpio_request(&pdev->dev, reset_gpio, "pci-reset"); /* enable auto-switching between PCI and EBU */ @@ -192,7 +192,7 @@ static int __devinit ltq_pci_startup(struct platform_device *pdev) ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN); /* toggle reset pin */ - if (gpio_is_valid(reset_gpio)) { + if (reset_gpio > 0) { __gpio_set_value(reset_gpio, 0); wmb(); mdelay(1); diff --git a/trunk/arch/mips/pci/pci-xlr.c b/trunk/arch/mips/pci/pci-xlr.c index 172af1cd5867..1644805a6730 100644 --- a/trunk/arch/mips/pci/pci-xlr.c +++ b/trunk/arch/mips/pci/pci-xlr.c @@ -41,7 +41,6 @@ #include #include #include -#include #include @@ -157,55 +156,35 @@ struct pci_controller nlm_pci_controller = { .io_offset = 0x00000000UL, }; -/* - * The top level PCIe links on the XLS PCIe controller appear as - * bridges. Given a device, this function finds which link it is - * on. - */ -static struct pci_dev *xls_get_pcie_link(const struct pci_dev *dev) -{ - struct pci_bus *bus, *p; - - /* Find the bridge on bus 0 */ - bus = dev->bus; - for (p = bus->parent; p && p->number != 0; p = p->parent) - bus = p; - - return p ? bus->self : NULL; -} - static int get_irq_vector(const struct pci_dev *dev) { - struct pci_dev *lnk; - if (!nlm_chip_is_xls()) - return PIC_PCIX_IRQ; /* for XLR just one IRQ */ + return PIC_PCIX_IRQ; /* for XLR just one IRQ*/ /* * For XLS PCIe, there is an IRQ per Link, find out which * link the device is on to assign interrupts - */ - lnk = xls_get_pcie_link(dev); - if (lnk == NULL) + */ + if (dev->bus->self == NULL) return 0; - switch (PCI_SLOT(lnk->devfn)) { - case 0: + switch (dev->bus->self->devfn) { + case 0x0: return PIC_PCIE_LINK0_IRQ; - case 1: + case 0x8: return PIC_PCIE_LINK1_IRQ; - case 2: + case 0x10: if (nlm_chip_is_xls_b()) return PIC_PCIE_XLSB0_LINK2_IRQ; else return PIC_PCIE_LINK2_IRQ; - case 3: + case 0x18: if (nlm_chip_is_xls_b()) return PIC_PCIE_XLSB0_LINK3_IRQ; else return PIC_PCIE_LINK3_IRQ; } - WARN(1, "Unexpected devfn %d\n", lnk->devfn); + WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn); return 0; } @@ -223,27 +202,7 @@ void arch_teardown_msi_irq(unsigned int irq) int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) { struct msi_msg msg; - struct pci_dev *lnk; int irq, ret; - u16 val; - - /* MSI not supported on XLR */ - if (!nlm_chip_is_xls()) - return 1; - - /* - * Enable MSI on the XLS PCIe controller bridge which was disabled - * at enumeration, the bridge MSI capability is at 0x50 - */ - lnk = xls_get_pcie_link(dev); - if (lnk == NULL) - return 1; - - pci_read_config_word(lnk, 0x50 + PCI_MSI_FLAGS, &val); - if ((val & PCI_MSI_FLAGS_ENABLE) == 0) { - val |= PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(lnk, 0x50 + PCI_MSI_FLAGS, val); - } irq = get_irq_vector(dev); if (irq <= 0) @@ -368,7 +327,7 @@ static int __init pcibios_init(void) } } else { /* XLR PCI controller ACK */ - irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack); + irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack); } return 0; diff --git a/trunk/arch/mips/pmc-sierra/yosemite/smp.c b/trunk/arch/mips/pmc-sierra/yosemite/smp.c index 5edab2bc6fc0..b71fae231049 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/smp.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/smp.c @@ -115,11 +115,11 @@ static void yos_send_ipi_mask(const struct cpumask *mask, unsigned int action) */ static void __cpuinit yos_init_secondary(void) { + set_c0_status(ST0_CO | ST0_IE | ST0_IM); } static void __cpuinit yos_smp_finish(void) { - set_c0_status(ST0_CO | ST0_IM | ST0_IE); } /* Hook for after all CPUs are online */ diff --git a/trunk/arch/mips/powertv/asic/asic-calliope.c b/trunk/arch/mips/powertv/asic/asic-calliope.c index 7773f3d956b0..0a170e0ffeaa 100644 --- a/trunk/arch/mips/powertv/asic/asic-calliope.c +++ b/trunk/arch/mips/powertv/asic/asic-calliope.c @@ -28,7 +28,7 @@ #define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x)) -const struct register_map calliope_register_map __initconst = { +const struct register_map calliope_register_map __initdata = { .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)}, .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)}, .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)}, diff --git a/trunk/arch/mips/powertv/asic/asic-cronus.c b/trunk/arch/mips/powertv/asic/asic-cronus.c index da076db7b7ed..bbc0c122be5e 100644 --- a/trunk/arch/mips/powertv/asic/asic-cronus.c +++ b/trunk/arch/mips/powertv/asic/asic-cronus.c @@ -28,7 +28,7 @@ #define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x)) -const struct register_map cronus_register_map __initconst = { +const struct register_map cronus_register_map __initdata = { .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)}, .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)}, .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)}, diff --git a/trunk/arch/mips/powertv/asic/asic-gaia.c b/trunk/arch/mips/powertv/asic/asic-gaia.c index 47683b370e74..91dda682752c 100644 --- a/trunk/arch/mips/powertv/asic/asic-gaia.c +++ b/trunk/arch/mips/powertv/asic/asic-gaia.c @@ -23,7 +23,7 @@ #include #include -const struct register_map gaia_register_map __initconst = { +const struct register_map gaia_register_map __initdata = { .eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000}, .eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038}, .eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C}, diff --git a/trunk/arch/mips/powertv/asic/asic-zeus.c b/trunk/arch/mips/powertv/asic/asic-zeus.c index 6ff4b10f09da..4a05bb096476 100644 --- a/trunk/arch/mips/powertv/asic/asic-zeus.c +++ b/trunk/arch/mips/powertv/asic/asic-zeus.c @@ -28,7 +28,7 @@ #define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x)) -const struct register_map zeus_register_map __initconst = { +const struct register_map zeus_register_map __initdata = { .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)}, .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)}, .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)}, diff --git a/trunk/arch/mips/txx9/generic/pci.c b/trunk/arch/mips/txx9/generic/pci.c index 64eb71b15280..682efb0c108d 100644 --- a/trunk/arch/mips/txx9/generic/pci.c +++ b/trunk/arch/mips/txx9/generic/pci.c @@ -269,7 +269,7 @@ txx9_i8259_irq_setup(int irq) return err; } -static void __devinit quirk_slc90e66_bridge(struct pci_dev *dev) +static void __init quirk_slc90e66_bridge(struct pci_dev *dev) { int irq; /* PCI/ISA Bridge interrupt */ u8 reg_64; diff --git a/trunk/arch/mn10300/include/asm/ptrace.h b/trunk/arch/mn10300/include/asm/ptrace.h index 44251b974f1d..55b79ef10028 100644 --- a/trunk/arch/mn10300/include/asm/ptrace.h +++ b/trunk/arch/mn10300/include/asm/ptrace.h @@ -81,6 +81,9 @@ struct pt_regs { #define PTRACE_GETFPREGS 14 #define PTRACE_SETFPREGS 15 +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + #ifdef __KERNEL__ #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) diff --git a/trunk/arch/mn10300/include/asm/thread_info.h b/trunk/arch/mn10300/include/asm/thread_info.h index ac519bbd42ff..08251d6f6b11 100644 --- a/trunk/arch/mn10300/include/asm/thread_info.h +++ b/trunk/arch/mn10300/include/asm/thread_info.h @@ -123,7 +123,7 @@ static inline unsigned long current_stack_pointer(void) } #ifndef CONFIG_KGDB -void arch_release_thread_info(struct thread_info *ti); +void arch_release_thread_info(struct thread_info *ti) #endif #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) diff --git a/trunk/arch/mn10300/include/asm/timex.h b/trunk/arch/mn10300/include/asm/timex.h index f8e66425cbf8..bd4e90dfe6c2 100644 --- a/trunk/arch/mn10300/include/asm/timex.h +++ b/trunk/arch/mn10300/include/asm/timex.h @@ -11,6 +11,7 @@ #ifndef _ASM_TIMEX_H #define _ASM_TIMEX_H +#include #include #define TICK_SIZE (tick_nsec / 1000) @@ -29,6 +30,16 @@ static inline cycles_t get_cycles(void) extern int init_clockevents(void); extern int init_clocksource(void); +static inline void setup_jiffies_interrupt(int irq, + struct irqaction *action) +{ + u16 tmp; + setup_irq(irq, action); + set_intr_level(irq, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL)); + GxICR(irq) |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST; + tmp = GxICR(irq); +} + #endif /* __KERNEL__ */ #endif /* _ASM_TIMEX_H */ diff --git a/trunk/arch/mn10300/kernel/cevt-mn10300.c b/trunk/arch/mn10300/kernel/cevt-mn10300.c index ccce35e3e179..69cae0260786 100644 --- a/trunk/arch/mn10300/kernel/cevt-mn10300.c +++ b/trunk/arch/mn10300/kernel/cevt-mn10300.c @@ -70,16 +70,6 @@ static void event_handler(struct clock_event_device *dev) { } -static inline void setup_jiffies_interrupt(int irq, - struct irqaction *action) -{ - u16 tmp; - setup_irq(irq, action); - set_intr_level(irq, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL)); - GxICR(irq) |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST; - tmp = GxICR(irq); -} - int __init init_clockevents(void) { struct clock_event_device *cd; diff --git a/trunk/arch/mn10300/kernel/internal.h b/trunk/arch/mn10300/kernel/internal.h index 2df440105a80..a5ac755dd69f 100644 --- a/trunk/arch/mn10300/kernel/internal.h +++ b/trunk/arch/mn10300/kernel/internal.h @@ -9,8 +9,6 @@ * 2 of the Licence, or (at your option) any later version. */ -#include - struct clocksource; struct clock_event_device; diff --git a/trunk/arch/mn10300/kernel/irq.c b/trunk/arch/mn10300/kernel/irq.c index 35932a8de8b8..2381df83bd00 100644 --- a/trunk/arch/mn10300/kernel/irq.c +++ b/trunk/arch/mn10300/kernel/irq.c @@ -170,9 +170,9 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask, case SC1TXIRQ: #ifdef CONFIG_MN10300_TTYSM1_TIMER12 case TM12IRQ: -#elif defined(CONFIG_MN10300_TTYSM1_TIMER9) +#elif CONFIG_MN10300_TTYSM1_TIMER9 case TM9IRQ: -#elif defined(CONFIG_MN10300_TTYSM1_TIMER3) +#elif CONFIG_MN10300_TTYSM1_TIMER3 case TM3IRQ: #endif /* CONFIG_MN10300_TTYSM1_TIMER12 */ #endif /* CONFIG_MN10300_TTYSM1 */ diff --git a/trunk/arch/mn10300/kernel/signal.c b/trunk/arch/mn10300/kernel/signal.c index 4d584ae29ae1..6ab0bee2a54f 100644 --- a/trunk/arch/mn10300/kernel/signal.c +++ b/trunk/arch/mn10300/kernel/signal.c @@ -459,11 +459,10 @@ static int handle_signal(int sig, else ret = setup_frame(sig, ka, oldset, regs); if (ret) - return ret; + return; signal_delivered(sig, info, ka, regs, - test_thread_flag(TIF_SINGLESTEP)); - return 0; + test_thread_flag(TIF_SINGLESTEP)); } /* diff --git a/trunk/arch/mn10300/kernel/smp.c b/trunk/arch/mn10300/kernel/smp.c index e62c223e4c45..090d35d36973 100644 --- a/trunk/arch/mn10300/kernel/smp.c +++ b/trunk/arch/mn10300/kernel/smp.c @@ -876,7 +876,9 @@ static void __init smp_online(void) notify_cpu_starting(cpu); + ipi_call_lock(); set_cpu_online(cpu, true); + ipi_call_unlock(); local_irq_enable(); } diff --git a/trunk/arch/mn10300/kernel/traps.c b/trunk/arch/mn10300/kernel/traps.c index b900e5afa0ae..94a9c6d53e1b 100644 --- a/trunk/arch/mn10300/kernel/traps.c +++ b/trunk/arch/mn10300/kernel/traps.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mn10300/mm/dma-alloc.c b/trunk/arch/mn10300/mm/dma-alloc.c index e244ebe637e1..159acb02cfd4 100644 --- a/trunk/arch/mn10300/mm/dma-alloc.c +++ b/trunk/arch/mn10300/mm/dma-alloc.c @@ -15,7 +15,6 @@ #include #include #include -#include #include static unsigned long pci_sram_allocated = 0xbc000000; diff --git a/trunk/arch/mn10300/unit-asb2303/include/unit/timex.h b/trunk/arch/mn10300/unit-asb2303/include/unit/timex.h index c37f9832cf17..cc18fe7d8b90 100644 --- a/trunk/arch/mn10300/unit-asb2303/include/unit/timex.h +++ b/trunk/arch/mn10300/unit-asb2303/include/unit/timex.h @@ -11,6 +11,10 @@ #ifndef _ASM_UNIT_TIMEX_H #define _ASM_UNIT_TIMEX_H +#ifndef __ASSEMBLY__ +#include +#endif /* __ASSEMBLY__ */ + #include #include #include diff --git a/trunk/arch/mn10300/unit-asb2303/smc91111.c b/trunk/arch/mn10300/unit-asb2303/smc91111.c index 53677694b165..43c246439413 100644 --- a/trunk/arch/mn10300/unit-asb2303/smc91111.c +++ b/trunk/arch/mn10300/unit-asb2303/smc91111.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mn10300/unit-asb2305/include/unit/timex.h b/trunk/arch/mn10300/unit-asb2305/include/unit/timex.h index 4cefc224f448..758af30d1a16 100644 --- a/trunk/arch/mn10300/unit-asb2305/include/unit/timex.h +++ b/trunk/arch/mn10300/unit-asb2305/include/unit/timex.h @@ -11,6 +11,10 @@ #ifndef _ASM_UNIT_TIMEX_H #define _ASM_UNIT_TIMEX_H +#ifndef __ASSEMBLY__ +#include +#endif /* __ASSEMBLY__ */ + #include #include #include diff --git a/trunk/arch/mn10300/unit-asb2305/unit-init.c b/trunk/arch/mn10300/unit-asb2305/unit-init.c index bc4adfaf815c..e1becd6b7571 100644 --- a/trunk/arch/mn10300/unit-asb2305/unit-init.c +++ b/trunk/arch/mn10300/unit-asb2305/unit-init.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mn10300/unit-asb2364/include/unit/timex.h b/trunk/arch/mn10300/unit-asb2364/include/unit/timex.h index 42f32db75087..ddb7ed010706 100644 --- a/trunk/arch/mn10300/unit-asb2364/include/unit/timex.h +++ b/trunk/arch/mn10300/unit-asb2364/include/unit/timex.h @@ -11,6 +11,10 @@ #ifndef _ASM_UNIT_TIMEX_H #define _ASM_UNIT_TIMEX_H +#ifndef __ASSEMBLY__ +#include +#endif /* __ASSEMBLY__ */ + #include #include #include diff --git a/trunk/arch/parisc/Makefile b/trunk/arch/parisc/Makefile index 5707f1a62341..dbc3850b1d0d 100644 --- a/trunk/arch/parisc/Makefile +++ b/trunk/arch/parisc/Makefile @@ -21,7 +21,6 @@ KBUILD_DEFCONFIG := default_defconfig NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 -LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) MACHINE := $(shell uname -m) ifeq ($(MACHINE),parisc*) @@ -80,7 +79,7 @@ kernel-y := mm/ kernel/ math-emu/ kernel-$(CONFIG_HPUX) += hpux/ core-y += $(addprefix arch/parisc/, $(kernel-y)) -libs-y += arch/parisc/lib/ $(LIBGCC) +libs-y += arch/parisc/lib/ `$(CC) -print-libgcc-file-name` drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ diff --git a/trunk/arch/parisc/include/asm/Kbuild b/trunk/arch/parisc/include/asm/Kbuild index 4383707d9801..19a434f55059 100644 --- a/trunk/arch/parisc/include/asm/Kbuild +++ b/trunk/arch/parisc/include/asm/Kbuild @@ -1,4 +1,3 @@ include include/asm-generic/Kbuild.asm header-y += pdc.h -generic-y += word-at-a-time.h diff --git a/trunk/arch/parisc/include/asm/bug.h b/trunk/arch/parisc/include/asm/bug.h index 62a33338549c..72cfdb0cfdd1 100644 --- a/trunk/arch/parisc/include/asm/bug.h +++ b/trunk/arch/parisc/include/asm/bug.h @@ -1,8 +1,6 @@ #ifndef _PARISC_BUG_H #define _PARISC_BUG_H -#include /* for BUGFLAG_TAINT */ - /* * Tell the user there is some problem. * The offending file and line are encoded in the __bug_table section. diff --git a/trunk/arch/parisc/kernel/smp.c b/trunk/arch/parisc/kernel/smp.c index 6266730efd61..a47828d31fe6 100644 --- a/trunk/arch/parisc/kernel/smp.c +++ b/trunk/arch/parisc/kernel/smp.c @@ -300,7 +300,9 @@ smp_cpu_init(int cpunum) notify_cpu_starting(cpunum); + ipi_call_lock(); set_cpu_online(cpunum, true); + ipi_call_unlock(); /* Initialise the idle task for this CPU */ atomic_inc(&init_mm.mm_count); diff --git a/trunk/arch/powerpc/include/asm/hw_irq.h b/trunk/arch/powerpc/include/asm/hw_irq.h index 0554ab062bdc..c9aac24b02e2 100644 --- a/trunk/arch/powerpc/include/asm/hw_irq.h +++ b/trunk/arch/powerpc/include/asm/hw_irq.h @@ -86,8 +86,8 @@ static inline bool arch_irqs_disabled(void) } #ifdef CONFIG_PPC_BOOK3E -#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory") -#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory") +#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory"); +#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory"); #else #define __hard_irq_enable() __mtmsrd(local_paca->kernel_msr | MSR_EE, 1) #define __hard_irq_disable() __mtmsrd(local_paca->kernel_msr, 1) @@ -100,14 +100,6 @@ static inline void hard_irq_disable(void) get_paca()->irq_happened |= PACA_IRQ_HARD_DIS; } -/* include/linux/interrupt.h needs hard_irq_disable to be a macro */ -#define hard_irq_disable hard_irq_disable - -static inline bool lazy_irq_pending(void) -{ - return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS); -} - /* * This is called by asynchronous interrupts to conditionally * re-enable hard interrupts when soft-disabled after having @@ -125,8 +117,6 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs) return !regs->softe; } -extern bool prep_irq_for_idle(void); - #else /* CONFIG_PPC64 */ #define SET_MSR_EE(x) mtmsr(x) diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 5971c85df136..ed1718feb9d9 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -558,54 +558,27 @@ _GLOBAL(ret_from_except_lite) mtmsrd r10,1 /* Update machine state */ #endif /* CONFIG_PPC_BOOK3E */ +#ifdef CONFIG_PREEMPT clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ + li r0,_TIF_NEED_RESCHED /* bits to check */ ld r3,_MSR(r1) ld r4,TI_FLAGS(r9) + /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ + rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING + and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */ + bne do_work + +#else /* !CONFIG_PREEMPT */ + ld r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR - beq resume_kernel + beq restore /* if not, just restore regs and return */ /* Check current_thread_info()->flags */ - andi. r0,r4,_TIF_USER_WORK_MASK - beq restore - - andi. r0,r4,_TIF_NEED_RESCHED - beq 1f - bl .restore_interrupts - bl .schedule - b .ret_from_except_lite - -1: bl .save_nvgprs - bl .restore_interrupts - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_notify_resume - b .ret_from_except - -resume_kernel: -#ifdef CONFIG_PREEMPT - /* Check if we need to preempt */ - andi. r0,r4,_TIF_NEED_RESCHED - beq+ restore - /* Check that preempt_count() == 0 and interrupts are enabled */ - lwz r8,TI_PREEMPT(r9) - cmpwi cr1,r8,0 - ld r0,SOFTE(r1) - cmpdi r0,0 - crandc eq,cr1*4+eq,eq - bne restore - - /* - * Here we are preempting the current task. We want to make - * sure we are soft-disabled first - */ - SOFT_DISABLE_INTS(r3,r4) -1: bl .preempt_schedule_irq - - /* Re-test flags and eventually loop */ clrrdi r9,r1,THREAD_SHIFT ld r4,TI_FLAGS(r9) - andi. r0,r4,_TIF_NEED_RESCHED - bne 1b -#endif /* CONFIG_PREEMPT */ + andi. r0,r4,_TIF_USER_WORK_MASK + bne do_work +#endif /* !CONFIG_PREEMPT */ .globl fast_exc_return_irq fast_exc_return_irq: @@ -786,6 +759,50 @@ restore_check_irq_replay: #endif /* CONFIG_PPC_BOOK3E */ 1: b .ret_from_except /* What else to do here ? */ + + +3: +do_work: +#ifdef CONFIG_PREEMPT + andi. r0,r3,MSR_PR /* Returning to user mode? */ + bne user_work + /* Check that preempt_count() == 0 and interrupts are enabled */ + lwz r8,TI_PREEMPT(r9) + cmpwi cr1,r8,0 + ld r0,SOFTE(r1) + cmpdi r0,0 + crandc eq,cr1*4+eq,eq + bne restore + + /* + * Here we are preempting the current task. We want to make + * sure we are soft-disabled first + */ + SOFT_DISABLE_INTS(r3,r4) +1: bl .preempt_schedule_irq + + /* Re-test flags and eventually loop */ + clrrdi r9,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r9) + andi. r0,r4,_TIF_NEED_RESCHED + bne 1b + b restore + +user_work: +#endif /* CONFIG_PREEMPT */ + + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + bl .restore_interrupts + bl .schedule + b .ret_from_except_lite + +1: bl .save_nvgprs + bl .restore_interrupts + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_notify_resume + b .ret_from_except + unrecov_restore: addi r3,r1,STACK_FRAME_OVERHEAD bl .unrecoverable_exception diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 1f017bb7a7ce..7835a5e1ea5f 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -229,7 +229,7 @@ notrace void arch_local_irq_restore(unsigned long en) */ if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) __hard_irq_disable(); -#ifdef CONFIG_TRACE_IRQFLAGS +#ifdef CONFIG_TRACE_IRQFLAG else { /* * We should already be hard disabled here. We had bugs @@ -277,7 +277,7 @@ EXPORT_SYMBOL(arch_local_irq_restore); * NOTE: This is called with interrupts hard disabled but not marked * as such in paca->irq_happened, so we need to resync this. */ -void notrace restore_interrupts(void) +void restore_interrupts(void) { if (irqs_disabled()) { local_paca->irq_happened |= PACA_IRQ_HARD_DIS; @@ -286,52 +286,6 @@ void notrace restore_interrupts(void) __hard_irq_enable(); } -/* - * This is a helper to use when about to go into idle low-power - * when the latter has the side effect of re-enabling interrupts - * (such as calling H_CEDE under pHyp). - * - * You call this function with interrupts soft-disabled (this is - * already the case when ppc_md.power_save is called). The function - * will return whether to enter power save or just return. - * - * In the former case, it will have notified lockdep of interrupts - * being re-enabled and generally sanitized the lazy irq state, - * and in the latter case it will leave with interrupts hard - * disabled and marked as such, so the local_irq_enable() call - * in cpu_idle() will properly re-enable everything. - */ -bool prep_irq_for_idle(void) -{ - /* - * First we need to hard disable to ensure no interrupt - * occurs before we effectively enter the low power state - */ - hard_irq_disable(); - - /* - * If anything happened while we were soft-disabled, - * we return now and do not enter the low power state. - */ - if (lazy_irq_pending()) - return false; - - /* Tell lockdep we are about to re-enable */ - trace_hardirqs_on(); - - /* - * Mark interrupts as soft-enabled and clear the - * PACA_IRQ_HARD_DIS from the pending mask since we - * are about to hard enable as well as a side effect - * of entering the low power state. - */ - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; - local_paca->soft_enabled = 1; - - /* Tell the caller to enter the low power state */ - return true; -} - #endif /* CONFIG_PPC64 */ int arch_show_interrupts(struct seq_file *p, int prec) diff --git a/trunk/arch/powerpc/kernel/module_32.c b/trunk/arch/powerpc/kernel/module_32.c index 2e3200ca485f..0b6d79617d7b 100644 --- a/trunk/arch/powerpc/kernel/module_32.c +++ b/trunk/arch/powerpc/kernel/module_32.c @@ -176,8 +176,8 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr, static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) { - if (entry->jump[0] == 0x3d800000 + ((val + 0x8000) >> 16) - && entry->jump[1] == 0x398c0000 + (val & 0xffff)) + if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16) + && entry->jump[1] == 0x396b0000 + (val & 0xffff)) return 1; return 0; } @@ -204,9 +204,10 @@ static uint32_t do_plt_call(void *location, entry++; } - entry->jump[0] = 0x3d800000+((val+0x8000)>>16); /* lis r12,sym@ha */ - entry->jump[1] = 0x398c0000 + (val&0xffff); /* addi r12,r12,sym@l*/ - entry->jump[2] = 0x7d8903a6; /* mtctr r12 */ + /* Stolen from Paul Mackerras as well... */ + entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */ + entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/ + entry->jump[2] = 0x7d6903a6; /* mtctr r11 */ entry->jump[3] = 0x4e800420; /* bctr */ DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 0794a3017b1b..1b488e5305c5 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -1312,7 +1312,7 @@ static struct opal_secondary_data { extern char opal_secondary_entry; -static void __init prom_query_opal(void) +static void prom_query_opal(void) { long rc; @@ -1436,7 +1436,7 @@ static void __init prom_opal_hold_cpus(void) prom_debug("prom_opal_hold_cpus: end...\n"); } -static void __init prom_opal_takeover(void) +static void prom_opal_takeover(void) { struct opal_secondary_data *data = &RELOC(opal_secondary_data); struct opal_takeover_args *args = &data->args; diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index e1417c42155c..e4cb34322de4 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -571,6 +571,7 @@ void __devinit start_secondary(void *unused) if (system_state == SYSTEM_RUNNING) vdso_data->processorCount++; #endif + ipi_call_lock(); notify_cpu_starting(cpu); set_cpu_online(cpu, true); /* Update sibling maps */ @@ -600,6 +601,7 @@ void __devinit start_secondary(void *unused) of_node_put(np); } of_node_put(l2_cache); + ipi_call_unlock(); local_irq_enable(); diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index be171ee73bf8..99a995c2a3f2 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -475,7 +475,6 @@ void timer_interrupt(struct pt_regs * regs) struct pt_regs *old_regs; u64 *next_tb = &__get_cpu_var(decrementers_next_tb); struct clock_event_device *evt = &__get_cpu_var(decrementers); - u64 now; /* Ensure a positive value is written to the decrementer, or else * some CPUs will continue to take decrementer exceptions. @@ -510,16 +509,9 @@ void timer_interrupt(struct pt_regs * regs) irq_work_run(); } - now = get_tb_or_rtc(); - if (now >= *next_tb) { - *next_tb = ~(u64)0; - if (evt->event_handler) - evt->event_handler(evt); - } else { - now = *next_tb - now; - if (now <= DECREMENTER_MAX) - set_dec((int)now); - } + *next_tb = ~(u64)0; + if (evt->event_handler) + evt->event_handler(evt); #ifdef CONFIG_PPC64 /* collect purr register values often, for accurate calculations */ diff --git a/trunk/arch/powerpc/kvm/book3s_hv.c b/trunk/arch/powerpc/kvm/book3s_hv.c index 3abe1b86e583..c6af1d623839 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv.c +++ b/trunk/arch/powerpc/kvm/book3s_hv.c @@ -268,45 +268,24 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, return err; } -static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap) +static void kvmppc_update_vpa(struct kvm *kvm, struct kvmppc_vpa *vpap) { - struct kvm *kvm = vcpu->kvm; void *va; unsigned long nb; - unsigned long gpa; - - /* - * We need to pin the page pointed to by vpap->next_gpa, - * but we can't call kvmppc_pin_guest_page under the lock - * as it does get_user_pages() and down_read(). So we - * have to drop the lock, pin the page, then get the lock - * again and check that a new area didn't get registered - * in the meantime. - */ - for (;;) { - gpa = vpap->next_gpa; - spin_unlock(&vcpu->arch.vpa_update_lock); - va = NULL; - nb = 0; - if (gpa) - va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb); - spin_lock(&vcpu->arch.vpa_update_lock); - if (gpa == vpap->next_gpa) - break; - /* sigh... unpin that one and try again */ - if (va) - kvmppc_unpin_guest_page(kvm, va); - } vpap->update_pending = 0; - if (va && nb < vpap->len) { - /* - * If it's now too short, it must be that userspace - * has changed the mappings underlying guest memory, - * so unregister the region. - */ - kvmppc_unpin_guest_page(kvm, va); - va = NULL; + va = NULL; + if (vpap->next_gpa) { + va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb); + if (nb < vpap->len) { + /* + * If it's now too short, it must be that userspace + * has changed the mappings underlying guest memory, + * so unregister the region. + */ + kvmppc_unpin_guest_page(kvm, va); + va = NULL; + } } if (vpap->pinned_addr) kvmppc_unpin_guest_page(kvm, vpap->pinned_addr); @@ -317,18 +296,20 @@ static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap) static void kvmppc_update_vpas(struct kvm_vcpu *vcpu) { + struct kvm *kvm = vcpu->kvm; + spin_lock(&vcpu->arch.vpa_update_lock); if (vcpu->arch.vpa.update_pending) { - kvmppc_update_vpa(vcpu, &vcpu->arch.vpa); + kvmppc_update_vpa(kvm, &vcpu->arch.vpa); init_vpa(vcpu, vcpu->arch.vpa.pinned_addr); } if (vcpu->arch.dtl.update_pending) { - kvmppc_update_vpa(vcpu, &vcpu->arch.dtl); + kvmppc_update_vpa(kvm, &vcpu->arch.dtl); vcpu->arch.dtl_ptr = vcpu->arch.dtl.pinned_addr; vcpu->arch.dtl_index = 0; } if (vcpu->arch.slb_shadow.update_pending) - kvmppc_update_vpa(vcpu, &vcpu->arch.slb_shadow); + kvmppc_update_vpa(kvm, &vcpu->arch.slb_shadow); spin_unlock(&vcpu->arch.vpa_update_lock); } @@ -819,39 +800,12 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc) struct kvm_vcpu *vcpu, *vcpu0, *vnext; long ret; u64 now; - int ptid, i, need_vpa_update; + int ptid, i; /* don't start if any threads have a signal pending */ - need_vpa_update = 0; - list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { + list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) if (signal_pending(vcpu->arch.run_task)) return 0; - need_vpa_update |= vcpu->arch.vpa.update_pending | - vcpu->arch.slb_shadow.update_pending | - vcpu->arch.dtl.update_pending; - } - - /* - * Initialize *vc, in particular vc->vcore_state, so we can - * drop the vcore lock if necessary. - */ - vc->n_woken = 0; - vc->nap_count = 0; - vc->entry_exit_count = 0; - vc->vcore_state = VCORE_RUNNING; - vc->in_guest = 0; - vc->napping_threads = 0; - - /* - * Updating any of the vpas requires calling kvmppc_pin_guest_page, - * which can't be called with any spinlocks held. - */ - if (need_vpa_update) { - spin_unlock(&vc->lock); - list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) - kvmppc_update_vpas(vcpu); - spin_lock(&vc->lock); - } /* * Make sure we are running on thread 0, and that @@ -884,10 +838,20 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc) if (vcpu->arch.ceded) vcpu->arch.ptid = ptid++; + vc->n_woken = 0; + vc->nap_count = 0; + vc->entry_exit_count = 0; + vc->vcore_state = VCORE_RUNNING; vc->stolen_tb += mftb() - vc->preempt_tb; + vc->in_guest = 0; vc->pcpu = smp_processor_id(); + vc->napping_threads = 0; list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { kvmppc_start_thread(vcpu); + if (vcpu->arch.vpa.update_pending || + vcpu->arch.slb_shadow.update_pending || + vcpu->arch.dtl.update_pending) + kvmppc_update_vpas(vcpu); kvmppc_create_dtl_entry(vcpu, vc); } /* Grab any remaining hw threads so they can't go into the kernel */ diff --git a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S index a1044f43becd..a84aafce2a12 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -810,7 +810,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) lwz r3,VCORE_NAPPING_THREADS(r5) lwz r4,VCPU_PTID(r9) li r0,1 - sld r0,r0,r4 + sldi r0,r0,r4 andc. r3,r3,r0 /* no sense IPI'ing ourselves */ beq 43f mulli r4,r4,PACA_SIZE /* get paca for thread 0 */ diff --git a/trunk/arch/powerpc/kvm/book3s_pr_papr.c b/trunk/arch/powerpc/kvm/book3s_pr_papr.c index ee02b30878ed..3ff9013d6e79 100644 --- a/trunk/arch/powerpc/kvm/book3s_pr_papr.c +++ b/trunk/arch/powerpc/kvm/book3s_pr_papr.c @@ -241,7 +241,6 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) case H_PUT_TCE: return kvmppc_h_pr_put_tce(vcpu); case H_CEDE: - vcpu->arch.shared->msr |= MSR_EE; kvm_vcpu_block(vcpu); clear_bit(KVM_REQ_UNHALT, &vcpu->requests); vcpu->stat.halt_wakeup++; diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 1e95556dc692..b6edbb3b4a54 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -635,11 +635,11 @@ static inline int __init read_usm_ranges(const u32 **usm) */ static void __init parse_drconf_memory(struct device_node *memory) { - const u32 *uninitialized_var(dm), *usm; + const u32 *dm, *usm; unsigned int n, rc, ranges, is_kexec_kdump = 0; unsigned long lmb_size, base, size, sz; int nid; - struct assoc_arrays aa = { .arrays = NULL }; + struct assoc_arrays aa; n = of_get_drconf_memory(memory, &dm); if (!n) diff --git a/trunk/arch/powerpc/net/bpf_jit_64.S b/trunk/arch/powerpc/net/bpf_jit_64.S index 7d3a3b5619a2..55ba3855a97f 100644 --- a/trunk/arch/powerpc/net/bpf_jit_64.S +++ b/trunk/arch/powerpc/net/bpf_jit_64.S @@ -105,7 +105,6 @@ sk_load_byte_msh_positive_offset: mr r4, r_addr; \ li r6, SIZE; \ bl skb_copy_bits; \ - nop; \ /* R3 = 0 on success */ \ addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ ld r0, 16(r1); \ @@ -157,7 +156,6 @@ bpf_slow_path_byte_msh: mr r4, r_addr; \ li r5, SIZE; \ bl bpf_internal_load_pointer_neg_helper; \ - nop; \ /* R3 != 0 on success */ \ addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ ld r0, 16(r1); \ diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c index d17e98bc0c10..efdacc829576 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/pervasive.c @@ -42,9 +42,11 @@ static void cbe_power_save(void) { unsigned long ctrl, thread_switch_control; - /* Ensure our interrupt state is properly tracked */ - if (!prep_irq_for_idle()) - return; + /* + * We need to hard disable interrupts, the local_irq_enable() done by + * our caller upon return will hard re-enable. + */ + hard_irq_disable(); ctrl = mfspr(SPRN_CTRLF); @@ -79,9 +81,6 @@ static void cbe_power_save(void) */ ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); mtspr(SPRN_CTRLT, ctrl); - - /* Re-enable interrupts in MSR */ - __hard_irq_enable(); } static int cbe_system_reset_exception(struct pt_regs *regs) diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index 2d311c0caf8e..0915b1ad66ce 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -106,7 +106,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, tcep++; } - if (tbl->it_type & TCE_PCI_SWINV_CREATE) + if (tbl->it_type == TCE_PCI_SWINV_CREATE) tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); return 0; } @@ -121,7 +121,7 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) while (npages--) *(tcep++) = 0; - if (tbl->it_type & TCE_PCI_SWINV_FREE) + if (tbl->it_type == TCE_PCI_SWINV_FREE) tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); } diff --git a/trunk/arch/powerpc/platforms/pseries/nvram.c b/trunk/arch/powerpc/platforms/pseries/nvram.c index 8733a86ad52e..36f957f31842 100644 --- a/trunk/arch/powerpc/platforms/pseries/nvram.c +++ b/trunk/arch/powerpc/platforms/pseries/nvram.c @@ -68,7 +68,9 @@ static const char *pseries_nvram_os_partitions[] = { }; static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason); + enum kmsg_dump_reason reason, + const char *old_msgs, unsigned long old_len, + const char *new_msgs, unsigned long new_len); static struct kmsg_dumper nvram_kmsg_dumper = { .dump = oops_to_nvram @@ -501,6 +503,28 @@ int __init pSeries_nvram_init(void) return 0; } +/* + * Try to capture the last capture_len bytes of the printk buffer. Return + * the amount actually captured. + */ +static size_t capture_last_msgs(const char *old_msgs, size_t old_len, + const char *new_msgs, size_t new_len, + char *captured, size_t capture_len) +{ + if (new_len >= capture_len) { + memcpy(captured, new_msgs + (new_len - capture_len), + capture_len); + return capture_len; + } else { + /* Grab the end of old_msgs. */ + size_t old_tail_len = min(old_len, capture_len - new_len); + memcpy(captured, old_msgs + (old_len - old_tail_len), + old_tail_len); + memcpy(captured + old_tail_len, new_msgs, new_len); + return old_tail_len + new_len; + } +} + /* * Are we using the ibm,rtas-log for oops/panic reports? And if so, * would logging this oops/panic overwrite an RTAS event that rtas_errd @@ -517,6 +541,27 @@ static int clobbering_unread_rtas_event(void) NVRAM_RTAS_READ_TIMEOUT); } +/* Squeeze out each line's severity prefix. */ +static size_t elide_severities(char *buf, size_t len) +{ + char *in, *out, *buf_end = buf + len; + /* Assume a at the very beginning marks the start of a line. */ + int newline = 1; + + in = out = buf; + while (in < buf_end) { + if (newline && in+3 <= buf_end && + *in == '<' && isdigit(in[1]) && in[2] == '>') { + in += 3; + newline = 0; + } else { + newline = (*in == '\n'); + *out++ = *in++; + } + } + return out - buf; +} + /* Derived from logfs_compress() */ static int nvram_compress(const void *in, void *out, size_t inlen, size_t outlen) @@ -574,7 +619,9 @@ static int zip_oops(size_t text_len) * partition. If that's too much, go back and capture uncompressed text. */ static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason) + enum kmsg_dump_reason reason, + const char *old_msgs, unsigned long old_len, + const char *new_msgs, unsigned long new_len) { static unsigned int oops_count = 0; static bool panicking = false; @@ -613,14 +660,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, return; if (big_oops_buf) { - kmsg_dump_get_buffer(dumper, false, - big_oops_buf, big_oops_buf_sz, &text_len); + text_len = capture_last_msgs(old_msgs, old_len, + new_msgs, new_len, big_oops_buf, big_oops_buf_sz); + text_len = elide_severities(big_oops_buf, text_len); rc = zip_oops(text_len); } if (rc != 0) { - kmsg_dump_rewind(dumper); - kmsg_dump_get_buffer(dumper, true, - oops_data, oops_data_sz, &text_len); + text_len = capture_last_msgs(old_msgs, old_len, + new_msgs, new_len, oops_data, oops_data_sz); err_type = ERR_TYPE_KERNEL_PANIC; *oops_len = (u16) text_len; } diff --git a/trunk/arch/powerpc/platforms/pseries/processor_idle.c b/trunk/arch/powerpc/platforms/pseries/processor_idle.c index c71be66bd5dc..41a34bc4a9a2 100644 --- a/trunk/arch/powerpc/platforms/pseries/processor_idle.c +++ b/trunk/arch/powerpc/platforms/pseries/processor_idle.c @@ -99,18 +99,15 @@ static int snooze_loop(struct cpuidle_device *dev, static void check_and_cede_processor(void) { /* - * Ensure our interrupt state is properly tracked, - * also checks if no interrupt has occurred while we - * were soft-disabled + * Interrupts are soft-disabled at this point, + * but not hard disabled. So an interrupt might have + * occurred before entering NAP, and would be potentially + * lost (edge events, decrementer events, etc...) unless + * we first hard disable then check. */ - if (prep_irq_for_idle()) { + hard_irq_disable(); + if (get_paca()->irq_happened == 0) cede_processor(); -#ifdef CONFIG_TRACE_IRQFLAGS - /* Ensure that H_CEDE returns with IRQs on */ - if (WARN_ON(!(mfmsr() & MSR_EE))) - __hard_irq_enable(); -#endif - } } static int dedicated_cede_loop(struct cpuidle_device *dev, diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index eab3492a45c5..0f3ab06d2222 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -971,7 +971,7 @@ static int cpu_cmd(void) /* print cpus waiting or in xmon */ printf("cpus stopped:"); count = 0; - for_each_possible_cpu(cpu) { + for (cpu = 0; cpu < NR_CPUS; ++cpu) { if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { if (count == 0) printf(" %x", cpu); diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 8dca9c248ac7..15cca26ccb6c 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -717,7 +717,9 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) init_cpu_vtimer(); pfault_init(); notify_cpu_starting(smp_processor_id()); + ipi_call_lock(); set_cpu_online(smp_processor_id(), true); + ipi_call_unlock(); local_irq_enable(); /* cpu_idle will call schedule for us */ cpu_idle(); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 31d9db7913e4..99bcd0ee838d 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -32,8 +32,6 @@ config SUPERH select GENERIC_SMP_IDLE_THREAD select GENERIC_CLOCKEVENTS select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST - select GENERIC_STRNCPY_FROM_USER - select GENERIC_STRNLEN_USER help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index aed701c7b11b..46edf070da1c 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -9,12 +9,6 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -ifneq ($(SUBARCH),$(ARCH)) - ifeq ($(CROSS_COMPILE),) - CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-) - endif -endif - isa-y := any isa-$(CONFIG_SH_DSP) := sh isa-$(CONFIG_CPU_SH2) := sh2 @@ -112,13 +106,19 @@ LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \ KBUILD_DEFCONFIG := cayman_defconfig endif +ifneq ($(SUBARCH),$(ARCH)) + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-) + endif +endif + ifdef CONFIG_CPU_LITTLE_ENDIAN ld-bfd := elf32-$(UTS_MACHINE)-linux -LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd) +LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' --oformat $(ld-bfd) LDFLAGS += -EL else ld-bfd := elf32-$(UTS_MACHINE)big-linux -LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd) +LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4' --oformat $(ld-bfd) LDFLAGS += -EB endif diff --git a/trunk/arch/sh/boards/mach-kfr2r09/setup.c b/trunk/arch/sh/boards/mach-kfr2r09/setup.c index 43a179ce9afc..158c9176e42a 100644 --- a/trunk/arch/sh/boards/mach-kfr2r09/setup.c +++ b/trunk/arch/sh/boards/mach-kfr2r09/setup.c @@ -201,8 +201,8 @@ static struct resource kfr2r09_usb0_gadget_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = evt2irq(0xa20), - .end = evt2irq(0xa20), + .start = evtirq(0xa20), + .end = evtirq(0xa20), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, }, }; diff --git a/trunk/arch/sh/drivers/pci/pcie-sh7786.c b/trunk/arch/sh/drivers/pci/pcie-sh7786.c index 9e702f2f8045..c045142f7338 100644 --- a/trunk/arch/sh/drivers/pci/pcie-sh7786.c +++ b/trunk/arch/sh/drivers/pci/pcie-sh7786.c @@ -239,7 +239,7 @@ static int __init pcie_clk_init(struct sh7786_pcie_port *port) clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR); clk->enable_bit = BITS_CKE; - ret = sh_clk_mstp_register(clk, 1); + ret = sh_clk_mstp32_register(clk, 1); if (unlikely(ret < 0)) goto err_phy; diff --git a/trunk/arch/sh/include/asm/Kbuild b/trunk/arch/sh/include/asm/Kbuild index 7b673ddcd555..7beb42322f60 100644 --- a/trunk/arch/sh/include/asm/Kbuild +++ b/trunk/arch/sh/include/asm/Kbuild @@ -1,39 +1,5 @@ include include/asm-generic/Kbuild.asm -generic-y += bitsperlong.h -generic-y += cputime.h -generic-y += current.h -generic-y += delay.h -generic-y += div64.h -generic-y += emergency-restart.h -generic-y += errno.h -generic-y += fcntl.h -generic-y += ioctl.h -generic-y += ipcbuf.h -generic-y += irq_regs.h -generic-y += kvm_para.h -generic-y += local.h -generic-y += local64.h -generic-y += param.h -generic-y += parport.h -generic-y += percpu.h -generic-y += poll.h -generic-y += mman.h -generic-y += msgbuf.h -generic-y += resource.h -generic-y += scatterlist.h -generic-y += sembuf.h -generic-y += serial.h -generic-y += shmbuf.h -generic-y += siginfo.h -generic-y += sizes.h -generic-y += socket.h -generic-y += statfs.h -generic-y += termbits.h -generic-y += termios.h -generic-y += ucontext.h -generic-y += xor.h - header-y += cachectl.h header-y += cpu-features.h header-y += hw_breakpoint.h diff --git a/trunk/arch/sh/include/asm/bitsperlong.h b/trunk/arch/sh/include/asm/bitsperlong.h new file mode 100644 index 000000000000..6dc0bb0c13b2 --- /dev/null +++ b/trunk/arch/sh/include/asm/bitsperlong.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/cputime.h b/trunk/arch/sh/include/asm/cputime.h new file mode 100644 index 000000000000..6ca395d1393e --- /dev/null +++ b/trunk/arch/sh/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef __SH_CPUTIME_H +#define __SH_CPUTIME_H + +#include + +#endif /* __SH_CPUTIME_H */ diff --git a/trunk/arch/sh/include/asm/current.h b/trunk/arch/sh/include/asm/current.h new file mode 100644 index 000000000000..4c51401b5537 --- /dev/null +++ b/trunk/arch/sh/include/asm/current.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/delay.h b/trunk/arch/sh/include/asm/delay.h new file mode 100644 index 000000000000..9670e127b7b2 --- /dev/null +++ b/trunk/arch/sh/include/asm/delay.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/div64.h b/trunk/arch/sh/include/asm/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/trunk/arch/sh/include/asm/div64.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/emergency-restart.h b/trunk/arch/sh/include/asm/emergency-restart.h new file mode 100644 index 000000000000..108d8c48e42e --- /dev/null +++ b/trunk/arch/sh/include/asm/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/trunk/arch/sh/include/asm/errno.h b/trunk/arch/sh/include/asm/errno.h new file mode 100644 index 000000000000..51cf6f9cebb8 --- /dev/null +++ b/trunk/arch/sh/include/asm/errno.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_ERRNO_H +#define __ASM_SH_ERRNO_H + +#include + +#endif /* __ASM_SH_ERRNO_H */ diff --git a/trunk/arch/sh/include/asm/fcntl.h b/trunk/arch/sh/include/asm/fcntl.h new file mode 100644 index 000000000000..46ab12db5739 --- /dev/null +++ b/trunk/arch/sh/include/asm/fcntl.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/io_noioport.h b/trunk/arch/sh/include/asm/io_noioport.h index 4d48f1436a63..e136d28d1d2e 100644 --- a/trunk/arch/sh/include/asm/io_noioport.h +++ b/trunk/arch/sh/include/asm/io_noioport.h @@ -19,20 +19,9 @@ static inline u32 inl(unsigned long addr) return -1; } -static inline void outb(unsigned char x, unsigned long port) -{ - BUG(); -} - -static inline void outw(unsigned short x, unsigned long port) -{ - BUG(); -} - -static inline void outl(unsigned int x, unsigned long port) -{ - BUG(); -} +#define outb(x, y) BUG() +#define outw(x, y) BUG() +#define outl(x, y) BUG() #define inb_p(addr) inb(addr) #define inw_p(addr) inw(addr) diff --git a/trunk/arch/sh/include/asm/ioctl.h b/trunk/arch/sh/include/asm/ioctl.h new file mode 100644 index 000000000000..b279fe06dfe5 --- /dev/null +++ b/trunk/arch/sh/include/asm/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/ipcbuf.h b/trunk/arch/sh/include/asm/ipcbuf.h new file mode 100644 index 000000000000..84c7e51cb6d0 --- /dev/null +++ b/trunk/arch/sh/include/asm/ipcbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/irq_regs.h b/trunk/arch/sh/include/asm/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/trunk/arch/sh/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/kvm_para.h b/trunk/arch/sh/include/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/trunk/arch/sh/include/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/local.h b/trunk/arch/sh/include/asm/local.h new file mode 100644 index 000000000000..9ed9b9cb459a --- /dev/null +++ b/trunk/arch/sh/include/asm/local.h @@ -0,0 +1,7 @@ +#ifndef __ASM_SH_LOCAL_H +#define __ASM_SH_LOCAL_H + +#include + +#endif /* __ASM_SH_LOCAL_H */ + diff --git a/trunk/arch/sh/include/asm/local64.h b/trunk/arch/sh/include/asm/local64.h new file mode 100644 index 000000000000..36c93b5cc239 --- /dev/null +++ b/trunk/arch/sh/include/asm/local64.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/mman.h b/trunk/arch/sh/include/asm/mman.h new file mode 100644 index 000000000000..8eebf89f5ab1 --- /dev/null +++ b/trunk/arch/sh/include/asm/mman.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/msgbuf.h b/trunk/arch/sh/include/asm/msgbuf.h new file mode 100644 index 000000000000..809134c644a6 --- /dev/null +++ b/trunk/arch/sh/include/asm/msgbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/param.h b/trunk/arch/sh/include/asm/param.h new file mode 100644 index 000000000000..965d45427975 --- /dev/null +++ b/trunk/arch/sh/include/asm/param.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/parport.h b/trunk/arch/sh/include/asm/parport.h new file mode 100644 index 000000000000..cf252af64590 --- /dev/null +++ b/trunk/arch/sh/include/asm/parport.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/percpu.h b/trunk/arch/sh/include/asm/percpu.h new file mode 100644 index 000000000000..4db4b39a4399 --- /dev/null +++ b/trunk/arch/sh/include/asm/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ARCH_SH_PERCPU +#define __ARCH_SH_PERCPU + +#include + +#endif /* __ARCH_SH_PERCPU */ diff --git a/trunk/arch/sh/include/asm/poll.h b/trunk/arch/sh/include/asm/poll.h new file mode 100644 index 000000000000..c98509d3149e --- /dev/null +++ b/trunk/arch/sh/include/asm/poll.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/resource.h b/trunk/arch/sh/include/asm/resource.h new file mode 100644 index 000000000000..9c2499a86ec0 --- /dev/null +++ b/trunk/arch/sh/include/asm/resource.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_RESOURCE_H +#define __ASM_SH_RESOURCE_H + +#include + +#endif /* __ASM_SH_RESOURCE_H */ diff --git a/trunk/arch/sh/include/asm/scatterlist.h b/trunk/arch/sh/include/asm/scatterlist.h new file mode 100644 index 000000000000..98dfc3510f10 --- /dev/null +++ b/trunk/arch/sh/include/asm/scatterlist.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_SCATTERLIST_H +#define __ASM_SH_SCATTERLIST_H + +#include + +#endif /* __ASM_SH_SCATTERLIST_H */ diff --git a/trunk/arch/sh/include/asm/sembuf.h b/trunk/arch/sh/include/asm/sembuf.h new file mode 100644 index 000000000000..7673b83cfef7 --- /dev/null +++ b/trunk/arch/sh/include/asm/sembuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/serial.h b/trunk/arch/sh/include/asm/serial.h new file mode 100644 index 000000000000..a0cb0caff152 --- /dev/null +++ b/trunk/arch/sh/include/asm/serial.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/shmbuf.h b/trunk/arch/sh/include/asm/shmbuf.h new file mode 100644 index 000000000000..83c05fc2de38 --- /dev/null +++ b/trunk/arch/sh/include/asm/shmbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/siginfo.h b/trunk/arch/sh/include/asm/siginfo.h new file mode 100644 index 000000000000..813040ed68a9 --- /dev/null +++ b/trunk/arch/sh/include/asm/siginfo.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_SIGINFO_H +#define __ASM_SH_SIGINFO_H + +#include + +#endif /* __ASM_SH_SIGINFO_H */ diff --git a/trunk/arch/sh/include/asm/sizes.h b/trunk/arch/sh/include/asm/sizes.h new file mode 100644 index 000000000000..dd248c2e1085 --- /dev/null +++ b/trunk/arch/sh/include/asm/sizes.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/socket.h b/trunk/arch/sh/include/asm/socket.h new file mode 100644 index 000000000000..6b71384b9d8b --- /dev/null +++ b/trunk/arch/sh/include/asm/socket.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/statfs.h b/trunk/arch/sh/include/asm/statfs.h new file mode 100644 index 000000000000..9202a023328f --- /dev/null +++ b/trunk/arch/sh/include/asm/statfs.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_STATFS_H +#define __ASM_SH_STATFS_H + +#include + +#endif /* __ASM_SH_STATFS_H */ diff --git a/trunk/arch/sh/include/asm/termbits.h b/trunk/arch/sh/include/asm/termbits.h new file mode 100644 index 000000000000..3935b106de79 --- /dev/null +++ b/trunk/arch/sh/include/asm/termbits.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/termios.h b/trunk/arch/sh/include/asm/termios.h new file mode 100644 index 000000000000..280d78a9d966 --- /dev/null +++ b/trunk/arch/sh/include/asm/termios.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/uaccess.h b/trunk/arch/sh/include/asm/uaccess.h index 8698a80ed00c..050f221fa898 100644 --- a/trunk/arch/sh/include/asm/uaccess.h +++ b/trunk/arch/sh/include/asm/uaccess.h @@ -25,8 +25,6 @@ (__chk_user_ptr(addr), \ __access_ok((unsigned long __force)(addr), (size))) -#define user_addr_max() (current_thread_info()->addr_limit.seg) - /* * Uh, these should become the main single-value transfer routines ... * They automatically use the right size if we just have the right @@ -102,11 +100,6 @@ struct __large_struct { unsigned long buf[100]; }; # include "uaccess_64.h" #endif -extern long strncpy_from_user(char *dest, const char __user *src, long count); - -extern __must_check long strlen_user(const char __user *str); -extern __must_check long strnlen_user(const char __user *str, long n); - /* Generic arbitrary sized copy. */ /* Return the number of bytes NOT copied */ __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); @@ -144,6 +137,37 @@ __kernel_size_t __clear_user(void *addr, __kernel_size_t size); __cl_size; \ }) +/** + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ +#define strncpy_from_user(dest,src,count) \ +({ \ + unsigned long __sfu_src = (unsigned long)(src); \ + int __sfu_count = (int)(count); \ + long __sfu_res = -EFAULT; \ + \ + if (__access_ok(__sfu_src, __sfu_count)) \ + __sfu_res = __strncpy_from_user((unsigned long)(dest), \ + __sfu_src, __sfu_count); \ + \ + __sfu_res; \ +}) + static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { @@ -168,6 +192,43 @@ copy_to_user(void __user *to, const void *from, unsigned long n) return __copy_size; } +/** + * strnlen_user: - Get the size of a string in user space. + * @s: The string to measure. + * @n: The maximum valid length + * + * Context: User context only. This function may sleep. + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * If the string is too long, returns a value greater than @n. + */ +static inline long strnlen_user(const char __user *s, long n) +{ + if (!__addr_ok(s)) + return 0; + else + return __strnlen_user(s, n); +} + +/** + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * + * Context: User context only. This function may sleep. + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * + * If there is a limit on the length of a valid string, you may wish to + * consider using strnlen_user() instead. + */ +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) + /* * The exception table consists of pairs of addresses: the first is the * address of an instruction that is allowed to fault, and the second is diff --git a/trunk/arch/sh/include/asm/uaccess_32.h b/trunk/arch/sh/include/asm/uaccess_32.h index c0de7ee35ab7..ae0d24f6653f 100644 --- a/trunk/arch/sh/include/asm/uaccess_32.h +++ b/trunk/arch/sh/include/asm/uaccess_32.h @@ -170,4 +170,79 @@ __asm__ __volatile__( \ extern void __put_user_unknown(void); +static inline int +__strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count) +{ + __kernel_size_t res; + unsigned long __dummy, _d, _s, _c; + + __asm__ __volatile__( + "9:\n" + "mov.b @%2+, %1\n\t" + "cmp/eq #0, %1\n\t" + "bt/s 2f\n" + "1:\n" + "mov.b %1, @%3\n\t" + "dt %4\n\t" + "bf/s 9b\n\t" + " add #1, %3\n\t" + "2:\n\t" + "sub %4, %0\n" + "3:\n" + ".section .fixup,\"ax\"\n" + "4:\n\t" + "mov.l 5f, %1\n\t" + "jmp @%1\n\t" + " mov %9, %0\n\t" + ".balign 4\n" + "5: .long 3b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .balign 4\n" + " .long 9b,4b\n" + ".previous" + : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d), "=r"(_c) + : "0" (__count), "2" (__src), "3" (__dest), "4" (__count), + "i" (-EFAULT) + : "memory", "t"); + + return res; +} + +/* + * Return the size of a string (including the ending 0 even when we have + * exceeded the maximum string length). + */ +static inline long __strnlen_user(const char __user *__s, long __n) +{ + unsigned long res; + unsigned long __dummy; + + __asm__ __volatile__( + "1:\t" + "mov.b @(%0,%3), %1\n\t" + "cmp/eq %4, %0\n\t" + "bt/s 2f\n\t" + " add #1, %0\n\t" + "tst %1, %1\n\t" + "bf 1b\n\t" + "2:\n" + ".section .fixup,\"ax\"\n" + "3:\n\t" + "mov.l 4f, %1\n\t" + "jmp @%1\n\t" + " mov #0, %0\n" + ".balign 4\n" + "4: .long 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .balign 4\n" + " .long 1b,3b\n" + ".previous" + : "=z" (res), "=&r" (__dummy) + : "0" (0), "r" (__s), "r" (__n) + : "t"); + return res; +} + #endif /* __ASM_SH_UACCESS_32_H */ diff --git a/trunk/arch/sh/include/asm/uaccess_64.h b/trunk/arch/sh/include/asm/uaccess_64.h index 2e07e0f40c6a..56fd20b8cdcc 100644 --- a/trunk/arch/sh/include/asm/uaccess_64.h +++ b/trunk/arch/sh/include/asm/uaccess_64.h @@ -84,4 +84,8 @@ extern long __put_user_asm_l(void *, long); extern long __put_user_asm_q(void *, long); extern void __put_user_unknown(void); +extern long __strnlen_user(const char *__s, long __n); +extern int __strncpy_from_user(unsigned long __dest, + unsigned long __user __src, int __count); + #endif /* __ASM_SH_UACCESS_64_H */ diff --git a/trunk/arch/sh/include/asm/ucontext.h b/trunk/arch/sh/include/asm/ucontext.h new file mode 100644 index 000000000000..9bc07b9f30fb --- /dev/null +++ b/trunk/arch/sh/include/asm/ucontext.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/asm/word-at-a-time.h b/trunk/arch/sh/include/asm/word-at-a-time.h deleted file mode 100644 index 6e38953ff7fd..000000000000 --- a/trunk/arch/sh/include/asm/word-at-a-time.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __ASM_SH_WORD_AT_A_TIME_H -#define __ASM_SH_WORD_AT_A_TIME_H - -#ifdef CONFIG_CPU_BIG_ENDIAN -# include -#else -/* - * Little-endian version cribbed from x86. - */ -struct word_at_a_time { - const unsigned long one_bits, high_bits; -}; - -#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } - -/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ -static inline long count_masked_bytes(long mask) -{ - /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ - long a = (0x0ff0001+mask) >> 23; - /* Fix the 1 for 00 case */ - return a & mask; -} - -/* Return nonzero if it has a zero */ -static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c) -{ - unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; - *bits = mask; - return mask; -} - -static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c) -{ - return bits; -} - -static inline unsigned long create_zero_mask(unsigned long bits) -{ - bits = (bits - 1) & ~bits; - return bits >> 7; -} - -/* The mask we created is directly usable as a bytemask */ -#define zero_bytemask(mask) (mask) - -static inline unsigned long find_zero(unsigned long mask) -{ - return count_masked_bytes(mask); -} -#endif - -#endif diff --git a/trunk/arch/sh/include/asm/xor.h b/trunk/arch/sh/include/asm/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/trunk/arch/sh/include/asm/xor.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sh/include/cpu-sh2a/cpu/ubc.h b/trunk/arch/sh/include/cpu-sh2a/cpu/ubc.h new file mode 100644 index 000000000000..1192e1c761a7 --- /dev/null +++ b/trunk/arch/sh/include/cpu-sh2a/cpu/ubc.h @@ -0,0 +1,28 @@ +/* + * SH-2A UBC definitions + * + * Copyright (C) 2008 Kieran Bingham + * + * 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. + */ + +#ifndef __ASM_CPU_SH2A_UBC_H +#define __ASM_CPU_SH2A_UBC_H + +#define UBC_BARA 0xfffc0400 +#define UBC_BAMRA 0xfffc0404 +#define UBC_BBRA 0xfffc04a0 /* 16 bit access */ +#define UBC_BDRA 0xfffc0408 +#define UBC_BDMRA 0xfffc040c + +#define UBC_BARB 0xfffc0410 +#define UBC_BAMRB 0xfffc0414 +#define UBC_BBRB 0xfffc04b0 /* 16 bit access */ +#define UBC_BDRB 0xfffc0418 +#define UBC_BDMRB 0xfffc041c + +#define UBC_BRCR 0xfffc04c0 + +#endif /* __ASM_CPU_SH2A_UBC_H */ diff --git a/trunk/arch/sh/kernel/cpu/sh3/serial-sh7720.c b/trunk/arch/sh/kernel/cpu/sh3/serial-sh7720.c index c4a0336660dd..8832c526cdf9 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/serial-sh7720.c +++ b/trunk/arch/sh/kernel/cpu/sh3/serial-sh7720.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include static void sh7720_sci_init_pins(struct uart_port *port, unsigned int cflag) { diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 53638e231cd0..ea01a72f1b94 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -283,7 +283,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 22e485d1990b..7ac07b4f75de 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -276,7 +276,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index c4cb740e4d10..8e1f97010c0d 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -261,7 +261,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR); + ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 37c41c7747a3..35f75cf0c7e5 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -311,7 +311,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR); + ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index c87e78f73234..2a87901673fe 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -375,7 +375,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR); + ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7734.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7734.c index deb683abacf0..1697642c1f73 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7734.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7734.c @@ -260,7 +260,7 @@ int __init arch_clk_init(void) &div4_table); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index e84a43229b9c..04ab5aeaf920 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -148,7 +148,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 1c83788db76a..ab1c58f2d101 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -175,7 +175,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 8bba6f159023..491709483e10 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -194,7 +194,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-shx3.c index a9422dab0ce7..0f11b392bf46 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -149,7 +149,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh5/entry.S b/trunk/arch/sh/kernel/cpu/sh5/entry.S index b7cf6a547f11..ff1f0e6e9bec 100644 --- a/trunk/arch/sh/kernel/cpu/sh5/entry.S +++ b/trunk/arch/sh/kernel/cpu/sh5/entry.S @@ -1568,6 +1568,86 @@ ___clear_user_exit: #endif /* CONFIG_MMU */ +/* + * int __strncpy_from_user(unsigned long __dest, unsigned long __src, + * int __count) + * + * Inputs: + * (r2) target address + * (r3) source address + * (r4) maximum size in bytes + * + * Ouputs: + * (*r2) copied data + * (r2) -EFAULT (in case of faulting) + * copied data (otherwise) + */ + .global __strncpy_from_user +__strncpy_from_user: + pta ___strncpy_from_user1, tr0 + pta ___strncpy_from_user_done, tr1 + or r4, ZERO, r5 /* r5 = original count */ + beq/u r4, r63, tr1 /* early exit if r4==0 */ + movi -(EFAULT), r6 /* r6 = reply, no real fixup */ + or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ + +___strncpy_from_user1: + ld.b r3, 0, r7 /* Fault address: only in reading */ + st.b r2, 0, r7 + addi r2, 1, r2 + addi r3, 1, r3 + beq/u ZERO, r7, tr1 + addi r4, -1, r4 /* return real number of copied bytes */ + bne/l ZERO, r4, tr0 + +___strncpy_from_user_done: + sub r5, r4, r6 /* If done, return copied */ + +___strncpy_from_user_exit: + or r6, ZERO, r2 + ptabs LINK, tr0 + blink tr0, ZERO + +/* + * extern long __strnlen_user(const char *__s, long __n) + * + * Inputs: + * (r2) source address + * (r3) source size in bytes + * + * Ouputs: + * (r2) -EFAULT (in case of faulting) + * string length (otherwise) + */ + .global __strnlen_user +__strnlen_user: + pta ___strnlen_user_set_reply, tr0 + pta ___strnlen_user1, tr1 + or ZERO, ZERO, r5 /* r5 = counter */ + movi -(EFAULT), r6 /* r6 = reply, no real fixup */ + or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ + beq r3, ZERO, tr0 + +___strnlen_user1: + ldx.b r2, r5, r7 /* Fault address: only in reading */ + addi r3, -1, r3 /* No real fixup */ + addi r5, 1, r5 + beq r3, ZERO, tr0 + bne r7, ZERO, tr1 +! The line below used to be active. This meant led to a junk byte lying between each pair +! of entries in the argv & envp structures in memory. Whilst the program saw the right data +! via the argv and envp arguments to main, it meant the 'flat' representation visible through +! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example. +! addi r5, 1, r5 /* Include '\0' */ + +___strnlen_user_set_reply: + or r5, ZERO, r6 /* If done, return counter */ + +___strnlen_user_exit: + or r6, ZERO, r2 + ptabs LINK, tr0 + blink tr0, ZERO + /* * extern long __get_user_asm_?(void *val, long addr) * @@ -1902,6 +1982,8 @@ asm_uaccess_start: .long ___copy_user2, ___copy_user_exit .long ___clear_user1, ___clear_user_exit #endif + .long ___strncpy_from_user1, ___strncpy_from_user_exit + .long ___strnlen_user1, ___strnlen_user_exit .long ___get_user_asm_b1, ___get_user_asm_b_exit .long ___get_user_asm_w1, ___get_user_asm_w_exit .long ___get_user_asm_l1, ___get_user_asm_l_exit diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index 055d91b70305..9b7a459a4613 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -4,7 +4,6 @@ #include #include #include -#include struct kmem_cache *task_xstate_cachep = NULL; unsigned int xstate_size; diff --git a/trunk/arch/sh/kernel/process_64.c b/trunk/arch/sh/kernel/process_64.c index 602545b12a86..4264583eabac 100644 --- a/trunk/arch/sh/kernel/process_64.c +++ b/trunk/arch/sh/kernel/process_64.c @@ -33,7 +33,6 @@ #include struct task_struct *last_task_used_math = NULL; -struct pt_regs fake_swapper_regs = { 0, }; void show_regs(struct pt_regs *regs) { diff --git a/trunk/arch/sh/kernel/sh_ksyms_64.c b/trunk/arch/sh/kernel/sh_ksyms_64.c index 26a0774f5272..45afa5c51f67 100644 --- a/trunk/arch/sh/kernel/sh_ksyms_64.c +++ b/trunk/arch/sh/kernel/sh_ksyms_64.c @@ -32,6 +32,8 @@ EXPORT_SYMBOL(__get_user_asm_b); EXPORT_SYMBOL(__get_user_asm_w); EXPORT_SYMBOL(__get_user_asm_l); EXPORT_SYMBOL(__get_user_asm_q); +EXPORT_SYMBOL(__strnlen_user); +EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__copy_user); diff --git a/trunk/arch/sparc/include/asm/cmt.h b/trunk/arch/sparc/include/asm/cmt.h new file mode 100644 index 000000000000..870db5928577 --- /dev/null +++ b/trunk/arch/sparc/include/asm/cmt.h @@ -0,0 +1,59 @@ +#ifndef _SPARC64_CMT_H +#define _SPARC64_CMT_H + +/* cmt.h: Chip Multi-Threading register definitions + * + * Copyright (C) 2004 David S. Miller (davem@redhat.com) + */ + +/* ASI_CORE_ID - private */ +#define LP_ID 0x0000000000000010UL +#define LP_ID_MAX 0x00000000003f0000UL +#define LP_ID_ID 0x000000000000003fUL + +/* ASI_INTR_ID - private */ +#define LP_INTR_ID 0x0000000000000000UL +#define LP_INTR_ID_ID 0x00000000000003ffUL + +/* ASI_CESR_ID - private */ +#define CESR_ID 0x0000000000000040UL +#define CESR_ID_ID 0x00000000000000ffUL + +/* ASI_CORE_AVAILABLE - shared */ +#define LP_AVAIL 0x0000000000000000UL +#define LP_AVAIL_1 0x0000000000000002UL +#define LP_AVAIL_0 0x0000000000000001UL + +/* ASI_CORE_ENABLE_STATUS - shared */ +#define LP_ENAB_STAT 0x0000000000000010UL +#define LP_ENAB_STAT_1 0x0000000000000002UL +#define LP_ENAB_STAT_0 0x0000000000000001UL + +/* ASI_CORE_ENABLE - shared */ +#define LP_ENAB 0x0000000000000020UL +#define LP_ENAB_1 0x0000000000000002UL +#define LP_ENAB_0 0x0000000000000001UL + +/* ASI_CORE_RUNNING - shared */ +#define LP_RUNNING_RW 0x0000000000000050UL +#define LP_RUNNING_W1S 0x0000000000000060UL +#define LP_RUNNING_W1C 0x0000000000000068UL +#define LP_RUNNING_1 0x0000000000000002UL +#define LP_RUNNING_0 0x0000000000000001UL + +/* ASI_CORE_RUNNING_STAT - shared */ +#define LP_RUN_STAT 0x0000000000000058UL +#define LP_RUN_STAT_1 0x0000000000000002UL +#define LP_RUN_STAT_0 0x0000000000000001UL + +/* ASI_XIR_STEERING - shared */ +#define LP_XIR_STEER 0x0000000000000030UL +#define LP_XIR_STEER_1 0x0000000000000002UL +#define LP_XIR_STEER_0 0x0000000000000001UL + +/* ASI_CMT_ERROR_STEERING - shared */ +#define CMT_ER_STEER 0x0000000000000040UL +#define CMT_ER_STEER_1 0x0000000000000002UL +#define CMT_ER_STEER_0 0x0000000000000001UL + +#endif /* _SPARC64_CMT_H */ diff --git a/trunk/arch/sparc/include/asm/mpmbox.h b/trunk/arch/sparc/include/asm/mpmbox.h new file mode 100644 index 000000000000..f8423039b242 --- /dev/null +++ b/trunk/arch/sparc/include/asm/mpmbox.h @@ -0,0 +1,67 @@ +/* + * mpmbox.h: Interface and defines for the OpenProm mailbox + * facilities for MP machines under Linux. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_MPMBOX_H +#define _SPARC_MPMBOX_H + +/* The prom allocates, for each CPU on the machine an unsigned + * byte in physical ram. You probe the device tree prom nodes + * for these values. The purpose of this byte is to be able to + * pass messages from one cpu to another. + */ + +/* These are the main message types we have to look for in our + * Cpu mailboxes, based upon these values we decide what course + * of action to take. + */ + +/* The CPU is executing code in the kernel. */ +#define MAILBOX_ISRUNNING 0xf0 + +/* Another CPU called romvec->pv_exit(), you should call + * prom_stopcpu() when you see this in your mailbox. + */ +#define MAILBOX_EXIT 0xfb + +/* Another CPU called romvec->pv_enter(), you should call + * prom_cpuidle() when this is seen. + */ +#define MAILBOX_GOSPIN 0xfc + +/* Another CPU has hit a breakpoint either into kadb or the prom + * itself. Just like MAILBOX_GOSPIN, you should call prom_cpuidle() + * at this point. + */ +#define MAILBOX_BPT_SPIN 0xfd + +/* Oh geese, some other nitwit got a damn watchdog reset. The party's + * over so go call prom_stopcpu(). + */ +#define MAILBOX_WDOG_STOP 0xfe + +#ifndef __ASSEMBLY__ + +/* Handy macro's to determine a cpu's state. */ + +/* Is the cpu still in Power On Self Test? */ +#define MBOX_POST_P(letter) ((letter) >= 0x00 && (letter) <= 0x7f) + +/* Is the cpu at the 'ok' prompt of the PROM? */ +#define MBOX_PROMPROMPT_P(letter) ((letter) >= 0x80 && (letter) <= 0x8f) + +/* Is the cpu spinning in the PROM? */ +#define MBOX_PROMSPIN_P(letter) ((letter) >= 0x90 && (letter) <= 0xef) + +/* Sanity check... This is junk mail, throw it out. */ +#define MBOX_BOGON_P(letter) ((letter) >= 0xf1 && (letter) <= 0xfa) + +/* Is the cpu actively running an application/kernel-code? */ +#define MBOX_RUNNING_P(letter) ((letter) == MAILBOX_ISRUNNING) + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC_MPMBOX_H) */ diff --git a/trunk/arch/sparc/kernel/smp_64.c b/trunk/arch/sparc/kernel/smp_64.c index 781bcb10b8bd..f591598d92f6 100644 --- a/trunk/arch/sparc/kernel/smp_64.c +++ b/trunk/arch/sparc/kernel/smp_64.c @@ -103,6 +103,8 @@ void __cpuinit smp_callin(void) if (cheetah_pcache_forced_on) cheetah_enable_pcache(); + local_irq_enable(); + callin_flag = 1; __asm__ __volatile__("membar #Sync\n\t" "flush %%g6" : : : "memory"); @@ -122,8 +124,9 @@ void __cpuinit smp_callin(void) while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) rmb(); + ipi_call_lock_irq(); set_cpu_online(cpuid, true); - local_irq_enable(); + ipi_call_unlock_irq(); /* idle thread is expected to have preempt disabled */ preempt_disable(); @@ -1305,7 +1308,9 @@ int __cpu_disable(void) mdelay(1); local_irq_disable(); + ipi_call_lock(); set_cpu_online(cpu, false); + ipi_call_unlock(); cpu_map_rebuild(); diff --git a/trunk/arch/sparc/kernel/vio.c b/trunk/arch/sparc/kernel/vio.c index 3e244f31e56b..5cffdc55f075 100644 --- a/trunk/arch/sparc/kernel/vio.c +++ b/trunk/arch/sparc/kernel/vio.c @@ -443,7 +443,7 @@ static int __init vio_init(void) root_vdev = vio_create_one(hp, root, NULL); err = -ENODEV; if (!root_vdev) { - printk(KERN_ERR "VIO: Could not create root device.\n"); + printk(KERN_ERR "VIO: Coult not create root device.\n"); goto out_release; } diff --git a/trunk/arch/tile/include/asm/thread_info.h b/trunk/arch/tile/include/asm/thread_info.h index e9c670d7a7fe..7e1fef36bde6 100644 --- a/trunk/arch/tile/include/asm/thread_info.h +++ b/trunk/arch/tile/include/asm/thread_info.h @@ -91,6 +91,11 @@ extern void smp_nap(void); /* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */ extern void _cpu_idle(void); +/* Switch boot idle thread to a freshly-allocated stack and free old stack. */ +extern void cpu_idle_on_new_stack(struct thread_info *old_ti, + unsigned long new_sp, + unsigned long new_ss10); + #else /* __ASSEMBLY__ */ /* diff --git a/trunk/arch/tile/include/asm/uaccess.h b/trunk/arch/tile/include/asm/uaccess.h index 9ab078a4605d..c3dd275f25e2 100644 --- a/trunk/arch/tile/include/asm/uaccess.h +++ b/trunk/arch/tile/include/asm/uaccess.h @@ -146,7 +146,7 @@ extern int fixup_exception(struct pt_regs *regs); #ifdef __tilegx__ #define __get_user_1(x, ptr, ret) __get_user_asm(ld1u, x, ptr, ret) #define __get_user_2(x, ptr, ret) __get_user_asm(ld2u, x, ptr, ret) -#define __get_user_4(x, ptr, ret) __get_user_asm(ld4s, x, ptr, ret) +#define __get_user_4(x, ptr, ret) __get_user_asm(ld4u, x, ptr, ret) #define __get_user_8(x, ptr, ret) __get_user_asm(ld, x, ptr, ret) #else #define __get_user_1(x, ptr, ret) __get_user_asm(lb_u, x, ptr, ret) diff --git a/trunk/arch/tile/kernel/backtrace.c b/trunk/arch/tile/kernel/backtrace.c index f8b74ca83b92..9092ce8aa6b4 100644 --- a/trunk/arch/tile/kernel/backtrace.c +++ b/trunk/arch/tile/kernel/backtrace.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -337,12 +336,8 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location, bytes_to_prefetch / sizeof(tile_bundle_bits); } - /* - * Decode the next bundle. - * TILE always stores instruction bundles in little-endian - * mode, even when the chip is running in big-endian mode. - */ - bundle.bits = le64_to_cpu(prefetched_bundles[next_bundle++]); + /* Decode the next bundle. */ + bundle.bits = prefetched_bundles[next_bundle++]; bundle.num_insns = parse_insn_tile(bundle.bits, pc, bundle.insns); num_info_ops = bt_get_info_ops(&bundle, info_operands); diff --git a/trunk/arch/tile/kernel/entry.S b/trunk/arch/tile/kernel/entry.S index c31637baff28..133c4b56a99e 100644 --- a/trunk/arch/tile/kernel/entry.S +++ b/trunk/arch/tile/kernel/entry.S @@ -68,6 +68,20 @@ STD_ENTRY(KBacktraceIterator_init_current) jrp lr /* keep backtracer happy */ STD_ENDPROC(KBacktraceIterator_init_current) +/* + * Reset our stack to r1/r2 (sp and ksp0+cpu respectively), then + * free the old stack (passed in r0) and re-invoke cpu_idle(). + * We update sp and ksp0 simultaneously to avoid backtracer warnings. + */ +STD_ENTRY(cpu_idle_on_new_stack) + { + move sp, r1 + mtspr SPR_SYSTEM_SAVE_K_0, r2 + } + jal free_thread_info + j cpu_idle + STD_ENDPROC(cpu_idle_on_new_stack) + /* Loop forever on a nap during SMP boot. */ STD_ENTRY(smp_nap) nap diff --git a/trunk/arch/tile/kernel/setup.c b/trunk/arch/tile/kernel/setup.c index dd87f3420390..6098ccc59be2 100644 --- a/trunk/arch/tile/kernel/setup.c +++ b/trunk/arch/tile/kernel/setup.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/tile/kernel/smpboot.c b/trunk/arch/tile/kernel/smpboot.c index e686c5ac90be..84873fbe8f27 100644 --- a/trunk/arch/tile/kernel/smpboot.c +++ b/trunk/arch/tile/kernel/smpboot.c @@ -198,7 +198,17 @@ void __cpuinit online_secondary(void) notify_cpu_starting(smp_processor_id()); + /* + * We need to hold call_lock, so there is no inconsistency + * between the time smp_call_function() determines number of + * IPI recipients, and the time when the determination is made + * for which cpus receive the IPI. Holding this + * lock helps us to not include this cpu in a currently in progress + * smp_call_function(). + */ + ipi_call_lock(); set_cpu_online(smp_processor_id(), 1); + ipi_call_unlock(); __get_cpu_var(cpu_state) = CPU_ONLINE; /* Set up tile-specific state for this cpu. */ diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 43b39d61b538..88e466b159dc 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -705,6 +705,7 @@ static void stack_proc(void *arg) struct task_struct *from = current, *to = arg; to->thread.saved_task = from; + rcu_switch_from(from); switch_to(from, to, from); } diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index b0c5276861ec..1f2521434554 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -49,9 +49,6 @@ else KBUILD_AFLAGS += -m64 KBUILD_CFLAGS += -m64 - # Use -mpreferred-stack-boundary=3 if supported. - KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3) - # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) diff --git a/trunk/arch/x86/boot/header.S b/trunk/arch/x86/boot/header.S index efe5acfc79c3..8bbea6aa40d9 100644 --- a/trunk/arch/x86/boot/header.S +++ b/trunk/arch/x86/boot/header.S @@ -94,10 +94,10 @@ bs_die: .section ".bsdata", "a" bugger_off_msg: - .ascii "Direct floppy boot is not supported. " - .ascii "Use a boot loader program instead.\r\n" + .ascii "Direct booting from floppy is no longer supported.\r\n" + .ascii "Please use a boot loader program instead.\r\n" .ascii "\n" - .ascii "Remove disk and press any key to reboot ...\r\n" + .ascii "Remove disk and press any key to reboot . . .\r\n" .byte 0 #ifdef CONFIG_EFI_STUB @@ -111,7 +111,7 @@ coff_header: #else .word 0x8664 # x86-64 #endif - .word 3 # nr_sections + .word 2 # nr_sections .long 0 # TimeDateStamp .long 0 # PointerToSymbolTable .long 1 # NumberOfSymbols @@ -158,8 +158,8 @@ extra_header_fields: #else .quad 0 # ImageBase #endif - .long 0x20 # SectionAlignment - .long 0x20 # FileAlignment + .long 0x1000 # SectionAlignment + .long 0x200 # FileAlignment .word 0 # MajorOperatingSystemVersion .word 0 # MinorOperatingSystemVersion .word 0 # MajorImageVersion @@ -200,10 +200,8 @@ extra_header_fields: # Section table section_table: - # - # The offset & size fields are filled in by build.c. - # - .ascii ".setup" + .ascii ".text" + .byte 0 .byte 0 .byte 0 .long 0 @@ -219,8 +217,9 @@ section_table: # # The EFI application loader requires a relocation section - # because EFI applications must be relocatable. The .reloc - # offset & size fields are filled in by build.c. + # because EFI applications must be relocatable. But since + # we don't need the loader to fixup any relocs for us, we + # just create an empty (zero-length) .reloc section header. # .ascii ".reloc" .byte 0 @@ -234,25 +233,6 @@ section_table: .word 0 # NumberOfRelocations .word 0 # NumberOfLineNumbers .long 0x42100040 # Characteristics (section flags) - - # - # The offset & size fields are filled in by build.c. - # - .ascii ".text" - .byte 0 - .byte 0 - .byte 0 - .long 0 - .long 0x0 # startup_{32,64} - .long 0 # Size of initialized data - # on disk - .long 0x0 # startup_{32,64} - .long 0 # PointerToRelocations - .long 0 # PointerToLineNumbers - .word 0 # NumberOfRelocations - .word 0 # NumberOfLineNumbers - .long 0x60500020 # Characteristics (section flags) - #endif /* CONFIG_EFI_STUB */ # Kernel attributes; used by setup. This is part 1 of the diff --git a/trunk/arch/x86/boot/tools/build.c b/trunk/arch/x86/boot/tools/build.c index 4b8e165ee572..3f61f6e2b46f 100644 --- a/trunk/arch/x86/boot/tools/build.c +++ b/trunk/arch/x86/boot/tools/build.c @@ -50,8 +50,6 @@ typedef unsigned int u32; u8 buf[SETUP_SECT_MAX*512]; int is_big_kernel; -#define PECOFF_RELOC_RESERVE 0x20 - /*----------------------------------------------------------------------*/ static const u32 crctab32[] = { @@ -135,103 +133,11 @@ static void usage(void) die("Usage: build setup system [> image]"); } -#ifdef CONFIG_EFI_STUB - -static void update_pecoff_section_header(char *section_name, u32 offset, u32 size) -{ - unsigned int pe_header; - unsigned short num_sections; - u8 *section; - - pe_header = get_unaligned_le32(&buf[0x3c]); - num_sections = get_unaligned_le16(&buf[pe_header + 6]); - -#ifdef CONFIG_X86_32 - section = &buf[pe_header + 0xa8]; -#else - section = &buf[pe_header + 0xb8]; -#endif - - while (num_sections > 0) { - if (strncmp((char*)section, section_name, 8) == 0) { - /* section header size field */ - put_unaligned_le32(size, section + 0x8); - - /* section header vma field */ - put_unaligned_le32(offset, section + 0xc); - - /* section header 'size of initialised data' field */ - put_unaligned_le32(size, section + 0x10); - - /* section header 'file offset' field */ - put_unaligned_le32(offset, section + 0x14); - - break; - } - section += 0x28; - num_sections--; - } -} - -static void update_pecoff_setup_and_reloc(unsigned int size) -{ - u32 setup_offset = 0x200; - u32 reloc_offset = size - PECOFF_RELOC_RESERVE; - u32 setup_size = reloc_offset - setup_offset; - - update_pecoff_section_header(".setup", setup_offset, setup_size); - update_pecoff_section_header(".reloc", reloc_offset, PECOFF_RELOC_RESERVE); - - /* - * Modify .reloc section contents with a single entry. The - * relocation is applied to offset 10 of the relocation section. - */ - put_unaligned_le32(reloc_offset + 10, &buf[reloc_offset]); - put_unaligned_le32(10, &buf[reloc_offset + 4]); -} - -static void update_pecoff_text(unsigned int text_start, unsigned int file_sz) -{ - unsigned int pe_header; - unsigned int text_sz = file_sz - text_start; - - pe_header = get_unaligned_le32(&buf[0x3c]); - - /* Size of image */ - put_unaligned_le32(file_sz, &buf[pe_header + 0x50]); - - /* - * Size of code: Subtract the size of the first sector (512 bytes) - * which includes the header. - */ - put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]); - -#ifdef CONFIG_X86_32 - /* - * Address of entry point. - * - * The EFI stub entry point is +16 bytes from the start of - * the .text section. - */ - put_unaligned_le32(text_start + 16, &buf[pe_header + 0x28]); -#else - /* - * Address of entry point. startup_32 is at the beginning and - * the 64-bit entry point (startup_64) is always 512 bytes - * after. The EFI stub entry point is 16 bytes after that, as - * the first instruction allows legacy loaders to jump over - * the EFI stub initialisation - */ - put_unaligned_le32(text_start + 528, &buf[pe_header + 0x28]); -#endif /* CONFIG_X86_32 */ - - update_pecoff_section_header(".text", text_start, text_sz); -} - -#endif /* CONFIG_EFI_STUB */ - int main(int argc, char ** argv) { +#ifdef CONFIG_EFI_STUB + unsigned int file_sz, pe_header; +#endif unsigned int i, sz, setup_sectors; int c; u32 sys_size; @@ -257,12 +163,6 @@ int main(int argc, char ** argv) die("Boot block hasn't got boot flag (0xAA55)"); fclose(file); -#ifdef CONFIG_EFI_STUB - /* Reserve 0x20 bytes for .reloc section */ - memset(buf+c, 0, PECOFF_RELOC_RESERVE); - c += PECOFF_RELOC_RESERVE; -#endif - /* Pad unused space with zeros */ setup_sectors = (c + 511) / 512; if (setup_sectors < SETUP_SECT_MIN) @@ -270,10 +170,6 @@ int main(int argc, char ** argv) i = setup_sectors*512; memset(buf+c, 0, i-c); -#ifdef CONFIG_EFI_STUB - update_pecoff_setup_and_reloc(i); -#endif - /* Set the default root device */ put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); @@ -298,8 +194,66 @@ int main(int argc, char ** argv) put_unaligned_le32(sys_size, &buf[0x1f4]); #ifdef CONFIG_EFI_STUB - update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz)); -#endif + file_sz = sz + i + ((sys_size * 16) - sz); + + pe_header = get_unaligned_le32(&buf[0x3c]); + + /* Size of image */ + put_unaligned_le32(file_sz, &buf[pe_header + 0x50]); + + /* + * Subtract the size of the first section (512 bytes) which + * includes the header and .reloc section. The remaining size + * is that of the .text section. + */ + file_sz -= 512; + + /* Size of code */ + put_unaligned_le32(file_sz, &buf[pe_header + 0x1c]); + +#ifdef CONFIG_X86_32 + /* + * Address of entry point. + * + * The EFI stub entry point is +16 bytes from the start of + * the .text section. + */ + put_unaligned_le32(i + 16, &buf[pe_header + 0x28]); + + /* .text size */ + put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]); + + /* .text vma */ + put_unaligned_le32(0x200, &buf[pe_header + 0xb4]); + + /* .text size of initialised data */ + put_unaligned_le32(file_sz, &buf[pe_header + 0xb8]); + + /* .text file offset */ + put_unaligned_le32(0x200, &buf[pe_header + 0xbc]); +#else + /* + * Address of entry point. startup_32 is at the beginning and + * the 64-bit entry point (startup_64) is always 512 bytes + * after. The EFI stub entry point is 16 bytes after that, as + * the first instruction allows legacy loaders to jump over + * the EFI stub initialisation + */ + put_unaligned_le32(i + 528, &buf[pe_header + 0x28]); + + /* .text size */ + put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]); + + /* .text vma */ + put_unaligned_le32(0x200, &buf[pe_header + 0xc4]); + + /* .text size of initialised data */ + put_unaligned_le32(file_sz, &buf[pe_header + 0xc8]); + + /* .text file offset */ + put_unaligned_le32(0x200, &buf[pe_header + 0xcc]); +#endif /* CONFIG_X86_32 */ +#endif /* CONFIG_EFI_STUB */ crc = partial_crc32(buf, i, crc); if (fwrite(buf, 1, i, stdout) != i) diff --git a/trunk/arch/x86/crypto/aesni-intel_asm.S b/trunk/arch/x86/crypto/aesni-intel_asm.S index 3470624d7835..be6d9e365a80 100644 --- a/trunk/arch/x86/crypto/aesni-intel_asm.S +++ b/trunk/arch/x86/crypto/aesni-intel_asm.S @@ -2460,12 +2460,10 @@ ENTRY(aesni_cbc_dec) pxor IN3, STATE4 movaps IN4, IV #else + pxor (INP), STATE2 + pxor 0x10(INP), STATE3 pxor IN1, STATE4 movaps IN2, IV - movups (INP), IN1 - pxor IN1, STATE2 - movups 0x10(INP), IN2 - pxor IN2, STATE3 #endif movups STATE1, (OUTP) movups STATE2, 0x10(OUTP) diff --git a/trunk/arch/x86/ia32/ia32_signal.c b/trunk/arch/x86/ia32/ia32_signal.c index 673ac9b63d6b..daeca56211e3 100644 --- a/trunk/arch/x86/ia32/ia32_signal.c +++ b/trunk/arch/x86/ia32/ia32_signal.c @@ -38,7 +38,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) { int err = 0; - bool ia32 = test_thread_flag(TIF_IA32); + bool ia32 = is_ia32_task(); if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) return -EFAULT; diff --git a/trunk/arch/x86/include/asm/alternative.h b/trunk/arch/x86/include/asm/alternative.h index 70780689599a..49331bedc158 100644 --- a/trunk/arch/x86/include/asm/alternative.h +++ b/trunk/arch/x86/include/asm/alternative.h @@ -75,54 +75,23 @@ static inline int alternatives_text_reserved(void *start, void *end) } #endif /* CONFIG_SMP */ -#define OLDINSTR(oldinstr) "661:\n\t" oldinstr "\n662:\n" - -#define b_replacement(number) "663"#number -#define e_replacement(number) "664"#number - -#define alt_slen "662b-661b" -#define alt_rlen(number) e_replacement(number)"f-"b_replacement(number)"f" - -#define ALTINSTR_ENTRY(feature, number) \ - " .long 661b - .\n" /* label */ \ - " .long " b_replacement(number)"f - .\n" /* new instruction */ \ - " .word " __stringify(feature) "\n" /* feature bit */ \ - " .byte " alt_slen "\n" /* source len */ \ - " .byte " alt_rlen(number) "\n" /* replacement len */ - -#define DISCARD_ENTRY(number) /* rlen <= slen */ \ - " .byte 0xff + (" alt_rlen(number) ") - (" alt_slen ")\n" - -#define ALTINSTR_REPLACEMENT(newinstr, feature, number) /* replacement */ \ - b_replacement(number)":\n\t" newinstr "\n" e_replacement(number) ":\n\t" - /* alternative assembly primitive: */ #define ALTERNATIVE(oldinstr, newinstr, feature) \ - OLDINSTR(oldinstr) \ - ".section .altinstructions,\"a\"\n" \ - ALTINSTR_ENTRY(feature, 1) \ - ".previous\n" \ - ".section .discard,\"aw\",@progbits\n" \ - DISCARD_ENTRY(1) \ - ".previous\n" \ - ".section .altinstr_replacement, \"ax\"\n" \ - ALTINSTR_REPLACEMENT(newinstr, feature, 1) \ - ".previous" - -#define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\ - OLDINSTR(oldinstr) \ - ".section .altinstructions,\"a\"\n" \ - ALTINSTR_ENTRY(feature1, 1) \ - ALTINSTR_ENTRY(feature2, 2) \ - ".previous\n" \ - ".section .discard,\"aw\",@progbits\n" \ - DISCARD_ENTRY(1) \ - DISCARD_ENTRY(2) \ - ".previous\n" \ - ".section .altinstr_replacement, \"ax\"\n" \ - ALTINSTR_REPLACEMENT(newinstr1, feature1, 1) \ - ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \ - ".previous" + \ + "661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + " .long 661b - .\n" /* label */ \ + " .long 663f - .\n" /* new instruction */ \ + " .word " __stringify(feature) "\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .discard,\"aw\",@progbits\n" \ + " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \ + ".previous\n" \ + ".section .altinstr_replacement, \"ax\"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" /* * This must be included *after* the definition of ALTERNATIVE due to @@ -170,19 +139,6 @@ static inline int alternatives_text_reserved(void *start, void *end) asm volatile (ALTERNATIVE("call %P[old]", "call %P[new]", feature) \ : output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input) -/* - * Like alternative_call, but there are two features and respective functions. - * If CPU has feature2, function2 is used. - * Otherwise, if CPU has feature1, function1 is used. - * Otherwise, old function is used. - */ -#define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ - output, input...) \ - asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ - "call %P[new2]", feature2) \ - : output : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ - [new2] "i" (newfunc2), ## input) - /* * use this macro(s) if you need more than one output parameter * in alternative_io diff --git a/trunk/arch/x86/include/asm/apic.h b/trunk/arch/x86/include/asm/apic.h index 88093c1d44fd..eaff4790ed96 100644 --- a/trunk/arch/x86/include/asm/apic.h +++ b/trunk/arch/x86/include/asm/apic.h @@ -306,8 +306,7 @@ struct apic { unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); unsigned long (*check_apicid_present)(int apicid); - void (*vector_allocation_domain)(int cpu, struct cpumask *retmask, - const struct cpumask *mask); + void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); void (*init_apic_ldr)(void); void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); @@ -332,9 +331,9 @@ struct apic { unsigned long (*set_apic_id)(unsigned int id); unsigned long apic_id_mask; - int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid); + unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); + unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, + const struct cpumask *andmask); /* ipi */ void (*send_IPI_mask)(const struct cpumask *mask, int vector); @@ -538,11 +537,6 @@ static inline const struct cpumask *default_target_cpus(void) #endif } -static inline const struct cpumask *online_target_cpus(void) -{ - return cpu_online_mask; -} - DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); @@ -592,50 +586,21 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) #endif -static inline int -flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid) +static inline unsigned int +default_cpu_mask_to_apicid(const struct cpumask *cpumask) { - unsigned long cpu_mask = cpumask_bits(cpumask)[0] & - cpumask_bits(andmask)[0] & - cpumask_bits(cpu_online_mask)[0] & - APIC_ALL_CPUS; - - if (likely(cpu_mask)) { - *apicid = (unsigned int)cpu_mask; - return 0; - } else { - return -EINVAL; - } + return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; } -extern int +static inline unsigned int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid); - -static inline void -flat_vector_allocation_domain(int cpu, struct cpumask *retmask, - const struct cpumask *mask) + const struct cpumask *andmask) { - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} + unsigned long mask1 = cpumask_bits(cpumask)[0]; + unsigned long mask2 = cpumask_bits(andmask)[0]; + unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; -static inline void -default_vector_allocation_domain(int cpu, struct cpumask *retmask, - const struct cpumask *mask) -{ - cpumask_copy(retmask, cpumask_of(cpu)); + return (unsigned int)(mask1 & mask2 & mask3); } static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h index f91e80f4f180..340ee49961a6 100644 --- a/trunk/arch/x86/include/asm/cpufeature.h +++ b/trunk/arch/x86/include/asm/cpufeature.h @@ -176,7 +176,7 @@ #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ -#define X86_FEATURE_DTHERM (7*32+ 7) /* Digital Thermal Sensor */ +#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ #define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */ /* Virtualization flags: Linux defined, word 8 */ diff --git a/trunk/arch/x86/include/asm/emergency-restart.h b/trunk/arch/x86/include/asm/emergency-restart.h index 75ce3f47d204..cc70c1c78ca4 100644 --- a/trunk/arch/x86/include/asm/emergency-restart.h +++ b/trunk/arch/x86/include/asm/emergency-restart.h @@ -4,7 +4,9 @@ enum reboot_type { BOOT_TRIPLE = 't', BOOT_KBD = 'k', +#ifdef CONFIG_X86_32 BOOT_BIOS = 'b', +#endif BOOT_ACPI = 'a', BOOT_EFI = 'e', BOOT_CF9 = 'p', diff --git a/trunk/arch/x86/include/asm/floppy.h b/trunk/arch/x86/include/asm/floppy.h index d3d74698dce9..dbe82a5c5eac 100644 --- a/trunk/arch/x86/include/asm/floppy.h +++ b/trunk/arch/x86/include/asm/floppy.h @@ -99,7 +99,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) virtual_dma_residue += virtual_dma_count; virtual_dma_count = 0; #ifdef TRACE_FLPY_INT - printk(KERN_DEBUG "count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", + printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", virtual_dma_count, virtual_dma_residue, calls, bytes, dma_wait); calls = 0; diff --git a/trunk/arch/x86/include/asm/kvm_host.h b/trunk/arch/x86/include/asm/kvm_host.h index 2da88c0cda14..db7c1f2709a2 100644 --- a/trunk/arch/x86/include/asm/kvm_host.h +++ b/trunk/arch/x86/include/asm/kvm_host.h @@ -313,8 +313,8 @@ struct kvm_pmu { u64 counter_bitmask[2]; u64 global_ctrl_mask; u8 version; - struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC]; - struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED]; + struct kvm_pmc gp_counters[X86_PMC_MAX_GENERIC]; + struct kvm_pmc fixed_counters[X86_PMC_MAX_FIXED]; struct irq_work irq_work; u64 reprogram_pmi; }; diff --git a/trunk/arch/x86/include/asm/msr.h b/trunk/arch/x86/include/asm/msr.h index 813ed103f45e..084ef95274cd 100644 --- a/trunk/arch/x86/include/asm/msr.h +++ b/trunk/arch/x86/include/asm/msr.h @@ -115,8 +115,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr, extern unsigned long long native_read_tsc(void); -extern int rdmsr_safe_regs(u32 regs[8]); -extern int wrmsr_safe_regs(u32 regs[8]); +extern int native_rdmsr_safe_regs(u32 regs[8]); +extern int native_wrmsr_safe_regs(u32 regs[8]); static __always_inline unsigned long long __native_read_tsc(void) { @@ -187,6 +187,43 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) return err; } +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = native_rdmsr_safe_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return native_wrmsr_safe_regs(gprs); +} + +static inline int rdmsr_safe_regs(u32 regs[8]) +{ + return native_rdmsr_safe_regs(regs); +} + +static inline int wrmsr_safe_regs(u32 regs[8]) +{ + return native_wrmsr_safe_regs(regs); +} + #define rdtscl(low) \ ((low) = (u32)__native_read_tsc()) @@ -200,8 +237,6 @@ do { \ (high) = (u32)(_l >> 32); \ } while (0) -#define rdpmcl(counter, val) ((val) = native_read_pmc(counter)) - #define rdtscp(low, high, aux) \ do { \ unsigned long long _val = native_read_tscp(&(aux)); \ @@ -213,7 +248,8 @@ do { \ #endif /* !CONFIG_PARAVIRT */ -#define wrmsrl_safe(msr, val) wrmsr_safe((msr), (u32)(val), \ + +#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ (u32)((val) >> 32)) #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) diff --git a/trunk/arch/x86/include/asm/nmi.h b/trunk/arch/x86/include/asm/nmi.h index c0fa356e90de..0e3793b821ef 100644 --- a/trunk/arch/x86/include/asm/nmi.h +++ b/trunk/arch/x86/include/asm/nmi.h @@ -44,14 +44,14 @@ struct nmiaction { const char *name; }; -#define register_nmi_handler(t, fn, fg, n, init...) \ +#define register_nmi_handler(t, fn, fg, n) \ ({ \ - static struct nmiaction init fn##_na = { \ + static struct nmiaction fn##_na = { \ .handler = (fn), \ .name = (n), \ .flags = (fg), \ }; \ - __register_nmi_handler((t), &fn##_na); \ + __register_nmi_handler((t), &fn##_na); \ }) int __register_nmi_handler(unsigned int, struct nmiaction *); diff --git a/trunk/arch/x86/include/asm/paravirt.h b/trunk/arch/x86/include/asm/paravirt.h index 0b47ddb6f00b..6cbbabf52707 100644 --- a/trunk/arch/x86/include/asm/paravirt.h +++ b/trunk/arch/x86/include/asm/paravirt.h @@ -128,11 +128,21 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err) return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); } +static inline int paravirt_rdmsr_regs(u32 *regs) +{ + return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs); +} + static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) { return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); } +static inline int paravirt_wrmsr_regs(u32 *regs) +{ + return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs); +} + /* These should all do BUG_ON(_err), but our headers are too tangled. */ #define rdmsr(msr, val1, val2) \ do { \ @@ -166,6 +176,9 @@ do { \ _err; \ }) +#define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs) +#define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs) + static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) { int err; @@ -173,6 +186,32 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) *p = paravirt_read_msr(msr, &err); return err; } +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = paravirt_rdmsr_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return paravirt_wrmsr_regs(gprs); +} static inline u64 paravirt_read_tsc(void) { @@ -213,8 +252,6 @@ do { \ high = _l >> 32; \ } while (0) -#define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter)) - static inline unsigned long long paravirt_rdtscp(unsigned int *aux) { return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); diff --git a/trunk/arch/x86/include/asm/paravirt_types.h b/trunk/arch/x86/include/asm/paravirt_types.h index 8613cbb7ba41..8e8b9a4987ee 100644 --- a/trunk/arch/x86/include/asm/paravirt_types.h +++ b/trunk/arch/x86/include/asm/paravirt_types.h @@ -153,7 +153,9 @@ struct pv_cpu_ops { /* MSR, PMC and TSR operations. err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ u64 (*read_msr)(unsigned int msr, int *err); + int (*rdmsr_regs)(u32 *regs); int (*write_msr)(unsigned int msr, unsigned low, unsigned high); + int (*wrmsr_regs)(u32 *regs); u64 (*read_tsc)(void); u64 (*read_pmc)(int counter); diff --git a/trunk/arch/x86/include/asm/pci_x86.h b/trunk/arch/x86/include/asm/pci_x86.h index 5ad24a89b19b..b3a531746026 100644 --- a/trunk/arch/x86/include/asm/pci_x86.h +++ b/trunk/arch/x86/include/asm/pci_x86.h @@ -7,13 +7,9 @@ #undef DEBUG #ifdef DEBUG -#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__) +#define DBG(x...) printk(x) #else -#define DBG(fmt, ...) \ -do { \ - if (0) \ - printk(fmt, ##__VA_ARGS__); \ -} while (0) +#define DBG(x...) #endif #define PCI_PROBE_BIOS 0x0001 diff --git a/trunk/arch/x86/include/asm/perf_event.h b/trunk/arch/x86/include/asm/perf_event.h index c78f14a0df00..588f52ea810e 100644 --- a/trunk/arch/x86/include/asm/perf_event.h +++ b/trunk/arch/x86/include/asm/perf_event.h @@ -5,10 +5,11 @@ * Performance event hw details: */ -#define INTEL_PMC_MAX_GENERIC 32 -#define INTEL_PMC_MAX_FIXED 3 -#define INTEL_PMC_IDX_FIXED 32 +#define X86_PMC_MAX_GENERIC 32 +#define X86_PMC_MAX_FIXED 3 +#define X86_PMC_IDX_GENERIC 0 +#define X86_PMC_IDX_FIXED 32 #define X86_PMC_IDX_MAX 64 #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 @@ -47,7 +48,8 @@ (X86_RAW_EVENT_MASK | \ AMD64_EVENTSEL_EVENT) #define AMD64_NUM_COUNTERS 4 -#define AMD64_NUM_COUNTERS_CORE 6 +#define AMD64_NUM_COUNTERS_F15H 6 +#define AMD64_NUM_COUNTERS_MAX AMD64_NUM_COUNTERS_F15H #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) @@ -119,16 +121,16 @@ struct x86_pmu_capability { /* Instr_Retired.Any: */ #define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 -#define INTEL_PMC_IDX_FIXED_INSTRUCTIONS (INTEL_PMC_IDX_FIXED + 0) +#define X86_PMC_IDX_FIXED_INSTRUCTIONS (X86_PMC_IDX_FIXED + 0) /* CPU_CLK_Unhalted.Core: */ #define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a -#define INTEL_PMC_IDX_FIXED_CPU_CYCLES (INTEL_PMC_IDX_FIXED + 1) +#define X86_PMC_IDX_FIXED_CPU_CYCLES (X86_PMC_IDX_FIXED + 1) /* CPU_CLK_Unhalted.Ref: */ #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b -#define INTEL_PMC_IDX_FIXED_REF_CYCLES (INTEL_PMC_IDX_FIXED + 2) -#define INTEL_PMC_MSK_FIXED_REF_CYCLES (1ULL << INTEL_PMC_IDX_FIXED_REF_CYCLES) +#define X86_PMC_IDX_FIXED_REF_CYCLES (X86_PMC_IDX_FIXED + 2) +#define X86_PMC_MSK_FIXED_REF_CYCLES (1ULL << X86_PMC_IDX_FIXED_REF_CYCLES) /* * We model BTS tracing as another fixed-mode PMC. @@ -137,7 +139,7 @@ struct x86_pmu_capability { * values are used by actual fixed events and higher values are used * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr. */ -#define INTEL_PMC_IDX_FIXED_BTS (INTEL_PMC_IDX_FIXED + 16) +#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) /* * IBS cpuid feature detection @@ -232,7 +234,6 @@ struct perf_guest_switch_msr { extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); -extern void perf_check_microcode(void); #else static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr) { @@ -246,7 +247,6 @@ static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap) } static inline void perf_events_lapic_init(void) { } -static inline void perf_check_microcode(void) { } #endif #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) diff --git a/trunk/arch/x86/include/asm/pgtable-2level.h b/trunk/arch/x86/include/asm/pgtable-2level.h index f2b489cf1602..98391db840c6 100644 --- a/trunk/arch/x86/include/asm/pgtable-2level.h +++ b/trunk/arch/x86/include/asm/pgtable-2level.h @@ -2,9 +2,9 @@ #define _ASM_X86_PGTABLE_2LEVEL_H #define pte_ERROR(e) \ - pr_err("%s:%d: bad pte %08lx\n", __FILE__, __LINE__, (e).pte_low) + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) #define pgd_ERROR(e) \ - pr_err("%s:%d: bad pgd %08lx\n", __FILE__, __LINE__, pgd_val(e)) + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) /* * Certain architectures need to do special things when PTEs diff --git a/trunk/arch/x86/include/asm/pgtable-3level.h b/trunk/arch/x86/include/asm/pgtable-3level.h index 4cc9f2b7cdc3..43876f16caf1 100644 --- a/trunk/arch/x86/include/asm/pgtable-3level.h +++ b/trunk/arch/x86/include/asm/pgtable-3level.h @@ -9,13 +9,13 @@ */ #define pte_ERROR(e) \ - pr_err("%s:%d: bad pte %p(%08lx%08lx)\n", \ + printk("%s:%d: bad pte %p(%08lx%08lx).\n", \ __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low) #define pmd_ERROR(e) \ - pr_err("%s:%d: bad pmd %p(%016Lx)\n", \ + printk("%s:%d: bad pmd %p(%016Lx).\n", \ __FILE__, __LINE__, &(e), pmd_val(e)) #define pgd_ERROR(e) \ - pr_err("%s:%d: bad pgd %p(%016Lx)\n", \ + printk("%s:%d: bad pgd %p(%016Lx).\n", \ __FILE__, __LINE__, &(e), pgd_val(e)) /* Rules for using set_pte: the pte being assigned *must* be @@ -47,26 +47,16 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd * operations. * - * Without THP if the mmap_sem is hold for reading, the pmd can only - * transition from null to not null while pmd_read_atomic runs. So - * we can always return atomic pmd values with this function. + * Without THP if the mmap_sem is hold for reading, the + * pmd can only transition from null to not null while pmd_read_atomic runs. + * So there's no need of literally reading it atomically. * * With THP if the mmap_sem is hold for reading, the pmd can become - * trans_huge or none or point to a pte (and in turn become "stable") - * at any time under pmd_read_atomic. We could read it really - * atomically here with a atomic64_read for the THP enabled case (and - * it would be a whole lot simpler), but to avoid using cmpxchg8b we - * only return an atomic pmdval if the low part of the pmdval is later - * found stable (i.e. pointing to a pte). And we're returning a none - * pmdval if the low part of the pmd is none. In some cases the high - * and low part of the pmdval returned may not be consistent if THP is - * enabled (the low part may point to previously mapped hugepage, - * while the high part may point to a more recently mapped hugepage), - * but pmd_none_or_trans_huge_or_clear_bad() only needs the low part - * of the pmd to be read atomically to decide if the pmd is unstable - * or not, with the only exception of when the low part of the pmd is - * zero in which case we return a none pmd. + * THP or null or point to a pte (and in turn become "stable") at any + * time under pmd_read_atomic, so it's mandatory to read it atomically + * with cmpxchg8b. */ +#ifndef CONFIG_TRANSPARENT_HUGEPAGE static inline pmd_t pmd_read_atomic(pmd_t *pmdp) { pmdval_t ret; @@ -84,6 +74,12 @@ static inline pmd_t pmd_read_atomic(pmd_t *pmdp) return (pmd_t) { ret }; } +#else /* CONFIG_TRANSPARENT_HUGEPAGE */ +static inline pmd_t pmd_read_atomic(pmd_t *pmdp) +{ + return (pmd_t) { atomic64_read((atomic64_t *)pmdp) }; +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) { diff --git a/trunk/arch/x86/include/asm/pgtable_64.h b/trunk/arch/x86/include/asm/pgtable_64.h index 8251be02301e..975f709e09ae 100644 --- a/trunk/arch/x86/include/asm/pgtable_64.h +++ b/trunk/arch/x86/include/asm/pgtable_64.h @@ -26,16 +26,16 @@ extern pgd_t init_level4_pgt[]; extern void paging_init(void); #define pte_ERROR(e) \ - pr_err("%s:%d: bad pte %p(%016lx)\n", \ + printk("%s:%d: bad pte %p(%016lx).\n", \ __FILE__, __LINE__, &(e), pte_val(e)) #define pmd_ERROR(e) \ - pr_err("%s:%d: bad pmd %p(%016lx)\n", \ + printk("%s:%d: bad pmd %p(%016lx).\n", \ __FILE__, __LINE__, &(e), pmd_val(e)) #define pud_ERROR(e) \ - pr_err("%s:%d: bad pud %p(%016lx)\n", \ + printk("%s:%d: bad pud %p(%016lx).\n", \ __FILE__, __LINE__, &(e), pud_val(e)) #define pgd_ERROR(e) \ - pr_err("%s:%d: bad pgd %p(%016lx)\n", \ + printk("%s:%d: bad pgd %p(%016lx).\n", \ __FILE__, __LINE__, &(e), pgd_val(e)) struct mm_struct; diff --git a/trunk/arch/x86/include/asm/realmode.h b/trunk/arch/x86/include/asm/realmode.h index fe1ec5bcd846..fce3f4ae5bd6 100644 --- a/trunk/arch/x86/include/asm/realmode.h +++ b/trunk/arch/x86/include/asm/realmode.h @@ -21,9 +21,8 @@ struct real_mode_header { u32 wakeup_header; #endif /* APM/BIOS reboot */ +#ifdef CONFIG_X86_32 u32 machine_real_restart_asm; -#ifdef CONFIG_X86_64 - u32 machine_real_restart_seg; #endif }; diff --git a/trunk/arch/x86/include/asm/reboot.h b/trunk/arch/x86/include/asm/reboot.h index a82c4f1b4d83..92f297069e87 100644 --- a/trunk/arch/x86/include/asm/reboot.h +++ b/trunk/arch/x86/include/asm/reboot.h @@ -18,8 +18,8 @@ extern struct machine_ops machine_ops; void native_machine_crash_shutdown(struct pt_regs *regs); void native_machine_shutdown(void); -void __noreturn machine_real_restart(unsigned int type); -/* These must match dispatch in arch/x86/realmore/rm/reboot.S */ +void machine_real_restart(unsigned int type); +/* These must match dispatch_table in reboot_32.S */ #define MRR_BIOS 0 #define MRR_APM 1 diff --git a/trunk/arch/x86/include/asm/smp.h b/trunk/arch/x86/include/asm/smp.h index 2ffa95dc2333..f48394513c37 100644 --- a/trunk/arch/x86/include/asm/smp.h +++ b/trunk/arch/x86/include/asm/smp.h @@ -169,6 +169,11 @@ void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); void smp_store_cpu_info(int id); #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) +/* We don't mark CPUs online until __cpu_up(), so we need another measure */ +static inline int num_booting_cpus(void) +{ + return cpumask_weight(cpu_callout_mask); +} #else /* !CONFIG_SMP */ #define wbinvd_on_cpu(cpu) wbinvd() static inline int wbinvd_on_all_cpus(void) diff --git a/trunk/arch/x86/include/asm/uaccess.h b/trunk/arch/x86/include/asm/uaccess.h index e1f3a17034fc..04cd6882308e 100644 --- a/trunk/arch/x86/include/asm/uaccess.h +++ b/trunk/arch/x86/include/asm/uaccess.h @@ -33,8 +33,9 @@ #define segment_eq(a, b) ((a).seg == (b).seg) #define user_addr_max() (current_thread_info()->addr_limit.seg) -#define __addr_ok(addr) \ - ((unsigned long __force)(addr) < user_addr_max()) +#define __addr_ok(addr) \ + ((unsigned long __force)(addr) < \ + (current_thread_info()->addr_limit.seg)) /* * Test whether a block of memory is a valid user space address. @@ -46,14 +47,14 @@ * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry... */ -#define __range_not_ok(addr, size, limit) \ +#define __range_not_ok(addr, size) \ ({ \ unsigned long flag, roksum; \ __chk_user_ptr(addr); \ asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ : "=&r" (flag), "=r" (roksum) \ : "1" (addr), "g" ((long)(size)), \ - "rm" (limit)); \ + "rm" (current_thread_info()->addr_limit.seg)); \ flag; \ }) @@ -76,8 +77,7 @@ * checks that the pointer is in the user space range - after calling * this function, memory access functions may still return -EFAULT. */ -#define access_ok(type, addr, size) \ - (likely(__range_not_ok(addr, size, user_addr_max()) == 0)) +#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) /* * The exception table consists of pairs of addresses relative to the diff --git a/trunk/arch/x86/include/asm/uaccess_64.h b/trunk/arch/x86/include/asm/uaccess_64.h index d8def8b3dba0..8e796fbbf9c6 100644 --- a/trunk/arch/x86/include/asm/uaccess_64.h +++ b/trunk/arch/x86/include/asm/uaccess_64.h @@ -17,8 +17,6 @@ /* Handles exceptions in both to and from, but doesn't do access_ok */ __must_check unsigned long -copy_user_enhanced_fast_string(void *to, const void *from, unsigned len); -__must_check unsigned long copy_user_generic_string(void *to, const void *from, unsigned len); __must_check unsigned long copy_user_generic_unrolled(void *to, const void *from, unsigned len); @@ -28,16 +26,9 @@ copy_user_generic(void *to, const void *from, unsigned len) { unsigned ret; - /* - * If CPU has ERMS feature, use copy_user_enhanced_fast_string. - * Otherwise, if CPU has rep_good feature, use copy_user_generic_string. - * Otherwise, use copy_user_generic_unrolled. - */ - alternative_call_2(copy_user_generic_unrolled, + alternative_call(copy_user_generic_unrolled, copy_user_generic_string, X86_FEATURE_REP_GOOD, - copy_user_enhanced_fast_string, - X86_FEATURE_ERMS, ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from), "=d" (len)), "1" (to), "2" (from), "3" (len) diff --git a/trunk/arch/x86/include/asm/uprobes.h b/trunk/arch/x86/include/asm/uprobes.h index f3971bbcd1de..1e9bed14f7ae 100644 --- a/trunk/arch/x86/include/asm/uprobes.h +++ b/trunk/arch/x86/include/asm/uprobes.h @@ -48,7 +48,7 @@ struct arch_uprobe_task { #endif }; -extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); +extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm); extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); diff --git a/trunk/arch/x86/include/asm/uv/uv_bau.h b/trunk/arch/x86/include/asm/uv/uv_bau.h index a06983cdc125..becf47b81735 100644 --- a/trunk/arch/x86/include/asm/uv/uv_bau.h +++ b/trunk/arch/x86/include/asm/uv/uv_bau.h @@ -140,9 +140,6 @@ #define IPI_RESET_LIMIT 1 /* after this # consecutive successes, bump up the throttle if it was lowered */ #define COMPLETE_THRESHOLD 5 -/* after this # of giveups (fall back to kernel IPI's) disable the use of - the BAU for a period of time */ -#define GIVEUP_LIMIT 100 #define UV_LB_SUBNODEID 0x10 @@ -152,6 +149,7 @@ /* 4 bits of software ack period */ #define UV2_ACK_MASK 0x7UL #define UV2_ACK_UNITS_SHFT 3 +#define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT /* @@ -169,6 +167,7 @@ #define FLUSH_RETRY_TIMEOUT 2 #define FLUSH_GIVEUP 3 #define FLUSH_COMPLETE 4 +#define FLUSH_RETRY_BUSYBUG 5 /* * tuning the action when the numalink network is extremely delayed @@ -177,7 +176,7 @@ microseconds */ #define CONGESTED_REPS 10 /* long delays averaged over this many broadcasts */ -#define DISABLED_PERIOD 10 /* time for the bau to be +#define CONGESTED_PERIOD 30 /* time for the bau to be disabled, in seconds */ /* see msg_type: */ #define MSG_NOOP 0 @@ -522,12 +521,6 @@ struct ptc_stats { unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */ unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */ unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */ - unsigned long s_overipilimit; /* over the ipi reset limit */ - unsigned long s_giveuplimit; /* disables, over giveup limit*/ - unsigned long s_enters; /* entries to the driver */ - unsigned long s_ipifordisabled; /* fall back to IPI; disabled */ - unsigned long s_plugged; /* plugged by h/w bug*/ - unsigned long s_congested; /* giveup on long wait */ /* destination statistics */ unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ @@ -594,8 +587,8 @@ struct bau_control { int timeout_tries; int ipi_attempts; int conseccompletes; - short nobau; - short baudisabled; + int baudisabled; + int set_bau_off; short cpu; short osnode; short uvhub_cpu; @@ -604,16 +597,14 @@ struct bau_control { short cpus_in_socket; short cpus_in_uvhub; short partition_base_pnode; - short busy; /* all were busy (war) */ + short using_desc; /* an index, like uvhub_cpu */ + unsigned int inuse_map; unsigned short message_number; unsigned short uvhub_quiesce; short socket_acknowledge_count[DEST_Q_SIZE]; cycles_t send_message; - cycles_t period_end; - cycles_t period_time; spinlock_t uvhub_lock; spinlock_t queue_lock; - spinlock_t disable_lock; /* tunables */ int max_concurr; int max_concurr_const; @@ -624,9 +615,9 @@ struct bau_control { int complete_threshold; int cong_response_us; int cong_reps; - cycles_t disabled_period; - int period_giveups; - int giveup_limit; + int cong_period; + unsigned long clocks_per_100_usec; + cycles_t period_time; long period_requests; struct hub_and_pnode *thp; }; diff --git a/trunk/arch/x86/include/asm/x2apic.h b/trunk/arch/x86/include/asm/x2apic.h index f90f0a587c66..92e54abf89e0 100644 --- a/trunk/arch/x86/include/asm/x2apic.h +++ b/trunk/arch/x86/include/asm/x2apic.h @@ -9,6 +9,15 @@ #include #include +/* + * Need to use more than cpu 0, because we need more vectors + * when MSI-X are used. + */ +static const struct cpumask *x2apic_target_cpus(void) +{ + return cpu_online_mask; +} + static int x2apic_apic_id_valid(int apicid) { return 1; @@ -19,6 +28,15 @@ static int x2apic_apic_id_registered(void) return 1; } +/* + * For now each logical cpu is in its own vector allocation domain. + */ +static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) { diff --git a/trunk/arch/x86/include/asm/x86_init.h b/trunk/arch/x86/include/asm/x86_init.h index 38155f667144..c090af10ac7d 100644 --- a/trunk/arch/x86/include/asm/x86_init.h +++ b/trunk/arch/x86/include/asm/x86_init.h @@ -156,6 +156,7 @@ struct x86_cpuinit_ops { /** * struct x86_platform_ops - platform specific runtime functions * @calibrate_tsc: calibrate TSC + * @wallclock_init: init the wallclock device * @get_wallclock: get time from HW clock like RTC etc. * @set_wallclock: set time back to HW clock * @is_untracked_pat_range exclude from PAT logic @@ -163,10 +164,10 @@ struct x86_cpuinit_ops { * @i8042_detect pre-detect if i8042 controller exists * @save_sched_clock_state: save state for sched_clock() on suspend * @restore_sched_clock_state: restore state for sched_clock() on resume - * @apic_post_init: adjust apic if neeeded */ struct x86_platform_ops { unsigned long (*calibrate_tsc)(void); + void (*wallclock_init)(void); unsigned long (*get_wallclock)(void); int (*set_wallclock)(unsigned long nowtime); void (*iommu_shutdown)(void); @@ -176,7 +177,6 @@ struct x86_platform_ops { int (*i8042_detect)(void); void (*save_sched_clock_state)(void); void (*restore_sched_clock_state)(void); - void (*apic_post_init)(void); }; struct pci_dev; diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c index b2297e58c6ed..8afb69319815 100644 --- a/trunk/arch/x86/kernel/acpi/boot.c +++ b/trunk/arch/x86/kernel/acpi/boot.c @@ -422,14 +422,12 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, return 0; } - if (intsrc->source_irq == 0) { + if (intsrc->source_irq == 0 && intsrc->global_irq == 2) { if (acpi_skip_timer_override) { - printk(PREFIX "BIOS IRQ0 override ignored.\n"); + printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); return 0; } - - if ((intsrc->global_irq == 2) && acpi_fix_pin2_polarity - && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { + if (acpi_fix_pin2_polarity && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK; printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n"); } @@ -1336,12 +1334,17 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d) } /* - * Force ignoring BIOS IRQ0 override + * Force ignoring BIOS IRQ0 pin2 override */ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) { + /* + * The ati_ixp4x0_rev() early PCI quirk should have set + * the acpi_skip_timer_override flag already: + */ if (!acpi_skip_timer_override) { - pr_notice("%s detected: Ignoring BIOS IRQ0 override\n", + WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n"); + pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident); acpi_skip_timer_override = 1; } @@ -1435,7 +1438,7 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { * is enabled. This input is incorrectly designated the * ISA IRQ 0 via an interrupt source override even though * it is wired to the output of the master 8259A and INTIN0 - * is not connected at all. Force ignoring BIOS IRQ0 + * is not connected at all. Force ignoring BIOS IRQ0 pin2 * override in that cases. */ { @@ -1470,14 +1473,6 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), }, }, - { - .callback = dmi_ignore_irq0_timer_override, - .ident = "FUJITSU SIEMENS", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), - }, - }, {} }; diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c index 931280ff8299..1f84794f0759 100644 --- a/trunk/arch/x86/kernel/alternative.c +++ b/trunk/arch/x86/kernel/alternative.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) "SMP alternatives: " fmt - #include #include #include @@ -65,11 +63,8 @@ static int __init setup_noreplace_paravirt(char *str) __setup("noreplace-paravirt", setup_noreplace_paravirt); #endif -#define DPRINTK(fmt, ...) \ -do { \ - if (debug_alternative) \ - printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ -} while (0) +#define DPRINTK(fmt, args...) if (debug_alternative) \ + printk(KERN_DEBUG fmt, args) /* * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes @@ -433,7 +428,7 @@ void alternatives_smp_switch(int smp) * If this still occurs then you should see a hang * or crash shortly after this line: */ - pr_info("lockdep: fixing up alternatives\n"); + printk("lockdep: fixing up alternatives.\n"); #endif if (noreplace_smp || smp_alt_once || skip_smp_alternatives) @@ -449,14 +444,14 @@ void alternatives_smp_switch(int smp) if (smp == smp_mode) { /* nothing */ } else if (smp) { - pr_info("switching to SMP code\n"); + printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP); list_for_each_entry(mod, &smp_alt_modules, next) alternatives_smp_lock(mod->locks, mod->locks_end, mod->text, mod->text_end); } else { - pr_info("switching to UP code\n"); + printk(KERN_INFO "SMP alternatives: switching to UP code\n"); set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); list_for_each_entry(mod, &smp_alt_modules, next) @@ -551,7 +546,7 @@ void __init alternative_instructions(void) #ifdef CONFIG_SMP if (smp_alt_once) { if (1 == num_possible_cpus()) { - pr_info("switching to UP code\n"); + printk(KERN_INFO "SMP alternatives: switching to UP code\n"); set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); @@ -669,7 +664,7 @@ static int __kprobes stop_machine_text_poke(void *data) struct text_poke_param *p; int i; - if (atomic_xchg(&stop_machine_first, 0)) { + if (atomic_dec_and_test(&stop_machine_first)) { for (i = 0; i < tpp->nparams; i++) { p = &tpp->params[i]; text_poke(p->addr, p->opcode, p->len); diff --git a/trunk/arch/x86/kernel/amd_nb.c b/trunk/arch/x86/kernel/amd_nb.c index f29f6dd6bc08..153a0ee88fb1 100644 --- a/trunk/arch/x86/kernel/amd_nb.c +++ b/trunk/arch/x86/kernel/amd_nb.c @@ -2,9 +2,6 @@ * Shared support code for AMD K8 northbridges and derivates. * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -19,6 +16,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, {} }; EXPORT_SYMBOL(amd_nb_misc_ids); @@ -261,7 +259,7 @@ void amd_flush_garts(void) } spin_unlock_irqrestore(&gart_lock, flags); if (!flushed) - pr_notice("nothing to flush?\n"); + printk("nothing to flush?\n"); } EXPORT_SYMBOL_GPL(amd_flush_garts); @@ -272,10 +270,11 @@ static __init int init_amd_nbs(void) err = amd_cache_northbridges(); if (err < 0) - pr_notice("Cannot enumerate AMD northbridges\n"); + printk(KERN_NOTICE "AMD NB: Cannot enumerate AMD northbridges.\n"); if (amd_cache_gart() < 0) - pr_notice("Cannot initialize GART flush words, GART support disabled\n"); + printk(KERN_NOTICE "AMD NB: Cannot initialize GART flush words, " + "GART support disabled.\n"); return err; } diff --git a/trunk/arch/x86/kernel/aperture_64.c b/trunk/arch/x86/kernel/aperture_64.c index d5fd66f0d4cd..6e76c191a835 100644 --- a/trunk/arch/x86/kernel/aperture_64.c +++ b/trunk/arch/x86/kernel/aperture_64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,11 @@ static u32 __init allocate_aperture(void) return 0; } memblock_reserve(addr, aper_size); + /* + * Kmemleak should not scan this block as it may not be mapped via the + * kernel direct mapping. + */ + kmemleak_ignore(phys_to_virt(addr)); printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, addr); insert_aperture_resource((u32)addr, aper_size); diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index c421512ca5eb..39a222e094af 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -2123,25 +2123,6 @@ void default_init_apic_ldr(void) apic_write(APIC_LDR, val); } -int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid) -{ - unsigned int cpu; - - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - - if (likely(cpu < nr_cpu_ids)) { - *apicid = per_cpu(x86_cpu_to_apicid, cpu); - return 0; - } - - return -EINVAL; -} - /* * Power management */ diff --git a/trunk/arch/x86/kernel/apic/apic_flat_64.c b/trunk/arch/x86/kernel/apic/apic_flat_64.c index 00c77cf78e9e..0e881c46e8c8 100644 --- a/trunk/arch/x86/kernel/apic/apic_flat_64.c +++ b/trunk/arch/x86/kernel/apic/apic_flat_64.c @@ -36,6 +36,25 @@ static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 1; } +static const struct cpumask *flat_target_cpus(void) +{ + return cpu_online_mask; +} + +static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + /* * Set up the logical destination ID. * @@ -73,7 +92,7 @@ static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector) } static void -flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) + flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { unsigned long mask = cpumask_bits(cpumask)[0]; int cpu = smp_processor_id(); @@ -167,7 +186,7 @@ static struct apic apic_flat = { .irq_delivery_mode = dest_LowestPrio, .irq_dest_mode = 1, /* logical */ - .target_cpus = online_target_cpus, + .target_cpus = flat_target_cpus, .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, .check_apicid_used = NULL, @@ -191,7 +210,8 @@ static struct apic apic_flat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = flat_send_IPI_mask, .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, @@ -242,6 +262,17 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } +static const struct cpumask *physflat_target_cpus(void) +{ + return cpu_online_mask; +} + +static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector) { default_send_IPI_mask_sequence_phys(cpumask, vector); @@ -263,6 +294,38 @@ static void physflat_send_IPI_all(int vector) physflat_send_IPI_mask(cpu_online_mask, vector); } +static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + cpu = cpumask_first(cpumask); + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + else + return BAD_APICID; +} + +static unsigned int +physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + return per_cpu(x86_cpu_to_apicid, cpu); +} + static int physflat_probe(void) { if (apic == &apic_physflat || num_possible_cpus() > 8) @@ -282,13 +345,13 @@ static struct apic apic_physflat = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = online_target_cpus, + .target_cpus = physflat_target_cpus, .disable_esr = 0, .dest_logical = 0, .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = default_vector_allocation_domain, + .vector_allocation_domain = physflat_vector_allocation_domain, /* not needed, but shouldn't hurt: */ .init_apic_ldr = flat_init_apic_ldr, @@ -307,7 +370,8 @@ static struct apic apic_physflat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = physflat_cpu_mask_to_apicid_and, .send_IPI_mask = physflat_send_IPI_mask, .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself, diff --git a/trunk/arch/x86/kernel/apic/apic_noop.c b/trunk/arch/x86/kernel/apic/apic_noop.c index e145f28b4099..a6e4c6e06c08 100644 --- a/trunk/arch/x86/kernel/apic/apic_noop.c +++ b/trunk/arch/x86/kernel/apic/apic_noop.c @@ -100,12 +100,12 @@ static unsigned long noop_check_apicid_present(int bit) return physid_isset(bit, phys_cpu_present_map); } -static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask, - const struct cpumask *mask) +static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) { if (cpu != 0) pr_warning("APIC: Vector allocated for non-BSP cpu\n"); - cpumask_copy(retmask, cpumask_of(cpu)); + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); } static u32 noop_apic_read(u32 reg) @@ -159,7 +159,8 @@ struct apic apic_noop = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = noop_send_IPI_mask, .send_IPI_mask_allbutself = noop_send_IPI_mask_allbutself, diff --git a/trunk/arch/x86/kernel/apic/apic_numachip.c b/trunk/arch/x86/kernel/apic/apic_numachip.c index bc552cff2578..6ec6d5d297c3 100644 --- a/trunk/arch/x86/kernel/apic/apic_numachip.c +++ b/trunk/arch/x86/kernel/apic/apic_numachip.c @@ -72,6 +72,17 @@ static int numachip_phys_pkg_id(int initial_apic_id, int index_msb) return initial_apic_id >> index_msb; } +static const struct cpumask *numachip_target_cpus(void) +{ + return cpu_online_mask; +} + +static void numachip_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + static int __cpuinit numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip) { union numachip_csr_g3_ext_irq_gen int_gen; @@ -146,6 +157,38 @@ static void numachip_send_IPI_self(int vector) __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); } +static unsigned int numachip_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + cpu = cpumask_first(cpumask); + if (likely((unsigned)cpu < nr_cpu_ids)) + return per_cpu(x86_cpu_to_apicid, cpu); + + return BAD_APICID; +} + +static unsigned int +numachip_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + return per_cpu(x86_cpu_to_apicid, cpu); +} + static int __init numachip_probe(void) { return apic == &apic_numachip; @@ -210,13 +253,13 @@ static struct apic apic_numachip __refconst = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = online_target_cpus, + .target_cpus = numachip_target_cpus, .disable_esr = 0, .dest_logical = 0, .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = default_vector_allocation_domain, + .vector_allocation_domain = numachip_vector_allocation_domain, .init_apic_ldr = flat_init_apic_ldr, .ioapic_phys_id_map = NULL, @@ -234,7 +277,8 @@ static struct apic apic_numachip __refconst = { .set_apic_id = set_apic_id, .apic_id_mask = 0xffU << 24, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = numachip_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = numachip_cpu_mask_to_apicid_and, .send_IPI_mask = numachip_send_IPI_mask, .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself, diff --git a/trunk/arch/x86/kernel/apic/bigsmp_32.c b/trunk/arch/x86/kernel/apic/bigsmp_32.c index d50e3640d5ae..31fbdbfbf960 100644 --- a/trunk/arch/x86/kernel/apic/bigsmp_32.c +++ b/trunk/arch/x86/kernel/apic/bigsmp_32.c @@ -26,6 +26,15 @@ static int bigsmp_apic_id_registered(void) return 1; } +static const struct cpumask *bigsmp_target_cpus(void) +{ +#ifdef CONFIG_SMP + return cpu_online_mask; +#else + return cpumask_of(0); +#endif +} + static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid) { return 0; @@ -96,6 +105,32 @@ static int bigsmp_check_phys_apicid_present(int phys_apicid) return 1; } +/* As we are using single CPU as destination, pick only one CPU here */ +static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + int cpu = cpumask_first(cpumask); + + if (cpu < nr_cpu_ids) + return cpu_physical_id(cpu); + return BAD_APICID; +} + +static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + return cpu_physical_id(cpu); + } + return BAD_APICID; +} + static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) { return cpuid_apic >> index_msb; @@ -142,6 +177,12 @@ static const struct dmi_system_id bigsmp_dmi_table[] = { { } /* NULL entry stops DMI scanning */ }; +static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + static int probe_bigsmp(void) { if (def_to_bigsmp) @@ -164,13 +205,13 @@ static struct apic apic_bigsmp = { /* phys delivery to target CPU: */ .irq_dest_mode = 0, - .target_cpus = default_target_cpus, + .target_cpus = bigsmp_target_cpus, .disable_esr = 1, .dest_logical = 0, .check_apicid_used = bigsmp_check_apicid_used, .check_apicid_present = bigsmp_check_apicid_present, - .vector_allocation_domain = default_vector_allocation_domain, + .vector_allocation_domain = bigsmp_vector_allocation_domain, .init_apic_ldr = bigsmp_init_apic_ldr, .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, @@ -188,7 +229,8 @@ static struct apic apic_bigsmp = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = bigsmp_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = bigsmp_cpu_mask_to_apicid_and, .send_IPI_mask = bigsmp_send_IPI_mask, .send_IPI_mask_allbutself = NULL, diff --git a/trunk/arch/x86/kernel/apic/es7000_32.c b/trunk/arch/x86/kernel/apic/es7000_32.c index 0874799a98c6..db4ab1be3c79 100644 --- a/trunk/arch/x86/kernel/apic/es7000_32.c +++ b/trunk/arch/x86/kernel/apic/es7000_32.c @@ -394,6 +394,21 @@ static void es7000_enable_apic_mode(void) WARN(1, "Command failed, status = %x\n", mip_status); } +static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + + static void es7000_wait_for_init_deassert(atomic_t *deassert) { while (!atomic_read(deassert)) @@ -525,49 +540,45 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) return 1; } -static inline int -es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) +static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) { unsigned int round = 0; - unsigned int cpu, uninitialized_var(apicid); + int cpu, uninitialized_var(apicid); /* * The cpus in the mask must all be on the apic cluster. */ - for_each_cpu_and(cpu, cpumask, cpu_online_mask) { + for_each_cpu(cpu, cpumask) { int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { WARN(1, "Not a valid mask!"); - return -EINVAL; + return BAD_APICID; } - apicid |= new_apicid; + apicid = new_apicid; round++; } - if (!round) - return -EINVAL; - *dest_id = apicid; - return 0; + return apicid; } -static int +static unsigned int es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, - const struct cpumask *andmask, - unsigned int *apicid) + const struct cpumask *andmask) { + int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); cpumask_var_t cpumask; - *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) - return 0; + return apicid; cpumask_and(cpumask, inmask, andmask); - es7000_cpu_mask_to_apicid(cpumask, apicid); + cpumask_and(cpumask, cpumask, cpu_online_mask); + apicid = es7000_cpu_mask_to_apicid(cpumask); free_cpumask_var(cpumask); - return 0; + return apicid; } static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) @@ -627,7 +638,7 @@ static struct apic __refdata apic_es7000_cluster = { .check_apicid_used = es7000_check_apicid_used, .check_apicid_present = es7000_check_apicid_present, - .vector_allocation_domain = flat_vector_allocation_domain, + .vector_allocation_domain = es7000_vector_allocation_domain, .init_apic_ldr = es7000_init_apic_ldr_cluster, .ioapic_phys_id_map = es7000_ioapic_phys_id_map, @@ -645,6 +656,7 @@ static struct apic __refdata apic_es7000_cluster = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, + .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, .send_IPI_mask = es7000_send_IPI_mask, @@ -693,7 +705,7 @@ static struct apic __refdata apic_es7000 = { .check_apicid_used = es7000_check_apicid_used, .check_apicid_present = es7000_check_apicid_present, - .vector_allocation_domain = flat_vector_allocation_domain, + .vector_allocation_domain = es7000_vector_allocation_domain, .init_apic_ldr = es7000_init_apic_ldr, .ioapic_phys_id_map = es7000_ioapic_phys_id_map, @@ -711,6 +723,7 @@ static struct apic __refdata apic_es7000 = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, + .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, .send_IPI_mask = es7000_send_IPI_mask, diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index 406eee784684..ac96561d1a99 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -448,8 +448,8 @@ static int __add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pi entry = alloc_irq_pin_list(node); if (!entry) { - pr_err("can not alloc irq_pin_list (%d,%d,%d)\n", - node, apic, pin); + printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n", + node, apic, pin); return -ENOMEM; } entry->apic = apic; @@ -661,7 +661,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) ioapic_mask_entry(apic, pin); entry = ioapic_read_entry(apic, pin); if (entry.irr) - pr_err("Unable to reset IRR for apic: %d, pin :%d\n", + printk(KERN_ERR "Unable to reset IRR for apic: %d, pin :%d\n", mpc_ioapic_id(apic), pin); } @@ -895,7 +895,7 @@ static int irq_polarity(int idx) } case 2: /* reserved */ { - pr_warn("broken BIOS!!\n"); + printk(KERN_WARNING "broken BIOS!!\n"); polarity = 1; break; } @@ -906,7 +906,7 @@ static int irq_polarity(int idx) } default: /* invalid */ { - pr_warn("broken BIOS!!\n"); + printk(KERN_WARNING "broken BIOS!!\n"); polarity = 1; break; } @@ -948,7 +948,7 @@ static int irq_trigger(int idx) } default: { - pr_warn("broken BIOS!!\n"); + printk(KERN_WARNING "broken BIOS!!\n"); trigger = 1; break; } @@ -962,7 +962,7 @@ static int irq_trigger(int idx) } case 2: /* reserved */ { - pr_warn("broken BIOS!!\n"); + printk(KERN_WARNING "broken BIOS!!\n"); trigger = 1; break; } @@ -973,7 +973,7 @@ static int irq_trigger(int idx) } default: /* invalid */ { - pr_warn("broken BIOS!!\n"); + printk(KERN_WARNING "broken BIOS!!\n"); trigger = 0; break; } @@ -991,7 +991,7 @@ static int pin_2_irq(int idx, int apic, int pin) * Debugging check, we are in big trouble if this message pops up! */ if (mp_irqs[idx].dstirq != pin) - pr_err("broken BIOS or MPTABLE parser, ayiee!!\n"); + printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); if (test_bit(bus, mp_bus_not_pci)) { irq = mp_irqs[idx].srcbusirq; @@ -1112,7 +1112,8 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) * 0x80, because int 0x80 is hm, kind of importantish. ;) */ static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; - static int current_offset = VECTOR_OFFSET_START % 16; + static int current_offset = VECTOR_OFFSET_START % 8; + unsigned int old_vector; int cpu, err; cpumask_var_t tmp_mask; @@ -1122,45 +1123,35 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) return -ENOMEM; + old_vector = cfg->vector; + if (old_vector) { + cpumask_and(tmp_mask, mask, cpu_online_mask); + cpumask_and(tmp_mask, cfg->domain, tmp_mask); + if (!cpumask_empty(tmp_mask)) { + free_cpumask_var(tmp_mask); + return 0; + } + } + /* Only try and allocate irqs on cpus that are present */ err = -ENOSPC; - cpumask_clear(cfg->old_domain); - cpu = cpumask_first_and(mask, cpu_online_mask); - while (cpu < nr_cpu_ids) { - int new_cpu, vector, offset; + for_each_cpu_and(cpu, mask, cpu_online_mask) { + int new_cpu; + int vector, offset; - apic->vector_allocation_domain(cpu, tmp_mask, mask); - - if (cpumask_subset(tmp_mask, cfg->domain)) { - err = 0; - if (cpumask_equal(tmp_mask, cfg->domain)) - break; - /* - * New cpumask using the vector is a proper subset of - * the current in use mask. So cleanup the vector - * allocation for the members that are not used anymore. - */ - cpumask_andnot(cfg->old_domain, cfg->domain, tmp_mask); - cfg->move_in_progress = 1; - cpumask_and(cfg->domain, cfg->domain, tmp_mask); - break; - } + apic->vector_allocation_domain(cpu, tmp_mask); vector = current_vector; offset = current_offset; next: - vector += 16; + vector += 8; if (vector >= first_system_vector) { - offset = (offset + 1) % 16; + /* If out of vectors on large boxen, must share them. */ + offset = (offset + 1) % 8; vector = FIRST_EXTERNAL_VECTOR + offset; } - - if (unlikely(current_vector == vector)) { - cpumask_or(cfg->old_domain, cfg->old_domain, tmp_mask); - cpumask_andnot(tmp_mask, mask, cfg->old_domain); - cpu = cpumask_first_and(tmp_mask, cpu_online_mask); + if (unlikely(current_vector == vector)) continue; - } if (test_bit(vector, used_vectors)) goto next; @@ -1171,7 +1162,7 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) /* Found one! */ current_vector = vector; current_offset = offset; - if (cfg->vector) { + if (old_vector) { cfg->move_in_progress = 1; cpumask_copy(cfg->old_domain, cfg->domain); } @@ -1204,7 +1195,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) BUG_ON(!cfg->vector); vector = cfg->vector; - for_each_cpu(cpu, cfg->domain) + for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) per_cpu(vector_irq, cpu)[vector] = -1; cfg->vector = 0; @@ -1212,7 +1203,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) if (likely(!cfg->move_in_progress)) return; - for_each_cpu(cpu, cfg->old_domain) { + for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { if (per_cpu(vector_irq, cpu)[vector] != irq) @@ -1355,18 +1346,18 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, if (!IO_APIC_IRQ(irq)) return; + /* + * For legacy irqs, cfg->domain starts with cpu 0 for legacy + * controllers like 8259. Now that IO-APIC can handle this irq, update + * the cfg->domain. + */ + if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain)) + apic->vector_allocation_domain(0, cfg->domain); if (assign_irq_vector(irq, cfg, apic->target_cpus())) return; - if (apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus(), - &dest)) { - pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n", - mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); - __clear_irq_vector(irq, cfg); - - return; - } + dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " @@ -1375,7 +1366,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, cfg->vector, irq, attr->trigger, attr->polarity, dest); if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) { - pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", + pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); __clear_irq_vector(irq, cfg); @@ -1478,10 +1469,9 @@ void setup_IO_APIC_irq_extra(u32 gsi) * Set up the timer pin, possibly with the 8259A-master behind. */ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, - unsigned int pin, int vector) + unsigned int pin, int vector) { struct IO_APIC_route_entry entry; - unsigned int dest; if (irq_remapping_enabled) return; @@ -1492,13 +1482,9 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, * We use logical delivery to get the timer IRQ * to the first CPU. */ - if (unlikely(apic->cpu_mask_to_apicid_and(apic->target_cpus(), - apic->target_cpus(), &dest))) - dest = BAD_APICID; - entry.dest_mode = apic->irq_dest_mode; entry.mask = 0; /* don't mask IRQ for edge */ - entry.dest = dest; + entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); entry.delivery_mode = apic->irq_delivery_mode; entry.polarity = 0; entry.trigger = 0; @@ -1535,6 +1521,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) reg_03.raw = io_apic_read(ioapic_idx, 3); raw_spin_unlock_irqrestore(&ioapic_lock, flags); + printk("\n"); printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(ioapic_idx)); printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); @@ -1591,7 +1578,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) i, ir_entry->index ); - pr_cont("%1d %1d %1d %1d %1d " + printk("%1d %1d %1d %1d %1d " "%1d %1d %X %02X\n", ir_entry->format, ir_entry->mask, @@ -1611,7 +1598,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) i, entry.dest ); - pr_cont("%1d %1d %1d %1d %1d " + printk("%1d %1d %1d %1d %1d " "%1d %1d %02X\n", entry.mask, entry.trigger, @@ -1664,8 +1651,8 @@ __apicdebuginit(void) print_IO_APICs(void) continue; printk(KERN_DEBUG "IRQ%d ", irq); for_each_irq_pin(entry, cfg->irq_2_pin) - pr_cont("-> %d:%d", entry->apic, entry->pin); - pr_cont("\n"); + printk("-> %d:%d", entry->apic, entry->pin); + printk("\n"); } printk(KERN_INFO ".................................... done.\n"); @@ -1678,9 +1665,9 @@ __apicdebuginit(void) print_APIC_field(int base) printk(KERN_DEBUG); for (i = 0; i < 8; i++) - pr_cont("%08x", apic_read(base + i*0x10)); + printk(KERN_CONT "%08x", apic_read(base + i*0x10)); - pr_cont("\n"); + printk(KERN_CONT "\n"); } __apicdebuginit(void) print_local_APIC(void *dummy) @@ -1782,7 +1769,7 @@ __apicdebuginit(void) print_local_APIC(void *dummy) printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v); } } - pr_cont("\n"); + printk("\n"); } __apicdebuginit(void) print_local_APICs(int maxcpu) @@ -2078,7 +2065,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) reg_00.raw = io_apic_read(ioapic_idx, 0); raw_spin_unlock_irqrestore(&ioapic_lock, flags); if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx)) - pr_cont("could not set ID!\n"); + printk("could not set ID!\n"); else apic_printk(APIC_VERBOSE, " ok.\n"); } @@ -2223,6 +2210,71 @@ void send_cleanup_vector(struct irq_cfg *cfg) cfg->move_in_progress = 0; } +static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) +{ + int apic, pin; + struct irq_pin_list *entry; + u8 vector = cfg->vector; + + for_each_irq_pin(entry, cfg->irq_2_pin) { + unsigned int reg; + + apic = entry->apic; + pin = entry->pin; + /* + * With interrupt-remapping, destination information comes + * from interrupt-remapping table entry. + */ + if (!irq_remapped(cfg)) + io_apic_write(apic, 0x11 + pin*2, dest); + reg = io_apic_read(apic, 0x10 + pin*2); + reg &= ~IO_APIC_REDIR_VECTOR_MASK; + reg |= vector; + io_apic_modify(apic, 0x10 + pin*2, reg); + } +} + +/* + * Either sets data->affinity to a valid value, and returns + * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and + * leaves data->affinity untouched. + */ +int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, + unsigned int *dest_id) +{ + struct irq_cfg *cfg = data->chip_data; + + if (!cpumask_intersects(mask, cpu_online_mask)) + return -1; + + if (assign_irq_vector(data->irq, data->chip_data, mask)) + return -1; + + cpumask_copy(data->affinity, mask); + + *dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain); + return 0; +} + +static int +ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, + bool force) +{ + unsigned int dest, irq = data->irq; + unsigned long flags; + int ret; + + raw_spin_lock_irqsave(&ioapic_lock, flags); + ret = __ioapic_set_affinity(data, mask, &dest); + if (!ret) { + /* Only the high 8 bits are valid. */ + dest = SET_APIC_LOGICAL_ID(dest); + __target_IO_APIC_irq(irq, dest, data->chip_data); + } + raw_spin_unlock_irqrestore(&ioapic_lock, flags); + return ret; +} + asmlinkage void smp_irq_move_cleanup_interrupt(void) { unsigned vector, me; @@ -2310,87 +2362,6 @@ void irq_force_complete_move(int irq) static inline void irq_complete_move(struct irq_cfg *cfg) { } #endif -static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) -{ - int apic, pin; - struct irq_pin_list *entry; - u8 vector = cfg->vector; - - for_each_irq_pin(entry, cfg->irq_2_pin) { - unsigned int reg; - - apic = entry->apic; - pin = entry->pin; - /* - * With interrupt-remapping, destination information comes - * from interrupt-remapping table entry. - */ - if (!irq_remapped(cfg)) - io_apic_write(apic, 0x11 + pin*2, dest); - reg = io_apic_read(apic, 0x10 + pin*2); - reg &= ~IO_APIC_REDIR_VECTOR_MASK; - reg |= vector; - io_apic_modify(apic, 0x10 + pin*2, reg); - } -} - -/* - * Either sets data->affinity to a valid value, and returns - * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and - * leaves data->affinity untouched. - */ -int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, - unsigned int *dest_id) -{ - struct irq_cfg *cfg = data->chip_data; - unsigned int irq = data->irq; - int err; - - if (!config_enabled(CONFIG_SMP)) - return -1; - - if (!cpumask_intersects(mask, cpu_online_mask)) - return -EINVAL; - - err = assign_irq_vector(irq, cfg, mask); - if (err) - return err; - - err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id); - if (err) { - if (assign_irq_vector(irq, cfg, data->affinity)) - pr_err("Failed to recover vector for irq %d\n", irq); - return err; - } - - cpumask_copy(data->affinity, mask); - - return 0; -} - -static int -ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, - bool force) -{ - unsigned int dest, irq = data->irq; - unsigned long flags; - int ret; - - if (!config_enabled(CONFIG_SMP)) - return -1; - - raw_spin_lock_irqsave(&ioapic_lock, flags); - ret = __ioapic_set_affinity(data, mask, &dest); - if (!ret) { - /* Only the high 8 bits are valid. */ - dest = SET_APIC_LOGICAL_ID(dest); - __target_IO_APIC_irq(irq, dest, data->chip_data); - ret = IRQ_SET_MASK_OK_NOCOPY; - } - raw_spin_unlock_irqrestore(&ioapic_lock, flags); - return ret; -} - static void ack_apic_edge(struct irq_data *data) { irq_complete_move(data->chip_data); @@ -2570,7 +2541,9 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip) chip->irq_ack = ir_ack_apic_edge; chip->irq_eoi = ir_ack_apic_level; +#ifdef CONFIG_SMP chip->irq_set_affinity = set_remapped_irq_affinity; +#endif } #endif /* CONFIG_IRQ_REMAP */ @@ -2581,7 +2554,9 @@ static struct irq_chip ioapic_chip __read_mostly = { .irq_unmask = unmask_ioapic_irq, .irq_ack = ack_apic_edge, .irq_eoi = ack_apic_level, +#ifdef CONFIG_SMP .irq_set_affinity = ioapic_set_affinity, +#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3063,10 +3038,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, if (err) return err; - err = apic->cpu_mask_to_apicid_and(cfg->domain, - apic->target_cpus(), &dest); - if (err) - return err; + dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); if (irq_remapped(cfg)) { compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); @@ -3100,6 +3072,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, return err; } +#ifdef CONFIG_SMP static int msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -3119,8 +3092,9 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) __write_msi_msg(data->msi_desc, &msg); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; } +#endif /* CONFIG_SMP */ /* * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, @@ -3131,7 +3105,9 @@ static struct irq_chip msi_chip = { .irq_unmask = unmask_msi_irq, .irq_mask = mask_msi_irq, .irq_ack = ack_apic_edge, +#ifdef CONFIG_SMP .irq_set_affinity = msi_set_affinity, +#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3216,6 +3192,7 @@ void native_teardown_msi_irq(unsigned int irq) } #ifdef CONFIG_DMAR_TABLE +#ifdef CONFIG_SMP static int dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) @@ -3237,15 +3214,19 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, dmar_msi_write(irq, &msg); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; } +#endif /* CONFIG_SMP */ + static struct irq_chip dmar_msi_type = { .name = "DMAR_MSI", .irq_unmask = dmar_msi_unmask, .irq_mask = dmar_msi_mask, .irq_ack = ack_apic_edge, +#ifdef CONFIG_SMP .irq_set_affinity = dmar_msi_set_affinity, +#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3266,6 +3247,7 @@ int arch_setup_dmar_msi(unsigned int irq) #ifdef CONFIG_HPET_TIMER +#ifdef CONFIG_SMP static int hpet_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -3285,15 +3267,19 @@ static int hpet_msi_set_affinity(struct irq_data *data, hpet_msi_write(data->handler_data, &msg); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; } +#endif /* CONFIG_SMP */ + static struct irq_chip hpet_msi_type = { .name = "HPET_MSI", .irq_unmask = hpet_msi_unmask, .irq_mask = hpet_msi_mask, .irq_ack = ack_apic_edge, +#ifdef CONFIG_SMP .irq_set_affinity = hpet_msi_set_affinity, +#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3328,6 +3314,8 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) */ #ifdef CONFIG_HT_IRQ +#ifdef CONFIG_SMP + static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) { struct ht_irq_msg msg; @@ -3352,23 +3340,25 @@ ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) return -1; target_ht_irq(data->irq, dest, cfg->vector); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; } +#endif + static struct irq_chip ht_irq_chip = { .name = "PCI-HT", .irq_mask = mask_ht_irq, .irq_unmask = unmask_ht_irq, .irq_ack = ack_apic_edge, +#ifdef CONFIG_SMP .irq_set_affinity = ht_set_affinity, +#endif .irq_retrigger = ioapic_retrigger_irq, }; int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) { struct irq_cfg *cfg; - struct ht_irq_msg msg; - unsigned dest; int err; if (disable_apic) @@ -3376,37 +3366,36 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) cfg = irq_cfg(irq); err = assign_irq_vector(irq, cfg, apic->target_cpus()); - if (err) - return err; - - err = apic->cpu_mask_to_apicid_and(cfg->domain, - apic->target_cpus(), &dest); - if (err) - return err; + if (!err) { + struct ht_irq_msg msg; + unsigned dest; - msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); + dest = apic->cpu_mask_to_apicid_and(cfg->domain, + apic->target_cpus()); - msg.address_lo = - HT_IRQ_LOW_BASE | - HT_IRQ_LOW_DEST_ID(dest) | - HT_IRQ_LOW_VECTOR(cfg->vector) | - ((apic->irq_dest_mode == 0) ? - HT_IRQ_LOW_DM_PHYSICAL : - HT_IRQ_LOW_DM_LOGICAL) | - HT_IRQ_LOW_RQEOI_EDGE | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - HT_IRQ_LOW_MT_FIXED : - HT_IRQ_LOW_MT_ARBITRATED) | - HT_IRQ_LOW_IRQ_MASKED; + msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); - write_ht_irq_msg(irq, &msg); + msg.address_lo = + HT_IRQ_LOW_BASE | + HT_IRQ_LOW_DEST_ID(dest) | + HT_IRQ_LOW_VECTOR(cfg->vector) | + ((apic->irq_dest_mode == 0) ? + HT_IRQ_LOW_DM_PHYSICAL : + HT_IRQ_LOW_DM_LOGICAL) | + HT_IRQ_LOW_RQEOI_EDGE | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + HT_IRQ_LOW_MT_FIXED : + HT_IRQ_LOW_MT_ARBITRATED) | + HT_IRQ_LOW_IRQ_MASKED; - irq_set_chip_and_handler_name(irq, &ht_irq_chip, - handle_edge_irq, "edge"); + write_ht_irq_msg(irq, &msg); - dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); + irq_set_chip_and_handler_name(irq, &ht_irq_chip, + handle_edge_irq, "edge"); - return 0; + dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); + } + return err; } #endif /* CONFIG_HT_IRQ */ @@ -3574,8 +3563,7 @@ static int __init io_apic_get_unique_id(int ioapic, int apic_id) /* Sanity check */ if (reg_00.bits.ID != apic_id) { - pr_err("IOAPIC[%d]: Unable to change apic_id!\n", - ioapic); + printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); return -1; } } diff --git a/trunk/arch/x86/kernel/apic/numaq_32.c b/trunk/arch/x86/kernel/apic/numaq_32.c index d661ee95cabf..f00a68cca37a 100644 --- a/trunk/arch/x86/kernel/apic/numaq_32.c +++ b/trunk/arch/x86/kernel/apic/numaq_32.c @@ -406,13 +406,16 @@ static inline int numaq_check_phys_apicid_present(int phys_apicid) * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ -static int +static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + return 0x0F; +} + +static inline unsigned int numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid) + const struct cpumask *andmask) { - *apicid = 0x0F; - return 0; + return 0x0F; } /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ @@ -438,6 +441,20 @@ static int probe_numaq(void) return found_numaq; } +static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + static void numaq_setup_portio_remap(void) { int num_quads = num_online_nodes(); @@ -474,7 +491,7 @@ static struct apic __refdata apic_numaq = { .check_apicid_used = numaq_check_apicid_used, .check_apicid_present = numaq_check_apicid_present, - .vector_allocation_domain = flat_vector_allocation_domain, + .vector_allocation_domain = numaq_vector_allocation_domain, .init_apic_ldr = numaq_init_apic_ldr, .ioapic_phys_id_map = numaq_ioapic_phys_id_map, @@ -492,6 +509,7 @@ static struct apic __refdata apic_numaq = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, + .cpu_mask_to_apicid = numaq_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and, .send_IPI_mask = numaq_send_IPI_mask, diff --git a/trunk/arch/x86/kernel/apic/probe_32.c b/trunk/arch/x86/kernel/apic/probe_32.c index eb35ef9ee63f..1b291da09e60 100644 --- a/trunk/arch/x86/kernel/apic/probe_32.c +++ b/trunk/arch/x86/kernel/apic/probe_32.c @@ -66,6 +66,21 @@ static void setup_apic_flat_routing(void) #endif } +static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* + * Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + /* should be called last. */ static int probe_default(void) { @@ -90,7 +105,7 @@ static struct apic apic_default = { .check_apicid_used = default_check_apicid_used, .check_apicid_present = default_check_apicid_present, - .vector_allocation_domain = flat_vector_allocation_domain, + .vector_allocation_domain = default_vector_allocation_domain, .init_apic_ldr = default_init_apic_ldr, .ioapic_phys_id_map = default_ioapic_phys_id_map, @@ -108,7 +123,8 @@ static struct apic apic_default = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = default_send_IPI_mask_logical, .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, @@ -192,9 +208,6 @@ void __init default_setup_apic_routing(void) if (apic->setup_apic_routing) apic->setup_apic_routing(); - - if (x86_platform.apic_post_init) - x86_platform.apic_post_init(); } void __init generic_apic_probe(void) diff --git a/trunk/arch/x86/kernel/apic/probe_64.c b/trunk/arch/x86/kernel/apic/probe_64.c index 1793dba7a741..3fe986698929 100644 --- a/trunk/arch/x86/kernel/apic/probe_64.c +++ b/trunk/arch/x86/kernel/apic/probe_64.c @@ -23,6 +23,11 @@ #include #include +static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) +{ + return hard_smp_processor_id() >> index_msb; +} + /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ @@ -43,8 +48,10 @@ void __init default_setup_apic_routing(void) } } - if (x86_platform.apic_post_init) - x86_platform.apic_post_init(); + if (is_vsmp_box()) { + /* need to update phys_pkg_id */ + apic->phys_pkg_id = apicid_phys_pkg_id; + } } /* Same for both flat and physical. */ diff --git a/trunk/arch/x86/kernel/apic/summit_32.c b/trunk/arch/x86/kernel/apic/summit_32.c index 77c95c0e1bf7..659897c00755 100644 --- a/trunk/arch/x86/kernel/apic/summit_32.c +++ b/trunk/arch/x86/kernel/apic/summit_32.c @@ -26,8 +26,6 @@ * */ -#define pr_fmt(fmt) "summit: %s: " fmt, __func__ - #include #include #include @@ -237,8 +235,8 @@ static int summit_apic_id_registered(void) static void summit_setup_apic_routing(void) { - pr_info("Enabling APIC mode: Summit. Using %d I/O APICs\n", - nr_ioapics); + printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", + nr_ioapics); } static int summit_cpu_present_to_apicid(int mps_cpu) @@ -265,48 +263,43 @@ static int summit_check_phys_apicid_present(int physical_apicid) return 1; } -static inline int -summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) +static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) { unsigned int round = 0; - unsigned int cpu, apicid = 0; + int cpu, apicid = 0; /* * The cpus in the mask must all be on the apic cluster. */ - for_each_cpu_and(cpu, cpumask, cpu_online_mask) { + for_each_cpu(cpu, cpumask) { int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - pr_err("Not a valid mask!\n"); - return -EINVAL; + printk("%s: Not a valid mask!\n", __func__); + return BAD_APICID; } apicid |= new_apicid; round++; } - if (!round) - return -EINVAL; - *dest_id = apicid; - return 0; + return apicid; } -static int -summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, - const struct cpumask *andmask, - unsigned int *apicid) +static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, + const struct cpumask *andmask) { + int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); cpumask_var_t cpumask; - *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) - return 0; + return apicid; cpumask_and(cpumask, inmask, andmask); - summit_cpu_mask_to_apicid(cpumask, apicid); + cpumask_and(cpumask, cpumask, cpu_online_mask); + apicid = summit_cpu_mask_to_apicid(cpumask); free_cpumask_var(cpumask); - return 0; + return apicid; } /* @@ -327,6 +320,20 @@ static int probe_summit(void) return 0; } +static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + #ifdef CONFIG_X86_SUMMIT_NUMA static struct rio_table_hdr *rio_table_hdr; static struct scal_detail *scal_devs[MAX_NUMNODES]; @@ -348,7 +355,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) } } if (i == rio_table_hdr->num_rio_dev) { - pr_err("Couldn't find owner Cyclone for Winnipeg!\n"); + printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__); return last_bus; } @@ -359,7 +366,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) } } if (i == rio_table_hdr->num_scal_dev) { - pr_err("Couldn't find owner Twister for Cyclone!\n"); + printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__); return last_bus; } @@ -389,7 +396,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) num_buses = 9; break; default: - pr_info("Unsupported Winnipeg type!\n"); + printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__); return last_bus; } @@ -404,15 +411,13 @@ static int build_detail_arrays(void) int i, scal_detail_size, rio_detail_size; if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) { - pr_warn("MAX_NUMNODES too low! Defined as %d, but system has %d nodes\n", - MAX_NUMNODES, rio_table_hdr->num_scal_dev); + printk(KERN_WARNING "%s: MAX_NUMNODES too low! Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev); return 0; } switch (rio_table_hdr->version) { default: - pr_warn("Invalid Rio Grande Table Version: %d\n", - rio_table_hdr->version); + printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version); return 0; case 2: scal_detail_size = 11; @@ -457,7 +462,7 @@ void setup_summit(void) offset = *((unsigned short *)(ptr + offset)); } if (!rio_table_hdr) { - pr_err("Unable to locate Rio Grande Table in EBDA - bailing!\n"); + printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__); return; } @@ -504,7 +509,7 @@ static struct apic apic_summit = { .check_apicid_used = summit_check_apicid_used, .check_apicid_present = summit_check_apicid_present, - .vector_allocation_domain = flat_vector_allocation_domain, + .vector_allocation_domain = summit_vector_allocation_domain, .init_apic_ldr = summit_init_apic_ldr, .ioapic_phys_id_map = summit_ioapic_phys_id_map, @@ -522,6 +527,7 @@ static struct apic apic_summit = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, + .cpu_mask_to_apicid = summit_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and, .send_IPI_mask = summit_send_IPI_mask, diff --git a/trunk/arch/x86/kernel/apic/x2apic_cluster.c b/trunk/arch/x86/kernel/apic/x2apic_cluster.c index c88baa4ff0e5..ff35cff0e1a7 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_cluster.c +++ b/trunk/arch/x86/kernel/apic/x2apic_cluster.c @@ -81,7 +81,7 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) } static void -x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) + x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) { __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); } @@ -96,37 +96,36 @@ static void x2apic_send_IPI_all(int vector) __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); } -static int -x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid) +static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) { - u32 dest = 0; - u16 cluster; - int i; + /* + * We're using fixed IRQ delivery, can only return one logical APIC ID. + * May as well be the first. + */ + int cpu = cpumask_first(cpumask); - for_each_cpu_and(i, cpumask, andmask) { - if (!cpumask_test_cpu(i, cpu_online_mask)) - continue; - dest = per_cpu(x86_cpu_to_logical_apicid, i); - cluster = x2apic_cluster(i); - break; - } + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_logical_apicid, cpu); + else + return BAD_APICID; +} - if (!dest) - return -EINVAL; +static unsigned int +x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; - for_each_cpu_and(i, cpumask, andmask) { - if (!cpumask_test_cpu(i, cpu_online_mask)) - continue; - if (cluster != x2apic_cluster(i)) - continue; - dest |= per_cpu(x86_cpu_to_logical_apicid, i); + /* + * We're using fixed IRQ delivery, can only return one logical APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; } - *apicid = dest; - - return 0; + return per_cpu(x86_cpu_to_logical_apicid, cpu); } static void init_x2apic_ldr(void) @@ -209,32 +208,6 @@ static int x2apic_cluster_probe(void) return 0; } -static const struct cpumask *x2apic_cluster_target_cpus(void) -{ - return cpu_all_mask; -} - -/* - * Each x2apic cluster is an allocation domain. - */ -static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask, - const struct cpumask *mask) -{ - /* - * To minimize vector pressure, default case of boot, device bringup - * etc will use a single cpu for the interrupt destination. - * - * On explicit migration requests coming from irqbalance etc, - * interrupts will be routed to the x2apic cluster (cluster-id - * derived from the first cpu in the mask) members specified - * in the mask. - */ - if (mask == x2apic_cluster_target_cpus()) - cpumask_copy(retmask, cpumask_of(cpu)); - else - cpumask_and(retmask, mask, per_cpu(cpus_in_cluster, cpu)); -} - static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", @@ -246,13 +219,13 @@ static struct apic apic_x2apic_cluster = { .irq_delivery_mode = dest_LowestPrio, .irq_dest_mode = 1, /* logical */ - .target_cpus = x2apic_cluster_target_cpus, + .target_cpus = x2apic_target_cpus, .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = cluster_vector_allocation_domain, + .vector_allocation_domain = x2apic_vector_allocation_domain, .init_apic_ldr = init_x2apic_ldr, .ioapic_phys_id_map = NULL, @@ -270,6 +243,7 @@ static struct apic apic_x2apic_cluster = { .set_apic_id = x2apic_set_apic_id, .apic_id_mask = 0xFFFFFFFFu, + .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, .send_IPI_mask = x2apic_send_IPI_mask, diff --git a/trunk/arch/x86/kernel/apic/x2apic_phys.c b/trunk/arch/x86/kernel/apic/x2apic_phys.c index e03a1e180e81..c17e982db275 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_phys.c +++ b/trunk/arch/x86/kernel/apic/x2apic_phys.c @@ -76,6 +76,38 @@ static void x2apic_send_IPI_all(int vector) __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); } +static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + int cpu = cpumask_first(cpumask); + + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + else + return BAD_APICID; +} + +static unsigned int +x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + + return per_cpu(x86_cpu_to_apicid, cpu); +} + static void init_x2apic_ldr(void) { } @@ -99,13 +131,13 @@ static struct apic apic_x2apic_phys = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = online_target_cpus, + .target_cpus = x2apic_target_cpus, .disable_esr = 0, .dest_logical = 0, .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = default_vector_allocation_domain, + .vector_allocation_domain = x2apic_vector_allocation_domain, .init_apic_ldr = init_x2apic_ldr, .ioapic_phys_id_map = NULL, @@ -123,7 +155,8 @@ static struct apic apic_x2apic_phys = { .set_apic_id = x2apic_set_apic_id, .apic_id_mask = 0xFFFFFFFFu, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, .send_IPI_mask = x2apic_send_IPI_mask, .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, diff --git a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c index 8cfade9510a4..c6d03f7a4401 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c @@ -185,6 +185,17 @@ EXPORT_SYMBOL_GPL(uv_possible_blades); unsigned long sn_rtc_cycles_per_second; EXPORT_SYMBOL(sn_rtc_cycles_per_second); +static const struct cpumask *uv_target_cpus(void) +{ + return cpu_online_mask; +} + +static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) { #ifdef CONFIG_SMP @@ -269,12 +280,25 @@ static void uv_init_apic_ldr(void) { } -static int +static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + int cpu = cpumask_first(cpumask); + + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; + else + return BAD_APICID; +} + +static unsigned int uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid) + const struct cpumask *andmask) { - int unsigned cpu; + int cpu; /* * We're using fixed IRQ delivery, can only return one phys APIC ID. @@ -284,13 +308,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - - if (likely(cpu < nr_cpu_ids)) { - *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; - return 0; - } - - return -EINVAL; + return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; } static unsigned int x2apic_get_apic_id(unsigned long x) @@ -344,13 +362,13 @@ static struct apic __refdata apic_x2apic_uv_x = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = online_target_cpus, + .target_cpus = uv_target_cpus, .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = default_vector_allocation_domain, + .vector_allocation_domain = uv_vector_allocation_domain, .init_apic_ldr = uv_init_apic_ldr, .ioapic_phys_id_map = NULL, @@ -368,6 +386,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFFFFFFFu, + .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and, .send_IPI_mask = uv_send_IPI_mask, diff --git a/trunk/arch/x86/kernel/apm_32.c b/trunk/arch/x86/kernel/apm_32.c index d65464e43503..07b0c0db466c 100644 --- a/trunk/arch/x86/kernel/apm_32.c +++ b/trunk/arch/x86/kernel/apm_32.c @@ -201,8 +201,6 @@ * http://www.microsoft.com/whdc/archive/amp_12.mspx] */ -#define pr_fmt(fmt) "apm: " fmt - #include #include @@ -487,11 +485,11 @@ static void apm_error(char *str, int err) if (error_table[i].key == err) break; if (i < ERROR_COUNT) - pr_notice("%s: %s\n", str, error_table[i].msg); + printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg); else if (err < 0) - pr_notice("%s: linux error code %i\n", str, err); + printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err); else - pr_notice("%s: unknown error code %#2.2x\n", + printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n", str, err); } @@ -1186,7 +1184,7 @@ static void queue_event(apm_event_t event, struct apm_user *sender) static int notified; if (notified++ == 0) - pr_err("an event queue overflowed\n"); + printk(KERN_ERR "apm: an event queue overflowed\n"); if (++as->event_tail >= APM_MAX_EVENTS) as->event_tail = 0; } @@ -1449,7 +1447,7 @@ static void apm_mainloop(void) static int check_apm_user(struct apm_user *as, const char *func) { if (as == NULL || as->magic != APM_BIOS_MAGIC) { - pr_err("%s passed bad filp\n", func); + printk(KERN_ERR "apm: %s passed bad filp\n", func); return 1; } return 0; @@ -1588,7 +1586,7 @@ static int do_release(struct inode *inode, struct file *filp) as1 = as1->next) ; if (as1 == NULL) - pr_err("filp not in user list\n"); + printk(KERN_ERR "apm: filp not in user list\n"); else as1->next = as->next; } @@ -1602,9 +1600,11 @@ static int do_open(struct inode *inode, struct file *filp) struct apm_user *as; as = kmalloc(sizeof(*as), GFP_KERNEL); - if (as == NULL) + if (as == NULL) { + printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", + sizeof(*as)); return -ENOMEM; - + } as->magic = APM_BIOS_MAGIC; as->event_tail = as->event_head = 0; as->suspends_pending = as->standbys_pending = 0; @@ -2313,16 +2313,16 @@ static int __init apm_init(void) } if (apm_info.disabled) { - pr_notice("disabled on user request.\n"); + printk(KERN_NOTICE "apm: disabled on user request.\n"); return -ENODEV; } if ((num_online_cpus() > 1) && !power_off && !smp) { - pr_notice("disabled - APM is not SMP safe.\n"); + printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n"); apm_info.disabled = 1; return -ENODEV; } if (!acpi_disabled) { - pr_notice("overridden by ACPI.\n"); + printk(KERN_NOTICE "apm: overridden by ACPI.\n"); apm_info.disabled = 1; return -ENODEV; } @@ -2356,7 +2356,8 @@ static int __init apm_init(void) kapmd_task = kthread_create(apm, NULL, "kapmd"); if (IS_ERR(kapmd_task)) { - pr_err("disabled - Unable to start kernel thread\n"); + printk(KERN_ERR "apm: disabled - Unable to start kernel " + "thread.\n"); err = PTR_ERR(kapmd_task); kapmd_task = NULL; remove_proc_entry("apm", NULL); diff --git a/trunk/arch/x86/kernel/cpu/Makefile b/trunk/arch/x86/kernel/cpu/Makefile index bac4c3804cc7..6ab6aa2fdfdd 100644 --- a/trunk/arch/x86/kernel/cpu/Makefile +++ b/trunk/arch/x86/kernel/cpu/Makefile @@ -32,9 +32,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o ifdef CONFIG_PERF_EVENTS obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o endif obj-$(CONFIG_X86_MCE) += mcheck/ diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 9d92e19039f0..146bb6218eec 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -19,39 +19,6 @@ #include "cpu.h" -static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) -{ - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); - u32 gprs[8] = { 0 }; - int err; - - WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); - - gprs[1] = msr; - gprs[7] = 0x9c5a203a; - - err = rdmsr_safe_regs(gprs); - - *p = gprs[0] | ((u64)gprs[2] << 32); - - return err; -} - -static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) -{ - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); - u32 gprs[8] = { 0 }; - - WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); - - gprs[0] = (u32)val; - gprs[1] = msr; - gprs[2] = val >> 32; - gprs[7] = 0x9c5a203a; - - return wrmsr_safe_regs(gprs); -} - #ifdef CONFIG_X86_32 /* * B step AMD K6 before B 9730xxxx have hardware bugs that can cause @@ -619,9 +586,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) !cpu_has(c, X86_FEATURE_TOPOEXT)) { u64 val; - if (!rdmsrl_safe(0xc0011005, &val)) { + if (!rdmsrl_amd_safe(0xc0011005, &val)) { val |= 1ULL << 54; - wrmsrl_safe(0xc0011005, val); + wrmsrl_amd_safe(0xc0011005, val); rdmsrl(0xc0011005, val); if (val & (1ULL << 54)) { set_cpu_cap(c, X86_FEATURE_TOPOEXT); @@ -712,7 +679,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); if (err == 0) { mask |= (1 << 10); - wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask); + checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); } } diff --git a/trunk/arch/x86/kernel/cpu/bugs.c b/trunk/arch/x86/kernel/cpu/bugs.c index c97bb7b5a9f8..46674fbb62ba 100644 --- a/trunk/arch/x86/kernel/cpu/bugs.c +++ b/trunk/arch/x86/kernel/cpu/bugs.c @@ -55,8 +55,8 @@ static void __init check_fpu(void) if (!boot_cpu_data.hard_math) { #ifndef CONFIG_MATH_EMULATION - pr_emerg("No coprocessor found and no math emulation present\n"); - pr_emerg("Giving up\n"); + printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); + printk(KERN_EMERG "Giving up.\n"); for (;;) ; #endif return; @@ -86,7 +86,7 @@ static void __init check_fpu(void) boot_cpu_data.fdiv_bug = fdiv_bug; if (boot_cpu_data.fdiv_bug) - pr_warn("Hmm, FPU with FDIV bug\n"); + printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n"); } static void __init check_hlt(void) @@ -94,16 +94,16 @@ static void __init check_hlt(void) if (boot_cpu_data.x86 >= 5 || paravirt_enabled()) return; - pr_info("Checking 'hlt' instruction... "); + printk(KERN_INFO "Checking 'hlt' instruction... "); if (!boot_cpu_data.hlt_works_ok) { - pr_cont("disabled\n"); + printk("disabled\n"); return; } halt(); halt(); halt(); halt(); - pr_cont("OK\n"); + printk(KERN_CONT "OK.\n"); } /* @@ -116,7 +116,7 @@ static void __init check_popad(void) #ifndef CONFIG_X86_POPAD_OK int res, inp = (int) &res; - pr_info("Checking for popad bug... "); + printk(KERN_INFO "Checking for popad bug... "); __asm__ __volatile__( "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " : "=&a" (res) @@ -127,9 +127,9 @@ static void __init check_popad(void) * CPU hard. Too bad. */ if (res != 12345678) - pr_cont("Buggy\n"); + printk(KERN_CONT "Buggy.\n"); else - pr_cont("OK\n"); + printk(KERN_CONT "OK.\n"); #endif } @@ -161,7 +161,7 @@ void __init check_bugs(void) { identify_boot_cpu(); #ifndef CONFIG_SMP - pr_info("CPU: "); + printk(KERN_INFO "CPU: "); print_cpu_info(&boot_cpu_data); #endif check_config(); diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index 5bbc082c47ad..6b9333b429ba 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -947,7 +947,7 @@ static void __cpuinit __print_cpu_msr(void) index_max = msr_range_array[i].max; for (index = index_min; index < index_max; index++) { - if (rdmsrl_safe(index, &val)) + if (rdmsrl_amd_safe(index, &val)) continue; printk(KERN_INFO " MSR%08x: %016llx\n", index, val); } diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c index 5a5a5dc1ff15..0a687fd185e6 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c @@ -7,9 +7,6 @@ * Copyright 2008 Intel Corporation * Author: Andi Kleen */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -213,7 +210,7 @@ static void drain_mcelog_buffer(void) cpu_relax(); if (!m->finished && retries >= 4) { - pr_err("skipping error being logged currently!\n"); + pr_err("MCE: skipping error being logged currently!\n"); break; } } @@ -1170,9 +1167,8 @@ int memory_failure(unsigned long pfn, int vector, int flags) { /* mce_severity() should not hand us an ACTION_REQUIRED error */ BUG_ON(flags & MF_ACTION_REQUIRED); - pr_err("Uncorrected memory error in page 0x%lx ignored\n" - "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", - pfn); + printk(KERN_ERR "Uncorrected memory error in page 0x%lx ignored\n" + "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", pfn); return 0; } @@ -1278,7 +1274,7 @@ static void mce_timer_fn(unsigned long data) */ iv = __this_cpu_read(mce_next_interval); if (mce_notify_irq()) - iv = max(iv / 2, (unsigned long) HZ/100); + iv = max(iv, (unsigned long) HZ/100); else iv = min(iv * 2, round_jiffies_relative(check_interval * HZ)); __this_cpu_write(mce_next_interval, iv); @@ -1362,10 +1358,11 @@ static int __cpuinit __mcheck_cpu_cap_init(void) b = cap & MCG_BANKCNT_MASK; if (!banks) - pr_info("CPU supports %d MCE banks\n", b); + printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b); if (b > MAX_NR_BANKS) { - pr_warn("Using only %u machine check banks out of %u\n", + printk(KERN_WARNING + "MCE: Using only %u machine check banks out of %u\n", MAX_NR_BANKS, b); b = MAX_NR_BANKS; } @@ -1422,7 +1419,7 @@ static void __mcheck_cpu_init_generic(void) static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) { if (c->x86_vendor == X86_VENDOR_UNKNOWN) { - pr_info("unknown CPU type - not enabling MCE support\n"); + pr_info("MCE: unknown CPU type - not enabling MCE support.\n"); return -EOPNOTSUPP; } @@ -1560,7 +1557,7 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) static void __mcheck_cpu_init_timer(void) { struct timer_list *t = &__get_cpu_var(mce_timer); - unsigned long iv = check_interval * HZ; + unsigned long iv = __this_cpu_read(mce_next_interval); setup_timer(t, mce_timer_fn, smp_processor_id()); @@ -1577,7 +1574,7 @@ static void __mcheck_cpu_init_timer(void) /* Handle unconfigured int18 (should never happen) */ static void unexpected_machine_check(struct pt_regs *regs, long error_code) { - pr_err("CPU#%d: Unexpected int18 (Machine Check)\n", + printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id()); } @@ -1896,7 +1893,8 @@ static int __init mcheck_enable(char *str) get_option(&str, &monarch_timeout); } } else { - pr_info("mce argument %s ignored. Please use /sys\n", str); + printk(KERN_INFO "mce argument %s ignored. Please use /sys\n", + str); return 0; } return 1; diff --git a/trunk/arch/x86/kernel/cpu/mkcapflags.pl b/trunk/arch/x86/kernel/cpu/mkcapflags.pl index c7b3fe2d72e0..dfea390e1608 100644 --- a/trunk/arch/x86/kernel/cpu/mkcapflags.pl +++ b/trunk/arch/x86/kernel/cpu/mkcapflags.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # # Generate the x86_cap_flags[] array from include/asm-x86/cpufeature.h # @@ -11,35 +11,22 @@ print OUT "#include \n\n"; print OUT "const char * const x86_cap_flags[NCAPINTS*32] = {\n"; -%features = (); -$err = 0; - while (defined($line = )) { if ($line =~ /^\s*\#\s*define\s+(X86_FEATURE_(\S+))\s+(.*)$/) { $macro = $1; - $feature = "\L$2"; + $feature = $2; $tail = $3; if ($tail =~ /\/\*\s*\"([^"]*)\".*\*\//) { - $feature = "\L$1"; + $feature = $1; } - next if ($feature eq ''); - - if ($features{$feature}++) { - print STDERR "$in: duplicate feature name: $feature\n"; - $err++; + if ($feature ne '') { + printf OUT "\t%-32s = \"%s\",\n", + "[$macro]", "\L$feature"; } - printf OUT "\t%-32s = \"%s\",\n", "[$macro]", $feature; } } print OUT "};\n"; close(IN); close(OUT); - -if ($err) { - unlink($out); - exit(1); -} - -exit(0); diff --git a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c index 35ffda5d0727..bdda2e6c673b 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -258,11 +258,11 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, /* Compute the maximum size with which we can make a range: */ if (range_startk) - max_align = __ffs(range_startk); + max_align = ffs(range_startk) - 1; else - max_align = BITS_PER_LONG - 1; + max_align = 32; - align = __fls(range_sizek); + align = fls(range_sizek) - 1; if (align > max_align) align = max_align; diff --git a/trunk/arch/x86/kernel/cpu/mtrr/generic.c b/trunk/arch/x86/kernel/cpu/mtrr/generic.c index e9fe907cd249..75772ae6c65f 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/generic.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/generic.c @@ -361,7 +361,11 @@ static void __init print_mtrr_state(void) } pr_debug("MTRR variable ranges %sabled:\n", mtrr_state.enabled & 2 ? "en" : "dis"); - high_width = (__ffs64(size_or_mask) - (32 - PAGE_SHIFT) + 3) / 4; + if (size_or_mask & 0xffffffffUL) + high_width = ffs(size_or_mask & 0xffffffffUL) - 1; + else + high_width = ffs(size_or_mask>>32) + 32 - 1; + high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; for (i = 0; i < num_var_ranges; ++i) { if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index 29557aa06dda..e049d6da0183 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -35,6 +35,17 @@ #include "perf_event.h" +#if 0 +#undef wrmsrl +#define wrmsrl(msr, val) \ +do { \ + trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\ + (unsigned long)(val)); \ + native_write_msr((msr), (u32)((u64)(val)), \ + (u32)((u64)(val) >> 32)); \ +} while (0) +#endif + struct x86_pmu x86_pmu __read_mostly; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { @@ -63,7 +74,7 @@ u64 x86_perf_event_update(struct perf_event *event) int idx = hwc->idx; s64 delta; - if (idx == INTEL_PMC_IDX_FIXED_BTS) + if (idx == X86_PMC_IDX_FIXED_BTS) return 0; /* @@ -75,7 +86,7 @@ u64 x86_perf_event_update(struct perf_event *event) */ again: prev_raw_count = local64_read(&hwc->prev_count); - rdpmcl(hwc->event_base_rdpmc, new_raw_count); + rdmsrl(hwc->event_base, new_raw_count); if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, new_raw_count) != prev_raw_count) @@ -178,7 +189,7 @@ static void release_pmc_hardware(void) {} static bool check_hw_exists(void) { - u64 val, val_new = ~0; + u64 val, val_new = 0; int i, reg, ret = 0; /* @@ -211,9 +222,8 @@ static bool check_hw_exists(void) * that don't trap on the MSR access and always return 0s. */ val = 0xabcdUL; - reg = x86_pmu_event_addr(0); - ret = wrmsrl_safe(reg, val); - ret |= rdmsrl_safe(reg, &val_new); + ret = checking_wrmsrl(x86_pmu_event_addr(0), val); + ret |= rdmsrl_safe(x86_pmu_event_addr(0), &val_new); if (ret || val != val_new) goto msr_fail; @@ -230,7 +240,6 @@ static bool check_hw_exists(void) msr_fail: printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); - printk(KERN_ERR "Failed to access perfctr msr (MSR %x is %Lx)\n", reg, val_new); return false; } @@ -379,7 +388,7 @@ int x86_pmu_hw_config(struct perf_event *event) int precise = 0; /* Support for constant skid */ - if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { + if (x86_pmu.pebs_active) { precise++; /* Support for IP fixup */ @@ -628,8 +637,8 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) c = sched->constraints[sched->state.event]; /* Prefer fixed purpose counters */ - if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { - idx = INTEL_PMC_IDX_FIXED; + if (x86_pmu.num_counters_fixed) { + idx = X86_PMC_IDX_FIXED; for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { if (!__test_and_set_bit(idx, sched->state.used)) goto done; @@ -637,7 +646,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) } /* Grab the first unused counter starting with idx */ idx = sched->state.counter; - for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { + for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_FIXED) { if (!__test_and_set_bit(idx, sched->state.used)) goto done; } @@ -695,8 +704,8 @@ static bool perf_sched_next_event(struct perf_sched *sched) /* * Assign a counter for each event. */ -int perf_assign_events(struct event_constraint **constraints, int n, - int wmin, int wmax, int *assign) +static int perf_assign_events(struct event_constraint **constraints, int n, + int wmin, int wmax, int *assign) { struct perf_sched sched; @@ -815,17 +824,15 @@ static inline void x86_assign_hw_event(struct perf_event *event, hwc->last_cpu = smp_processor_id(); hwc->last_tag = ++cpuc->tags[i]; - if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) { + if (hwc->idx == X86_PMC_IDX_FIXED_BTS) { hwc->config_base = 0; hwc->event_base = 0; - } else if (hwc->idx >= INTEL_PMC_IDX_FIXED) { + } else if (hwc->idx >= X86_PMC_IDX_FIXED) { hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; - hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED); - hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30; + hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - X86_PMC_IDX_FIXED); } else { hwc->config_base = x86_pmu_config_addr(hwc->idx); hwc->event_base = x86_pmu_event_addr(hwc->idx); - hwc->event_base_rdpmc = hwc->idx; } } @@ -923,7 +930,7 @@ int x86_perf_event_set_period(struct perf_event *event) s64 period = hwc->sample_period; int ret = 0, idx = hwc->idx; - if (idx == INTEL_PMC_IDX_FIXED_BTS) + if (idx == X86_PMC_IDX_FIXED_BTS) return 0; /* @@ -1309,6 +1316,7 @@ static struct attribute_group x86_pmu_format_group = { static int __init init_hw_perf_events(void) { struct x86_pmu_quirk *quirk; + struct event_constraint *c; int err; pr_info("Performance Events: "); @@ -1339,8 +1347,21 @@ static int __init init_hw_perf_events(void) for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) quirk->func(); - if (!x86_pmu.intel_ctrl) - x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; + if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { + WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", + x86_pmu.num_counters, X86_PMC_MAX_GENERIC); + x86_pmu.num_counters = X86_PMC_MAX_GENERIC; + } + x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; + + if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { + WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", + x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); + x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; + } + + x86_pmu.intel_ctrl |= + ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; perf_events_lapic_init(); register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI"); @@ -1349,6 +1370,22 @@ static int __init init_hw_perf_events(void) __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, 0, x86_pmu.num_counters, 0); + if (x86_pmu.event_constraints) { + /* + * event on fixed counter2 (REF_CYCLES) only works on this + * counter, so do not extend mask to generic counters + */ + for_each_event_constraint(c, x86_pmu.event_constraints) { + if (c->cmask != X86_RAW_EVENT_MASK + || c->idxmsk64 == X86_PMC_MSK_FIXED_REF_CYCLES) { + continue; + } + + c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; + c->weight += x86_pmu.num_counters; + } + } + x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ x86_pmu_format_group.attrs = x86_pmu.format_attrs; @@ -1459,7 +1496,6 @@ static struct cpu_hw_events *allocate_fake_cpuc(void) if (!cpuc->shared_regs) goto error; } - cpuc->is_fake = 1; return cpuc; error: free_fake_cpuc(cpuc); @@ -1583,8 +1619,8 @@ static int x86_pmu_event_idx(struct perf_event *event) if (!x86_pmu.attr_rdpmc) return 0; - if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) { - idx -= INTEL_PMC_IDX_FIXED; + if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { + idx -= X86_PMC_IDX_FIXED; idx |= 1 << 30; } @@ -1612,12 +1648,7 @@ static ssize_t set_attr_rdpmc(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long val; - ssize_t ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; + unsigned long val = simple_strtoul(buf, NULL, 0); if (!!val != !!x86_pmu.attr_rdpmc) { x86_pmu.attr_rdpmc = !!val; @@ -1650,20 +1681,13 @@ static void x86_pmu_flush_branch_stack(void) x86_pmu.flush_branch_stack(); } -void perf_check_microcode(void) -{ - if (x86_pmu.check_microcode) - x86_pmu.check_microcode(); -} -EXPORT_SYMBOL_GPL(perf_check_microcode); - static struct pmu pmu = { .pmu_enable = x86_pmu_enable, .pmu_disable = x86_pmu_disable, - .attr_groups = x86_pmu_attr_groups, + .attr_groups = x86_pmu_attr_groups, - .event_init = x86_pmu_event_init, + .event_init = x86_pmu_event_init, .add = x86_pmu_add, .del = x86_pmu_del, @@ -1671,11 +1695,11 @@ static struct pmu pmu = { .stop = x86_pmu_stop, .read = x86_pmu_read, - .start_txn = x86_pmu_start_txn, - .cancel_txn = x86_pmu_cancel_txn, - .commit_txn = x86_pmu_commit_txn, + .start_txn = x86_pmu_start_txn, + .cancel_txn = x86_pmu_cancel_txn, + .commit_txn = x86_pmu_commit_txn, - .event_idx = x86_pmu_event_idx, + .event_idx = x86_pmu_event_idx, .flush_branch_stack = x86_pmu_flush_branch_stack, }; @@ -1732,12 +1756,6 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); } -static inline int -valid_user_frame(const void __user *fp, unsigned long size) -{ - return (__range_not_ok(fp, size, TASK_SIZE) == 0); -} - #ifdef CONFIG_COMPAT #include @@ -1762,7 +1780,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) if (bytes != sizeof(frame)) break; - if (!valid_user_frame(fp, sizeof(frame))) + if (fp < compat_ptr(regs->sp)) break; perf_callchain_store(entry, frame.return_address); @@ -1808,7 +1826,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) if (bytes != sizeof(frame)) break; - if (!valid_user_frame(fp, sizeof(frame))) + if ((unsigned long)fp < regs->sp) break; perf_callchain_store(entry, frame.return_address); @@ -1838,7 +1856,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) else misc |= PERF_RECORD_MISC_GUEST_KERNEL; } else { - if (!kernel_ip(regs->ip)) + if (user_mode(regs)) misc |= PERF_RECORD_MISC_USER; else misc |= PERF_RECORD_MISC_KERNEL; diff --git a/trunk/arch/x86/kernel/cpu/perf_event.h b/trunk/arch/x86/kernel/cpu/perf_event.h index a15df4be151f..6638aaf54493 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.h +++ b/trunk/arch/x86/kernel/cpu/perf_event.h @@ -14,18 +14,6 @@ #include -#if 0 -#undef wrmsrl -#define wrmsrl(msr, val) \ -do { \ - unsigned int _msr = (msr); \ - u64 _val = (val); \ - trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr), \ - (unsigned long long)(_val)); \ - native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32)); \ -} while (0) -#endif - /* * | NHM/WSM | SNB | * register ------------------------------- @@ -69,7 +57,7 @@ struct amd_nb { }; /* The maximal number of PEBS events: */ -#define MAX_PEBS_EVENTS 8 +#define MAX_PEBS_EVENTS 4 /* * A debug store configuration. @@ -129,7 +117,6 @@ struct cpu_hw_events { struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ unsigned int group_flag; - int is_fake; /* * Intel DebugStore bits @@ -361,8 +348,6 @@ struct x86_pmu { void (*cpu_starting)(int cpu); void (*cpu_dying)(int cpu); void (*cpu_dead)(int cpu); - - void (*check_microcode)(void); void (*flush_branch_stack)(void); /* @@ -374,16 +359,11 @@ struct x86_pmu { /* * Intel DebugStore bits */ - int bts :1, - bts_active :1, - pebs :1, - pebs_active :1, - pebs_broken :1; + int bts, pebs; + int bts_active, pebs_active; int pebs_record_size; void (*drain_pebs)(struct pt_regs *regs); struct event_constraint *pebs_constraints; - void (*pebs_aliases)(struct perf_event *event); - int max_pebs_events; /* * Intel LBR @@ -486,8 +466,6 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, void x86_pmu_enable_all(int added); -int perf_assign_events(struct event_constraint **constraints, int n, - int wmin, int wmax, int *assign); int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); void x86_pmu_stop(struct perf_event *event, int flags); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd.c b/trunk/arch/x86/kernel/cpu/perf_event_amd.c index 4528ae7b6ec4..11a4eb9131d5 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_amd.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_amd.c @@ -366,7 +366,7 @@ static void amd_pmu_cpu_starting(int cpu) cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY; - if (boot_cpu_data.x86_max_cores < 2) + if (boot_cpu_data.x86_max_cores < 2 || boot_cpu_data.x86 == 0x15) return; nb_id = amd_get_nb_id(cpu); @@ -422,6 +422,35 @@ static struct attribute *amd_format_attr[] = { NULL, }; +static __initconst const struct x86_pmu amd_pmu = { + .name = "AMD", + .handle_irq = x86_pmu_handle_irq, + .disable_all = x86_pmu_disable_all, + .enable_all = x86_pmu_enable_all, + .enable = x86_pmu_enable_event, + .disable = x86_pmu_disable_event, + .hw_config = amd_pmu_hw_config, + .schedule_events = x86_schedule_events, + .eventsel = MSR_K7_EVNTSEL0, + .perfctr = MSR_K7_PERFCTR0, + .event_map = amd_pmu_event_map, + .max_events = ARRAY_SIZE(amd_perfmon_event_map), + .num_counters = AMD64_NUM_COUNTERS, + .cntval_bits = 48, + .cntval_mask = (1ULL << 48) - 1, + .apic = 1, + /* use highest bit to detect overflow */ + .max_period = (1ULL << 47) - 1, + .get_event_constraints = amd_get_event_constraints, + .put_event_constraints = amd_put_event_constraints, + + .format_attrs = amd_format_attr, + + .cpu_prepare = amd_pmu_cpu_prepare, + .cpu_starting = amd_pmu_cpu_starting, + .cpu_dead = amd_pmu_cpu_dead, +}; + /* AMD Family 15h */ #define AMD_EVENT_TYPE_MASK 0x000000F0ULL @@ -568,8 +597,8 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev } } -static __initconst const struct x86_pmu amd_pmu = { - .name = "AMD", +static __initconst const struct x86_pmu amd_pmu_f15h = { + .name = "AMD Family 15h", .handle_irq = x86_pmu_handle_irq, .disable_all = x86_pmu_disable_all, .enable_all = x86_pmu_enable_all, @@ -577,68 +606,50 @@ static __initconst const struct x86_pmu amd_pmu = { .disable = x86_pmu_disable_event, .hw_config = amd_pmu_hw_config, .schedule_events = x86_schedule_events, - .eventsel = MSR_K7_EVNTSEL0, - .perfctr = MSR_K7_PERFCTR0, + .eventsel = MSR_F15H_PERF_CTL, + .perfctr = MSR_F15H_PERF_CTR, .event_map = amd_pmu_event_map, .max_events = ARRAY_SIZE(amd_perfmon_event_map), - .num_counters = AMD64_NUM_COUNTERS, + .num_counters = AMD64_NUM_COUNTERS_F15H, .cntval_bits = 48, .cntval_mask = (1ULL << 48) - 1, .apic = 1, /* use highest bit to detect overflow */ .max_period = (1ULL << 47) - 1, - .get_event_constraints = amd_get_event_constraints, + .get_event_constraints = amd_get_event_constraints_f15h, + /* nortbridge counters not yet implemented: */ +#if 0 .put_event_constraints = amd_put_event_constraints, - .format_attrs = amd_format_attr, - .cpu_prepare = amd_pmu_cpu_prepare, - .cpu_starting = amd_pmu_cpu_starting, .cpu_dead = amd_pmu_cpu_dead, +#endif + .cpu_starting = amd_pmu_cpu_starting, + .format_attrs = amd_format_attr, }; -static int setup_event_constraints(void) -{ - if (boot_cpu_data.x86 >= 0x15) - x86_pmu.get_event_constraints = amd_get_event_constraints_f15h; - return 0; -} - -static int setup_perfctr_core(void) -{ - if (!cpu_has_perfctr_core) { - WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h, - KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!"); - return -ENODEV; - } - - WARN(x86_pmu.get_event_constraints == amd_get_event_constraints, - KERN_ERR "hw perf events core counters need constraints handler!"); - - /* - * If core performance counter extensions exists, we must use - * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also - * x86_pmu_addr_offset(). - */ - x86_pmu.eventsel = MSR_F15H_PERF_CTL; - x86_pmu.perfctr = MSR_F15H_PERF_CTR; - x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE; - - printk(KERN_INFO "perf: AMD core performance counters detected\n"); - - return 0; -} - __init int amd_pmu_init(void) { /* Performance-monitoring supported from K7 and later: */ if (boot_cpu_data.x86 < 6) return -ENODEV; - x86_pmu = amd_pmu; - - setup_event_constraints(); - setup_perfctr_core(); + /* + * If core performance counter extensions exists, it must be + * family 15h, otherwise fail. See x86_pmu_addr_offset(). + */ + switch (boot_cpu_data.x86) { + case 0x15: + if (!cpu_has_perfctr_core) + return -ENODEV; + x86_pmu = amd_pmu_f15h; + break; + default: + if (cpu_has_perfctr_core) + return -ENODEV; + x86_pmu = amd_pmu; + break; + } /* Events are common for all AMDs */ memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index 7a8b9d0abcaa..166546ec6aef 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -5,8 +5,6 @@ * among events on a single PMU. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -23,14 +21,14 @@ */ static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = { - [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, - [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, - [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, - [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, - [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, - [PERF_COUNT_HW_BUS_CYCLES] = 0x013c, - [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */ + [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, + [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, + [PERF_COUNT_HW_BUS_CYCLES] = 0x013c, + [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */ }; static struct event_constraint intel_core_event_constraints[] __read_mostly = @@ -749,7 +747,7 @@ static void intel_pmu_disable_all(void) wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); - if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) + if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) intel_pmu_disable_bts(); intel_pmu_pebs_disable_all(); @@ -765,9 +763,9 @@ static void intel_pmu_enable_all(int added) wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); - if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { + if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { struct perf_event *event = - cpuc->events[INTEL_PMC_IDX_FIXED_BTS]; + cpuc->events[X86_PMC_IDX_FIXED_BTS]; if (WARN_ON_ONCE(!event)) return; @@ -873,7 +871,7 @@ static inline void intel_pmu_ack_status(u64 ack) static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) { - int idx = hwc->idx - INTEL_PMC_IDX_FIXED; + int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, mask; mask = 0xfULL << (idx * 4); @@ -888,7 +886,7 @@ static void intel_pmu_disable_event(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) { + if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { intel_pmu_disable_bts(); intel_pmu_drain_bts_buffer(); return; @@ -917,7 +915,7 @@ static void intel_pmu_disable_event(struct perf_event *event) static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) { - int idx = hwc->idx - INTEL_PMC_IDX_FIXED; + int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, bits, mask; /* @@ -951,7 +949,7 @@ static void intel_pmu_enable_event(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) { + if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { if (!__this_cpu_read(cpu_hw_events.enabled)) return; @@ -1002,14 +1000,14 @@ static void intel_pmu_reset(void) local_irq_save(flags); - pr_info("clearing PMU state on CPU#%d\n", smp_processor_id()); + printk("clearing PMU state on CPU#%d\n", smp_processor_id()); for (idx = 0; idx < x86_pmu.num_counters; idx++) { - wrmsrl_safe(x86_pmu_config_addr(idx), 0ull); - wrmsrl_safe(x86_pmu_event_addr(idx), 0ull); + checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); + checking_wrmsrl(x86_pmu_event_addr(idx), 0ull); } for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) - wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); + checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); if (ds) ds->bts_index = ds->bts_buffer_base; @@ -1121,33 +1119,27 @@ intel_bts_constraints(struct perf_event *event) return NULL; } -static int intel_alt_er(int idx) +static bool intel_try_alt_er(struct perf_event *event, int orig_idx) { if (!(x86_pmu.er_flags & ERF_HAS_RSP_1)) - return idx; - - if (idx == EXTRA_REG_RSP_0) - return EXTRA_REG_RSP_1; - - if (idx == EXTRA_REG_RSP_1) - return EXTRA_REG_RSP_0; - - return idx; -} - -static void intel_fixup_er(struct perf_event *event, int idx) -{ - event->hw.extra_reg.idx = idx; + return false; - if (idx == EXTRA_REG_RSP_0) { - event->hw.config &= ~INTEL_ARCH_EVENT_MASK; - event->hw.config |= 0x01b7; - event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; - } else if (idx == EXTRA_REG_RSP_1) { + if (event->hw.extra_reg.idx == EXTRA_REG_RSP_0) { event->hw.config &= ~INTEL_ARCH_EVENT_MASK; event->hw.config |= 0x01bb; + event->hw.extra_reg.idx = EXTRA_REG_RSP_1; event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; + } else if (event->hw.extra_reg.idx == EXTRA_REG_RSP_1) { + event->hw.config &= ~INTEL_ARCH_EVENT_MASK; + event->hw.config |= 0x01b7; + event->hw.extra_reg.idx = EXTRA_REG_RSP_0; + event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; } + + if (event->hw.extra_reg.idx == orig_idx) + return false; + + return true; } /* @@ -1165,18 +1157,14 @@ __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, struct event_constraint *c = &emptyconstraint; struct er_account *era; unsigned long flags; - int idx = reg->idx; + int orig_idx = reg->idx; - /* - * reg->alloc can be set due to existing state, so for fake cpuc we - * need to ignore this, otherwise we might fail to allocate proper fake - * state for this extra reg constraint. Also see the comment below. - */ - if (reg->alloc && !cpuc->is_fake) + /* already allocated shared msr */ + if (reg->alloc) return NULL; /* call x86_get_event_constraint() */ again: - era = &cpuc->shared_regs->regs[idx]; + era = &cpuc->shared_regs->regs[reg->idx]; /* * we use spin_lock_irqsave() to avoid lockdep issues when * passing a fake cpuc @@ -1185,29 +1173,6 @@ __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, if (!atomic_read(&era->ref) || era->config == reg->config) { - /* - * If its a fake cpuc -- as per validate_{group,event}() we - * shouldn't touch event state and we can avoid doing so - * since both will only call get_event_constraints() once - * on each event, this avoids the need for reg->alloc. - * - * Not doing the ER fixup will only result in era->reg being - * wrong, but since we won't actually try and program hardware - * this isn't a problem either. - */ - if (!cpuc->is_fake) { - if (idx != reg->idx) - intel_fixup_er(event, idx); - - /* - * x86_schedule_events() can call get_event_constraints() - * multiple times on events in the case of incremental - * scheduling(). reg->alloc ensures we only do the ER - * allocation once. - */ - reg->alloc = 1; - } - /* lock in msr value */ era->config = reg->config; era->reg = reg->reg; @@ -1215,17 +1180,17 @@ __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, /* one more user */ atomic_inc(&era->ref); + /* no need to reallocate during incremental event scheduling */ + reg->alloc = 1; + /* * need to call x86_get_event_constraint() * to check if associated event has constraints */ c = NULL; - } else { - idx = intel_alt_er(idx); - if (idx != reg->idx) { - raw_spin_unlock_irqrestore(&era->lock, flags); - goto again; - } + } else if (intel_try_alt_er(event, orig_idx)) { + raw_spin_unlock_irqrestore(&era->lock, flags); + goto again; } raw_spin_unlock_irqrestore(&era->lock, flags); @@ -1239,14 +1204,11 @@ __intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc, struct er_account *era; /* - * Only put constraint if extra reg was actually allocated. Also takes - * care of event which do not use an extra shared reg. - * - * Also, if this is a fake cpuc we shouldn't touch any event state - * (reg->alloc) and we don't care about leaving inconsistent cpuc state - * either since it'll be thrown out. + * only put constraint if extra reg was actually + * allocated. Also takes care of event which do + * not use an extra shared reg */ - if (!reg->alloc || cpuc->is_fake) + if (!reg->alloc) return; era = &cpuc->shared_regs->regs[reg->idx]; @@ -1338,9 +1300,15 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc, intel_put_shared_regs_event_constraints(cpuc, event); } -static void intel_pebs_aliases_core2(struct perf_event *event) +static int intel_pmu_hw_config(struct perf_event *event) { - if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { + int ret = x86_pmu_hw_config(event); + + if (ret) + return ret; + + if (event->attr.precise_ip && + (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { /* * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P * (0x003c) so that we can use it with PEBS. @@ -1361,48 +1329,10 @@ static void intel_pebs_aliases_core2(struct perf_event *event) */ u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16); - alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); - event->hw.config = alt_config; - } -} - -static void intel_pebs_aliases_snb(struct perf_event *event) -{ - if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { - /* - * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P - * (0x003c) so that we can use it with PEBS. - * - * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't - * PEBS capable. However we can use UOPS_RETIRED.ALL - * (0x01c2), which is a PEBS capable event, to get the same - * count. - * - * UOPS_RETIRED.ALL counts the number of cycles that retires - * CNTMASK micro-ops. By setting CNTMASK to a value (16) - * larger than the maximum number of micro-ops that can be - * retired per cycle (4) and then inverting the condition, we - * count all cycles that retire 16 or less micro-ops, which - * is every cycle. - * - * Thereby we gain a PEBS capable cycle counter. - */ - u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16); alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); event->hw.config = alt_config; } -} - -static int intel_pmu_hw_config(struct perf_event *event) -{ - int ret = x86_pmu_hw_config(event); - - if (ret) - return ret; - - if (event->attr.precise_ip && x86_pmu.pebs_aliases) - x86_pmu.pebs_aliases(event); if (intel_pmu_needs_lbr_smpl(event)) { ret = intel_pmu_setup_lbr_filter(event); @@ -1677,7 +1607,6 @@ static __initconst const struct x86_pmu intel_pmu = { .max_period = (1ULL << 31) - 1, .get_event_constraints = intel_get_event_constraints, .put_event_constraints = intel_put_event_constraints, - .pebs_aliases = intel_pebs_aliases_core2, .format_attrs = intel_arch3_formats_attr, @@ -1709,61 +1638,16 @@ static __init void intel_clovertown_quirk(void) * But taken together it might just make sense to not enable PEBS on * these chips. */ - pr_warn("PEBS disabled due to CPU errata\n"); + printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); x86_pmu.pebs = 0; x86_pmu.pebs_constraints = NULL; } -static int intel_snb_pebs_broken(int cpu) -{ - u32 rev = UINT_MAX; /* default to broken for unknown models */ - - switch (cpu_data(cpu).x86_model) { - case 42: /* SNB */ - rev = 0x28; - break; - - case 45: /* SNB-EP */ - switch (cpu_data(cpu).x86_mask) { - case 6: rev = 0x618; break; - case 7: rev = 0x70c; break; - } - } - - return (cpu_data(cpu).microcode < rev); -} - -static void intel_snb_check_microcode(void) -{ - int pebs_broken = 0; - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) { - if ((pebs_broken = intel_snb_pebs_broken(cpu))) - break; - } - put_online_cpus(); - - if (pebs_broken == x86_pmu.pebs_broken) - return; - - /* - * Serialized by the microcode lock.. - */ - if (x86_pmu.pebs_broken) { - pr_info("PEBS enabled due to microcode update\n"); - x86_pmu.pebs_broken = 0; - } else { - pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n"); - x86_pmu.pebs_broken = 1; - } -} - static __init void intel_sandybridge_quirk(void) { - x86_pmu.check_microcode = intel_snb_check_microcode; - intel_snb_check_microcode(); + printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); + x86_pmu.pebs = 0; + x86_pmu.pebs_constraints = NULL; } static const struct { int id; char *name; } intel_arch_events_map[] __initconst = { @@ -1783,8 +1667,8 @@ static __init void intel_arch_events_quirk(void) /* disable event that reported as not presend by cpuid */ for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) { intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0; - pr_warn("CPUID marked event: \'%s\' unavailable\n", - intel_arch_events_map[bit].name); + printk(KERN_WARNING "CPUID marked event: \'%s\' unavailable\n", + intel_arch_events_map[bit].name); } } @@ -1803,7 +1687,7 @@ static __init void intel_nehalem_quirk(void) intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; ebx.split.no_branch_misses_retired = 0; x86_pmu.events_maskl = ebx.full; - pr_info("CPU erratum AAJ80 worked around\n"); + printk(KERN_INFO "CPU erratum AAJ80 worked around\n"); } } @@ -1812,7 +1696,6 @@ __init int intel_pmu_init(void) union cpuid10_edx edx; union cpuid10_eax eax; union cpuid10_ebx ebx; - struct event_constraint *c; unsigned int unused; int version; @@ -1848,8 +1731,6 @@ __init int intel_pmu_init(void) x86_pmu.events_maskl = ebx.full; x86_pmu.events_mask_len = eax.split.mask_length; - x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); - /* * Quirk: v2 perfmon does not report fixed-purpose events, so * assume at least 3 events: @@ -1959,9 +1840,8 @@ __init int intel_pmu_init(void) break; case 42: /* SandyBridge */ - case 45: /* SandyBridge, "Romely-EP" */ x86_add_quirk(intel_sandybridge_quirk); - case 58: /* IvyBridge */ + case 45: /* SandyBridge, "Romely-EP" */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -1969,7 +1849,6 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_snb_event_constraints; x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; - x86_pmu.pebs_aliases = intel_pebs_aliases_snb; x86_pmu.extra_regs = intel_snb_extra_regs; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; @@ -2001,37 +1880,5 @@ __init int intel_pmu_init(void) } } - if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { - WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", - x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC); - x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC; - } - x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; - - if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) { - WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", - x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED); - x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED; - } - - x86_pmu.intel_ctrl |= - ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED; - - if (x86_pmu.event_constraints) { - /* - * event on fixed counter2 (REF_CYCLES) only works on this - * counter, so do not extend mask to generic counters - */ - for_each_event_constraint(c, x86_pmu.event_constraints) { - if (c->cmask != X86_RAW_EVENT_MASK - || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) { - continue; - } - - c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; - c->weight += x86_pmu.num_counters; - } - } - return 0; } diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c index 629ae0b7ad90..5a3edc27f6e5 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -248,7 +248,7 @@ void reserve_ds_buffers(void) */ struct event_constraint bts_constraint = - EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0); + EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0); void intel_pmu_enable_bts(u64 config) { @@ -295,7 +295,7 @@ int intel_pmu_drain_bts_buffer(void) u64 to; u64 flags; }; - struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS]; + struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS]; struct bts_record *at, *top; struct perf_output_handle handle; struct perf_event_header header; @@ -400,7 +400,14 @@ struct event_constraint intel_snb_pebs_event_constraints[] = { INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ + INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS_LOADS */ + INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS_STORES */ + INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOP_RETIRED.LOCK_LOADS */ + INTEL_UEVENT_CONSTRAINT(0x22d0, 0xf), /* MEM_UOP_RETIRED.LOCK_STORES */ + INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOP_RETIRED.SPLIT_LOADS */ + INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf), /* MEM_UOP_RETIRED.SPLIT_STORES */ + INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOP_RETIRED.ANY_LOADS */ + INTEL_UEVENT_CONSTRAINT(0x82d0, 0xf), /* MEM_UOP_RETIRED.ANY_STORES */ INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ INTEL_UEVENT_CONSTRAINT(0x02d4, 0xf), /* MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS */ @@ -620,7 +627,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) * Should not happen, we program the threshold at 1 and do not * set a reset value. */ - WARN_ONCE(n > 1, "bad leftover pebs %d\n", n); + WARN_ON_ONCE(n > 1); at += n - 1; __intel_pmu_pebs_event(event, iregs, at); @@ -651,10 +658,10 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) * Should not happen, we program the threshold at 1 and do not * set a reset value. */ - WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n); + WARN_ON_ONCE(n > MAX_PEBS_EVENTS); for ( ; at < top; at++) { - for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) { + for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { event = cpuc->events[bit]; if (!test_bit(bit, cpuc->active_mask)) continue; @@ -670,7 +677,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) break; } - if (!event || bit >= x86_pmu.max_pebs_events) + if (!event || bit >= MAX_PEBS_EVENTS) continue; __intel_pmu_pebs_event(event, iregs, at); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c deleted file mode 100644 index 19faffc60886..000000000000 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ /dev/null @@ -1,1850 +0,0 @@ -#include "perf_event_intel_uncore.h" - -static struct intel_uncore_type *empty_uncore[] = { NULL, }; -static struct intel_uncore_type **msr_uncores = empty_uncore; -static struct intel_uncore_type **pci_uncores = empty_uncore; -/* pci bus to socket mapping */ -static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; - -static DEFINE_RAW_SPINLOCK(uncore_box_lock); - -/* mask of cpus that collect uncore events */ -static cpumask_t uncore_cpu_mask; - -/* constraint for the fixed counter */ -static struct event_constraint constraint_fixed = - EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL); -static struct event_constraint constraint_empty = - EVENT_CONSTRAINT(0, 0, 0); - -DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); -DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); -DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); -DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); -DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); -DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); -DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); -DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); -DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); -DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); -DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); -DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); -DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); -DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); -DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); -DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); -DEFINE_UNCORE_FORMAT_ATTR(filter_brand0, filter_brand0, "config1:0-7"); -DEFINE_UNCORE_FORMAT_ATTR(filter_brand1, filter_brand1, "config1:8-15"); -DEFINE_UNCORE_FORMAT_ATTR(filter_brand2, filter_brand2, "config1:16-23"); -DEFINE_UNCORE_FORMAT_ATTR(filter_brand3, filter_brand3, "config1:24-31"); - -/* Sandy Bridge-EP uncore support */ -static struct intel_uncore_type snbep_uncore_cbox; -static struct intel_uncore_type snbep_uncore_pcu; - -static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int box_ctl = uncore_pci_box_ctl(box); - u32 config; - - pci_read_config_dword(pdev, box_ctl, &config); - config |= SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); -} - -static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int box_ctl = uncore_pci_box_ctl(box); - u32 config; - - pci_read_config_dword(pdev, box_ctl, &config); - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); -} - -static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, hwc->config_base, hwc->config | - SNBEP_PMON_CTL_EN); -} - -static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, hwc->config_base, hwc->config); -} - -static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - u64 count; - - pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); - pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); - return count; -} - -static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, - SNBEP_PMON_BOX_CTL_INT); -} - -static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - u64 config; - unsigned msr; - - msr = uncore_msr_box_ctl(box); - if (msr) { - rdmsrl(msr, config); - config |= SNBEP_PMON_BOX_CTL_FRZ; - wrmsrl(msr, config); - return; - } -} - -static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - u64 config; - unsigned msr; - - msr = uncore_msr_box_ctl(box); - if (msr) { - rdmsrl(msr, config); - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - wrmsrl(msr, config); - return; - } -} - -static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - - if (reg1->idx != EXTRA_REG_NONE) - wrmsrl(reg1->reg, reg1->config); - - wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); -} - -static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - wrmsrl(hwc->config_base, hwc->config); -} - -static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - u64 count; - - rdmsrl(hwc->event_base, count); - return count; -} - -static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) -{ - unsigned msr = uncore_msr_box_ctl(box); - if (msr) - wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); -} - -static struct event_constraint * -snbep_uncore_get_constraint(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct intel_uncore_extra_reg *er; - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - unsigned long flags; - bool ok = false; - - if (reg1->idx == EXTRA_REG_NONE || (box->phys_id >= 0 && reg1->alloc)) - return NULL; - - er = &box->shared_regs[reg1->idx]; - raw_spin_lock_irqsave(&er->lock, flags); - if (!atomic_read(&er->ref) || er->config1 == reg1->config) { - atomic_inc(&er->ref); - er->config1 = reg1->config; - ok = true; - } - raw_spin_unlock_irqrestore(&er->lock, flags); - - if (ok) { - if (box->phys_id >= 0) - reg1->alloc = 1; - return NULL; - } - return &constraint_empty; -} - -static void snbep_uncore_put_constraint(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct intel_uncore_extra_reg *er; - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - - if (box->phys_id < 0 || !reg1->alloc) - return; - - er = &box->shared_regs[reg1->idx]; - atomic_dec(&er->ref); - reg1->alloc = 0; -} - -static int snbep_uncore_hw_config(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - - if (box->pmu->type == &snbep_uncore_cbox) { - reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + - SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; - reg1->config = event->attr.config1 & - SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; - } else if (box->pmu->type == &snbep_uncore_pcu) { - reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; - reg1->config = event->attr.config1 & - SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; - } else { - return 0; - } - reg1->idx = 0; - return 0; -} - -static struct attribute *snbep_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - NULL, -}; - -static struct attribute *snbep_uncore_ubox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - NULL, -}; - -static struct attribute *snbep_uncore_cbox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_tid_en.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - &format_attr_filter_tid.attr, - &format_attr_filter_nid.attr, - &format_attr_filter_state.attr, - &format_attr_filter_opc.attr, - NULL, -}; - -static struct attribute *snbep_uncore_pcu_formats_attr[] = { - &format_attr_event.attr, - &format_attr_occ_sel.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - &format_attr_occ_invert.attr, - &format_attr_occ_edge.attr, - &format_attr_filter_brand0.attr, - &format_attr_filter_brand1.attr, - &format_attr_filter_brand2.attr, - &format_attr_filter_brand3.attr, - NULL, -}; - -static struct uncore_event_desc snbep_uncore_imc_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), - INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"), - INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"), - { /* end: all zeroes */ }, -}; - -static struct uncore_event_desc snbep_uncore_qpi_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), - INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), - INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"), - INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"), - { /* end: all zeroes */ }, -}; - -static struct attribute_group snbep_uncore_format_group = { - .name = "format", - .attrs = snbep_uncore_formats_attr, -}; - -static struct attribute_group snbep_uncore_ubox_format_group = { - .name = "format", - .attrs = snbep_uncore_ubox_formats_attr, -}; - -static struct attribute_group snbep_uncore_cbox_format_group = { - .name = "format", - .attrs = snbep_uncore_cbox_formats_attr, -}; - -static struct attribute_group snbep_uncore_pcu_format_group = { - .name = "format", - .attrs = snbep_uncore_pcu_formats_attr, -}; - -static struct intel_uncore_ops snbep_uncore_msr_ops = { - .init_box = snbep_uncore_msr_init_box, - .disable_box = snbep_uncore_msr_disable_box, - .enable_box = snbep_uncore_msr_enable_box, - .disable_event = snbep_uncore_msr_disable_event, - .enable_event = snbep_uncore_msr_enable_event, - .read_counter = snbep_uncore_msr_read_counter, - .get_constraint = snbep_uncore_get_constraint, - .put_constraint = snbep_uncore_put_constraint, - .hw_config = snbep_uncore_hw_config, -}; - -static struct intel_uncore_ops snbep_uncore_pci_ops = { - .init_box = snbep_uncore_pci_init_box, - .disable_box = snbep_uncore_pci_disable_box, - .enable_box = snbep_uncore_pci_enable_box, - .disable_event = snbep_uncore_pci_disable_event, - .enable_event = snbep_uncore_pci_enable_event, - .read_counter = snbep_uncore_pci_read_counter, -}; - -static struct event_constraint snbep_uncore_cbox_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x01, 0x1), - UNCORE_EVENT_CONSTRAINT(0x02, 0x3), - UNCORE_EVENT_CONSTRAINT(0x04, 0x3), - UNCORE_EVENT_CONSTRAINT(0x05, 0x3), - UNCORE_EVENT_CONSTRAINT(0x07, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x1), - UNCORE_EVENT_CONSTRAINT(0x12, 0x3), - UNCORE_EVENT_CONSTRAINT(0x13, 0x3), - UNCORE_EVENT_CONSTRAINT(0x1b, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1c, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1d, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1e, 0xc), - EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff), - UNCORE_EVENT_CONSTRAINT(0x21, 0x3), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x31, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - UNCORE_EVENT_CONSTRAINT(0x35, 0x3), - UNCORE_EVENT_CONSTRAINT(0x36, 0x1), - UNCORE_EVENT_CONSTRAINT(0x37, 0x3), - UNCORE_EVENT_CONSTRAINT(0x38, 0x3), - UNCORE_EVENT_CONSTRAINT(0x39, 0x3), - UNCORE_EVENT_CONSTRAINT(0x3b, 0x1), - EVENT_CONSTRAINT_END -}; - -static struct event_constraint snbep_uncore_r2pcie_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x10, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x3), - UNCORE_EVENT_CONSTRAINT(0x12, 0x1), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x24, 0x3), - UNCORE_EVENT_CONSTRAINT(0x25, 0x3), - UNCORE_EVENT_CONSTRAINT(0x26, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - EVENT_CONSTRAINT_END -}; - -static struct event_constraint snbep_uncore_r3qpi_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x10, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x3), - UNCORE_EVENT_CONSTRAINT(0x12, 0x3), - UNCORE_EVENT_CONSTRAINT(0x13, 0x1), - UNCORE_EVENT_CONSTRAINT(0x20, 0x3), - UNCORE_EVENT_CONSTRAINT(0x21, 0x3), - UNCORE_EVENT_CONSTRAINT(0x22, 0x3), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x24, 0x3), - UNCORE_EVENT_CONSTRAINT(0x25, 0x3), - UNCORE_EVENT_CONSTRAINT(0x26, 0x3), - UNCORE_EVENT_CONSTRAINT(0x30, 0x3), - UNCORE_EVENT_CONSTRAINT(0x31, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - UNCORE_EVENT_CONSTRAINT(0x36, 0x3), - UNCORE_EVENT_CONSTRAINT(0x37, 0x3), - EVENT_CONSTRAINT_END -}; - -static struct intel_uncore_type snbep_uncore_ubox = { - .name = "ubox", - .num_counters = 2, - .num_boxes = 1, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNBEP_U_MSR_PMON_CTR0, - .event_ctl = SNBEP_U_MSR_PMON_CTL0, - .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, - .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, - .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_ubox_format_group, -}; - -static struct intel_uncore_type snbep_uncore_cbox = { - .name = "cbox", - .num_counters = 4, - .num_boxes = 8, - .perf_ctr_bits = 44, - .event_ctl = SNBEP_C0_MSR_PMON_CTL0, - .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, - .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, - .msr_offset = SNBEP_CBO_MSR_OFFSET, - .num_shared_regs = 1, - .constraints = snbep_uncore_cbox_constraints, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_cbox_format_group, -}; - -static struct intel_uncore_type snbep_uncore_pcu = { - .name = "pcu", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, - .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, - .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, - .num_shared_regs = 1, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_pcu_format_group, -}; - -static struct intel_uncore_type *snbep_msr_uncores[] = { - &snbep_uncore_ubox, - &snbep_uncore_cbox, - &snbep_uncore_pcu, - NULL, -}; - -#define SNBEP_UNCORE_PCI_COMMON_INIT() \ - .perf_ctr = SNBEP_PCI_PMON_CTR0, \ - .event_ctl = SNBEP_PCI_PMON_CTL0, \ - .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \ - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ - .ops = &snbep_uncore_pci_ops, \ - .format_group = &snbep_uncore_format_group - -static struct intel_uncore_type snbep_uncore_ha = { - .name = "ha", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_imc = { - .name = "imc", - .num_counters = 4, - .num_boxes = 4, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, - .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, - .event_descs = snbep_uncore_imc_events, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_qpi = { - .name = "qpi", - .num_counters = 4, - .num_boxes = 2, - .perf_ctr_bits = 48, - .event_descs = snbep_uncore_qpi_events, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - - -static struct intel_uncore_type snbep_uncore_r2pcie = { - .name = "r2pcie", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r2pcie_constraints, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_r3qpi = { - .name = "r3qpi", - .num_counters = 3, - .num_boxes = 2, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r3qpi_constraints, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type *snbep_pci_uncores[] = { - &snbep_uncore_ha, - &snbep_uncore_imc, - &snbep_uncore_qpi, - &snbep_uncore_r2pcie, - &snbep_uncore_r3qpi, - NULL, -}; - -static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { - { /* Home Agent */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), - .driver_data = (unsigned long)&snbep_uncore_ha, - }, - { /* MC Channel 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* MC Channel 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* MC Channel 2 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* MC Channel 3 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* QPI Port 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), - .driver_data = (unsigned long)&snbep_uncore_qpi, - }, - { /* QPI Port 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), - .driver_data = (unsigned long)&snbep_uncore_qpi, - }, - { /* P2PCIe */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), - .driver_data = (unsigned long)&snbep_uncore_r2pcie, - }, - { /* R3QPI Link 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), - .driver_data = (unsigned long)&snbep_uncore_r3qpi, - }, - { /* R3QPI Link 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), - .driver_data = (unsigned long)&snbep_uncore_r3qpi, - }, - { /* end: all zeroes */ } -}; - -static struct pci_driver snbep_uncore_pci_driver = { - .name = "snbep_uncore", - .id_table = snbep_uncore_pci_ids, -}; - -/* - * build pci bus to socket mapping - */ -static void snbep_pci2phy_map_init(void) -{ - struct pci_dev *ubox_dev = NULL; - int i, bus, nodeid; - u32 config; - - while (1) { - /* find the UBOX device */ - ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX, - ubox_dev); - if (!ubox_dev) - break; - bus = ubox_dev->bus->number; - /* get the Node ID of the local register */ - pci_read_config_dword(ubox_dev, 0x40, &config); - nodeid = config; - /* get the Node ID mapping */ - pci_read_config_dword(ubox_dev, 0x54, &config); - /* - * every three bits in the Node ID mapping register maps - * to a particular node. - */ - for (i = 0; i < 8; i++) { - if (nodeid == ((config >> (3 * i)) & 0x7)) { - pcibus_to_physid[bus] = i; - break; - } - } - }; - return; -} -/* end of Sandy Bridge-EP uncore support */ - - -/* Sandy Bridge uncore support */ -static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx < UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); - else - wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); -} - -static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - wrmsrl(event->hw.config_base, 0); -} - -static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - u64 count; - rdmsrl(event->hw.event_base, count); - return count; -} - -static void snb_uncore_msr_init_box(struct intel_uncore_box *box) -{ - if (box->pmu->pmu_idx == 0) { - wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, - SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL); - } -} - -static struct attribute *snb_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask5.attr, - NULL, -}; - -static struct attribute_group snb_uncore_format_group = { - .name = "format", - .attrs = snb_uncore_formats_attr, -}; - -static struct intel_uncore_ops snb_uncore_msr_ops = { - .init_box = snb_uncore_msr_init_box, - .disable_event = snb_uncore_msr_disable_event, - .enable_event = snb_uncore_msr_enable_event, - .read_counter = snb_uncore_msr_read_counter, -}; - -static struct event_constraint snb_uncore_cbox_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x80, 0x1), - UNCORE_EVENT_CONSTRAINT(0x83, 0x1), - EVENT_CONSTRAINT_END -}; - -static struct intel_uncore_type snb_uncore_cbox = { - .name = "cbox", - .num_counters = 2, - .num_boxes = 4, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, - .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, - .fixed_ctr = SNB_UNC_FIXED_CTR, - .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL, - .single_fixed = 1, - .event_mask = SNB_UNC_RAW_EVENT_MASK, - .msr_offset = SNB_UNC_CBO_MSR_OFFSET, - .constraints = snb_uncore_cbox_constraints, - .ops = &snb_uncore_msr_ops, - .format_group = &snb_uncore_format_group, -}; - -static struct intel_uncore_type *snb_msr_uncores[] = { - &snb_uncore_cbox, - NULL, -}; -/* end of Sandy Bridge uncore support */ - -/* Nehalem uncore support */ -static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0); -} - -static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, - NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); -} - -static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx < UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); - else - wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN); -} - -static struct attribute *nhm_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask8.attr, - NULL, -}; - -static struct attribute_group nhm_uncore_format_group = { - .name = "format", - .attrs = nhm_uncore_formats_attr, -}; - -static struct uncore_event_desc nhm_uncore_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), - INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"), - INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"), - INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"), - INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"), - INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"), - INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"), - INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"), - INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"), - { /* end: all zeroes */ }, -}; - -static struct intel_uncore_ops nhm_uncore_msr_ops = { - .disable_box = nhm_uncore_msr_disable_box, - .enable_box = nhm_uncore_msr_enable_box, - .disable_event = snb_uncore_msr_disable_event, - .enable_event = nhm_uncore_msr_enable_event, - .read_counter = snb_uncore_msr_read_counter, -}; - -static struct intel_uncore_type nhm_uncore = { - .name = "", - .num_counters = 8, - .num_boxes = 1, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .event_ctl = NHM_UNC_PERFEVTSEL0, - .perf_ctr = NHM_UNC_UNCORE_PMC0, - .fixed_ctr = NHM_UNC_FIXED_CTR, - .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL, - .event_mask = NHM_UNC_RAW_EVENT_MASK, - .event_descs = nhm_uncore_events, - .ops = &nhm_uncore_msr_ops, - .format_group = &nhm_uncore_format_group, -}; - -static struct intel_uncore_type *nhm_msr_uncores[] = { - &nhm_uncore, - NULL, -}; -/* end of Nehalem uncore support */ - -static void uncore_assign_hw_event(struct intel_uncore_box *box, - struct perf_event *event, int idx) -{ - struct hw_perf_event *hwc = &event->hw; - - hwc->idx = idx; - hwc->last_tag = ++box->tags[idx]; - - if (hwc->idx == UNCORE_PMC_IDX_FIXED) { - hwc->event_base = uncore_fixed_ctr(box); - hwc->config_base = uncore_fixed_ctl(box); - return; - } - - hwc->config_base = uncore_event_ctl(box, hwc->idx); - hwc->event_base = uncore_perf_ctr(box, hwc->idx); -} - -static void uncore_perf_event_update(struct intel_uncore_box *box, - struct perf_event *event) -{ - u64 prev_count, new_count, delta; - int shift; - - if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) - shift = 64 - uncore_fixed_ctr_bits(box); - else - shift = 64 - uncore_perf_ctr_bits(box); - - /* the hrtimer might modify the previous event value */ -again: - prev_count = local64_read(&event->hw.prev_count); - new_count = uncore_read_counter(box, event); - if (local64_xchg(&event->hw.prev_count, new_count) != prev_count) - goto again; - - delta = (new_count << shift) - (prev_count << shift); - delta >>= shift; - - local64_add(delta, &event->count); -} - -/* - * The overflow interrupt is unavailable for SandyBridge-EP, is broken - * for SandyBridge. So we use hrtimer to periodically poll the counter - * to avoid overflow. - */ -static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) -{ - struct intel_uncore_box *box; - unsigned long flags; - int bit; - - box = container_of(hrtimer, struct intel_uncore_box, hrtimer); - if (!box->n_active || box->cpu != smp_processor_id()) - return HRTIMER_NORESTART; - /* - * disable local interrupt to prevent uncore_pmu_event_start/stop - * to interrupt the update process - */ - local_irq_save(flags); - - for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX) - uncore_perf_event_update(box, box->events[bit]); - - local_irq_restore(flags); - - hrtimer_forward_now(hrtimer, ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL)); - return HRTIMER_RESTART; -} - -static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) -{ - __hrtimer_start_range_ns(&box->hrtimer, - ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL), 0, - HRTIMER_MODE_REL_PINNED, 0); -} - -static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box) -{ - hrtimer_cancel(&box->hrtimer); -} - -static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box) -{ - hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - box->hrtimer.function = uncore_pmu_hrtimer; -} - -struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, - int cpu) -{ - struct intel_uncore_box *box; - int i, size; - - size = sizeof(*box) + type->num_shared_regs * - sizeof(struct intel_uncore_extra_reg); - - box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); - if (!box) - return NULL; - - for (i = 0; i < type->num_shared_regs; i++) - raw_spin_lock_init(&box->shared_regs[i].lock); - - uncore_pmu_init_hrtimer(box); - atomic_set(&box->refcnt, 1); - box->cpu = -1; - box->phys_id = -1; - - return box; -} - -static struct intel_uncore_box * -uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) -{ - static struct intel_uncore_box *box; - - box = *per_cpu_ptr(pmu->box, cpu); - if (box) - return box; - - raw_spin_lock(&uncore_box_lock); - list_for_each_entry(box, &pmu->box_list, list) { - if (box->phys_id == topology_physical_package_id(cpu)) { - atomic_inc(&box->refcnt); - *per_cpu_ptr(pmu->box, cpu) = box; - break; - } - } - raw_spin_unlock(&uncore_box_lock); - - return *per_cpu_ptr(pmu->box, cpu); -} - -static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) -{ - return container_of(event->pmu, struct intel_uncore_pmu, pmu); -} - -static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) -{ - /* - * perf core schedules event on the basis of cpu, uncore events are - * collected by one of the cpus inside a physical package. - */ - return uncore_pmu_to_box(uncore_event_to_pmu(event), - smp_processor_id()); -} - -static int uncore_collect_events(struct intel_uncore_box *box, - struct perf_event *leader, bool dogrp) -{ - struct perf_event *event; - int n, max_count; - - max_count = box->pmu->type->num_counters; - if (box->pmu->type->fixed_ctl) - max_count++; - - if (box->n_events >= max_count) - return -EINVAL; - - n = box->n_events; - box->event_list[n] = leader; - n++; - if (!dogrp) - return n; - - list_for_each_entry(event, &leader->sibling_list, group_entry) { - if (event->state <= PERF_EVENT_STATE_OFF) - continue; - - if (n >= max_count) - return -EINVAL; - - box->event_list[n] = event; - n++; - } - return n; -} - -static struct event_constraint * -uncore_get_event_constraint(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct intel_uncore_type *type = box->pmu->type; - struct event_constraint *c; - - if (type->ops->get_constraint) { - c = type->ops->get_constraint(box, event); - if (c) - return c; - } - - if (event->hw.config == ~0ULL) - return &constraint_fixed; - - if (type->constraints) { - for_each_event_constraint(c, type->constraints) { - if ((event->hw.config & c->cmask) == c->code) - return c; - } - } - - return &type->unconstrainted; -} - -static void uncore_put_event_constraint(struct intel_uncore_box *box, - struct perf_event *event) -{ - if (box->pmu->type->ops->put_constraint) - box->pmu->type->ops->put_constraint(box, event); -} - -static int uncore_assign_events(struct intel_uncore_box *box, - int assign[], int n) -{ - unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; - struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; - int i, wmin, wmax, ret = 0; - struct hw_perf_event *hwc; - - bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); - - for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { - c = uncore_get_event_constraint(box, box->event_list[i]); - constraints[i] = c; - wmin = min(wmin, c->weight); - wmax = max(wmax, c->weight); - } - - /* fastpath, try to reuse previous register */ - for (i = 0; i < n; i++) { - hwc = &box->event_list[i]->hw; - c = constraints[i]; - - /* never assigned */ - if (hwc->idx == -1) - break; - - /* constraint still honored */ - if (!test_bit(hwc->idx, c->idxmsk)) - break; - - /* not already used */ - if (test_bit(hwc->idx, used_mask)) - break; - - __set_bit(hwc->idx, used_mask); - if (assign) - assign[i] = hwc->idx; - } - /* slow path */ - if (i != n) - ret = perf_assign_events(constraints, n, wmin, wmax, assign); - - if (!assign || ret) { - for (i = 0; i < n; i++) - uncore_put_event_constraint(box, box->event_list[i]); - } - return ret ? -EINVAL : 0; -} - -static void uncore_pmu_event_start(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - int idx = event->hw.idx; - - if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) - return; - - if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX)) - return; - - event->hw.state = 0; - box->events[idx] = event; - box->n_active++; - __set_bit(idx, box->active_mask); - - local64_set(&event->hw.prev_count, uncore_read_counter(box, event)); - uncore_enable_event(box, event); - - if (box->n_active == 1) { - uncore_enable_box(box); - uncore_pmu_start_hrtimer(box); - } -} - -static void uncore_pmu_event_stop(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - struct hw_perf_event *hwc = &event->hw; - - if (__test_and_clear_bit(hwc->idx, box->active_mask)) { - uncore_disable_event(box, event); - box->n_active--; - box->events[hwc->idx] = NULL; - WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); - hwc->state |= PERF_HES_STOPPED; - - if (box->n_active == 0) { - uncore_disable_box(box); - uncore_pmu_cancel_hrtimer(box); - } - } - - if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { - /* - * Drain the remaining delta count out of a event - * that we are disabling: - */ - uncore_perf_event_update(box, event); - hwc->state |= PERF_HES_UPTODATE; - } -} - -static int uncore_pmu_event_add(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - struct hw_perf_event *hwc = &event->hw; - int assign[UNCORE_PMC_IDX_MAX]; - int i, n, ret; - - if (!box) - return -ENODEV; - - ret = n = uncore_collect_events(box, event, false); - if (ret < 0) - return ret; - - hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; - if (!(flags & PERF_EF_START)) - hwc->state |= PERF_HES_ARCH; - - ret = uncore_assign_events(box, assign, n); - if (ret) - return ret; - - /* save events moving to new counters */ - for (i = 0; i < box->n_events; i++) { - event = box->event_list[i]; - hwc = &event->hw; - - if (hwc->idx == assign[i] && - hwc->last_tag == box->tags[assign[i]]) - continue; - /* - * Ensure we don't accidentally enable a stopped - * counter simply because we rescheduled. - */ - if (hwc->state & PERF_HES_STOPPED) - hwc->state |= PERF_HES_ARCH; - - uncore_pmu_event_stop(event, PERF_EF_UPDATE); - } - - /* reprogram moved events into new counters */ - for (i = 0; i < n; i++) { - event = box->event_list[i]; - hwc = &event->hw; - - if (hwc->idx != assign[i] || - hwc->last_tag != box->tags[assign[i]]) - uncore_assign_hw_event(box, event, assign[i]); - else if (i < box->n_events) - continue; - - if (hwc->state & PERF_HES_ARCH) - continue; - - uncore_pmu_event_start(event, 0); - } - box->n_events = n; - - return 0; -} - -static void uncore_pmu_event_del(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - int i; - - uncore_pmu_event_stop(event, PERF_EF_UPDATE); - - for (i = 0; i < box->n_events; i++) { - if (event == box->event_list[i]) { - uncore_put_event_constraint(box, event); - - while (++i < box->n_events) - box->event_list[i - 1] = box->event_list[i]; - - --box->n_events; - break; - } - } - - event->hw.idx = -1; - event->hw.last_tag = ~0ULL; -} - -static void uncore_pmu_event_read(struct perf_event *event) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - uncore_perf_event_update(box, event); -} - -/* - * validation ensures the group can be loaded onto the - * PMU if it was the only group available. - */ -static int uncore_validate_group(struct intel_uncore_pmu *pmu, - struct perf_event *event) -{ - struct perf_event *leader = event->group_leader; - struct intel_uncore_box *fake_box; - int ret = -EINVAL, n; - - fake_box = uncore_alloc_box(pmu->type, smp_processor_id()); - if (!fake_box) - return -ENOMEM; - - fake_box->pmu = pmu; - /* - * the event is not yet connected with its - * siblings therefore we must first collect - * existing siblings, then add the new event - * before we can simulate the scheduling - */ - n = uncore_collect_events(fake_box, leader, true); - if (n < 0) - goto out; - - fake_box->n_events = n; - n = uncore_collect_events(fake_box, event, false); - if (n < 0) - goto out; - - fake_box->n_events = n; - - ret = uncore_assign_events(fake_box, NULL, n); -out: - kfree(fake_box); - return ret; -} - -int uncore_pmu_event_init(struct perf_event *event) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - struct hw_perf_event *hwc = &event->hw; - int ret; - - if (event->attr.type != event->pmu->type) - return -ENOENT; - - pmu = uncore_event_to_pmu(event); - /* no device found for this pmu */ - if (pmu->func_id < 0) - return -ENOENT; - - /* - * Uncore PMU does measure at all privilege level all the time. - * So it doesn't make sense to specify any exclude bits. - */ - if (event->attr.exclude_user || event->attr.exclude_kernel || - event->attr.exclude_hv || event->attr.exclude_idle) - return -EINVAL; - - /* Sampling not supported yet */ - if (hwc->sample_period) - return -EINVAL; - - /* - * Place all uncore events for a particular physical package - * onto a single cpu - */ - if (event->cpu < 0) - return -EINVAL; - box = uncore_pmu_to_box(pmu, event->cpu); - if (!box || box->cpu < 0) - return -EINVAL; - event->cpu = box->cpu; - - event->hw.idx = -1; - event->hw.last_tag = ~0ULL; - event->hw.extra_reg.idx = EXTRA_REG_NONE; - - if (event->attr.config == UNCORE_FIXED_EVENT) { - /* no fixed counter */ - if (!pmu->type->fixed_ctl) - return -EINVAL; - /* - * if there is only one fixed counter, only the first pmu - * can access the fixed counter - */ - if (pmu->type->single_fixed && pmu->pmu_idx > 0) - return -EINVAL; - hwc->config = ~0ULL; - } else { - hwc->config = event->attr.config & pmu->type->event_mask; - if (pmu->type->ops->hw_config) { - ret = pmu->type->ops->hw_config(box, event); - if (ret) - return ret; - } - } - - if (event->group_leader != event) - ret = uncore_validate_group(pmu, event); - else - ret = 0; - - return ret; -} - -static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) -{ - int ret; - - pmu->pmu = (struct pmu) { - .attr_groups = pmu->type->attr_groups, - .task_ctx_nr = perf_invalid_context, - .event_init = uncore_pmu_event_init, - .add = uncore_pmu_event_add, - .del = uncore_pmu_event_del, - .start = uncore_pmu_event_start, - .stop = uncore_pmu_event_stop, - .read = uncore_pmu_event_read, - }; - - if (pmu->type->num_boxes == 1) { - if (strlen(pmu->type->name) > 0) - sprintf(pmu->name, "uncore_%s", pmu->type->name); - else - sprintf(pmu->name, "uncore"); - } else { - sprintf(pmu->name, "uncore_%s_%d", pmu->type->name, - pmu->pmu_idx); - } - - ret = perf_pmu_register(&pmu->pmu, pmu->name, -1); - return ret; -} - -static void __init uncore_type_exit(struct intel_uncore_type *type) -{ - int i; - - for (i = 0; i < type->num_boxes; i++) - free_percpu(type->pmus[i].box); - kfree(type->pmus); - type->pmus = NULL; - kfree(type->attr_groups[1]); - type->attr_groups[1] = NULL; -} - -static void uncore_types_exit(struct intel_uncore_type **types) -{ - int i; - for (i = 0; types[i]; i++) - uncore_type_exit(types[i]); -} - -static int __init uncore_type_init(struct intel_uncore_type *type) -{ - struct intel_uncore_pmu *pmus; - struct attribute_group *events_group; - struct attribute **attrs; - int i, j; - - pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL); - if (!pmus) - return -ENOMEM; - - type->unconstrainted = (struct event_constraint) - __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, - 0, type->num_counters, 0); - - for (i = 0; i < type->num_boxes; i++) { - pmus[i].func_id = -1; - pmus[i].pmu_idx = i; - pmus[i].type = type; - INIT_LIST_HEAD(&pmus[i].box_list); - pmus[i].box = alloc_percpu(struct intel_uncore_box *); - if (!pmus[i].box) - goto fail; - } - - if (type->event_descs) { - i = 0; - while (type->event_descs[i].attr.attr.name) - i++; - - events_group = kzalloc(sizeof(struct attribute *) * (i + 1) + - sizeof(*events_group), GFP_KERNEL); - if (!events_group) - goto fail; - - attrs = (struct attribute **)(events_group + 1); - events_group->name = "events"; - events_group->attrs = attrs; - - for (j = 0; j < i; j++) - attrs[j] = &type->event_descs[j].attr.attr; - - type->attr_groups[1] = events_group; - } - - type->pmus = pmus; - return 0; -fail: - uncore_type_exit(type); - return -ENOMEM; -} - -static int __init uncore_types_init(struct intel_uncore_type **types) -{ - int i, ret; - - for (i = 0; types[i]; i++) { - ret = uncore_type_init(types[i]); - if (ret) - goto fail; - } - return 0; -fail: - while (--i >= 0) - uncore_type_exit(types[i]); - return ret; -} - -static struct pci_driver *uncore_pci_driver; -static bool pcidrv_registered; - -/* - * add a pci uncore device - */ -static int __devinit uncore_pci_add(struct intel_uncore_type *type, - struct pci_dev *pdev) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, phys_id; - - phys_id = pcibus_to_physid[pdev->bus->number]; - if (phys_id < 0) - return -ENODEV; - - box = uncore_alloc_box(type, 0); - if (!box) - return -ENOMEM; - - /* - * for performance monitoring unit with multiple boxes, - * each box has a different function id. - */ - for (i = 0; i < type->num_boxes; i++) { - pmu = &type->pmus[i]; - if (pmu->func_id == pdev->devfn) - break; - if (pmu->func_id < 0) { - pmu->func_id = pdev->devfn; - break; - } - pmu = NULL; - } - - if (!pmu) { - kfree(box); - return -EINVAL; - } - - box->phys_id = phys_id; - box->pci_dev = pdev; - box->pmu = pmu; - uncore_box_init(box); - pci_set_drvdata(pdev, box); - - raw_spin_lock(&uncore_box_lock); - list_add_tail(&box->list, &pmu->box_list); - raw_spin_unlock(&uncore_box_lock); - - return 0; -} - -static void uncore_pci_remove(struct pci_dev *pdev) -{ - struct intel_uncore_box *box = pci_get_drvdata(pdev); - struct intel_uncore_pmu *pmu = box->pmu; - int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; - - if (WARN_ON_ONCE(phys_id != box->phys_id)) - return; - - raw_spin_lock(&uncore_box_lock); - list_del(&box->list); - raw_spin_unlock(&uncore_box_lock); - - for_each_possible_cpu(cpu) { - if (*per_cpu_ptr(pmu->box, cpu) == box) { - *per_cpu_ptr(pmu->box, cpu) = NULL; - atomic_dec(&box->refcnt); - } - } - - WARN_ON_ONCE(atomic_read(&box->refcnt) != 1); - kfree(box); -} - -static int __devinit uncore_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct intel_uncore_type *type; - - type = (struct intel_uncore_type *)id->driver_data; - return uncore_pci_add(type, pdev); -} - -static int __init uncore_pci_init(void) -{ - int ret; - - switch (boot_cpu_data.x86_model) { - case 45: /* Sandy Bridge-EP */ - pci_uncores = snbep_pci_uncores; - uncore_pci_driver = &snbep_uncore_pci_driver; - snbep_pci2phy_map_init(); - break; - default: - return 0; - } - - ret = uncore_types_init(pci_uncores); - if (ret) - return ret; - - uncore_pci_driver->probe = uncore_pci_probe; - uncore_pci_driver->remove = uncore_pci_remove; - - ret = pci_register_driver(uncore_pci_driver); - if (ret == 0) - pcidrv_registered = true; - else - uncore_types_exit(pci_uncores); - - return ret; -} - -static void __init uncore_pci_exit(void) -{ - if (pcidrv_registered) { - pcidrv_registered = false; - pci_unregister_driver(uncore_pci_driver); - uncore_types_exit(pci_uncores); - } -} - -static void __cpuinit uncore_cpu_dying(int cpu) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, j; - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - box = *per_cpu_ptr(pmu->box, cpu); - *per_cpu_ptr(pmu->box, cpu) = NULL; - if (box && atomic_dec_and_test(&box->refcnt)) - kfree(box); - } - } -} - -static int __cpuinit uncore_cpu_starting(int cpu) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box, *exist; - int i, j, k, phys_id; - - phys_id = topology_physical_package_id(cpu); - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - box = *per_cpu_ptr(pmu->box, cpu); - /* called by uncore_cpu_init? */ - if (box && box->phys_id >= 0) { - uncore_box_init(box); - continue; - } - - for_each_online_cpu(k) { - exist = *per_cpu_ptr(pmu->box, k); - if (exist && exist->phys_id == phys_id) { - atomic_inc(&exist->refcnt); - *per_cpu_ptr(pmu->box, cpu) = exist; - kfree(box); - box = NULL; - break; - } - } - - if (box) { - box->phys_id = phys_id; - uncore_box_init(box); - } - } - } - return 0; -} - -static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, j; - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - if (pmu->func_id < 0) - pmu->func_id = j; - - box = uncore_alloc_box(type, cpu); - if (!box) - return -ENOMEM; - - box->pmu = pmu; - box->phys_id = phys_id; - *per_cpu_ptr(pmu->box, cpu) = box; - } - } - return 0; -} - -static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores, - int old_cpu, int new_cpu) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, j; - - for (i = 0; uncores[i]; i++) { - type = uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - if (old_cpu < 0) - box = uncore_pmu_to_box(pmu, new_cpu); - else - box = uncore_pmu_to_box(pmu, old_cpu); - if (!box) - continue; - - if (old_cpu < 0) { - WARN_ON_ONCE(box->cpu != -1); - box->cpu = new_cpu; - continue; - } - - WARN_ON_ONCE(box->cpu != old_cpu); - if (new_cpu >= 0) { - uncore_pmu_cancel_hrtimer(box); - perf_pmu_migrate_context(&pmu->pmu, - old_cpu, new_cpu); - box->cpu = new_cpu; - } else { - box->cpu = -1; - } - } - } -} - -static void __cpuinit uncore_event_exit_cpu(int cpu) -{ - int i, phys_id, target; - - /* if exiting cpu is used for collecting uncore events */ - if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask)) - return; - - /* find a new cpu to collect uncore events */ - phys_id = topology_physical_package_id(cpu); - target = -1; - for_each_online_cpu(i) { - if (i == cpu) - continue; - if (phys_id == topology_physical_package_id(i)) { - target = i; - break; - } - } - - /* migrate uncore events to the new cpu */ - if (target >= 0) - cpumask_set_cpu(target, &uncore_cpu_mask); - - uncore_change_context(msr_uncores, cpu, target); - uncore_change_context(pci_uncores, cpu, target); -} - -static void __cpuinit uncore_event_init_cpu(int cpu) -{ - int i, phys_id; - - phys_id = topology_physical_package_id(cpu); - for_each_cpu(i, &uncore_cpu_mask) { - if (phys_id == topology_physical_package_id(i)) - return; - } - - cpumask_set_cpu(cpu, &uncore_cpu_mask); - - uncore_change_context(msr_uncores, -1, cpu); - uncore_change_context(pci_uncores, -1, cpu); -} - -static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (long)hcpu; - - /* allocate/free data structure for uncore box */ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_UP_PREPARE: - uncore_cpu_prepare(cpu, -1); - break; - case CPU_STARTING: - uncore_cpu_starting(cpu); - break; - case CPU_UP_CANCELED: - case CPU_DYING: - uncore_cpu_dying(cpu); - break; - default: - break; - } - - /* select the cpu that collects uncore events */ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_DOWN_FAILED: - case CPU_STARTING: - uncore_event_init_cpu(cpu); - break; - case CPU_DOWN_PREPARE: - uncore_event_exit_cpu(cpu); - break; - default: - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block uncore_cpu_nb __cpuinitdata = { - .notifier_call = uncore_cpu_notifier, - /* - * to migrate uncore events, our notifier should be executed - * before perf core's notifier. - */ - .priority = CPU_PRI_PERF + 1, -}; - -static void __init uncore_cpu_setup(void *dummy) -{ - uncore_cpu_starting(smp_processor_id()); -} - -static int __init uncore_cpu_init(void) -{ - int ret, cpu, max_cores; - - max_cores = boot_cpu_data.x86_max_cores; - switch (boot_cpu_data.x86_model) { - case 26: /* Nehalem */ - case 30: - case 37: /* Westmere */ - case 44: - msr_uncores = nhm_msr_uncores; - break; - case 42: /* Sandy Bridge */ - if (snb_uncore_cbox.num_boxes > max_cores) - snb_uncore_cbox.num_boxes = max_cores; - msr_uncores = snb_msr_uncores; - break; - case 45: /* Sandy Birdge-EP */ - if (snbep_uncore_cbox.num_boxes > max_cores) - snbep_uncore_cbox.num_boxes = max_cores; - msr_uncores = snbep_msr_uncores; - break; - default: - return 0; - } - - ret = uncore_types_init(msr_uncores); - if (ret) - return ret; - - get_online_cpus(); - - for_each_online_cpu(cpu) { - int i, phys_id = topology_physical_package_id(cpu); - - for_each_cpu(i, &uncore_cpu_mask) { - if (phys_id == topology_physical_package_id(i)) { - phys_id = -1; - break; - } - } - if (phys_id < 0) - continue; - - uncore_cpu_prepare(cpu, phys_id); - uncore_event_init_cpu(cpu); - } - on_each_cpu(uncore_cpu_setup, NULL, 1); - - register_cpu_notifier(&uncore_cpu_nb); - - put_online_cpus(); - - return 0; -} - -static int __init uncore_pmus_register(void) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_type *type; - int i, j; - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - uncore_pmu_register(pmu); - } - } - - for (i = 0; pci_uncores[i]; i++) { - type = pci_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - uncore_pmu_register(pmu); - } - } - - return 0; -} - -static int __init intel_uncore_init(void) -{ - int ret; - - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return -ENODEV; - - ret = uncore_pci_init(); - if (ret) - goto fail; - ret = uncore_cpu_init(); - if (ret) { - uncore_pci_exit(); - goto fail; - } - - uncore_pmus_register(); - return 0; -fail: - return ret; -} -device_initcall(intel_uncore_init); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h deleted file mode 100644 index b13e9ea81def..000000000000 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ /dev/null @@ -1,424 +0,0 @@ -#include -#include -#include -#include -#include "perf_event.h" - -#define UNCORE_PMU_NAME_LEN 32 -#define UNCORE_BOX_HASH_SIZE 8 - -#define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) - -#define UNCORE_FIXED_EVENT 0xff -#define UNCORE_PMC_IDX_MAX_GENERIC 8 -#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC -#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) - -#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) - -/* SNB event control */ -#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff -#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 -#define SNB_UNC_CTL_EDGE_DET (1 << 18) -#define SNB_UNC_CTL_EN (1 << 22) -#define SNB_UNC_CTL_INVERT (1 << 23) -#define SNB_UNC_CTL_CMASK_MASK 0x1f000000 -#define NHM_UNC_CTL_CMASK_MASK 0xff000000 -#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0) - -#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ - SNB_UNC_CTL_UMASK_MASK | \ - SNB_UNC_CTL_EDGE_DET | \ - SNB_UNC_CTL_INVERT | \ - SNB_UNC_CTL_CMASK_MASK) - -#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ - SNB_UNC_CTL_UMASK_MASK | \ - SNB_UNC_CTL_EDGE_DET | \ - SNB_UNC_CTL_INVERT | \ - NHM_UNC_CTL_CMASK_MASK) - -/* SNB global control register */ -#define SNB_UNC_PERF_GLOBAL_CTL 0x391 -#define SNB_UNC_FIXED_CTR_CTRL 0x394 -#define SNB_UNC_FIXED_CTR 0x395 - -/* SNB uncore global control */ -#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1) -#define SNB_UNC_GLOBAL_CTL_EN (1 << 29) - -/* SNB Cbo register */ -#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700 -#define SNB_UNC_CBO_0_PER_CTR0 0x706 -#define SNB_UNC_CBO_MSR_OFFSET 0x10 - -/* NHM global control register */ -#define NHM_UNC_PERF_GLOBAL_CTL 0x391 -#define NHM_UNC_FIXED_CTR 0x394 -#define NHM_UNC_FIXED_CTR_CTRL 0x395 - -/* NHM uncore global control */ -#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1) -#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32) - -/* NHM uncore register */ -#define NHM_UNC_PERFEVTSEL0 0x3c0 -#define NHM_UNC_UNCORE_PMC0 0x3b0 - -/* SNB-EP Box level control */ -#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) -#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) -#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8) -#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16) -#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ - SNBEP_PMON_BOX_CTL_RST_CTRS | \ - SNBEP_PMON_BOX_CTL_FRZ_EN) -/* SNB-EP event control */ -#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff -#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 -#define SNBEP_PMON_CTL_RST (1 << 17) -#define SNBEP_PMON_CTL_EDGE_DET (1 << 18) -#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) /* only for QPI */ -#define SNBEP_PMON_CTL_EN (1 << 22) -#define SNBEP_PMON_CTL_INVERT (1 << 23) -#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 -#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_PMON_CTL_TRESH_MASK) - -/* SNB-EP Ubox event control */ -#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000 -#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_U_MSR_PMON_CTL_TRESH_MASK) - -#define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19) -#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \ - SNBEP_CBO_PMON_CTL_TID_EN) - -/* SNB-EP PCU event control */ -#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000 -#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000 -#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30) -#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31) -#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) - -/* SNB-EP pci control register */ -#define SNBEP_PCI_PMON_BOX_CTL 0xf4 -#define SNBEP_PCI_PMON_CTL0 0xd8 -/* SNB-EP pci counter register */ -#define SNBEP_PCI_PMON_CTR0 0xa0 - -/* SNB-EP home agent register */ -#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40 -#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44 -#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48 -/* SNB-EP memory controller register */ -#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0 -#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0 -/* SNB-EP QPI register */ -#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228 -#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c -#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238 -#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c - -/* SNB-EP Ubox register */ -#define SNBEP_U_MSR_PMON_CTR0 0xc16 -#define SNBEP_U_MSR_PMON_CTL0 0xc10 - -#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08 -#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09 - -/* SNB-EP Cbo register */ -#define SNBEP_C0_MSR_PMON_CTR0 0xd16 -#define SNBEP_C0_MSR_PMON_CTL0 0xd10 -#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 -#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 -#define SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK 0xfffffc1f -#define SNBEP_CBO_MSR_OFFSET 0x20 - -/* SNB-EP PCU register */ -#define SNBEP_PCU_MSR_PMON_CTR0 0xc36 -#define SNBEP_PCU_MSR_PMON_CTL0 0xc30 -#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24 -#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34 -#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff -#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc -#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd - -struct intel_uncore_ops; -struct intel_uncore_pmu; -struct intel_uncore_box; -struct uncore_event_desc; - -struct intel_uncore_type { - const char *name; - int num_counters; - int num_boxes; - int perf_ctr_bits; - int fixed_ctr_bits; - unsigned perf_ctr; - unsigned event_ctl; - unsigned event_mask; - unsigned fixed_ctr; - unsigned fixed_ctl; - unsigned box_ctl; - unsigned msr_offset; - unsigned num_shared_regs:8; - unsigned single_fixed:1; - struct event_constraint unconstrainted; - struct event_constraint *constraints; - struct intel_uncore_pmu *pmus; - struct intel_uncore_ops *ops; - struct uncore_event_desc *event_descs; - const struct attribute_group *attr_groups[3]; -}; - -#define format_group attr_groups[0] - -struct intel_uncore_ops { - void (*init_box)(struct intel_uncore_box *); - void (*disable_box)(struct intel_uncore_box *); - void (*enable_box)(struct intel_uncore_box *); - void (*disable_event)(struct intel_uncore_box *, struct perf_event *); - void (*enable_event)(struct intel_uncore_box *, struct perf_event *); - u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *); - int (*hw_config)(struct intel_uncore_box *, struct perf_event *); - struct event_constraint *(*get_constraint)(struct intel_uncore_box *, - struct perf_event *); - void (*put_constraint)(struct intel_uncore_box *, struct perf_event *); -}; - -struct intel_uncore_pmu { - struct pmu pmu; - char name[UNCORE_PMU_NAME_LEN]; - int pmu_idx; - int func_id; - struct intel_uncore_type *type; - struct intel_uncore_box ** __percpu box; - struct list_head box_list; -}; - -struct intel_uncore_extra_reg { - raw_spinlock_t lock; - u64 config1; - atomic_t ref; -}; - -struct intel_uncore_box { - int phys_id; - int n_active; /* number of active events */ - int n_events; - int cpu; /* cpu to collect events */ - unsigned long flags; - atomic_t refcnt; - struct perf_event *events[UNCORE_PMC_IDX_MAX]; - struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; - unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; - u64 tags[UNCORE_PMC_IDX_MAX]; - struct pci_dev *pci_dev; - struct intel_uncore_pmu *pmu; - struct hrtimer hrtimer; - struct list_head list; - struct intel_uncore_extra_reg shared_regs[0]; -}; - -#define UNCORE_BOX_FLAG_INITIATED 0 - -struct uncore_event_desc { - struct kobj_attribute attr; - const char *config; -}; - -#define INTEL_UNCORE_EVENT_DESC(_name, _config) \ -{ \ - .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \ - .config = _config, \ -} - -#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ -static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, \ - char *page) \ -{ \ - BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ - return sprintf(page, _format "\n"); \ -} \ -static struct kobj_attribute format_attr_##_var = \ - __ATTR(_name, 0444, __uncore_##_var##_show, NULL) - - -static ssize_t uncore_event_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct uncore_event_desc *event = - container_of(attr, struct uncore_event_desc, attr); - return sprintf(buf, "%s", event->config); -} - -static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box) -{ - return box->pmu->type->box_ctl; -} - -static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctl; -} - -static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctr; -} - -static inline -unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx) -{ - return idx * 4 + box->pmu->type->event_ctl; -} - -static inline -unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx) -{ - return idx * 8 + box->pmu->type->perf_ctr; -} - -static inline -unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) -{ - if (!box->pmu->type->box_ctl) - return 0; - return box->pmu->type->box_ctl + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) -{ - if (!box->pmu->type->fixed_ctl) - return 0; - return box->pmu->type->fixed_ctl + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctr + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) -{ - return idx + box->pmu->type->event_ctl + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) -{ - return idx + box->pmu->type->perf_ctr + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_fixed_ctl(struct intel_uncore_box *box) -{ - if (box->pci_dev) - return uncore_pci_fixed_ctl(box); - else - return uncore_msr_fixed_ctl(box); -} - -static inline -unsigned uncore_fixed_ctr(struct intel_uncore_box *box) -{ - if (box->pci_dev) - return uncore_pci_fixed_ctr(box); - else - return uncore_msr_fixed_ctr(box); -} - -static inline -unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx) -{ - if (box->pci_dev) - return uncore_pci_event_ctl(box, idx); - else - return uncore_msr_event_ctl(box, idx); -} - -static inline -unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx) -{ - if (box->pci_dev) - return uncore_pci_perf_ctr(box, idx); - else - return uncore_msr_perf_ctr(box, idx); -} - -static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box) -{ - return box->pmu->type->perf_ctr_bits; -} - -static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctr_bits; -} - -static inline int uncore_num_counters(struct intel_uncore_box *box) -{ - return box->pmu->type->num_counters; -} - -static inline void uncore_disable_box(struct intel_uncore_box *box) -{ - if (box->pmu->type->ops->disable_box) - box->pmu->type->ops->disable_box(box); -} - -static inline void uncore_enable_box(struct intel_uncore_box *box) -{ - if (box->pmu->type->ops->enable_box) - box->pmu->type->ops->enable_box(box); -} - -static inline void uncore_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - box->pmu->type->ops->disable_event(box, event); -} - -static inline void uncore_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - box->pmu->type->ops->enable_event(box, event); -} - -static inline u64 uncore_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - return box->pmu->type->ops->read_counter(box, event); -} - -static inline void uncore_box_init(struct intel_uncore_box *box) -{ - if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { - if (box->pmu->type->ops->init_box) - box->pmu->type->ops->init_box(box); - } -} diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p4.c b/trunk/arch/x86/kernel/cpu/perf_event_p4.c index 92c7e39a079f..47124a73dd73 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p4.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p4.c @@ -895,8 +895,8 @@ static void p4_pmu_disable_pebs(void) * So at moment let leave metrics turned on forever -- it's * ok for now but need to be revisited! * - * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)0); - * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)0); + * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0); + * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0); */ } @@ -909,7 +909,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) * state we need to clear P4_CCCR_OVF, otherwise interrupt get * asserted again and again */ - (void)wrmsrl_safe(hwc->config_base, + (void)checking_wrmsrl(hwc->config_base, (u64)(p4_config_unpack_cccr(hwc->config)) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); } @@ -943,8 +943,8 @@ static void p4_pmu_enable_pebs(u64 config) bind = &p4_pebs_bind_map[idx]; - (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); - (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); + (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); + (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); } static void p4_pmu_enable_event(struct perf_event *event) @@ -978,8 +978,8 @@ static void p4_pmu_enable_event(struct perf_event *event) */ p4_pmu_enable_pebs(hwc->config); - (void)wrmsrl_safe(escr_addr, escr_conf); - (void)wrmsrl_safe(hwc->config_base, + (void)checking_wrmsrl(escr_addr, escr_conf); + (void)checking_wrmsrl(hwc->config_base, (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); } @@ -1325,7 +1325,7 @@ __init int p4_pmu_init(void) unsigned int low, high; /* If we get stripped -- indexing fails */ - BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC); + BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC); rdmsr(MSR_IA32_MISC_ENABLE, low, high); if (!(low & (1 << 7))) { diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p6.c b/trunk/arch/x86/kernel/cpu/perf_event_p6.c index e4dd0f7a0453..32bcfc7dd230 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p6.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p6.c @@ -71,7 +71,7 @@ p6_pmu_disable_event(struct perf_event *event) if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)wrmsrl_safe(hwc->config_base, val); + (void)checking_wrmsrl(hwc->config_base, val); } static void p6_pmu_enable_event(struct perf_event *event) @@ -84,7 +84,7 @@ static void p6_pmu_enable_event(struct perf_event *event) if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)wrmsrl_safe(hwc->config_base, val); + (void)checking_wrmsrl(hwc->config_base, val); } PMU_FORMAT_ATTR(event, "config:0-7" ); diff --git a/trunk/arch/x86/kernel/cpu/scattered.c b/trunk/arch/x86/kernel/cpu/scattered.c index ee8e9abc859f..addf9e82a7f2 100644 --- a/trunk/arch/x86/kernel/cpu/scattered.c +++ b/trunk/arch/x86/kernel/cpu/scattered.c @@ -31,7 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { - { X86_FEATURE_DTHERM, CR_EAX, 0, 0x00000006, 0 }, + { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c index ae42418bc50f..571246d81edf 100644 --- a/trunk/arch/x86/kernel/dumpstack.c +++ b/trunk/arch/x86/kernel/dumpstack.c @@ -27,8 +27,8 @@ static int die_counter; void printk_address(unsigned long address, int reliable) { - pr_cont(" [<%p>] %s%pB\n", - (void *)address, reliable ? "" : "? ", (void *)address); + printk(" [<%p>] %s%pB\n", (void *) address, + reliable ? "" : "? ", (void *) address); } #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -271,7 +271,6 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) return 1; - print_modules(); show_regs(regs); #ifdef CONFIG_X86_32 if (user_mode_vm(regs)) { diff --git a/trunk/arch/x86/kernel/dumpstack_32.c b/trunk/arch/x86/kernel/dumpstack_32.c index 1038a417ea53..e0b1d783daab 100644 --- a/trunk/arch/x86/kernel/dumpstack_32.c +++ b/trunk/arch/x86/kernel/dumpstack_32.c @@ -73,11 +73,11 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, if (kstack_end(stack)) break; if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - pr_cont("\n"); - pr_cont(" %08lx", *stack++); + printk(KERN_CONT "\n"); + printk(KERN_CONT " %08lx", *stack++); touch_nmi_watchdog(); } - pr_cont("\n"); + printk(KERN_CONT "\n"); show_trace_log_lvl(task, regs, sp, bp, log_lvl); } @@ -86,11 +86,12 @@ void show_regs(struct pt_regs *regs) { int i; + print_modules(); __show_regs(regs, !user_mode_vm(regs)); - pr_emerg("Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", - TASK_COMM_LEN, current->comm, task_pid_nr(current), - current_thread_info(), current, task_thread_info(current)); + printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", + TASK_COMM_LEN, current->comm, task_pid_nr(current), + current_thread_info(), current, task_thread_info(current)); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. @@ -101,10 +102,10 @@ void show_regs(struct pt_regs *regs) unsigned char c; u8 *ip; - pr_emerg("Stack:\n"); + printk(KERN_EMERG "Stack:\n"); show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); - pr_emerg("Code:"); + printk(KERN_EMERG "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { @@ -115,16 +116,16 @@ void show_regs(struct pt_regs *regs) for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - pr_cont(" Bad EIP value."); + printk(KERN_CONT " Bad EIP value."); break; } if (ip == (u8 *)regs->ip) - pr_cont(" <%02x>", c); + printk(KERN_CONT "<%02x> ", c); else - pr_cont(" %02x", c); + printk(KERN_CONT "%02x ", c); } } - pr_cont("\n"); + printk(KERN_CONT "\n"); } int is_valid_bugaddr(unsigned long ip) diff --git a/trunk/arch/x86/kernel/dumpstack_64.c b/trunk/arch/x86/kernel/dumpstack_64.c index b653675d5288..791b76122aa8 100644 --- a/trunk/arch/x86/kernel/dumpstack_64.c +++ b/trunk/arch/x86/kernel/dumpstack_64.c @@ -228,20 +228,20 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, if (stack >= irq_stack && stack <= irq_stack_end) { if (stack == irq_stack_end) { stack = (unsigned long *) (irq_stack_end[-1]); - pr_cont(" "); + printk(KERN_CONT " "); } } else { if (((long) stack & (THREAD_SIZE-1)) == 0) break; } if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - pr_cont("\n"); - pr_cont(" %016lx", *stack++); + printk(KERN_CONT "\n"); + printk(KERN_CONT " %016lx", *stack++); touch_nmi_watchdog(); } preempt_enable(); - pr_cont("\n"); + printk(KERN_CONT "\n"); show_trace_log_lvl(task, regs, sp, bp, log_lvl); } @@ -254,9 +254,10 @@ void show_regs(struct pt_regs *regs) sp = regs->sp; printk("CPU %d ", cpu); + print_modules(); __show_regs(regs, 1); - printk(KERN_DEFAULT "Process %s (pid: %d, threadinfo %p, task %p)\n", - cur->comm, cur->pid, task_thread_info(cur), cur); + printk("Process %s (pid: %d, threadinfo %p, task %p)\n", + cur->comm, cur->pid, task_thread_info(cur), cur); /* * When in-kernel, we also print out the stack and code at the @@ -283,16 +284,16 @@ void show_regs(struct pt_regs *regs) for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - pr_cont(" Bad RIP value."); + printk(KERN_CONT " Bad RIP value."); break; } if (ip == (u8 *)regs->ip) - pr_cont("<%02x> ", c); + printk(KERN_CONT "<%02x> ", c); else - pr_cont("%02x ", c); + printk(KERN_CONT "%02x ", c); } } - pr_cont("\n"); + printk(KERN_CONT "\n"); } int is_valid_bugaddr(unsigned long ip) diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index 111f6bbd8b38..7d65133b51be 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -1758,30 +1758,10 @@ end_repeat_nmi: */ call save_paranoid DEFAULT_FRAME 0 - - /* - * Save off the CR2 register. If we take a page fault in the NMI then - * it could corrupt the CR2 value. If the NMI preempts a page fault - * handler before it was able to read the CR2 register, and then the - * NMI itself takes a page fault, the page fault that was preempted - * will read the information from the NMI page fault and not the - * origin fault. Save it off and restore it if it changes. - * Use the r12 callee-saved register. - */ - movq %cr2, %r12 - /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi movq $-1,%rsi call do_nmi - - /* Did the NMI take a page fault? Restore cr2 if it did */ - movq %cr2, %rcx - cmpq %rcx, %r12 - je 1f - movq %r12, %cr2 -1: - testl %ebx,%ebx /* swapgs needed? */ jnz nmi_restore nmi_swapgs: diff --git a/trunk/arch/x86/kernel/irq.c b/trunk/arch/x86/kernel/irq.c index 1f5f1d5d2a02..3dafc6003b7c 100644 --- a/trunk/arch/x86/kernel/irq.c +++ b/trunk/arch/x86/kernel/irq.c @@ -294,9 +294,9 @@ void fixup_irqs(void) raw_spin_unlock(&desc->lock); if (break_affinity && set_affinity) - pr_notice("Broke affinity for irq %i\n", irq); + printk("Broke affinity for irq %i\n", irq); else if (!set_affinity) - pr_notice("Cannot set affinity for irq %i\n", irq); + printk("Cannot set affinity for irq %i\n", irq); } /* diff --git a/trunk/arch/x86/kernel/kgdb.c b/trunk/arch/x86/kernel/kgdb.c index 3f61904365cf..8bfb6146f753 100644 --- a/trunk/arch/x86/kernel/kgdb.c +++ b/trunk/arch/x86/kernel/kgdb.c @@ -444,12 +444,12 @@ void kgdb_roundup_cpus(unsigned long flags) /** * kgdb_arch_handle_exception - Handle architecture specific GDB packets. - * @e_vector: The error vector of the exception that happened. + * @vector: The error vector of the exception that happened. * @signo: The signal number of the exception that happened. * @err_code: The error code of the exception that happened. - * @remcomInBuffer: The buffer of the packet we have read. - * @remcomOutBuffer: The buffer of %BUFMAX bytes to write a packet into. - * @linux_regs: The &struct pt_regs of the current process. + * @remcom_in_buffer: The buffer of the packet we have read. + * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. + * @regs: The &struct pt_regs of the current process. * * This function MUST handle the 'c' and 's' command packets, * as well packets to set / remove a hardware breakpoint, if used. diff --git a/trunk/arch/x86/kernel/kvmclock.c b/trunk/arch/x86/kernel/kvmclock.c index f1b42b3a186c..086eb58c6e80 100644 --- a/trunk/arch/x86/kernel/kvmclock.c +++ b/trunk/arch/x86/kernel/kvmclock.c @@ -120,6 +120,11 @@ bool kvm_check_and_clear_guest_paused(void) bool ret = false; struct pvclock_vcpu_time_info *src; + /* + * per_cpu() is safe here because this function is only called from + * timer functions where preemption is already disabled. + */ + WARN_ON(!in_atomic()); src = &__get_cpu_var(hv_clock); if ((src->flags & PVCLOCK_GUEST_STOPPED) != 0) { __this_cpu_and(hv_clock.flags, ~PVCLOCK_GUEST_STOPPED); diff --git a/trunk/arch/x86/kernel/microcode_core.c b/trunk/arch/x86/kernel/microcode_core.c index 4873e62db6a1..fbdfc6917180 100644 --- a/trunk/arch/x86/kernel/microcode_core.c +++ b/trunk/arch/x86/kernel/microcode_core.c @@ -87,7 +87,6 @@ #include #include #include -#include MODULE_DESCRIPTION("Microcode Update Driver"); MODULE_AUTHOR("Tigran Aivazian "); @@ -278,6 +277,7 @@ static int reload_for_cpu(int cpu) struct ucode_cpu_info *uci = ucode_cpu_info + cpu; int err = 0; + mutex_lock(µcode_mutex); if (uci->valid) { enum ucode_state ustate; @@ -288,6 +288,7 @@ static int reload_for_cpu(int cpu) if (ustate == UCODE_ERROR) err = -EINVAL; } + mutex_unlock(µcode_mutex); return err; } @@ -297,31 +298,19 @@ static ssize_t reload_store(struct device *dev, const char *buf, size_t size) { unsigned long val; - int cpu; - ssize_t ret = 0, tmp_ret; + int cpu = dev->id; + ssize_t ret = 0; ret = kstrtoul(buf, 0, &val); if (ret) return ret; - if (val != 1) - return size; - - get_online_cpus(); - mutex_lock(µcode_mutex); - for_each_online_cpu(cpu) { - tmp_ret = reload_for_cpu(cpu); - if (tmp_ret != 0) - pr_warn("Error reloading microcode on CPU %d\n", cpu); - - /* save retval of the first encountered reload error */ - if (!ret) - ret = tmp_ret; + if (val == 1) { + get_online_cpus(); + if (cpu_online(cpu)) + ret = reload_for_cpu(cpu); + put_online_cpus(); } - if (!ret) - perf_check_microcode(); - mutex_unlock(µcode_mutex); - put_online_cpus(); if (!ret) ret = size; @@ -350,6 +339,7 @@ static DEVICE_ATTR(version, 0400, version_show, NULL); static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); static struct attribute *mc_default_attrs[] = { + &dev_attr_reload.attr, &dev_attr_version.attr, &dev_attr_processor_flags.attr, NULL @@ -514,7 +504,7 @@ static struct notifier_block __refdata mc_cpu_notifier = { #ifdef MODULE /* Autoload on Intel and AMD systems */ -static const struct x86_cpu_id __initconst microcode_id[] = { +static const struct x86_cpu_id microcode_id[] = { #ifdef CONFIG_MICROCODE_INTEL { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, #endif @@ -526,16 +516,6 @@ static const struct x86_cpu_id __initconst microcode_id[] = { MODULE_DEVICE_TABLE(x86cpu, microcode_id); #endif -static struct attribute *cpu_root_microcode_attrs[] = { - &dev_attr_reload.attr, - NULL -}; - -static struct attribute_group cpu_root_microcode_group = { - .name = "microcode", - .attrs = cpu_root_microcode_attrs, -}; - static int __init microcode_init(void) { struct cpuinfo_x86 *c = &cpu_data(0); @@ -560,25 +540,16 @@ static int __init microcode_init(void) mutex_lock(µcode_mutex); error = subsys_interface_register(&mc_cpu_interface); - if (!error) - perf_check_microcode(); + mutex_unlock(µcode_mutex); put_online_cpus(); if (error) goto out_pdev; - error = sysfs_create_group(&cpu_subsys.dev_root->kobj, - &cpu_root_microcode_group); - - if (error) { - pr_err("Error creating microcode group!\n"); - goto out_driver; - } - error = microcode_dev_init(); if (error) - goto out_ucode_group; + goto out_driver; register_syscore_ops(&mc_syscore_ops); register_hotcpu_notifier(&mc_cpu_notifier); @@ -588,11 +559,7 @@ static int __init microcode_init(void) return 0; - out_ucode_group: - sysfs_remove_group(&cpu_subsys.dev_root->kobj, - &cpu_root_microcode_group); - - out_driver: +out_driver: get_online_cpus(); mutex_lock(µcode_mutex); @@ -601,7 +568,7 @@ static int __init microcode_init(void) mutex_unlock(µcode_mutex); put_online_cpus(); - out_pdev: +out_pdev: platform_device_unregister(microcode_pdev); return error; @@ -617,9 +584,6 @@ static void __exit microcode_exit(void) unregister_hotcpu_notifier(&mc_cpu_notifier); unregister_syscore_ops(&mc_syscore_ops); - sysfs_remove_group(&cpu_subsys.dev_root->kobj, - &cpu_root_microcode_group); - get_online_cpus(); mutex_lock(µcode_mutex); diff --git a/trunk/arch/x86/kernel/module.c b/trunk/arch/x86/kernel/module.c index 202494d2ec6e..f21fd94ac897 100644 --- a/trunk/arch/x86/kernel/module.c +++ b/trunk/arch/x86/kernel/module.c @@ -15,9 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -33,14 +30,9 @@ #include #if 0 -#define DEBUGP(fmt, ...) \ - printk(KERN_DEBUG fmt, ##__VA_ARGS__) +#define DEBUGP printk #else -#define DEBUGP(fmt, ...) \ -do { \ - if (0) \ - printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ -} while (0) +#define DEBUGP(fmt...) #endif void *module_alloc(unsigned long size) @@ -64,8 +56,8 @@ int apply_relocate(Elf32_Shdr *sechdrs, Elf32_Sym *sym; uint32_t *location; - DEBUGP("Applying relocate section %u to %u\n", - relsec, sechdrs[relsec].sh_info); + DEBUGP("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr @@ -85,7 +77,7 @@ int apply_relocate(Elf32_Shdr *sechdrs, *location += sym->st_value - (uint32_t)location; break; default: - pr_err("%s: Unknown relocation: %u\n", + printk(KERN_ERR "module %s: Unknown relocation: %u\n", me->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -105,8 +97,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, void *loc; u64 val; - DEBUGP("Applying relocate section %u to %u\n", - relsec, sechdrs[relsec].sh_info); + DEBUGP("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr @@ -118,8 +110,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, + ELF64_R_SYM(rel[i].r_info); DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n", - (int)ELF64_R_TYPE(rel[i].r_info), - sym->st_value, rel[i].r_addend, (u64)loc); + (int)ELF64_R_TYPE(rel[i].r_info), + sym->st_value, rel[i].r_addend, (u64)loc); val = sym->st_value + rel[i].r_addend; @@ -148,7 +140,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, #endif break; default: - pr_err("%s: Unknown rela relocation: %llu\n", + printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n", me->name, ELF64_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -156,9 +148,9 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return 0; overflow: - pr_err("overflow in relocation type %d val %Lx\n", + printk(KERN_ERR "overflow in relocation type %d val %Lx\n", (int)ELF64_R_TYPE(rel[i].r_info), val); - pr_err("`%s' likely not compiled with -mcmodel=kernel\n", + printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n", me->name); return -ENOEXEC; } diff --git a/trunk/arch/x86/kernel/nmi.c b/trunk/arch/x86/kernel/nmi.c index f84f5c57de35..a0b2f84457be 100644 --- a/trunk/arch/x86/kernel/nmi.c +++ b/trunk/arch/x86/kernel/nmi.c @@ -365,9 +365,8 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) #ifdef CONFIG_X86_32 /* * For i386, NMIs use the same stack as the kernel, and we can - * add a workaround to the iret problem in C (preventing nested - * NMIs if an NMI takes a trap). Simply have 3 states the NMI - * can be in: + * add a workaround to the iret problem in C. Simply have 3 states + * the NMI can be in. * * 1) not running * 2) executing @@ -384,50 +383,32 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) * If an NMI hits a breakpoint that executes an iret, another * NMI can preempt it. We do not want to allow this new NMI * to run, but we want to execute it when the first one finishes. - * We set the state to "latched", and the exit of the first NMI will - * perform a dec_return, if the result is zero (NOT_RUNNING), then - * it will simply exit the NMI handler. If not, the dec_return - * would have set the state to NMI_EXECUTING (what we want it to - * be when we are running). In this case, we simply jump back - * to rerun the NMI handler again, and restart the 'latched' NMI. - * - * No trap (breakpoint or page fault) should be hit before nmi_restart, - * thus there is no race between the first check of state for NOT_RUNNING - * and setting it to NMI_EXECUTING. The HW will prevent nested NMIs - * at this point. - * - * In case the NMI takes a page fault, we need to save off the CR2 - * because the NMI could have preempted another page fault and corrupt - * the CR2 that is about to be read. As nested NMIs must be restarted - * and they can not take breakpoints or page faults, the update of the - * CR2 must be done before converting the nmi state back to NOT_RUNNING. - * Otherwise, there would be a race of another nested NMI coming in - * after setting state to NOT_RUNNING but before updating the nmi_cr2. + * We set the state to "latched", and the first NMI will perform + * an cmpxchg on the state, and if it doesn't successfully + * reset the state to "not running" it will restart the next + * NMI. */ enum nmi_states { - NMI_NOT_RUNNING = 0, + NMI_NOT_RUNNING, NMI_EXECUTING, NMI_LATCHED, }; static DEFINE_PER_CPU(enum nmi_states, nmi_state); -static DEFINE_PER_CPU(unsigned long, nmi_cr2); #define nmi_nesting_preprocess(regs) \ do { \ - if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) { \ - this_cpu_write(nmi_state, NMI_LATCHED); \ + if (__get_cpu_var(nmi_state) != NMI_NOT_RUNNING) { \ + __get_cpu_var(nmi_state) = NMI_LATCHED; \ return; \ } \ - this_cpu_write(nmi_state, NMI_EXECUTING); \ - this_cpu_write(nmi_cr2, read_cr2()); \ - } while (0); \ - nmi_restart: + nmi_restart: \ + __get_cpu_var(nmi_state) = NMI_EXECUTING; \ + } while (0) #define nmi_nesting_postprocess() \ do { \ - if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) \ - write_cr2(this_cpu_read(nmi_cr2)); \ - if (this_cpu_dec_return(nmi_state)) \ + if (cmpxchg(&__get_cpu_var(nmi_state), \ + NMI_EXECUTING, NMI_NOT_RUNNING) != NMI_EXECUTING) \ goto nmi_restart; \ } while (0) #else /* x86_64 */ diff --git a/trunk/arch/x86/kernel/nmi_selftest.c b/trunk/arch/x86/kernel/nmi_selftest.c index 6d9582ec0324..e31bf8d5c4d2 100644 --- a/trunk/arch/x86/kernel/nmi_selftest.c +++ b/trunk/arch/x86/kernel/nmi_selftest.c @@ -42,8 +42,7 @@ static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs) static void __init init_nmi_testsuite(void) { /* trap all the unknown NMIs we may generate */ - register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk", - __initdata); + register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk"); } static void __init cleanup_nmi_testsuite(void) @@ -66,7 +65,7 @@ static void __init test_nmi_ipi(struct cpumask *mask) unsigned long timeout; if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, - NMI_FLAG_FIRST, "nmi_selftest", __initdata)) { + NMI_FLAG_FIRST, "nmi_selftest")) { nmi_fail = FAILURE; return; } diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index 17fff18a1031..9ce885996fd7 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -352,7 +352,9 @@ struct pv_cpu_ops pv_cpu_ops = { #endif .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, + .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = native_write_msr_safe, + .wrmsr_regs = native_wrmsr_safe_regs, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, .read_tscp = native_read_tscp, diff --git a/trunk/arch/x86/kernel/pci-calgary_64.c b/trunk/arch/x86/kernel/pci-calgary_64.c index 299d49302e7d..b72838bae64a 100644 --- a/trunk/arch/x86/kernel/pci-calgary_64.c +++ b/trunk/arch/x86/kernel/pci-calgary_64.c @@ -22,8 +22,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) "Calgary: " fmt - #include #include #include @@ -247,7 +245,7 @@ static unsigned long iommu_range_alloc(struct device *dev, offset = iommu_area_alloc(tbl->it_map, tbl->it_size, 0, npages, 0, boundary_size, 0); if (offset == ~0UL) { - pr_warn("IOMMU full\n"); + printk(KERN_WARNING "Calgary: IOMMU full.\n"); spin_unlock_irqrestore(&tbl->it_lock, flags); if (panic_on_overflow) panic("Calgary: fix the allocator.\n"); @@ -273,8 +271,8 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl, entry = iommu_range_alloc(dev, tbl, npages); if (unlikely(entry == DMA_ERROR_CODE)) { - pr_warn("failed to allocate %u pages in iommu %p\n", - npages, tbl); + printk(KERN_WARNING "Calgary: failed to allocate %u pages in " + "iommu %p\n", npages, tbl); return DMA_ERROR_CODE; } @@ -563,7 +561,8 @@ static void calgary_tce_cache_blast(struct iommu_table *tbl) i++; } while ((val & 0xff) != 0xff && i < 100); if (i == 100) - pr_warn("PCI bus not quiesced, continuing anyway\n"); + printk(KERN_WARNING "Calgary: PCI bus not quiesced, " + "continuing anyway\n"); /* invalidate TCE cache */ target = calgary_reg(bbar, tar_offset(tbl->it_busno)); @@ -605,7 +604,8 @@ static void calioc2_tce_cache_blast(struct iommu_table *tbl) i++; } while ((val64 & 0xff) != 0xff && i < 100); if (i == 100) - pr_warn("CalIOC2: PCI bus not quiesced, continuing anyway\n"); + printk(KERN_WARNING "CalIOC2: PCI bus not quiesced, " + "continuing anyway\n"); /* 3. poll Page Migration DEBUG for SoftStopFault */ target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG); @@ -617,7 +617,8 @@ static void calioc2_tce_cache_blast(struct iommu_table *tbl) if (++count < 100) goto begin; else { - pr_warn("CalIOC2: too many SoftStopFaults, aborting TCE cache flush sequence!\n"); + printk(KERN_WARNING "CalIOC2: too many SoftStopFaults, " + "aborting TCE cache flush sequence!\n"); return; /* pray for the best */ } } @@ -839,8 +840,8 @@ static void calgary_dump_error_regs(struct iommu_table *tbl) plssr = be32_to_cpu(readl(target)); /* If no error, the agent ID in the CSR is not valid */ - pr_emerg("DMA error on Calgary PHB 0x%x, 0x%08x@CSR 0x%08x@PLSSR\n", - tbl->it_busno, csr, plssr); + printk(KERN_EMERG "Calgary: DMA error on Calgary PHB 0x%x, " + "0x%08x@CSR 0x%08x@PLSSR\n", tbl->it_busno, csr, plssr); } static void calioc2_dump_error_regs(struct iommu_table *tbl) @@ -866,21 +867,22 @@ static void calioc2_dump_error_regs(struct iommu_table *tbl) target = calgary_reg(bbar, phboff | 0x800); mck = be32_to_cpu(readl(target)); - pr_emerg("DMA error on CalIOC2 PHB 0x%x\n", tbl->it_busno); + printk(KERN_EMERG "Calgary: DMA error on CalIOC2 PHB 0x%x\n", + tbl->it_busno); - pr_emerg("0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", - csr, plssr, csmr, mck); + printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", + csr, plssr, csmr, mck); /* dump rest of error regs */ - pr_emerg(""); + printk(KERN_EMERG "Calgary: "); for (i = 0; i < ARRAY_SIZE(errregs); i++) { /* err regs are at 0x810 - 0x870 */ erroff = (0x810 + (i * 0x10)); target = calgary_reg(bbar, phboff | erroff); errregs[i] = be32_to_cpu(readl(target)); - pr_cont("0x%08x@0x%lx ", errregs[i], erroff); + printk("0x%08x@0x%lx ", errregs[i], erroff); } - pr_cont("\n"); + printk("\n"); /* root complex status */ target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS); diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index c0f420f76cd3..62c9457ccd2f 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -100,7 +100,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, struct dma_attrs *attrs) { unsigned long dma_mask; - struct page *page; + struct page *page = NULL; unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; dma_addr_t addr; @@ -108,7 +108,6 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, flag |= __GFP_ZERO; again: - page = NULL; if (!(flag & GFP_ATOMIC)) page = dma_alloc_from_contiguous(dev, count, get_order(size)); if (!page) diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index ef6a8456f719..735279e54e59 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -147,14 +145,16 @@ void show_regs_common(void) /* Board Name is optional */ board = dmi_get_system_info(DMI_BOARD_NAME); - printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s %s%s%s\n", - current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version, - vendor, product, - board ? "/" : "", - board ? board : ""); + printk(KERN_CONT "\n"); + printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s", + current->pid, current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + printk(KERN_CONT " %s %s", vendor, product); + if (board) + printk(KERN_CONT "/%s", board); + printk(KERN_CONT "\n"); } void flush_thread(void) @@ -645,7 +645,7 @@ static void amd_e400_idle(void) amd_e400_c1e_detected = true; if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) mark_tsc_unstable("TSC halt in AMD C1E"); - pr_info("System has AMD C1E enabled\n"); + printk(KERN_INFO "System has AMD C1E enabled\n"); } } @@ -659,7 +659,8 @@ static void amd_e400_idle(void) */ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &cpu); - pr_info("Switch to broadcast mode on CPU%d\n", cpu); + printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", + cpu); } clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); @@ -680,7 +681,8 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP if (pm_idle == poll_idle && smp_num_siblings > 1) { - pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n"); + printk_once(KERN_WARNING "WARNING: polling idle and HT enabled," + " performance may degrade.\n"); } #endif if (pm_idle) @@ -690,11 +692,11 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) /* * One CPU supports mwait => All CPUs supports mwait */ - pr_info("using mwait in idle threads\n"); + printk(KERN_INFO "using mwait in idle threads.\n"); pm_idle = mwait_idle; } else if (cpu_has_amd_erratum(amd_erratum_400)) { /* E400: APIC timer interrupt does not wake up CPU from C1e */ - pr_info("using AMD E400 aware idle routine\n"); + printk(KERN_INFO "using AMD E400 aware idle routine\n"); pm_idle = amd_e400_idle; } else pm_idle = default_idle; @@ -713,7 +715,7 @@ static int __init idle_setup(char *str) return -EINVAL; if (!strcmp(str, "poll")) { - pr_info("using polling idle threads\n"); + printk("using polling idle threads.\n"); pm_idle = poll_idle; boot_option_idle_override = IDLE_POLL; } else if (!strcmp(str, "mwait")) { diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index 0a980c9d7cb8..61cdf7fdf099 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -117,10 +117,10 @@ void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { if (dead_task->mm->context.size) { - pr_warn("WARNING: dead process %8s still has LDT? <%p/%d>\n", - dead_task->comm, - dead_task->mm->context.ldt, - dead_task->mm->context.size); + printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", + dead_task->comm, + dead_task->mm->context.ldt, + dead_task->mm->context.size); BUG(); } } @@ -466,7 +466,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) task->thread.gs = addr; if (doit) { load_gs_index(0); - ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr); + ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); } } put_cpu(); @@ -494,7 +494,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) /* set the selector to 0 to not confuse __switch_to */ loadsegment(fs, 0); - ret = wrmsrl_safe(MSR_FS_BASE, addr); + ret = checking_wrmsrl(MSR_FS_BASE, addr); } } put_cpu(); diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c index 52190a938b4a..79c45af81604 100644 --- a/trunk/arch/x86/kernel/reboot.c +++ b/trunk/arch/x86/kernel/reboot.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -22,12 +20,14 @@ #include #include #include -#include -#include -#include -#include -#include +#ifdef CONFIG_X86_32 +# include +# include +# include +#else +# include +#endif /* * Power off function, if any @@ -49,7 +49,7 @@ int reboot_force; */ static int reboot_default = 1; -#ifdef CONFIG_SMP +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) static int reboot_cpu = -1; #endif @@ -67,8 +67,8 @@ bool port_cf9_safe = false; * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] * warm Don't set the cold reboot flag * cold Set the cold reboot flag - * bios Reboot by jumping through the BIOS - * smp Reboot by executing reset on BSP or other CPU + * bios Reboot by jumping through the BIOS (only for X86_32) + * smp Reboot by executing reset on BSP or other CPU (only for X86_32) * triple Force a triple fault (init) * kbd Use the keyboard controller. cold reset (default) * acpi Use the RESET_REG in the FADT @@ -95,6 +95,7 @@ static int __init reboot_setup(char *str) reboot_mode = 0; break; +#ifdef CONFIG_X86_32 #ifdef CONFIG_SMP case 's': if (isdigit(*(str+1))) { @@ -111,6 +112,7 @@ static int __init reboot_setup(char *str) #endif /* CONFIG_SMP */ case 'b': +#endif case 'a': case 'k': case 't': @@ -136,6 +138,7 @@ static int __init reboot_setup(char *str) __setup("reboot=", reboot_setup); +#ifdef CONFIG_X86_32 /* * Reboot options and system auto-detection code provided by * Dell Inc. so their systems "just work". :-) @@ -149,14 +152,16 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) { if (reboot_type != BOOT_BIOS) { reboot_type = BOOT_BIOS; - pr_info("%s series board detected. Selecting %s-method for reboots.\n", - "BIOS", d->ident); + printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident); } return 0; } -void __noreturn machine_real_restart(unsigned int type) +void machine_real_restart(unsigned int type) { + void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) + real_mode_header->machine_real_restart_asm; + local_irq_disable(); /* @@ -176,28 +181,25 @@ void __noreturn machine_real_restart(unsigned int type) /* * Switch back to the initial page table. */ -#ifdef CONFIG_X86_32 load_cr3(initial_page_table); -#else - write_cr3(real_mode_header->trampoline_pgd); -#endif + + /* + * Write 0x1234 to absolute memory location 0x472. The BIOS reads + * this on booting to tell it to "Bypass memory test (also warm + * boot)". This seems like a fairly standard thing that gets set by + * REBOOT.COM programs, and the previous reset routine did this + * too. */ + *((unsigned short *)0x472) = reboot_mode; /* Jump to the identity-mapped low memory code */ -#ifdef CONFIG_X86_32 - asm volatile("jmpl *%0" : : - "rm" (real_mode_header->machine_real_restart_asm), - "a" (type)); -#else - asm volatile("ljmpl *%0" : : - "m" (real_mode_header->machine_real_restart_asm), - "D" (type)); -#endif - unreachable(); + restart_lowmem(type); } #ifdef CONFIG_APM_MODULE EXPORT_SYMBOL(machine_real_restart); #endif +#endif /* CONFIG_X86_32 */ + /* * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot */ @@ -205,8 +207,8 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) { if (reboot_type != BOOT_CF9) { reboot_type = BOOT_CF9; - pr_info("%s series board detected. Selecting %s-method for reboots.\n", - "PCI", d->ident); + printk(KERN_INFO "%s series board detected. " + "Selecting PCI-method for reboots.\n", d->ident); } return 0; } @@ -215,16 +217,17 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) { if (reboot_type != BOOT_KBD) { reboot_type = BOOT_KBD; - pr_info("%s series board detected. Selecting %s-method for reboot.\n", - "KBD", d->ident); + printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident); } return 0; } /* - * This is a single dmi_table handling all reboot quirks. + * This is a single dmi_table handling all reboot quirks. Note that + * REBOOT_BIOS is only available for 32bit */ static struct dmi_system_id __initdata reboot_dmi_table[] = { +#ifdef CONFIG_X86_32 { /* Handle problems with rebooting on Dell E520's */ .callback = set_bios_reboot, .ident = "Dell E520", @@ -374,6 +377,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "P4S800"), }, }, +#endif /* CONFIG_X86_32 */ { /* Handle reboot issue on Acer Aspire one */ .callback = set_kbd_reboot, @@ -447,14 +451,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), }, }, - { /* Handle problems with rebooting on the Precision M6600. */ - .callback = set_pci_reboot, - .ident = "Dell OptiPlex 990", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), - }, - }, { } }; @@ -580,11 +576,13 @@ static void native_machine_emergency_restart(void) reboot_type = BOOT_KBD; break; +#ifdef CONFIG_X86_32 case BOOT_BIOS: machine_real_restart(MRR_BIOS); reboot_type = BOOT_KBD; break; +#endif case BOOT_ACPI: acpi_reboot(); @@ -626,10 +624,12 @@ void native_machine_shutdown(void) /* The boot cpu is always logical cpu 0 */ int reboot_cpu_id = 0; +#ifdef CONFIG_X86_32 /* See if there has been given a command line override */ if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && cpu_online(reboot_cpu)) reboot_cpu_id = reboot_cpu; +#endif /* Make certain the cpu I'm about to reboot on is online */ if (!cpu_online(reboot_cpu_id)) @@ -639,11 +639,9 @@ void native_machine_shutdown(void) set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id)); /* - * O.K Now that I'm on the appropriate processor, stop all of the - * others. Also disable the local irq to not receive the per-cpu - * timer interrupt which may trigger scheduler's load balance. + * O.K Now that I'm on the appropriate processor, + * stop all of the others. */ - local_irq_disable(); stop_other_cpus(); #endif @@ -670,7 +668,7 @@ static void __machine_emergency_restart(int emergency) static void native_machine_restart(char *__unused) { - pr_notice("machine restart\n"); + printk("machine restart\n"); if (!reboot_force) machine_shutdown(); diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index f4b9b80e1b95..16be6dc14db1 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -1031,6 +1031,8 @@ void __init setup_arch(char **cmdline_p) x86_init.timers.wallclock_init(); + x86_platform.wallclock_init(); + mcheck_init(); arch_init_ideal_nops(); diff --git a/trunk/arch/x86/kernel/signal.c b/trunk/arch/x86/kernel/signal.c index b280908a376e..21af737053aa 100644 --- a/trunk/arch/x86/kernel/signal.c +++ b/trunk/arch/x86/kernel/signal.c @@ -6,9 +6,6 @@ * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2002 x86-64 support by Andi Kleen */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -817,7 +814,7 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) me->comm, me->pid, where, frame, regs->ip, regs->sp, regs->orig_ax); print_vma_addr(" in ", regs->ip); - pr_cont("\n"); + printk(KERN_CONT "\n"); } force_sig(SIGSEGV, me); diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index c1a310fb8309..f56f96da77f5 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -1,4 +1,4 @@ - /* +/* * x86 SMP booting functions * * (c) 1995 Alan Cox, Building #3 @@ -39,8 +39,6 @@ * Glauber Costa : i386 and x86_64 integration */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -186,7 +184,7 @@ static void __cpuinit smp_callin(void) * boards) */ - pr_debug("CALLIN, before setup_local_APIC()\n"); + pr_debug("CALLIN, before setup_local_APIC().\n"); if (apic->smp_callin_clear_local_apic) apic->smp_callin_clear_local_apic(); setup_local_APIC(); @@ -257,13 +255,22 @@ notrace static void __cpuinit start_secondary(void *unused) check_tsc_sync_target(); /* + * We need to hold call_lock, so there is no inconsistency + * between the time smp_call_function() determines number of + * IPI recipients, and the time when the determination is made + * for which cpus receive the IPI. Holding this + * lock helps us to not include this cpu in a currently in progress + * smp_call_function(). + * * We need to hold vector_lock so there the set of online cpus * does not change while we are assigning vectors to cpus. Holding * this lock ensures we don't half assign or remove an irq from a cpu. */ + ipi_call_lock(); lock_vector_lock(); set_cpu_online(smp_processor_id(), true); unlock_vector_lock(); + ipi_call_unlock(); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; x86_platform.nmi_init(); @@ -342,12 +349,9 @@ static bool __cpuinit match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) static bool __cpuinit match_mc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) { - if (c->phys_proc_id == o->phys_proc_id) { - if (cpu_has(c, X86_FEATURE_AMD_DCM)) - return true; - + if (c->phys_proc_id == o->phys_proc_id) return topology_sane(c, o, "mc"); - } + return false; } @@ -378,15 +382,6 @@ void __cpuinit set_cpu_sibling_map(int cpu) if ((i == cpu) || (has_mc && match_llc(c, o))) link_mask(llc_shared, cpu, i); - } - - /* - * This needs a separate iteration over the cpus because we rely on all - * cpu_sibling_mask links to be set-up. - */ - for_each_cpu(i, cpu_sibling_setup_mask) { - o = &cpu_data(i); - if ((i == cpu) || (has_mc && match_mc(c, o))) { link_mask(core, cpu, i); @@ -415,7 +410,15 @@ void __cpuinit set_cpu_sibling_map(int cpu) /* maps the cpu to the sched domain representing multi-core */ const struct cpumask *cpu_coregroup_mask(int cpu) { - return cpu_llc_shared_mask(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 + */ + if (!(cpu_has(c, X86_FEATURE_AMD_DCM))) + return cpu_core_mask(cpu); + else + return cpu_llc_shared_mask(cpu); } static void impress_friends(void) @@ -425,16 +428,17 @@ static void impress_friends(void) /* * Allow the user to impress friends. */ - pr_debug("Before bogomips\n"); + pr_debug("Before bogomips.\n"); for_each_possible_cpu(cpu) if (cpumask_test_cpu(cpu, cpu_callout_mask)) bogosum += cpu_data(cpu).loops_per_jiffy; - pr_info("Total of %d processors activated (%lu.%02lu BogoMIPS)\n", + printk(KERN_INFO + "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); - pr_debug("Before bogocount - setting activated=1\n"); + pr_debug("Before bogocount - setting activated=1.\n"); } void __inquire_remote_apic(int apicid) @@ -444,17 +448,18 @@ void __inquire_remote_apic(int apicid) int timeout; u32 status; - pr_info("Inquiring remote APIC 0x%x...\n", apicid); + printk(KERN_INFO "Inquiring remote APIC 0x%x...\n", apicid); for (i = 0; i < ARRAY_SIZE(regs); i++) { - pr_info("... APIC 0x%x %s: ", apicid, names[i]); + printk(KERN_INFO "... APIC 0x%x %s: ", apicid, names[i]); /* * Wait for idle. */ status = safe_apic_wait_icr_idle(); if (status) - pr_cont("a previous APIC delivery may have failed\n"); + printk(KERN_CONT + "a previous APIC delivery may have failed\n"); apic_icr_write(APIC_DM_REMRD | regs[i], apicid); @@ -467,10 +472,10 @@ void __inquire_remote_apic(int apicid) switch (status) { case APIC_ICR_RR_VALID: status = apic_read(APIC_RRR); - pr_cont("%08x\n", status); + printk(KERN_CONT "%08x\n", status); break; default: - pr_cont("failed\n"); + printk(KERN_CONT "failed\n"); } } } @@ -504,12 +509,12 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) apic_write(APIC_ESR, 0); accept_status = (apic_read(APIC_ESR) & 0xEF); } - pr_debug("NMI sent\n"); + pr_debug("NMI sent.\n"); if (send_status) - pr_err("APIC never delivered???\n"); + printk(KERN_ERR "APIC never delivered???\n"); if (accept_status) - pr_err("APIC delivery error (%lx)\n", accept_status); + printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); return (send_status | accept_status); } @@ -531,7 +536,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) apic_read(APIC_ESR); } - pr_debug("Asserting INIT\n"); + pr_debug("Asserting INIT.\n"); /* * Turn INIT on target chip @@ -547,7 +552,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) mdelay(10); - pr_debug("Deasserting INIT\n"); + pr_debug("Deasserting INIT.\n"); /* Target chip */ /* Send IPI */ @@ -580,14 +585,14 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) /* * Run STARTUP IPI loop. */ - pr_debug("#startup loops: %d\n", num_starts); + pr_debug("#startup loops: %d.\n", num_starts); for (j = 1; j <= num_starts; j++) { - pr_debug("Sending STARTUP #%d\n", j); + pr_debug("Sending STARTUP #%d.\n", j); if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ apic_write(APIC_ESR, 0); apic_read(APIC_ESR); - pr_debug("After apic_write\n"); + pr_debug("After apic_write.\n"); /* * STARTUP IPI @@ -604,7 +609,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) */ udelay(300); - pr_debug("Startup point 1\n"); + pr_debug("Startup point 1.\n"); pr_debug("Waiting for send to finish...\n"); send_status = safe_apic_wait_icr_idle(); @@ -619,12 +624,12 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) if (send_status || accept_status) break; } - pr_debug("After Startup\n"); + pr_debug("After Startup.\n"); if (send_status) - pr_err("APIC never delivered???\n"); + printk(KERN_ERR "APIC never delivered???\n"); if (accept_status) - pr_err("APIC delivery error (%lx)\n", accept_status); + printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); return (send_status | accept_status); } @@ -638,11 +643,11 @@ static void __cpuinit announce_cpu(int cpu, int apicid) if (system_state == SYSTEM_BOOTING) { if (node != current_node) { if (current_node > (-1)) - pr_cont(" OK\n"); + pr_cont(" Ok.\n"); current_node = node; pr_info("Booting Node %3d, Processors ", node); } - pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " OK\n" : ""); + pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " Ok.\n" : ""); return; } else pr_info("Booting Node %d Processor %d APIC 0x%x\n", @@ -722,9 +727,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) /* * allow APs to start initializing. */ - pr_debug("Before Callout %d\n", cpu); + pr_debug("Before Callout %d.\n", cpu); cpumask_set_cpu(cpu, cpu_callout_mask); - pr_debug("After Callout %d\n", cpu); + pr_debug("After Callout %d.\n", cpu); /* * Wait 5s total for a response @@ -752,7 +757,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) pr_err("CPU%d: Stuck ??\n", cpu); else /* trampoline code not run */ - pr_err("CPU%d: Not responding\n", cpu); + pr_err("CPU%d: Not responding.\n", cpu); if (apic->inquire_remote_apic) apic->inquire_remote_apic(apicid); } @@ -797,7 +802,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid || !physid_isset(apicid, phys_cpu_present_map) || !apic->apic_id_valid(apicid)) { - pr_err("%s: bad cpu %d\n", __func__, cpu); + printk(KERN_ERR "%s: bad cpu %d\n", __func__, cpu); return -EINVAL; } @@ -878,8 +883,9 @@ static int __init smp_sanity_check(unsigned max_cpus) unsigned int cpu; unsigned nr; - pr_warn("More than 8 CPUs detected - skipping them\n" - "Use CONFIG_X86_BIGSMP\n"); + printk(KERN_WARNING + "More than 8 CPUs detected - skipping them.\n" + "Use CONFIG_X86_BIGSMP.\n"); nr = 0; for_each_present_cpu(cpu) { @@ -900,7 +906,8 @@ static int __init smp_sanity_check(unsigned max_cpus) #endif if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { - pr_warn("weird, boot CPU (#%d) not listed by the BIOS\n", + printk(KERN_WARNING + "weird, boot CPU (#%d) not listed by the BIOS.\n", hard_smp_processor_id()); physid_set(hard_smp_processor_id(), phys_cpu_present_map); @@ -912,10 +919,11 @@ static int __init smp_sanity_check(unsigned max_cpus) */ if (!smp_found_config && !acpi_lapic) { preempt_enable(); - pr_notice("SMP motherboard not detected\n"); + printk(KERN_NOTICE "SMP motherboard not detected.\n"); disable_smp(); if (APIC_init_uniprocessor()) - pr_notice("Local APIC not detected. Using dummy APIC emulation.\n"); + printk(KERN_NOTICE "Local APIC not detected." + " Using dummy APIC emulation.\n"); return -1; } @@ -924,8 +932,9 @@ static int __init smp_sanity_check(unsigned max_cpus) * CPU too, but we do it for the sake of robustness anyway. */ if (!apic->check_phys_apicid_present(boot_cpu_physical_apicid)) { - pr_notice("weird, boot CPU (#%d) not listed by the BIOS\n", - boot_cpu_physical_apicid); + printk(KERN_NOTICE + "weird, boot CPU (#%d) not listed by the BIOS.\n", + boot_cpu_physical_apicid); physid_set(hard_smp_processor_id(), phys_cpu_present_map); } preempt_enable(); @@ -938,7 +947,8 @@ static int __init smp_sanity_check(unsigned max_cpus) if (!disable_apic) { pr_err("BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); - pr_err("... forcing use of dummy APIC emulation (tell your hw vendor)\n"); + pr_err("... forcing use of dummy APIC emulation." + "(tell your hw vendor)\n"); } smpboot_clear_io_apic(); disable_ioapic_support(); @@ -951,7 +961,7 @@ static int __init smp_sanity_check(unsigned max_cpus) * If SMP should be disabled, then really disable it! */ if (!max_cpus) { - pr_info("SMP mode deactivated\n"); + printk(KERN_INFO "SMP mode deactivated.\n"); smpboot_clear_io_apic(); connect_bsp_APIC(); @@ -1003,7 +1013,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) if (smp_sanity_check(max_cpus) < 0) { - pr_info("SMP disabled\n"); + printk(KERN_INFO "SMP disabled\n"); disable_smp(); goto out; } @@ -1041,7 +1051,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) * Set up local APIC timer on boot CPU. */ - pr_info("CPU%d: ", 0); + printk(KERN_INFO "CPU%d: ", 0); print_cpu_info(&cpu_data(0)); x86_init.timers.setup_percpu_clockev(); @@ -1091,7 +1101,7 @@ void __init native_smp_prepare_boot_cpu(void) void __init native_smp_cpus_done(unsigned int max_cpus) { - pr_debug("Boot done\n"); + pr_debug("Boot done.\n"); nmi_selftest(); impress_friends(); @@ -1152,7 +1162,8 @@ __init void prefill_possible_map(void) /* nr_cpu_ids could be reduced via nr_cpus= */ if (possible > nr_cpu_ids) { - pr_warn("%d Processors exceeds NR_CPUS limit of %d\n", + printk(KERN_WARNING + "%d Processors exceeds NR_CPUS limit of %d\n", possible, nr_cpu_ids); possible = nr_cpu_ids; } @@ -1161,12 +1172,13 @@ __init void prefill_possible_map(void) if (!setup_max_cpus) #endif if (possible > i) { - pr_warn("%d Processors exceeds max_cpus limit of %u\n", + printk(KERN_WARNING + "%d Processors exceeds max_cpus limit of %u\n", possible, setup_max_cpus); possible = i; } - pr_info("Allowing %d CPUs, %d hotplug CPUs\n", + printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", possible, max_t(int, possible - num_processors, 0)); for (i = 0; i < possible; i++) diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index b481341c9369..05b31d92f69c 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -9,9 +9,6 @@ /* * Handle hardware traps and faults. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -146,11 +143,12 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, #ifdef CONFIG_X86_64 if (show_unhandled_signals && unhandled_signal(tsk, signr) && printk_ratelimit()) { - pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", - tsk->comm, tsk->pid, str, - regs->ip, regs->sp, error_code); + printk(KERN_INFO + "%s[%d] trap %s ip:%lx sp:%lx error:%lx", + tsk->comm, tsk->pid, str, + regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); - pr_cont("\n"); + printk("\n"); } #endif @@ -271,11 +269,12 @@ do_general_protection(struct pt_regs *regs, long error_code) if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && printk_ratelimit()) { - pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", + printk(KERN_INFO + "%s[%d] general protection ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); - pr_cont("\n"); + printk("\n"); } force_sig(SIGSEGV, tsk); @@ -571,7 +570,7 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) conditional_sti(regs); #if 0 /* No need to warn about this any longer. */ - pr_info("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); + printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); #endif } diff --git a/trunk/arch/x86/kernel/tsc.c b/trunk/arch/x86/kernel/tsc.c index cfa5d4f7ca56..fc0a147e3727 100644 --- a/trunk/arch/x86/kernel/tsc.c +++ b/trunk/arch/x86/kernel/tsc.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -86,7 +84,8 @@ EXPORT_SYMBOL_GPL(check_tsc_unstable); #ifdef CONFIG_X86_TSC int __init notsc_setup(char *str) { - pr_warn("Kernel compiled with CONFIG_X86_TSC, cannot disable TSC completely\n"); + printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " + "cannot disable TSC completely.\n"); tsc_disabled = 1; return 1; } @@ -374,7 +373,7 @@ static unsigned long quick_pit_calibrate(void) goto success; } } - pr_err("Fast TSC calibration failed\n"); + printk("Fast TSC calibration failed\n"); return 0; success: @@ -393,7 +392,7 @@ static unsigned long quick_pit_calibrate(void) */ delta *= PIT_TICK_RATE; do_div(delta, i*256*1000); - pr_info("Fast TSC calibration using PIT\n"); + printk("Fast TSC calibration using PIT\n"); return delta; } @@ -488,8 +487,9 @@ unsigned long native_calibrate_tsc(void) * use the reference value, as it is more precise. */ if (delta >= 90 && delta <= 110) { - pr_info("PIT calibration matches %s. %d loops\n", - hpet ? "HPET" : "PMTIMER", i + 1); + printk(KERN_INFO + "TSC: PIT calibration matches %s. %d loops\n", + hpet ? "HPET" : "PMTIMER", i + 1); return tsc_ref_min; } @@ -511,36 +511,38 @@ unsigned long native_calibrate_tsc(void) */ if (tsc_pit_min == ULONG_MAX) { /* PIT gave no useful value */ - pr_warn("Unable to calibrate against PIT\n"); + printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n"); /* We don't have an alternative source, disable TSC */ if (!hpet && !ref1 && !ref2) { - pr_notice("No reference (HPET/PMTIMER) available\n"); + printk("TSC: No reference (HPET/PMTIMER) available\n"); return 0; } /* The alternative source failed as well, disable TSC */ if (tsc_ref_min == ULONG_MAX) { - pr_warn("HPET/PMTIMER calibration failed\n"); + printk(KERN_WARNING "TSC: HPET/PMTIMER calibration " + "failed.\n"); return 0; } /* Use the alternative source */ - pr_info("using %s reference calibration\n", - hpet ? "HPET" : "PMTIMER"); + printk(KERN_INFO "TSC: using %s reference calibration\n", + hpet ? "HPET" : "PMTIMER"); return tsc_ref_min; } /* We don't have an alternative source, use the PIT calibration value */ if (!hpet && !ref1 && !ref2) { - pr_info("Using PIT calibration value\n"); + printk(KERN_INFO "TSC: Using PIT calibration value\n"); return tsc_pit_min; } /* The alternative source failed, use the PIT calibration value */ if (tsc_ref_min == ULONG_MAX) { - pr_warn("HPET/PMTIMER calibration failed. Using PIT calibration.\n"); + printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. " + "Using PIT calibration\n"); return tsc_pit_min; } @@ -549,9 +551,9 @@ unsigned long native_calibrate_tsc(void) * the PIT value as we know that there are PMTIMERs around * running at double speed. At least we let the user know: */ - pr_warn("PIT calibration deviates from %s: %lu %lu\n", - hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); - pr_info("Using PIT calibration value\n"); + printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n", + hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); + printk(KERN_INFO "TSC: Using PIT calibration value\n"); return tsc_pit_min; } @@ -783,7 +785,7 @@ void mark_tsc_unstable(char *reason) tsc_unstable = 1; sched_clock_stable = 0; disable_sched_clock_irqtime(); - pr_info("Marking TSC unstable due to %s\n", reason); + printk(KERN_INFO "Marking TSC unstable due to %s\n", reason); /* Change only the rating, when not registered */ if (clocksource_tsc.mult) clocksource_mark_unstable(&clocksource_tsc); @@ -910,9 +912,9 @@ static void tsc_refine_calibration_work(struct work_struct *work) goto out; tsc_khz = freq; - pr_info("Refined TSC clocksource calibration: %lu.%03lu MHz\n", - (unsigned long)tsc_khz / 1000, - (unsigned long)tsc_khz % 1000); + printk(KERN_INFO "Refined TSC clocksource calibration: " + "%lu.%03lu MHz.\n", (unsigned long)tsc_khz / 1000, + (unsigned long)tsc_khz % 1000); out: clocksource_register_khz(&clocksource_tsc, tsc_khz); @@ -968,9 +970,9 @@ void __init tsc_init(void) return; } - pr_info("Detected %lu.%03lu MHz processor\n", - (unsigned long)cpu_khz / 1000, - (unsigned long)cpu_khz % 1000); + printk("Detected %lu.%03lu MHz processor.\n", + (unsigned long)cpu_khz / 1000, + (unsigned long)cpu_khz % 1000); /* * Secondary CPUs do not run through tsc_init(), so set up diff --git a/trunk/arch/x86/kernel/uprobes.c b/trunk/arch/x86/kernel/uprobes.c index 36fd42091fa7..dc4e910a7d96 100644 --- a/trunk/arch/x86/kernel/uprobes.c +++ b/trunk/arch/x86/kernel/uprobes.c @@ -409,10 +409,9 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. * @mm: the probed address space. * @arch_uprobe: the probepoint information. - * @addr: virtual address at which to install the probepoint * Return 0 on success or a -ve number on error. */ -int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr) +int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm) { int ret; struct insn insn; diff --git a/trunk/arch/x86/kernel/vm86_32.c b/trunk/arch/x86/kernel/vm86_32.c index 54abcc0baf23..255f58ae71e8 100644 --- a/trunk/arch/x86/kernel/vm86_32.c +++ b/trunk/arch/x86/kernel/vm86_32.c @@ -28,8 +28,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -139,14 +137,14 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) local_irq_enable(); if (!current->thread.vm86_info) { - pr_alert("no vm86_info: BAD\n"); + printk("no vm86_info: BAD\n"); do_exit(SIGSEGV); } set_flags(regs->pt.flags, VEFLAGS, X86_EFLAGS_VIF | current->thread.v86mask); tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs, regs); tmp += put_user(current->thread.screen_bitmap, ¤t->thread.vm86_info->screen_bitmap); if (tmp) { - pr_alert("could not access userspace vm86_info\n"); + printk("vm86: could not access userspace vm86_info\n"); do_exit(SIGSEGV); } diff --git a/trunk/arch/x86/kernel/vsmp_64.c b/trunk/arch/x86/kernel/vsmp_64.c index 992f890283e9..8eeb55a551b4 100644 --- a/trunk/arch/x86/kernel/vsmp_64.c +++ b/trunk/arch/x86/kernel/vsmp_64.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -96,18 +95,6 @@ static void __init set_vsmp_pv_ops(void) ctl = readl(address + 4); printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n", cap, ctl); - - /* If possible, let the vSMP foundation route the interrupt optimally */ -#ifdef CONFIG_SMP - if (cap & ctl & BIT(8)) { - ctl &= ~BIT(8); -#ifdef CONFIG_PROC_FS - /* Don't let users change irq affinity via procfs */ - no_irq_affinity = 1; -#endif - } -#endif - if (cap & ctl & (1 << 4)) { /* Setup irq ops and turn on vSMP IRQ fastpath handling */ pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); @@ -115,11 +102,12 @@ static void __init set_vsmp_pv_ops(void) pv_irq_ops.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); pv_irq_ops.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); pv_init_ops.patch = vsmp_patch; + ctl &= ~(1 << 4); + writel(ctl, address + 4); + ctl = readl(address + 4); + printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl); } - writel(ctl, address + 4); - ctl = readl(address + 4); - pr_info("vSMP CTL: control set to:0x%08x\n", ctl); early_iounmap(address, 8); } @@ -199,36 +187,12 @@ static void __init vsmp_cap_cpus(void) #endif } -static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) -{ - return hard_smp_processor_id() >> index_msb; -} - -/* - * In vSMP, all cpus should be capable of handling interrupts, regardless of - * the APIC used. - */ -static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask, - const struct cpumask *mask) -{ - cpumask_setall(retmask); -} - -static void vsmp_apic_post_init(void) -{ - /* need to update phys_pkg_id */ - apic->phys_pkg_id = apicid_phys_pkg_id; - apic->vector_allocation_domain = fill_vector_allocation_domain; -} - void __init vsmp_init(void) { detect_vsmp_box(); if (!is_vsmp_box()) return; - x86_platform.apic_post_init = vsmp_apic_post_init; - vsmp_cap_cpus(); set_vsmp_pv_ops(); diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c index 8d141b309046..7515cf0e1805 100644 --- a/trunk/arch/x86/kernel/vsyscall_64.c +++ b/trunk/arch/x86/kernel/vsyscall_64.c @@ -18,8 +18,6 @@ * use the vDSO. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -113,13 +111,18 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, const char *message) { - if (!show_unhandled_signals) + static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); + struct task_struct *tsk; + + if (!show_unhandled_signals || !__ratelimit(&rs)) return; - pr_notice_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", - level, current->comm, task_pid_nr(current), - message, regs->ip, regs->cs, - regs->sp, regs->ax, regs->si, regs->di); + tsk = current; + + printk("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", + level, tsk->comm, task_pid_nr(tsk), + message, regs->ip, regs->cs, + regs->sp, regs->ax, regs->si, regs->di); } static int addr_to_vsyscall_nr(unsigned long addr) @@ -136,19 +139,6 @@ static int addr_to_vsyscall_nr(unsigned long addr) return nr; } -#ifdef CONFIG_SECCOMP -static int vsyscall_seccomp(struct task_struct *tsk, int syscall_nr) -{ - if (!seccomp_mode(&tsk->seccomp)) - return 0; - task_pt_regs(tsk)->orig_ax = syscall_nr; - task_pt_regs(tsk)->ax = syscall_nr; - return __secure_computing(syscall_nr); -} -#else -#define vsyscall_seccomp(_tsk, _nr) 0 -#endif - static bool write_ok_or_segv(unsigned long ptr, size_t size) { /* @@ -184,7 +174,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) int vsyscall_nr; int prev_sig_on_uaccess_error; long ret; - int skip; /* * No point in checking CS -- the only way to get here is a user mode @@ -216,6 +205,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) } tsk = current; + if (seccomp_mode(&tsk->seccomp)) + do_exit(SIGKILL); + /* * With a real vsyscall, page faults cause SIGSEGV. We want to * preserve that behavior to make writing exploits harder. @@ -230,13 +222,8 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) * address 0". */ ret = -EFAULT; - skip = 0; switch (vsyscall_nr) { case 0: - skip = vsyscall_seccomp(tsk, __NR_gettimeofday); - if (skip) - break; - if (!write_ok_or_segv(regs->di, sizeof(struct timeval)) || !write_ok_or_segv(regs->si, sizeof(struct timezone))) break; @@ -247,10 +234,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) break; case 1: - skip = vsyscall_seccomp(tsk, __NR_time); - if (skip) - break; - if (!write_ok_or_segv(regs->di, sizeof(time_t))) break; @@ -258,10 +241,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) break; case 2: - skip = vsyscall_seccomp(tsk, __NR_getcpu); - if (skip) - break; - if (!write_ok_or_segv(regs->di, sizeof(unsigned)) || !write_ok_or_segv(regs->si, sizeof(unsigned))) break; @@ -274,12 +253,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) current_thread_info()->sig_on_uaccess_error = prev_sig_on_uaccess_error; - if (skip) { - if ((long)regs->ax <= 0L) /* seccomp errno emulation */ - goto do_ret; - goto done; /* seccomp trace/trap */ - } - if (ret == -EFAULT) { /* Bad news -- userspace fed a bad pointer to a vsyscall. */ warn_bad_vsyscall(KERN_INFO, regs, @@ -298,11 +271,10 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) regs->ax = ret; -do_ret: /* Emulate a ret instruction. */ regs->ip = caller; regs->sp += 8; -done: + return true; sigsegv: diff --git a/trunk/arch/x86/kernel/x8664_ksyms_64.c b/trunk/arch/x86/kernel/x8664_ksyms_64.c index 6020f6f5927c..9796c2f3d074 100644 --- a/trunk/arch/x86/kernel/x8664_ksyms_64.c +++ b/trunk/arch/x86/kernel/x8664_ksyms_64.c @@ -28,7 +28,6 @@ EXPORT_SYMBOL(__put_user_8); EXPORT_SYMBOL(copy_user_generic_string); EXPORT_SYMBOL(copy_user_generic_unrolled); -EXPORT_SYMBOL(copy_user_enhanced_fast_string); EXPORT_SYMBOL(__copy_user_nocache); EXPORT_SYMBOL(_copy_from_user); EXPORT_SYMBOL(_copy_to_user); diff --git a/trunk/arch/x86/kernel/x86_init.c b/trunk/arch/x86/kernel/x86_init.c index 9f3167e891ef..35c5e543f550 100644 --- a/trunk/arch/x86/kernel/x86_init.c +++ b/trunk/arch/x86/kernel/x86_init.c @@ -29,6 +29,7 @@ void __init x86_init_uint_noop(unsigned int unused) { } void __init x86_init_pgd_noop(pgd_t *unused) { } int __init iommu_init_noop(void) { return 0; } void iommu_shutdown_noop(void) { } +void wallclock_init_noop(void) { } /* * The platform setup functions are preset with the default functions @@ -100,6 +101,7 @@ static int default_i8042_detect(void) { return 1; }; struct x86_platform_ops x86_platform = { .calibrate_tsc = native_calibrate_tsc, + .wallclock_init = wallclock_init_noop, .get_wallclock = mach_get_cmos_time, .set_wallclock = mach_set_rtc_mmss, .iommu_shutdown = iommu_shutdown_noop, diff --git a/trunk/arch/x86/kernel/xsave.c b/trunk/arch/x86/kernel/xsave.c index 3d3e20709119..bd18149b2b0f 100644 --- a/trunk/arch/x86/kernel/xsave.c +++ b/trunk/arch/x86/kernel/xsave.c @@ -3,9 +3,6 @@ * * Author: Suresh Siddha */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -165,7 +162,7 @@ int save_i387_xstate(void __user *buf) BUG_ON(sig_xstate_size < xstate_size); if ((unsigned long)buf % 64) - pr_err("%s: bad fpstate %p\n", __func__, buf); + printk("save_i387_xstate: bad fpstate %p\n", buf); if (!used_math()) return 0; @@ -425,7 +422,7 @@ static void __init xstate_enable_boot_cpu(void) pcntxt_mask = eax + ((u64)edx << 32); if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) { - pr_err("FP/SSE not shown under xsave features 0x%llx\n", + printk(KERN_ERR "FP/SSE not shown under xsave features 0x%llx\n", pcntxt_mask); BUG(); } @@ -448,8 +445,9 @@ static void __init xstate_enable_boot_cpu(void) setup_xstate_init(); - pr_info("enabled xstate_bv 0x%llx, cntxt size 0x%x\n", - pcntxt_mask, xstate_size); + printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%llx, " + "cntxt size 0x%x\n", + pcntxt_mask, xstate_size); } /* diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 57e168e27b5b..be3cea4407ff 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -3934,9 +3934,6 @@ static void kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm, { struct kvm_mmu_page *page; - if (list_empty(&kvm->arch.active_mmu_pages)) - return; - page = container_of(kvm->arch.active_mmu_pages.prev, struct kvm_mmu_page, link); kvm_mmu_prepare_zap_page(kvm, page, invalid_list); diff --git a/trunk/arch/x86/kvm/pmu.c b/trunk/arch/x86/kvm/pmu.c index 9b7ec1150ab0..2e88438ffd83 100644 --- a/trunk/arch/x86/kvm/pmu.c +++ b/trunk/arch/x86/kvm/pmu.c @@ -80,10 +80,10 @@ static inline struct kvm_pmc *get_fixed_pmc_idx(struct kvm_pmu *pmu, int idx) static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx) { - if (idx < INTEL_PMC_IDX_FIXED) + if (idx < X86_PMC_IDX_FIXED) return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0); else - return get_fixed_pmc_idx(pmu, idx - INTEL_PMC_IDX_FIXED); + return get_fixed_pmc_idx(pmu, idx - X86_PMC_IDX_FIXED); } void kvm_deliver_pmi(struct kvm_vcpu *vcpu) @@ -291,7 +291,7 @@ static void reprogram_idx(struct kvm_pmu *pmu, int idx) if (pmc_is_gp(pmc)) reprogram_gp_counter(pmc, pmc->eventsel); else { - int fidx = idx - INTEL_PMC_IDX_FIXED; + int fidx = idx - X86_PMC_IDX_FIXED; reprogram_fixed_counter(pmc, fixed_en_pmi(pmu->fixed_ctr_ctrl, fidx), fidx); } @@ -452,7 +452,7 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) return; pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff, - INTEL_PMC_MAX_GENERIC); + X86_PMC_MAX_GENERIC); pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1; bitmap_len = (entry->eax >> 24) & 0xff; @@ -462,13 +462,13 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) pmu->nr_arch_fixed_counters = 0; } else { pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), - INTEL_PMC_MAX_FIXED); + X86_PMC_MAX_FIXED); pmu->counter_bitmask[KVM_PMC_FIXED] = ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; } pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | - (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED); + (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); pmu->global_ctrl_mask = ~pmu->global_ctrl; } @@ -478,15 +478,15 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu) struct kvm_pmu *pmu = &vcpu->arch.pmu; memset(pmu, 0, sizeof(*pmu)); - for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) { + for (i = 0; i < X86_PMC_MAX_GENERIC; i++) { pmu->gp_counters[i].type = KVM_PMC_GP; pmu->gp_counters[i].vcpu = vcpu; pmu->gp_counters[i].idx = i; } - for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) { + for (i = 0; i < X86_PMC_MAX_FIXED; i++) { pmu->fixed_counters[i].type = KVM_PMC_FIXED; pmu->fixed_counters[i].vcpu = vcpu; - pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED; + pmu->fixed_counters[i].idx = i + X86_PMC_IDX_FIXED; } init_irq_work(&pmu->irq_work, trigger_pmi); kvm_pmu_cpuid_update(vcpu); @@ -498,13 +498,13 @@ void kvm_pmu_reset(struct kvm_vcpu *vcpu) int i; irq_work_sync(&pmu->irq_work); - for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) { + for (i = 0; i < X86_PMC_MAX_GENERIC; i++) { struct kvm_pmc *pmc = &pmu->gp_counters[i]; stop_counter(pmc); pmc->counter = pmc->eventsel = 0; } - for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) + for (i = 0; i < X86_PMC_MAX_FIXED; i++) stop_counter(&pmu->fixed_counters[i]); pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = diff --git a/trunk/arch/x86/kvm/trace.h b/trunk/arch/x86/kvm/trace.h index 62d02e3c3ed6..911d2641f14c 100644 --- a/trunk/arch/x86/kvm/trace.h +++ b/trunk/arch/x86/kvm/trace.h @@ -710,6 +710,16 @@ TRACE_EVENT(kvm_skinit, __entry->rip, __entry->slb) ); +#define __print_insn(insn, ilen) ({ \ + int i; \ + const char *ret = p->buffer + p->len; \ + \ + for (i = 0; i < ilen; ++i) \ + trace_seq_printf(p, " %02x", insn[i]); \ + trace_seq_printf(p, "%c", 0); \ + ret; \ + }) + #define KVM_EMUL_INSN_F_CR0_PE (1 << 0) #define KVM_EMUL_INSN_F_EFL_VM (1 << 1) #define KVM_EMUL_INSN_F_CS_D (1 << 2) @@ -776,7 +786,7 @@ TRACE_EVENT(kvm_emulate_insn, TP_printk("%x:%llx:%s (%s)%s", __entry->csbase, __entry->rip, - __print_hex(__entry->insn, __entry->len), + __print_insn(__entry->insn, __entry->len), __print_symbolic(__entry->flags, kvm_trace_symbol_emul_flags), __entry->failed ? " failed" : "" diff --git a/trunk/arch/x86/lib/csum-wrappers_64.c b/trunk/arch/x86/lib/csum-wrappers_64.c index 25b7ae8d058a..459b58a8a15c 100644 --- a/trunk/arch/x86/lib/csum-wrappers_64.c +++ b/trunk/arch/x86/lib/csum-wrappers_64.c @@ -115,7 +115,7 @@ EXPORT_SYMBOL(csum_partial_copy_to_user); * @src: source address * @dst: destination address * @len: number of bytes to be copied. - * @sum: initial sum that is added into the result (32bit unfolded) + * @isum: initial sum that is added into the result (32bit unfolded) * * Returns an 32bit unfolded checksum of the buffer. */ diff --git a/trunk/arch/x86/lib/msr-reg-export.c b/trunk/arch/x86/lib/msr-reg-export.c index 8d6ef78b5d01..a311cc59b65d 100644 --- a/trunk/arch/x86/lib/msr-reg-export.c +++ b/trunk/arch/x86/lib/msr-reg-export.c @@ -1,5 +1,5 @@ #include #include -EXPORT_SYMBOL(rdmsr_safe_regs); -EXPORT_SYMBOL(wrmsr_safe_regs); +EXPORT_SYMBOL(native_rdmsr_safe_regs); +EXPORT_SYMBOL(native_wrmsr_safe_regs); diff --git a/trunk/arch/x86/lib/msr-reg.S b/trunk/arch/x86/lib/msr-reg.S index f6d13eefad10..69fa10623f21 100644 --- a/trunk/arch/x86/lib/msr-reg.S +++ b/trunk/arch/x86/lib/msr-reg.S @@ -6,13 +6,13 @@ #ifdef CONFIG_X86_64 /* - * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); + * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); * * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] * */ .macro op_safe_regs op -ENTRY(\op\()_safe_regs) +ENTRY(native_\op\()_safe_regs) CFI_STARTPROC pushq_cfi %rbx pushq_cfi %rbp @@ -45,13 +45,13 @@ ENTRY(\op\()_safe_regs) _ASM_EXTABLE(1b, 3b) CFI_ENDPROC -ENDPROC(\op\()_safe_regs) +ENDPROC(native_\op\()_safe_regs) .endm #else /* X86_32 */ .macro op_safe_regs op -ENTRY(\op\()_safe_regs) +ENTRY(native_\op\()_safe_regs) CFI_STARTPROC pushl_cfi %ebx pushl_cfi %ebp @@ -92,7 +92,7 @@ ENTRY(\op\()_safe_regs) _ASM_EXTABLE(1b, 3b) CFI_ENDPROC -ENDPROC(\op\()_safe_regs) +ENDPROC(native_\op\()_safe_regs) .endm #endif diff --git a/trunk/arch/x86/lib/usercopy.c b/trunk/arch/x86/lib/usercopy.c index 4f74d94c8d97..f61ee67ec00f 100644 --- a/trunk/arch/x86/lib/usercopy.c +++ b/trunk/arch/x86/lib/usercopy.c @@ -8,7 +8,6 @@ #include #include -#include /* * best effort, GUP based copy_from_user() that is NMI-safe @@ -22,9 +21,6 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) void *map; int ret; - if (__range_not_ok(from, n, TASK_SIZE)) - return len; - do { ret = __get_user_pages_fast(addr, 1, 0, &page); if (!ret) diff --git a/trunk/arch/x86/lib/x86-opcode-map.txt b/trunk/arch/x86/lib/x86-opcode-map.txt index 5d7e51f3fd28..819137904428 100644 --- a/trunk/arch/x86/lib/x86-opcode-map.txt +++ b/trunk/arch/x86/lib/x86-opcode-map.txt @@ -28,7 +28,7 @@ # - (66): the last prefix is 0x66 # - (F3): the last prefix is 0xF3 # - (F2): the last prefix is 0xF2 -# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) +# Table: one byte opcode Referrer: @@ -515,12 +515,12 @@ b4: LFS Gv,Mp b5: LGS Gv,Mp b6: MOVZX Gv,Eb b7: MOVZX Gv,Ew -b8: JMPE (!F3) | POPCNT Gv,Ev (F3) +b8: JMPE | POPCNT Gv,Ev (F3) b9: Grp10 (1A) ba: Grp8 Ev,Ib (1A) bb: BTC Ev,Gv -bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) -bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) +bc: BSF Gv,Ev | TZCNT Gv,Ev (F3) +bd: BSR Gv,Ev | LZCNT Gv,Ev (F3) be: MOVSX Gv,Eb bf: MOVSX Gv,Ew # 0x0f 0xc0-0xcf diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index e0e6990723e9..97141c26a13a 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -62,8 +62,7 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en extra += PMD_SIZE; #endif /* The first 2/4M doesn't use large pages. */ - if (mr->start < PMD_SIZE) - extra += mr->end - mr->start; + extra += mr->end - mr->start; ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; } else @@ -385,7 +384,7 @@ void free_initmem(void) } #ifdef CONFIG_BLK_DEV_INITRD -void __init free_initrd_mem(unsigned long start, unsigned long end) +void free_initrd_mem(unsigned long start, unsigned long end) { /* * end could be not aligned, and We can not align that, diff --git a/trunk/arch/x86/mm/ioremap.c b/trunk/arch/x86/mm/ioremap.c index 78fe3f1ac49f..be1ef574ce9a 100644 --- a/trunk/arch/x86/mm/ioremap.c +++ b/trunk/arch/x86/mm/ioremap.c @@ -180,7 +180,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, /** * ioremap_nocache - map bus memory into CPU space - * @phys_addr: bus address of the memory + * @offset: bus address of the memory * @size: size of the resource to map * * ioremap_nocache performs a platform specific sequence of operations to @@ -217,7 +217,7 @@ EXPORT_SYMBOL(ioremap_nocache); /** * ioremap_wc - map memory into CPU space write combined - * @phys_addr: bus address of the memory + * @offset: bus address of the memory * @size: size of the resource to map * * This version of ioremap ensures that the memory is marked write combining. diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index a718e0d23503..e1ebde315210 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -122,7 +122,7 @@ within(unsigned long addr, unsigned long start, unsigned long end) /** * clflush_cache_range - flush a cache range with clflush - * @vaddr: virtual start address + * @addr: virtual start address * @size: number of bytes to flush * * clflush is an unordered instruction which needs fencing with mfence diff --git a/trunk/arch/x86/mm/srat.c b/trunk/arch/x86/mm/srat.c index 4599c3e8bcb6..732af3a96183 100644 --- a/trunk/arch/x86/mm/srat.c +++ b/trunk/arch/x86/mm/srat.c @@ -176,8 +176,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) return; } - node_set(node, numa_nodes_parsed); - printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", node, pxm, (unsigned long long) start, (unsigned long long) end - 1); diff --git a/trunk/arch/x86/oprofile/op_model_amd.c b/trunk/arch/x86/oprofile/op_model_amd.c index b2b94438ff05..303f08637826 100644 --- a/trunk/arch/x86/oprofile/op_model_amd.c +++ b/trunk/arch/x86/oprofile/op_model_amd.c @@ -312,7 +312,7 @@ static int op_amd_fill_in_addresses(struct op_msrs * const msrs) goto fail; } /* both registers must be reserved */ - if (num_counters == AMD64_NUM_COUNTERS_CORE) { + if (num_counters == AMD64_NUM_COUNTERS_F15H) { msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); } else { @@ -514,7 +514,7 @@ static int op_amd_init(struct oprofile_operations *ops) ops->create_files = setup_ibs_files; if (boot_cpu_data.x86 == 0x15) { - num_counters = AMD64_NUM_COUNTERS_CORE; + num_counters = AMD64_NUM_COUNTERS_F15H; } else { num_counters = AMD64_NUM_COUNTERS; } diff --git a/trunk/arch/x86/platform/mrst/early_printk_mrst.c b/trunk/arch/x86/platform/mrst/early_printk_mrst.c index 028454f0c3a5..3c6e328483c7 100644 --- a/trunk/arch/x86/platform/mrst/early_printk_mrst.c +++ b/trunk/arch/x86/platform/mrst/early_printk_mrst.c @@ -110,16 +110,19 @@ static struct kmsg_dumper dw_dumper; static int dumper_registered; static void dw_kmsg_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason) + enum kmsg_dump_reason reason, + const char *s1, unsigned long l1, + const char *s2, unsigned long l2) { - static char line[1024]; - size_t len; + int i; /* When run to this, we'd better re-init the HW */ mrst_early_console_init(); - while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) - early_mrst_console.write(&early_mrst_console, line, len); + for (i = 0; i < l1; i++) + early_mrst_console.write(&early_mrst_console, s1 + i, 1); + for (i = 0; i < l2; i++) + early_mrst_console.write(&early_mrst_console, s2 + i, 1); } /* Set the ratio rate to 115200, 8n1, IRQ disabled */ diff --git a/trunk/arch/x86/platform/mrst/mrst.c b/trunk/arch/x86/platform/mrst/mrst.c index fd41a9262d65..e31bcd8f2eee 100644 --- a/trunk/arch/x86/platform/mrst/mrst.c +++ b/trunk/arch/x86/platform/mrst/mrst.c @@ -782,7 +782,7 @@ BLOCKING_NOTIFIER_HEAD(intel_scu_notifier); EXPORT_SYMBOL_GPL(intel_scu_notifier); /* Called by IPC driver */ -void __devinit intel_scu_devices_create(void) +void intel_scu_devices_create(void) { int i; diff --git a/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c b/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c index 599be499fdf7..23e5b9d7977b 100644 --- a/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/trunk/arch/x86/platform/olpc/olpc-xo15-sci.c @@ -203,7 +203,7 @@ static int xo15_sci_remove(struct acpi_device *device, int type) return 0; } -static int xo15_sci_resume(struct device *dev) +static int xo15_sci_resume(struct acpi_device *device) { /* Enable all EC events */ olpc_ec_mask_write(EC_SCI_SRC_ALL); @@ -215,8 +215,6 @@ static int xo15_sci_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume); - static const struct acpi_device_id xo15_sci_device_ids[] = { {"XO15EC", 0}, {"", 0}, @@ -229,8 +227,8 @@ static struct acpi_driver xo15_sci_drv = { .ops = { .add = xo15_sci_add, .remove = xo15_sci_remove, + .resume = xo15_sci_resume, }, - .drv.pm = &xo15_sci_pm, }; static int __init xo15_sci_init(void) diff --git a/trunk/arch/x86/platform/uv/tlb_uv.c b/trunk/arch/x86/platform/uv/tlb_uv.c index 71b5d5a07d7b..3ae0e61abd23 100644 --- a/trunk/arch/x86/platform/uv/tlb_uv.c +++ b/trunk/arch/x86/platform/uv/tlb_uv.c @@ -1,7 +1,7 @@ /* * SGI UltraViolet TLB flush routines. * - * (c) 2008-2012 Cliff Wickman , SGI. + * (c) 2008-2011 Cliff Wickman , SGI. * * This code is released under the GNU General Public License version 2 or * later. @@ -38,7 +38,8 @@ static int timeout_base_ns[] = { static int timeout_us; static int nobau; -static int nobau_perm; +static int baudisabled; +static spinlock_t disable_lock; static cycles_t congested_cycles; /* tunables: */ @@ -46,13 +47,12 @@ static int max_concurr = MAX_BAU_CONCURRENT; static int max_concurr_const = MAX_BAU_CONCURRENT; static int plugged_delay = PLUGGED_DELAY; static int plugsb4reset = PLUGSB4RESET; -static int giveup_limit = GIVEUP_LIMIT; static int timeoutsb4reset = TIMEOUTSB4RESET; static int ipi_reset_limit = IPI_RESET_LIMIT; static int complete_threshold = COMPLETE_THRESHOLD; static int congested_respns_us = CONGESTED_RESPONSE_US; static int congested_reps = CONGESTED_REPS; -static int disabled_period = DISABLED_PERIOD; +static int congested_period = CONGESTED_PERIOD; static struct tunables tunables[] = { {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ @@ -63,8 +63,7 @@ static struct tunables tunables[] = { {&complete_threshold, COMPLETE_THRESHOLD}, {&congested_respns_us, CONGESTED_RESPONSE_US}, {&congested_reps, CONGESTED_REPS}, - {&disabled_period, DISABLED_PERIOD}, - {&giveup_limit, GIVEUP_LIMIT} + {&congested_period, CONGESTED_PERIOD} }; static struct dentry *tunables_dir; @@ -121,40 +120,6 @@ static DEFINE_PER_CPU(struct ptc_stats, ptcstats); static DEFINE_PER_CPU(struct bau_control, bau_control); static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); -static void -set_bau_on(void) -{ - int cpu; - struct bau_control *bcp; - - if (nobau_perm) { - pr_info("BAU not initialized; cannot be turned on\n"); - return; - } - nobau = 0; - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - bcp->nobau = 0; - } - pr_info("BAU turned on\n"); - return; -} - -static void -set_bau_off(void) -{ - int cpu; - struct bau_control *bcp; - - nobau = 1; - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - bcp->nobau = 1; - } - pr_info("BAU turned off\n"); - return; -} - /* * Determine the first node on a uvhub. 'Nodes' are used for kernel * memory allocation. @@ -313,7 +278,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, * Both sockets dump their completed count total into * the message's count. */ - *sp = 0; + smaster->socket_acknowledge_count[mdp->msg_slot] = 0; asp = (struct atomic_short *)&msg->acknowledge_count; msg_ack_count = atom_asr(socket_ack_count, asp); @@ -526,15 +491,16 @@ static int uv1_wait_completion(struct bau_desc *bau_desc, } /* - * UV2 could have an extra bit of status in the ACTIVATION_STATUS_2 register. - * But not currently used. + * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register. */ static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc) { unsigned long descriptor_status; + unsigned long descriptor_status2; - descriptor_status = - ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK) << 1; + descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK); + descriptor_status2 = (read_mmr_uv2_status() >> desc) & 0x1UL; + descriptor_status = (descriptor_status << 1) | descriptor_status2; return descriptor_status; } @@ -565,11 +531,87 @@ int normal_busy(struct bau_control *bcp) */ int handle_uv2_busy(struct bau_control *bcp) { + int busy_one = bcp->using_desc; + int normal = bcp->uvhub_cpu; + int selected = -1; + int i; + unsigned long descriptor_status; + unsigned long status; + int mmr_offset; + struct bau_desc *bau_desc_old; + struct bau_desc *bau_desc_new; + struct bau_control *hmaster = bcp->uvhub_master; struct ptc_stats *stat = bcp->statp; + cycles_t ttm; stat->s_uv2_wars++; - bcp->busy = 1; - return FLUSH_GIVEUP; + spin_lock(&hmaster->uvhub_lock); + /* try for the original first */ + if (busy_one != normal) { + if (!normal_busy(bcp)) + selected = normal; + } + if (selected < 0) { + /* can't use the normal, select an alternate */ + mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; + descriptor_status = read_lmmr(mmr_offset); + + /* scan available descriptors 32-63 */ + for (i = 0; i < UV_CPUS_PER_AS; i++) { + if ((hmaster->inuse_map & (1 << i)) == 0) { + status = ((descriptor_status >> + (i * UV_ACT_STATUS_SIZE)) & + UV_ACT_STATUS_MASK) << 1; + if (status != UV2H_DESC_BUSY) { + selected = i + UV_CPUS_PER_AS; + break; + } + } + } + } + + if (busy_one != normal) + /* mark the busy alternate as not in-use */ + hmaster->inuse_map &= ~(1 << (busy_one - UV_CPUS_PER_AS)); + + if (selected >= 0) { + /* switch to the selected descriptor */ + if (selected != normal) { + /* set the selected alternate as in-use */ + hmaster->inuse_map |= + (1 << (selected - UV_CPUS_PER_AS)); + if (selected > stat->s_uv2_wars_hw) + stat->s_uv2_wars_hw = selected; + } + bau_desc_old = bcp->descriptor_base; + bau_desc_old += (ITEMS_PER_DESC * busy_one); + bcp->using_desc = selected; + bau_desc_new = bcp->descriptor_base; + bau_desc_new += (ITEMS_PER_DESC * selected); + *bau_desc_new = *bau_desc_old; + } else { + /* + * All are busy. Wait for the normal one for this cpu to + * free up. + */ + stat->s_uv2_war_waits++; + spin_unlock(&hmaster->uvhub_lock); + ttm = get_cycles(); + do { + cpu_relax(); + } while (normal_busy(bcp)); + spin_lock(&hmaster->uvhub_lock); + /* switch to the original descriptor */ + bcp->using_desc = normal; + bau_desc_old = bcp->descriptor_base; + bau_desc_old += (ITEMS_PER_DESC * bcp->using_desc); + bcp->using_desc = (ITEMS_PER_DESC * normal); + bau_desc_new = bcp->descriptor_base; + bau_desc_new += (ITEMS_PER_DESC * normal); + *bau_desc_new = *bau_desc_old; /* copy the entire descriptor */ + } + spin_unlock(&hmaster->uvhub_lock); + return FLUSH_RETRY_BUSYBUG; } static int uv2_wait_completion(struct bau_desc *bau_desc, @@ -578,7 +620,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, { unsigned long descriptor_stat; cycles_t ttm; - int desc = bcp->uvhub_cpu; + int desc = bcp->using_desc; long busy_reps = 0; struct ptc_stats *stat = bcp->statp; @@ -586,38 +628,24 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, /* spin on the status MMR, waiting for it to go idle */ while (descriptor_stat != UV2H_DESC_IDLE) { - if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT)) { - /* - * A h/w bug on the destination side may - * have prevented the message being marked - * pending, thus it doesn't get replied to - * and gets continually nacked until it times - * out with a SOURCE_TIMEOUT. - */ + /* + * Our software ack messages may be blocked because + * there are no swack resources available. As long + * as none of them has timed out hardware will NACK + * our message and its state will stay IDLE. + */ + if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) || + (descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) { stat->s_stimeout++; return FLUSH_GIVEUP; + } else if (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) { + stat->s_strongnacks++; + bcp->conseccompletes = 0; + return FLUSH_GIVEUP; } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { - ttm = get_cycles(); - - /* - * Our retries may be blocked by all destination - * swack resources being consumed, and a timeout - * pending. In that case hardware returns the - * ERROR that looks like a destination timeout. - * Without using the extended status we have to - * deduce from the short time that this was a - * strong nack. - */ - if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { - bcp->conseccompletes = 0; - stat->s_plugged++; - /* FLUSH_RETRY_PLUGGED causes hang on boot */ - return FLUSH_GIVEUP; - } stat->s_dtimeout++; bcp->conseccompletes = 0; - /* FLUSH_RETRY_TIMEOUT causes hang on boot */ - return FLUSH_GIVEUP; + return FLUSH_RETRY_TIMEOUT; } else { busy_reps++; if (busy_reps > 1000000) { @@ -625,8 +653,9 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, busy_reps = 0; ttm = get_cycles(); if ((ttm - bcp->send_message) > - bcp->timeout_interval) + (bcp->clocks_per_100_usec)) { return handle_uv2_busy(bcp); + } } /* * descriptor_stat is still BUSY @@ -650,7 +679,7 @@ static int wait_completion(struct bau_desc *bau_desc, { int right_shift; unsigned long mmr_offset; - int desc = bcp->uvhub_cpu; + int desc = bcp->using_desc; if (desc < UV_CPUS_PER_AS) { mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; @@ -729,31 +758,33 @@ static void destination_timeout(struct bau_desc *bau_desc, } /* - * Stop all cpus on a uvhub from using the BAU for a period of time. - * This is reversed by check_enable. + * Completions are taking a very long time due to a congested numalink + * network. */ -static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) +static void disable_for_congestion(struct bau_control *bcp, + struct ptc_stats *stat) { - int tcpu; - struct bau_control *tbcp; - struct bau_control *hmaster; - cycles_t tm1; - - hmaster = bcp->uvhub_master; - spin_lock(&hmaster->disable_lock); - if (!bcp->baudisabled) { + /* let only one cpu do this disabling */ + spin_lock(&disable_lock); + + if (!baudisabled && bcp->period_requests && + ((bcp->period_time / bcp->period_requests) > congested_cycles)) { + int tcpu; + struct bau_control *tbcp; + /* it becomes this cpu's job to turn on the use of the + BAU again */ + baudisabled = 1; + bcp->set_bau_off = 1; + bcp->set_bau_on_time = get_cycles(); + bcp->set_bau_on_time += sec_2_cycles(bcp->cong_period); stat->s_bau_disabled++; - tm1 = get_cycles(); for_each_present_cpu(tcpu) { tbcp = &per_cpu(bau_control, tcpu); - if (tbcp->uvhub_master == hmaster) { - tbcp->baudisabled = 1; - tbcp->set_bau_on_time = - tm1 + bcp->disabled_period; - } + tbcp->baudisabled = 1; } } - spin_unlock(&hmaster->disable_lock); + + spin_unlock(&disable_lock); } static void count_max_concurr(int stat, struct bau_control *bcp, @@ -784,30 +815,16 @@ static void record_send_stats(cycles_t time1, cycles_t time2, bcp->period_requests++; bcp->period_time += elapsed; if ((elapsed > congested_cycles) && - (bcp->period_requests > bcp->cong_reps) && - ((bcp->period_time / bcp->period_requests) > - congested_cycles)) { - stat->s_congested++; - disable_for_period(bcp, stat); - } + (bcp->period_requests > bcp->cong_reps)) + disable_for_congestion(bcp, stat); } } else stat->s_requestor--; if (completion_status == FLUSH_COMPLETE && try > 1) stat->s_retriesok++; - else if (completion_status == FLUSH_GIVEUP) { + else if (completion_status == FLUSH_GIVEUP) stat->s_giveup++; - if (get_cycles() > bcp->period_end) - bcp->period_giveups = 0; - bcp->period_giveups++; - if (bcp->period_giveups == 1) - bcp->period_end = get_cycles() + bcp->disabled_period; - if (bcp->period_giveups > bcp->giveup_limit) { - disable_for_period(bcp, stat); - stat->s_giveuplimit++; - } - } } /* @@ -851,8 +868,7 @@ static void handle_cmplt(int completion_status, struct bau_desc *bau_desc, * Returns 1 if it gives up entirely and the original cpu mask is to be * returned to the kernel. */ -int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp, - struct bau_desc *bau_desc) +int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) { int seq_number = 0; int completion_stat = 0; @@ -865,23 +881,24 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp, struct bau_control *hmaster = bcp->uvhub_master; struct uv1_bau_msg_header *uv1_hdr = NULL; struct uv2_bau_msg_header *uv2_hdr = NULL; + struct bau_desc *bau_desc; - if (bcp->uvhub_version == 1) { - uv1 = 1; + if (bcp->uvhub_version == 1) uv1_throttle(hmaster, stat); - } while (hmaster->uvhub_quiesce) cpu_relax(); time1 = get_cycles(); - if (uv1) - uv1_hdr = &bau_desc->header.uv1_hdr; - else - uv2_hdr = &bau_desc->header.uv2_hdr; - do { - if (try == 0) { + bau_desc = bcp->descriptor_base; + bau_desc += (ITEMS_PER_DESC * bcp->using_desc); + if (bcp->uvhub_version == 1) { + uv1 = 1; + uv1_hdr = &bau_desc->header.uv1_hdr; + } else + uv2_hdr = &bau_desc->header.uv2_hdr; + if ((try == 0) || (completion_stat == FLUSH_RETRY_BUSYBUG)) { if (uv1) uv1_hdr->msg_type = MSG_REGULAR; else @@ -899,24 +916,25 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp, uv1_hdr->sequence = seq_number; else uv2_hdr->sequence = seq_number; - index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; + index = (1UL << AS_PUSH_SHIFT) | bcp->using_desc; bcp->send_message = get_cycles(); write_mmr_activation(index); try++; completion_stat = wait_completion(bau_desc, bcp, try); + /* UV2: wait_completion() may change the bcp->using_desc */ handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { bcp->ipi_attempts = 0; - stat->s_overipilimit++; completion_stat = FLUSH_GIVEUP; break; } cpu_relax(); } while ((completion_stat == FLUSH_RETRY_PLUGGED) || + (completion_stat == FLUSH_RETRY_BUSYBUG) || (completion_stat == FLUSH_RETRY_TIMEOUT)); time2 = get_cycles(); @@ -937,33 +955,28 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp, } /* - * The BAU is disabled for this uvhub. When the disabled time period has - * expired re-enable it. - * Return 0 if it is re-enabled for all cpus on this uvhub. + * The BAU is disabled. When the disabled time period has expired, the cpu + * that disabled it must re-enable it. + * Return 0 if it is re-enabled for all cpus. */ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) { int tcpu; struct bau_control *tbcp; - struct bau_control *hmaster; - hmaster = bcp->uvhub_master; - spin_lock(&hmaster->disable_lock); - if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { - stat->s_bau_reenabled++; - for_each_present_cpu(tcpu) { - tbcp = &per_cpu(bau_control, tcpu); - if (tbcp->uvhub_master == hmaster) { + if (bcp->set_bau_off) { + if (get_cycles() >= bcp->set_bau_on_time) { + stat->s_bau_reenabled++; + baudisabled = 0; + for_each_present_cpu(tcpu) { + tbcp = &per_cpu(bau_control, tcpu); tbcp->baudisabled = 0; tbcp->period_requests = 0; tbcp->period_time = 0; - tbcp->period_giveups = 0; } + return 0; } - spin_unlock(&hmaster->disable_lock); - return 0; } - spin_unlock(&hmaster->disable_lock); return -1; } @@ -1065,32 +1078,18 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct cpumask *flush_mask; struct ptc_stats *stat; struct bau_control *bcp; - unsigned long descriptor_status; - unsigned long status; - bcp = &per_cpu(bau_control, cpu); - stat = bcp->statp; - stat->s_enters++; - - if (bcp->nobau) + /* kernel was booted 'nobau' */ + if (nobau) return cpumask; - if (bcp->busy) { - descriptor_status = - read_lmmr(UVH_LB_BAU_SB_ACTIVATION_STATUS_0); - status = ((descriptor_status >> (bcp->uvhub_cpu * - UV_ACT_STATUS_SIZE)) & UV_ACT_STATUS_MASK) << 1; - if (status == UV2H_DESC_BUSY) - return cpumask; - bcp->busy = 0; - } + bcp = &per_cpu(bau_control, cpu); + stat = bcp->statp; /* bau was disabled due to slow response */ if (bcp->baudisabled) { - if (check_enable(bcp, stat)) { - stat->s_ipifordisabled++; + if (check_enable(bcp, stat)) return cpumask; - } } /* @@ -1106,7 +1105,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, stat->s_ntargself++; bau_desc = bcp->descriptor_base; - bau_desc += (ITEMS_PER_DESC * bcp->uvhub_cpu); + bau_desc += (ITEMS_PER_DESC * bcp->using_desc); bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) return NULL; @@ -1119,27 +1118,25 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, * uv_flush_send_and_wait returns 0 if all cpu's were messaged, * or 1 if it gave up and the original cpumask should be returned. */ - if (!uv_flush_send_and_wait(flush_mask, bcp, bau_desc)) + if (!uv_flush_send_and_wait(flush_mask, bcp)) return NULL; else return cpumask; } /* - * Search the message queue for any 'other' unprocessed message with the - * same software acknowledge resource bit vector as the 'msg' message. + * Search the message queue for any 'other' message with the same software + * acknowledge resource bit vector. */ struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg, - struct bau_control *bcp) + struct bau_control *bcp, unsigned char swack_vec) { struct bau_pq_entry *msg_next = msg + 1; - unsigned char swack_vec = msg->swack_vec; if (msg_next > bcp->queue_last) msg_next = bcp->queue_first; - while (msg_next != msg) { - if ((msg_next->canceled == 0) && (msg_next->replied_to == 0) && - (msg_next->swack_vec == swack_vec)) + while ((msg_next->swack_vec != 0) && (msg_next != msg)) { + if (msg_next->swack_vec == swack_vec) return msg_next; msg_next++; if (msg_next > bcp->queue_last) @@ -1168,30 +1165,32 @@ void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp) * This message was assigned a swack resource, but no * reserved acknowlegment is pending. * The bug has prevented this message from setting the MMR. + * And no other message has used the same sw_ack resource. + * Do the requested shootdown but do not reply to the msg. + * (the 0 means make no acknowledge) */ + bau_process_message(mdp, bcp, 0); + return; + } + + /* + * Some message has set the MMR 'pending' bit; it might have been + * another message. Look for that message. + */ + other_msg = find_another_by_swack(msg, bcp, msg->swack_vec); + if (other_msg) { + /* There is another. Do not ack the current one. */ + bau_process_message(mdp, bcp, 0); /* - * Some message has set the MMR 'pending' bit; it might have - * been another message. Look for that message. + * Let the natural processing of that message acknowledge + * it. Don't get the processing of sw_ack's out of order. */ - other_msg = find_another_by_swack(msg, bcp); - if (other_msg) { - /* - * There is another. Process this one but do not - * ack it. - */ - bau_process_message(mdp, bcp, 0); - /* - * Let the natural processing of that other message - * acknowledge it. Don't get the processing of sw_ack's - * out of order. - */ - return; - } + return; } /* - * Either the MMR shows this one pending a reply or there is no - * other message using this sw_ack, so it is safe to acknowledge it. + * There is no other message using this sw_ack, so it is safe to + * acknowledge it. */ bau_process_message(mdp, bcp, 1); @@ -1296,8 +1295,8 @@ static void __init enable_timeouts(void) */ mmr_image |= (1L << SOFTACK_MSHIFT); if (is_uv2_hub()) { - /* hw bug workaround; do not use extended status */ - mmr_image &= ~(1L << UV2_EXT_SHFT); + mmr_image &= ~(1L << UV2_LEG_SHFT); + mmr_image |= (1L << UV2_EXT_SHFT); } write_mmr_misc_control(pnode, mmr_image); } @@ -1340,34 +1339,29 @@ static inline unsigned long long usec_2_cycles(unsigned long microsec) static int ptc_seq_show(struct seq_file *file, void *data) { struct ptc_stats *stat; - struct bau_control *bcp; int cpu; cpu = *(loff_t *)data; if (!cpu) { seq_printf(file, - "# cpu bauoff sent stime self locals remotes ncpus localhub "); + "# cpu sent stime self locals remotes ncpus localhub "); seq_printf(file, "remotehub numuvhubs numuvhubs16 numuvhubs8 "); seq_printf(file, - "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries "); - seq_printf(file, - "rok resetp resett giveup sto bz throt disable "); + "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries rok "); seq_printf(file, - "enable wars warshw warwaits enters ipidis plugged "); + "resetp resett giveup sto bz throt swack recv rtime "); seq_printf(file, - "ipiover glim cong swack recv rtime all one mult "); + "all one mult none retry canc nocan reset rcan "); seq_printf(file, - "none retry canc nocan reset rcan\n"); + "disable enable wars warshw warwaits\n"); } if (cpu < num_possible_cpus() && cpu_online(cpu)) { - bcp = &per_cpu(bau_control, cpu); - stat = bcp->statp; + stat = &per_cpu(ptcstats, cpu); /* source side statistics */ seq_printf(file, - "cpu %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", - cpu, bcp->nobau, stat->s_requestor, - cycles_2_us(stat->s_time), + "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", + cpu, stat->s_requestor, cycles_2_us(stat->s_time), stat->s_ntargself, stat->s_ntarglocals, stat->s_ntargremotes, stat->s_ntargcpu, stat->s_ntarglocaluvhub, stat->s_ntargremoteuvhub, @@ -1381,23 +1375,20 @@ static int ptc_seq_show(struct seq_file *file, void *data) stat->s_resets_plug, stat->s_resets_timeout, stat->s_giveup, stat->s_stimeout, stat->s_busy, stat->s_throttles); - seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", - stat->s_bau_disabled, stat->s_bau_reenabled, - stat->s_uv2_wars, stat->s_uv2_wars_hw, - stat->s_uv2_war_waits, stat->s_enters, - stat->s_ipifordisabled, stat->s_plugged, - stat->s_overipilimit, stat->s_giveuplimit, - stat->s_congested); /* destination side statistics */ seq_printf(file, - "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", + "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)), stat->d_requestee, cycles_2_us(stat->d_time), stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, stat->d_nomsg, stat->d_retries, stat->d_canceled, stat->d_nocanceled, stat->d_resets, stat->d_rcanceled); + seq_printf(file, "%ld %ld %ld %ld %ld\n", + stat->s_bau_disabled, stat->s_bau_reenabled, + stat->s_uv2_wars, stat->s_uv2_wars_hw, + stat->s_uv2_war_waits); } return 0; } @@ -1411,14 +1402,13 @@ static ssize_t tunables_read(struct file *file, char __user *userbuf, char *buf; int ret; - buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d %d\n", - "max_concur plugged_delay plugsb4reset timeoutsb4reset", - "ipi_reset_limit complete_threshold congested_response_us", - "congested_reps disabled_period giveup_limit", + buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", + "max_concur plugged_delay plugsb4reset", + "timeoutsb4reset ipi_reset_limit complete_threshold", + "congested_response_us congested_reps congested_period", max_concurr, plugged_delay, plugsb4reset, timeoutsb4reset, ipi_reset_limit, complete_threshold, - congested_respns_us, congested_reps, disabled_period, - giveup_limit); + congested_respns_us, congested_reps, congested_period); if (!buf) return -ENOMEM; @@ -1449,14 +1439,6 @@ static ssize_t ptc_proc_write(struct file *file, const char __user *user, return -EFAULT; optstr[count - 1] = '\0'; - if (!strcmp(optstr, "on")) { - set_bau_on(); - return count; - } else if (!strcmp(optstr, "off")) { - set_bau_off(); - return count; - } - if (strict_strtol(optstr, 10, &input_arg) < 0) { printk(KERN_DEBUG "%s is invalid\n", optstr); return -EINVAL; @@ -1589,8 +1571,7 @@ static ssize_t tunables_write(struct file *file, const char __user *user, bcp->complete_threshold = complete_threshold; bcp->cong_response_us = congested_respns_us; bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; + bcp->cong_period = congested_period; } return count; } @@ -1719,10 +1700,6 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) * fairness chaining multilevel count replied_to */ } else { - /* - * BIOS uses legacy mode, but UV2 hardware always - * uses native mode for selective broadcasts. - */ uv2_hdr = &bd2->header.uv2_hdr; uv2_hdr->swack_flag = 1; uv2_hdr->base_dest_nasid = @@ -1835,8 +1812,8 @@ static int calculate_destination_timeout(void) index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; - ts_ns = timeout_base_ns[index]; - ts_ns *= (mult1 * mult2); + base = timeout_base_ns[index]; + ts_ns = base * mult1 * mult2; ret = ts_ns / 1000; } else { /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */ @@ -1860,8 +1837,6 @@ static void __init init_per_cpu_tunables(void) for_each_present_cpu(cpu) { bcp = &per_cpu(bau_control, cpu); bcp->baudisabled = 0; - if (nobau) - bcp->nobau = 1; bcp->statp = &per_cpu(ptcstats, cpu); /* time interval to catch a hardware stay-busy bug */ bcp->timeout_interval = usec_2_cycles(2*timeout_us); @@ -1874,11 +1849,10 @@ static void __init init_per_cpu_tunables(void) bcp->complete_threshold = complete_threshold; bcp->cong_response_us = congested_respns_us; bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; + bcp->cong_period = congested_period; + bcp->clocks_per_100_usec = usec_2_cycles(100); spin_lock_init(&bcp->queue_lock); spin_lock_init(&bcp->uvhub_lock); - spin_lock_init(&bcp->disable_lock); } } @@ -1999,6 +1973,7 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp, } bcp->uvhub_master = *hmasterp; bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; + bcp->using_desc = bcp->uvhub_cpu; if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { printk(KERN_EMERG "%d cpus per uvhub invalid\n", bcp->uvhub_cpu); @@ -2095,12 +2070,16 @@ static int __init uv_bau_init(void) if (!is_uv_system()) return 0; + if (nobau) + return 0; + for_each_possible_cpu(cur_cpu) { mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); } nuvhubs = uv_num_possible_blades(); + spin_lock_init(&disable_lock); congested_cycles = usec_2_cycles(congested_respns_us); uv_base_pnode = 0x7fffffff; @@ -2113,8 +2092,7 @@ static int __init uv_bau_init(void) enable_timeouts(); if (init_per_cpu(nuvhubs, uv_base_pnode)) { - set_bau_off(); - nobau_perm = 1; + nobau = 1; return 0; } diff --git a/trunk/arch/x86/platform/uv/uv_irq.c b/trunk/arch/x86/platform/uv/uv_irq.c index acf7752da952..f25c2765a5c9 100644 --- a/trunk/arch/x86/platform/uv/uv_irq.c +++ b/trunk/arch/x86/platform/uv/uv_irq.c @@ -135,7 +135,6 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, unsigned long mmr_value; struct uv_IO_APIC_route_entry *entry; int mmr_pnode, err; - unsigned int dest; BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); @@ -144,10 +143,6 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, if (err != 0) return err; - err = apic->cpu_mask_to_apicid_and(eligible_cpu, eligible_cpu, &dest); - if (err != 0) - return err; - if (limit == UV_AFFINITY_CPU) irq_set_status_flags(irq, IRQ_NO_BALANCING); else @@ -164,7 +159,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, entry->polarity = 0; entry->trigger = 0; entry->mask = 0; - entry->dest = dest; + entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); mmr_pnode = uv_blade_to_pnode(mmr_blade); uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); @@ -227,7 +222,7 @@ uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask, if (cfg->move_in_progress) send_cleanup_vector(cfg); - return IRQ_SET_MASK_OK_NOCOPY; + return 0; } /* diff --git a/trunk/arch/x86/realmode/rm/Makefile b/trunk/arch/x86/realmode/rm/Makefile index b2d534cab25f..5b84a2d30888 100644 --- a/trunk/arch/x86/realmode/rm/Makefile +++ b/trunk/arch/x86/realmode/rm/Makefile @@ -22,7 +22,7 @@ wakeup-objs += video-bios.o realmode-y += header.o realmode-y += trampoline_$(BITS).o realmode-y += stack.o -realmode-y += reboot.o +realmode-$(CONFIG_X86_32) += reboot_32.o realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) targets += $(realmode-y) diff --git a/trunk/arch/x86/realmode/rm/header.S b/trunk/arch/x86/realmode/rm/header.S index a28221d94e69..fadf48378ada 100644 --- a/trunk/arch/x86/realmode/rm/header.S +++ b/trunk/arch/x86/realmode/rm/header.S @@ -6,7 +6,6 @@ #include #include -#include #include "realmode.h" @@ -29,9 +28,8 @@ GLOBAL(real_mode_header) .long pa_wakeup_header #endif /* APM/BIOS reboot */ +#ifdef CONFIG_X86_32 .long pa_machine_real_restart_asm -#ifdef CONFIG_X86_64 - .long __KERNEL32_CS #endif END(real_mode_header) diff --git a/trunk/arch/x86/realmode/rm/reboot.S b/trunk/arch/x86/realmode/rm/reboot_32.S similarity index 85% rename from trunk/arch/x86/realmode/rm/reboot.S rename to trunk/arch/x86/realmode/rm/reboot_32.S index f932ea61d1c8..114044876b3d 100644 --- a/trunk/arch/x86/realmode/rm/reboot.S +++ b/trunk/arch/x86/realmode/rm/reboot_32.S @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include "realmode.h" /* @@ -14,35 +12,13 @@ * doesn't work with at least one type of 486 motherboard. It is easy * to stop this code working; hence the copious comments. * - * This code is called with the restart type (0 = BIOS, 1 = APM) in - * the primary argument register (%eax for 32 bit, %edi for 64 bit). + * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. */ .section ".text32", "ax" .code32 -ENTRY(machine_real_restart_asm) - -#ifdef CONFIG_X86_64 - /* Switch to trampoline GDT as it is guaranteed < 4 GiB */ - movl $__KERNEL_DS, %eax - movl %eax, %ds - lgdtl pa_tr_gdt - - /* Disable paging to drop us out of long mode */ - movl %cr0, %eax - andl $~X86_CR0_PG, %eax - movl %eax, %cr0 - ljmpl $__KERNEL32_CS, $pa_machine_real_restart_paging_off -GLOBAL(machine_real_restart_paging_off) - xorl %eax, %eax - xorl %edx, %edx - movl $MSR_EFER, %ecx - wrmsr - - movl %edi, %eax - -#endif /* CONFIG_X86_64 */ - + .balign 16 +ENTRY(machine_real_restart_asm) /* Set up the IDT for real mode. */ lidtl pa_machine_real_restart_idt diff --git a/trunk/arch/x86/tools/gen-insn-attr-x86.awk b/trunk/arch/x86/tools/gen-insn-attr-x86.awk index ddcf39b1a18d..5f6a5b6c3a15 100644 --- a/trunk/arch/x86/tools/gen-insn-attr-x86.awk +++ b/trunk/arch/x86/tools/gen-insn-attr-x86.awk @@ -66,10 +66,9 @@ BEGIN { rex_expr = "^REX(\\.[XRWB]+)*" fpu_expr = "^ESC" # TODO - lprefix1_expr = "\\((66|!F3)\\)" + lprefix1_expr = "\\(66\\)" lprefix2_expr = "\\(F3\\)" - lprefix3_expr = "\\((F2|!F3)\\)" - lprefix_expr = "\\((66|F2|F3)\\)" + lprefix3_expr = "\\(F2\\)" max_lprefix = 4 # All opcodes starting with lower-case 'v' or with (v1) superscript @@ -334,16 +333,13 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, lprefix1_expr)) { lptable1[idx] = add_flags(lptable1[idx],flags) variant = "INAT_VARIANT" - } - if (match(ext, lprefix2_expr)) { + } else if (match(ext, lprefix2_expr)) { lptable2[idx] = add_flags(lptable2[idx],flags) variant = "INAT_VARIANT" - } - if (match(ext, lprefix3_expr)) { + } else if (match(ext, lprefix3_expr)) { lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" - } - if (!match(ext, lprefix_expr)){ + } else { table[idx] = add_flags(table[idx],flags) } } diff --git a/trunk/arch/x86/um/sys_call_table_32.c b/trunk/arch/x86/um/sys_call_table_32.c index 68d1dc91b37b..416bd40c0eba 100644 --- a/trunk/arch/x86/um/sys_call_table_32.c +++ b/trunk/arch/x86/um/sys_call_table_32.c @@ -39,9 +39,9 @@ #undef __SYSCALL_I386 #define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym, -typedef asmlinkage void (*sys_call_ptr_t)(void); +typedef void (*sys_call_ptr_t)(void); -extern asmlinkage void sys_ni_syscall(void); +extern void sys_ni_syscall(void); const sys_call_ptr_t sys_call_table[] __cacheline_aligned = { /* diff --git a/trunk/arch/x86/vdso/vdso32-setup.c b/trunk/arch/x86/vdso/vdso32-setup.c index 0faad646f5fd..66e6d9359826 100644 --- a/trunk/arch/x86/vdso/vdso32-setup.c +++ b/trunk/arch/x86/vdso/vdso32-setup.c @@ -205,9 +205,9 @@ void syscall32_cpu_init(void) { /* Load these always in case some future AMD CPU supports SYSENTER from compat mode too. */ - wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); - wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); - wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); + checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); + checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); + checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); wrmsrl(MSR_CSTAR, ia32_cstar_target); } diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index ed7d54985d0c..e74df9548a02 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -209,9 +209,6 @@ static void __init xen_banner(void) xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); } -#define CPUID_THERM_POWER_LEAF 6 -#define APERFMPERF_PRESENT 0 - static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; @@ -245,11 +242,6 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, *dx = cpuid_leaf5_edx_val; return; - case CPUID_THERM_POWER_LEAF: - /* Disabling APERFMPERF for kernel usage */ - maskecx = ~(1 << APERFMPERF_PRESENT); - break; - case 0xb: /* Suppress extended topology stuff */ maskebx = 0; @@ -1124,7 +1116,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, + .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = xen_write_msr_safe, + .wrmsr_regs = native_wrmsr_safe_regs, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, diff --git a/trunk/arch/x86/xen/p2m.c b/trunk/arch/x86/xen/p2m.c index 64effdc6da94..ffd08c414e91 100644 --- a/trunk/arch/x86/xen/p2m.c +++ b/trunk/arch/x86/xen/p2m.c @@ -706,7 +706,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, unsigned long uninitialized_var(address); unsigned level; pte_t *ptep = NULL; - int ret = 0; pfn = page_to_pfn(page); if (!PageHighMem(page)) { @@ -742,24 +741,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); spin_unlock_irqrestore(&m2p_override_lock, flags); - /* p2m(m2p(mfn)) == mfn: the mfn is already present somewhere in - * this domain. Set the FOREIGN_FRAME_BIT in the p2m for the other - * pfn so that the following mfn_to_pfn(mfn) calls will return the - * pfn from the m2p_override (the backend pfn) instead. - * We need to do this because the pages shared by the frontend - * (xen-blkfront) can be already locked (lock_page, called by - * do_read_cache_page); when the userspace backend tries to use them - * with direct_IO, mfn_to_pfn returns the pfn of the frontend, so - * do_blockdev_direct_IO is going to try to lock the same pages - * again resulting in a deadlock. - * As a side effect get_user_pages_fast might not be safe on the - * frontend pages while they are being shared with the backend, - * because mfn_to_pfn (that ends up being called by GUPF) will - * return the backend pfn rather than the frontend pfn. */ - ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); - if (ret == 0 && get_phys_to_machine(pfn) == mfn) - set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); - return 0; } EXPORT_SYMBOL_GPL(m2p_add_override); @@ -771,7 +752,6 @@ int m2p_remove_override(struct page *page, bool clear_pte) unsigned long uninitialized_var(address); unsigned level; pte_t *ptep = NULL; - int ret = 0; pfn = page_to_pfn(page); mfn = get_phys_to_machine(pfn); @@ -841,22 +821,6 @@ int m2p_remove_override(struct page *page, bool clear_pte) } else set_phys_to_machine(pfn, page->index); - /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present - * somewhere in this domain, even before being added to the - * m2p_override (see comment above in m2p_add_override). - * If there are no other entries in the m2p_override corresponding - * to this mfn, then remove the FOREIGN_FRAME_BIT from the p2m for - * the original pfn (the one shared by the frontend): the backend - * cannot do any IO on this page anymore because it has been - * unshared. Removing the FOREIGN_FRAME_BIT from the p2m entry of - * the original pfn causes mfn_to_pfn(mfn) to return the frontend - * pfn again. */ - mfn &= ~FOREIGN_FRAME_BIT; - ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); - if (ret == 0 && get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) && - m2p_find_override(mfn) == NULL) - set_phys_to_machine(pfn, mfn); - return 0; } EXPORT_SYMBOL_GPL(m2p_remove_override); diff --git a/trunk/arch/x86/xen/setup.c b/trunk/arch/x86/xen/setup.c index a4790bf22c59..3ebba0753d38 100644 --- a/trunk/arch/x86/xen/setup.c +++ b/trunk/arch/x86/xen/setup.c @@ -371,8 +371,7 @@ char * __init xen_memory_setup(void) populated = xen_populate_chunk(map, memmap.nr_entries, max_pfn, &last_pfn, xen_released_pages); - xen_released_pages -= populated; - extra_pages += xen_released_pages; + extra_pages += (xen_released_pages - populated); if (last_pfn > max_pfn) { max_pfn = min(MAX_DOMAIN_PAGES, last_pfn); diff --git a/trunk/arch/x86/xen/smp.c b/trunk/arch/x86/xen/smp.c index f58dca7a6e52..afb250d22a6b 100644 --- a/trunk/arch/x86/xen/smp.c +++ b/trunk/arch/x86/xen/smp.c @@ -80,7 +80,9 @@ static void __cpuinit cpu_bringup(void) notify_cpu_starting(cpu); + ipi_call_lock(); set_cpu_online(cpu, true); + ipi_call_unlock(); this_cpu_write(cpu_state, CPU_ONLINE); diff --git a/trunk/arch/xtensa/Makefile b/trunk/arch/xtensa/Makefile index f973754ddf90..7608559de93a 100644 --- a/trunk/arch/xtensa/Makefile +++ b/trunk/arch/xtensa/Makefile @@ -68,8 +68,8 @@ endif # Only build variant and/or platform if it includes a Makefile -buildvar := $(shell test -e $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) -buildplf := $(shell test -e $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) +buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) +buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) # Find libgcc.a diff --git a/trunk/arch/xtensa/include/asm/syscall.h b/trunk/arch/xtensa/include/asm/syscall.h index c1dacca312f3..0b9f2e13c781 100644 --- a/trunk/arch/xtensa/include/asm/syscall.h +++ b/trunk/arch/xtensa/include/asm/syscall.h @@ -31,5 +31,5 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, struct timespec __user *tsp, const sigset_t __user *sigmask, size_t sigsetsize); -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, - size_t sigsetsize); + + diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index 2c8d6a3d250a..9b306e550e3f 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -277,7 +277,7 @@ void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) /* Don't leak any random bits. */ - memset(elfregs, 0, sizeof(*elfregs)); + memset(elfregs, 0, sizeof (elfregs)); /* Note: PS.EXCM is not set while user task is running; its * being set in regs->ps is for exception handling convenience. diff --git a/trunk/arch/xtensa/kernel/signal.c b/trunk/arch/xtensa/kernel/signal.c index efe4e854b3cd..b9f8e5850d3a 100644 --- a/trunk/arch/xtensa/kernel/signal.c +++ b/trunk/arch/xtensa/kernel/signal.c @@ -493,7 +493,7 @@ static void do_signal(struct pt_regs *regs) if (ret) return; - signal_delivered(signr, &info, &ka, regs, 0); + signal_delivered(signr, info, ka, regs, 0); if (current->ptrace & PT_SINGLESTEP) task_pt_regs(current)->icountlevel = 1; diff --git a/trunk/arch/xtensa/kernel/vmlinux.lds.S b/trunk/arch/xtensa/kernel/vmlinux.lds.S index ee2e2089483d..88ecea3facb4 100644 --- a/trunk/arch/xtensa/kernel/vmlinux.lds.S +++ b/trunk/arch/xtensa/kernel/vmlinux.lds.S @@ -83,6 +83,7 @@ SECTIONS _text = .; _stext = .; + _ftext = .; .text : { @@ -111,7 +112,7 @@ SECTIONS EXCEPTION_TABLE(16) /* Data section */ - _sdata = .; + _fdata = .; RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) _edata = .; diff --git a/trunk/arch/xtensa/mm/init.c b/trunk/arch/xtensa/mm/init.c index db955179da2d..ba150e5de2eb 100644 --- a/trunk/arch/xtensa/mm/init.c +++ b/trunk/arch/xtensa/mm/init.c @@ -26,7 +26,11 @@ #include #include -#include + +/* References to section boundaries */ + +extern char _ftext, _etext, _fdata, _edata, _rodata_end; +extern char __init_begin, __init_end; /* * mem_reserve(start, end, must_exist) @@ -193,9 +197,9 @@ void __init mem_init(void) reservedpages++; } - codesize = (unsigned long) _etext - (unsigned long) _stext; - datasize = (unsigned long) _edata - (unsigned long) _sdata; - initsize = (unsigned long) __init_end - (unsigned long) __init_begin; + codesize = (unsigned long) &_etext - (unsigned long) &_ftext; + datasize = (unsigned long) &_edata - (unsigned long) &_fdata; + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " "%ldk data, %ldk init %ldk highmem)\n", @@ -233,7 +237,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) void free_initmem(void) { - free_reserved_mem(__init_begin, __init_end); - printk("Freeing unused kernel memory: %zuk freed\n", - (__init_end - __init_begin) >> 10); + free_reserved_mem(&__init_begin, &__init_end); + printk("Freeing unused kernel memory: %dk freed\n", + (&__init_end - &__init_begin) >> 10); } diff --git a/trunk/block/blk-cgroup.c b/trunk/block/blk-cgroup.c index e7dee617358e..02cf6335e9bd 100644 --- a/trunk/block/blk-cgroup.c +++ b/trunk/block/blk-cgroup.c @@ -125,8 +125,12 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) blkg->pd[i] = pd; pd->blkg = blkg; + } + + /* invoke per-policy init */ + for (i = 0; i < BLKCG_MAX_POLS; i++) { + struct blkcg_policy *pol = blkcg_policy[i]; - /* invoke per-policy init */ if (blkcg_policy_enabled(blkg->q, pol)) pol->pd_init_fn(blkg); } @@ -241,9 +245,10 @@ EXPORT_SYMBOL_GPL(blkg_lookup_create); static void blkg_destroy(struct blkcg_gq *blkg) { + struct request_queue *q = blkg->q; struct blkcg *blkcg = blkg->blkcg; - lockdep_assert_held(blkg->q->queue_lock); + lockdep_assert_held(q->queue_lock); lockdep_assert_held(&blkcg->lock); /* Something wrong if we are trying to remove same group twice */ diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 93eb3e4f88ce..3c923a7aeb56 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -361,10 +361,9 @@ EXPORT_SYMBOL(blk_put_queue); */ void blk_drain_queue(struct request_queue *q, bool drain_all) { - int i; - while (true) { bool drain = false; + int i; spin_lock_irq(q->queue_lock); @@ -409,18 +408,6 @@ void blk_drain_queue(struct request_queue *q, bool drain_all) break; msleep(10); } - - /* - * With queue marked dead, any woken up waiter will fail the - * allocation path, so the wakeup chaining is lost and we're - * left with hung waiters. We need to wake up those waiters. - */ - if (q->request_fn) { - spin_lock_irq(q->queue_lock); - for (i = 0; i < ARRAY_SIZE(q->rq.wait); i++) - wake_up_all(&q->rq.wait[i]); - spin_unlock_irq(q->queue_lock); - } } /** @@ -480,6 +467,7 @@ void blk_cleanup_queue(struct request_queue *q) /* mark @q DEAD, no new request or merges will be allowed afterwards */ mutex_lock(&q->sysfs_lock); queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q); + spin_lock_irq(lock); /* @@ -497,6 +485,10 @@ void blk_cleanup_queue(struct request_queue *q) queue_flag_set(QUEUE_FLAG_NOMERGES, q); queue_flag_set(QUEUE_FLAG_NOXMERGES, q); queue_flag_set(QUEUE_FLAG_DEAD, q); + + if (q->queue_lock != &q->__queue_lock) + q->queue_lock = &q->__queue_lock; + spin_unlock_irq(lock); mutex_unlock(&q->sysfs_lock); @@ -507,11 +499,6 @@ void blk_cleanup_queue(struct request_queue *q) del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer); blk_sync_queue(q); - spin_lock_irq(lock); - if (q->queue_lock != &q->__queue_lock) - q->queue_lock = &q->__queue_lock; - spin_unlock_irq(lock); - /* @q is and will stay empty, shutdown and put */ blk_put_queue(q); } diff --git a/trunk/block/blk-timeout.c b/trunk/block/blk-timeout.c index 6e4744cbfb56..780354888958 100644 --- a/trunk/block/blk-timeout.c +++ b/trunk/block/blk-timeout.c @@ -197,3 +197,44 @@ void blk_add_timer(struct request *req) mod_timer(&q->timeout, expiry); } +/** + * blk_abort_queue -- Abort all request on given queue + * @queue: pointer to queue + * + */ +void blk_abort_queue(struct request_queue *q) +{ + unsigned long flags; + struct request *rq, *tmp; + LIST_HEAD(list); + + /* + * Not a request based block device, nothing to abort + */ + if (!q->request_fn) + return; + + spin_lock_irqsave(q->queue_lock, flags); + + elv_abort_queue(q); + + /* + * Splice entries to local list, to avoid deadlocking if entries + * get readded to the timeout list by error handling + */ + list_splice_init(&q->timeout_list, &list); + + list_for_each_entry_safe(rq, tmp, &list, timeout_list) + blk_abort_request(rq); + + /* + * Occasionally, blk_abort_request() will return without + * deleting the element from the list. Make sure we add those back + * instead of leaving them on the local stack list. + */ + list_splice(&list, &q->timeout_list); + + spin_unlock_irqrestore(q->queue_lock, flags); + +} +EXPORT_SYMBOL_GPL(blk_abort_queue); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index fb52df9744f5..673c977cc2bf 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -17,6 +17,8 @@ #include "blk.h" #include "blk-cgroup.h" +static struct blkcg_policy blkcg_policy_cfq __maybe_unused; + /* * tunables */ @@ -416,6 +418,11 @@ static inline struct cfq_group *pd_to_cfqg(struct blkg_policy_data *pd) return pd ? container_of(pd, struct cfq_group, pd) : NULL; } +static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg) +{ + return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); +} + static inline struct blkcg_gq *cfqg_to_blkg(struct cfq_group *cfqg) { return pd_to_blkg(&cfqg->pd); @@ -565,13 +572,6 @@ static inline void cfqg_stats_update_avg_queue_size(struct cfq_group *cfqg) { } #ifdef CONFIG_CFQ_GROUP_IOSCHED -static struct blkcg_policy blkcg_policy_cfq; - -static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg) -{ - return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); -} - static inline void cfqg_get(struct cfq_group *cfqg) { return blkg_get(cfqg_to_blkg(cfqg)); @@ -3951,11 +3951,10 @@ static void cfq_exit_queue(struct elevator_queue *e) cfq_shutdown_timer_wq(cfqd); -#ifdef CONFIG_CFQ_GROUP_IOSCHED - blkcg_deactivate_policy(q, &blkcg_policy_cfq); -#else +#ifndef CONFIG_CFQ_GROUP_IOSCHED kfree(cfqd->root_group); #endif + blkcg_deactivate_policy(q, &blkcg_policy_cfq); kfree(cfqd); } @@ -4195,15 +4194,14 @@ static int __init cfq_init(void) #ifdef CONFIG_CFQ_GROUP_IOSCHED if (!cfq_group_idle) cfq_group_idle = 1; +#else + cfq_group_idle = 0; +#endif ret = blkcg_policy_register(&blkcg_policy_cfq); if (ret) return ret; -#else - cfq_group_idle = 0; -#endif - ret = -ENOMEM; cfq_pool = KMEM_CACHE(cfq_queue, 0); if (!cfq_pool) goto err_pol_unreg; @@ -4217,17 +4215,13 @@ static int __init cfq_init(void) err_free_pool: kmem_cache_destroy(cfq_pool); err_pol_unreg: -#ifdef CONFIG_CFQ_GROUP_IOSCHED blkcg_policy_unregister(&blkcg_policy_cfq); -#endif return ret; } static void __exit cfq_exit(void) { -#ifdef CONFIG_CFQ_GROUP_IOSCHED blkcg_policy_unregister(&blkcg_policy_cfq); -#endif elv_unregister(&iosched_cfq); kmem_cache_destroy(cfq_pool); } diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 9a87daa6f4fb..260fa80ef575 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -721,14 +721,11 @@ int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) break; } - if (capable(CAP_SYS_RAWIO)) - return 0; - /* In particular, rule out all resets and host-specific ioctls. */ printk_ratelimited(KERN_WARNING "%s: sending ioctl %x to a partition!\n", current->comm, cmd); - return -ENOIOCTLCMD; + return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD; } EXPORT_SYMBOL(scsi_verify_blk_ioctl); diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 80998958cf45..47768ff87343 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -208,7 +208,7 @@ config ACPI_IPMI config ACPI_HOTPLUG_CPU bool - depends on EXPERIMENTAL && ACPI_PROCESSOR && HOTPLUG_CPU + depends on ACPI_PROCESSOR && HOTPLUG_CPU select ACPI_CONTAINER default y diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index ff9f6bd48301..6512b20aeccd 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -61,6 +61,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_remove(struct acpi_device *device, int type); +static int acpi_ac_resume(struct acpi_device *device); static void acpi_ac_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id ac_device_ids[] = { @@ -69,9 +70,6 @@ static const struct acpi_device_id ac_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ac_device_ids); -static int acpi_ac_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); - static struct acpi_driver acpi_ac_driver = { .name = "ac", .class = ACPI_AC_CLASS, @@ -80,9 +78,9 @@ static struct acpi_driver acpi_ac_driver = { .ops = { .add = acpi_ac_add, .remove = acpi_ac_remove, + .resume = acpi_ac_resume, .notify = acpi_ac_notify, }, - .drv.pm = &acpi_ac_pm, }; struct acpi_ac { @@ -311,18 +309,13 @@ static int acpi_ac_add(struct acpi_device *device) return result; } -static int acpi_ac_resume(struct device *dev) +static int acpi_ac_resume(struct acpi_device *device) { struct acpi_ac *ac; unsigned old_state; - - if (!dev) - return -EINVAL; - - ac = acpi_driver_data(to_acpi_device(dev)); - if (!ac) + if (!device || !acpi_driver_data(device)) return -EINVAL; - + ac = acpi_driver_data(device); old_state = ac->state; if (acpi_ac_get_state(ac)) return 0; diff --git a/trunk/drivers/acpi/acpi_pad.c b/trunk/drivers/acpi/acpi_pad.c index 1502c50273b5..a43fa1a57d57 100644 --- a/trunk/drivers/acpi/acpi_pad.c +++ b/trunk/drivers/acpi/acpi_pad.c @@ -36,7 +36,6 @@ #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 static DEFINE_MUTEX(isolated_cpus_lock); -static DEFINE_MUTEX(round_robin_lock); static unsigned long power_saving_mwait_eax; @@ -108,7 +107,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return; - mutex_lock(&round_robin_lock); + mutex_lock(&isolated_cpus_lock); cpumask_clear(tmp); for_each_cpu(cpu, pad_busy_cpus) cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); @@ -117,7 +116,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (cpumask_empty(tmp)) cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); if (cpumask_empty(tmp)) { - mutex_unlock(&round_robin_lock); + mutex_unlock(&isolated_cpus_lock); return; } for_each_cpu(cpu, tmp) { @@ -132,7 +131,7 @@ static void round_robin_cpu(unsigned int tsk_index) tsk_in_cpu[tsk_index] = preferred_cpu; cpumask_set_cpu(preferred_cpu, pad_busy_cpus); cpu_weight[preferred_cpu]++; - mutex_unlock(&round_robin_lock); + mutex_unlock(&isolated_cpus_lock); set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); } diff --git a/trunk/drivers/acpi/acpica/hwsleep.c b/trunk/drivers/acpi/acpica/hwsleep.c index 615996a36bed..0ed85cac3231 100644 --- a/trunk/drivers/acpi/acpica/hwsleep.c +++ b/trunk/drivers/acpi/acpica/hwsleep.c @@ -95,6 +95,18 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) return_ACPI_STATUS(status); } + if (sleep_state != ACPI_STATE_S5) { + /* + * Disable BM arbitration. This feature is contained within an + * optional register (PM2 Control), so ignore a BAD_ADDRESS + * exception. + */ + status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); + if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { + return_ACPI_STATUS(status); + } + } + /* * 1) Disable/Clear all GPEs * 2) Enable all wakeup GPEs @@ -352,6 +364,16 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) [ACPI_EVENT_POWER_BUTTON]. status_register_id, ACPI_CLEAR_STATUS); + /* + * Enable BM arbitration. This feature is contained within an + * optional register (PM2 Control), so ignore a BAD_ADDRESS + * exception. + */ + status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); + if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { + return_ACPI_STATUS(status); + } + acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/acpica/nspredef.c b/trunk/drivers/acpi/acpica/nspredef.c index fe6626035495..23ce09686418 100644 --- a/trunk/drivers/acpi/acpica/nspredef.c +++ b/trunk/drivers/acpi/acpica/nspredef.c @@ -638,7 +638,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data, /* Create the new outer package and populate it */ status = - acpi_ns_wrap_with_package(data, return_object, + acpi_ns_wrap_with_package(data, *elements, return_object_ptr); if (ACPI_FAILURE(status)) { return (status); diff --git a/trunk/drivers/acpi/apei/apei-base.c b/trunk/drivers/acpi/apei/apei-base.c index 6686b1eaf13e..5577762daee1 100644 --- a/trunk/drivers/acpi/apei/apei-base.c +++ b/trunk/drivers/acpi/apei/apei-base.c @@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - return apei_map_generic_address(&entry->register_region); + return acpi_os_map_generic_address(&entry->register_region); return 0; } @@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - apei_unmap_generic_address(&entry->register_region); + acpi_os_unmap_generic_address(&entry->register_region); return 0; } @@ -606,19 +606,6 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, return 0; } -int apei_map_generic_address(struct acpi_generic_address *reg) -{ - int rc; - u32 access_bit_width; - u64 address; - - rc = apei_check_gar(reg, &address, &access_bit_width); - if (rc) - return rc; - return acpi_os_map_generic_address(reg); -} -EXPORT_SYMBOL_GPL(apei_map_generic_address); - /* read GAR in interrupt (including NMI) or process context */ int apei_read(u64 *val, struct acpi_generic_address *reg) { diff --git a/trunk/drivers/acpi/apei/apei-internal.h b/trunk/drivers/acpi/apei/apei-internal.h index f220d642136e..cca240a33038 100644 --- a/trunk/drivers/acpi/apei/apei-internal.h +++ b/trunk/drivers/acpi/apei/apei-internal.h @@ -7,8 +7,6 @@ #define APEI_INTERNAL_H #include -#include -#include struct apei_exec_context; @@ -70,13 +68,6 @@ static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 actio /* IP has been set in instruction function */ #define APEI_EXEC_SET_IP 1 -int apei_map_generic_address(struct acpi_generic_address *reg); - -static inline void apei_unmap_generic_address(struct acpi_generic_address *reg) -{ - acpi_os_unmap_generic_address(reg); -} - int apei_read(u64 *val, struct acpi_generic_address *reg); int apei_write(u64 val, struct acpi_generic_address *reg); diff --git a/trunk/drivers/acpi/apei/ghes.c b/trunk/drivers/acpi/apei/ghes.c index 1599566ed1fe..9b3cac0abecc 100644 --- a/trunk/drivers/acpi/apei/ghes.c +++ b/trunk/drivers/acpi/apei/ghes.c @@ -301,7 +301,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) if (!ghes) return ERR_PTR(-ENOMEM); ghes->generic = generic; - rc = apei_map_generic_address(&generic->error_status_address); + rc = acpi_os_map_generic_address(&generic->error_status_address); if (rc) goto err_free; error_block_length = generic->error_block_length; @@ -321,7 +321,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) return ghes; err_unmap: - apei_unmap_generic_address(&generic->error_status_address); + acpi_os_unmap_generic_address(&generic->error_status_address); err_free: kfree(ghes); return ERR_PTR(rc); @@ -330,7 +330,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) static void ghes_fini(struct ghes *ghes) { kfree(ghes->estatus); - apei_unmap_generic_address(&ghes->generic->error_status_address); + acpi_os_unmap_generic_address(&ghes->generic->error_status_address); } enum { diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 023f9c8534d0..86933ca8b472 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -643,19 +643,11 @@ static int acpi_battery_update(struct acpi_battery *battery) static void acpi_battery_refresh(struct acpi_battery *battery) { - int power_unit; - if (!battery->bat.dev) return; - power_unit = battery->power_unit; - acpi_battery_get_info(battery); - - if (power_unit == battery->power_unit) - return; - - /* The battery has changed its reporting units. */ + /* The battery may have changed its reporting units. */ sysfs_remove_battery(battery); sysfs_add_battery(battery); } @@ -1044,24 +1036,17 @@ static int acpi_battery_remove(struct acpi_device *device, int type) } /* this is needed to learn about changes made in suspended state */ -static int acpi_battery_resume(struct device *dev) +static int acpi_battery_resume(struct acpi_device *device) { struct acpi_battery *battery; - - if (!dev) - return -EINVAL; - - battery = acpi_driver_data(to_acpi_device(dev)); - if (!battery) + if (!device) return -EINVAL; - + battery = acpi_driver_data(device); battery->update_time = 0; acpi_battery_update(battery); return 0; } -static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); - static struct acpi_driver acpi_battery_driver = { .name = "battery", .class = ACPI_BATTERY_CLASS, @@ -1069,10 +1054,10 @@ static struct acpi_driver acpi_battery_driver = { .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = acpi_battery_add, + .resume = acpi_battery_resume, .remove = acpi_battery_remove, .notify = acpi_battery_notify, }, - .drv.pm = &acpi_battery_pm, }; static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index adceafda9c17..3188da3df8da 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -182,66 +182,41 @@ EXPORT_SYMBOL(acpi_bus_get_private_data); Power Management -------------------------------------------------------------------------- */ -static const char *state_string(int state) -{ - switch (state) { - case ACPI_STATE_D0: - return "D0"; - case ACPI_STATE_D1: - return "D1"; - case ACPI_STATE_D2: - return "D2"; - case ACPI_STATE_D3_HOT: - return "D3hot"; - case ACPI_STATE_D3_COLD: - return "D3"; - default: - return "(unknown)"; - } -} - static int __acpi_bus_get_power(struct acpi_device *device, int *state) { - int result = ACPI_STATE_UNKNOWN; + int result = 0; + acpi_status status = 0; + unsigned long long psc = 0; if (!device || !state) return -EINVAL; - if (!device->flags.power_manageable) { + *state = ACPI_STATE_UNKNOWN; + + if (device->flags.power_manageable) { + /* + * Get the device's power state either directly (via _PSC) or + * indirectly (via power resources). + */ + if (device->power.flags.power_resources) { + result = acpi_power_get_inferred_state(device, state); + if (result) + return result; + } else if (device->power.flags.explicit_get) { + status = acpi_evaluate_integer(device->handle, "_PSC", + NULL, &psc); + if (ACPI_FAILURE(status)) + return -ENODEV; + *state = (int)psc; + } + } else { /* TBD: Non-recursive algorithm for walking up hierarchy. */ *state = device->parent ? device->parent->power.state : ACPI_STATE_D0; - goto out; - } - - /* - * Get the device's power state either directly (via _PSC) or - * indirectly (via power resources). - */ - if (device->power.flags.explicit_get) { - unsigned long long psc; - acpi_status status = acpi_evaluate_integer(device->handle, - "_PSC", NULL, &psc); - if (ACPI_FAILURE(status)) - return -ENODEV; - - result = psc; - } - /* The test below covers ACPI_STATE_UNKNOWN too. */ - if (result <= ACPI_STATE_D2) { - ; /* Do nothing. */ - } else if (device->power.flags.power_resources) { - int error = acpi_power_get_inferred_state(device, &result); - if (error) - return error; - } else if (result == ACPI_STATE_D3_HOT) { - result = ACPI_STATE_D3; } - *state = result; - out: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n", - device->pnp.bus_id, state_string(*state))); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", + device->pnp.bus_id, *state)); return 0; } @@ -259,14 +234,13 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state) /* Make sure this is a valid target state */ if (state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n", - state_string(state))); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", + state)); return 0; } if (!device->power.states[state].flags.valid) { - printk(KERN_WARNING PREFIX "Device does not support %s\n", - state_string(state)); + printk(KERN_WARNING PREFIX "Device does not support D%d\n", state); return -ENODEV; } if (device->parent && (state < device->parent->power.state)) { @@ -320,13 +294,13 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state) end: if (result) printk(KERN_WARNING PREFIX - "Device [%s] failed to transition to %s\n", - device->pnp.bus_id, state_string(state)); + "Device [%s] failed to transition to D%d\n", + device->pnp.bus_id, state); else { device->power.state = state; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device [%s] transitioned to %s\n", - device->pnp.bus_id, state_string(state))); + "Device [%s] transitioned to D%d\n", + device->pnp.bus_id, state)); } return result; diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index 79d4c22f7a6d..d27d072472f9 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -76,21 +76,19 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids); static int acpi_button_add(struct acpi_device *device); static int acpi_button_remove(struct acpi_device *device, int type); +static int acpi_button_resume(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); -static int acpi_button_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); - static struct acpi_driver acpi_button_driver = { .name = "button", .class = ACPI_BUTTON_CLASS, .ids = button_device_ids, .ops = { .add = acpi_button_add, + .resume = acpi_button_resume, .remove = acpi_button_remove, .notify = acpi_button_notify, }, - .drv.pm = &acpi_button_pm, }; struct acpi_button { @@ -310,9 +308,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) } } -static int acpi_button_resume(struct device *dev) +static int acpi_button_resume(struct acpi_device *device) { - struct acpi_device *device = to_acpi_device(dev); struct acpi_button *button = acpi_driver_data(device); if (button->type == ACPI_BUTTON_TYPE_LID) diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index 669d9ee80d16..0f0356ca1a9e 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -46,6 +46,8 @@ MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_remove(struct acpi_device *device, int type); +static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state); +static int acpi_fan_resume(struct acpi_device *device); static const struct acpi_device_id fan_device_ids[] = { {"PNP0C0B", 0}, @@ -53,10 +55,6 @@ static const struct acpi_device_id fan_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, fan_device_ids); -static int acpi_fan_suspend(struct device *dev); -static int acpi_fan_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); - static struct acpi_driver acpi_fan_driver = { .name = "fan", .class = ACPI_FAN_CLASS, @@ -64,8 +62,9 @@ static struct acpi_driver acpi_fan_driver = { .ops = { .add = acpi_fan_add, .remove = acpi_fan_remove, + .suspend = acpi_fan_suspend, + .resume = acpi_fan_resume, }, - .drv.pm = &acpi_fan_pm, }; /* thermal cooling device callbacks */ @@ -184,24 +183,24 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return 0; } -static int acpi_fan_suspend(struct device *dev) +static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) { - if (!dev) + if (!device) return -EINVAL; - acpi_bus_set_power(to_acpi_device(dev)->handle, ACPI_STATE_D0); + acpi_bus_set_power(device->handle, ACPI_STATE_D0); return AE_OK; } -static int acpi_fan_resume(struct device *dev) +static int acpi_fan_resume(struct acpi_device *device) { int result; - if (!dev) + if (!device) return -EINVAL; - result = acpi_bus_update_power(to_acpi_device(dev)->handle, NULL); + result = acpi_bus_update_power(device->handle, NULL); if (result) printk(KERN_ERR PREFIX "Error updating fan power state\n"); diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index 894d45c6bc67..0500f719f63e 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -60,6 +60,7 @@ ACPI_MODULE_NAME("power"); static int acpi_power_add(struct acpi_device *device); static int acpi_power_remove(struct acpi_device *device, int type); +static int acpi_power_resume(struct acpi_device *device); static const struct acpi_device_id power_device_ids[] = { {ACPI_POWER_HID, 0}, @@ -67,9 +68,6 @@ static const struct acpi_device_id power_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, power_device_ids); -static int acpi_power_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); - static struct acpi_driver acpi_power_driver = { .name = "power", .class = ACPI_POWER_CLASS, @@ -77,8 +75,8 @@ static struct acpi_driver acpi_power_driver = { .ops = { .add = acpi_power_add, .remove = acpi_power_remove, + .resume = acpi_power_resume, }, - .drv.pm = &acpi_power_pm, }; /* @@ -633,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) * We know a device's inferred power state when all the resources * required for a given D-state are 'on'. */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) { list = &device->power.states[i].resources; if (list->count < 1) continue; @@ -773,16 +771,14 @@ static int acpi_power_remove(struct acpi_device *device, int type) return 0; } -static int acpi_power_resume(struct device *dev) +static int acpi_power_resume(struct acpi_device *device) { int result = 0, state; - struct acpi_device *device; struct acpi_power_resource *resource; - if (!dev) + if (!device) return -EINVAL; - device = to_acpi_device(dev); resource = acpi_driver_data(device); if (!resource) return -EINVAL; diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index eff722278ff5..c850de4c9a14 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -189,12 +189,10 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) * Processor (CPU3, 0x03, 0x00000410, 0x06) {} * } * - * Ignores apic_id and always returns 0 for the processor - * handle with acpi id 0 if nr_cpu_ids is 1. - * This should be the case if SMP tables are not found. + * Ignores apic_id and always return 0 for CPU0's handle. * Return -1 for other CPU's handle. */ - if (nr_cpu_ids <= 1 && acpi_id == 0) + if (acpi_id == 0) return acpi_id; else return apic_id; diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index 7048b97853e0..0734086537b8 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -93,9 +93,6 @@ static const struct acpi_device_id processor_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); -static SIMPLE_DEV_PM_OPS(acpi_processor_pm, - acpi_processor_suspend, acpi_processor_resume); - static struct acpi_driver acpi_processor_driver = { .name = "processor", .class = ACPI_PROCESSOR_CLASS, @@ -103,9 +100,10 @@ static struct acpi_driver acpi_processor_driver = { .ops = { .add = acpi_processor_add, .remove = acpi_processor_remove, + .suspend = acpi_processor_suspend, + .resume = acpi_processor_resume, .notify = acpi_processor_notify, }, - .drv.pm = &acpi_processor_pm, }; #define INSTALL_NOTIFY_HANDLER 1 @@ -429,11 +427,18 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, * Initialize missing things */ if (pr->flags.need_hotplug_init) { + struct cpuidle_driver *idle_driver = + cpuidle_get_driver(); + printk(KERN_INFO "Will online and init hotplugged " "CPU: %d\n", pr->id); WARN(acpi_processor_start(pr), "Failed to start CPU:" " %d\n", pr->id); pr->flags.need_hotplug_init = 0; + if (idle_driver && !strcmp(idle_driver->name, + "intel_idle")) { + intel_idle_cpu_init(pr->id); + } /* Normal CPU soft online event */ } else { acpi_processor_ppc_has_changed(pr, 0); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index e589c1985248..f3decb30223f 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -221,6 +221,9 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, #endif +/* + * Suspend / resume control + */ static u32 saved_bm_rld; static void acpi_idle_bm_rld_save(void) @@ -237,13 +240,13 @@ static void acpi_idle_bm_rld_restore(void) acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); } -int acpi_processor_suspend(struct device *dev) +int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { acpi_idle_bm_rld_save(); return 0; } -int acpi_processor_resume(struct device *dev) +int acpi_processor_resume(struct acpi_device * device) { acpi_idle_bm_rld_restore(); return 0; @@ -583,6 +586,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, */ cx->valid = 1; + cx->latency_ticks = cx->latency; /* * On older chipsets, BM_RLD needs to be set * in order for Bus Master activity to wake the @@ -615,6 +619,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) if (!cx->address) break; cx->valid = 1; + cx->latency_ticks = cx->latency; /* Normalize latency */ break; case ACPI_STATE_C3: @@ -749,7 +754,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, local_irq_disable(); - lapic_timer_state_broadcast(pr, cx, 1); kt1 = ktime_get_real(); acpi_idle_do_entry(cx); @@ -760,6 +764,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, dev->last_residency = (int)idle_time; local_irq_enable(); + cx->usage++; lapic_timer_state_broadcast(pr, cx, 0); return index; @@ -818,7 +823,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, local_irq_disable(); - if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -862,7 +866,10 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, if (cx->entry_method != ACPI_CSTATE_FFH) current_thread_info()->status |= TS_POLLING; + cx->usage++; + lapic_timer_state_broadcast(pr, cx, 0); + cx->time += idle_time; return index; } @@ -902,13 +909,12 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, local_irq_disable(); acpi_safe_halt(); local_irq_enable(); - return -EBUSY; + return -EINVAL; } } local_irq_disable(); - if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -980,7 +986,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, if (cx->entry_method != ACPI_CSTATE_FFH) current_thread_info()->status |= TS_POLLING; + cx->usage++; + lapic_timer_state_broadcast(pr, cx, 0); + cx->time += idle_time; return index; } diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index a093dc163a42..0af48a8554cd 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -333,7 +333,6 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) struct acpi_buffer state = { 0, NULL }; union acpi_object *pss = NULL; int i; - int last_invalid = -1; status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); @@ -395,33 +394,14 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) ((u32)(px->core_frequency * 1000) != (px->core_frequency * 1000))) { printk(KERN_ERR FW_BUG PREFIX - "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n", - pr->id, px->core_frequency); - if (last_invalid == -1) - last_invalid = i; - } else { - if (last_invalid != -1) { - /* - * Copy this valid entry over last_invalid entry - */ - memcpy(&(pr->performance->states[last_invalid]), - px, sizeof(struct acpi_processor_px)); - ++last_invalid; - } + "Invalid BIOS _PSS frequency: 0x%llx MHz\n", + px->core_frequency); + result = -EFAULT; + kfree(pr->performance->states); + goto end; } } - if (last_invalid == 0) { - printk(KERN_ERR FW_BUG PREFIX - "No valid BIOS _PSS frequency found for processor %d\n", pr->id); - result = -EFAULT; - kfree(pr->performance->states); - pr->performance->states = NULL; - } - - if (last_invalid > 0) - pr->performance->state_count = last_invalid; - end: kfree(buffer.pointer); diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index c0b9aa5faf4c..6e36d0c0057c 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -988,18 +988,16 @@ static void acpi_sbs_rmdirs(void) #endif } -static int acpi_sbs_resume(struct device *dev) +static int acpi_sbs_resume(struct acpi_device *device) { struct acpi_sbs *sbs; - if (!dev) + if (!device) return -EINVAL; - sbs = to_acpi_device(dev)->driver_data; + sbs = device->driver_data; acpi_sbs_callback(sbs); return 0; } -static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); - static struct acpi_driver acpi_sbs_driver = { .name = "sbs", .class = ACPI_SBS_CLASS, @@ -1007,8 +1005,8 @@ static struct acpi_driver acpi_sbs_driver = { .ops = { .add = acpi_sbs_add, .remove = acpi_sbs_remove, + .resume = acpi_sbs_resume, }, - .drv.pm = &acpi_sbs_pm, }; static int __init acpi_sbs_init(void) diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index fdda49336560..85cbfdccc97c 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -290,6 +290,26 @@ static void acpi_device_release(struct device *dev) kfree(acpi_dev); } +static int acpi_device_suspend(struct device *dev, pm_message_t state) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_driver *acpi_drv = acpi_dev->driver; + + if (acpi_drv && acpi_drv->ops.suspend) + return acpi_drv->ops.suspend(acpi_dev, state); + return 0; +} + +static int acpi_device_resume(struct device *dev) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_driver *acpi_drv = acpi_dev->driver; + + if (acpi_drv && acpi_drv->ops.resume) + return acpi_drv->ops.resume(acpi_dev); + return 0; +} + static int acpi_bus_match(struct device *dev, struct device_driver *drv) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -421,6 +441,8 @@ static int acpi_device_remove(struct device * dev) struct bus_type acpi_bus_type = { .name = "acpi", + .suspend = acpi_device_suspend, + .resume = acpi_device_resume, .match = acpi_bus_match, .probe = acpi_device_probe, .remove = acpi_device_remove, @@ -1545,7 +1567,6 @@ static int acpi_bus_scan_fixed(void) ACPI_BUS_TYPE_POWER_BUTTON, ACPI_STA_DEFAULT, &ops); - device_init_wakeup(&device->dev, true); } if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 88561029cca8..74ee4ab577b6 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -57,7 +57,6 @@ MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); static u8 sleep_states[ACPI_S_STATE_COUNT]; -static bool pwr_btn_event_pending; static void acpi_sleep_tts_switch(u32 acpi_state) { @@ -185,14 +184,6 @@ static int acpi_pm_prepare(void) return error; } -static int find_powerf_dev(struct device *dev, void *data) -{ - struct acpi_device *device = to_acpi_device(dev); - const char *hid = acpi_device_hid(device); - - return !strcmp(hid, ACPI_BUTTON_HID_POWERF); -} - /** * acpi_pm_finish - Instruct the platform to leave a sleep state. * @@ -201,7 +192,6 @@ static int find_powerf_dev(struct device *dev, void *data) */ static void acpi_pm_finish(void) { - struct device *pwr_btn_dev; u32 acpi_state = acpi_target_sleep_state; acpi_ec_unblock_transactions(); @@ -219,23 +209,6 @@ static void acpi_pm_finish(void) acpi_set_firmware_waking_vector((acpi_physical_address) 0); acpi_target_sleep_state = ACPI_STATE_S0; - - /* If we were woken with the fixed power button, provide a small - * hint to userspace in the form of a wakeup event on the fixed power - * button device (if it can be found). - * - * We delay the event generation til now, as the PM layer requires - * timekeeping to be running before we generate events. */ - if (!pwr_btn_event_pending) - return; - - pwr_btn_event_pending = false; - pwr_btn_dev = bus_find_device(&acpi_bus_type, NULL, NULL, - find_powerf_dev); - if (pwr_btn_dev) { - pm_wakeup_event(pwr_btn_dev, 0); - put_device(pwr_btn_dev); - } } /** @@ -325,23 +298,9 @@ static int acpi_suspend_enter(suspend_state_t pm_state) /* ACPI 3.0 specs (P62) says that it's the responsibility * of the OSPM to clear the status bit [ implying that the * POWER_BUTTON event should not reach userspace ] - * - * However, we do generate a small hint for userspace in the form of - * a wakeup event. We flag this condition for now and generate the - * event later, as we're currently too early in resume to be able to - * generate wakeup events. */ - if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) { - acpi_event_status pwr_btn_status; - - acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status); - - if (pwr_btn_status & ACPI_EVENT_FLAG_SET) { - acpi_clear_event(ACPI_EVENT_POWER_BUTTON); - /* Flag for later */ - pwr_btn_event_pending = true; - } - } + if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) + acpi_clear_event(ACPI_EVENT_POWER_BUTTON); /* * Disable and clear GPE status before interrupt is enabled. Some GPEs @@ -771,8 +730,8 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) * can wake the system. _S0W may be valid, too. */ if (acpi_target_sleep_state == ACPI_STATE_S0 || - (device_may_wakeup(dev) && adev->wakeup.flags.valid && - adev->wakeup.sleep_state >= acpi_target_sleep_state)) { + (device_may_wakeup(dev) && + adev->wakeup.sleep_state <= acpi_target_sleep_state)) { acpi_status status; acpi_method[3] = 'W'; diff --git a/trunk/drivers/acpi/sysfs.c b/trunk/drivers/acpi/sysfs.c index 240a24400976..9f66181c814e 100644 --- a/trunk/drivers/acpi/sysfs.c +++ b/trunk/drivers/acpi/sysfs.c @@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; - if (!strncmp(val, "enable", strlen("enable"))) { + if (!strncmp(val, "enable", strlen("enable") - 1)) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) @@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) goto exit; } - if (!strncmp(val, "disable", strlen("disable"))) { + if (!strncmp(val, "disable", strlen("disable") - 1)) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 21dd4c268aef..7dbebea1ec31 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -98,6 +98,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); +static int acpi_thermal_resume(struct acpi_device *device); static void acpi_thermal_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id thermal_device_ids[] = { @@ -106,9 +107,6 @@ static const struct acpi_device_id thermal_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, thermal_device_ids); -static int acpi_thermal_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); - static struct acpi_driver acpi_thermal_driver = { .name = "thermal", .class = ACPI_THERMAL_CLASS, @@ -116,9 +114,9 @@ static struct acpi_driver acpi_thermal_driver = { .ops = { .add = acpi_thermal_add, .remove = acpi_thermal_remove, + .resume = acpi_thermal_resume, .notify = acpi_thermal_notify, }, - .drv.pm = &acpi_thermal_pm, }; struct acpi_thermal_state { @@ -1043,18 +1041,17 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) return 0; } -static int acpi_thermal_resume(struct device *dev) +static int acpi_thermal_resume(struct acpi_device *device) { - struct acpi_thermal *tz; + struct acpi_thermal *tz = NULL; int i, j, power_state, result; - if (!dev) - return -EINVAL; - tz = acpi_driver_data(to_acpi_device(dev)); - if (!tz) + if (!device || !acpi_driver_data(device)) return -EINVAL; + tz = acpi_driver_data(device); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { if (!(&tz->trips.active[i])) break; diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 1e0a9e17c31d..9577b6fa2650 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -558,8 +558,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; - if (!video->cap._DOS) - return 0; if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) return -EINVAL; @@ -1689,6 +1687,10 @@ static int acpi_video_bus_add(struct acpi_device *device) set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); set_bit(KEY_DISPLAY_OFF, input->keybit); + error = input_register_device(input); + if (error) + goto err_stop_video; + printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), video->flags.multihead ? "yes" : "no", @@ -1699,16 +1701,12 @@ static int acpi_video_bus_add(struct acpi_device *device) video->pm_nb.priority = 0; error = register_pm_notifier(&video->pm_nb); if (error) - goto err_stop_video; - - error = input_register_device(input); - if (error) - goto err_unregister_pm_notifier; + goto err_unregister_input_dev; return 0; - err_unregister_pm_notifier: - unregister_pm_notifier(&video->pm_nb); + err_unregister_input_dev: + input_unregister_device(input); err_stop_video: acpi_video_bus_stop_devices(video); err_free_input_dev: @@ -1745,18 +1743,9 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) return 0; } -static int __init is_i740(struct pci_dev *dev) -{ - if (dev->device == 0x00D1) - return 1; - if (dev->device == 0x7000) - return 1; - return 0; -} - static int __init intel_opregion_present(void) { - int opregion = 0; +#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE) struct pci_dev *dev = NULL; u32 address; @@ -1765,15 +1754,13 @@ static int __init intel_opregion_present(void) continue; if (dev->vendor != PCI_VENDOR_ID_INTEL) continue; - /* We don't want to poke around undefined i740 registers */ - if (is_i740(dev)) - continue; pci_read_config_dword(dev, 0xfc, &address); if (!address) continue; - opregion = 1; + return 1; } - return opregion; +#endif + return 0; } int acpi_video_register(void) diff --git a/trunk/drivers/ata/pata_arasan_cf.c b/trunk/drivers/ata/pata_arasan_cf.c index ac6a5beb28f3..3239517f4d90 100644 --- a/trunk/drivers/ata/pata_arasan_cf.c +++ b/trunk/drivers/ata/pata_arasan_cf.c @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller source file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -959,7 +959,7 @@ static struct platform_driver arasan_cf_driver = { module_platform_driver(arasan_cf_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index 4b01ab3d2c24..1b1cbb571d38 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "base.h" #include "power/power.h" @@ -101,7 +100,7 @@ static void driver_deferred_probe_add(struct device *dev) mutex_lock(&deferred_probe_mutex); if (list_empty(&dev->p->deferred_probe)) { dev_dbg(dev, "Added to deferred list\n"); - list_add_tail(&dev->p->deferred_probe, &deferred_probe_pending_list); + list_add(&dev->p->deferred_probe, &deferred_probe_pending_list); } mutex_unlock(&deferred_probe_mutex); } @@ -333,7 +332,6 @@ void wait_for_device_probe(void) /* wait for the known devices to complete their probing */ wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); async_synchronize_full(); - scsi_complete_async_scans(); } EXPORT_SYMBOL_GPL(wait_for_device_probe); diff --git a/trunk/drivers/base/power/domain.c b/trunk/drivers/base/power/domain.c index ba3487c9835b..83aa694a8efe 100644 --- a/trunk/drivers/base/power/domain.c +++ b/trunk/drivers/base/power/domain.c @@ -75,6 +75,19 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev) start_latency_ns, "start"); } +static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) +{ + return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev, + save_state_latency_ns, "state save"); +} + +static int genpd_restore_dev(struct generic_pm_domain *genpd, struct device *dev) +{ + return GENPD_DEV_TIMED_CALLBACK(genpd, int, restore_state, dev, + restore_state_latency_ns, + "state restore"); +} + static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) { bool ret = false; @@ -126,19 +139,6 @@ static void genpd_set_active(struct generic_pm_domain *genpd) genpd->status = GPD_STATE_ACTIVE; } -static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) -{ - s64 usecs64; - - if (!genpd->cpu_data) - return; - - usecs64 = genpd->power_on_latency_ns; - do_div(usecs64, NSEC_PER_USEC); - usecs64 += genpd->cpu_data->saved_exit_latency; - genpd->cpu_data->idle_state->exit_latency = usecs64; -} - /** * __pm_genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. @@ -146,7 +146,7 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) * Restore power to @genpd and all of its masters so that it is possible to * resume a device belonging to it. */ -static int __pm_genpd_poweron(struct generic_pm_domain *genpd) +int __pm_genpd_poweron(struct generic_pm_domain *genpd) __releases(&genpd->lock) __acquires(&genpd->lock) { struct gpd_link *link; @@ -176,13 +176,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) return 0; } - if (genpd->cpu_data) { - cpuidle_pause_and_lock(); - genpd->cpu_data->idle_state->disabled = true; - cpuidle_resume_and_unlock(); - goto out; - } - /* * The list is guaranteed not to change while the loop below is being * executed, unless one of the masters' .power_on() callbacks fiddles @@ -222,7 +215,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) if (elapsed_ns > genpd->power_on_latency_ns) { genpd->power_on_latency_ns = elapsed_ns; genpd->max_off_time_changed = true; - genpd_recalc_cpu_exit_latency(genpd); if (genpd->name) pr_warning("%s: Power-on latency exceeded, " "new value %lld ns\n", genpd->name, @@ -230,7 +222,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) } } - out: genpd_set_active(genpd); return 0; @@ -260,19 +251,6 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd) #ifdef CONFIG_PM_RUNTIME -static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) -{ - return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev, - save_state_latency_ns, "state save"); -} - -static int genpd_restore_dev(struct generic_pm_domain *genpd, struct device *dev) -{ - return GENPD_DEV_TIMED_CALLBACK(genpd, int, restore_state, dev, - restore_state_latency_ns, - "state restore"); -} - static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, unsigned long val, void *ptr) { @@ -297,7 +275,7 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, pdd = dev->power.subsys_data ? dev->power.subsys_data->domain_data : NULL; - if (pdd && pdd->dev) { + if (pdd) { to_gpd_data(pdd)->td.constraint_changed = true; genpd = dev_to_genpd(dev); } else { @@ -361,16 +339,19 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd, { struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); struct device *dev = pdd->dev; - bool need_restore = gpd_data->need_restore; - gpd_data->need_restore = false; + if (!gpd_data->need_restore) + return; + mutex_unlock(&genpd->lock); genpd_start_dev(genpd, dev); - if (need_restore) - genpd_restore_dev(genpd, dev); + genpd_restore_dev(genpd, dev); + genpd_stop_dev(genpd, dev); mutex_lock(&genpd->lock); + + gpd_data->need_restore = false; } /** @@ -477,21 +458,6 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) } } - if (genpd->cpu_data) { - /* - * If cpu_data is set, cpuidle should turn the domain off when - * the CPU in it is idle. In that case we don't decrement the - * subdomain counts of the master domains, so that power is not - * removed from the current domain prematurely as a result of - * cutting off the masters' power. - */ - genpd->status = GPD_STATE_POWER_OFF; - cpuidle_pause_and_lock(); - genpd->cpu_data->idle_state->disabled = false; - cpuidle_resume_and_unlock(); - goto out; - } - if (genpd->power_off) { ktime_t time_start; s64 elapsed_ns; @@ -629,7 +595,7 @@ static int pm_genpd_runtime_resume(struct device *dev) /* If power.irq_safe, the PM domain is never powered off. */ if (dev->power.irq_safe) - return genpd_start_dev(genpd, dev); + goto out; mutex_lock(&genpd->lock); ret = __pm_genpd_poweron(genpd); @@ -662,6 +628,9 @@ static int pm_genpd_runtime_resume(struct device *dev) wake_up_all(&genpd->status_wait_queue); mutex_unlock(&genpd->lock); + out: + genpd_start_dev(genpd, dev); + return 0; } @@ -1266,27 +1235,6 @@ static void pm_genpd_complete(struct device *dev) #endif /* CONFIG_PM_SLEEP */ -static struct generic_pm_domain_data *__pm_genpd_alloc_dev_data(struct device *dev) -{ - struct generic_pm_domain_data *gpd_data; - - gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); - if (!gpd_data) - return NULL; - - mutex_init(&gpd_data->lock); - gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; - dev_pm_qos_add_notifier(dev, &gpd_data->nb); - return gpd_data; -} - -static void __pm_genpd_free_dev_data(struct device *dev, - struct generic_pm_domain_data *gpd_data) -{ - dev_pm_qos_remove_notifier(dev, &gpd_data->nb); - kfree(gpd_data); -} - /** * __pm_genpd_add_device - Add a device to an I/O PM domain. * @genpd: PM domain to add the device to. @@ -1296,7 +1244,7 @@ static void __pm_genpd_free_dev_data(struct device *dev, int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td) { - struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL; + struct generic_pm_domain_data *gpd_data; struct pm_domain_data *pdd; int ret = 0; @@ -1305,10 +1253,14 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) return -EINVAL; - gpd_data_new = __pm_genpd_alloc_dev_data(dev); - if (!gpd_data_new) + gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); + if (!gpd_data) return -ENOMEM; + mutex_init(&gpd_data->lock); + gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; + dev_pm_qos_add_notifier(dev, &gpd_data->nb); + genpd_acquire_lock(genpd); if (genpd->prepared_count > 0) { @@ -1322,42 +1274,35 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, goto out; } - ret = dev_pm_get_subsys_data(dev); - if (ret) - goto out; - genpd->device_count++; genpd->max_off_time_changed = true; - spin_lock_irq(&dev->power.lock); - - dev->pm_domain = &genpd->domain; - if (dev->power.subsys_data->domain_data) { - gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); - } else { - gpd_data = gpd_data_new; - dev->power.subsys_data->domain_data = &gpd_data->base; - } - gpd_data->refcount++; - if (td) - gpd_data->td = *td; - - spin_unlock_irq(&dev->power.lock); + dev_pm_get_subsys_data(dev); mutex_lock(&gpd_data->lock); + spin_lock_irq(&dev->power.lock); + dev->pm_domain = &genpd->domain; + dev->power.subsys_data->domain_data = &gpd_data->base; gpd_data->base.dev = dev; list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF; + if (td) + gpd_data->td = *td; + gpd_data->td.constraint_changed = true; gpd_data->td.effective_constraint_ns = -1; + spin_unlock_irq(&dev->power.lock); mutex_unlock(&gpd_data->lock); - out: genpd_release_lock(genpd); - if (gpd_data != gpd_data_new) - __pm_genpd_free_dev_data(dev, gpd_data_new); + return 0; + + out: + genpd_release_lock(genpd); + dev_pm_qos_remove_notifier(dev, &gpd_data->nb); + kfree(gpd_data); return ret; } @@ -1403,7 +1348,6 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, { struct generic_pm_domain_data *gpd_data; struct pm_domain_data *pdd; - bool remove = false; int ret = 0; dev_dbg(dev, "%s()\n", __func__); @@ -1424,28 +1368,22 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, genpd->max_off_time_changed = true; spin_lock_irq(&dev->power.lock); - dev->pm_domain = NULL; pdd = dev->power.subsys_data->domain_data; list_del_init(&pdd->list_node); - gpd_data = to_gpd_data(pdd); - if (--gpd_data->refcount == 0) { - dev->power.subsys_data->domain_data = NULL; - remove = true; - } - + dev->power.subsys_data->domain_data = NULL; spin_unlock_irq(&dev->power.lock); + gpd_data = to_gpd_data(pdd); mutex_lock(&gpd_data->lock); pdd->dev = NULL; mutex_unlock(&gpd_data->lock); genpd_release_lock(genpd); + dev_pm_qos_remove_notifier(dev, &gpd_data->nb); + kfree(gpd_data); dev_pm_put_subsys_data(dev); - if (remove) - __pm_genpd_free_dev_data(dev, gpd_data); - return 0; out: @@ -1603,52 +1541,33 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, * @dev: Device to add the callbacks to. * @ops: Set of callbacks to add. * @td: Timing data to add to the device along with the callbacks (optional). - * - * Every call to this routine should be balanced with a call to - * __pm_genpd_remove_callbacks() and they must not be nested. */ int pm_genpd_add_callbacks(struct device *dev, struct gpd_dev_ops *ops, struct gpd_timing_data *td) { - struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL; + struct pm_domain_data *pdd; int ret = 0; - if (!(dev && ops)) + if (!(dev && dev->power.subsys_data && ops)) return -EINVAL; - gpd_data_new = __pm_genpd_alloc_dev_data(dev); - if (!gpd_data_new) - return -ENOMEM; - pm_runtime_disable(dev); device_pm_lock(); - ret = dev_pm_get_subsys_data(dev); - if (ret) - goto out; - - spin_lock_irq(&dev->power.lock); + pdd = dev->power.subsys_data->domain_data; + if (pdd) { + struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); - if (dev->power.subsys_data->domain_data) { - gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); + gpd_data->ops = *ops; + if (td) + gpd_data->td = *td; } else { - gpd_data = gpd_data_new; - dev->power.subsys_data->domain_data = &gpd_data->base; + ret = -EINVAL; } - gpd_data->refcount++; - gpd_data->ops = *ops; - if (td) - gpd_data->td = *td; - - spin_unlock_irq(&dev->power.lock); - out: device_pm_unlock(); pm_runtime_enable(dev); - if (gpd_data != gpd_data_new) - __pm_genpd_free_dev_data(dev, gpd_data_new); - return ret; } EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks); @@ -1657,13 +1576,10 @@ EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks); * __pm_genpd_remove_callbacks - Remove PM domain callbacks from a given device. * @dev: Device to remove the callbacks from. * @clear_td: If set, clear the device's timing data too. - * - * This routine can only be called after pm_genpd_add_callbacks(). */ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) { - struct generic_pm_domain_data *gpd_data = NULL; - bool remove = false; + struct pm_domain_data *pdd; int ret = 0; if (!(dev && dev->power.subsys_data)) @@ -1672,117 +1588,23 @@ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) pm_runtime_disable(dev); device_pm_lock(); - spin_lock_irq(&dev->power.lock); + pdd = dev->power.subsys_data->domain_data; + if (pdd) { + struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); - if (dev->power.subsys_data->domain_data) { - gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); - gpd_data->ops = (struct gpd_dev_ops){ NULL }; + gpd_data->ops = (struct gpd_dev_ops){ 0 }; if (clear_td) gpd_data->td = (struct gpd_timing_data){ 0 }; - - if (--gpd_data->refcount == 0) { - dev->power.subsys_data->domain_data = NULL; - remove = true; - } } else { ret = -EINVAL; } - spin_unlock_irq(&dev->power.lock); - device_pm_unlock(); pm_runtime_enable(dev); - if (ret) - return ret; - - dev_pm_put_subsys_data(dev); - if (remove) - __pm_genpd_free_dev_data(dev, gpd_data); - - return 0; -} -EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); - -int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) -{ - struct cpuidle_driver *cpuidle_drv; - struct gpd_cpu_data *cpu_data; - struct cpuidle_state *idle_state; - int ret = 0; - - if (IS_ERR_OR_NULL(genpd) || state < 0) - return -EINVAL; - - genpd_acquire_lock(genpd); - - if (genpd->cpu_data) { - ret = -EEXIST; - goto out; - } - cpu_data = kzalloc(sizeof(*cpu_data), GFP_KERNEL); - if (!cpu_data) { - ret = -ENOMEM; - goto out; - } - cpuidle_drv = cpuidle_driver_ref(); - if (!cpuidle_drv) { - ret = -ENODEV; - goto out; - } - if (cpuidle_drv->state_count <= state) { - ret = -EINVAL; - goto err; - } - idle_state = &cpuidle_drv->states[state]; - if (!idle_state->disabled) { - ret = -EAGAIN; - goto err; - } - cpu_data->idle_state = idle_state; - cpu_data->saved_exit_latency = idle_state->exit_latency; - genpd->cpu_data = cpu_data; - genpd_recalc_cpu_exit_latency(genpd); - - out: - genpd_release_lock(genpd); - return ret; - - err: - cpuidle_driver_unref(); - goto out; -} - -int genpd_detach_cpuidle(struct generic_pm_domain *genpd) -{ - struct gpd_cpu_data *cpu_data; - struct cpuidle_state *idle_state; - int ret = 0; - - if (IS_ERR_OR_NULL(genpd)) - return -EINVAL; - - genpd_acquire_lock(genpd); - - cpu_data = genpd->cpu_data; - if (!cpu_data) { - ret = -ENODEV; - goto out; - } - idle_state = cpu_data->idle_state; - if (!idle_state->disabled) { - ret = -EAGAIN; - goto out; - } - idle_state->exit_latency = cpu_data->saved_exit_latency; - cpuidle_driver_unref(); - genpd->cpu_data = NULL; - kfree(cpu_data); - - out: - genpd_release_lock(genpd); return ret; } +EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); /* Default device callbacks for generic PM domains. */ @@ -1793,24 +1615,16 @@ int genpd_detach_cpuidle(struct generic_pm_domain *genpd) static int pm_genpd_default_save_state(struct device *dev) { int (*cb)(struct device *__dev); + struct device_driver *drv = dev->driver; cb = dev_gpd_data(dev)->ops.save_state; if (cb) return cb(dev); - if (dev->type && dev->type->pm) - cb = dev->type->pm->runtime_suspend; - else if (dev->class && dev->class->pm) - cb = dev->class->pm->runtime_suspend; - else if (dev->bus && dev->bus->pm) - cb = dev->bus->pm->runtime_suspend; - else - cb = NULL; - - if (!cb && dev->driver && dev->driver->pm) - cb = dev->driver->pm->runtime_suspend; + if (drv && drv->pm && drv->pm->runtime_suspend) + return drv->pm->runtime_suspend(dev); - return cb ? cb(dev) : 0; + return 0; } /** @@ -1820,24 +1634,16 @@ static int pm_genpd_default_save_state(struct device *dev) static int pm_genpd_default_restore_state(struct device *dev) { int (*cb)(struct device *__dev); + struct device_driver *drv = dev->driver; cb = dev_gpd_data(dev)->ops.restore_state; if (cb) return cb(dev); - if (dev->type && dev->type->pm) - cb = dev->type->pm->runtime_resume; - else if (dev->class && dev->class->pm) - cb = dev->class->pm->runtime_resume; - else if (dev->bus && dev->bus->pm) - cb = dev->bus->pm->runtime_resume; - else - cb = NULL; + if (drv && drv->pm && drv->pm->runtime_resume) + return drv->pm->runtime_resume(dev); - if (!cb && dev->driver && dev->driver->pm) - cb = dev->driver->pm->runtime_resume; - - return cb ? cb(dev) : 0; + return 0; } #ifdef CONFIG_PM_SLEEP diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 0113adc310dc..e0fb5b0435a3 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -28,7 +28,7 @@ #include #include #include -#include + #include "../base.h" #include "power.h" @@ -45,10 +45,10 @@ typedef int (*pm_callback_t)(struct device *); */ LIST_HEAD(dpm_list); -static LIST_HEAD(dpm_prepared_list); -static LIST_HEAD(dpm_suspended_list); -static LIST_HEAD(dpm_late_early_list); -static LIST_HEAD(dpm_noirq_list); +LIST_HEAD(dpm_prepared_list); +LIST_HEAD(dpm_suspended_list); +LIST_HEAD(dpm_late_early_list); +LIST_HEAD(dpm_noirq_list); struct suspend_stats suspend_stats; static DEFINE_MUTEX(dpm_list_mtx); @@ -166,7 +166,7 @@ static ktime_t initcall_debug_start(struct device *dev) { ktime_t calltime = ktime_set(0, 0); - if (pm_print_times_enabled) { + if (initcall_debug) { pr_info("calling %s+ @ %i, parent: %s\n", dev_name(dev), task_pid_nr(current), dev->parent ? dev_name(dev->parent) : "none"); @@ -181,7 +181,7 @@ static void initcall_debug_report(struct device *dev, ktime_t calltime, { ktime_t delta, rettime; - if (pm_print_times_enabled) { + if (initcall_debug) { rettime = ktime_get(); delta = ktime_sub(rettime, calltime); pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), @@ -467,7 +467,6 @@ static void dpm_resume_noirq(pm_message_t state) mutex_unlock(&dpm_list_mtx); dpm_show_time(starttime, state, "noirq"); resume_device_irqs(); - cpuidle_resume(); } /** @@ -868,7 +867,6 @@ static int dpm_suspend_noirq(pm_message_t state) ktime_t starttime = ktime_get(); int error = 0; - cpuidle_pause(); suspend_device_irqs(); mutex_lock(&dpm_list_mtx); while (!list_empty(&dpm_late_early_list)) { @@ -991,16 +989,8 @@ static int dpm_suspend_late(pm_message_t state) int dpm_suspend_end(pm_message_t state) { int error = dpm_suspend_late(state); - if (error) - return error; - - error = dpm_suspend_noirq(state); - if (error) { - dpm_resume_early(state); - return error; - } - return 0; + return error ? : dpm_suspend_noirq(state); } EXPORT_SYMBOL_GPL(dpm_suspend_end); @@ -1041,7 +1031,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dpm_wait_for_children(dev, async); if (async_error) - goto Complete; + return 0; pm_runtime_get_noresume(dev); if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) @@ -1050,7 +1040,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (pm_wakeup_pending()) { pm_runtime_put_sync(dev); async_error = -EBUSY; - goto Complete; + return 0; } device_lock(dev); @@ -1107,8 +1097,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } device_unlock(dev); - - Complete: complete_all(&dev->power.completion); if (error) { diff --git a/trunk/drivers/base/power/qos.c b/trunk/drivers/base/power/qos.c index 74a67e0019a2..fd849a2c4fa8 100644 --- a/trunk/drivers/base/power/qos.c +++ b/trunk/drivers/base/power/qos.c @@ -462,7 +462,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); static void __dev_pm_qos_drop_user_request(struct device *dev) { dev_pm_qos_remove_request(dev->power.pq_req); - dev->power.pq_req = NULL; + dev->power.pq_req = 0; } /** diff --git a/trunk/drivers/base/power/sysfs.c b/trunk/drivers/base/power/sysfs.c index b91dc6f1e914..48be2ad4dd2c 100644 --- a/trunk/drivers/base/power/sysfs.c +++ b/trunk/drivers/base/power/sysfs.c @@ -474,8 +474,6 @@ static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL); #endif -#ifdef CONFIG_PM_SLEEP - static ssize_t async_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -502,8 +500,6 @@ static ssize_t async_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(async, 0644, async_show, async_store); - -#endif #endif /* CONFIG_PM_ADVANCED_DEBUG */ static struct attribute *power_attrs[] = { diff --git a/trunk/drivers/base/regmap/internal.h b/trunk/drivers/base/regmap/internal.h index 80f9ab9c3aa4..b986b8660b0c 100644 --- a/trunk/drivers/base/regmap/internal.h +++ b/trunk/drivers/base/regmap/internal.h @@ -95,9 +95,6 @@ struct regmap { /* if set, converts bulk rw to single rw */ bool use_single_rw; - - struct rb_root range_tree; - void *selector_work_buf; /* Scratch buffer used for selector */ }; struct regcache_ops { @@ -118,20 +115,6 @@ bool regmap_precious(struct regmap *map, unsigned int reg); int _regmap_write(struct regmap *map, unsigned int reg, unsigned int val); -struct regmap_range_node { - struct rb_node node; - - unsigned int range_min; - unsigned int range_max; - - unsigned int selector_reg; - unsigned int selector_mask; - int selector_shift; - - unsigned int window_start; - unsigned int window_len; -}; - #ifdef CONFIG_DEBUG_FS extern void regmap_debugfs_initcall(void); extern void regmap_debugfs_init(struct regmap *map, const char *name); diff --git a/trunk/drivers/base/regmap/regmap-irq.c b/trunk/drivers/base/regmap/regmap-irq.c index a89734621e51..4fac4b9be88f 100644 --- a/trunk/drivers/base/regmap/regmap-irq.c +++ b/trunk/drivers/base/regmap/regmap-irq.c @@ -24,18 +24,14 @@ struct regmap_irq_chip_data { struct mutex lock; struct regmap *map; - const struct regmap_irq_chip *chip; + struct regmap_irq_chip *chip; int irq_base; struct irq_domain *domain; - int irq; - int wake_count; - unsigned int *status_buf; unsigned int *mask_buf; unsigned int *mask_buf_def; - unsigned int *wake_buf; unsigned int irq_reg_stride; }; @@ -75,16 +71,6 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->chip->mask_base + (i * map->reg_stride)); } - /* If we've changed our wakeup count propagate it to the parent */ - if (d->wake_count < 0) - for (i = d->wake_count; i < 0; i++) - irq_set_irq_wake(d->irq, 0); - else if (d->wake_count > 0) - for (i = 0; i < d->wake_count; i++) - irq_set_irq_wake(d->irq, 1); - - d->wake_count = 0; - mutex_unlock(&d->lock); } @@ -106,41 +92,18 @@ static void regmap_irq_disable(struct irq_data *data) d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; } -static int regmap_irq_set_wake(struct irq_data *data, unsigned int on) -{ - struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); - struct regmap *map = d->map; - const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); - - if (!d->chip->wake_base) - return -EINVAL; - - if (on) { - d->wake_buf[irq_data->reg_offset / map->reg_stride] - &= ~irq_data->mask; - d->wake_count++; - } else { - d->wake_buf[irq_data->reg_offset / map->reg_stride] - |= irq_data->mask; - d->wake_count--; - } - - return 0; -} - static struct irq_chip regmap_irq_chip = { .name = "regmap", .irq_bus_lock = regmap_irq_lock, .irq_bus_sync_unlock = regmap_irq_sync_unlock, .irq_disable = regmap_irq_disable, .irq_enable = regmap_irq_enable, - .irq_set_wake = regmap_irq_set_wake, }; static irqreturn_t regmap_irq_thread(int irq, void *d) { struct regmap_irq_chip_data *data = d; - const struct regmap_irq_chip *chip = data->chip; + struct regmap_irq_chip *chip = data->chip; struct regmap *map = data->map; int ret, i; bool handled = false; @@ -232,7 +195,7 @@ static struct irq_domain_ops regmap_domain_ops = { * register values used by the IRQ controller over suspend and resume. */ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, - int irq_base, const struct regmap_irq_chip *chip, + int irq_base, struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { struct regmap_irq_chip_data *d; @@ -277,14 +240,6 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, if (!d->mask_buf_def) goto err_alloc; - if (chip->wake_base) { - d->wake_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, - GFP_KERNEL); - if (!d->wake_buf) - goto err_alloc; - } - - d->irq = irq; d->map = map; d->chip = chip; d->irq_base = irq_base; @@ -339,7 +294,6 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, err_domain: /* Should really dispose of the domain but... */ err_alloc: - kfree(d->wake_buf); kfree(d->mask_buf_def); kfree(d->mask_buf); kfree(d->status_buf); @@ -361,7 +315,6 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) free_irq(irq, d); /* We should unmap the domain but... */ - kfree(d->wake_buf); kfree(d->mask_buf_def); kfree(d->mask_buf); kfree(d->status_buf); @@ -393,10 +346,6 @@ EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); */ int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) { - /* Handle holes in the IRQ list */ - if (!data->chip->irqs[irq].mask) - return -EINVAL; - return irq_create_mapping(data->domain, irq); } EXPORT_SYMBOL_GPL(regmap_irq_get_virq); diff --git a/trunk/drivers/base/regmap/regmap-mmio.c b/trunk/drivers/base/regmap/regmap-mmio.c index f05fc74dd84a..febd6de6c8ac 100644 --- a/trunk/drivers/base/regmap/regmap-mmio.c +++ b/trunk/drivers/base/regmap/regmap-mmio.c @@ -37,7 +37,7 @@ static int regmap_mmio_gather_write(void *context, BUG_ON(reg_size != 4); - offset = *(u32 *)reg; + offset = be32_to_cpup(reg); while (val_size) { switch (ctx->val_bytes) { @@ -45,14 +45,14 @@ static int regmap_mmio_gather_write(void *context, writeb(*(u8 *)val, ctx->regs + offset); break; case 2: - writew(*(u16 *)val, ctx->regs + offset); + writew(be16_to_cpup(val), ctx->regs + offset); break; case 4: - writel(*(u32 *)val, ctx->regs + offset); + writel(be32_to_cpup(val), ctx->regs + offset); break; #ifdef CONFIG_64BIT case 8: - writeq(*(u64 *)val, ctx->regs + offset); + writeq(be64_to_cpup(val), ctx->regs + offset); break; #endif default: @@ -83,7 +83,7 @@ static int regmap_mmio_read(void *context, BUG_ON(reg_size != 4); - offset = *(u32 *)reg; + offset = be32_to_cpup(reg); while (val_size) { switch (ctx->val_bytes) { @@ -91,14 +91,14 @@ static int regmap_mmio_read(void *context, *(u8 *)val = readb(ctx->regs + offset); break; case 2: - *(u16 *)val = readw(ctx->regs + offset); + *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset)); break; case 4: - *(u32 *)val = readl(ctx->regs + offset); + *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset)); break; #ifdef CONFIG_64BIT case 8: - *(u64 *)val = readq(ctx->regs + offset); + *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset)); break; #endif default: @@ -124,11 +124,9 @@ static struct regmap_bus regmap_mmio = { .gather_write = regmap_mmio_gather_write, .read = regmap_mmio_read, .free_context = regmap_mmio_free_context, - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, - .val_format_endian_default = REGMAP_ENDIAN_NATIVE, }; -static struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, +struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, const struct regmap_config *config) { struct regmap_mmio_context *ctx; @@ -164,15 +162,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, if (config->reg_stride < min_stride) return ERR_PTR(-EINVAL); - switch (config->reg_format_endian) { - case REGMAP_ENDIAN_DEFAULT: - case REGMAP_ENDIAN_NATIVE: - break; - default: - return ERR_PTR(-EINVAL); - } - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc(GFP_KERNEL, sizeof(*ctx)); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/trunk/drivers/base/regmap/regmap.c b/trunk/drivers/base/regmap/regmap.c index c241ae2f2f10..0bcda488f11c 100644 --- a/trunk/drivers/base/regmap/regmap.c +++ b/trunk/drivers/base/regmap/regmap.c @@ -15,25 +15,12 @@ #include #include #include -#include #define CREATE_TRACE_POINTS #include #include "internal.h" -/* - * Sometimes for failures during very early init the trace - * infrastructure isn't available early enough to be used. For this - * sort of problem defining LOG_DEVICE will add printks for basic - * register I/O on a specific device. - */ -#undef LOG_DEVICE - -static int _regmap_update_bits(struct regmap *map, unsigned int reg, - unsigned int mask, unsigned int val, - bool *change); - bool regmap_writeable(struct regmap *map, unsigned int reg) { if (map->max_register && reg > map->max_register) @@ -132,19 +119,13 @@ static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) b[0] = val << shift; } -static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_16(void *buf, unsigned int val, unsigned int shift) { __be16 *b = buf; b[0] = cpu_to_be16(val << shift); } -static void regmap_format_16_native(void *buf, unsigned int val, - unsigned int shift) -{ - *(u16 *)buf = val << shift; -} - static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) { u8 *b = buf; @@ -156,19 +137,13 @@ static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) b[2] = val; } -static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_32(void *buf, unsigned int val, unsigned int shift) { __be32 *b = buf; b[0] = cpu_to_be32(val << shift); } -static void regmap_format_32_native(void *buf, unsigned int val, - unsigned int shift) -{ - *(u32 *)buf = val << shift; -} - static unsigned int regmap_parse_8(void *buf) { u8 *b = buf; @@ -176,7 +151,7 @@ static unsigned int regmap_parse_8(void *buf) return b[0]; } -static unsigned int regmap_parse_16_be(void *buf) +static unsigned int regmap_parse_16(void *buf) { __be16 *b = buf; @@ -185,11 +160,6 @@ static unsigned int regmap_parse_16_be(void *buf) return b[0]; } -static unsigned int regmap_parse_16_native(void *buf) -{ - return *(u16 *)buf; -} - static unsigned int regmap_parse_24(void *buf) { u8 *b = buf; @@ -200,7 +170,7 @@ static unsigned int regmap_parse_24(void *buf) return ret; } -static unsigned int regmap_parse_32_be(void *buf) +static unsigned int regmap_parse_32(void *buf) { __be32 *b = buf; @@ -209,11 +179,6 @@ static unsigned int regmap_parse_32_be(void *buf) return b[0]; } -static unsigned int regmap_parse_32_native(void *buf) -{ - return *(u32 *)buf; -} - static void regmap_lock_mutex(struct regmap *map) { mutex_lock(&map->mutex); @@ -243,67 +208,6 @@ static void dev_get_regmap_release(struct device *dev, void *res) */ } -static bool _regmap_range_add(struct regmap *map, - struct regmap_range_node *data) -{ - struct rb_root *root = &map->range_tree; - struct rb_node **new = &(root->rb_node), *parent = NULL; - - while (*new) { - struct regmap_range_node *this = - container_of(*new, struct regmap_range_node, node); - - parent = *new; - if (data->range_max < this->range_min) - new = &((*new)->rb_left); - else if (data->range_min > this->range_max) - new = &((*new)->rb_right); - else - return false; - } - - rb_link_node(&data->node, parent, new); - rb_insert_color(&data->node, root); - - return true; -} - -static struct regmap_range_node *_regmap_range_lookup(struct regmap *map, - unsigned int reg) -{ - struct rb_node *node = map->range_tree.rb_node; - - while (node) { - struct regmap_range_node *this = - container_of(node, struct regmap_range_node, node); - - if (reg < this->range_min) - node = node->rb_left; - else if (reg > this->range_max) - node = node->rb_right; - else - return this; - } - - return NULL; -} - -static void regmap_range_exit(struct regmap *map) -{ - struct rb_node *next; - struct regmap_range_node *range_node; - - next = rb_first(&map->range_tree); - while (next) { - range_node = rb_entry(next, struct regmap_range_node, node); - next = rb_next(&range_node->node); - rb_erase(&range_node->node, &map->range_tree); - kfree(range_node); - } - - kfree(map->selector_work_buf); -} - /** * regmap_init(): Initialise register map * @@ -323,8 +227,6 @@ struct regmap *regmap_init(struct device *dev, { struct regmap *map, **m; int ret = -EINVAL; - enum regmap_endian reg_endian, val_endian; - int i, j; if (!bus || !config) goto err; @@ -344,11 +246,11 @@ struct regmap *regmap_init(struct device *dev, map->lock = regmap_lock_mutex; map->unlock = regmap_unlock_mutex; } + map->format.buf_size = (config->reg_bits + config->val_bits) / 8; map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); map->format.pad_bytes = config->pad_bits / 8; map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); - map->format.buf_size = DIV_ROUND_UP(config->reg_bits + - config->val_bits + config->pad_bits, 8); + map->format.buf_size += map->format.pad_bytes; map->reg_shift = config->pad_bits % 8; if (config->reg_stride) map->reg_stride = config->reg_stride; @@ -373,18 +275,6 @@ struct regmap *regmap_init(struct device *dev, map->read_flag_mask = bus->read_flag_mask; } - reg_endian = config->reg_format_endian; - if (reg_endian == REGMAP_ENDIAN_DEFAULT) - reg_endian = bus->reg_format_endian_default; - if (reg_endian == REGMAP_ENDIAN_DEFAULT) - reg_endian = REGMAP_ENDIAN_BIG; - - val_endian = config->val_format_endian; - if (val_endian == REGMAP_ENDIAN_DEFAULT) - val_endian = bus->val_format_endian_default; - if (val_endian == REGMAP_ENDIAN_DEFAULT) - val_endian = REGMAP_ENDIAN_BIG; - switch (config->reg_bits + map->reg_shift) { case 2: switch (config->val_bits) { @@ -431,29 +321,11 @@ struct regmap *regmap_init(struct device *dev, break; case 16: - switch (reg_endian) { - case REGMAP_ENDIAN_BIG: - map->format.format_reg = regmap_format_16_be; - break; - case REGMAP_ENDIAN_NATIVE: - map->format.format_reg = regmap_format_16_native; - break; - default: - goto err_map; - } + map->format.format_reg = regmap_format_16; break; case 32: - switch (reg_endian) { - case REGMAP_ENDIAN_BIG: - map->format.format_reg = regmap_format_32_be; - break; - case REGMAP_ENDIAN_NATIVE: - map->format.format_reg = regmap_format_32_native; - break; - default: - goto err_map; - } + map->format.format_reg = regmap_format_32; break; default: @@ -466,47 +338,21 @@ struct regmap *regmap_init(struct device *dev, map->format.parse_val = regmap_parse_8; break; case 16: - switch (val_endian) { - case REGMAP_ENDIAN_BIG: - map->format.format_val = regmap_format_16_be; - map->format.parse_val = regmap_parse_16_be; - break; - case REGMAP_ENDIAN_NATIVE: - map->format.format_val = regmap_format_16_native; - map->format.parse_val = regmap_parse_16_native; - break; - default: - goto err_map; - } + map->format.format_val = regmap_format_16; + map->format.parse_val = regmap_parse_16; break; case 24: - if (val_endian != REGMAP_ENDIAN_BIG) - goto err_map; map->format.format_val = regmap_format_24; map->format.parse_val = regmap_parse_24; break; case 32: - switch (val_endian) { - case REGMAP_ENDIAN_BIG: - map->format.format_val = regmap_format_32_be; - map->format.parse_val = regmap_parse_32_be; - break; - case REGMAP_ENDIAN_NATIVE: - map->format.format_val = regmap_format_32_native; - map->format.parse_val = regmap_parse_32_native; - break; - default: - goto err_map; - } + map->format.format_val = regmap_format_32; + map->format.parse_val = regmap_parse_32; break; } - if (map->format.format_write) { - if ((reg_endian != REGMAP_ENDIAN_BIG) || - (val_endian != REGMAP_ENDIAN_BIG)) - goto err_map; + if (map->format.format_write) map->use_single_rw = true; - } if (!map->format.format_write && !(map->format.format_reg && map->format.format_val)) @@ -518,88 +364,26 @@ struct regmap *regmap_init(struct device *dev, goto err_map; } - map->range_tree = RB_ROOT; - for (i = 0; i < config->n_ranges; i++) { - const struct regmap_range_cfg *range_cfg = &config->ranges[i]; - struct regmap_range_node *new; - - /* Sanity check */ - if (range_cfg->range_max < range_cfg->range_min || - range_cfg->range_max > map->max_register || - range_cfg->selector_reg > map->max_register || - range_cfg->window_len == 0) - goto err_range; - - /* Make sure, that this register range has no selector - or data window within its boundary */ - for (j = 0; j < config->n_ranges; j++) { - unsigned sel_reg = config->ranges[j].selector_reg; - unsigned win_min = config->ranges[j].window_start; - unsigned win_max = win_min + - config->ranges[j].window_len - 1; - - if (range_cfg->range_min <= sel_reg && - sel_reg <= range_cfg->range_max) { - goto err_range; - } - - if (!(win_max < range_cfg->range_min || - win_min > range_cfg->range_max)) { - goto err_range; - } - } - - new = kzalloc(sizeof(*new), GFP_KERNEL); - if (new == NULL) { - ret = -ENOMEM; - goto err_range; - } - - new->range_min = range_cfg->range_min; - new->range_max = range_cfg->range_max; - new->selector_reg = range_cfg->selector_reg; - new->selector_mask = range_cfg->selector_mask; - new->selector_shift = range_cfg->selector_shift; - new->window_start = range_cfg->window_start; - new->window_len = range_cfg->window_len; - - if (_regmap_range_add(map, new) == false) { - kfree(new); - goto err_range; - } - - if (map->selector_work_buf == NULL) { - map->selector_work_buf = - kzalloc(map->format.buf_size, GFP_KERNEL); - if (map->selector_work_buf == NULL) { - ret = -ENOMEM; - goto err_range; - } - } - } + regmap_debugfs_init(map, config->name); ret = regcache_init(map, config); if (ret < 0) - goto err_range; - - regmap_debugfs_init(map, config->name); + goto err_free_workbuf; /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); if (!m) { ret = -ENOMEM; - goto err_debugfs; + goto err_cache; } *m = map; devres_add(dev, m); return map; -err_debugfs: - regmap_debugfs_exit(map); +err_cache: regcache_exit(map); -err_range: - regmap_range_exit(map); +err_free_workbuf: kfree(map->work_buf); err_map: kfree(map); @@ -687,7 +471,6 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) return ret; } -EXPORT_SYMBOL_GPL(regmap_reinit_cache); /** * regmap_exit(): Free a previously allocated register map @@ -696,7 +479,6 @@ void regmap_exit(struct regmap *map) { regcache_exit(map); regmap_debugfs_exit(map); - regmap_range_exit(map); if (map->bus->free_context) map->bus->free_context(map->bus_context); kfree(map->work_buf); @@ -742,57 +524,6 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name) } EXPORT_SYMBOL_GPL(dev_get_regmap); -static int _regmap_select_page(struct regmap *map, unsigned int *reg, - unsigned int val_num) -{ - struct regmap_range_node *range; - void *orig_work_buf; - unsigned int win_offset; - unsigned int win_page; - bool page_chg; - int ret; - - range = _regmap_range_lookup(map, *reg); - if (range) { - win_offset = (*reg - range->range_min) % range->window_len; - win_page = (*reg - range->range_min) / range->window_len; - - if (val_num > 1) { - /* Bulk write shouldn't cross range boundary */ - if (*reg + val_num - 1 > range->range_max) - return -EINVAL; - - /* ... or single page boundary */ - if (val_num > range->window_len - win_offset) - return -EINVAL; - } - - /* It is possible to have selector register inside data window. - In that case, selector register is located on every page and - it needs no page switching, when accessed alone. */ - if (val_num > 1 || - range->window_start + win_offset != range->selector_reg) { - /* Use separate work_buf during page switching */ - orig_work_buf = map->work_buf; - map->work_buf = map->selector_work_buf; - - ret = _regmap_update_bits(map, range->selector_reg, - range->selector_mask, - win_page << range->selector_shift, - &page_chg); - - map->work_buf = orig_work_buf; - - if (ret < 0) - return ret; - } - - *reg = range->window_start + win_offset; - } - - return 0; -} - static int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { @@ -830,10 +561,6 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, } } - ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); - if (ret < 0) - return ret; - map->format.format_reg(map->work_buf, reg, map->reg_shift); u8[0] |= map->write_flag_mask; @@ -894,18 +621,9 @@ int _regmap_write(struct regmap *map, unsigned int reg, } } -#ifdef LOG_DEVICE - if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) - dev_info(map->dev, "%x <= %x\n", reg, val); -#endif - trace_regmap_reg_write(map->dev, reg, val); if (map->format.format_write) { - ret = _regmap_select_page(map, ®, 1); - if (ret < 0) - return ret; - map->format.format_write(map, reg, val); trace_regmap_hw_write_start(map->dev, reg, 1); @@ -1063,10 +781,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, u8 *u8 = map->work_buf; int ret; - ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); - if (ret < 0) - return ret; - map->format.format_reg(map->work_buf, reg, map->reg_shift); /* @@ -1110,12 +824,6 @@ static int _regmap_read(struct regmap *map, unsigned int reg, ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); if (ret == 0) { *val = map->format.parse_val(map->work_buf); - -#ifdef LOG_DEVICE - if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) - dev_info(map->dev, "%x => %x\n", reg, *val); -#endif - trace_regmap_reg_read(map->dev, reg, *val); } @@ -1272,9 +980,11 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, int ret; unsigned int tmp, orig; + map->lock(map); + ret = _regmap_read(map, reg, &orig); if (ret != 0) - return ret; + goto out; tmp = orig & ~mask; tmp |= val & mask; @@ -1286,6 +996,9 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, *change = false; } +out: + map->unlock(map); + return ret; } @@ -1303,13 +1016,7 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val) { bool change; - int ret; - - map->lock(map); - ret = _regmap_update_bits(map, reg, mask, val, &change); - map->unlock(map); - - return ret; + return _regmap_update_bits(map, reg, mask, val, &change); } EXPORT_SYMBOL_GPL(regmap_update_bits); @@ -1329,12 +1036,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change) { - int ret; - - map->lock(map); - ret = _regmap_update_bits(map, reg, mask, val, change); - map->unlock(map); - return ret; + return _regmap_update_bits(map, reg, mask, val, change); } EXPORT_SYMBOL_GPL(regmap_update_bits_check); diff --git a/trunk/drivers/bcma/driver_chipcommon_pmu.c b/trunk/drivers/bcma/driver_chipcommon_pmu.c index 61ce4054b3c3..a058842f14fd 100644 --- a/trunk/drivers/bcma/driver_chipcommon_pmu.c +++ b/trunk/drivers/bcma/driver_chipcommon_pmu.c @@ -139,9 +139,7 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc) bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); break; case 0x4331: - case 43431: - /* Ext PA lines must be enabled for tx on BCM4331 */ - bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true); + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */ break; case 43224: if (bus->chipinfo.rev == 0) { diff --git a/trunk/drivers/bcma/driver_pci.c b/trunk/drivers/bcma/driver_pci.c index c32ebd537abe..9a96f14c8f47 100644 --- a/trunk/drivers/bcma/driver_pci.c +++ b/trunk/drivers/bcma/driver_pci.c @@ -232,19 +232,17 @@ void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc) int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable) { - struct pci_dev *pdev; + struct pci_dev *pdev = pc->core->bus->host_pci; u32 coremask, tmp; int err = 0; - if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) { + if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) { /* This bcma device is not on a PCI host-bus. So the IRQs are * not routed through the PCI core. * So we must not enable routing through the PCI core. */ goto out; } - pdev = pc->core->bus->host_pci; - err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); if (err) goto out; diff --git a/trunk/drivers/bcma/sprom.c b/trunk/drivers/bcma/sprom.c index f16f42d36071..c7f93359acb0 100644 --- a/trunk/drivers/bcma/sprom.c +++ b/trunk/drivers/bcma/sprom.c @@ -579,13 +579,13 @@ int bcma_sprom_get(struct bcma_bus *bus) if (!sprom) return -ENOMEM; - if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431) + if (bus->chipinfo.id == 0x4331) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); - if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431) + if (bus->chipinfo.id == 0x4331) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); err = bcma_sprom_valid(sprom); diff --git a/trunk/drivers/block/drbd/drbd_bitmap.c b/trunk/drivers/block/drbd/drbd_bitmap.c index fcb956bb4b4c..b5c5ff53cb57 100644 --- a/trunk/drivers/block/drbd/drbd_bitmap.c +++ b/trunk/drivers/block/drbd/drbd_bitmap.c @@ -1475,17 +1475,10 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi first_word = 0; spin_lock_irq(&b->bm_lock); } + /* last page (respectively only page, for first page == last page) */ last_word = MLPP(el >> LN2_BPL); - - /* consider bitmap->bm_bits = 32768, bitmap->bm_number_of_pages = 1. (or multiples). - * ==> e = 32767, el = 32768, last_page = 2, - * and now last_word = 0. - * We do not want to touch last_page in this case, - * as we did not allocate it, it is not present in bitmap->bm_pages. - */ - if (last_word) - bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); + bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); /* possibly trailing bits. * example: (e & 63) == 63, el will be e+1. diff --git a/trunk/drivers/block/drbd/drbd_req.c b/trunk/drivers/block/drbd/drbd_req.c index 8e93a6ac9bb6..9c5c84946b05 100644 --- a/trunk/drivers/block/drbd/drbd_req.c +++ b/trunk/drivers/block/drbd/drbd_req.c @@ -472,17 +472,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - if (req->rq_state & RQ_LOCAL_ABORTED) { - _req_may_be_done(req, m); - break; - } + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); __drbd_chk_io_error(mdev, false); goto_queue_for_net_read: - D_ASSERT(!(req->rq_state & RQ_NET_MASK)); - /* no point in retrying if there is no good remote data, * or we have no connection. */ if (mdev->state.pdsk != D_UP_TO_DATE) { @@ -770,40 +765,6 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); } -static void maybe_pull_ahead(struct drbd_conf *mdev) -{ - int congested = 0; - - /* If I don't even have good local storage, we can not reasonably try - * to pull ahead of the peer. We also need the local reference to make - * sure mdev->act_log is there. - * Note: caller has to make sure that net_conf is there. - */ - if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) - return; - - if (mdev->net_conf->cong_fill && - atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { - dev_info(DEV, "Congestion-fill threshold reached\n"); - congested = 1; - } - - if (mdev->act_log->used >= mdev->net_conf->cong_extents) { - dev_info(DEV, "Congestion-extents threshold reached\n"); - congested = 1; - } - - if (congested) { - queue_barrier(mdev); /* last barrier, after mirrored writes */ - - if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) - _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); - else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ - _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); - } - put_ldev(mdev); -} - static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) { const int rw = bio_rw(bio); @@ -1011,8 +972,29 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns _req_mod(req, queue_for_send_oos); if (remote && - mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) - maybe_pull_ahead(mdev); + mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) { + int congested = 0; + + if (mdev->net_conf->cong_fill && + atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { + dev_info(DEV, "Congestion-fill threshold reached\n"); + congested = 1; + } + + if (mdev->act_log->used >= mdev->net_conf->cong_extents) { + dev_info(DEV, "Congestion-extents threshold reached\n"); + congested = 1; + } + + if (congested) { + queue_barrier(mdev); /* last barrier, after mirrored writes */ + + if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) + _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); + else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ + _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); + } + } spin_unlock_irq(&mdev->req_lock); kfree(b); /* if someone else has beaten us to it... */ diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 553f43a90953..cce7df367b79 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -671,7 +671,6 @@ static void __reschedule_timeout(int drive, const char *message) if (drive == current_reqD) drive = current_drive; - __cancel_delayed_work(&fd_timeout); if (drive < 0 || drive >= N_DRIVE) { delay = 20UL * HZ; diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 3bba65510d23..bbca966f8f66 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -1597,12 +1597,14 @@ static int loop_add(struct loop_device **l, int i) struct gendisk *disk; int err; - err = -ENOMEM; lo = kzalloc(sizeof(*lo), GFP_KERNEL); - if (!lo) + if (!lo) { + err = -ENOMEM; goto out; + } - if (!idr_pre_get(&loop_index_idr, GFP_KERNEL)) + err = idr_pre_get(&loop_index_idr, GFP_KERNEL); + if (err < 0) goto out_free_dev; if (i >= 0) { diff --git a/trunk/drivers/block/mg_disk.c b/trunk/drivers/block/mg_disk.c index 1788f491e0fb..76fa3deaee84 100644 --- a/trunk/drivers/block/mg_disk.c +++ b/trunk/drivers/block/mg_disk.c @@ -780,9 +780,9 @@ static const struct block_device_operations mg_disk_ops = { .getgeo = mg_getgeo }; -static int mg_suspend(struct device *dev) +static int mg_suspend(struct platform_device *plat_dev, pm_message_t state) { - struct mg_drv_data *prv_data = dev->platform_data; + struct mg_drv_data *prv_data = plat_dev->dev.platform_data; struct mg_host *host = prv_data->host; if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) @@ -804,9 +804,9 @@ static int mg_suspend(struct device *dev) return 0; } -static int mg_resume(struct device *dev) +static int mg_resume(struct platform_device *plat_dev) { - struct mg_drv_data *prv_data = dev->platform_data; + struct mg_drv_data *prv_data = plat_dev->dev.platform_data; struct mg_host *host = prv_data->host; if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) @@ -825,8 +825,6 @@ static int mg_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(mg_pm, mg_suspend, mg_resume); - static int mg_probe(struct platform_device *plat_dev) { struct mg_host *host; @@ -1076,10 +1074,11 @@ static int mg_remove(struct platform_device *plat_dev) static struct platform_driver mg_disk_driver = { .probe = mg_probe, .remove = mg_remove, + .suspend = mg_suspend, + .resume = mg_resume, .driver = { .name = MG_DEV_NAME, .owner = THIS_MODULE, - .pm = &mg_pm, } }; diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index a8fddeb3d638..264bc77dcb91 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -37,7 +37,6 @@ #include #include <../drivers/ata/ahci.h> #include -#include #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -86,7 +85,6 @@ static int instance; * allocated in mtip_init(). */ static int mtip_major; -static struct dentry *dfs_parent; static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); @@ -2548,7 +2546,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, } /* - * Sysfs status dump. + * Sysfs register/status dump. * * @dev Pointer to the device structure, passed by the kernrel. * @attr Pointer to the device_attribute structure passed by the kernel. @@ -2557,68 +2555,45 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t mtip_hw_show_status(struct device *dev, +static ssize_t mtip_hw_show_registers(struct device *dev, struct device_attribute *attr, char *buf) { + u32 group_allocated; struct driver_data *dd = dev_to_disk(dev)->private_data; int size = 0; - - if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "thermal_shutdown\n"); - else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "write_protect\n"); - else - size += sprintf(buf, "%s", "online\n"); - - return size; -} - -static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); - -static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, - size_t len, loff_t *offset) -{ - struct driver_data *dd = (struct driver_data *)f->private_data; - char buf[MTIP_DFS_MAX_BUF_SIZE]; - u32 group_allocated; - int size = *offset; int n; - if (!len || size) - return 0; - - if (size < 0) - return -EINVAL; - - size += sprintf(&buf[size], "H/ S ACTive : [ 0x"); + size += sprintf(&buf[size], "Hardware\n--------\n"); + size += sprintf(&buf[size], "S ACTive : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->s_active[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "H/ Command Issue : [ 0x"); + size += sprintf(&buf[size], "Command Issue : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->cmd_issue[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "H/ Completed : [ 0x"); + size += sprintf(&buf[size], "Completed : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->completed[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "H/ PORT IRQ STAT : [ 0x%08X ]\n", + size += sprintf(&buf[size], "PORT IRQ STAT : [ 0x%08X ]\n", readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "H/ HOST IRQ STAT : [ 0x%08X ]\n", + size += sprintf(&buf[size], "HOST IRQ STAT : [ 0x%08X ]\n", readl(dd->mmio + HOST_IRQ_STAT)); size += sprintf(&buf[size], "\n"); - size += sprintf(&buf[size], "L/ Allocated : [ 0x"); + size += sprintf(&buf[size], "Local\n-----\n"); + size += sprintf(&buf[size], "Allocated : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) { if (sizeof(long) > sizeof(u32)) @@ -2630,7 +2605,7 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, } size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "L/ Commands in Q : [ 0x"); + size += sprintf(&buf[size], "Commands in Q: [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) { if (sizeof(long) > sizeof(u32)) @@ -2642,53 +2617,44 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, } size += sprintf(&buf[size], "]\n"); - *offset = size <= len ? size : len; - size = copy_to_user(ubuf, buf, *offset); - if (size) - return -EFAULT; - - return *offset; + return size; } -static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, - size_t len, loff_t *offset) +static ssize_t mtip_hw_show_status(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct driver_data *dd = (struct driver_data *)f->private_data; - char buf[MTIP_DFS_MAX_BUF_SIZE]; - int size = *offset; + struct driver_data *dd = dev_to_disk(dev)->private_data; + int size = 0; - if (!len || size) - return 0; + if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "thermal_shutdown\n"); + else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "write_protect\n"); + else + size += sprintf(buf, "%s", "online\n"); - if (size < 0) - return -EINVAL; + return size; +} - size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n", +static ssize_t mtip_hw_show_flags(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct driver_data *dd = dev_to_disk(dev)->private_data; + int size = 0; + + size += sprintf(&buf[size], "Flag in port struct : [ %08lX ]\n", dd->port->flags); - size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n", + size += sprintf(&buf[size], "Flag in dd struct : [ %08lX ]\n", dd->dd_flag); - *offset = size <= len ? size : len; - size = copy_to_user(ubuf, buf, *offset); - if (size) - return -EFAULT; - - return *offset; + return size; } -static const struct file_operations mtip_regs_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mtip_hw_read_registers, - .llseek = no_llseek, -}; - -static const struct file_operations mtip_flags_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mtip_hw_read_flags, - .llseek = no_llseek, -}; +static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); +static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); +static DEVICE_ATTR(flags, S_IRUGO, mtip_hw_show_flags, NULL); /* * Create the sysfs related attributes. @@ -2705,9 +2671,15 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; + if (sysfs_create_file(kobj, &dev_attr_registers.attr)) + dev_warn(&dd->pdev->dev, + "Error creating 'registers' sysfs entry\n"); if (sysfs_create_file(kobj, &dev_attr_status.attr)) dev_warn(&dd->pdev->dev, "Error creating 'status' sysfs entry\n"); + if (sysfs_create_file(kobj, &dev_attr_flags.attr)) + dev_warn(&dd->pdev->dev, + "Error creating 'flags' sysfs entry\n"); return 0; } @@ -2726,39 +2698,13 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; + sysfs_remove_file(kobj, &dev_attr_registers.attr); sysfs_remove_file(kobj, &dev_attr_status.attr); + sysfs_remove_file(kobj, &dev_attr_flags.attr); return 0; } -static int mtip_hw_debugfs_init(struct driver_data *dd) -{ - if (!dfs_parent) - return -1; - - dd->dfs_node = debugfs_create_dir(dd->disk->disk_name, dfs_parent); - if (IS_ERR_OR_NULL(dd->dfs_node)) { - dev_warn(&dd->pdev->dev, - "Error creating node %s under debugfs\n", - dd->disk->disk_name); - dd->dfs_node = NULL; - return -1; - } - - debugfs_create_file("flags", S_IRUGO, dd->dfs_node, dd, - &mtip_flags_fops); - debugfs_create_file("registers", S_IRUGO, dd->dfs_node, dd, - &mtip_regs_fops); - - return 0; -} - -static void mtip_hw_debugfs_exit(struct driver_data *dd) -{ - debugfs_remove_recursive(dd->dfs_node); -} - - /* * Perform any init/resume time hardware setup * @@ -3784,7 +3730,6 @@ static int mtip_block_initialize(struct driver_data *dd) mtip_hw_sysfs_init(dd, kobj); kobject_put(kobj); } - mtip_hw_debugfs_init(dd); if (dd->mtip_svc_handler) { set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); @@ -3810,8 +3755,6 @@ static int mtip_block_initialize(struct driver_data *dd) return rv; kthread_run_error: - mtip_hw_debugfs_exit(dd); - /* Delete our gendisk. This also removes the device from /dev */ del_gendisk(dd->disk); @@ -3862,7 +3805,6 @@ static int mtip_block_remove(struct driver_data *dd) kobject_put(kobj); } } - mtip_hw_debugfs_exit(dd); /* * Delete our gendisk structure. This also removes the device @@ -4210,20 +4152,10 @@ static int __init mtip_init(void) } mtip_major = error; - if (!dfs_parent) { - dfs_parent = debugfs_create_dir("rssd", NULL); - if (IS_ERR_OR_NULL(dfs_parent)) { - printk(KERN_WARNING "Error creating debugfs parent\n"); - dfs_parent = NULL; - } - } - /* Register our PCI operations. */ error = pci_register_driver(&mtip_pci_driver); - if (error) { - debugfs_remove(dfs_parent); + if (error) unregister_blkdev(mtip_major, MTIP_DRV_NAME); - } return error; } @@ -4240,8 +4172,6 @@ static int __init mtip_init(void) */ static void __exit mtip_exit(void) { - debugfs_remove_recursive(dfs_parent); - /* Release the allocated major block device number. */ unregister_blkdev(mtip_major, MTIP_DRV_NAME); diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index f51fc23d17bb..b2c88da26b2a 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -26,6 +26,7 @@ #include #include #include +#include /* Offset of Subsystem Device ID in pci confoguration space */ #define PCI_SUBSYSTEM_DEVICEID 0x2E @@ -110,8 +111,6 @@ #define dbg_printk(format, arg...) #endif -#define MTIP_DFS_MAX_BUF_SIZE 1024 - #define __force_bit2int (unsigned int __force) enum { @@ -448,8 +447,6 @@ struct driver_data { unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ - - struct dentry *dfs_node; }; #endif diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index 8f428a8ab003..65665c9c42c6 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -499,7 +499,7 @@ static int rbd_header_from_disk(struct rbd_image_header *header, / sizeof (*ondisk)) return -EINVAL; header->snapc = kmalloc(sizeof(struct ceph_snap_context) + - snap_count * sizeof(u64), + snap_count * sizeof (*ondisk), gfp_flags); if (!header->snapc) return -ENOMEM; @@ -977,7 +977,7 @@ static void rbd_req_cb(struct ceph_osd_request *req, struct ceph_msg *msg) op = (void *)(replyhead + 1); rc = le32_to_cpu(replyhead->result); bytes = le64_to_cpu(op->extent.length); - read_op = (le16_to_cpu(op->op) == CEPH_OSD_OP_READ); + read_op = (le32_to_cpu(op->op) == CEPH_OSD_OP_READ); dout("rbd_req_cb bytes=%lld readop=%d rc=%d\n", bytes, read_op, rc); diff --git a/trunk/drivers/block/umem.c b/trunk/drivers/block/umem.c index 9a72277a31df..aa2712060bfb 100644 --- a/trunk/drivers/block/umem.c +++ b/trunk/drivers/block/umem.c @@ -513,44 +513,6 @@ static void process_page(unsigned long data) } } -struct mm_plug_cb { - struct blk_plug_cb cb; - struct cardinfo *card; -}; - -static void mm_unplug(struct blk_plug_cb *cb) -{ - struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); - - spin_lock_irq(&mmcb->card->lock); - activate(mmcb->card); - spin_unlock_irq(&mmcb->card->lock); - kfree(mmcb); -} - -static int mm_check_plugged(struct cardinfo *card) -{ - struct blk_plug *plug = current->plug; - struct mm_plug_cb *mmcb; - - if (!plug) - return 0; - - list_for_each_entry(mmcb, &plug->cb_list, cb.list) { - if (mmcb->cb.callback == mm_unplug && mmcb->card == card) - return 1; - } - /* Not currently on the callback list */ - mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC); - if (!mmcb) - return 0; - - mmcb->card = card; - mmcb->cb.callback = mm_unplug; - list_add(&mmcb->cb.list, &plug->cb_list); - return 1; -} - static void mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; @@ -561,8 +523,6 @@ static void mm_make_request(struct request_queue *q, struct bio *bio) *card->biotail = bio; bio->bi_next = NULL; card->biotail = &bio->bi_next; - if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card)) - activate(card); spin_unlock_irq(&card->lock); return; diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 9ad3b5ec1dc1..773cf27dc23f 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -257,7 +257,6 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; - dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; @@ -288,7 +287,6 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; - dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index e4fb3374dcd2..60eed4bdd2e4 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -141,36 +141,14 @@ static int get_id_from_freelist(struct blkfront_info *info) return free; } -static int add_id_to_freelist(struct blkfront_info *info, +static void add_id_to_freelist(struct blkfront_info *info, unsigned long id) { - if (info->shadow[id].req.u.rw.id != id) - return -EINVAL; - if (info->shadow[id].request == NULL) - return -EINVAL; info->shadow[id].req.u.rw.id = info->shadow_free; info->shadow[id].request = NULL; info->shadow_free = id; - return 0; } -static const char *op_name(int op) -{ - static const char *const names[] = { - [BLKIF_OP_READ] = "read", - [BLKIF_OP_WRITE] = "write", - [BLKIF_OP_WRITE_BARRIER] = "barrier", - [BLKIF_OP_FLUSH_DISKCACHE] = "flush", - [BLKIF_OP_DISCARD] = "discard" }; - - if (op < 0 || op >= ARRAY_SIZE(names)) - return "unknown"; - - if (!names[op]) - return "reserved"; - - return names[op]; -} static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) { unsigned int end = minor + nr; @@ -768,36 +746,20 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; - /* - * The backend has messed up and given us an id that we would - * never have given to it (we stamp it up to BLK_RING_SIZE - - * look in get_id_from_freelist. - */ - if (id >= BLK_RING_SIZE) { - WARN(1, "%s: response to %s has incorrect id (%ld)\n", - info->gd->disk_name, op_name(bret->operation), id); - /* We can't safely get the 'struct request' as - * the id is busted. */ - continue; - } req = info->shadow[id].request; if (bret->operation != BLKIF_OP_DISCARD) blkif_completion(&info->shadow[id]); - if (add_id_to_freelist(info, id)) { - WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n", - info->gd->disk_name, op_name(bret->operation), id); - continue; - } + add_id_to_freelist(info, id); error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; switch (bret->operation) { case BLKIF_OP_DISCARD: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { struct request_queue *rq = info->rq; - printk(KERN_WARNING "blkfront: %s: %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + printk(KERN_WARNING "blkfront: %s: discard op failed\n", + info->gd->disk_name); error = -EOPNOTSUPP; info->feature_discard = 0; info->feature_secdiscard = 0; @@ -809,14 +771,18 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) case BLKIF_OP_FLUSH_DISKCACHE: case BLKIF_OP_WRITE_BARRIER: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { - printk(KERN_WARNING "blkfront: %s: %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + printk(KERN_WARNING "blkfront: %s: write %s op failed\n", + info->flush_op == BLKIF_OP_WRITE_BARRIER ? + "barrier" : "flush disk cache", + info->gd->disk_name); error = -EOPNOTSUPP; } if (unlikely(bret->status == BLKIF_RSP_ERROR && info->shadow[id].req.u.rw.nr_segments == 0)) { - printk(KERN_WARNING "blkfront: %s: empty %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n", + info->flush_op == BLKIF_OP_WRITE_BARRIER ? + "barrier" : "flush disk cache", + info->gd->disk_name); error = -EOPNOTSUPP; } if (unlikely(error)) { diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index 10308cd8a7ed..ad591bd240ec 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -63,7 +63,6 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, - { USB_DEVICE(0x0CF3, 0xE019) }, { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, @@ -78,7 +77,6 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, - { USB_DEVICE(0x0930, 0x0219) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -103,7 +101,6 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, diff --git a/trunk/drivers/bluetooth/btmrvl_drv.h b/trunk/drivers/bluetooth/btmrvl_drv.h index 27068d149380..94f2d65131c4 100644 --- a/trunk/drivers/bluetooth/btmrvl_drv.h +++ b/trunk/drivers/bluetooth/btmrvl_drv.h @@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv); void btmrvl_interrupt(struct btmrvl_private *priv); -bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); +void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); diff --git a/trunk/drivers/bluetooth/btmrvl_main.c b/trunk/drivers/bluetooth/btmrvl_main.c index dc304def8400..681ca9d18e12 100644 --- a/trunk/drivers/bluetooth/btmrvl_main.c +++ b/trunk/drivers/bluetooth/btmrvl_main.c @@ -44,33 +44,23 @@ void btmrvl_interrupt(struct btmrvl_private *priv) } EXPORT_SYMBOL_GPL(btmrvl_interrupt); -bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) +void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; struct hci_ev_cmd_complete *ec; - u16 opcode, ocf, ogf; + u16 opcode, ocf; if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); - ogf = hci_opcode_ogf(opcode); - if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } - - if (ogf == OGF) { - BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf); - kfree_skb(skb); - return false; - } } - - return true; } EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); diff --git a/trunk/drivers/bluetooth/btmrvl_sdio.c b/trunk/drivers/bluetooth/btmrvl_sdio.c index 0cd61d9f07cd..a853244e7fd7 100644 --- a/trunk/drivers/bluetooth/btmrvl_sdio.c +++ b/trunk/drivers/bluetooth/btmrvl_sdio.c @@ -562,12 +562,10 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); - if (type == HCI_EVENT_PKT) { - if (btmrvl_check_evtpkt(priv, skb)) - hci_recv_frame(skb); - } else - hci_recv_frame(skb); + if (type == HCI_EVENT_PKT) + btmrvl_check_evtpkt(priv, skb); + hci_recv_frame(skb); hdev->stat.byte_rx += buf_len; break; diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index 83ebb241bfcc..c9463af8e564 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -125,7 +125,6 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, @@ -140,7 +139,6 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index 0a4185279417..764f70c5e690 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -898,7 +898,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_B43_HB), ID(PCI_DEVICE_ID_INTEL_B43_1_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), - ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), diff --git a/trunk/drivers/char/agp/intel-agp.h b/trunk/drivers/char/agp/intel-agp.h index 8e2d9140f300..c0091753a0d1 100644 --- a/trunk/drivers/char/agp/intel-agp.h +++ b/trunk/drivers/char/agp/intel-agp.h @@ -212,7 +212,6 @@ #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040 -#define PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB 0x0069 #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042 #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044 #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 diff --git a/trunk/drivers/char/hw_random/atmel-rng.c b/trunk/drivers/char/hw_random/atmel-rng.c index 731c9046cf7b..f518b99f53f5 100644 --- a/trunk/drivers/char/hw_random/atmel-rng.c +++ b/trunk/drivers/char/hw_random/atmel-rng.c @@ -34,15 +34,8 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, u32 *data = buf; /* data ready? */ - if (readl(trng->base + TRNG_ISR) & 1) { + if (readl(trng->base + TRNG_ODATA) & 1) { *data = readl(trng->base + TRNG_ODATA); - /* - ensure data ready is only set again AFTER the next data - word is ready in case it got set between checking ISR - and reading ODATA, so we don't risk re-reading the - same word - */ - readl(trng->base + TRNG_ISR); return 4; } else return 0; diff --git a/trunk/drivers/char/hw_random/omap-rng.c b/trunk/drivers/char/hw_random/omap-rng.c index d706bd0e9e80..1412565c01af 100644 --- a/trunk/drivers/char/hw_random/omap-rng.c +++ b/trunk/drivers/char/hw_random/omap-rng.c @@ -162,24 +162,22 @@ static int __exit omap_rng_remove(struct platform_device *pdev) #ifdef CONFIG_PM -static int omap_rng_suspend(struct device *dev) +static int omap_rng_suspend(struct platform_device *pdev, pm_message_t message) { omap_rng_write_reg(RNG_MASK_REG, 0x0); return 0; } -static int omap_rng_resume(struct device *dev) +static int omap_rng_resume(struct platform_device *pdev) { omap_rng_write_reg(RNG_MASK_REG, 0x1); return 0; } -static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); -#define OMAP_RNG_PM (&omap_rng_pm) - #else -#define OMAP_RNG_PM NULL +#define omap_rng_suspend NULL +#define omap_rng_resume NULL #endif @@ -190,10 +188,11 @@ static struct platform_driver omap_rng_driver = { .driver = { .name = "omap_rng", .owner = THIS_MODULE, - .pm = OMAP_RNG_PM, }, .probe = omap_rng_probe, .remove = __exit_p(omap_rng_remove), + .suspend = omap_rng_suspend, + .resume = omap_rng_resume }; static int __init omap_rng_init(void) diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 83f85cf7fb1b..1e638fff40ea 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -2503,6 +2503,18 @@ static void __devexit ipmi_pci_remove(struct pci_dev *pdev) cleanup_one_si(info); } +#ifdef CONFIG_PM +static int ipmi_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + return 0; +} + +static int ipmi_pci_resume(struct pci_dev *pdev) +{ + return 0; +} +#endif + static struct pci_device_id ipmi_pci_devices[] = { { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, @@ -2515,6 +2527,10 @@ static struct pci_driver ipmi_pci_driver = { .id_table = ipmi_pci_devices, .probe = ipmi_pci_probe, .remove = __devexit_p(ipmi_pci_remove), +#ifdef CONFIG_PM + .suspend = ipmi_pci_suspend, + .resume = ipmi_pci_resume, +#endif }; #endif /* CONFIG_PCI */ diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index f87780502b41..45713f0e7d61 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -1459,7 +1459,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) #ifdef CONFIG_PM static int old_camera_power; -static int sonypi_suspend(struct device *dev) +static int sonypi_suspend(struct platform_device *dev, pm_message_t state) { old_camera_power = sonypi_device.camera_power; sonypi_disable(); @@ -1467,16 +1467,14 @@ static int sonypi_suspend(struct device *dev) return 0; } -static int sonypi_resume(struct device *dev) +static int sonypi_resume(struct platform_device *dev) { sonypi_enable(old_camera_power); return 0; } - -static SIMPLE_DEV_PM_OPS(sonypi_pm, sonypi_suspend, sonypi_resume); -#define SONYPI_PM (&sonypi_pm) #else -#define SONYPI_PM NULL +#define sonypi_suspend NULL +#define sonypi_resume NULL #endif static void sonypi_shutdown(struct platform_device *dev) @@ -1488,11 +1486,12 @@ static struct platform_driver sonypi_driver = { .driver = { .name = "sonypi", .owner = THIS_MODULE, - .pm = SONYPI_PM, }, .probe = sonypi_probe, .remove = __devexit_p(sonypi_remove), .shutdown = sonypi_shutdown, + .suspend = sonypi_suspend, + .resume = sonypi_resume, }; static struct platform_device *sonypi_platform_device; diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index ae43ac55fc1e..ad7c7320dd1b 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -1274,7 +1274,7 @@ static struct tpm_input_header savestate_header = { * We are about to suspend. Save the TPM state * so that it can be restored. */ -int tpm_pm_suspend(struct device *dev) +int tpm_pm_suspend(struct device *dev, pm_message_t pm_state) { struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_cmd_t cmd; diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h index 917f727e6740..b1c5280ac159 100644 --- a/trunk/drivers/char/tpm/tpm.h +++ b/trunk/drivers/char/tpm/tpm.h @@ -299,7 +299,7 @@ extern ssize_t tpm_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); extern void tpm_remove_hardware(struct device *); -extern int tpm_pm_suspend(struct device *); +extern int tpm_pm_suspend(struct device *, pm_message_t); extern int tpm_pm_resume(struct device *); extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, wait_queue_head_t *); diff --git a/trunk/drivers/char/tpm/tpm_atmel.c b/trunk/drivers/char/tpm/tpm_atmel.c index 678d57019dc4..c64a1bc65349 100644 --- a/trunk/drivers/char/tpm/tpm_atmel.c +++ b/trunk/drivers/char/tpm/tpm_atmel.c @@ -168,14 +168,22 @@ static void atml_plat_remove(void) } } -static SIMPLE_DEV_PM_OPS(tpm_atml_pm, tpm_pm_suspend, tpm_pm_resume); +static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg) +{ + return tpm_pm_suspend(&dev->dev, msg); +} +static int tpm_atml_resume(struct platform_device *dev) +{ + return tpm_pm_resume(&dev->dev); +} static struct platform_driver atml_drv = { .driver = { .name = "tpm_atmel", .owner = THIS_MODULE, - .pm = &tpm_atml_pm, }, + .suspend = tpm_atml_suspend, + .resume = tpm_atml_resume, }; static int __init init_atmel(void) diff --git a/trunk/drivers/char/tpm/tpm_nsc.c b/trunk/drivers/char/tpm/tpm_nsc.c index 640c9a427b59..4d2464871ada 100644 --- a/trunk/drivers/char/tpm/tpm_nsc.c +++ b/trunk/drivers/char/tpm/tpm_nsc.c @@ -274,13 +274,22 @@ static void tpm_nsc_remove(struct device *dev) } } -static SIMPLE_DEV_PM_OPS(tpm_nsc_pm, tpm_pm_suspend, tpm_pm_resume); +static int tpm_nsc_suspend(struct platform_device *dev, pm_message_t msg) +{ + return tpm_pm_suspend(&dev->dev, msg); +} + +static int tpm_nsc_resume(struct platform_device *dev) +{ + return tpm_pm_resume(&dev->dev); +} static struct platform_driver nsc_drv = { + .suspend = tpm_nsc_suspend, + .resume = tpm_nsc_resume, .driver = { .name = "tpm_nsc", .owner = THIS_MODULE, - .pm = &tpm_nsc_pm, }, }; diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index 89682fa8801e..d2a70cae76df 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -750,7 +750,7 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) { - return tpm_pm_suspend(&dev->dev); + return tpm_pm_suspend(&dev->dev, msg); } static int tpm_tis_pnp_resume(struct pnp_dev *dev) @@ -806,25 +806,27 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); #endif +static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg) +{ + return tpm_pm_suspend(&dev->dev, msg); +} -static int tpm_tis_resume(struct device *dev) +static int tpm_tis_resume(struct platform_device *dev) { - struct tpm_chip *chip = dev_get_drvdata(dev); + struct tpm_chip *chip = dev_get_drvdata(&dev->dev); if (chip->vendor.irq) tpm_tis_reenable_interrupts(chip); - return tpm_pm_resume(dev); + return tpm_pm_resume(&dev->dev); } - -static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); - static struct platform_driver tis_drv = { .driver = { .name = "tpm_tis", .owner = THIS_MODULE, - .pm = &tpm_tis_pm, }, + .suspend = tpm_tis_suspend, + .resume = tpm_tis_resume, }; static struct platform_device *pdev; diff --git a/trunk/drivers/clk/clk.c b/trunk/drivers/clk/clk.c index 9a1eb0cfa95f..687b00d67c8a 100644 --- a/trunk/drivers/clk/clk.c +++ b/trunk/drivers/clk/clk.c @@ -850,21 +850,18 @@ static void clk_change_rate(struct clk *clk) { struct clk *child; unsigned long old_rate; - unsigned long best_parent_rate = 0; struct hlist_node *tmp; old_rate = clk->rate; - if (clk->parent) - best_parent_rate = clk->parent->rate; - if (clk->ops->set_rate) - clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); + clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); if (clk->ops->recalc_rate) - clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate); + clk->rate = clk->ops->recalc_rate(clk->hw, + clk->parent->rate); else - clk->rate = best_parent_rate; + clk->rate = clk->parent->rate; if (clk->notifier_count && old_rate != clk->rate) __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); @@ -1002,7 +999,7 @@ static struct clk *__clk_init_parent(struct clk *clk) if (!clk->parents) clk->parents = - kzalloc((sizeof(struct clk*) * clk->num_parents), + kmalloc((sizeof(struct clk*) * clk->num_parents), GFP_KERNEL); if (!clk->parents) @@ -1067,24 +1064,21 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) old_parent = clk->parent; - if (!clk->parents) - clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), - GFP_KERNEL); + /* find index of new parent clock using cached parent ptrs */ + for (i = 0; i < clk->num_parents; i++) + if (clk->parents[i] == parent) + break; /* - * find index of new parent clock using cached parent ptrs, - * or if not yet cached, use string name comparison and cache - * them now to avoid future calls to __clk_lookup. + * find index of new parent clock using string name comparison + * also try to cache the parent to avoid future calls to __clk_lookup */ - for (i = 0; i < clk->num_parents; i++) { - if (clk->parents && clk->parents[i] == parent) - break; - else if (!strcmp(clk->parent_names[i], parent->name)) { - if (clk->parents) + if (i == clk->num_parents) + for (i = 0; i < clk->num_parents; i++) + if (!strcmp(clk->parent_names[i], parent->name)) { clk->parents[i] = __clk_lookup(parent->name); - break; - } - } + break; + } if (i == clk->num_parents) { pr_debug("%s: clock %s is not a possible parent of clock %s\n", diff --git a/trunk/drivers/clk/mxs/clk-imx23.c b/trunk/drivers/clk/mxs/clk-imx23.c index db2391c054ee..f7be225f544c 100644 --- a/trunk/drivers/clk/mxs/clk-imx23.c +++ b/trunk/drivers/clk/mxs/clk-imx23.c @@ -71,7 +71,7 @@ static void __init clk_misc_init(void) __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC); } -static struct clk_lookup uart_lookups[] = { +static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -80,31 +80,31 @@ static struct clk_lookup uart_lookups[] = { { .dev_id = "80070000.serial", }, }; -static struct clk_lookup hbus_lookups[] = { +static struct clk_lookup hbus_lookups[] __initdata = { { .dev_id = "imx23-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] = { +static struct clk_lookup xbus_lookups[] __initdata = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80070000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx23-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp_lookups[] = { +static struct clk_lookup ssp_lookups[] __initdata = { { .dev_id = "imx23-mmc.0", }, { .dev_id = "imx23-mmc.1", }, { .dev_id = "80010000.ssp", }, { .dev_id = "80034000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] = { +static struct clk_lookup lcdif_lookups[] __initdata = { { .dev_id = "imx23-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] = { +static struct clk_lookup gpmi_lookups[] __initdata = { { .dev_id = "imx23-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; diff --git a/trunk/drivers/clk/mxs/clk-imx28.c b/trunk/drivers/clk/mxs/clk-imx28.c index 7fad6c8c13d2..2826a2606a29 100644 --- a/trunk/drivers/clk/mxs/clk-imx28.c +++ b/trunk/drivers/clk/mxs/clk-imx28.c @@ -120,7 +120,7 @@ static void __init clk_misc_init(void) writel_relaxed(val, FRAC0); } -static struct clk_lookup uart_lookups[] = { +static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -135,71 +135,71 @@ static struct clk_lookup uart_lookups[] = { { .dev_id = "80074000.serial", }, }; -static struct clk_lookup hbus_lookups[] = { +static struct clk_lookup hbus_lookups[] __initdata = { { .dev_id = "imx28-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] = { +static struct clk_lookup xbus_lookups[] __initdata = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80074000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx28-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp0_lookups[] = { +static struct clk_lookup ssp0_lookups[] __initdata = { { .dev_id = "imx28-mmc.0", }, { .dev_id = "80010000.ssp", }, }; -static struct clk_lookup ssp1_lookups[] = { +static struct clk_lookup ssp1_lookups[] __initdata = { { .dev_id = "imx28-mmc.1", }, { .dev_id = "80012000.ssp", }, }; -static struct clk_lookup ssp2_lookups[] = { +static struct clk_lookup ssp2_lookups[] __initdata = { { .dev_id = "imx28-mmc.2", }, { .dev_id = "80014000.ssp", }, }; -static struct clk_lookup ssp3_lookups[] = { +static struct clk_lookup ssp3_lookups[] __initdata = { { .dev_id = "imx28-mmc.3", }, { .dev_id = "80016000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] = { +static struct clk_lookup lcdif_lookups[] __initdata = { { .dev_id = "imx28-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] = { +static struct clk_lookup gpmi_lookups[] __initdata = { { .dev_id = "imx28-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; -static struct clk_lookup fec_lookups[] = { +static struct clk_lookup fec_lookups[] __initdata = { { .dev_id = "imx28-fec.0", }, { .dev_id = "imx28-fec.1", }, { .dev_id = "800f0000.ethernet", }, { .dev_id = "800f4000.ethernet", }, }; -static struct clk_lookup can0_lookups[] = { +static struct clk_lookup can0_lookups[] __initdata = { { .dev_id = "flexcan.0", }, { .dev_id = "80032000.can", }, }; -static struct clk_lookup can1_lookups[] = { +static struct clk_lookup can1_lookups[] __initdata = { { .dev_id = "flexcan.1", }, { .dev_id = "80034000.can", }, }; -static struct clk_lookup saif0_lookups[] = { +static struct clk_lookup saif0_lookups[] __initdata = { { .dev_id = "mxs-saif.0", }, { .dev_id = "80042000.saif", }, }; -static struct clk_lookup saif1_lookups[] = { +static struct clk_lookup saif1_lookups[] __initdata = { { .dev_id = "mxs-saif.1", }, { .dev_id = "80046000.saif", }, }; @@ -245,8 +245,8 @@ int __init mx28_clocks_init(void) clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000); clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0); clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1); - clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 2); - clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 3); + clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2); + clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3); clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0); clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1); clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2); diff --git a/trunk/drivers/clk/spear/clk-aux-synth.c b/trunk/drivers/clk/spear/clk-aux-synth.c index 6756e7c3bc07..af34074e702b 100644 --- a/trunk/drivers/clk/spear/clk-aux-synth.c +++ b/trunk/drivers/clk/spear/clk-aux-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/clk/spear/clk-frac-synth.c b/trunk/drivers/clk/spear/clk-frac-synth.c index 958aa3ad1d60..4dbdb3fe18e0 100644 --- a/trunk/drivers/clk/spear/clk-frac-synth.c +++ b/trunk/drivers/clk/spear/clk-frac-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/clk/spear/clk-gpt-synth.c b/trunk/drivers/clk/spear/clk-gpt-synth.c index 1afc18c4effc..b471c9762a97 100644 --- a/trunk/drivers/clk/spear/clk-gpt-synth.c +++ b/trunk/drivers/clk/spear/clk-gpt-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/clk/spear/clk-vco-pll.c b/trunk/drivers/clk/spear/clk-vco-pll.c index 5f1b6badeb15..dcd4bdf4b0d9 100644 --- a/trunk/drivers/clk/spear/clk-vco-pll.c +++ b/trunk/drivers/clk/spear/clk-vco-pll.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/clk/spear/clk.c b/trunk/drivers/clk/spear/clk.c index 7cd63788d546..376d4e5ff326 100644 --- a/trunk/drivers/clk/spear/clk.c +++ b/trunk/drivers/clk/spear/clk.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/clk/spear/clk.h b/trunk/drivers/clk/spear/clk.h index 931737677dfa..3321c46a071c 100644 --- a/trunk/drivers/clk/spear/clk.h +++ b/trunk/drivers/clk/spear/clk.h @@ -2,7 +2,7 @@ * Clock framework definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/clk/spear/spear1310_clock.c b/trunk/drivers/clk/spear/spear1310_clock.c index 0fcec2aae19c..42b68df9aeef 100644 --- a/trunk/drivers/clk/spear/spear1310_clock.c +++ b/trunk/drivers/clk/spear/spear1310_clock.c @@ -4,7 +4,7 @@ * SPEAr1310 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -345,30 +345,31 @@ static struct frac_rate_tbl gen_rtbl[] = { /* clock parents */ static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; -static const char *uart0_parents[] = { "pll5_clk", "uart_syn_gclk", }; -static const char *c3_parents[] = { "pll5_clk", "c3_syn_gclk", }; -static const char *gmac_phy_input_parents[] = { "gmii_pad_clk", "pll2_clk", +static const char *uart0_parents[] = { "pll5_clk", "uart_synth_gate_clk", }; +static const char *c3_parents[] = { "pll5_clk", "c3_synth_gate_clk", }; +static const char *gmac_phy_input_parents[] = { "gmii_125m_pad_clk", "pll2_clk", "osc_25m_clk", }; -static const char *gmac_phy_parents[] = { "phy_input_mclk", "phy_syn_gclk", }; +static const char *gmac_phy_parents[] = { "gmac_phy_input_mux_clk", + "gmac_phy_synth_gate_clk", }; static const char *clcd_synth_parents[] = { "vco1div4_clk", "pll2_clk", }; -static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_syn_clk", }; +static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_synth_clk", }; static const char *i2s_src_parents[] = { "vco1div2_clk", "none", "pll3_clk", "i2s_src_pad_clk", }; -static const char *i2s_ref_parents[] = { "i2s_src_mclk", "i2s_prs1_clk", }; +static const char *i2s_ref_parents[] = { "i2s_src_mux_clk", "i2s_prs1_clk", }; static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", "pll3_clk", }; static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco3div2_clk", "pll2_clk", }; static const char *rmii_phy_parents[] = { "ras_tx50_clk", "none", - "ras_pll2_clk", "ras_syn0_clk", }; + "ras_pll2_clk", "ras_synth0_clk", }; static const char *smii_rgmii_phy_parents[] = { "none", "ras_tx125_clk", - "ras_pll2_clk", "ras_syn0_clk", }; -static const char *uart_parents[] = { "ras_apb_clk", "gen_syn3_clk", }; -static const char *i2c_parents[] = { "ras_apb_clk", "gen_syn1_clk", }; -static const char *ssp1_parents[] = { "ras_apb_clk", "gen_syn1_clk", + "ras_pll2_clk", "ras_synth0_clk", }; +static const char *uart_parents[] = { "ras_apb_clk", "gen_synth3_clk", }; +static const char *i2c_parents[] = { "ras_apb_clk", "gen_synth1_clk", }; +static const char *ssp1_parents[] = { "ras_apb_clk", "gen_synth1_clk", "ras_plclk0_clk", }; -static const char *pci_parents[] = { "ras_pll3_clk", "gen_syn2_clk", }; -static const char *tdm_parents[] = { "ras_pll3_clk", "gen_syn1_clk", }; +static const char *pci_parents[] = { "ras_pll3_clk", "gen_synth2_clk", }; +static const char *tdm_parents[] = { "ras_pll3_clk", "gen_synth1_clk", }; void __init spear1310_clk_init(void) { @@ -389,9 +390,9 @@ void __init spear1310_clk_init(void) 25000000); clk_register_clkdev(clk, "osc_25m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, - 125000000); - clk_register_clkdev(clk, "gmii_pad_clk", NULL); + clk = clk_register_fixed_rate(NULL, "gmii_125m_pad_clk", NULL, + CLK_IS_ROOT, 125000000); + clk_register_clkdev(clk, "gmii_125m_pad_clk", NULL); clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, CLK_IS_ROOT, 12288000); @@ -405,34 +406,34 @@ void __init spear1310_clk_init(void) /* clock derived from 24 or 25 MHz osc clk */ /* vco-pll */ - clk = clk_register_mux(NULL, "vco1_mclk", vco_parents, + clk = clk_register_mux(NULL, "vco1_mux_clk", vco_parents, ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, SPEAR1310_PLL1_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "vco1_mclk", NULL); - clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mclk", + clk_register_clkdev(clk, "vco1_mux_clk", NULL); + clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mux_clk", 0, SPEAR1310_PLL1_CTR, SPEAR1310_PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco1_clk", NULL); clk_register_clkdev(clk1, "pll1_clk", NULL); - clk = clk_register_mux(NULL, "vco2_mclk", vco_parents, + clk = clk_register_mux(NULL, "vco2_mux_clk", vco_parents, ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, SPEAR1310_PLL2_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "vco2_mclk", NULL); - clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mclk", + clk_register_clkdev(clk, "vco2_mux_clk", NULL); + clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mux_clk", 0, SPEAR1310_PLL2_CTR, SPEAR1310_PLL2_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco2_clk", NULL); clk_register_clkdev(clk1, "pll2_clk", NULL); - clk = clk_register_mux(NULL, "vco3_mclk", vco_parents, + clk = clk_register_mux(NULL, "vco3_mux_clk", vco_parents, ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, SPEAR1310_PLL3_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "vco3_mclk", NULL); - clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mclk", + clk_register_clkdev(clk, "vco3_mux_clk", NULL); + clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mux_clk", 0, SPEAR1310_PLL3_CTR, SPEAR1310_PLL3_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco3_clk", NULL); @@ -472,7 +473,7 @@ void __init spear1310_clk_init(void) /* peripherals */ clk_register_fixed_factor(NULL, "thermal_clk", "osc_24m_clk", 0, 1, 128); - clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0, + clk = clk_register_gate(NULL, "thermal_gate_clk", "thermal_clk", 0, SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_THSENS_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_thermal"); @@ -499,176 +500,177 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "apb_clk", NULL); /* gpt clocks */ - clk = clk_register_mux(NULL, "gpt0_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT0_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt0_mclk", NULL); - clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mclk", 0, + clk_register_clkdev(clk, "gpt0_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mux_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt0"); - clk = clk_register_mux(NULL, "gpt1_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT1_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt1_mclk", NULL); - clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, + clk_register_clkdev(clk, "gpt1_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt1"); - clk = clk_register_mux(NULL, "gpt2_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT2_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt2_mclk", NULL); - clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, + clk_register_clkdev(clk, "gpt2_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt2"); - clk = clk_register_mux(NULL, "gpt3_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT3_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt3_mclk", NULL); - clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0, + clk_register_clkdev(clk, "gpt3_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0, SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt3"); /* others */ - clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "vco1div2_clk", - 0, SPEAR1310_UART_CLK_SYNT, NULL, aux_rtbl, - ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "uart_syn_clk", NULL); - clk_register_clkdev(clk1, "uart_syn_gclk", NULL); + clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk", + "vco1div2_clk", 0, SPEAR1310_UART_CLK_SYNT, NULL, + aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "uart_synth_clk", NULL); + clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, + clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents, ARRAY_SIZE(uart0_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_UART_CLK_SHIFT, SPEAR1310_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart0_mclk", NULL); + clk_register_clkdev(clk, "uart0_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, + clk = clk_register_gate(NULL, "uart0_clk", "uart0_mux_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UART_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0000000.serial"); - clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk", + clk = clk_register_aux("sdhci_synth_clk", "sdhci_synth_gate_clk", "vco1div2_clk", 0, SPEAR1310_SDHCI_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "sdhci_syn_clk", NULL); - clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); + clk_register_clkdev(clk, "sdhci_synth_clk", NULL); + clk_register_clkdev(clk1, "sdhci_synth_gate_clk", NULL); - clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, + clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_synth_gate_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SDHCI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b3000000.sdhci"); - clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", - 0, SPEAR1310_CFXD_CLK_SYNT, NULL, aux_rtbl, - ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "cfxd_syn_clk", NULL); - clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); + clk = clk_register_aux("cfxd_synth_clk", "cfxd_synth_gate_clk", + "vco1div2_clk", 0, SPEAR1310_CFXD_CLK_SYNT, NULL, + aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "cfxd_synth_clk", NULL); + clk_register_clkdev(clk1, "cfxd_synth_gate_clk", NULL); - clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, + clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_synth_gate_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CFXD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b2800000.cf"); clk_register_clkdev(clk, NULL, "arasan_xd"); - clk = clk_register_aux("c3_syn_clk", "c3_syn_gclk", "vco1div2_clk", - 0, SPEAR1310_C3_CLK_SYNT, NULL, aux_rtbl, - ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "c3_syn_clk", NULL); - clk_register_clkdev(clk1, "c3_syn_gclk", NULL); + clk = clk_register_aux("c3_synth_clk", "c3_synth_gate_clk", + "vco1div2_clk", 0, SPEAR1310_C3_CLK_SYNT, NULL, + aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "c3_synth_clk", NULL); + clk_register_clkdev(clk1, "c3_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "c3_mclk", c3_parents, + clk = clk_register_mux(NULL, "c3_mux_clk", c3_parents, ARRAY_SIZE(c3_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_C3_CLK_SHIFT, SPEAR1310_C3_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "c3_mclk", NULL); + clk_register_clkdev(clk, "c3_mux_clk", NULL); - clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, + clk = clk_register_gate(NULL, "c3_clk", "c3_mux_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_C3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "c3"); /* gmac */ - clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents, + clk = clk_register_mux(NULL, "gmac_phy_input_mux_clk", + gmac_phy_input_parents, ARRAY_SIZE(gmac_phy_input_parents), 0, SPEAR1310_GMAC_CLK_CFG, SPEAR1310_GMAC_PHY_INPUT_CLK_SHIFT, SPEAR1310_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "phy_input_mclk", NULL); + clk_register_clkdev(clk, "gmac_phy_input_mux_clk", NULL); - clk = clk_register_aux("phy_syn_clk", "phy_syn_gclk", "phy_input_mclk", - 0, SPEAR1310_GMAC_CLK_SYNT, NULL, gmac_rtbl, - ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "phy_syn_clk", NULL); - clk_register_clkdev(clk1, "phy_syn_gclk", NULL); + clk = clk_register_aux("gmac_phy_synth_clk", "gmac_phy_synth_gate_clk", + "gmac_phy_input_mux_clk", 0, SPEAR1310_GMAC_CLK_SYNT, + NULL, gmac_rtbl, ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "gmac_phy_synth_clk", NULL); + clk_register_clkdev(clk1, "gmac_phy_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "phy_mclk", gmac_phy_parents, + clk = clk_register_mux(NULL, "gmac_phy_mux_clk", gmac_phy_parents, ARRAY_SIZE(gmac_phy_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT, SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "stmmacphy.0"); /* clcd */ - clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, + clk = clk_register_mux(NULL, "clcd_synth_mux_clk", clcd_synth_parents, ARRAY_SIZE(clcd_synth_parents), 0, SPEAR1310_CLCD_CLK_SYNT, SPEAR1310_CLCD_SYNT_CLK_SHIFT, SPEAR1310_CLCD_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_syn_mclk", NULL); + clk_register_clkdev(clk, "clcd_synth_mux_clk", NULL); - clk = clk_register_frac("clcd_syn_clk", "clcd_syn_mclk", 0, + clk = clk_register_frac("clcd_synth_clk", "clcd_synth_mux_clk", 0, SPEAR1310_CLCD_CLK_SYNT, clcd_rtbl, ARRAY_SIZE(clcd_rtbl), &_lock); - clk_register_clkdev(clk, "clcd_syn_clk", NULL); + clk_register_clkdev(clk, "clcd_synth_clk", NULL); - clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, + clk = clk_register_mux(NULL, "clcd_pixel_mux_clk", clcd_pixel_parents, ARRAY_SIZE(clcd_pixel_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT, SPEAR1310_CLCD_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "clcd_pixel_clk", NULL); - clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, + clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mux_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "clcd_clk", NULL); /* i2s */ - clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, + clk = clk_register_mux(NULL, "i2s_src_mux_clk", i2s_src_parents, ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_src_clk", NULL); - clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, + clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mux_clk", 0, SPEAR1310_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); clk_register_clkdev(clk, "i2s_prs1_clk", NULL); - clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, + clk = clk_register_mux(NULL, "i2s_ref_mux_clk", i2s_ref_parents, ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_REF_SHIFT, SPEAR1310_I2S_REF_SEL_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_clk", NULL); - clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, + clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mux_clk", 0, SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_I2S_REF_PAD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); - clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk", + clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gate_clk", "i2s_ref_pad_clk", 0, SPEAR1310_I2S_CLK_CFG, &i2s_sclk_masks, i2s_sclk_rtbl, ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); clk_register_clkdev(clk, "i2s_sclk_clk", NULL); - clk_register_clkdev(clk1, "i2s_sclk_gclk", NULL); + clk_register_clkdev(clk1, "i2s_sclk_gate_clk", NULL); /* clock derived from ahb clk */ clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, @@ -745,13 +747,13 @@ void __init spear1310_clk_init(void) &_lock); clk_register_clkdev(clk, "sysram1_clk", NULL); - clk = clk_register_aux("adc_syn_clk", "adc_syn_gclk", "ahb_clk", + clk = clk_register_aux("adc_synth_clk", "adc_synth_gate_clk", "ahb_clk", 0, SPEAR1310_ADC_CLK_SYNT, NULL, adc_rtbl, ARRAY_SIZE(adc_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "adc_syn_clk", NULL); - clk_register_clkdev(clk1, "adc_syn_gclk", NULL); + clk_register_clkdev(clk, "adc_synth_clk", NULL); + clk_register_clkdev(clk1, "adc_synth_gate_clk", NULL); - clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, + clk = clk_register_gate(NULL, "adc_clk", "adc_synth_gate_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "adc_clk"); @@ -788,37 +790,37 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, NULL, "e0300000.kbd"); /* RAS clks */ - clk = clk_register_mux(NULL, "gen_syn0_1_mclk", gen_synth0_1_parents, - ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1310_PLL_CFG, - SPEAR1310_RAS_SYNT0_1_CLK_SHIFT, + clk = clk_register_mux(NULL, "gen_synth0_1_mux_clk", + gen_synth0_1_parents, ARRAY_SIZE(gen_synth0_1_parents), + 0, SPEAR1310_PLL_CFG, SPEAR1310_RAS_SYNT0_1_CLK_SHIFT, SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn0_1_clk", NULL); + clk_register_clkdev(clk, "gen_synth0_1_clk", NULL); - clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents, - ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1310_PLL_CFG, - SPEAR1310_RAS_SYNT2_3_CLK_SHIFT, + clk = clk_register_mux(NULL, "gen_synth2_3_mux_clk", + gen_synth2_3_parents, ARRAY_SIZE(gen_synth2_3_parents), + 0, SPEAR1310_PLL_CFG, SPEAR1310_RAS_SYNT2_3_CLK_SHIFT, SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn2_3_clk", NULL); + clk_register_clkdev(clk, "gen_synth2_3_clk", NULL); - clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0, + clk = clk_register_frac("gen_synth0_clk", "gen_synth0_1_clk", 0, SPEAR1310_RAS_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn0_clk", NULL); + clk_register_clkdev(clk, "gen_synth0_clk", NULL); - clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0, + clk = clk_register_frac("gen_synth1_clk", "gen_synth0_1_clk", 0, SPEAR1310_RAS_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn1_clk", NULL); + clk_register_clkdev(clk, "gen_synth1_clk", NULL); - clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0, + clk = clk_register_frac("gen_synth2_clk", "gen_synth2_3_clk", 0, SPEAR1310_RAS_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn2_clk", NULL); + clk_register_clkdev(clk, "gen_synth2_clk", NULL); - clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0, + clk = clk_register_frac("gen_synth3_clk", "gen_synth2_3_clk", 0, SPEAR1310_RAS_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn3_clk", NULL); + clk_register_clkdev(clk, "gen_synth3_clk", NULL); clk = clk_register_gate(NULL, "ras_osc_24m_clk", "osc_24m_clk", 0, SPEAR1310_RAS_CLK_ENB, SPEAR1310_OSC_24M_CLK_ENB, 0, @@ -845,7 +847,7 @@ void __init spear1310_clk_init(void) &_lock); clk_register_clkdev(clk, "ras_pll3_clk", NULL); - clk = clk_register_gate(NULL, "ras_tx125_clk", "gmii_pad_clk", 0, + clk = clk_register_gate(NULL, "ras_tx125_clk", "gmii_125m_pad_clk", 0, SPEAR1310_RAS_CLK_ENB, SPEAR1310_C125M_PAD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_tx125_clk", NULL); @@ -910,7 +912,7 @@ void __init spear1310_clk_init(void) &_lock); clk_register_clkdev(clk, NULL, "5c700000.eth"); - clk = clk_register_mux(NULL, "smii_rgmii_phy_mclk", + clk = clk_register_mux(NULL, "smii_rgmii_phy_mux_clk", smii_rgmii_phy_parents, ARRAY_SIZE(smii_rgmii_phy_parents), 0, SPEAR1310_RAS_CTRL_REG1, @@ -920,184 +922,184 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, NULL, "stmmacphy.2"); clk_register_clkdev(clk, NULL, "stmmacphy.4"); - clk = clk_register_mux(NULL, "rmii_phy_mclk", rmii_phy_parents, + clk = clk_register_mux(NULL, "rmii_phy_mux_clk", rmii_phy_parents, ARRAY_SIZE(rmii_phy_parents), 0, SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT, SPEAR1310_PHY_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "stmmacphy.3"); - clk = clk_register_mux(NULL, "uart1_mclk", uart_parents, + clk = clk_register_mux(NULL, "uart1_mux_clk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART1_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart1_mclk", NULL); + clk_register_clkdev(clk, "uart1_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart1_clk", "uart1_mclk", 0, + clk = clk_register_gate(NULL, "uart1_clk", "uart1_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5c800000.serial"); - clk = clk_register_mux(NULL, "uart2_mclk", uart_parents, + clk = clk_register_mux(NULL, "uart2_mux_clk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART2_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart2_mclk", NULL); + clk_register_clkdev(clk, "uart2_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart2_clk", "uart2_mclk", 0, + clk = clk_register_gate(NULL, "uart2_clk", "uart2_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5c900000.serial"); - clk = clk_register_mux(NULL, "uart3_mclk", uart_parents, + clk = clk_register_mux(NULL, "uart3_mux_clk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART3_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart3_mclk", NULL); + clk_register_clkdev(clk, "uart3_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart3_clk", "uart3_mclk", 0, + clk = clk_register_gate(NULL, "uart3_clk", "uart3_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5ca00000.serial"); - clk = clk_register_mux(NULL, "uart4_mclk", uart_parents, + clk = clk_register_mux(NULL, "uart4_mux_clk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART4_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart4_mclk", NULL); + clk_register_clkdev(clk, "uart4_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart4_clk", "uart4_mclk", 0, + clk = clk_register_gate(NULL, "uart4_clk", "uart4_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART4_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5cb00000.serial"); - clk = clk_register_mux(NULL, "uart5_mclk", uart_parents, + clk = clk_register_mux(NULL, "uart5_mux_clk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART5_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart5_mclk", NULL); + clk_register_clkdev(clk, "uart5_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart5_clk", "uart5_mclk", 0, + clk = clk_register_gate(NULL, "uart5_clk", "uart5_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART5_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5cc00000.serial"); - clk = clk_register_mux(NULL, "i2c1_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c1_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C1_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c1_mclk", NULL); + clk_register_clkdev(clk, "i2c1_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c1_clk", "i2c1_mclk", 0, + clk = clk_register_gate(NULL, "i2c1_clk", "i2c1_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5cd00000.i2c"); - clk = clk_register_mux(NULL, "i2c2_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c2_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C2_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c2_mclk", NULL); + clk_register_clkdev(clk, "i2c2_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c2_clk", "i2c2_mclk", 0, + clk = clk_register_gate(NULL, "i2c2_clk", "i2c2_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5ce00000.i2c"); - clk = clk_register_mux(NULL, "i2c3_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c3_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C3_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c3_mclk", NULL); + clk_register_clkdev(clk, "i2c3_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c3_clk", "i2c3_mclk", 0, + clk = clk_register_gate(NULL, "i2c3_clk", "i2c3_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5cf00000.i2c"); - clk = clk_register_mux(NULL, "i2c4_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c4_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C4_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c4_mclk", NULL); + clk_register_clkdev(clk, "i2c4_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c4_clk", "i2c4_mclk", 0, + clk = clk_register_gate(NULL, "i2c4_clk", "i2c4_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C4_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5d000000.i2c"); - clk = clk_register_mux(NULL, "i2c5_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c5_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C5_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c5_mclk", NULL); + clk_register_clkdev(clk, "i2c5_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c5_clk", "i2c5_mclk", 0, + clk = clk_register_gate(NULL, "i2c5_clk", "i2c5_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C5_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5d100000.i2c"); - clk = clk_register_mux(NULL, "i2c6_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c6_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C6_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c6_mclk", NULL); + clk_register_clkdev(clk, "i2c6_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c6_clk", "i2c6_mclk", 0, + clk = clk_register_gate(NULL, "i2c6_clk", "i2c6_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C6_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5d200000.i2c"); - clk = clk_register_mux(NULL, "i2c7_mclk", i2c_parents, + clk = clk_register_mux(NULL, "i2c7_mux_clk", i2c_parents, ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C7_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2c7_mclk", NULL); + clk_register_clkdev(clk, "i2c7_mux_clk", NULL); - clk = clk_register_gate(NULL, "i2c7_clk", "i2c7_mclk", 0, + clk = clk_register_gate(NULL, "i2c7_clk", "i2c7_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C7_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5d300000.i2c"); - clk = clk_register_mux(NULL, "ssp1_mclk", ssp1_parents, + clk = clk_register_mux(NULL, "ssp1_mux_clk", ssp1_parents, ARRAY_SIZE(ssp1_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_SSP1_CLK_SHIFT, SPEAR1310_SSP1_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "ssp1_mclk", NULL); + clk_register_clkdev(clk, "ssp1_mux_clk", NULL); - clk = clk_register_gate(NULL, "ssp1_clk", "ssp1_mclk", 0, + clk = clk_register_gate(NULL, "ssp1_clk", "ssp1_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_SSP1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "5d400000.spi"); - clk = clk_register_mux(NULL, "pci_mclk", pci_parents, + clk = clk_register_mux(NULL, "pci_mux_clk", pci_parents, ARRAY_SIZE(pci_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_PCI_CLK_SHIFT, SPEAR1310_PCI_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "pci_mclk", NULL); + clk_register_clkdev(clk, "pci_mux_clk", NULL); - clk = clk_register_gate(NULL, "pci_clk", "pci_mclk", 0, + clk = clk_register_gate(NULL, "pci_clk", "pci_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_PCI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "pci"); - clk = clk_register_mux(NULL, "tdm1_mclk", tdm_parents, + clk = clk_register_mux(NULL, "tdm1_mux_clk", tdm_parents, ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_TDM1_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "tdm1_mclk", NULL); + clk_register_clkdev(clk, "tdm1_mux_clk", NULL); - clk = clk_register_gate(NULL, "tdm1_clk", "tdm1_mclk", 0, + clk = clk_register_gate(NULL, "tdm1_clk", "tdm1_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_TDM1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "tdm_hdlc.0"); - clk = clk_register_mux(NULL, "tdm2_mclk", tdm_parents, + clk = clk_register_mux(NULL, "tdm2_mux_clk", tdm_parents, ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0, SPEAR1310_TDM2_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "tdm2_mclk", NULL); + clk_register_clkdev(clk, "tdm2_mux_clk", NULL); - clk = clk_register_gate(NULL, "tdm2_clk", "tdm2_mclk", 0, + clk = clk_register_gate(NULL, "tdm2_clk", "tdm2_mux_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_TDM2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "tdm_hdlc.1"); diff --git a/trunk/drivers/clk/spear/spear1340_clock.c b/trunk/drivers/clk/spear/spear1340_clock.c index 2352cee7f645..f130919d5bf8 100644 --- a/trunk/drivers/clk/spear/spear1340_clock.c +++ b/trunk/drivers/clk/spear/spear1340_clock.c @@ -4,7 +4,7 @@ * SPEAr1340 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -369,25 +369,27 @@ static struct frac_rate_tbl gen_rtbl[] = { /* clock parents */ static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; -static const char *sys_parents[] = { "pll1_clk", "pll1_clk", "pll1_clk", - "pll1_clk", "sys_synth_clk", "sys_synth_clk", "pll2_clk", "pll3_clk", }; -static const char *ahb_parents[] = { "cpu_div3_clk", "amba_syn_clk", }; +static const char *sys_parents[] = { "none", "pll1_clk", "none", "none", + "sys_synth_clk", "none", "pll2_clk", "pll3_clk", }; +static const char *ahb_parents[] = { "cpu_div3_clk", "amba_synth_clk", }; static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; static const char *uart0_parents[] = { "pll5_clk", "osc_24m_clk", - "uart0_syn_gclk", }; + "uart0_synth_gate_clk", }; static const char *uart1_parents[] = { "pll5_clk", "osc_24m_clk", - "uart1_syn_gclk", }; -static const char *c3_parents[] = { "pll5_clk", "c3_syn_gclk", }; -static const char *gmac_phy_input_parents[] = { "gmii_pad_clk", "pll2_clk", + "uart1_synth_gate_clk", }; +static const char *c3_parents[] = { "pll5_clk", "c3_synth_gate_clk", }; +static const char *gmac_phy_input_parents[] = { "gmii_125m_pad_clk", "pll2_clk", "osc_25m_clk", }; -static const char *gmac_phy_parents[] = { "phy_input_mclk", "phy_syn_gclk", }; +static const char *gmac_phy_parents[] = { "gmac_phy_input_mux_clk", + "gmac_phy_synth_gate_clk", }; static const char *clcd_synth_parents[] = { "vco1div4_clk", "pll2_clk", }; -static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_syn_clk", }; +static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_synth_clk", }; static const char *i2s_src_parents[] = { "vco1div2_clk", "pll2_clk", "pll3_clk", "i2s_src_pad_clk", }; -static const char *i2s_ref_parents[] = { "i2s_src_mclk", "i2s_prs1_clk", }; -static const char *spdif_out_parents[] = { "i2s_src_pad_clk", "gen_syn2_clk", }; -static const char *spdif_in_parents[] = { "pll2_clk", "gen_syn3_clk", }; +static const char *i2s_ref_parents[] = { "i2s_src_mux_clk", "i2s_prs1_clk", }; +static const char *spdif_out_parents[] = { "i2s_src_pad_clk", "gen_synth2_clk", +}; +static const char *spdif_in_parents[] = { "pll2_clk", "gen_synth3_clk", }; static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", "pll3_clk", }; @@ -413,9 +415,9 @@ void __init spear1340_clk_init(void) 25000000); clk_register_clkdev(clk, "osc_25m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, - 125000000); - clk_register_clkdev(clk, "gmii_pad_clk", NULL); + clk = clk_register_fixed_rate(NULL, "gmii_125m_pad_clk", NULL, + CLK_IS_ROOT, 125000000); + clk_register_clkdev(clk, "gmii_125m_pad_clk", NULL); clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, CLK_IS_ROOT, 12288000); @@ -429,35 +431,35 @@ void __init spear1340_clk_init(void) /* clock derived from 24 or 25 MHz osc clk */ /* vco-pll */ - clk = clk_register_mux(NULL, "vco1_mclk", vco_parents, + clk = clk_register_mux(NULL, "vco1_mux_clk", vco_parents, ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_PLL1_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "vco1_mclk", NULL); - clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mclk", 0, - SPEAR1340_PLL1_CTR, SPEAR1340_PLL1_FRQ, pll_rtbl, + clk_register_clkdev(clk, "vco1_mux_clk", NULL); + clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mux_clk", + 0, SPEAR1340_PLL1_CTR, SPEAR1340_PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco1_clk", NULL); clk_register_clkdev(clk1, "pll1_clk", NULL); - clk = clk_register_mux(NULL, "vco2_mclk", vco_parents, + clk = clk_register_mux(NULL, "vco2_mux_clk", vco_parents, ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_PLL2_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "vco2_mclk", NULL); - clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mclk", 0, - SPEAR1340_PLL2_CTR, SPEAR1340_PLL2_FRQ, pll_rtbl, + clk_register_clkdev(clk, "vco2_mux_clk", NULL); + clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mux_clk", + 0, SPEAR1340_PLL2_CTR, SPEAR1340_PLL2_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco2_clk", NULL); clk_register_clkdev(clk1, "pll2_clk", NULL); - clk = clk_register_mux(NULL, "vco3_mclk", vco_parents, + clk = clk_register_mux(NULL, "vco3_mux_clk", vco_parents, ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_PLL3_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "vco3_mclk", NULL); - clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mclk", 0, - SPEAR1340_PLL3_CTR, SPEAR1340_PLL3_FRQ, pll_rtbl, + clk_register_clkdev(clk, "vco3_mux_clk", NULL); + clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mux_clk", + 0, SPEAR1340_PLL3_CTR, SPEAR1340_PLL3_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco3_clk", NULL); clk_register_clkdev(clk1, "pll3_clk", NULL); @@ -496,7 +498,7 @@ void __init spear1340_clk_init(void) /* peripherals */ clk_register_fixed_factor(NULL, "thermal_clk", "osc_24m_clk", 0, 1, 128); - clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0, + clk = clk_register_gate(NULL, "thermal_gate_clk", "thermal_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_THSENS_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_thermal"); @@ -507,23 +509,23 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "ddr_clk", NULL); /* clock derived from pll1 clk */ - clk = clk_register_frac("sys_syn_clk", "vco1div2_clk", 0, + clk = clk_register_frac("sys_synth_clk", "vco1div2_clk", 0, SPEAR1340_SYS_CLK_SYNT, sys_synth_rtbl, ARRAY_SIZE(sys_synth_rtbl), &_lock); - clk_register_clkdev(clk, "sys_syn_clk", NULL); + clk_register_clkdev(clk, "sys_synth_clk", NULL); - clk = clk_register_frac("amba_syn_clk", "vco1div2_clk", 0, + clk = clk_register_frac("amba_synth_clk", "vco1div2_clk", 0, SPEAR1340_AMBA_CLK_SYNT, amba_synth_rtbl, ARRAY_SIZE(amba_synth_rtbl), &_lock); - clk_register_clkdev(clk, "amba_syn_clk", NULL); + clk_register_clkdev(clk, "amba_synth_clk", NULL); - clk = clk_register_mux(NULL, "sys_mclk", sys_parents, + clk = clk_register_mux(NULL, "sys_mux_clk", sys_parents, ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL, SPEAR1340_SCLK_SRC_SEL_SHIFT, SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock); clk_register_clkdev(clk, "sys_clk", NULL); - clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mclk", 0, 1, + clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mux_clk", 0, 1, 2); clk_register_clkdev(clk, "cpu_clk", NULL); @@ -546,193 +548,194 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "apb_clk", NULL); /* gpt clocks */ - clk = clk_register_mux(NULL, "gpt0_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT0_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt0_mclk", NULL); - clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mclk", 0, + clk_register_clkdev(clk, "gpt0_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mux_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt0"); - clk = clk_register_mux(NULL, "gpt1_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT1_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt1_mclk", NULL); - clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, + clk_register_clkdev(clk, "gpt1_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt1"); - clk = clk_register_mux(NULL, "gpt2_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT2_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt2_mclk", NULL); - clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, + clk_register_clkdev(clk, "gpt2_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt2"); - clk = clk_register_mux(NULL, "gpt3_mclk", gpt_parents, + clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt_parents, ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT3_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt3_mclk", NULL); - clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0, + clk_register_clkdev(clk, "gpt3_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt3"); /* others */ - clk = clk_register_aux("uart0_syn_clk", "uart0_syn_gclk", + clk = clk_register_aux("uart0_synth_clk", "uart0_synth_gate_clk", "vco1div2_clk", 0, SPEAR1340_UART0_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "uart0_syn_clk", NULL); - clk_register_clkdev(clk1, "uart0_syn_gclk", NULL); + clk_register_clkdev(clk, "uart0_synth_clk", NULL); + clk_register_clkdev(clk1, "uart0_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, + clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents, ARRAY_SIZE(uart0_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART0_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart0_mclk", NULL); + clk_register_clkdev(clk, "uart0_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, + clk = clk_register_gate(NULL, "uart0_clk", "uart0_mux_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0000000.serial"); - clk = clk_register_aux("uart1_syn_clk", "uart1_syn_gclk", + clk = clk_register_aux("uart1_synth_clk", "uart1_synth_gate_clk", "vco1div2_clk", 0, SPEAR1340_UART1_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "uart1_syn_clk", NULL); - clk_register_clkdev(clk1, "uart1_syn_gclk", NULL); + clk_register_clkdev(clk, "uart1_synth_clk", NULL); + clk_register_clkdev(clk1, "uart1_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "uart1_mclk", uart1_parents, + clk = clk_register_mux(NULL, "uart1_mux_clk", uart1_parents, ARRAY_SIZE(uart1_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART1_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart1_mclk", NULL); + clk_register_clkdev(clk, "uart1_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart1_clk", "uart1_mclk", 0, - SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_UART1_CLK_ENB, 0, + clk = clk_register_gate(NULL, "uart1_clk", "uart1_mux_clk", 0, + SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b4100000.serial"); - clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk", + clk = clk_register_aux("sdhci_synth_clk", "sdhci_synth_gate_clk", "vco1div2_clk", 0, SPEAR1340_SDHCI_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "sdhci_syn_clk", NULL); - clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); + clk_register_clkdev(clk, "sdhci_synth_clk", NULL); + clk_register_clkdev(clk1, "sdhci_synth_gate_clk", NULL); - clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, + clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_synth_gate_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SDHCI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b3000000.sdhci"); - clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", - 0, SPEAR1340_CFXD_CLK_SYNT, NULL, aux_rtbl, - ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "cfxd_syn_clk", NULL); - clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); + clk = clk_register_aux("cfxd_synth_clk", "cfxd_synth_gate_clk", + "vco1div2_clk", 0, SPEAR1340_CFXD_CLK_SYNT, NULL, + aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "cfxd_synth_clk", NULL); + clk_register_clkdev(clk1, "cfxd_synth_gate_clk", NULL); - clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, + clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_synth_gate_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CFXD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b2800000.cf"); clk_register_clkdev(clk, NULL, "arasan_xd"); - clk = clk_register_aux("c3_syn_clk", "c3_syn_gclk", "vco1div2_clk", 0, - SPEAR1340_C3_CLK_SYNT, NULL, aux_rtbl, - ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "c3_syn_clk", NULL); - clk_register_clkdev(clk1, "c3_syn_gclk", NULL); + clk = clk_register_aux("c3_synth_clk", "c3_synth_gate_clk", + "vco1div2_clk", 0, SPEAR1340_C3_CLK_SYNT, NULL, + aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "c3_synth_clk", NULL); + clk_register_clkdev(clk1, "c3_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "c3_mclk", c3_parents, + clk = clk_register_mux(NULL, "c3_mux_clk", c3_parents, ARRAY_SIZE(c3_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_C3_CLK_SHIFT, SPEAR1340_C3_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "c3_mclk", NULL); + clk_register_clkdev(clk, "c3_mux_clk", NULL); - clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, + clk = clk_register_gate(NULL, "c3_clk", "c3_mux_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "c3"); /* gmac */ - clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents, + clk = clk_register_mux(NULL, "gmac_phy_input_mux_clk", + gmac_phy_input_parents, ARRAY_SIZE(gmac_phy_input_parents), 0, SPEAR1340_GMAC_CLK_CFG, SPEAR1340_GMAC_PHY_INPUT_CLK_SHIFT, SPEAR1340_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "phy_input_mclk", NULL); + clk_register_clkdev(clk, "gmac_phy_input_mux_clk", NULL); - clk = clk_register_aux("phy_syn_clk", "phy_syn_gclk", "phy_input_mclk", - 0, SPEAR1340_GMAC_CLK_SYNT, NULL, gmac_rtbl, - ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "phy_syn_clk", NULL); - clk_register_clkdev(clk1, "phy_syn_gclk", NULL); + clk = clk_register_aux("gmac_phy_synth_clk", "gmac_phy_synth_gate_clk", + "gmac_phy_input_mux_clk", 0, SPEAR1340_GMAC_CLK_SYNT, + NULL, gmac_rtbl, ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "gmac_phy_synth_clk", NULL); + clk_register_clkdev(clk1, "gmac_phy_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "phy_mclk", gmac_phy_parents, + clk = clk_register_mux(NULL, "gmac_phy_mux_clk", gmac_phy_parents, ARRAY_SIZE(gmac_phy_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT, SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "stmmacphy.0"); /* clcd */ - clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, + clk = clk_register_mux(NULL, "clcd_synth_mux_clk", clcd_synth_parents, ARRAY_SIZE(clcd_synth_parents), 0, SPEAR1340_CLCD_CLK_SYNT, SPEAR1340_CLCD_SYNT_CLK_SHIFT, SPEAR1340_CLCD_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_syn_mclk", NULL); + clk_register_clkdev(clk, "clcd_synth_mux_clk", NULL); - clk = clk_register_frac("clcd_syn_clk", "clcd_syn_mclk", 0, + clk = clk_register_frac("clcd_synth_clk", "clcd_synth_mux_clk", 0, SPEAR1340_CLCD_CLK_SYNT, clcd_rtbl, ARRAY_SIZE(clcd_rtbl), &_lock); - clk_register_clkdev(clk, "clcd_syn_clk", NULL); + clk_register_clkdev(clk, "clcd_synth_clk", NULL); - clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, + clk = clk_register_mux(NULL, "clcd_pixel_mux_clk", clcd_pixel_parents, ARRAY_SIZE(clcd_pixel_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT, SPEAR1340_CLCD_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "clcd_pixel_clk", NULL); - clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, + clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mux_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "clcd_clk", NULL); /* i2s */ - clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, + clk = clk_register_mux(NULL, "i2s_src_mux_clk", i2s_src_parents, ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_src_clk", NULL); - clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, + clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mux_clk", 0, SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); clk_register_clkdev(clk, "i2s_prs1_clk", NULL); - clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, + clk = clk_register_mux(NULL, "i2s_ref_mux_clk", i2s_ref_parents, ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_clk", NULL); - clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, + clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mux_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_I2S_REF_PAD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); - clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk", "i2s_ref_mclk", - 0, SPEAR1340_I2S_CLK_CFG, &i2s_sclk_masks, - i2s_sclk_rtbl, ARRAY_SIZE(i2s_sclk_rtbl), &_lock, - &clk1); + clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gate_clk", + "i2s_ref_mux_clk", 0, SPEAR1340_I2S_CLK_CFG, + &i2s_sclk_masks, i2s_sclk_rtbl, + ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); clk_register_clkdev(clk, "i2s_sclk_clk", NULL); - clk_register_clkdev(clk1, "i2s_sclk_gclk", NULL); + clk_register_clkdev(clk1, "i2s_sclk_gate_clk", NULL); /* clock derived from ahb clk */ clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, @@ -741,7 +744,7 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, NULL, "e0280000.i2c"); clk = clk_register_gate(NULL, "i2c1_clk", "ahb_clk", 0, - SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_I2C1_CLK_ENB, 0, + SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2C1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b4000000.i2c"); @@ -797,13 +800,13 @@ void __init spear1340_clk_init(void) &_lock); clk_register_clkdev(clk, "sysram1_clk", NULL); - clk = clk_register_aux("adc_syn_clk", "adc_syn_gclk", "ahb_clk", + clk = clk_register_aux("adc_synth_clk", "adc_synth_gate_clk", "ahb_clk", 0, SPEAR1340_ADC_CLK_SYNT, NULL, adc_rtbl, ARRAY_SIZE(adc_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "adc_syn_clk", NULL); - clk_register_clkdev(clk1, "adc_syn_gclk", NULL); + clk_register_clkdev(clk, "adc_synth_clk", NULL); + clk_register_clkdev(clk1, "adc_synth_gate_clk", NULL); - clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, + clk = clk_register_gate(NULL, "adc_clk", "adc_synth_gate_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "adc_clk"); @@ -840,39 +843,39 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, NULL, "e0300000.kbd"); /* RAS clks */ - clk = clk_register_mux(NULL, "gen_syn0_1_mclk", gen_synth0_1_parents, - ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1340_PLL_CFG, - SPEAR1340_GEN_SYNT0_1_CLK_SHIFT, + clk = clk_register_mux(NULL, "gen_synth0_1_mux_clk", + gen_synth0_1_parents, ARRAY_SIZE(gen_synth0_1_parents), + 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT0_1_CLK_SHIFT, SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn0_1_clk", NULL); + clk_register_clkdev(clk, "gen_synth0_1_clk", NULL); - clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents, - ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1340_PLL_CFG, - SPEAR1340_GEN_SYNT2_3_CLK_SHIFT, + clk = clk_register_mux(NULL, "gen_synth2_3_mux_clk", + gen_synth2_3_parents, ARRAY_SIZE(gen_synth2_3_parents), + 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT2_3_CLK_SHIFT, SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn2_3_clk", NULL); + clk_register_clkdev(clk, "gen_synth2_3_clk", NULL); - clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0, + clk = clk_register_frac("gen_synth0_clk", "gen_synth0_1_clk", 0, SPEAR1340_GEN_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn0_clk", NULL); + clk_register_clkdev(clk, "gen_synth0_clk", NULL); - clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0, + clk = clk_register_frac("gen_synth1_clk", "gen_synth0_1_clk", 0, SPEAR1340_GEN_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn1_clk", NULL); + clk_register_clkdev(clk, "gen_synth1_clk", NULL); - clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0, + clk = clk_register_frac("gen_synth2_clk", "gen_synth2_3_clk", 0, SPEAR1340_GEN_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn2_clk", NULL); + clk_register_clkdev(clk, "gen_synth2_clk", NULL); - clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0, + clk = clk_register_frac("gen_synth3_clk", "gen_synth2_3_clk", 0, SPEAR1340_GEN_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); - clk_register_clkdev(clk, "gen_syn3_clk", NULL); + clk_register_clkdev(clk, "gen_synth3_clk", NULL); - clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", 0, + clk = clk_register_gate(NULL, "mali_clk", "gen_synth3_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_MALI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "mali"); @@ -887,74 +890,74 @@ void __init spear1340_clk_init(void) &_lock); clk_register_clkdev(clk, NULL, "spear_cec.1"); - clk = clk_register_mux(NULL, "spdif_out_mclk", spdif_out_parents, + clk = clk_register_mux(NULL, "spdif_out_mux_clk", spdif_out_parents, ARRAY_SIZE(spdif_out_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT, SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "spdif_out_mclk", NULL); + clk_register_clkdev(clk, "spdif_out_mux_clk", NULL); - clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", 0, + clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spdif-out"); - clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents, + clk = clk_register_mux(NULL, "spdif_in_mux_clk", spdif_in_parents, ARRAY_SIZE(spdif_in_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT, SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "spdif_in_mclk", NULL); + clk_register_clkdev(clk, "spdif_in_mux_clk", NULL); - clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", 0, + clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spdif-in"); - clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0, + clk = clk_register_gate(NULL, "acp_clk", "acp_mux_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "acp_clk"); - clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0, + clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "plgpio"); - clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0, + clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "video_dec"); - clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mclk", 0, + clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "video_enc"); - clk = clk_register_gate(NULL, "video_in_clk", "video_in_mclk", 0, + clk = clk_register_gate(NULL, "video_in_clk", "video_in_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_vip"); - clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0, + clk = clk_register_gate(NULL, "cam0_clk", "cam0_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_camif.0"); - clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0, + clk = clk_register_gate(NULL, "cam1_clk", "cam1_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_camif.1"); - clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0, + clk = clk_register_gate(NULL, "cam2_clk", "cam2_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_camif.2"); - clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0, + clk = clk_register_gate(NULL, "cam3_clk", "cam3_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "spear_camif.3"); - clk = clk_register_gate(NULL, "pwm_clk", "pwm_mclk", 0, + clk = clk_register_gate(NULL, "pwm_clk", "pwm_mux_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "pwm"); diff --git a/trunk/drivers/clk/spear/spear3xx_clock.c b/trunk/drivers/clk/spear/spear3xx_clock.c index c3157454bb3f..440bb3e4c971 100644 --- a/trunk/drivers/clk/spear/spear3xx_clock.c +++ b/trunk/drivers/clk/spear/spear3xx_clock.c @@ -2,7 +2,7 @@ * SPEAr3xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -122,12 +122,12 @@ static struct gpt_rate_tbl gpt_rtbl[] = { }; /* clock parents */ -static const char *uart0_parents[] = { "pll3_clk", "uart_syn_gclk", }; -static const char *firda_parents[] = { "pll3_clk", "firda_syn_gclk", +static const char *uart0_parents[] = { "pll3_48m_clk", "uart_synth_gate_clk", }; +static const char *firda_parents[] = { "pll3_48m_clk", "firda_synth_gate_clk", }; -static const char *gpt0_parents[] = { "pll3_clk", "gpt0_syn_clk", }; -static const char *gpt1_parents[] = { "pll3_clk", "gpt1_syn_clk", }; -static const char *gpt2_parents[] = { "pll3_clk", "gpt2_syn_clk", }; +static const char *gpt0_parents[] = { "pll3_48m_clk", "gpt0_synth_clk", }; +static const char *gpt1_parents[] = { "pll3_48m_clk", "gpt1_synth_clk", }; +static const char *gpt2_parents[] = { "pll3_48m_clk", "gpt2_synth_clk", }; static const char *gen2_3_parents[] = { "pll1_clk", "pll2_clk", }; static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none", "pll2_clk", }; @@ -137,7 +137,7 @@ static void __init spear300_clk_init(void) { struct clk *clk; - clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_clk", 0, + clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_48m_clk", 0, 1, 1); clk_register_clkdev(clk, NULL, "60000000.clcd"); @@ -219,11 +219,15 @@ static void __init spear310_clk_init(void) #define SPEAR320_UARTX_PCLK_VAL_SYNTH1 0x0 #define SPEAR320_UARTX_PCLK_VAL_APB 0x1 -static const char *i2s_ref_parents[] = { "ras_pll2_clk", "ras_syn2_gclk", }; -static const char *sdhci_parents[] = { "ras_pll3_clk", "ras_syn3_gclk", }; +static const char *i2s_ref_parents[] = { "ras_pll2_clk", + "ras_gen2_synth_gate_clk", }; +static const char *sdhci_parents[] = { "ras_pll3_48m_clk", + "ras_gen3_synth_gate_clk", +}; static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk", - "ras_syn0_gclk", }; -static const char *uartx_parents[] = { "ras_syn1_gclk", "ras_apb_clk", }; + "ras_gen0_synth_gate_clk", }; +static const char *uartx_parents[] = { "ras_gen1_synth_gate_clk", "ras_apb_clk", +}; static void __init spear320_clk_init(void) { @@ -233,7 +237,7 @@ static void __init spear320_clk_init(void) CLK_IS_ROOT, 125000000); clk_register_clkdev(clk, "smii_125m_pad", NULL); - clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_clk", 0, + clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_48m_clk", 0, 1, 1); clk_register_clkdev(clk, NULL, "90000000.clcd"); @@ -359,9 +363,9 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk, NULL, "fc900000.rtc"); /* clock derived from 24 MHz osc clk */ - clk = clk_register_fixed_rate(NULL, "pll3_clk", "osc_24m_clk", 0, + clk = clk_register_fixed_rate(NULL, "pll3_48m_clk", "osc_24m_clk", 0, 48000000); - clk_register_clkdev(clk, "pll3_clk", NULL); + clk_register_clkdev(clk, "pll3_48m_clk", NULL); clk = clk_register_fixed_factor(NULL, "wdt_clk", "osc_24m_clk", 0, 1, 1); @@ -388,98 +392,98 @@ void __init spear3xx_clk_init(void) HCLK_RATIO_MASK, 0, &_lock); clk_register_clkdev(clk, "ahb_clk", NULL); - clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "pll1_clk", 0, - UART_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "uart_syn_clk", NULL); - clk_register_clkdev(clk1, "uart_syn_gclk", NULL); + clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk", + "pll1_clk", 0, UART_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "uart_synth_clk", NULL); + clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, + clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents, ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart0_mclk", NULL); + clk_register_clkdev(clk, "uart0_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart0", "uart0_mclk", 0, PERIP1_CLK_ENB, - UART_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "uart0", "uart0_mux_clk", 0, + PERIP1_CLK_ENB, UART_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "d0000000.serial"); - clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", 0, - FIRDA_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "firda_syn_clk", NULL); - clk_register_clkdev(clk1, "firda_syn_gclk", NULL); + clk = clk_register_aux("firda_synth_clk", "firda_synth_gate_clk", + "pll1_clk", 0, FIRDA_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "firda_synth_clk", NULL); + clk_register_clkdev(clk1, "firda_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "firda_mclk", firda_parents, + clk = clk_register_mux(NULL, "firda_mux_clk", firda_parents, ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "firda_mclk", NULL); + clk_register_clkdev(clk, "firda_mux_clk", NULL); - clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0, + clk = clk_register_gate(NULL, "firda_clk", "firda_mux_clk", 0, PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "firda"); /* gpt clocks */ - clk_register_gpt("gpt0_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl, - ARRAY_SIZE(gpt_rtbl), &_lock); + clk_register_gpt("gpt0_synth_clk", "pll1_clk", 0, PRSC0_CLK_CFG, + gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents, ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt0"); - clk_register_gpt("gpt1_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl, - ARRAY_SIZE(gpt_rtbl), &_lock); - clk = clk_register_mux(NULL, "gpt1_mclk", gpt1_parents, + clk_register_gpt("gpt1_synth_clk", "pll1_clk", 0, PRSC1_CLK_CFG, + gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); + clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt1_parents, ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt1_mclk", NULL); - clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, + clk_register_clkdev(clk, "gpt1_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt1"); - clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl, - ARRAY_SIZE(gpt_rtbl), &_lock); - clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents, + clk_register_gpt("gpt2_synth_clk", "pll1_clk", 0, PRSC2_CLK_CFG, + gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); + clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt2_parents, ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt2_mclk", NULL); - clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, + clk_register_clkdev(clk, "gpt2_mux_clk", NULL); + clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt2"); /* general synths clocks */ - clk = clk_register_aux("gen0_syn_clk", "gen0_syn_gclk", "pll1_clk", - 0, GEN0_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "gen0_syn_clk", NULL); - clk_register_clkdev(clk1, "gen0_syn_gclk", NULL); - - clk = clk_register_aux("gen1_syn_clk", "gen1_syn_gclk", "pll1_clk", - 0, GEN1_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "gen1_syn_clk", NULL); - clk_register_clkdev(clk1, "gen1_syn_gclk", NULL); - - clk = clk_register_mux(NULL, "gen2_3_par_clk", gen2_3_parents, + clk = clk_register_aux("gen0_synth_clk", "gen0_synth_gate_clk", + "pll1_clk", 0, GEN0_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "gen0_synth_clk", NULL); + clk_register_clkdev(clk1, "gen0_synth_gate_clk", NULL); + + clk = clk_register_aux("gen1_synth_clk", "gen1_synth_gate_clk", + "pll1_clk", 0, GEN1_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "gen1_synth_clk", NULL); + clk_register_clkdev(clk1, "gen1_synth_gate_clk", NULL); + + clk = clk_register_mux(NULL, "gen2_3_parent_clk", gen2_3_parents, ARRAY_SIZE(gen2_3_parents), 0, CORE_CLK_CFG, GEN_SYNTH2_3_CLK_SHIFT, GEN_SYNTH2_3_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen2_3_par_clk", NULL); + clk_register_clkdev(clk, "gen2_3_parent_clk", NULL); - clk = clk_register_aux("gen2_syn_clk", "gen2_syn_gclk", - "gen2_3_par_clk", 0, GEN2_CLK_SYNT, NULL, aux_rtbl, + clk = clk_register_aux("gen2_synth_clk", "gen2_synth_gate_clk", + "gen2_3_parent_clk", 0, GEN2_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "gen2_syn_clk", NULL); - clk_register_clkdev(clk1, "gen2_syn_gclk", NULL); + clk_register_clkdev(clk, "gen2_synth_clk", NULL); + clk_register_clkdev(clk1, "gen2_synth_gate_clk", NULL); - clk = clk_register_aux("gen3_syn_clk", "gen3_syn_gclk", - "gen2_3_par_clk", 0, GEN3_CLK_SYNT, NULL, aux_rtbl, + clk = clk_register_aux("gen3_synth_clk", "gen3_synth_gate_clk", + "gen2_3_parent_clk", 0, GEN3_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); - clk_register_clkdev(clk, "gen3_syn_clk", NULL); - clk_register_clkdev(clk1, "gen3_syn_gclk", NULL); + clk_register_clkdev(clk, "gen3_synth_clk", NULL); + clk_register_clkdev(clk1, "gen3_synth_gate_clk", NULL); /* clock derived from pll3 clk */ - clk = clk_register_gate(NULL, "usbh_clk", "pll3_clk", 0, PERIP1_CLK_ENB, - USBH_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "usbh_clk", "pll3_48m_clk", 0, + PERIP1_CLK_ENB, USBH_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "usbh_clk", NULL); clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1, @@ -490,8 +494,8 @@ void __init spear3xx_clk_init(void) 1); clk_register_clkdev(clk, "usbh.1_clk", NULL); - clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, - USBD_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "usbd_clk", "pll3_48m_clk", 0, + PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "designware_udc"); /* clock derived from ahb clk */ @@ -575,25 +579,29 @@ void __init spear3xx_clk_init(void) RAS_CLK_ENB, RAS_PLL2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_pll2_clk", NULL); - clk = clk_register_gate(NULL, "ras_pll3_clk", "pll3_clk", 0, + clk = clk_register_gate(NULL, "ras_pll3_48m_clk", "pll3_48m_clk", 0, RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "ras_pll3_clk", NULL); - - clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "ras_syn0_gclk", NULL); - - clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "ras_syn1_gclk", NULL); - - clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "ras_syn2_gclk", NULL); - - clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "ras_syn3_gclk", NULL); + clk_register_clkdev(clk, "ras_pll3_48m_clk", NULL); + + clk = clk_register_gate(NULL, "ras_gen0_synth_gate_clk", + "gen0_synth_gate_clk", 0, RAS_CLK_ENB, + RAS_SYNT0_CLK_ENB, 0, &_lock); + clk_register_clkdev(clk, "ras_gen0_synth_gate_clk", NULL); + + clk = clk_register_gate(NULL, "ras_gen1_synth_gate_clk", + "gen1_synth_gate_clk", 0, RAS_CLK_ENB, + RAS_SYNT1_CLK_ENB, 0, &_lock); + clk_register_clkdev(clk, "ras_gen1_synth_gate_clk", NULL); + + clk = clk_register_gate(NULL, "ras_gen2_synth_gate_clk", + "gen2_synth_gate_clk", 0, RAS_CLK_ENB, + RAS_SYNT2_CLK_ENB, 0, &_lock); + clk_register_clkdev(clk, "ras_gen2_synth_gate_clk", NULL); + + clk = clk_register_gate(NULL, "ras_gen3_synth_gate_clk", + "gen3_synth_gate_clk", 0, RAS_CLK_ENB, + RAS_SYNT3_CLK_ENB, 0, &_lock); + clk_register_clkdev(clk, "ras_gen3_synth_gate_clk", NULL); if (of_machine_is_compatible("st,spear300")) spear300_clk_init(); diff --git a/trunk/drivers/clk/spear/spear6xx_clock.c b/trunk/drivers/clk/spear/spear6xx_clock.c index a98d0866f541..f9a20b382304 100644 --- a/trunk/drivers/clk/spear/spear6xx_clock.c +++ b/trunk/drivers/clk/spear/spear6xx_clock.c @@ -2,7 +2,7 @@ * SPEAr6xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -97,12 +97,13 @@ static struct aux_rate_tbl aux_rtbl[] = { {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ }; -static const char *clcd_parents[] = { "pll3_clk", "clcd_syn_gclk", }; -static const char *firda_parents[] = { "pll3_clk", "firda_syn_gclk", }; -static const char *uart_parents[] = { "pll3_clk", "uart_syn_gclk", }; -static const char *gpt0_1_parents[] = { "pll3_clk", "gpt0_1_syn_clk", }; -static const char *gpt2_parents[] = { "pll3_clk", "gpt2_syn_clk", }; -static const char *gpt3_parents[] = { "pll3_clk", "gpt3_syn_clk", }; +static const char *clcd_parents[] = { "pll3_48m_clk", "clcd_synth_gate_clk", }; +static const char *firda_parents[] = { "pll3_48m_clk", "firda_synth_gate_clk", +}; +static const char *uart_parents[] = { "pll3_48m_clk", "uart_synth_gate_clk", }; +static const char *gpt0_1_parents[] = { "pll3_48m_clk", "gpt0_1_synth_clk", }; +static const char *gpt2_parents[] = { "pll3_48m_clk", "gpt2_synth_clk", }; +static const char *gpt3_parents[] = { "pll3_48m_clk", "gpt3_synth_clk", }; static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none", "pll2_clk", }; @@ -135,9 +136,9 @@ void __init spear6xx_clk_init(void) clk_register_clkdev(clk, NULL, "rtc-spear"); /* clock derived from 30 MHz osc clk */ - clk = clk_register_fixed_rate(NULL, "pll3_clk", "osc_24m_clk", 0, + clk = clk_register_fixed_rate(NULL, "pll3_48m_clk", "osc_24m_clk", 0, 48000000); - clk_register_clkdev(clk, "pll3_clk", NULL); + clk_register_clkdev(clk, "pll3_48m_clk", NULL); clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "osc_30m_clk", 0, PLL1_CTR, PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), @@ -145,9 +146,9 @@ void __init spear6xx_clk_init(void) clk_register_clkdev(clk, "vco1_clk", NULL); clk_register_clkdev(clk1, "pll1_clk", NULL); - clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "osc_30m_clk", - 0, PLL2_CTR, PLL2_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), - &_lock, &clk1, NULL); + clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, + "osc_30m_clk", 0, PLL2_CTR, PLL2_FRQ, pll_rtbl, + ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); clk_register_clkdev(clk, "vco2_clk", NULL); clk_register_clkdev(clk1, "pll2_clk", NULL); @@ -164,111 +165,111 @@ void __init spear6xx_clk_init(void) HCLK_RATIO_MASK, 0, &_lock); clk_register_clkdev(clk, "ahb_clk", NULL); - clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "pll1_clk", 0, - UART_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "uart_syn_clk", NULL); - clk_register_clkdev(clk1, "uart_syn_gclk", NULL); + clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk", + "pll1_clk", 0, UART_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "uart_synth_clk", NULL); + clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "uart_mclk", uart_parents, + clk = clk_register_mux(NULL, "uart_mux_clk", uart_parents, ARRAY_SIZE(uart_parents), 0, PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "uart_mclk", NULL); + clk_register_clkdev(clk, "uart_mux_clk", NULL); - clk = clk_register_gate(NULL, "uart0", "uart_mclk", 0, PERIP1_CLK_ENB, - UART0_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "uart0", "uart_mux_clk", 0, + PERIP1_CLK_ENB, UART0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "d0000000.serial"); - clk = clk_register_gate(NULL, "uart1", "uart_mclk", 0, PERIP1_CLK_ENB, - UART1_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "uart1", "uart_mux_clk", 0, + PERIP1_CLK_ENB, UART1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "d0080000.serial"); - clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", - 0, FIRDA_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "firda_syn_clk", NULL); - clk_register_clkdev(clk1, "firda_syn_gclk", NULL); + clk = clk_register_aux("firda_synth_clk", "firda_synth_gate_clk", + "pll1_clk", 0, FIRDA_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "firda_synth_clk", NULL); + clk_register_clkdev(clk1, "firda_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "firda_mclk", firda_parents, + clk = clk_register_mux(NULL, "firda_mux_clk", firda_parents, ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "firda_mclk", NULL); + clk_register_clkdev(clk, "firda_mux_clk", NULL); - clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0, + clk = clk_register_gate(NULL, "firda_clk", "firda_mux_clk", 0, PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "firda"); - clk = clk_register_aux("clcd_syn_clk", "clcd_syn_gclk", "pll1_clk", - 0, CLCD_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), - &_lock, &clk1); - clk_register_clkdev(clk, "clcd_syn_clk", NULL); - clk_register_clkdev(clk1, "clcd_syn_gclk", NULL); + clk = clk_register_aux("clcd_synth_clk", "clcd_synth_gate_clk", + "pll1_clk", 0, CLCD_CLK_SYNT, NULL, aux_rtbl, + ARRAY_SIZE(aux_rtbl), &_lock, &clk1); + clk_register_clkdev(clk, "clcd_synth_clk", NULL); + clk_register_clkdev(clk1, "clcd_synth_gate_clk", NULL); - clk = clk_register_mux(NULL, "clcd_mclk", clcd_parents, + clk = clk_register_mux(NULL, "clcd_mux_clk", clcd_parents, ARRAY_SIZE(clcd_parents), 0, PERIP_CLK_CFG, CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_mclk", NULL); + clk_register_clkdev(clk, "clcd_mux_clk", NULL); - clk = clk_register_gate(NULL, "clcd_clk", "clcd_mclk", 0, + clk = clk_register_gate(NULL, "clcd_clk", "clcd_mux_clk", 0, PERIP1_CLK_ENB, CLCD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "clcd"); /* gpt clocks */ - clk = clk_register_gpt("gpt0_1_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, + clk = clk_register_gpt("gpt0_1_synth_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); - clk_register_clkdev(clk, "gpt0_1_syn_clk", NULL); + clk_register_clkdev(clk, "gpt0_1_synth_clk", NULL); - clk = clk_register_mux(NULL, "gpt0_mclk", gpt0_1_parents, + clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt0_1_parents, ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt0"); - clk = clk_register_mux(NULL, "gpt1_mclk", gpt0_1_parents, + clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt0_1_parents, ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt1_mclk", NULL); + clk_register_clkdev(clk, "gpt1_mux_clk", NULL); - clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, + clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt1"); - clk = clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, + clk = clk_register_gpt("gpt2_synth_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); - clk_register_clkdev(clk, "gpt2_syn_clk", NULL); + clk_register_clkdev(clk, "gpt2_synth_clk", NULL); - clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents, + clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt2_parents, ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt2_mclk", NULL); + clk_register_clkdev(clk, "gpt2_mux_clk", NULL); - clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, + clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt2"); - clk = clk_register_gpt("gpt3_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, + clk = clk_register_gpt("gpt3_synth_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); - clk_register_clkdev(clk, "gpt3_syn_clk", NULL); + clk_register_clkdev(clk, "gpt3_synth_clk", NULL); - clk = clk_register_mux(NULL, "gpt3_mclk", gpt3_parents, + clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt3_parents, ARRAY_SIZE(gpt3_parents), 0, PERIP_CLK_CFG, GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gpt3_mclk", NULL); + clk_register_clkdev(clk, "gpt3_mux_clk", NULL); - clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0, + clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0, PERIP1_CLK_ENB, GPT3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt3"); /* clock derived from pll3 clk */ - clk = clk_register_gate(NULL, "usbh0_clk", "pll3_clk", 0, + clk = clk_register_gate(NULL, "usbh0_clk", "pll3_48m_clk", 0, PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "usbh.0_clk"); - clk = clk_register_gate(NULL, "usbh1_clk", "pll3_clk", 0, + clk = clk_register_gate(NULL, "usbh1_clk", "pll3_48m_clk", 0, PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "usbh.1_clk"); - clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, - USBD_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "usbd_clk", "pll3_48m_clk", 0, + PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "designware_udc"); /* clock derived from ahb clk */ @@ -277,8 +278,9 @@ void __init spear6xx_clk_init(void) clk_register_clkdev(clk, "ahbmult2_clk", NULL); clk = clk_register_mux(NULL, "ddr_clk", ddr_parents, - ARRAY_SIZE(ddr_parents), 0, PLL_CLK_CFG, MCTR_CLK_SHIFT, - MCTR_CLK_MASK, 0, &_lock); + ARRAY_SIZE(ddr_parents), + 0, PLL_CLK_CFG, MCTR_CLK_SHIFT, MCTR_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "ddr_clk", NULL); clk = clk_register_divider(NULL, "apb_clk", "ahb_clk", @@ -296,7 +298,7 @@ void __init spear6xx_clk_init(void) clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB, GMAC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e0800000.ethernet"); + clk_register_clkdev(clk, NULL, "gmac"); clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB, I2C_CLK_ENB, 0, &_lock); diff --git a/trunk/drivers/clocksource/Makefile b/trunk/drivers/clocksource/Makefile index dd3e661a124d..8d81a1d32653 100644 --- a/trunk/drivers/clocksource/Makefile +++ b/trunk/drivers/clocksource/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o -obj-$(CONFIG_EM_TIMER_STI) += em_sti.o obj-$(CONFIG_CLKBLD_I8253) += i8253.o obj-$(CONFIG_CLKSRC_MMIO) += mmio.o obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o diff --git a/trunk/drivers/clocksource/em_sti.c b/trunk/drivers/clocksource/em_sti.c deleted file mode 100644 index 372051d1bba8..000000000000 --- a/trunk/drivers/clocksource/em_sti.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Emma Mobile Timer Support - STI - * - * Copyright (C) 2012 Magnus Damm - * - * 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 -#include -#include -#include -#include - -enum { USER_CLOCKSOURCE, USER_CLOCKEVENT, USER_NR }; - -struct em_sti_priv { - void __iomem *base; - struct clk *clk; - struct platform_device *pdev; - unsigned int active[USER_NR]; - unsigned long rate; - raw_spinlock_t lock; - struct clock_event_device ced; - struct clocksource cs; -}; - -#define STI_CONTROL 0x00 -#define STI_COMPA_H 0x10 -#define STI_COMPA_L 0x14 -#define STI_COMPB_H 0x18 -#define STI_COMPB_L 0x1c -#define STI_COUNT_H 0x20 -#define STI_COUNT_L 0x24 -#define STI_COUNT_RAW_H 0x28 -#define STI_COUNT_RAW_L 0x2c -#define STI_SET_H 0x30 -#define STI_SET_L 0x34 -#define STI_INTSTATUS 0x40 -#define STI_INTRAWSTATUS 0x44 -#define STI_INTENSET 0x48 -#define STI_INTENCLR 0x4c -#define STI_INTFFCLR 0x50 - -static inline unsigned long em_sti_read(struct em_sti_priv *p, int offs) -{ - return ioread32(p->base + offs); -} - -static inline void em_sti_write(struct em_sti_priv *p, int offs, - unsigned long value) -{ - iowrite32(value, p->base + offs); -} - -static int em_sti_enable(struct em_sti_priv *p) -{ - int ret; - - /* enable clock */ - ret = clk_enable(p->clk); - if (ret) { - dev_err(&p->pdev->dev, "cannot enable clock\n"); - return ret; - } - - /* configure channel, periodic mode and maximum timeout */ - p->rate = clk_get_rate(p->clk); - - /* reset the counter */ - em_sti_write(p, STI_SET_H, 0x40000000); - em_sti_write(p, STI_SET_L, 0x00000000); - - /* mask and clear pending interrupts */ - em_sti_write(p, STI_INTENCLR, 3); - em_sti_write(p, STI_INTFFCLR, 3); - - /* enable updates of counter registers */ - em_sti_write(p, STI_CONTROL, 1); - - return 0; -} - -static void em_sti_disable(struct em_sti_priv *p) -{ - /* mask interrupts */ - em_sti_write(p, STI_INTENCLR, 3); - - /* stop clock */ - clk_disable(p->clk); -} - -static cycle_t em_sti_count(struct em_sti_priv *p) -{ - cycle_t ticks; - unsigned long flags; - - /* the STI hardware buffers the 48-bit count, but to - * break it out into two 32-bit access the registers - * must be accessed in a certain order. - * Always read STI_COUNT_H before STI_COUNT_L. - */ - raw_spin_lock_irqsave(&p->lock, flags); - ticks = (cycle_t)(em_sti_read(p, STI_COUNT_H) & 0xffff) << 32; - ticks |= em_sti_read(p, STI_COUNT_L); - raw_spin_unlock_irqrestore(&p->lock, flags); - - return ticks; -} - -static cycle_t em_sti_set_next(struct em_sti_priv *p, cycle_t next) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&p->lock, flags); - - /* mask compare A interrupt */ - em_sti_write(p, STI_INTENCLR, 1); - - /* update compare A value */ - em_sti_write(p, STI_COMPA_H, next >> 32); - em_sti_write(p, STI_COMPA_L, next & 0xffffffff); - - /* clear compare A interrupt source */ - em_sti_write(p, STI_INTFFCLR, 1); - - /* unmask compare A interrupt */ - em_sti_write(p, STI_INTENSET, 1); - - raw_spin_unlock_irqrestore(&p->lock, flags); - - return next; -} - -static irqreturn_t em_sti_interrupt(int irq, void *dev_id) -{ - struct em_sti_priv *p = dev_id; - - p->ced.event_handler(&p->ced); - return IRQ_HANDLED; -} - -static int em_sti_start(struct em_sti_priv *p, unsigned int user) -{ - unsigned long flags; - int used_before; - int ret = 0; - - raw_spin_lock_irqsave(&p->lock, flags); - used_before = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT]; - if (!used_before) - ret = em_sti_enable(p); - - if (!ret) - p->active[user] = 1; - raw_spin_unlock_irqrestore(&p->lock, flags); - - return ret; -} - -static void em_sti_stop(struct em_sti_priv *p, unsigned int user) -{ - unsigned long flags; - int used_before, used_after; - - raw_spin_lock_irqsave(&p->lock, flags); - used_before = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT]; - p->active[user] = 0; - used_after = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT]; - - if (used_before && !used_after) - em_sti_disable(p); - raw_spin_unlock_irqrestore(&p->lock, flags); -} - -static struct em_sti_priv *cs_to_em_sti(struct clocksource *cs) -{ - return container_of(cs, struct em_sti_priv, cs); -} - -static cycle_t em_sti_clocksource_read(struct clocksource *cs) -{ - return em_sti_count(cs_to_em_sti(cs)); -} - -static int em_sti_clocksource_enable(struct clocksource *cs) -{ - int ret; - struct em_sti_priv *p = cs_to_em_sti(cs); - - ret = em_sti_start(p, USER_CLOCKSOURCE); - if (!ret) - __clocksource_updatefreq_hz(cs, p->rate); - return ret; -} - -static void em_sti_clocksource_disable(struct clocksource *cs) -{ - em_sti_stop(cs_to_em_sti(cs), USER_CLOCKSOURCE); -} - -static void em_sti_clocksource_resume(struct clocksource *cs) -{ - em_sti_clocksource_enable(cs); -} - -static int em_sti_register_clocksource(struct em_sti_priv *p) -{ - struct clocksource *cs = &p->cs; - - memset(cs, 0, sizeof(*cs)); - cs->name = dev_name(&p->pdev->dev); - cs->rating = 200; - cs->read = em_sti_clocksource_read; - cs->enable = em_sti_clocksource_enable; - cs->disable = em_sti_clocksource_disable; - cs->suspend = em_sti_clocksource_disable; - cs->resume = em_sti_clocksource_resume; - cs->mask = CLOCKSOURCE_MASK(48); - cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; - - dev_info(&p->pdev->dev, "used as clock source\n"); - - /* Register with dummy 1 Hz value, gets updated in ->enable() */ - clocksource_register_hz(cs, 1); - return 0; -} - -static struct em_sti_priv *ced_to_em_sti(struct clock_event_device *ced) -{ - return container_of(ced, struct em_sti_priv, ced); -} - -static void em_sti_clock_event_mode(enum clock_event_mode mode, - struct clock_event_device *ced) -{ - struct em_sti_priv *p = ced_to_em_sti(ced); - - /* deal with old setting first */ - switch (ced->mode) { - case CLOCK_EVT_MODE_ONESHOT: - em_sti_stop(p, USER_CLOCKEVENT); - break; - default: - break; - } - - switch (mode) { - case CLOCK_EVT_MODE_ONESHOT: - dev_info(&p->pdev->dev, "used for oneshot clock events\n"); - em_sti_start(p, USER_CLOCKEVENT); - clockevents_config(&p->ced, p->rate); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - em_sti_stop(p, USER_CLOCKEVENT); - break; - default: - break; - } -} - -static int em_sti_clock_event_next(unsigned long delta, - struct clock_event_device *ced) -{ - struct em_sti_priv *p = ced_to_em_sti(ced); - cycle_t next; - int safe; - - next = em_sti_set_next(p, em_sti_count(p) + delta); - safe = em_sti_count(p) < (next - 1); - - return !safe; -} - -static void em_sti_register_clockevent(struct em_sti_priv *p) -{ - struct clock_event_device *ced = &p->ced; - - memset(ced, 0, sizeof(*ced)); - ced->name = dev_name(&p->pdev->dev); - ced->features = CLOCK_EVT_FEAT_ONESHOT; - ced->rating = 200; - ced->cpumask = cpumask_of(0); - ced->set_next_event = em_sti_clock_event_next; - ced->set_mode = em_sti_clock_event_mode; - - dev_info(&p->pdev->dev, "used for clock events\n"); - - /* Register with dummy 1 Hz value, gets updated in ->set_mode() */ - clockevents_config_and_register(ced, 1, 2, 0xffffffff); -} - -static int __devinit em_sti_probe(struct platform_device *pdev) -{ - struct em_sti_priv *p; - struct resource *res; - int irq, ret; - - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - ret = -ENOMEM; - goto err0; - } - - p->pdev = pdev; - platform_set_drvdata(pdev, p); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get I/O memory\n"); - ret = -EINVAL; - goto err0; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get irq\n"); - ret = -EINVAL; - goto err0; - } - - /* map memory, let base point to the STI instance */ - p->base = ioremap_nocache(res->start, resource_size(res)); - if (p->base == NULL) { - dev_err(&pdev->dev, "failed to remap I/O memory\n"); - ret = -ENXIO; - goto err0; - } - - /* get hold of clock */ - p->clk = clk_get(&pdev->dev, "sclk"); - if (IS_ERR(p->clk)) { - dev_err(&pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; - } - - if (request_irq(irq, em_sti_interrupt, - IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, - dev_name(&pdev->dev), p)) { - dev_err(&pdev->dev, "failed to request low IRQ\n"); - ret = -ENOENT; - goto err2; - } - - raw_spin_lock_init(&p->lock); - em_sti_register_clockevent(p); - em_sti_register_clocksource(p); - return 0; - -err2: - clk_put(p->clk); -err1: - iounmap(p->base); -err0: - kfree(p); - return ret; -} - -static int __devexit em_sti_remove(struct platform_device *pdev) -{ - return -EBUSY; /* cannot unregister clockevent and clocksource */ -} - -static const struct of_device_id em_sti_dt_ids[] __devinitconst = { - { .compatible = "renesas,em-sti", }, - {}, -}; -MODULE_DEVICE_TABLE(of, em_sti_dt_ids); - -static struct platform_driver em_sti_device_driver = { - .probe = em_sti_probe, - .remove = __devexit_p(em_sti_remove), - .driver = { - .name = "em_sti", - .of_match_table = em_sti_dt_ids, - } -}; - -module_platform_driver(em_sti_device_driver); - -MODULE_AUTHOR("Magnus Damm"); -MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/clocksource/sh_cmt.c b/trunk/drivers/clocksource/sh_cmt.c index 98b06baafcc6..32fe9ef5cc5c 100644 --- a/trunk/drivers/clocksource/sh_cmt.c +++ b/trunk/drivers/clocksource/sh_cmt.c @@ -48,13 +48,13 @@ struct sh_cmt_priv { unsigned long next_match_value; unsigned long max_match_value; unsigned long rate; - raw_spinlock_t lock; + spinlock_t lock; struct clock_event_device ced; struct clocksource cs; unsigned long total_cycles; }; -static DEFINE_RAW_SPINLOCK(sh_cmt_lock); +static DEFINE_SPINLOCK(sh_cmt_lock); #define CMSTR -1 /* shared register */ #define CMCSR 0 /* channel register */ @@ -139,7 +139,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) unsigned long flags, value; /* start stop register shared by multiple timer channels */ - raw_spin_lock_irqsave(&sh_cmt_lock, flags); + spin_lock_irqsave(&sh_cmt_lock, flags); value = sh_cmt_read(p, CMSTR); if (start) @@ -148,7 +148,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) value &= ~(1 << cfg->timer_bit); sh_cmt_write(p, CMSTR, value); - raw_spin_unlock_irqrestore(&sh_cmt_lock, flags); + spin_unlock_irqrestore(&sh_cmt_lock, flags); } static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) @@ -328,9 +328,9 @@ static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) { unsigned long flags; - raw_spin_lock_irqsave(&p->lock, flags); + spin_lock_irqsave(&p->lock, flags); __sh_cmt_set_next(p, delta); - raw_spin_unlock_irqrestore(&p->lock, flags); + spin_unlock_irqrestore(&p->lock, flags); } static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) @@ -385,7 +385,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) int ret = 0; unsigned long flags; - raw_spin_lock_irqsave(&p->lock, flags); + spin_lock_irqsave(&p->lock, flags); if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) ret = sh_cmt_enable(p, &p->rate); @@ -398,7 +398,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) __sh_cmt_set_next(p, p->max_match_value); out: - raw_spin_unlock_irqrestore(&p->lock, flags); + spin_unlock_irqrestore(&p->lock, flags); return ret; } @@ -408,7 +408,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) unsigned long flags; unsigned long f; - raw_spin_lock_irqsave(&p->lock, flags); + spin_lock_irqsave(&p->lock, flags); f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE); p->flags &= ~flag; @@ -420,7 +420,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) __sh_cmt_set_next(p, p->max_match_value); - raw_spin_unlock_irqrestore(&p->lock, flags); + spin_unlock_irqrestore(&p->lock, flags); } static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs) @@ -435,13 +435,13 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) unsigned long value; int has_wrapped; - raw_spin_lock_irqsave(&p->lock, flags); + spin_lock_irqsave(&p->lock, flags); value = p->total_cycles; raw = sh_cmt_get_counter(p, &has_wrapped); if (unlikely(has_wrapped)) raw += p->match_value + 1; - raw_spin_unlock_irqrestore(&p->lock, flags); + spin_unlock_irqrestore(&p->lock, flags); return value + raw; } @@ -591,7 +591,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name, p->max_match_value = (1 << p->width) - 1; p->match_value = p->max_match_value; - raw_spin_lock_init(&p->lock); + spin_lock_init(&p->lock); if (clockevent_rating) sh_cmt_register_clockevent(p, name, clockevent_rating); diff --git a/trunk/drivers/clocksource/sh_mtu2.c b/trunk/drivers/clocksource/sh_mtu2.c index d9b76ca64a61..a2172f690418 100644 --- a/trunk/drivers/clocksource/sh_mtu2.c +++ b/trunk/drivers/clocksource/sh_mtu2.c @@ -43,7 +43,7 @@ struct sh_mtu2_priv { struct clock_event_device ced; }; -static DEFINE_RAW_SPINLOCK(sh_mtu2_lock); +static DEFINE_SPINLOCK(sh_mtu2_lock); #define TSTR -1 /* shared register */ #define TCR 0 /* channel register */ @@ -107,7 +107,7 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start) unsigned long flags, value; /* start stop register shared by multiple timer channels */ - raw_spin_lock_irqsave(&sh_mtu2_lock, flags); + spin_lock_irqsave(&sh_mtu2_lock, flags); value = sh_mtu2_read(p, TSTR); if (start) @@ -116,7 +116,7 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start) value &= ~(1 << cfg->timer_bit); sh_mtu2_write(p, TSTR, value); - raw_spin_unlock_irqrestore(&sh_mtu2_lock, flags); + spin_unlock_irqrestore(&sh_mtu2_lock, flags); } static int sh_mtu2_enable(struct sh_mtu2_priv *p) diff --git a/trunk/drivers/clocksource/sh_tmu.c b/trunk/drivers/clocksource/sh_tmu.c index c1b51d49d106..97f54b634be4 100644 --- a/trunk/drivers/clocksource/sh_tmu.c +++ b/trunk/drivers/clocksource/sh_tmu.c @@ -45,7 +45,7 @@ struct sh_tmu_priv { struct clocksource cs; }; -static DEFINE_RAW_SPINLOCK(sh_tmu_lock); +static DEFINE_SPINLOCK(sh_tmu_lock); #define TSTR -1 /* shared register */ #define TCOR 0 /* channel register */ @@ -95,7 +95,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start) unsigned long flags, value; /* start stop register shared by multiple timer channels */ - raw_spin_lock_irqsave(&sh_tmu_lock, flags); + spin_lock_irqsave(&sh_tmu_lock, flags); value = sh_tmu_read(p, TSTR); if (start) @@ -104,7 +104,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start) value &= ~(1 << cfg->timer_bit); sh_tmu_write(p, TSTR, value); - raw_spin_unlock_irqrestore(&sh_tmu_lock, flags); + spin_unlock_irqrestore(&sh_tmu_lock, flags); } static int sh_tmu_enable(struct sh_tmu_priv *p) @@ -245,7 +245,12 @@ static void sh_tmu_clock_event_start(struct sh_tmu_priv *p, int periodic) sh_tmu_enable(p); - clockevents_config(ced, p->rate); + /* TODO: calculate good shift from rate and counter bit width */ + + ced->shift = 32; + ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift); + ced->max_delta_ns = clockevent_delta2ns(0xffffffff, ced); + ced->min_delta_ns = 5000; if (periodic) { p->periodic = (p->rate + HZ/2) / HZ; @@ -318,8 +323,7 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, ced->set_mode = sh_tmu_clock_event_mode; dev_info(&p->pdev->dev, "used for clock events\n"); - - clockevents_config_and_register(ced, 1, 0x300, 0xffffffff); + clockevents_register_device(ced); ret = setup_irq(p->irqaction.irq, &p->irqaction); if (ret) { diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index fb8a5279c5d8..7f2f149ae40f 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -138,7 +138,7 @@ void disable_cpufreq(void) static LIST_HEAD(cpufreq_governor_list); static DEFINE_MUTEX(cpufreq_governor_mutex); -static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) +struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) { struct cpufreq_policy *data; unsigned long flags; @@ -162,7 +162,7 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) if (!data) goto err_out_put_module; - if (!sysfs && !kobject_get(&data->kobj)) + if (!kobject_get(&data->kobj)) goto err_out_put_module; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); @@ -175,35 +175,16 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) err_out: return NULL; } - -struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) -{ - return __cpufreq_cpu_get(cpu, false); -} EXPORT_SYMBOL_GPL(cpufreq_cpu_get); -static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu) -{ - return __cpufreq_cpu_get(cpu, true); -} - -static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs) -{ - if (!sysfs) - kobject_put(&data->kobj); - module_put(cpufreq_driver->owner); -} void cpufreq_cpu_put(struct cpufreq_policy *data) { - __cpufreq_cpu_put(data, false); + kobject_put(&data->kobj); + module_put(cpufreq_driver->owner); } EXPORT_SYMBOL_GPL(cpufreq_cpu_put); -static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data) -{ - __cpufreq_cpu_put(data, true); -} /********************************************************************* * EXTERNALLY AFFECTING FREQUENCY CHANGES * @@ -636,7 +617,7 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) struct cpufreq_policy *policy = to_policy(kobj); struct freq_attr *fattr = to_attr(attr); ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get_sysfs(policy->cpu); + policy = cpufreq_cpu_get(policy->cpu); if (!policy) goto no_policy; @@ -650,7 +631,7 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) unlock_policy_rwsem_read(policy->cpu); fail: - cpufreq_cpu_put_sysfs(policy); + cpufreq_cpu_put(policy); no_policy: return ret; } @@ -661,7 +642,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, struct cpufreq_policy *policy = to_policy(kobj); struct freq_attr *fattr = to_attr(attr); ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get_sysfs(policy->cpu); + policy = cpufreq_cpu_get(policy->cpu); if (!policy) goto no_policy; @@ -675,7 +656,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, unlock_policy_rwsem_write(policy->cpu); fail: - cpufreq_cpu_put_sysfs(policy); + cpufreq_cpu_put(policy); no_policy: return ret; } diff --git a/trunk/drivers/cpufreq/exynos-cpufreq.c b/trunk/drivers/cpufreq/exynos-cpufreq.c index af2d81e10f71..b243a7ee01f6 100644 --- a/trunk/drivers/cpufreq/exynos-cpufreq.c +++ b/trunk/drivers/cpufreq/exynos-cpufreq.c @@ -62,18 +62,8 @@ static int exynos_target(struct cpufreq_policy *policy, goto out; } - /* - * The policy max have been changed so that we cannot get proper - * old_index with cpufreq_frequency_table_target(). Thus, ignore - * policy and get the index from the raw freqeuncy table. - */ - for (old_index = 0; - freq_table[old_index].frequency != CPUFREQ_TABLE_END; - old_index++) - if (freq_table[old_index].frequency == freqs.old) - break; - - if (freq_table[old_index].frequency == CPUFREQ_TABLE_END) { + if (cpufreq_frequency_table_target(policy, freq_table, + freqs.old, relation, &old_index)) { ret = -EINVAL; goto out; } diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c index d6a533e68e0f..d90519cec880 100644 --- a/trunk/drivers/cpuidle/cpuidle.c +++ b/trunk/drivers/cpuidle/cpuidle.c @@ -201,22 +201,6 @@ void cpuidle_resume_and_unlock(void) EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); -/* Currently used in suspend/resume path to suspend cpuidle */ -void cpuidle_pause(void) -{ - mutex_lock(&cpuidle_lock); - cpuidle_uninstall_idle_handler(); - mutex_unlock(&cpuidle_lock); -} - -/* Currently used in suspend/resume path to resume cpuidle */ -void cpuidle_resume(void) -{ - mutex_lock(&cpuidle_lock); - cpuidle_install_idle_handler(); - mutex_unlock(&cpuidle_lock); -} - /** * cpuidle_wrap_enter - performs timekeeping and irqen around enter function * @dev: pointer to a valid cpuidle_device object @@ -281,7 +265,7 @@ static void poll_idle_init(struct cpuidle_driver *drv) state->power_usage = -1; state->flags = 0; state->enter = poll_idle; - state->disabled = false; + state->disable = 0; } #else static void poll_idle_init(struct cpuidle_driver *drv) {} diff --git a/trunk/drivers/cpuidle/driver.c b/trunk/drivers/cpuidle/driver.c index 58bf3b1ac9c4..40cd3f3024df 100644 --- a/trunk/drivers/cpuidle/driver.c +++ b/trunk/drivers/cpuidle/driver.c @@ -16,7 +16,6 @@ static struct cpuidle_driver *cpuidle_curr_driver; DEFINE_SPINLOCK(cpuidle_driver_lock); -int cpuidle_driver_refcount; static void __cpuidle_register_driver(struct cpuidle_driver *drv) { @@ -90,34 +89,8 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv) } spin_lock(&cpuidle_driver_lock); - - if (!WARN_ON(cpuidle_driver_refcount > 0)) - cpuidle_curr_driver = NULL; - + cpuidle_curr_driver = NULL; spin_unlock(&cpuidle_driver_lock); } EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); - -struct cpuidle_driver *cpuidle_driver_ref(void) -{ - struct cpuidle_driver *drv; - - spin_lock(&cpuidle_driver_lock); - - drv = cpuidle_curr_driver; - cpuidle_driver_refcount++; - - spin_unlock(&cpuidle_driver_lock); - return drv; -} - -void cpuidle_driver_unref(void) -{ - spin_lock(&cpuidle_driver_lock); - - if (!WARN_ON(cpuidle_driver_refcount <= 0)) - cpuidle_driver_refcount--; - - spin_unlock(&cpuidle_driver_lock); -} diff --git a/trunk/drivers/cpuidle/governors/menu.c b/trunk/drivers/cpuidle/governors/menu.c index 5b1f2c372c1f..06335756ea14 100644 --- a/trunk/drivers/cpuidle/governors/menu.c +++ b/trunk/drivers/cpuidle/governors/menu.c @@ -281,8 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) * unless the timer is happening really really soon. */ if (data->expected_us > 5 && - !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && - dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) + drv->states[CPUIDLE_DRIVER_STATE_START].disable == 0) data->last_state_idx = CPUIDLE_DRIVER_STATE_START; /* @@ -291,9 +290,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) */ for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { struct cpuidle_state *s = &drv->states[i]; - struct cpuidle_state_usage *su = &dev->states_usage[i]; - if (s->disabled || su->disable) + if (s->disable) continue; if (s->target_residency > data->predicted_us) continue; diff --git a/trunk/drivers/cpuidle/sysfs.c b/trunk/drivers/cpuidle/sysfs.c index 5f809e337b89..88032b4dc6d2 100644 --- a/trunk/drivers/cpuidle/sysfs.c +++ b/trunk/drivers/cpuidle/sysfs.c @@ -217,8 +217,7 @@ struct cpuidle_state_attr { struct attribute attr; ssize_t (*show)(struct cpuidle_state *, \ struct cpuidle_state_usage *, char *); - ssize_t (*store)(struct cpuidle_state *, \ - struct cpuidle_state_usage *, const char *, size_t); + ssize_t (*store)(struct cpuidle_state *, const char *, size_t); }; #define define_one_state_ro(_name, show) \ @@ -234,22 +233,21 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \ return sprintf(buf, "%u\n", state->_name);\ } -#define define_store_state_ull_function(_name) \ +#define define_store_state_function(_name) \ static ssize_t store_state_##_name(struct cpuidle_state *state, \ - struct cpuidle_state_usage *state_usage, \ const char *buf, size_t size) \ { \ - unsigned long long value; \ + long value; \ int err; \ if (!capable(CAP_SYS_ADMIN)) \ return -EPERM; \ - err = kstrtoull(buf, 0, &value); \ + err = kstrtol(buf, 0, &value); \ if (err) \ return err; \ if (value) \ - state_usage->_name = 1; \ + state->disable = 1; \ else \ - state_usage->_name = 0; \ + state->disable = 0; \ return size; \ } @@ -275,8 +273,8 @@ define_show_state_ull_function(usage) define_show_state_ull_function(time) define_show_state_str_function(name) define_show_state_str_function(desc) -define_show_state_ull_function(disable) -define_store_state_ull_function(disable) +define_show_state_function(disable) +define_store_state_function(disable) define_one_state_ro(name, show_state_name); define_one_state_ro(desc, show_state_desc); @@ -320,11 +318,10 @@ static ssize_t cpuidle_state_store(struct kobject *kobj, { int ret = -EIO; struct cpuidle_state *state = kobj_to_state(kobj); - struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj); struct cpuidle_state_attr *cattr = attr_to_stateattr(attr); if (cattr->store) - ret = cattr->store(state, state_usage, buf, size); + ret = cattr->store(state, buf, size); return ret; } diff --git a/trunk/drivers/crypto/ux500/cryp/cryp_core.c b/trunk/drivers/crypto/ux500/cryp/cryp_core.c index 1c307e1b840c..7cac12793a4b 100644 --- a/trunk/drivers/crypto/ux500/cryp/cryp_core.c +++ b/trunk/drivers/crypto/ux500/cryp/cryp_core.c @@ -1661,26 +1661,27 @@ static void ux500_cryp_shutdown(struct platform_device *pdev) } -static int ux500_cryp_suspend(struct device *dev) +static int ux500_cryp_suspend(struct platform_device *pdev, pm_message_t state) { int ret; - struct platform_device *pdev = to_platform_device(dev); struct cryp_device_data *device_data; struct resource *res_irq; struct cryp_ctx *temp_ctx = NULL; - dev_dbg(dev, "[%s]", __func__); + dev_dbg(&pdev->dev, "[%s]", __func__); /* Handle state? */ device_data = platform_get_drvdata(pdev); if (!device_data) { - dev_err(dev, "[%s]: platform_get_drvdata() failed!", __func__); + dev_err(&pdev->dev, "[%s]: platform_get_drvdata() failed!", + __func__); return -ENOMEM; } res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res_irq) - dev_err(dev, "[%s]: IORESOURCE_IRQ, unavailable", __func__); + dev_err(&pdev->dev, "[%s]: IORESOURCE_IRQ, unavailable", + __func__); else disable_irq(res_irq->start); @@ -1691,32 +1692,32 @@ static int ux500_cryp_suspend(struct device *dev) if (device_data->current_ctx == ++temp_ctx) { if (down_interruptible(&driver_data.device_allocation)) - dev_dbg(dev, "[%s]: down_interruptible() failed", - __func__); - ret = cryp_disable_power(dev, device_data, false); + dev_dbg(&pdev->dev, "[%s]: down_interruptible() " + "failed", __func__); + ret = cryp_disable_power(&pdev->dev, device_data, false); } else - ret = cryp_disable_power(dev, device_data, true); + ret = cryp_disable_power(&pdev->dev, device_data, true); if (ret) - dev_err(dev, "[%s]: cryp_disable_power()", __func__); + dev_err(&pdev->dev, "[%s]: cryp_disable_power()", __func__); return ret; } -static int ux500_cryp_resume(struct device *dev) +static int ux500_cryp_resume(struct platform_device *pdev) { int ret = 0; - struct platform_device *pdev = to_platform_device(dev); struct cryp_device_data *device_data; struct resource *res_irq; struct cryp_ctx *temp_ctx = NULL; - dev_dbg(dev, "[%s]", __func__); + dev_dbg(&pdev->dev, "[%s]", __func__); device_data = platform_get_drvdata(pdev); if (!device_data) { - dev_err(dev, "[%s]: platform_get_drvdata() failed!", __func__); + dev_err(&pdev->dev, "[%s]: platform_get_drvdata() failed!", + __func__); return -ENOMEM; } @@ -1729,10 +1730,11 @@ static int ux500_cryp_resume(struct device *dev) if (!device_data->current_ctx) up(&driver_data.device_allocation); else - ret = cryp_enable_power(dev, device_data, true); + ret = cryp_enable_power(&pdev->dev, device_data, true); if (ret) - dev_err(dev, "[%s]: cryp_enable_power() failed!", __func__); + dev_err(&pdev->dev, "[%s]: cryp_enable_power() failed!", + __func__); else { res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) @@ -1742,16 +1744,15 @@ static int ux500_cryp_resume(struct device *dev) return ret; } -static SIMPLE_DEV_PM_OPS(ux500_cryp_pm, ux500_cryp_suspend, ux500_cryp_resume); - static struct platform_driver cryp_driver = { .probe = ux500_cryp_probe, .remove = ux500_cryp_remove, .shutdown = ux500_cryp_shutdown, + .suspend = ux500_cryp_suspend, + .resume = ux500_cryp_resume, .driver = { .owner = THIS_MODULE, .name = "cryp1" - .pm = &ux500_cryp_pm, } }; diff --git a/trunk/drivers/crypto/ux500/hash/hash_core.c b/trunk/drivers/crypto/ux500/hash/hash_core.c index 08d5032cb564..6dbb9ec709a3 100644 --- a/trunk/drivers/crypto/ux500/hash/hash_core.c +++ b/trunk/drivers/crypto/ux500/hash/hash_core.c @@ -1894,17 +1894,19 @@ static void ux500_hash_shutdown(struct platform_device *pdev) /** * ux500_hash_suspend - Function that suspends the hash device. - * @dev: Device to suspend. + * @pdev: The platform device. + * @state: - */ -static int ux500_hash_suspend(struct device *dev) +static int ux500_hash_suspend(struct platform_device *pdev, pm_message_t state) { int ret; struct hash_device_data *device_data; struct hash_ctx *temp_ctx = NULL; - device_data = dev_get_drvdata(dev); + device_data = platform_get_drvdata(pdev); if (!device_data) { - dev_err(dev, "[%s] platform_get_drvdata() failed!", __func__); + dev_err(&pdev->dev, "[%s] platform_get_drvdata() failed!", + __func__); return -ENOMEM; } @@ -1915,32 +1917,33 @@ static int ux500_hash_suspend(struct device *dev) if (device_data->current_ctx == ++temp_ctx) { if (down_interruptible(&driver_data.device_allocation)) - dev_dbg(dev, "[%s]: down_interruptible() failed", - __func__); + dev_dbg(&pdev->dev, "[%s]: down_interruptible() " + "failed", __func__); ret = hash_disable_power(device_data, false); } else ret = hash_disable_power(device_data, true); if (ret) - dev_err(dev, "[%s]: hash_disable_power()", __func__); + dev_err(&pdev->dev, "[%s]: hash_disable_power()", __func__); return ret; } /** * ux500_hash_resume - Function that resume the hash device. - * @dev: Device to resume. + * @pdev: The platform device. */ -static int ux500_hash_resume(struct device *dev) +static int ux500_hash_resume(struct platform_device *pdev) { int ret = 0; struct hash_device_data *device_data; struct hash_ctx *temp_ctx = NULL; - device_data = dev_get_drvdata(dev); + device_data = platform_get_drvdata(pdev); if (!device_data) { - dev_err(dev, "[%s] platform_get_drvdata() failed!", __func__); + dev_err(&pdev->dev, "[%s] platform_get_drvdata() failed!", + __func__); return -ENOMEM; } @@ -1955,21 +1958,21 @@ static int ux500_hash_resume(struct device *dev) ret = hash_enable_power(device_data, true); if (ret) - dev_err(dev, "[%s]: hash_enable_power() failed!", __func__); + dev_err(&pdev->dev, "[%s]: hash_enable_power() failed!", + __func__); return ret; } -static SIMPLE_DEV_PM_OPS(ux500_hash_pm, ux500_hash_suspend, ux500_hash_resume); - static struct platform_driver hash_driver = { .probe = ux500_hash_probe, .remove = ux500_hash_remove, .shutdown = ux500_hash_shutdown, + .suspend = ux500_hash_suspend, + .resume = ux500_hash_resume, .driver = { .owner = THIS_MODULE, .name = "hash1", - .pm = &ux500_hash_pm, } }; diff --git a/trunk/drivers/dma/dw_dmac.c b/trunk/drivers/dma/dw_dmac.c index 721296157577..e23dc82d43ac 100644 --- a/trunk/drivers/dma/dw_dmac.c +++ b/trunk/drivers/dma/dw_dmac.c @@ -1626,4 +1626,4 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/trunk/drivers/dma/imx-sdma.c b/trunk/drivers/dma/imx-sdma.c index 1dc2a4ad0026..fb4f4990f5eb 100644 --- a/trunk/drivers/dma/imx-sdma.c +++ b/trunk/drivers/dma/imx-sdma.c @@ -815,6 +815,8 @@ static int sdma_request_channel(struct sdma_channel *sdmac) init_completion(&sdmac->done); + sdmac->buf_tail = 0; + return 0; out: @@ -925,8 +927,6 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( sdmac->flags = 0; - sdmac->buf_tail = 0; - dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n", sg_len, channel); @@ -1027,8 +1027,6 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( sdmac->status = DMA_IN_PROGRESS; - sdmac->buf_tail = 0; - sdmac->flags |= IMX_DMA_SG_LOOP; sdmac->direction = direction; ret = sdma_load_context(sdmac); diff --git a/trunk/drivers/dma/pl330.c b/trunk/drivers/dma/pl330.c index e4feba6b03c0..cbcc28e79be6 100644 --- a/trunk/drivers/dma/pl330.c +++ b/trunk/drivers/dma/pl330.c @@ -392,8 +392,6 @@ struct pl330_req { struct pl330_reqcfg *cfg; /* Pointer to first xfer in the request. */ struct pl330_xfer *x; - /* Hook to attach to DMAC's list of reqs with due callback */ - struct list_head rqd; }; /* @@ -463,6 +461,8 @@ struct _pl330_req { /* Number of bytes taken to setup MC for the req */ u32 mc_len; struct pl330_req *r; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; }; /* ToBeDone for tasklet */ @@ -1683,7 +1683,7 @@ static void pl330_dotask(unsigned long data) /* Returns 1 if state was updated, 0 otherwise */ static int pl330_update(const struct pl330_info *pi) { - struct pl330_req *rqdone, *tmp; + struct _pl330_req *rqdone; struct pl330_dmac *pl330; unsigned long flags; void __iomem *regs; @@ -1750,10 +1750,7 @@ static int pl330_update(const struct pl330_info *pi) if (active == -1) /* Aborted */ continue; - /* Detach the req */ - rqdone = thrd->req[active].r; - thrd->req[active].r = NULL; - + rqdone = &thrd->req[active]; mark_free(thrd, active); /* Get going again ASAP */ @@ -1765,11 +1762,20 @@ static int pl330_update(const struct pl330_info *pi) } /* Now that we are in no hurry, do the callbacks */ - list_for_each_entry_safe(rqdone, tmp, &pl330->req_done, rqd) { - list_del(&rqdone->rqd); + while (!list_empty(&pl330->req_done)) { + struct pl330_req *r; + + rqdone = container_of(pl330->req_done.next, + struct _pl330_req, rqd); + + list_del_init(&rqdone->rqd); + + /* Detach the req */ + r = rqdone->r; + rqdone->r = NULL; spin_unlock_irqrestore(&pl330->lock, flags); - _callback(rqdone, PL330_ERR_NONE); + _callback(r, PL330_ERR_NONE); spin_lock_irqsave(&pl330->lock, flags); } @@ -2315,7 +2321,7 @@ static void pl330_tasklet(unsigned long data) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - if (!pch->cyclic) + if (pch->cyclic) dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); } @@ -2533,7 +2539,7 @@ static inline void _init_desc(struct dma_pl330_desc *desc) } /* Returns the number of descriptors added to the DMAC pool */ -static int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) { struct dma_pl330_desc *desc; unsigned long flags; diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index de5ba86e8b89..10f375032e96 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -164,7 +164,7 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) else return (char *)ptr; - r = (unsigned long)p % align; + r = size % align; if (r == 0) return (char *)ptr; diff --git a/trunk/drivers/edac/i7core_edac.c b/trunk/drivers/edac/i7core_edac.c index a499c7ed820a..d27778f65a5d 100644 --- a/trunk/drivers/edac/i7core_edac.c +++ b/trunk/drivers/edac/i7core_edac.c @@ -1814,6 +1814,12 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, if (mce->bank != 8) return NOTIFY_DONE; +#ifdef CONFIG_SMP + /* Only handle if it is the right mc controller */ + if (mce->socketid != pvt->i7core_dev->socket) + return NOTIFY_DONE; +#endif + smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { smp_wmb(); @@ -2110,6 +2116,8 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev) if (pvt->enable_scrub) disable_sdram_scrub_setting(mci); + mce_unregister_decode_chain(&i7_mce_dec); + /* Disable EDAC polling */ i7core_pci_ctl_release(pvt); @@ -2214,6 +2222,8 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev) /* DCLK for scrub rate setting */ pvt->dclk_freq = get_dclk_freq(); + mce_register_decode_chain(&i7_mce_dec); + return 0; fail0: @@ -2357,10 +2367,8 @@ static int __init i7core_init(void) pci_rc = pci_register_driver(&i7core_driver); - if (pci_rc >= 0) { - mce_register_decode_chain(&i7_mce_dec); + if (pci_rc >= 0) return 0; - } i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -2376,7 +2384,6 @@ static void __exit i7core_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&i7core_driver); - mce_unregister_decode_chain(&i7_mce_dec); } module_init(i7core_init); diff --git a/trunk/drivers/edac/mpc85xx_edac.c b/trunk/drivers/edac/mpc85xx_edac.c index 0e374625f6f8..4c402353ba98 100644 --- a/trunk/drivers/edac/mpc85xx_edac.c +++ b/trunk/drivers/edac/mpc85xx_edac.c @@ -980,8 +980,7 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = 1; layers[1].is_virt_csrow = false; - mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers, - sizeof(*pdata)); + mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), sizeof(*pdata)); if (!mci) { devres_release_group(&op->dev, mpc85xx_mc_err_probe); return -ENOMEM; diff --git a/trunk/drivers/edac/sb_edac.c b/trunk/drivers/edac/sb_edac.c index 36ad17e79d61..4adaf4b7da99 100644 --- a/trunk/drivers/edac/sb_edac.c +++ b/trunk/drivers/edac/sb_edac.c @@ -555,7 +555,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->is_close_pg = false; } - pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); + pci_read_config_dword(pvt->pci_ta, RANK_CFG_A, ®); if (IS_RDIMM_ENABLED(reg)) { /* FIXME: Can also be LRDIMM */ debugf0("Memory is registered\n"); @@ -1604,6 +1604,8 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", __func__, mci, &sbridge_dev->pdev[0]->dev); + mce_unregister_decode_chain(&sbridge_mce_dec); + /* Remove MC sysfs nodes */ edac_mc_del_mc(mci->dev); @@ -1680,6 +1682,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev) goto fail0; } + mce_register_decode_chain(&sbridge_mce_dec); return 0; fail0: @@ -1808,10 +1811,8 @@ static int __init sbridge_init(void) pci_rc = pci_register_driver(&sbridge_driver); - if (pci_rc >= 0) { - mce_register_decode_chain(&sbridge_mce_dec); + if (pci_rc >= 0) return 0; - } sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -1827,7 +1828,6 @@ static void __exit sbridge_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&sbridge_driver); - mce_unregister_decode_chain(&sbridge_mce_dec); } module_init(sbridge_init); diff --git a/trunk/drivers/extcon/extcon-max8997.c b/trunk/drivers/extcon/extcon-max8997.c index a4ed30bd9a41..23416e443765 100644 --- a/trunk/drivers/extcon/extcon-max8997.c +++ b/trunk/drivers/extcon/extcon-max8997.c @@ -116,8 +116,8 @@ const char *max8997_extcon_cable[] = { [5] = "Charge-downstream", [6] = "MHL", [7] = "Dock-desk", - [8] = "Dock-card", - [9] = "JIG", + [7] = "Dock-card", + [8] = "JIG", NULL, }; @@ -514,7 +514,6 @@ static int __devexit max8997_muic_remove(struct platform_device *pdev) extcon_dev_unregister(info->edev); - kfree(info->edev); kfree(info); return 0; diff --git a/trunk/drivers/extcon/extcon_class.c b/trunk/drivers/extcon/extcon_class.c index 159aeb07b3ba..f598a700ec15 100644 --- a/trunk/drivers/extcon/extcon_class.c +++ b/trunk/drivers/extcon/extcon_class.c @@ -762,7 +762,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev) #if defined(CONFIG_ANDROID) if (switch_class) ret = class_compat_create_link(switch_class, edev->dev, - NULL); + dev); #endif /* CONFIG_ANDROID */ spin_lock_init(&edev->lock); diff --git a/trunk/drivers/extcon/extcon_gpio.c b/trunk/drivers/extcon/extcon_gpio.c index 8a0dcc11c7c7..fe7a07b47336 100644 --- a/trunk/drivers/extcon/extcon_gpio.c +++ b/trunk/drivers/extcon/extcon_gpio.c @@ -125,7 +125,6 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) goto err_request_irq; - platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ gpio_extcon_work(&extcon_data->work.work); @@ -147,7 +146,6 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); - free_irq(extcon_data->irq, extcon_data); gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); devm_kfree(&pdev->dev, extcon_data); diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 542f0c04b695..c4067d0141f7 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -136,7 +136,7 @@ config GPIO_MPC8XXX config GPIO_MSM_V1 tristate "Qualcomm MSM GPIO v1" - depends on GPIOLIB && ARCH_MSM && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50) + depends on GPIOLIB && ARCH_MSM help Say yes here to support the GPIO interface on ARM v6 based Qualcomm MSM chips. Most of the pins on the MSM can be diff --git a/trunk/drivers/gpio/devres.c b/trunk/drivers/gpio/devres.c index 1077754f8289..9e9947cb86a3 100644 --- a/trunk/drivers/gpio/devres.c +++ b/trunk/drivers/gpio/devres.c @@ -98,7 +98,6 @@ int devm_gpio_request_one(struct device *dev, unsigned gpio, return 0; } -EXPORT_SYMBOL(devm_gpio_request_one); /** * devm_gpio_free - free an interrupt diff --git a/trunk/drivers/gpio/gpio-mxc.c b/trunk/drivers/gpio/gpio-mxc.c index c89c4c1e668d..c337143b18f8 100644 --- a/trunk/drivers/gpio/gpio-mxc.c +++ b/trunk/drivers/gpio/gpio-mxc.c @@ -398,12 +398,10 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) writel(~0, port->base + GPIO_ISR); if (mxc_gpio_hwtype == IMX21_GPIO) { - /* - * Setup one handler for all GPIO interrupts. Actually setting - * the handler is needed only once, but doing it for every port - * is more robust and easier. - */ - irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); + /* setup one handler for all GPIO interrupts */ + if (pdev->id == 0) + irq_set_chained_handler(port->irq, + mx2_gpio_irq_handler); } else { /* setup one handler for each entry */ irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); diff --git a/trunk/drivers/gpio/gpio-omap.c b/trunk/drivers/gpio/gpio-omap.c index 4fbc208c32cf..c4ed1722734c 100644 --- a/trunk/drivers/gpio/gpio-omap.c +++ b/trunk/drivers/gpio/gpio-omap.c @@ -174,22 +174,12 @@ static inline void _gpio_dbck_enable(struct gpio_bank *bank) if (bank->dbck_enable_mask && !bank->dbck_enabled) { clk_enable(bank->dbck); bank->dbck_enabled = true; - - __raw_writel(bank->dbck_enable_mask, - bank->base + bank->regs->debounce_en); } } static inline void _gpio_dbck_disable(struct gpio_bank *bank) { if (bank->dbck_enable_mask && bank->dbck_enabled) { - /* - * Disable debounce before cutting it's clock. If debounce is - * enabled but the clock is not, GPIO module seems to be unable - * to detect events and generate interrupts at least on OMAP3. - */ - __raw_writel(0, bank->base + bank->regs->debounce_en); - clk_disable(bank->dbck); bank->dbck_enabled = false; } @@ -1091,6 +1081,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank->is_mpuio = pdata->is_mpuio; bank->non_wakeup_gpios = pdata->non_wakeup_gpios; bank->loses_context = pdata->loses_context; + bank->get_context_loss_count = pdata->get_context_loss_count; bank->regs = pdata->regs; #ifdef CONFIG_OF_GPIO bank->chip.of_node = of_node_get(node); @@ -1144,9 +1135,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) omap_gpio_chip_init(bank); omap_gpio_show_rev(bank); - if (bank->loses_context) - bank->get_context_loss_count = pdata->get_context_loss_count; - pm_runtime_put(bank->dev); list_add_tail(&bank->node, &omap_gpio_list); diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index b6453d0e44ad..7bb00448e13d 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -2833,7 +2833,7 @@ static __init void exynos5_gpiolib_init(void) } /* need to set base address for gpc4 */ - exynos5_gpios_1[11].base = gpio_base1 + 0x2E0; + exonys5_gpios_1[11].base = gpio_base1 + 0x2E0; /* need to set base address for gpx */ chip = &exynos5_gpios_1[21]; diff --git a/trunk/drivers/gpio/gpio-sta2x11.c b/trunk/drivers/gpio/gpio-sta2x11.c index 6064fb376e11..38416be8ba11 100644 --- a/trunk/drivers/gpio/gpio-sta2x11.c +++ b/trunk/drivers/gpio/gpio-sta2x11.c @@ -383,9 +383,8 @@ static int __devinit gsta_probe(struct platform_device *dev) } spin_lock_init(&chip->lock); gsta_gpio_setup(chip); - if (gpio_pdata) - for (i = 0; i < GSTA_NR_GPIO; i++) - gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); + for (i = 0; i < GSTA_NR_GPIO; i++) + gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); /* 384 was used in previous code: be compatible for other drivers */ err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); diff --git a/trunk/drivers/gpio/gpio-tps65910.c b/trunk/drivers/gpio/gpio-tps65910.c index 11f29c82253c..c1ad2884f2ed 100644 --- a/trunk/drivers/gpio/gpio-tps65910.c +++ b/trunk/drivers/gpio/gpio-tps65910.c @@ -149,9 +149,6 @@ static int __devinit tps65910_gpio_probe(struct platform_device *pdev) tps65910_gpio->gpio_chip.set = tps65910_gpio_set; tps65910_gpio->gpio_chip.get = tps65910_gpio_get; tps65910_gpio->gpio_chip.dev = &pdev->dev; -#ifdef CONFIG_OF_GPIO - tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node; -#endif if (pdata && pdata->gpio_base) tps65910_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/trunk/drivers/gpio/gpio-wm8994.c b/trunk/drivers/gpio/gpio-wm8994.c index aa61ad2fcaaa..92ea5350dfe9 100644 --- a/trunk/drivers/gpio/gpio-wm8994.c +++ b/trunk/drivers/gpio/gpio-wm8994.c @@ -89,11 +89,8 @@ static int wm8994_gpio_direction_out(struct gpio_chip *chip, struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; - if (value) - value = WM8994_GPN_LVL; - return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, - WM8994_GPN_DIR | WM8994_GPN_LVL, value); + WM8994_GPN_DIR, 0); } static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index a8743c399e83..eb92fe257a39 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -610,7 +610,7 @@ static bool drm_monitor_supports_rb(struct edid *edid) { if (edid->revision >= 4) { - bool ret = false; + bool ret; drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); return ret; } @@ -1039,24 +1039,6 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid, return true; } -static bool valid_inferred_mode(const struct drm_connector *connector, - const struct drm_display_mode *mode) -{ - struct drm_display_mode *m; - bool ok = false; - - list_for_each_entry(m, &connector->probed_modes, head) { - if (mode->hdisplay == m->hdisplay && - mode->vdisplay == m->vdisplay && - drm_mode_vrefresh(mode) == drm_mode_vrefresh(m)) - return false; /* duplicated */ - if (mode->hdisplay <= m->hdisplay && - mode->vdisplay <= m->vdisplay) - ok = true; - } - return ok; -} - static int drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, struct detailed_timing *timing) @@ -1066,8 +1048,7 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, struct drm_device *dev = connector->dev; for (i = 0; i < drm_num_dmt_modes; i++) { - if (mode_in_range(drm_dmt_modes + i, edid, timing) && - valid_inferred_mode(connector, drm_dmt_modes + i)) { + if (mode_in_range(drm_dmt_modes + i, edid, timing)) { newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); if (newmode) { drm_mode_probed_add(connector, newmode); @@ -1107,8 +1088,7 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, return modes; fixup_mode_1366x768(newmode); - if (!mode_in_range(newmode, edid, timing) || - !valid_inferred_mode(connector, newmode)) { + if (!mode_in_range(newmode, edid, timing)) { drm_mode_destroy(dev, newmode); continue; } @@ -1136,8 +1116,7 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, return modes; fixup_mode_1366x768(newmode); - if (!mode_in_range(newmode, edid, timing) || - !valid_inferred_mode(connector, newmode)) { + if (!mode_in_range(newmode, edid, timing)) { drm_mode_destroy(dev, newmode); continue; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c index d6de2e07fa03..420953197d0a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -244,8 +244,8 @@ static const struct file_operations exynos_drm_driver_fops = { }; static struct drm_driver exynos_drm_driver = { - .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | - DRIVER_GEM | DRIVER_PRIME, + .driver_features = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM | + DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, .load = exynos_drm_load, .unload = exynos_drm_unload, .open = exynos_drm_open, diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 23d5ad379f86..6e9ac7bd1dcf 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -172,12 +172,19 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) manager_ops->commit(manager->dev); } +static struct drm_crtc * +exynos_drm_encoder_get_crtc(struct drm_encoder *encoder) +{ + return encoder->crtc; +} + static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { .dpms = exynos_drm_encoder_dpms, .mode_fixup = exynos_drm_encoder_mode_fixup, .mode_set = exynos_drm_encoder_mode_set, .prepare = exynos_drm_encoder_prepare, .commit = exynos_drm_encoder_commit, + .get_crtc = exynos_drm_encoder_get_crtc, }; static void exynos_drm_encoder_destroy(struct drm_encoder *encoder) diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c index 4ccfe4328fab..f82a299553fb 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -51,22 +51,11 @@ struct exynos_drm_fb { static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) { struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - unsigned int i; DRM_DEBUG_KMS("%s\n", __FILE__); drm_framebuffer_cleanup(fb); - for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) { - struct drm_gem_object *obj; - - if (exynos_fb->exynos_gem_obj[i] == NULL) - continue; - - obj = &exynos_fb->exynos_gem_obj[i]->base; - drm_gem_object_unreference_unlocked(obj); - } - kfree(exynos_fb); exynos_fb = NULL; } @@ -145,11 +134,11 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, return ERR_PTR(-ENOENT); } + drm_gem_object_unreference_unlocked(obj); + fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj); - if (IS_ERR(fb)) { - drm_gem_object_unreference_unlocked(obj); + if (IS_ERR(fb)) return fb; - } exynos_fb = to_exynos_fb(fb); nr = exynos_drm_format_num_buffers(fb->pixel_format); @@ -163,6 +152,8 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, return ERR_PTR(-ENOENT); } + drm_gem_object_unreference_unlocked(obj); + exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h index 50823756cdea..3ecb30d93552 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h @@ -31,10 +31,10 @@ static inline int exynos_drm_format_num_buffers(uint32_t format) { switch (format) { - case DRM_FORMAT_NV12: + case DRM_FORMAT_NV12M: case DRM_FORMAT_NV12MT: return 2; - case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV420M: return 3; default: return 1; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c index 5c8b683029ea..fc91293c4560 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -689,6 +689,7 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset) { + struct exynos_drm_gem_obj *exynos_gem_obj; struct drm_gem_object *obj; int ret = 0; @@ -709,13 +710,15 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, goto unlock; } - if (!obj->map_list.map) { - ret = drm_gem_create_mmap_offset(obj); + exynos_gem_obj = to_exynos_gem_obj(obj); + + if (!exynos_gem_obj->base.map_list.map) { + ret = drm_gem_create_mmap_offset(&exynos_gem_obj->base); if (ret) goto out; } - *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; + *offset = (u64)exynos_gem_obj->base.map_list.hash.key << PAGE_SHIFT; DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); out: diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index e2147a2ddcec..68ef01028375 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -365,7 +365,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) switch (win_data->pixel_format) { case DRM_FORMAT_NV12MT: tiled_mode = true; - case DRM_FORMAT_NV12: + case DRM_FORMAT_NV12M: crcb_mode = false; buf_num = 2; break; @@ -601,19 +601,17 @@ static void mixer_win_reset(struct mixer_context *ctx) mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); /* setting graphical layers */ + val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ val |= MXR_GRP_CFG_WIN_BLEND_EN; - val |= MXR_GRP_CFG_BLEND_PRE_MUL; - val |= MXR_GRP_CFG_PIXEL_BLEND_EN; val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ /* the same configuration for both layers */ mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); - mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); - /* setting video layers */ - val = MXR_GRP_CFG_ALPHA_VAL(0); - mixer_reg_write(res, MXR_VIDEO_CFG, val); + val |= MXR_GRP_CFG_BLEND_PRE_MUL; + val |= MXR_GRP_CFG_PIXEL_BLEND_EN; + mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); /* configuration of Video Processor Registers */ vp_win_reset(ctx); diff --git a/trunk/drivers/gpu/drm/gma500/cdv_device.c b/trunk/drivers/gpu/drm/gma500/cdv_device.c index b7e7b49d8f62..9764045428ce 100644 --- a/trunk/drivers/gpu/drm/gma500/cdv_device.c +++ b/trunk/drivers/gpu/drm/gma500/cdv_device.c @@ -78,6 +78,21 @@ static int cdv_backlight_combination_mode(struct drm_device *dev) return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE; } +static int cdv_get_brightness(struct backlight_device *bd) +{ + struct drm_device *dev = bl_get_data(bd); + u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + + if (cdv_backlight_combination_mode(dev)) { + u8 lbpc; + + val &= ~1; + pci_read_config_byte(dev->pdev, 0xF4, &lbpc); + val *= lbpc; + } + return val; +} + static u32 cdv_get_max_backlight(struct drm_device *dev) { u32 max = REG_READ(BLC_PWM_CTL); @@ -95,22 +110,6 @@ static u32 cdv_get_max_backlight(struct drm_device *dev) return max; } -static int cdv_get_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(bd); - u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - - if (cdv_backlight_combination_mode(dev)) { - u8 lbpc; - - val &= ~1; - pci_read_config_byte(dev->pdev, 0xF4, &lbpc); - val *= lbpc; - } - return (val * 100)/cdv_get_max_backlight(dev); - -} - static int cdv_set_brightness(struct backlight_device *bd) { struct drm_device *dev = bl_get_data(bd); @@ -121,9 +120,6 @@ static int cdv_set_brightness(struct backlight_device *bd) if (level < 1) level = 1; - level *= cdv_get_max_backlight(dev); - level /= 100; - if (cdv_backlight_combination_mode(dev)) { u32 max = cdv_get_max_backlight(dev); u8 lbpc; @@ -161,6 +157,7 @@ static int cdv_backlight_init(struct drm_device *dev) cdv_backlight_device->props.brightness = cdv_get_brightness(cdv_backlight_device); + cdv_backlight_device->props.max_brightness = cdv_get_max_backlight(dev); backlight_update_status(cdv_backlight_device); dev_priv->backlight_device = cdv_backlight_device; return 0; diff --git a/trunk/drivers/gpu/drm/gma500/opregion.c b/trunk/drivers/gpu/drm/gma500/opregion.c index c430bd424681..4f186eca3a30 100644 --- a/trunk/drivers/gpu/drm/gma500/opregion.c +++ b/trunk/drivers/gpu/drm/gma500/opregion.c @@ -144,8 +144,6 @@ struct opregion_asle { #define ASLE_CBLV_VALID (1<<31) -static struct psb_intel_opregion *system_opregion; - static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) { struct drm_psb_private *dev_priv = dev->dev_private; @@ -207,7 +205,7 @@ void psb_intel_opregion_enable_asle(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; struct opregion_asle *asle = dev_priv->opregion.asle; - if (asle && system_opregion ) { + if (asle) { /* Don't do this on Medfield or other non PC like devices, they use the bit for something different altogether */ psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); @@ -223,6 +221,7 @@ void psb_intel_opregion_enable_asle(struct drm_device *dev) #define ACPI_EV_LID (1<<1) #define ACPI_EV_DOCK (1<<2) +static struct psb_intel_opregion *system_opregion; static int psb_intel_opregion_video_event(struct notifier_block *nb, unsigned long val, void *data) @@ -267,6 +266,9 @@ void psb_intel_opregion_init(struct drm_device *dev) system_opregion = opregion; register_acpi_notifier(&psb_intel_opregion_notifier); } + + if (opregion->asle) + psb_intel_opregion_enable_asle(dev); } void psb_intel_opregion_fini(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/gma500/opregion.h b/trunk/drivers/gpu/drm/gma500/opregion.h index 4a90f8b0e16c..72dc6b921265 100644 --- a/trunk/drivers/gpu/drm/gma500/opregion.h +++ b/trunk/drivers/gpu/drm/gma500/opregion.h @@ -27,7 +27,6 @@ extern void psb_intel_opregion_asle_intr(struct drm_device *dev); extern void psb_intel_opregion_init(struct drm_device *dev); extern void psb_intel_opregion_fini(struct drm_device *dev); extern int psb_intel_opregion_setup(struct drm_device *dev); -extern void psb_intel_opregion_enable_asle(struct drm_device *dev); #else @@ -47,8 +46,4 @@ extern inline int psb_intel_opregion_setup(struct drm_device *dev) { return 0; } - -extern inline void psb_intel_opregion_enable_asle(struct drm_device *dev) -{ -} #endif diff --git a/trunk/drivers/gpu/drm/gma500/psb_device.c b/trunk/drivers/gpu/drm/gma500/psb_device.c index 5971bc82b765..eff039bf92d4 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_device.c +++ b/trunk/drivers/gpu/drm/gma500/psb_device.c @@ -144,10 +144,6 @@ static int psb_backlight_init(struct drm_device *dev) psb_backlight_device->props.max_brightness = 100; backlight_update_status(psb_backlight_device); dev_priv->backlight_device = psb_backlight_device; - - /* This must occur after the backlight is properly initialised */ - psb_lid_timer_init(dev_priv); - return 0; } @@ -358,6 +354,13 @@ static int psb_chip_setup(struct drm_device *dev) return 0; } +/* Not exactly an erratum more an irritation */ +static void psb_chip_errata(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + psb_lid_timer_init(dev_priv); +} + static void psb_chip_teardown(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; @@ -376,6 +379,7 @@ const struct psb_ops psb_chip_ops = { .sgx_offset = PSB_SGX_OFFSET, .chip_setup = psb_chip_setup, .chip_teardown = psb_chip_teardown, + .errata = psb_chip_errata, .crtc_helper = &psb_intel_helper_funcs, .crtc_funcs = &psb_intel_crtc_funcs, diff --git a/trunk/drivers/gpu/drm/gma500/psb_drv.c b/trunk/drivers/gpu/drm/gma500/psb_drv.c index a8858a907f47..caba6e08693c 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_drv.c +++ b/trunk/drivers/gpu/drm/gma500/psb_drv.c @@ -374,7 +374,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) return ret; - psb_intel_opregion_enable_asle(dev); #if 0 /*enable runtime pm at last*/ pm_runtime_enable(&dev->pdev->dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 36822b924eb1..f94792626b94 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1401,27 +1401,6 @@ i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, } } -static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) -{ - struct apertures_struct *ap; - struct pci_dev *pdev = dev_priv->dev->pdev; - bool primary; - - ap = alloc_apertures(1); - if (!ap) - return; - - ap->ranges[0].base = dev_priv->dev->agp->base; - ap->ranges[0].size = - dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - primary = - pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - - remove_conflicting_framebuffers(ap, "inteldrmfb", primary); - - kfree(ap); -} - /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1467,15 +1446,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } - dev_priv->mm.gtt = intel_gtt_get(); - if (!dev_priv->mm.gtt) { - DRM_ERROR("Failed to initialize GTT\n"); - ret = -ENODEV; - goto put_bridge; - } - - i915_kick_out_firmware_fb(dev_priv); - pci_set_master(dev->pdev); /* overlay on gen2 is broken and can't address above 1G */ @@ -1501,6 +1471,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto put_bridge; } + dev_priv->mm.gtt = intel_gtt_get(); + if (!dev_priv->mm.gtt) { + DRM_ERROR("Failed to initialize GTT\n"); + ret = -ENODEV; + goto out_rmmap; + } + aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; dev_priv->mm.gtt_mapping = diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 9fe9ebe52a7a..238a52165833 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -233,7 +233,6 @@ static const struct intel_device_info intel_sandybridge_d_info = { .has_blt_ring = 1, .has_llc = 1, .has_pch_split = 1, - .has_force_wake = 1, }; static const struct intel_device_info intel_sandybridge_m_info = { @@ -244,7 +243,6 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_blt_ring = 1, .has_llc = 1, .has_pch_split = 1, - .has_force_wake = 1, }; static const struct intel_device_info intel_ivybridge_d_info = { @@ -254,7 +252,6 @@ static const struct intel_device_info intel_ivybridge_d_info = { .has_blt_ring = 1, .has_llc = 1, .has_pch_split = 1, - .has_force_wake = 1, }; static const struct intel_device_info intel_ivybridge_m_info = { @@ -265,7 +262,6 @@ static const struct intel_device_info intel_ivybridge_m_info = { .has_blt_ring = 1, .has_llc = 1, .has_pch_split = 1, - .has_force_wake = 1, }; static const struct intel_device_info intel_valleyview_m_info = { @@ -293,7 +289,6 @@ static const struct intel_device_info intel_haswell_d_info = { .has_blt_ring = 1, .has_llc = 1, .has_pch_split = 1, - .has_force_wake = 1, }; static const struct intel_device_info intel_haswell_m_info = { @@ -303,7 +298,6 @@ static const struct intel_device_info intel_haswell_m_info = { .has_blt_ring = 1, .has_llc = 1, .has_pch_split = 1, - .has_force_wake = 1, }; static const struct pci_device_id pciidlist[] = { /* aka */ @@ -1145,9 +1139,10 @@ MODULE_LICENSE("GPL and additional rights"); /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ - ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ - ((reg) < 0x40000) && \ - ((reg) != FORCEWAKE)) + (((dev_priv)->info->gen >= 6) && \ + ((reg) < 0x40000) && \ + ((reg) != FORCEWAKE)) && \ + (!IS_VALLEYVIEW((dev_priv)->dev)) #define __i915_read(x, y) \ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index b0b676abde0d..c9cfc67c2cf5 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -285,7 +285,6 @@ struct intel_device_info { u8 is_ivybridge:1; u8 is_valleyview:1; u8 has_pch_split:1; - u8 has_force_wake:1; u8 is_haswell:1; u8 has_fbc:1; u8 has_pipe_cxsr:1; @@ -1102,8 +1101,6 @@ struct drm_i915_file_private { #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) -#define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake) - #include "i915_trace.h" /** diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index ed3224c37423..1417660a93ec 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -412,6 +412,7 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, */ spin_lock_irqsave(&dev_priv->rps_lock, flags); + WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); dev_priv->pm_iir |= pm_iir; I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); POSTING_READ(GEN6_PMIMR); @@ -509,7 +510,7 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) return ret; } -static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) +static void pch_irq_handler(struct drm_device *dev, u32 pch_iir) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int pipe; @@ -549,35 +550,6 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); } -static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe; - - if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) - DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", - (pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> - SDE_AUDIO_POWER_SHIFT_CPT); - - if (pch_iir & SDE_AUX_MASK_CPT) - DRM_DEBUG_DRIVER("AUX channel interrupt\n"); - - if (pch_iir & SDE_GMBUS_CPT) - DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n"); - - if (pch_iir & SDE_AUDIO_CP_REQ_CPT) - DRM_DEBUG_DRIVER("Audio CP request interrupt\n"); - - if (pch_iir & SDE_AUDIO_CP_CHG_CPT) - DRM_DEBUG_DRIVER("Audio CP change interrupt\n"); - - if (pch_iir & SDE_FDI_MASK_CPT) - for_each_pipe(pipe) - DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", - pipe_name(pipe), - I915_READ(FDI_RX_IIR(pipe))); -} - static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -619,7 +591,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) if (pch_iir & SDE_HOTPLUG_MASK_CPT) queue_work(dev_priv->wq, &dev_priv->hotplug_work); - cpt_irq_handler(dev, pch_iir); + pch_irq_handler(dev, pch_iir); /* clear PCH hotplug event before clear CPU irq */ I915_WRITE(SDEIIR, pch_iir); @@ -712,10 +684,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) if (de_iir & DE_PCH_EVENT) { if (pch_iir & hotplug_mask) queue_work(dev_priv->wq, &dev_priv->hotplug_work); - if (HAS_PCH_CPT(dev)) - cpt_irq_handler(dev, pch_iir); - else - ibx_irq_handler(dev, pch_iir); + pch_irq_handler(dev, pch_iir); } if (de_iir & DE_PCU_EVENT) { diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 48d5e8e051cf..2d49b9507ed0 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -210,14 +210,6 @@ #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) -/* IVB has funny definitions for which plane to flip. */ -#define MI_DISPLAY_FLIP_IVB_PLANE_A (0 << 19) -#define MI_DISPLAY_FLIP_IVB_PLANE_B (1 << 19) -#define MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19) -#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) -#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) -#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) - #define MI_SET_CONTEXT MI_INSTR(0x18, 0) #define MI_MM_SPACE_GTT (1<<8) #define MI_MM_SPACE_PHYSICAL (0<<8) @@ -3321,7 +3313,7 @@ /* PCH */ -/* south display engine interrupt: IBX */ +/* south display engine interrupt */ #define SDE_AUDIO_POWER_D (1 << 27) #define SDE_AUDIO_POWER_C (1 << 26) #define SDE_AUDIO_POWER_B (1 << 25) @@ -3357,44 +3349,15 @@ #define SDE_TRANSA_CRC_ERR (1 << 1) #define SDE_TRANSA_FIFO_UNDER (1 << 0) #define SDE_TRANS_MASK (0x3f) - -/* south display engine interrupt: CPT/PPT */ -#define SDE_AUDIO_POWER_D_CPT (1 << 31) -#define SDE_AUDIO_POWER_C_CPT (1 << 30) -#define SDE_AUDIO_POWER_B_CPT (1 << 29) -#define SDE_AUDIO_POWER_SHIFT_CPT 29 -#define SDE_AUDIO_POWER_MASK_CPT (7 << 29) -#define SDE_AUXD_CPT (1 << 27) -#define SDE_AUXC_CPT (1 << 26) -#define SDE_AUXB_CPT (1 << 25) -#define SDE_AUX_MASK_CPT (7 << 25) +/* CPT */ +#define SDE_CRT_HOTPLUG_CPT (1 << 19) #define SDE_PORTD_HOTPLUG_CPT (1 << 23) #define SDE_PORTC_HOTPLUG_CPT (1 << 22) #define SDE_PORTB_HOTPLUG_CPT (1 << 21) -#define SDE_CRT_HOTPLUG_CPT (1 << 19) #define SDE_HOTPLUG_MASK_CPT (SDE_CRT_HOTPLUG_CPT | \ SDE_PORTD_HOTPLUG_CPT | \ SDE_PORTC_HOTPLUG_CPT | \ SDE_PORTB_HOTPLUG_CPT) -#define SDE_GMBUS_CPT (1 << 17) -#define SDE_AUDIO_CP_REQ_C_CPT (1 << 10) -#define SDE_AUDIO_CP_CHG_C_CPT (1 << 9) -#define SDE_FDI_RXC_CPT (1 << 8) -#define SDE_AUDIO_CP_REQ_B_CPT (1 << 6) -#define SDE_AUDIO_CP_CHG_B_CPT (1 << 5) -#define SDE_FDI_RXB_CPT (1 << 4) -#define SDE_AUDIO_CP_REQ_A_CPT (1 << 2) -#define SDE_AUDIO_CP_CHG_A_CPT (1 << 1) -#define SDE_FDI_RXA_CPT (1 << 0) -#define SDE_AUDIO_CP_REQ_CPT (SDE_AUDIO_CP_REQ_C_CPT | \ - SDE_AUDIO_CP_REQ_B_CPT | \ - SDE_AUDIO_CP_REQ_A_CPT) -#define SDE_AUDIO_CP_CHG_CPT (SDE_AUDIO_CP_CHG_C_CPT | \ - SDE_AUDIO_CP_CHG_B_CPT | \ - SDE_AUDIO_CP_CHG_A_CPT) -#define SDE_FDI_MASK_CPT (SDE_FDI_RXC_CPT | \ - SDE_FDI_RXB_CPT | \ - SDE_FDI_RXA_CPT) #define SDEISR 0xc4000 #define SDEIMR 0xc4004 diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index a748e5cabe14..0ede02a99d91 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -740,11 +740,8 @@ static void i915_restore_display(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; - * otherwise we get blank eDP screen after S3 on some machines - */ - I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); + I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index a8538ac0299d..914789420906 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -6158,34 +6158,17 @@ static int intel_gen7_queue_flip(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; - uint32_t plane_bit = 0; int ret; ret = intel_pin_and_fence_fb_obj(dev, obj, ring); if (ret) goto err; - switch(intel_crtc->plane) { - case PLANE_A: - plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A; - break; - case PLANE_B: - plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B; - break; - case PLANE_C: - plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C; - break; - default: - WARN_ONCE(1, "unknown plane in flip command\n"); - ret = -ENODEV; - goto err; - } - ret = intel_ring_begin(ring, 4); if (ret) goto err_unpin; - intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); intel_ring_emit(ring, (obj->gtt_offset)); intel_ring_emit(ring, (MI_NOOP)); @@ -6558,7 +6541,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(HDMIC) & PORT_DETECTED) intel_hdmi_init(dev, HDMIC); - if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) + if (I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) @@ -6921,6 +6904,19 @@ static void i915_disable_vga(struct drm_device *dev) POSTING_READ(vga_reg); } +static void ivb_pch_pwm_override(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + /* + * IVB has CPU eDP backlight regs too, set things up to let the + * PCH regs control the backlight + */ + I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE); + I915_WRITE(BLC_PWM_CPU_CTL, 0); + I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30)); +} + void intel_modeset_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6937,6 +6933,9 @@ void intel_modeset_init_hw(struct drm_device *dev) gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } + + if (IS_IVYBRIDGE(dev)) + ivb_pch_pwm_override(dev); } void intel_modeset_init(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index c0449324143c..296cfc201a81 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -32,7 +32,6 @@ #include "drm.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" -#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -68,8 +67,6 @@ struct intel_dp { struct drm_display_mode *panel_fixed_mode; /* for eDP */ struct delayed_work panel_vdd_work; bool want_panel_vdd; - struct edid *edid; /* cached EDID for eDP */ - int edid_mode_count; }; /** @@ -374,7 +371,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, int recv_bytes; uint32_t status; uint32_t aux_clock_divider; - int try, precharge; + int try, precharge = 5; intel_dp_check_edp(intel_dp); /* The clock divider is based off the hrawclk, @@ -394,11 +391,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = intel_hrawclk(dev) / 2; - if (IS_GEN6(dev)) - precharge = 3; - else - precharge = 5; - /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ(ch_ctl); @@ -1981,8 +1973,6 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; - ironlake_edp_panel_vdd_on(intel_dp); - if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3)) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); @@ -1990,8 +1980,6 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3)) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); - - ironlake_edp_panel_vdd_off(intel_dp, false); } static bool @@ -2128,22 +2116,10 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { struct intel_dp *intel_dp = intel_attached_dp(connector); struct edid *edid; - int size; - - if (is_edp(intel_dp)) { - if (!intel_dp->edid) - return NULL; - - size = (intel_dp->edid->extensions + 1) * EDID_LENGTH; - edid = kmalloc(size, GFP_KERNEL); - if (!edid) - return NULL; - - memcpy(edid, intel_dp->edid, size); - return edid; - } + ironlake_edp_panel_vdd_on(intel_dp); edid = drm_get_edid(connector, adapter); + ironlake_edp_panel_vdd_off(intel_dp, false); return edid; } @@ -2153,17 +2129,9 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada struct intel_dp *intel_dp = intel_attached_dp(connector); int ret; - if (is_edp(intel_dp)) { - drm_mode_connector_update_edid_property(connector, - intel_dp->edid); - ret = drm_add_edid_modes(connector, intel_dp->edid); - drm_edid_to_eld(connector, - intel_dp->edid); - connector->display_info.raw_edid = NULL; - return intel_dp->edid_mode_count; - } - + ironlake_edp_panel_vdd_on(intel_dp); ret = intel_ddc_get_modes(connector, adapter); + ironlake_edp_panel_vdd_off(intel_dp, false); return ret; } @@ -2353,7 +2321,6 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { - kfree(intel_dp->edid); cancel_delayed_work_sync(&intel_dp->panel_vdd_work); ironlake_panel_vdd_off_sync(intel_dp); } @@ -2537,14 +2504,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; } - intel_dp_i2c_init(intel_dp, intel_connector, name); - /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { bool ret; struct edp_power_seq cur, vbt; u32 pp_on, pp_off, pp_div; - struct edid *edid; pp_on = I915_READ(PCH_PP_ON_DELAYS); pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2612,20 +2576,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) intel_dp_destroy(&intel_connector->base); return; } - - ironlake_edp_panel_vdd_on(intel_dp); - edid = drm_get_edid(connector, &intel_dp->adapter); - if (edid) { - drm_mode_connector_update_edid_property(connector, - edid); - intel_dp->edid_mode_count = - drm_add_edid_modes(connector, edid); - drm_edid_to_eld(connector, edid); - intel_dp->edid = edid; - } - ironlake_edp_panel_vdd_off(intel_dp, false); } + intel_dp_i2c_init(intel_dp, intel_connector, name); + intel_encoder->hot_plug = intel_dp_hot_plug; if (is_edp(intel_dp)) { diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index e5b84ff89ca5..b59b6d5b7583 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -266,15 +266,10 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) static int init_ring_common(struct intel_ring_buffer *ring) { - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = ring->dev->dev_private; struct drm_i915_gem_object *obj = ring->obj; - int ret = 0; u32 head; - if (HAS_FORCE_WAKE(dev)) - gen6_gt_force_wake_get(dev_priv); - /* Stop the ring if it's running. */ I915_WRITE_CTL(ring, 0); I915_WRITE_HEAD(ring, 0); @@ -322,8 +317,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); - ret = -EIO; - goto out; + return -EIO; } if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) @@ -332,14 +326,9 @@ static int init_ring_common(struct intel_ring_buffer *ring) ring->head = I915_READ_HEAD(ring); ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring_space(ring); - ring->last_retired_head = -1; } -out: - if (HAS_FORCE_WAKE(dev)) - gen6_gt_force_wake_put(dev_priv); - - return ret; + return 0; } static int @@ -998,10 +987,6 @@ static int intel_init_ring_buffer(struct drm_device *dev, if (ret) goto err_unref; - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - goto err_unpin; - ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset, ring->size); if (ring->virtual_start == NULL) { diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 1074bc5dd418..153b9a15469b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -467,7 +467,7 @@ int nouveau_fbcon_init(struct drm_device *dev) nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; ret = drm_fb_helper_init(dev, &nfbdev->helper, - dev->mode_config.num_crtc, 4); + nv_two_heads(dev) ? 2 : 1, 4); if (ret) { kfree(nfbdev); return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c b/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c index a25cf2cb931f..a89240e5fb29 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -1,26 +1,3 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - */ #include "drmP.h" #include "drm.h" diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 3904d7964a4b..01d77d1554f4 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1149,9 +1149,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_TAHITI) - tmp = rdev->config.si.tile_config; - else if (rdev->family >= CHIP_CAYMAN) + if (rdev->family >= CHIP_CAYMAN) tmp = rdev->config.cayman.tile_config; else tmp = rdev->config.evergreen.tile_config; @@ -1179,12 +1177,6 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } else if (tiling_flags & RADEON_TILING_MICRO) fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); - if ((rdev->family == CHIP_TAHITI) || - (rdev->family == CHIP_PITCAIRN)) - fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); - else if (rdev->family == CHIP_VERDE) - fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); - switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c index 486ccdf4aacd..e7b1ec5ae8c6 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1926,9 +1926,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { r600_hdmi_enable(encoder); - if (ASIC_IS_DCE6(rdev)) - ; /* TODO (use pointers instead of if-s?) */ - else if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE4(rdev)) evergreen_hdmi_setmode(encoder, adjusted_mode); else r600_hdmi_setmode(encoder, adjusted_mode); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 7fb3d2e0434c..01550d05e273 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1932,9 +1932,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); WREG32(SMX_DC_CTL0, smx_dc_ctl0); - if (rdev->family <= CHIP_SUMO2) - WREG32(SMX_SAR_CTL0, 0x00010000); - WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index c16554122ccd..4e7dd2b4843d 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -52,7 +52,6 @@ struct evergreen_cs_track { u32 cb_color_view[12]; u32 cb_color_pitch[12]; u32 cb_color_slice[12]; - u32 cb_color_slice_idx[12]; u32 cb_color_attrib[12]; u32 cb_color_cmask_slice[8];/* unused */ u32 cb_color_fmask_slice[8];/* unused */ @@ -128,14 +127,12 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track) track->cb_color_info[i] = 0; track->cb_color_view[i] = 0xFFFFFFFF; track->cb_color_pitch[i] = 0; - track->cb_color_slice[i] = 0xfffffff; - track->cb_color_slice_idx[i] = 0; + track->cb_color_slice[i] = 0; } track->cb_target_mask = 0xFFFFFFFF; track->cb_shader_mask = 0xFFFFFFFF; track->cb_dirty = true; - track->db_depth_slice = 0xffffffff; track->db_depth_view = 0xFFFFC000; track->db_depth_size = 0xFFFFFFFF; track->db_depth_control = 0xFFFFFFFF; @@ -253,9 +250,10 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, { struct evergreen_cs_track *track = p->track; unsigned palign, halign, tileb, slice_pt; - unsigned mtile_pr, mtile_ps, mtileb; tileb = 64 * surf->bpe * surf->nsamples; + palign = track->group_size / (8 * surf->bpe * surf->nsamples); + palign = MAX(8, palign); slice_pt = 1; if (tileb > surf->tsplit) { slice_pt = tileb / surf->tsplit; @@ -264,10 +262,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, /* macro tile width & height */ palign = (8 * surf->bankw * track->npipes) * surf->mtilea; halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - mtileb = (palign / 8) * (halign / 8) * tileb;; - mtile_pr = surf->nbx / palign; - mtile_ps = (mtile_pr * surf->nby) / halign; - surf->layer_size = mtile_ps * mtileb * slice_pt; + surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt; surf->base_align = (palign / 8) * (halign / 8) * tileb; surf->palign = palign; surf->halign = halign; @@ -439,39 +434,6 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i offset += surf.layer_size * mslice; if (offset > radeon_bo_size(track->cb_color_bo[id])) { - /* old ddx are broken they allocate bo with w*h*bpp but - * program slice with ALIGN(h, 8), catch this and patch - * command stream. - */ - if (!surf.mode) { - volatile u32 *ib = p->ib.ptr; - unsigned long tmp, nby, bsize, size, min = 0; - - /* find the height the ddx wants */ - if (surf.nby > 8) { - min = surf.nby - 8; - } - bsize = radeon_bo_size(track->cb_color_bo[id]); - tmp = track->cb_color_bo_offset[id] << 8; - for (nby = surf.nby; nby > min; nby--) { - size = nby * surf.nbx * surf.bpe * surf.nsamples; - if ((tmp + size * mslice) <= bsize) { - break; - } - } - if (nby > min) { - surf.nby = nby; - slice = ((nby * surf.nbx) / 64) - 1; - if (!evergreen_surface_check(p, &surf, "cb")) { - /* check if this one works */ - tmp += surf.layer_size * mslice; - if (tmp <= bsize) { - ib[track->cb_color_slice_idx[id]] = slice; - goto old_ddx_ok; - } - } - } - } dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " "offset %d, max layer %d, bo size %ld, slice %d)\n", __func__, __LINE__, id, surf.layer_size, @@ -484,7 +446,6 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i surf.tsplit, surf.mtilea); return -EINVAL; } -old_ddx_ok: return 0; } @@ -1571,7 +1532,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR7_SLICE: tmp = (reg - CB_COLOR0_SLICE) / 0x3c; track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); - track->cb_color_slice_idx[tmp] = idx; track->cb_dirty = true; break; case CB_COLOR8_SLICE: @@ -1580,7 +1540,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR11_SLICE: tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8; track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); - track->cb_color_slice_idx[tmp] = idx; track->cb_dirty = true; break; case CB_COLOR0_ATTRIB: diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c b/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c index 65c54160028b..a51f880985f8 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -156,6 +156,9 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; + if (ASIC_IS_DCE5(rdev)) + return; + /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index b50b15c70498..2773039b4902 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -503,7 +503,6 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 -#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define NUMBER_OF_SETS(x) ((x) << 1) diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index b7bf18e40215..3df4efa11942 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -460,28 +460,15 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.max_pipes_per_simd = 4; rdev->config.cayman.max_tile_pipes = 2; if ((rdev->pdev->device == 0x9900) || - (rdev->pdev->device == 0x9901) || - (rdev->pdev->device == 0x9905) || - (rdev->pdev->device == 0x9906) || - (rdev->pdev->device == 0x9907) || - (rdev->pdev->device == 0x9908) || - (rdev->pdev->device == 0x9909) || - (rdev->pdev->device == 0x9910) || - (rdev->pdev->device == 0x9917)) { + (rdev->pdev->device == 0x9901)) { rdev->config.cayman.max_simds_per_se = 6; rdev->config.cayman.max_backends_per_se = 2; } else if ((rdev->pdev->device == 0x9903) || - (rdev->pdev->device == 0x9904) || - (rdev->pdev->device == 0x990A) || - (rdev->pdev->device == 0x9913) || - (rdev->pdev->device == 0x9918)) { + (rdev->pdev->device == 0x9904)) { rdev->config.cayman.max_simds_per_se = 4; rdev->config.cayman.max_backends_per_se = 2; - } else if ((rdev->pdev->device == 0x9919) || - (rdev->pdev->device == 0x9990) || - (rdev->pdev->device == 0x9991) || - (rdev->pdev->device == 0x9994) || - (rdev->pdev->device == 0x99A0)) { + } else if ((rdev->pdev->device == 0x9990) || + (rdev->pdev->device == 0x9991)) { rdev->config.cayman.max_simds_per_se = 3; rdev->config.cayman.max_backends_per_se = 1; } else { @@ -1303,10 +1290,6 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = r600_audio_init(rdev); - if (r) - return r; - return 0; } @@ -1333,7 +1316,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { - r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index bff627293812..45cfcea63507 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -1839,7 +1839,6 @@ void r600_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); - WREG32(VC_ENHANCE, 0); } @@ -2427,12 +2426,6 @@ int r600_startup(struct radeon_device *rdev) if (r) return r; - r = r600_audio_init(rdev); - if (r) { - DRM_ERROR("radeon: audio init failed\n"); - return r; - } - return 0; } @@ -2469,6 +2462,12 @@ int r600_resume(struct radeon_device *rdev) return r; } + r = r600_audio_init(rdev); + if (r) { + DRM_ERROR("radeon: audio resume failed\n"); + return r; + } + return r; } @@ -2578,6 +2577,9 @@ int r600_init(struct radeon_device *rdev) rdev->accel_working = false; } + r = r600_audio_init(rdev); + if (r) + return r; /* TODO error handling */ return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/r600_audio.c b/trunk/drivers/gpu/drm/radeon/r600_audio.c index 79b55916cf90..7c4fa77f018f 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_audio.c +++ b/trunk/drivers/gpu/drm/radeon/r600_audio.c @@ -57,7 +57,7 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder) */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev)) + return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; @@ -192,7 +192,6 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); int base_rate = 48000; switch (radeon_encoder->encoder_id) { @@ -218,8 +217,8 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) WREG32(EVERGREEN_AUDIO_PLL1_DIV, clock * 10); WREG32(EVERGREEN_AUDIO_PLL1_UNK, 0x00000071); - /* Select DTO source */ - WREG32(0x5ac, radeon_crtc->crtc_id); + /* Some magic trigger or src sel? */ + WREG32_P(0x5ac, 0x01, ~0x77); } else { switch (dig->dig_encoder) { case 0: diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..0133f5f09bd6 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -2079,48 +2079,6 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } break; - case PACKET3_STRMOUT_BASE_UPDATE: - if (p->family < CHIP_RV770) { - DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); - return -EINVAL; - } - if (pkt->count != 1) { - DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n"); - return -EINVAL; - } - if (idx_value > 3) { - DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n"); - return -EINVAL; - } - { - u64 offset; - - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); - return -EINVAL; - } - - if (reloc->robj != track->vgt_strmout_bo[idx_value]) { - DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n"); - return -EINVAL; - } - - offset = radeon_get_ib_value(p, idx+1) << 8; - if (offset != track->vgt_strmout_bo_offset[idx_value]) { - DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n", - offset, track->vgt_strmout_bo_offset[idx_value]); - return -EINVAL; - } - - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - } - break; case PACKET3_SURFACE_BASE_UPDATE: if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); diff --git a/trunk/drivers/gpu/drm/radeon/r600_hdmi.c b/trunk/drivers/gpu/drm/radeon/r600_hdmi.c index 82a0a4c919c0..226379e00ac1 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/trunk/drivers/gpu/drm/radeon/r600_hdmi.c @@ -322,6 +322,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; + if (ASIC_IS_DCE5(rdev)) + return; + /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; @@ -345,6 +348,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ + HDMI0_AUDIO_SEND_MAX_PACKETS | /* send NULL packets if no audio is available */ HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ } @@ -480,7 +484,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) uint32_t offset; u32 hdmi; - if (ASIC_IS_DCE6(rdev)) + if (ASIC_IS_DCE5(rdev)) return; /* Silent, r600_hdmi_enable will raise WARN for us */ @@ -540,7 +544,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE6(rdev)) + if (ASIC_IS_DCE5(rdev)) return; /* Called for ATOM_ENCODER_MODE_HDMI only */ diff --git a/trunk/drivers/gpu/drm/radeon/r600d.h b/trunk/drivers/gpu/drm/radeon/r600d.h index 025fd5b6c08c..a0dbf1fe6a40 100644 --- a/trunk/drivers/gpu/drm/radeon/r600d.h +++ b/trunk/drivers/gpu/drm/radeon/r600d.h @@ -485,7 +485,6 @@ #define TC_L2_SIZE(x) ((x)<<5) #define L2_DISABLE_LATE_HIT (1<<9) -#define VC_ENHANCE 0x9714 #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) @@ -1164,7 +1163,6 @@ #define PACKET3_SET_CTL_CONST 0x6F #define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 #define PACKET3_SET_CTL_CONST_END 0x0003e200 -#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ #define PACKET3_SURFACE_BASE_UPDATE 0x73 diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index fefcca55c1eb..85dac33e3cce 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -1374,9 +1374,9 @@ struct cayman_asic { struct si_asic { unsigned max_shader_engines; + unsigned max_pipes_per_simd; unsigned max_tile_pipes; - unsigned max_cu_per_sh; - unsigned max_sh_per_se; + unsigned max_simds_per_se; unsigned max_backends_per_se; unsigned max_texture_channel_caches; unsigned max_gprs; @@ -1387,6 +1387,7 @@ struct si_asic { unsigned sc_hiz_tile_fifo_size; unsigned sc_earlyz_tile_fifo_size; + unsigned num_shader_engines; unsigned num_tile_pipes; unsigned num_backends_per_se; unsigned backend_disable_mask_per_asic; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 2c4d53fd20c5..f0bb2b543b13 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -57,11 +57,9 @@ * 2.13.0 - virtual memory support, streamout * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query - * 2.16.0 - fix evergreen 2D tiled surface calculation - * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 17 +#define KMS_DRIVER_MINOR 15 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gart.c b/trunk/drivers/gpu/drm/radeon/radeon_gart.c index 84b648a7ddd8..79db56e6c2ac 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gart.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gart.c @@ -289,9 +289,8 @@ int radeon_vm_manager_init(struct radeon_device *rdev) rdev->vm_manager.enabled = false; /* mark first vm as always in use, it's the system one */ - /* allocate enough for 2 full VM pts */ r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8 * 2, + rdev->vm_manager.max_pfn * 8, RADEON_GEM_DOMAIN_VRAM); if (r) { dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", @@ -477,18 +476,12 @@ int radeon_vm_bo_add(struct radeon_device *rdev, mutex_lock(&vm->mutex); if (last_pfn > vm->last_pfn) { - /* release mutex and lock in right order */ - mutex_unlock(&vm->mutex); + /* grow va space 32M by 32M */ + unsigned align = ((32 << 20) >> 12) - 1; radeon_mutex_lock(&rdev->cs_mutex); - mutex_lock(&vm->mutex); - /* and check again */ - if (last_pfn > vm->last_pfn) { - /* grow va space 32M by 32M */ - unsigned align = ((32 << 20) >> 12) - 1; - radeon_vm_unbind_locked(rdev, vm); - vm->last_pfn = (last_pfn + align) & ~align; - } + radeon_vm_unbind_locked(rdev, vm); radeon_mutex_unlock(&rdev->cs_mutex); + vm->last_pfn = (last_pfn + align) & ~align; } head = &vm->va; last_offset = 0; @@ -602,8 +595,8 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, if (bo_va == NULL) return 0; - radeon_mutex_lock(&rdev->cs_mutex); mutex_lock(&vm->mutex); + radeon_mutex_lock(&rdev->cs_mutex); radeon_vm_bo_update_pte(rdev, vm, bo, NULL); radeon_mutex_unlock(&rdev->cs_mutex); list_del(&bo_va->vm_list); @@ -634,15 +627,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) mutex_init(&vm->mutex); INIT_LIST_HEAD(&vm->list); INIT_LIST_HEAD(&vm->va); - /* SI requires equal sized PTs for all VMs, so always set - * last_pfn to max_pfn. cayman allows variable sized - * pts so we can grow then as needed. Once we switch - * to two level pts we can unify this again. - */ - if (rdev->family >= CHIP_TAHITI) - vm->last_pfn = rdev->vm_manager.max_pfn; - else - vm->last_pfn = 0; + vm->last_pfn = 0; /* map the ib pool buffer at 0 in virtual address space, set * read only */ @@ -656,8 +641,9 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) struct radeon_bo_va *bo_va, *tmp; int r; - radeon_mutex_lock(&rdev->cs_mutex); mutex_lock(&vm->mutex); + + radeon_mutex_lock(&rdev->cs_mutex); radeon_vm_unbind_locked(rdev, vm); radeon_mutex_unlock(&rdev->cs_mutex); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gem.c b/trunk/drivers/gpu/drm/radeon/radeon_gem.c index 21ec9f5653ce..f28bd4b7ef98 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gem.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gem.c @@ -292,7 +292,6 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { - struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_busy *args = data; struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -318,14 +317,13 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, break; } drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(rdev, r); + r = radeon_gem_handle_lockup(robj->rdev, r); return r; } int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { - struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_wait_idle *args = data; struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -338,10 +336,10 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, robj = gem_to_radeon_bo(gobj); r = radeon_bo_wait(robj, NULL, false); /* callback hw specific functions if any */ - if (rdev->asic->ioctl_wait_idle) - robj->rdev->asic->ioctl_wait_idle(rdev, robj); + if (robj->rdev->asic->ioctl_wait_idle) + robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(rdev, r); + r = radeon_gem_handle_lockup(robj->rdev, r); return r; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_kms.c index 5c58d7d90cb2..f1016a5820d1 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_kms.c @@ -273,7 +273,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) break; case RADEON_INFO_MAX_PIPES: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_cu_per_sh; + value = rdev->config.si.max_pipes_per_simd; else if (rdev->family >= CHIP_CAYMAN) value = rdev->config.cayman.max_pipes_per_simd; else if (rdev->family >= CHIP_CEDAR) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c index 5b37e283ec38..08825548ee69 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c @@ -801,13 +801,9 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) int i; for (i = 0; i < RADEON_NUM_RINGS; ++i) { - struct radeon_ring *ring = &rdev->ring[i]; - - if (ring->ready) { - not_processed += radeon_fence_count_emitted(rdev, i); - if (not_processed >= 3) - break; - } + not_processed += radeon_fence_count_emitted(rdev, i); + if (not_processed >= 3) + break; } if (not_processed >= 3) { /* should upclock */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_prime.c b/trunk/drivers/gpu/drm/radeon/radeon_prime.c index 6bef46ace831..8ddab4c76710 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_prime.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_prime.c @@ -169,17 +169,11 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct radeon_bo *bo = gem_to_radeon_bo(obj); int ret = 0; - ret = radeon_bo_reserve(bo, false); - if (unlikely(ret != 0)) - return ERR_PTR(ret); - /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (ret) { - radeon_bo_unreserve(bo); + if (ret) return ERR_PTR(ret); - } - radeon_bo_unreserve(bo); + return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags); } diff --git a/trunk/drivers/gpu/drm/radeon/rs600.c b/trunk/drivers/gpu/drm/radeon/rs600.c index e95c5e61d4e2..25f9eef12c42 100644 --- a/trunk/drivers/gpu/drm/radeon/rs600.c +++ b/trunk/drivers/gpu/drm/radeon/rs600.c @@ -908,6 +908,12 @@ static int rs600_startup(struct radeon_device *rdev) return r; } + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + r = radeon_ib_pool_start(rdev); if (r) return r; @@ -916,12 +922,6 @@ static int rs600_startup(struct radeon_device *rdev) if (r) return r; - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); - return r; - } - return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rs690.c b/trunk/drivers/gpu/drm/radeon/rs690.c index 159b6a43fda0..3277ddecfe9f 100644 --- a/trunk/drivers/gpu/drm/radeon/rs690.c +++ b/trunk/drivers/gpu/drm/radeon/rs690.c @@ -637,6 +637,12 @@ static int rs690_startup(struct radeon_device *rdev) return r; } + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + r = radeon_ib_pool_start(rdev); if (r) return r; @@ -645,12 +651,6 @@ static int rs690_startup(struct radeon_device *rdev) if (r) return r; - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); - return r; - } - return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index b4f51c569c36..04ddc365a908 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -616,9 +616,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) ACK_FLUSH_CTL(3) | SYNC_FLUSH_CTL)); - if (rdev->family != CHIP_RV770) - WREG32(SMX_SAR_CTL0, 0x00003f3f); - db_debug3 = RREG32(DB_DEBUG3); db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); switch (rdev->family) { @@ -795,7 +792,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); - WREG32(VC_ENHANCE, 0); + } void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) @@ -959,12 +956,6 @@ static int rv770_startup(struct radeon_device *rdev) if (r) return r; - r = r600_audio_init(rdev); - if (r) { - DRM_ERROR("radeon: audio init failed\n"); - return r; - } - return 0; } @@ -987,6 +978,12 @@ int rv770_resume(struct radeon_device *rdev) return r; } + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "radeon: audio init failed\n"); + return r; + } + return r; } @@ -1095,6 +1092,12 @@ int rv770_init(struct radeon_device *rdev) rdev->accel_working = false; } + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "radeon: audio init failed\n"); + return r; + } + return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rv770d.h b/trunk/drivers/gpu/drm/radeon/rv770d.h index b0adfc595d75..fdc089896011 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770d.h +++ b/trunk/drivers/gpu/drm/radeon/rv770d.h @@ -211,7 +211,6 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 -#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define CACHE_DEPTH(x) ((x) << 1) @@ -311,8 +310,6 @@ #define TCP_CNTL 0x9610 #define TCP_CHAN_STEER 0x9614 -#define VC_ENHANCE 0x9714 - #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) #define VC_ONLY 0 diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 0b0279291a73..549732e56ca9 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -867,6 +867,200 @@ void dce6_bandwidth_update(struct radeon_device *rdev) /* * Core functions */ +static u32 si_get_tile_pipe_to_backend_map(struct radeon_device *rdev, + u32 num_tile_pipes, + u32 num_backends_per_asic, + u32 *backend_disable_mask_per_asic, + u32 num_shader_engines) +{ + u32 backend_map = 0; + u32 enabled_backends_mask = 0; + u32 enabled_backends_count = 0; + u32 num_backends_per_se; + u32 cur_pipe; + u32 swizzle_pipe[SI_MAX_PIPES]; + u32 cur_backend = 0; + u32 i; + bool force_no_swizzle; + + /* force legal values */ + if (num_tile_pipes < 1) + num_tile_pipes = 1; + if (num_tile_pipes > rdev->config.si.max_tile_pipes) + num_tile_pipes = rdev->config.si.max_tile_pipes; + if (num_shader_engines < 1) + num_shader_engines = 1; + if (num_shader_engines > rdev->config.si.max_shader_engines) + num_shader_engines = rdev->config.si.max_shader_engines; + if (num_backends_per_asic < num_shader_engines) + num_backends_per_asic = num_shader_engines; + if (num_backends_per_asic > (rdev->config.si.max_backends_per_se * num_shader_engines)) + num_backends_per_asic = rdev->config.si.max_backends_per_se * num_shader_engines; + + /* make sure we have the same number of backends per se */ + num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines); + /* set up the number of backends per se */ + num_backends_per_se = num_backends_per_asic / num_shader_engines; + if (num_backends_per_se > rdev->config.si.max_backends_per_se) { + num_backends_per_se = rdev->config.si.max_backends_per_se; + num_backends_per_asic = num_backends_per_se * num_shader_engines; + } + + /* create enable mask and count for enabled backends */ + for (i = 0; i < SI_MAX_BACKENDS; ++i) { + if (((*backend_disable_mask_per_asic >> i) & 1) == 0) { + enabled_backends_mask |= (1 << i); + ++enabled_backends_count; + } + if (enabled_backends_count == num_backends_per_asic) + break; + } + + /* force the backends mask to match the current number of backends */ + if (enabled_backends_count != num_backends_per_asic) { + u32 this_backend_enabled; + u32 shader_engine; + u32 backend_per_se; + + enabled_backends_mask = 0; + enabled_backends_count = 0; + *backend_disable_mask_per_asic = SI_MAX_BACKENDS_MASK; + for (i = 0; i < SI_MAX_BACKENDS; ++i) { + /* calc the current se */ + shader_engine = i / rdev->config.si.max_backends_per_se; + /* calc the backend per se */ + backend_per_se = i % rdev->config.si.max_backends_per_se; + /* default to not enabled */ + this_backend_enabled = 0; + if ((shader_engine < num_shader_engines) && + (backend_per_se < num_backends_per_se)) + this_backend_enabled = 1; + if (this_backend_enabled) { + enabled_backends_mask |= (1 << i); + *backend_disable_mask_per_asic &= ~(1 << i); + ++enabled_backends_count; + } + } + } + + + memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * SI_MAX_PIPES); + switch (rdev->family) { + case CHIP_TAHITI: + case CHIP_PITCAIRN: + case CHIP_VERDE: + force_no_swizzle = true; + break; + default: + force_no_swizzle = false; + break; + } + if (force_no_swizzle) { + bool last_backend_enabled = false; + + force_no_swizzle = false; + for (i = 0; i < SI_MAX_BACKENDS; ++i) { + if (((enabled_backends_mask >> i) & 1) == 1) { + if (last_backend_enabled) + force_no_swizzle = true; + last_backend_enabled = true; + } else + last_backend_enabled = false; + } + } + + switch (num_tile_pipes) { + case 1: + case 3: + case 5: + case 7: + DRM_ERROR("odd number of pipes!\n"); + break; + case 2: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + break; + case 4: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + } else { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 1; + swizzle_pipe[3] = 3; + } + break; + case 6: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + swizzle_pipe[5] = 5; + } else { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 1; + swizzle_pipe[4] = 3; + swizzle_pipe[5] = 5; + } + break; + case 8: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + swizzle_pipe[5] = 5; + swizzle_pipe[6] = 6; + swizzle_pipe[7] = 7; + } else { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 6; + swizzle_pipe[4] = 1; + swizzle_pipe[5] = 3; + swizzle_pipe[6] = 5; + swizzle_pipe[7] = 7; + } + break; + } + + for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { + while (((1 << cur_backend) & enabled_backends_mask) == 0) + cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS; + + backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); + + cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS; + } + + return backend_map; +} + +static u32 si_get_disable_mask_per_asic(struct radeon_device *rdev, + u32 disable_mask_per_se, + u32 max_disable_mask_per_se, + u32 num_shader_engines) +{ + u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se); + u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se; + + if (num_shader_engines == 1) + return disable_mask_per_asic; + else if (num_shader_engines == 2) + return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se); + else + return 0xffffffff; +} + static void si_tiling_mode_table_init(struct radeon_device *rdev) { const u32 num_tile_mode_states = 32; @@ -1368,151 +1562,18 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev) DRM_ERROR("unknown asic: 0x%x\n", rdev->family); } -static void si_select_se_sh(struct radeon_device *rdev, - u32 se_num, u32 sh_num) -{ - u32 data = INSTANCE_BROADCAST_WRITES; - - if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) - data = SH_BROADCAST_WRITES | SE_BROADCAST_WRITES; - else if (se_num == 0xffffffff) - data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num); - else if (sh_num == 0xffffffff) - data |= SH_BROADCAST_WRITES | SE_INDEX(se_num); - else - data |= SH_INDEX(sh_num) | SE_INDEX(se_num); - WREG32(GRBM_GFX_INDEX, data); -} - -static u32 si_create_bitmask(u32 bit_width) -{ - u32 i, mask = 0; - - for (i = 0; i < bit_width; i++) { - mask <<= 1; - mask |= 1; - } - return mask; -} - -static u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh) -{ - u32 data, mask; - - data = RREG32(CC_GC_SHADER_ARRAY_CONFIG); - if (data & 1) - data &= INACTIVE_CUS_MASK; - else - data = 0; - data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG); - - data >>= INACTIVE_CUS_SHIFT; - - mask = si_create_bitmask(cu_per_sh); - - return ~data & mask; -} - -static void si_setup_spi(struct radeon_device *rdev, - u32 se_num, u32 sh_per_se, - u32 cu_per_sh) -{ - int i, j, k; - u32 data, mask, active_cu; - - for (i = 0; i < se_num; i++) { - for (j = 0; j < sh_per_se; j++) { - si_select_se_sh(rdev, i, j); - data = RREG32(SPI_STATIC_THREAD_MGMT_3); - active_cu = si_get_cu_enabled(rdev, cu_per_sh); - - mask = 1; - for (k = 0; k < 16; k++) { - mask <<= k; - if (active_cu & mask) { - data &= ~mask; - WREG32(SPI_STATIC_THREAD_MGMT_3, data); - break; - } - } - } - } - si_select_se_sh(rdev, 0xffffffff, 0xffffffff); -} - -static u32 si_get_rb_disabled(struct radeon_device *rdev, - u32 max_rb_num, u32 se_num, - u32 sh_per_se) -{ - u32 data, mask; - - data = RREG32(CC_RB_BACKEND_DISABLE); - if (data & 1) - data &= BACKEND_DISABLE_MASK; - else - data = 0; - data |= RREG32(GC_USER_RB_BACKEND_DISABLE); - - data >>= BACKEND_DISABLE_SHIFT; - - mask = si_create_bitmask(max_rb_num / se_num / sh_per_se); - - return data & mask; -} - -static void si_setup_rb(struct radeon_device *rdev, - u32 se_num, u32 sh_per_se, - u32 max_rb_num) -{ - int i, j; - u32 data, mask; - u32 disabled_rbs = 0; - u32 enabled_rbs = 0; - - for (i = 0; i < se_num; i++) { - for (j = 0; j < sh_per_se; j++) { - si_select_se_sh(rdev, i, j); - data = si_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); - disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); - } - } - si_select_se_sh(rdev, 0xffffffff, 0xffffffff); - - mask = 1; - for (i = 0; i < max_rb_num; i++) { - if (!(disabled_rbs & mask)) - enabled_rbs |= mask; - mask <<= 1; - } - - for (i = 0; i < se_num; i++) { - si_select_se_sh(rdev, i, 0xffffffff); - data = 0; - for (j = 0; j < sh_per_se; j++) { - switch (enabled_rbs & 3) { - case 1: - data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); - break; - case 2: - data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2); - break; - case 3: - default: - data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2); - break; - } - enabled_rbs >>= 2; - } - WREG32(PA_SC_RASTER_CONFIG, data); - } - si_select_se_sh(rdev, 0xffffffff, 0xffffffff); -} - static void si_gpu_init(struct radeon_device *rdev) { + u32 cc_rb_backend_disable = 0; + u32 cc_gc_shader_array_config; u32 gb_addr_config = 0; u32 mc_shared_chmap, mc_arb_ramcfg; + u32 gb_backend_map; + u32 cgts_tcc_disable; u32 sx_debug_1; + u32 gc_user_shader_array_config; + u32 gc_user_rb_backend_disable; + u32 cgts_user_tcc_disable; u32 hdp_host_path_cntl; u32 tmp; int i, j; @@ -1520,9 +1581,9 @@ static void si_gpu_init(struct radeon_device *rdev) switch (rdev->family) { case CHIP_TAHITI: rdev->config.si.max_shader_engines = 2; + rdev->config.si.max_pipes_per_simd = 4; rdev->config.si.max_tile_pipes = 12; - rdev->config.si.max_cu_per_sh = 8; - rdev->config.si.max_sh_per_se = 2; + rdev->config.si.max_simds_per_se = 8; rdev->config.si.max_backends_per_se = 4; rdev->config.si.max_texture_channel_caches = 12; rdev->config.si.max_gprs = 256; @@ -1533,13 +1594,12 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_prim_fifo_size_backend = 0x100; rdev->config.si.sc_hiz_tile_fifo_size = 0x30; rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_PITCAIRN: rdev->config.si.max_shader_engines = 2; + rdev->config.si.max_pipes_per_simd = 4; rdev->config.si.max_tile_pipes = 8; - rdev->config.si.max_cu_per_sh = 5; - rdev->config.si.max_sh_per_se = 2; + rdev->config.si.max_simds_per_se = 5; rdev->config.si.max_backends_per_se = 4; rdev->config.si.max_texture_channel_caches = 8; rdev->config.si.max_gprs = 256; @@ -1550,14 +1610,13 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_prim_fifo_size_backend = 0x100; rdev->config.si.sc_hiz_tile_fifo_size = 0x30; rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_VERDE: default: rdev->config.si.max_shader_engines = 1; + rdev->config.si.max_pipes_per_simd = 4; rdev->config.si.max_tile_pipes = 4; - rdev->config.si.max_cu_per_sh = 2; - rdev->config.si.max_sh_per_se = 2; + rdev->config.si.max_simds_per_se = 2; rdev->config.si.max_backends_per_se = 4; rdev->config.si.max_texture_channel_caches = 4; rdev->config.si.max_gprs = 256; @@ -1568,7 +1627,6 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_prim_fifo_size_backend = 0x40; rdev->config.si.sc_hiz_tile_fifo_size = 0x30; rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; break; } @@ -1590,7 +1648,31 @@ static void si_gpu_init(struct radeon_device *rdev) mc_shared_chmap = RREG32(MC_SHARED_CHMAP); mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); + cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); + cc_gc_shader_array_config = RREG32(CC_GC_SHADER_ARRAY_CONFIG); + cgts_tcc_disable = 0xffff0000; + for (i = 0; i < rdev->config.si.max_texture_channel_caches; i++) + cgts_tcc_disable &= ~(1 << (16 + i)); + gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); + gc_user_shader_array_config = RREG32(GC_USER_SHADER_ARRAY_CONFIG); + cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); + + rdev->config.si.num_shader_engines = rdev->config.si.max_shader_engines; rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes; + tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; + rdev->config.si.num_backends_per_se = r600_count_pipe_bits(tmp); + tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; + rdev->config.si.backend_disable_mask_per_asic = + si_get_disable_mask_per_asic(rdev, tmp, SI_MAX_BACKENDS_PER_SE_MASK, + rdev->config.si.num_shader_engines); + rdev->config.si.backend_map = + si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes, + rdev->config.si.num_backends_per_se * + rdev->config.si.num_shader_engines, + &rdev->config.si.backend_disable_mask_per_asic, + rdev->config.si.num_shader_engines); + tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT; + rdev->config.si.num_texture_channel_caches = r600_count_pipe_bits(tmp); rdev->config.si.mem_max_burst_length_bytes = 256; tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; @@ -1601,8 +1683,55 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.num_gpus = 1; rdev->config.si.multi_gpu_tile_size = 64; - /* fix up row size */ - gb_addr_config &= ~ROW_SIZE_MASK; + gb_addr_config = 0; + switch (rdev->config.si.num_tile_pipes) { + case 1: + gb_addr_config |= NUM_PIPES(0); + break; + case 2: + gb_addr_config |= NUM_PIPES(1); + break; + case 4: + gb_addr_config |= NUM_PIPES(2); + break; + case 8: + default: + gb_addr_config |= NUM_PIPES(3); + break; + } + + tmp = (rdev->config.si.mem_max_burst_length_bytes / 256) - 1; + gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp); + gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.si.num_shader_engines - 1); + tmp = (rdev->config.si.shader_engine_tile_size / 16) - 1; + gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp); + switch (rdev->config.si.num_gpus) { + case 1: + default: + gb_addr_config |= NUM_GPUS(0); + break; + case 2: + gb_addr_config |= NUM_GPUS(1); + break; + case 4: + gb_addr_config |= NUM_GPUS(2); + break; + } + switch (rdev->config.si.multi_gpu_tile_size) { + case 16: + gb_addr_config |= MULTI_GPU_TILE_SIZE(0); + break; + case 32: + default: + gb_addr_config |= MULTI_GPU_TILE_SIZE(1); + break; + case 64: + gb_addr_config |= MULTI_GPU_TILE_SIZE(2); + break; + case 128: + gb_addr_config |= MULTI_GPU_TILE_SIZE(3); + break; + } switch (rdev->config.si.mem_row_size_in_kb) { case 1: default: @@ -1616,6 +1745,26 @@ static void si_gpu_init(struct radeon_device *rdev) break; } + tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; + rdev->config.si.num_tile_pipes = (1 << tmp); + tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; + rdev->config.si.mem_max_burst_length_bytes = (tmp + 1) * 256; + tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT; + rdev->config.si.num_shader_engines = tmp + 1; + tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT; + rdev->config.si.num_gpus = tmp + 1; + tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT; + rdev->config.si.multi_gpu_tile_size = 1 << tmp; + tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; + rdev->config.si.mem_row_size_in_kb = 1 << tmp; + + gb_backend_map = + si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes, + rdev->config.si.num_backends_per_se * + rdev->config.si.num_shader_engines, + &rdev->config.si.backend_disable_mask_per_asic, + rdev->config.si.num_shader_engines); + /* setup tiling info dword. gb_addr_config is not adequate since it does * not have bank info, so create a custom tiling dword. * bits 3:0 num_pipes @@ -1640,29 +1789,33 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.tile_config |= (3 << 0); break; } - if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) - rdev->config.si.tile_config |= 1 << 4; - else - rdev->config.si.tile_config |= 0 << 4; + rdev->config.si.tile_config |= + ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; rdev->config.si.tile_config |= ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; rdev->config.si.tile_config |= ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; + rdev->config.si.backend_map = gb_backend_map; WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); - si_tiling_mode_table_init(rdev); + /* primary versions */ + WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); + WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); + WREG32(CC_GC_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config); - si_setup_rb(rdev, rdev->config.si.max_shader_engines, - rdev->config.si.max_sh_per_se, - rdev->config.si.max_backends_per_se); + WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); - si_setup_spi(rdev, rdev->config.si.max_shader_engines, - rdev->config.si.max_sh_per_se, - rdev->config.si.max_cu_per_sh); + /* user versions */ + WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable); + WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); + WREG32(GC_USER_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config); + WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); + + si_tiling_mode_table_init(rdev); /* set HW defaults for 3D engine */ WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | @@ -2365,12 +2518,12 @@ int si_pcie_gart_enable(struct radeon_device *rdev) WREG32(0x15DC, 0); /* empty context1-15 */ - /* FIXME start with 4G, once using 2 level pt switch to full + /* FIXME start with 1G, once using 2 level pt switch to full * vm size space */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); + WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, (1 << 30) / RADEON_GPU_PAGE_SIZE); for (i = 1; i < 16; i++) { if (i < 8) WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), diff --git a/trunk/drivers/gpu/drm/radeon/si_reg.h b/trunk/drivers/gpu/drm/radeon/si_reg.h index 501f9d431d57..eda938a7cb6e 100644 --- a/trunk/drivers/gpu/drm/radeon/si_reg.h +++ b/trunk/drivers/gpu/drm/radeon/si_reg.h @@ -30,76 +30,4 @@ #define SI_DC_GPIO_HPD_EN 0x65b8 #define SI_DC_GPIO_HPD_Y 0x65bc -#define SI_GRPH_CONTROL 0x6804 -# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0) -# define SI_GRPH_DEPTH_8BPP 0 -# define SI_GRPH_DEPTH_16BPP 1 -# define SI_GRPH_DEPTH_32BPP 2 -# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) -# define SI_ADDR_SURF_2_BANK 0 -# define SI_ADDR_SURF_4_BANK 1 -# define SI_ADDR_SURF_8_BANK 2 -# define SI_ADDR_SURF_16_BANK 3 -# define SI_GRPH_Z(x) (((x) & 0x3) << 4) -# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) -# define SI_ADDR_SURF_BANK_WIDTH_1 0 -# define SI_ADDR_SURF_BANK_WIDTH_2 1 -# define SI_ADDR_SURF_BANK_WIDTH_4 2 -# define SI_ADDR_SURF_BANK_WIDTH_8 3 -# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8) -/* 8 BPP */ -# define SI_GRPH_FORMAT_INDEXED 0 -/* 16 BPP */ -# define SI_GRPH_FORMAT_ARGB1555 0 -# define SI_GRPH_FORMAT_ARGB565 1 -# define SI_GRPH_FORMAT_ARGB4444 2 -# define SI_GRPH_FORMAT_AI88 3 -# define SI_GRPH_FORMAT_MONO16 4 -# define SI_GRPH_FORMAT_BGRA5551 5 -/* 32 BPP */ -# define SI_GRPH_FORMAT_ARGB8888 0 -# define SI_GRPH_FORMAT_ARGB2101010 1 -# define SI_GRPH_FORMAT_32BPP_DIG 2 -# define SI_GRPH_FORMAT_8B_ARGB2101010 3 -# define SI_GRPH_FORMAT_BGRA1010102 4 -# define SI_GRPH_FORMAT_8B_BGRA1010102 5 -# define SI_GRPH_FORMAT_RGB111110 6 -# define SI_GRPH_FORMAT_BGR101111 7 -# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) -# define SI_ADDR_SURF_BANK_HEIGHT_1 0 -# define SI_ADDR_SURF_BANK_HEIGHT_2 1 -# define SI_ADDR_SURF_BANK_HEIGHT_4 2 -# define SI_ADDR_SURF_BANK_HEIGHT_8 3 -# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) -# define SI_ADDR_SURF_TILE_SPLIT_64B 0 -# define SI_ADDR_SURF_TILE_SPLIT_128B 1 -# define SI_ADDR_SURF_TILE_SPLIT_256B 2 -# define SI_ADDR_SURF_TILE_SPLIT_512B 3 -# define SI_ADDR_SURF_TILE_SPLIT_1KB 4 -# define SI_ADDR_SURF_TILE_SPLIT_2KB 5 -# define SI_ADDR_SURF_TILE_SPLIT_4KB 6 -# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) -# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0 -# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1 -# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2 -# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3 -# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) -# define SI_GRPH_ARRAY_LINEAR_GENERAL 0 -# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1 -# define SI_GRPH_ARRAY_1D_TILED_THIN1 2 -# define SI_GRPH_ARRAY_2D_TILED_THIN1 4 -# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24) -# define SI_ADDR_SURF_P2 0 -# define SI_ADDR_SURF_P4_8x16 4 -# define SI_ADDR_SURF_P4_16x16 5 -# define SI_ADDR_SURF_P4_16x32 6 -# define SI_ADDR_SURF_P4_32x32 7 -# define SI_ADDR_SURF_P8_16x16_8x16 8 -# define SI_ADDR_SURF_P8_16x32_8x16 9 -# define SI_ADDR_SURF_P8_32x32_8x16 10 -# define SI_ADDR_SURF_P8_16x32_16x16 11 -# define SI_ADDR_SURF_P8_32x32_16x16 12 -# define SI_ADDR_SURF_P8_32x32_16x32 13 -# define SI_ADDR_SURF_P8_32x64_32x32 14 - #endif diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index db4067962868..53ea2c42dbd6 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -24,11 +24,6 @@ #ifndef SI_H #define SI_H -#define TAHITI_RB_BITMAP_WIDTH_PER_SH 2 - -#define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003 -#define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002 - #define CG_MULT_THERMAL_STATUS 0x714 #define ASIC_MAX_TEMP(x) ((x) << 0) #define ASIC_MAX_TEMP_MASK 0x000001ff @@ -413,12 +408,6 @@ #define SOFT_RESET_IA (1 << 15) #define GRBM_GFX_INDEX 0x802C -#define INSTANCE_INDEX(x) ((x) << 0) -#define SH_INDEX(x) ((x) << 8) -#define SE_INDEX(x) ((x) << 16) -#define SH_BROADCAST_WRITES (1 << 29) -#define INSTANCE_BROADCAST_WRITES (1 << 30) -#define SE_BROADCAST_WRITES (1 << 31) #define GRBM_INT_CNTL 0x8060 # define RDERR_INT_ENABLE (1 << 0) @@ -491,8 +480,6 @@ #define VGT_TF_MEMORY_BASE 0x89B8 #define CC_GC_SHADER_ARRAY_CONFIG 0x89bc -#define INACTIVE_CUS_MASK 0xFFFF0000 -#define INACTIVE_CUS_SHIFT 16 #define GC_USER_SHADER_ARRAY_CONFIG 0x89c0 #define PA_CL_ENHANCE 0x8A14 @@ -701,12 +688,6 @@ #define RLC_MC_CNTL 0xC344 #define RLC_UCODE_CNTL 0xC348 -#define PA_SC_RASTER_CONFIG 0x28350 -# define RASTER_CONFIG_RB_MAP_0 0 -# define RASTER_CONFIG_RB_MAP_1 1 -# define RASTER_CONFIG_RB_MAP_2 2 -# define RASTER_CONFIG_RB_MAP_3 3 - #define VGT_EVENT_INITIATOR 0x28a90 # define SAMPLE_STREAMOUTSTATS1 (1 << 0) # define SAMPLE_STREAMOUTSTATS2 (2 << 0) diff --git a/trunk/drivers/gpu/drm/sis/sis_drv.c b/trunk/drivers/gpu/drm/sis/sis_drv.c index dd14cd1a0033..30d98d14b5c5 100644 --- a/trunk/drivers/gpu/drm/sis/sis_drv.c +++ b/trunk/drivers/gpu/drm/sis/sis_drv.c @@ -47,9 +47,9 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; - idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; + idr_init(&dev->object_name_idr); return 0; } diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 36f4b28c1b90..b67cfcaa661f 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -1204,7 +1204,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, (*destroy)(bo); else kfree(bo); - ttm_mem_global_free(mem_glob, acc_size); return -EINVAL; } bo->destroy = destroy; @@ -1308,14 +1307,22 @@ int ttm_bo_create(struct ttm_bo_device *bdev, struct ttm_buffer_object **p_bo) { struct ttm_buffer_object *bo; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; size_t acc_size; int ret; + acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); + ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); + if (unlikely(ret != 0)) + return ret; + bo = kzalloc(sizeof(*bo), GFP_KERNEL); - if (unlikely(bo == NULL)) + + if (unlikely(bo == NULL)) { + ttm_mem_global_free(mem_glob, acc_size); return -ENOMEM; + } - acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, buffer_start, interruptible, persistent_swap_storage, acc_size, NULL, NULL); diff --git a/trunk/drivers/gpu/drm/udl/udl_drv.c b/trunk/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b3..4d02c46a9420 100644 --- a/trunk/drivers/gpu/drm/udl/udl_drv.c +++ b/trunk/drivers/gpu/drm/udl/udl_drv.c @@ -13,21 +13,8 @@ static struct drm_driver driver; -/* - * There are many DisplayLink-based graphics products, all with unique PIDs. - * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) - * We also require a match on SubClass (0x00) and Protocol (0x00), - * which is compatible with all known USB 2.0 era graphics chips and firmware, - * but allows DisplayLink to increment those for any future incompatible chips - */ static struct usb_device_id id_table[] = { - {.idVendor = 0x17e9, .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS | - USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, + {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, {}, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/trunk/drivers/gpu/drm/udl/udl_main.c b/trunk/drivers/gpu/drm/udl/udl_main.c index 4c2d836a0893..a8d5f09428c7 100644 --- a/trunk/drivers/gpu/drm/udl/udl_main.c +++ b/trunk/drivers/gpu/drm/udl/udl_main.c @@ -61,7 +61,7 @@ static int udl_parse_vendor_descriptor(struct drm_device *dev, u8 length; u16 key; - key = le16_to_cpu(*((u16 *) desc)); + key = *((u16 *) desc); desc += sizeof(u16); length = *desc; desc++; diff --git a/trunk/drivers/gpu/drm/via/via_map.c b/trunk/drivers/gpu/drm/via/via_map.c index c126182ac07e..1f182254e81e 100644 --- a/trunk/drivers/gpu/drm/via/via_map.c +++ b/trunk/drivers/gpu/drm/via/via_map.c @@ -100,11 +100,12 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; - idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; + idr_init(&dev->object_name_idr); + pci_set_master(dev->pdev); ret = drm_vblank_init(dev, 1); diff --git a/trunk/drivers/gpu/vga/vga_switcheroo.c b/trunk/drivers/gpu/vga/vga_switcheroo.c index 5b3c7d135dc9..38f9534ac513 100644 --- a/trunk/drivers/gpu/vga/vga_switcheroo.c +++ b/trunk/drivers/gpu/vga/vga_switcheroo.c @@ -190,19 +190,6 @@ find_active_client(struct list_head *head) return NULL; } -int vga_switcheroo_get_client_state(struct pci_dev *pdev) -{ - struct vga_switcheroo_client *client; - - client = find_client_from_pci(&vgasr_priv.clients, pdev); - if (!client) - return VGA_SWITCHEROO_NOT_FOUND; - if (!vgasr_priv.active) - return VGA_SWITCHEROO_INIT; - return client->pwr_state; -} -EXPORT_SYMBOL(vga_switcheroo_get_client_state); - void vga_switcheroo_unregister_client(struct pci_dev *pdev) { struct vga_switcheroo_client *client; @@ -304,6 +291,8 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) vga_switchon(new_client); vga_set_default_device(new_client->pdev); + set_audio_state(new_client->id, VGA_SWITCHEROO_ON); + return 0; } @@ -319,8 +308,6 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) active->active = false; - set_audio_state(active->id, VGA_SWITCHEROO_OFF); - if (new_client->fb_info) { struct fb_event event; event.info = new_client->fb_info; @@ -334,11 +321,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) if (new_client->ops->reprobe) new_client->ops->reprobe(new_client->pdev); + set_audio_state(active->id, VGA_SWITCHEROO_OFF); + if (active->pwr_state == VGA_SWITCHEROO_ON) vga_switchoff(active); - set_audio_state(new_client->id, VGA_SWITCHEROO_ON); - new_client->active = true; return 0; } @@ -384,9 +371,8 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, /* pwr off the device not in use */ if (strncmp(usercmd, "OFF", 3) == 0) { list_for_each_entry(client, &vgasr_priv.clients, list) { - if (client->active || client_is_audio(client)) + if (client->active) continue; - set_audio_state(client->id, VGA_SWITCHEROO_OFF); if (client->pwr_state == VGA_SWITCHEROO_ON) vga_switchoff(client); } @@ -395,11 +381,10 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, /* pwr on the device not in use */ if (strncmp(usercmd, "ON", 2) == 0) { list_for_each_entry(client, &vgasr_priv.clients, list) { - if (client->active || client_is_audio(client)) + if (client->active) continue; if (client->pwr_state == VGA_SWITCHEROO_OFF) vga_switchon(client); - set_audio_state(client->id, VGA_SWITCHEROO_ON); } goto out; } diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index 3fda8c87f02c..034c80a10f1f 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -1,11 +1,20 @@ # # HID driver configuration # -menu "HID support" - depends on INPUT +menuconfig HID_SUPPORT + bool "HID Devices" + depends on INPUT + default y + ---help--- + Say Y here to get to see options for various computer-human interface + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if HID_SUPPORT config HID - tristate "HID bus support" + tristate "Generic HID support" depends on INPUT default y ---help--- @@ -14,17 +23,14 @@ config HID most commonly used to refer to the USB-HID specification, but other devices (such as, but not strictly limited to, Bluetooth) are designed using HID specification (this involves certain keyboards, - mice, tablets, etc). This option adds the HID bus to the kernel, - together with generic HID layer code. The HID devices are added and - removed from the HID bus by the transport-layer drivers, such as - usbhid (USB_HID) and hidp (BT_HIDP). + mice, tablets, etc). This option compiles into kernel the generic + HID layer code (parser, usages, etc.), which can then be used by + transport-specific HID implementation (like USB or Bluetooth). For docs and specs, see http://www.usb.org/developers/hidpage/ If unsure, say Y. -if HID - config HID_BATTERY_STRENGTH bool "Battery level reporting for HID devices" depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY @@ -53,22 +59,23 @@ config HIDRAW If unsure, say Y. +source "drivers/hid/usbhid/Kconfig" + +menu "Special HID drivers" + depends on HID + config HID_GENERIC tristate "Generic HID driver" depends on HID - default HID + default y ---help--- - Support for generic devices on the HID bus. This includes most - keyboards and mice, joysticks, tablets and digitizers. + Support for generic HID devices. To compile this driver as a module, choose M here: the module will be called hid-generic. If unsure, say Y. -menu "Special HID drivers" - depends on HID - config HID_A4TECH tristate "A4 tech mice" if EXPERT depends on USB_HID @@ -386,7 +393,6 @@ config HID_MULTITOUCH - Unitec Panels - XAT optical touch panels - Xiroku optical touch panels - - Zytronic touch panels If unsure, say N. @@ -656,8 +662,4 @@ config HID_ZYDACRON endmenu -endif # HID - -source "drivers/hid/usbhid/Kconfig" - -endmenu +endif # HID_SUPPORT diff --git a/trunk/drivers/hid/hid-apple.c b/trunk/drivers/hid/hid-apple.c index 585344b6d338..fa10f847f7db 100644 --- a/trunk/drivers/hid/hid-apple.c +++ b/trunk/drivers/hid/hid-apple.c @@ -517,12 +517,6 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index 4c87276c8ddb..8e3a6b261477 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1503,9 +1503,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, @@ -1883,7 +1880,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AXENTIA, USB_DEVICE_ID_AXENTIA_FM_RADIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, @@ -1998,7 +1994,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MCT) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, @@ -2093,9 +2088,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 32039235cfee..9373f535dfe9 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -125,9 +125,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e -#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 -#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 -#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b @@ -163,9 +160,6 @@ #define USB_VENDOR_ID_AVERMEDIA 0x07ca #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 -#define USB_VENDOR_ID_AXENTIA 0x12cf -#define USB_DEVICE_ID_AXENTIA_FM_RADIO 0x7111 - #define USB_VENDOR_ID_BAANTO 0x2453 #define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100 @@ -521,9 +515,6 @@ #define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 #define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007 -#define USB_VENDOR_ID_MADCATZ 0x0738 -#define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 - #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a @@ -659,9 +650,6 @@ #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 -#define USB_VENDOR_ID_SENNHEISER 0x1395 -#define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c - #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 @@ -811,9 +799,6 @@ #define USB_VENDOR_ID_ZYDACRON 0x13EC #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 -#define USB_VENDOR_ID_ZYTRONIC 0x14c8 -#define USB_DEVICE_ID_ZYTRONIC_ZXY100 0x0005 - #define USB_VENDOR_ID_PRIMAX 0x0461 #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 diff --git a/trunk/drivers/hid/hid-input.c b/trunk/drivers/hid/hid-input.c index 5301006f6c15..132b0019365e 100644 --- a/trunk/drivers/hid/hid-input.c +++ b/trunk/drivers/hid/hid-input.c @@ -301,9 +301,6 @@ static const struct hid_device_id hid_battery_quirks[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, - USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), - HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, {} }; diff --git a/trunk/drivers/hid/hid-logitech-dj.c b/trunk/drivers/hid/hid-logitech-dj.c index 0f9c146fc00d..5e8a7ed42344 100644 --- a/trunk/drivers/hid/hid-logitech-dj.c +++ b/trunk/drivers/hid/hid-logitech-dj.c @@ -436,37 +436,27 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) { - struct dj_report *dj_report; - int retval; + struct dj_report dj_report; - dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); - if (!dj_report) - return -ENOMEM; - dj_report->report_id = REPORT_ID_DJ_SHORT; - dj_report->device_index = 0xFF; - dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; - retval = logi_dj_recv_send_report(djrcv_dev, dj_report); - kfree(dj_report); - return retval; + memset(&dj_report, 0, sizeof(dj_report)); + dj_report.report_id = REPORT_ID_DJ_SHORT; + dj_report.device_index = 0xFF; + dj_report.report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; + return logi_dj_recv_send_report(djrcv_dev, &dj_report); } static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, unsigned timeout) { - struct dj_report *dj_report; - int retval; + struct dj_report dj_report; - dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); - if (!dj_report) - return -ENOMEM; - dj_report->report_id = REPORT_ID_DJ_SHORT; - dj_report->device_index = 0xFF; - dj_report->report_type = REPORT_TYPE_CMD_SWITCH; - dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; - dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; - retval = logi_dj_recv_send_report(djrcv_dev, dj_report); - kfree(dj_report); - return retval; + memset(&dj_report, 0, sizeof(dj_report)); + dj_report.report_id = REPORT_ID_DJ_SHORT; + dj_report.device_index = 0xFF; + dj_report.report_type = REPORT_TYPE_CMD_SWITCH; + dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; + dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; + return logi_dj_recv_send_report(djrcv_dev, &dj_report); } diff --git a/trunk/drivers/hid/hid-magicmouse.c b/trunk/drivers/hid/hid-magicmouse.c index 40ac6654f1d1..7cf3ffe4b7bc 100644 --- a/trunk/drivers/hid/hid-magicmouse.c +++ b/trunk/drivers/hid/hid-magicmouse.c @@ -426,10 +426,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_ABS, input->evbit); input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, - 4, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, - 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); /* Note: Touch Y position from the device is inverted relative diff --git a/trunk/drivers/hid/hid-multitouch.c b/trunk/drivers/hid/hid-multitouch.c index 76479246d4ee..6e3332a99976 100644 --- a/trunk/drivers/hid/hid-multitouch.c +++ b/trunk/drivers/hid/hid-multitouch.c @@ -1048,11 +1048,6 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) }, - /* Zytronic panels */ - { .driver_data = MT_CLS_SERIAL, - MT_USB_DEVICE(USB_VENDOR_ID_ZYTRONIC, - USB_DEVICE_ID_ZYTRONIC_ZXY100) }, - /* Generic MT device */ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, { } diff --git a/trunk/drivers/hid/usbhid/Kconfig b/trunk/drivers/hid/usbhid/Kconfig index 0108c5991a04..0f20fd17cf06 100644 --- a/trunk/drivers/hid/usbhid/Kconfig +++ b/trunk/drivers/hid/usbhid/Kconfig @@ -1,13 +1,13 @@ -menu "USB HID support" +comment "USB Input Devices" depends on USB config USB_HID - tristate "USB HID transport layer" + tristate "USB Human Interface Device (full HID) support" default y depends on USB && INPUT select HID ---help--- - Say Y here if you want to connect USB keyboards, + Say Y here if you want full HID support to connect USB keyboards, mice, joysticks, graphic tablets, or any other HID based devices to your computer via USB, as well as Uninterruptible Power Supply (UPS) and monitor control devices. @@ -81,4 +81,4 @@ config USB_MOUSE endmenu -endmenu + diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index 903eef3d3e10..0597ee604f6e 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -76,7 +76,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, diff --git a/trunk/drivers/hwmon/acpi_power_meter.c b/trunk/drivers/hwmon/acpi_power_meter.c index e3fcf8146834..34ad5a27a7e9 100644 --- a/trunk/drivers/hwmon/acpi_power_meter.c +++ b/trunk/drivers/hwmon/acpi_power_meter.c @@ -929,25 +929,20 @@ static int acpi_power_meter_remove(struct acpi_device *device, int type) return 0; } -static int acpi_power_meter_resume(struct device *dev) +static int acpi_power_meter_resume(struct acpi_device *device) { struct acpi_power_meter_resource *resource; - if (!dev) - return -EINVAL; - - resource = acpi_driver_data(to_acpi_device(dev)); - if (!resource) + if (!device || !acpi_driver_data(device)) return -EINVAL; + resource = acpi_driver_data(device); free_capabilities(resource); read_capabilities(resource); return 0; } -static SIMPLE_DEV_PM_OPS(acpi_power_meter_pm, NULL, acpi_power_meter_resume); - static struct acpi_driver acpi_power_meter_driver = { .name = "power_meter", .class = ACPI_POWER_METER_CLASS, @@ -955,9 +950,9 @@ static struct acpi_driver acpi_power_meter_driver = { .ops = { .add = acpi_power_meter_add, .remove = acpi_power_meter_remove, + .resume = acpi_power_meter_resume, .notify = acpi_power_meter_notify, }, - .drv.pm = &acpi_power_meter_pm, }; /* Module init/exit routines */ diff --git a/trunk/drivers/hwmon/applesmc.c b/trunk/drivers/hwmon/applesmc.c index 2cde9ecf7731..f082e48ab113 100644 --- a/trunk/drivers/hwmon/applesmc.c +++ b/trunk/drivers/hwmon/applesmc.c @@ -8,7 +8,7 @@ * * Based on hdaps.c driver: * Copyright (C) 2005 Robert Love - * Copyright (C) 2005 Jesper Juhl + * Copyright (C) 2005 Jesper Juhl * * Fan control based on smcFanControl: * Copyright (C) 2006 Hendrik Holtmann @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) int i; if (send_command(cmd) || send_argument(key)) { - pr_warn("%.4s: read arg fail\n", key); + pr_warn("%s: read arg fail\n", key); return -EIO; } @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) for (i = 0; i < len; i++) { if (__wait_status(0x05)) { - pr_warn("%.4s: read data fail\n", key); + pr_warn("%s: read data fail\n", key); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index 637c51c11b44..b9d512331ed4 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -191,24 +191,6 @@ static ssize_t show_temp(struct device *dev, return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; } -struct tjmax { - char const *id; - int tjmax; -}; - -static struct tjmax __cpuinitconst tjmax_table[] = { - { "CPU D410", 100000 }, - { "CPU D425", 100000 }, - { "CPU D510", 100000 }, - { "CPU D525", 100000 }, - { "CPU N450", 100000 }, - { "CPU N455", 100000 }, - { "CPU N470", 100000 }, - { "CPU N475", 100000 }, - { "CPU 230", 100000 }, - { "CPU 330", 125000 }, -}; - static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) { @@ -220,13 +202,6 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, int err; u32 eax, edx; struct pci_dev *host_bridge; - int i; - - /* explicit tjmax table entries override heuristics */ - for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { - if (strstr(c->x86_model_id, tjmax_table[i].id)) - return tjmax_table[i].tjmax; - } /* Early chips have no MSR for TjMax */ @@ -235,8 +210,7 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, /* Atom CPUs */ - if (c->x86_model == 0x1c || c->x86_model == 0x26 - || c->x86_model == 0x27) { + if (c->x86_model == 0x1c) { usemsr_ee = 0; host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); @@ -249,9 +223,6 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, tjmax = 90000; pci_dev_put(host_bridge); - } else if (c->x86_model == 0x36) { - usemsr_ee = 0; - tjmax = 100000; } if (c->x86_model > 0xe && usemsr_ee) { @@ -693,7 +664,7 @@ static void __cpuinit get_core_online(unsigned int cpu) * sensors. We check this bit only, all the early CPUs * without thermal sensors will be filtered out. */ - if (!cpu_has(c, X86_FEATURE_DTHERM)) + if (!cpu_has(c, X86_FEATURE_DTS)) return; if (!pdev) { @@ -794,14 +765,14 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { }; static const struct x86_cpu_id coretemp_ids[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, {} }; MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); static int __init coretemp_init(void) { - int i, err; + int i, err = -ENODEV; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal diff --git a/trunk/drivers/hwmon/emc2103.c b/trunk/drivers/hwmon/emc2103.c index e7d234b59312..9691f664c76e 100644 --- a/trunk/drivers/hwmon/emc2103.c +++ b/trunk/drivers/hwmon/emc2103.c @@ -451,15 +451,11 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, data->fan_rpm_control = true; break; default: - count = -EINVAL; - goto err; + mutex_unlock(&data->update_lock); + return -EINVAL; } - result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); - if (result) { - count = result; - goto err; - } + read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); if (data->fan_rpm_control) conf_reg |= 0x80; @@ -467,7 +463,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, conf_reg &= ~0x80; i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); -err: + mutex_unlock(&data->update_lock); return count; } diff --git a/trunk/drivers/hwmon/it87.c b/trunk/drivers/hwmon/it87.c index f1de3979181f..e7701d99f8e8 100644 --- a/trunk/drivers/hwmon/it87.c +++ b/trunk/drivers/hwmon/it87.c @@ -2341,7 +2341,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) /* Start monitoring */ it87_write_value(data, IT87_REG_CONFIG, - (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) + (it87_read_value(data, IT87_REG_CONFIG) & 0x36) | (update_vbat ? 0x41 : 0x01)); } diff --git a/trunk/drivers/hwmon/jc42.c b/trunk/drivers/hwmon/jc42.c index e72ba5d2a824..a9bfd6736d9a 100644 --- a/trunk/drivers/hwmon/jc42.c +++ b/trunk/drivers/hwmon/jc42.c @@ -590,6 +590,6 @@ static struct jc42_data *jc42_update_device(struct device *dev) module_i2c_driver(jc42_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("JC42 driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/k10temp.c b/trunk/drivers/hwmon/k10temp.c index 7356b5ec8f67..f2fe8078633b 100644 --- a/trunk/drivers/hwmon/k10temp.c +++ b/trunk/drivers/hwmon/k10temp.c @@ -33,9 +33,6 @@ static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); -/* PCI-IDs for Northbridge devices not used anywhere else */ -#define PCI_DEVICE_ID_AMD_15H_M10H_NB_F3 0x1403 - /* CPUID function 0x80000001, ebx */ #define CPUID_PKGTYPE_MASK 0xf0000000 #define CPUID_PKGTYPE_F 0x00000000 @@ -213,7 +210,7 @@ static DEFINE_PCI_DEVICE_TABLE(k10temp_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_NB_F3) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); diff --git a/trunk/drivers/hwmon/lineage-pem.c b/trunk/drivers/hwmon/lineage-pem.c index bd75d2415432..d264937c7f5e 100644 --- a/trunk/drivers/hwmon/lineage-pem.c +++ b/trunk/drivers/hwmon/lineage-pem.c @@ -567,6 +567,6 @@ static struct i2c_driver pem_driver = { module_i2c_driver(pem_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/ltc4261.c b/trunk/drivers/hwmon/ltc4261.c index 77476a575c4e..069b7d34d8f9 100644 --- a/trunk/drivers/hwmon/ltc4261.c +++ b/trunk/drivers/hwmon/ltc4261.c @@ -292,6 +292,6 @@ static struct i2c_driver ltc4261_driver = { module_i2c_driver(ltc4261_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("LTC4261 driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/max16065.c b/trunk/drivers/hwmon/max16065.c index 019427d7a5fd..822261be84dd 100644 --- a/trunk/drivers/hwmon/max16065.c +++ b/trunk/drivers/hwmon/max16065.c @@ -692,6 +692,6 @@ static struct i2c_driver max16065_driver = { module_i2c_driver(max16065_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("MAX16065 driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwspinlock/hwspinlock_core.c b/trunk/drivers/hwspinlock/hwspinlock_core.c index 1201a15784c3..61c9cf15fa52 100644 --- a/trunk/drivers/hwspinlock/hwspinlock_core.c +++ b/trunk/drivers/hwspinlock/hwspinlock_core.c @@ -345,7 +345,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, spin_lock_init(&hwlock->lock); hwlock->bank = bank; - ret = hwspin_lock_register_single(hwlock, base_id + i); + ret = hwspin_lock_register_single(hwlock, i); if (ret) goto reg_failed; } @@ -354,7 +354,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, reg_failed: while (--i >= 0) - hwspin_lock_unregister_single(base_id + i); + hwspin_lock_unregister_single(i); return ret; } EXPORT_SYMBOL_GPL(hwspin_lock_register); diff --git a/trunk/drivers/i2c/muxes/Kconfig b/trunk/drivers/i2c/muxes/Kconfig index a0edd9854218..beb2491db274 100644 --- a/trunk/drivers/i2c/muxes/Kconfig +++ b/trunk/drivers/i2c/muxes/Kconfig @@ -37,16 +37,4 @@ config I2C_MUX_PCA954x This driver can also be built as a module. If so, the module will be called i2c-mux-pca954x. -config I2C_MUX_PINCTRL - tristate "pinctrl-based I2C multiplexer" - depends on PINCTRL - help - If you say yes to this option, support will be included for an I2C - multiplexer that uses the pinctrl subsystem, i.e. pin multiplexing. - This is useful for SoCs whose I2C module's signals can be routed to - different sets of pins at run-time. - - This driver can also be built as a module. If so, the module will be - called pinctrl-i2cmux. - endmenu diff --git a/trunk/drivers/i2c/muxes/Makefile b/trunk/drivers/i2c/muxes/Makefile index 76da8692afff..5826249b29ca 100644 --- a/trunk/drivers/i2c/muxes/Makefile +++ b/trunk/drivers/i2c/muxes/Makefile @@ -4,6 +4,5 @@ obj-$(CONFIG_I2C_MUX_GPIO) += i2c-mux-gpio.o obj-$(CONFIG_I2C_MUX_PCA9541) += i2c-mux-pca9541.o obj-$(CONFIG_I2C_MUX_PCA954x) += i2c-mux-pca954x.o -obj-$(CONFIG_I2C_MUX_PINCTRL) += i2c-mux-pinctrl.o ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG diff --git a/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c b/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c deleted file mode 100644 index 46a669763476..000000000000 --- a/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * I2C multiplexer using pinctrl API - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct i2c_mux_pinctrl { - struct device *dev; - struct i2c_mux_pinctrl_platform_data *pdata; - struct pinctrl *pinctrl; - struct pinctrl_state **states; - struct pinctrl_state *state_idle; - struct i2c_adapter *parent; - struct i2c_adapter **busses; -}; - -static int i2c_mux_pinctrl_select(struct i2c_adapter *adap, void *data, - u32 chan) -{ - struct i2c_mux_pinctrl *mux = data; - - return pinctrl_select_state(mux->pinctrl, mux->states[chan]); -} - -static int i2c_mux_pinctrl_deselect(struct i2c_adapter *adap, void *data, - u32 chan) -{ - struct i2c_mux_pinctrl *mux = data; - - return pinctrl_select_state(mux->pinctrl, mux->state_idle); -} - -#ifdef CONFIG_OF -static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl *mux, - struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - int num_names, i, ret; - struct device_node *adapter_np; - struct i2c_adapter *adapter; - - if (!np) - return 0; - - mux->pdata = devm_kzalloc(&pdev->dev, sizeof(*mux->pdata), GFP_KERNEL); - if (!mux->pdata) { - dev_err(mux->dev, - "Cannot allocate i2c_mux_pinctrl_platform_data\n"); - return -ENOMEM; - } - - num_names = of_property_count_strings(np, "pinctrl-names"); - if (num_names < 0) { - dev_err(mux->dev, "Cannot parse pinctrl-names: %d\n", - num_names); - return num_names; - } - - mux->pdata->pinctrl_states = devm_kzalloc(&pdev->dev, - sizeof(*mux->pdata->pinctrl_states) * num_names, - GFP_KERNEL); - if (!mux->pdata->pinctrl_states) { - dev_err(mux->dev, "Cannot allocate pinctrl_states\n"); - return -ENOMEM; - } - - for (i = 0; i < num_names; i++) { - ret = of_property_read_string_index(np, "pinctrl-names", i, - &mux->pdata->pinctrl_states[mux->pdata->bus_count]); - if (ret < 0) { - dev_err(mux->dev, "Cannot parse pinctrl-names: %d\n", - ret); - return ret; - } - if (!strcmp(mux->pdata->pinctrl_states[mux->pdata->bus_count], - "idle")) { - if (i != num_names - 1) { - dev_err(mux->dev, "idle state must be last\n"); - return -EINVAL; - } - mux->pdata->pinctrl_state_idle = "idle"; - } else { - mux->pdata->bus_count++; - } - } - - adapter_np = of_parse_phandle(np, "i2c-parent", 0); - if (!adapter_np) { - dev_err(mux->dev, "Cannot parse i2c-parent\n"); - return -ENODEV; - } - adapter = of_find_i2c_adapter_by_node(adapter_np); - if (!adapter) { - dev_err(mux->dev, "Cannot find parent bus\n"); - return -ENODEV; - } - mux->pdata->parent_bus_num = i2c_adapter_id(adapter); - put_device(&adapter->dev); - - return 0; -} -#else -static inline int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl *mux, - struct platform_device *pdev) -{ - return 0; -} -#endif - -static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) -{ - struct i2c_mux_pinctrl *mux; - int (*deselect)(struct i2c_adapter *, void *, u32); - int i, ret; - - mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); - if (!mux) { - dev_err(&pdev->dev, "Cannot allocate i2c_mux_pinctrl\n"); - ret = -ENOMEM; - goto err; - } - platform_set_drvdata(pdev, mux); - - mux->dev = &pdev->dev; - - mux->pdata = pdev->dev.platform_data; - if (!mux->pdata) { - ret = i2c_mux_pinctrl_parse_dt(mux, pdev); - if (ret < 0) - goto err; - } - if (!mux->pdata) { - dev_err(&pdev->dev, "Missing platform data\n"); - ret = -ENODEV; - goto err; - } - - mux->states = devm_kzalloc(&pdev->dev, - sizeof(*mux->states) * mux->pdata->bus_count, - GFP_KERNEL); - if (!mux->states) { - dev_err(&pdev->dev, "Cannot allocate states\n"); - ret = -ENOMEM; - goto err; - } - - mux->busses = devm_kzalloc(&pdev->dev, - sizeof(mux->busses) * mux->pdata->bus_count, - GFP_KERNEL); - if (!mux->states) { - dev_err(&pdev->dev, "Cannot allocate busses\n"); - ret = -ENOMEM; - goto err; - } - - mux->pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR(mux->pinctrl)) { - ret = PTR_ERR(mux->pinctrl); - dev_err(&pdev->dev, "Cannot get pinctrl: %d\n", ret); - goto err; - } - for (i = 0; i < mux->pdata->bus_count; i++) { - mux->states[i] = pinctrl_lookup_state(mux->pinctrl, - mux->pdata->pinctrl_states[i]); - if (IS_ERR(mux->states[i])) { - ret = PTR_ERR(mux->states[i]); - dev_err(&pdev->dev, - "Cannot look up pinctrl state %s: %d\n", - mux->pdata->pinctrl_states[i], ret); - goto err; - } - } - if (mux->pdata->pinctrl_state_idle) { - mux->state_idle = pinctrl_lookup_state(mux->pinctrl, - mux->pdata->pinctrl_state_idle); - if (IS_ERR(mux->state_idle)) { - ret = PTR_ERR(mux->state_idle); - dev_err(&pdev->dev, - "Cannot look up pinctrl state %s: %d\n", - mux->pdata->pinctrl_state_idle, ret); - goto err; - } - - deselect = i2c_mux_pinctrl_deselect; - } else { - deselect = NULL; - } - - mux->parent = i2c_get_adapter(mux->pdata->parent_bus_num); - if (!mux->parent) { - dev_err(&pdev->dev, "Parent adapter (%d) not found\n", - mux->pdata->parent_bus_num); - ret = -ENODEV; - goto err; - } - - for (i = 0; i < mux->pdata->bus_count; i++) { - u32 bus = mux->pdata->base_bus_num ? - (mux->pdata->base_bus_num + i) : 0; - - mux->busses[i] = i2c_add_mux_adapter(mux->parent, &pdev->dev, - mux, bus, i, - i2c_mux_pinctrl_select, - deselect); - if (!mux->busses[i]) { - ret = -ENODEV; - dev_err(&pdev->dev, "Failed to add adapter %d\n", i); - goto err_del_adapter; - } - } - - return 0; - -err_del_adapter: - for (; i > 0; i--) - i2c_del_mux_adapter(mux->busses[i - 1]); - i2c_put_adapter(mux->parent); -err: - return ret; -} - -static int __devexit i2c_mux_pinctrl_remove(struct platform_device *pdev) -{ - struct i2c_mux_pinctrl *mux = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < mux->pdata->bus_count; i++) - i2c_del_mux_adapter(mux->busses[i]); - - i2c_put_adapter(mux->parent); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id i2c_mux_pinctrl_of_match[] __devinitconst = { - { .compatible = "i2c-mux-pinctrl", }, - {}, -}; -MODULE_DEVICE_TABLE(of, i2c_mux_pinctrl_of_match); -#endif - -static struct platform_driver i2c_mux_pinctrl_driver = { - .driver = { - .name = "i2c-mux-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(i2c_mux_pinctrl_of_match), - }, - .probe = i2c_mux_pinctrl_probe, - .remove = __devexit_p(i2c_mux_pinctrl_remove), -}; -module_platform_driver(i2c_mux_pinctrl_driver); - -MODULE_DESCRIPTION("pinctrl-based I2C multiplexer driver"); -MODULE_AUTHOR("Stephen Warren "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:i2c-mux-pinctrl"); diff --git a/trunk/drivers/ide/icside.c b/trunk/drivers/ide/icside.c index bcb507b0cfd4..8716066a2f2b 100644 --- a/trunk/drivers/ide/icside.c +++ b/trunk/drivers/ide/icside.c @@ -236,7 +236,7 @@ static const struct ide_port_ops icside_v6_no_dma_port_ops = { */ static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - unsigned long cycle_time = 0; + unsigned long cycle_time; int use_dma_info = 0; const u8 xfer_mode = drive->dma_mode; @@ -271,9 +271,9 @@ static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) ide_set_drivedata(drive, (void *)cycle_time); - printk(KERN_INFO "%s: %s selected (peak %luMB/s)\n", - drive->name, ide_xfer_verbose(xfer_mode), - 2000 / (cycle_time ? cycle_time : (unsigned long) -1)); + printk("%s: %s selected (peak %dMB/s)\n", drive->name, + ide_xfer_verbose(xfer_mode), + 2000 / (unsigned long)ide_get_drivedata(drive)); } static const struct ide_port_ops icside_v6_port_ops = { @@ -375,6 +375,8 @@ static const struct ide_dma_ops icside_v6_dma_ops = { .dma_test_irq = icside_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, }; +#else +#define icside_v6_dma_ops NULL #endif static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d) @@ -454,6 +456,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) static const struct ide_port_info icside_v6_port_info __initdata = { .init_dma = icside_dma_off_init, .port_ops = &icside_v6_no_dma_port_ops, + .dma_ops = &icside_v6_dma_ops, .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, .mwdma_mask = ATA_MWDMA2, .swdma_mask = ATA_SWDMA2, @@ -515,13 +518,11 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) ecard_set_drvdata(ec, state); -#ifdef CONFIG_BLK_DEV_IDEDMA_ICS if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { d.init_dma = icside_dma_init; d.port_ops = &icside_v6_port_ops; - d.dma_ops = &icside_v6_dma_ops; - } -#endif + } else + d.dma_ops = NULL; ret = ide_host_register(host, &d, hws); if (ret) diff --git a/trunk/drivers/ide/ide-cs.c b/trunk/drivers/ide/ide-cs.c index f1e922e2479a..28e344ea514c 100644 --- a/trunk/drivers/ide/ide-cs.c +++ b/trunk/drivers/ide/ide-cs.c @@ -167,8 +167,7 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data) { int *is_kme = priv_data; - if ((pdev->resource[0]->flags & IO_DATA_PATH_WIDTH) - != IO_DATA_PATH_WIDTH_8) { + if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) { pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; } diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c index fe95d5464a02..d0f59c3f87ef 100644 --- a/trunk/drivers/idle/intel_idle.c +++ b/trunk/drivers/idle/intel_idle.c @@ -96,7 +96,6 @@ static const struct idle_cpu *icpu; static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; static int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); -static int intel_idle_cpu_init(int cpu); static struct cpuidle_state *cpuidle_state_table; @@ -303,35 +302,22 @@ static void __setup_broadcast_timer(void *arg) clockevents_notify(reason, &cpu); } -static int cpu_hotplug_notify(struct notifier_block *n, - unsigned long action, void *hcpu) +static int setup_broadcast_cpuhp_notify(struct notifier_block *n, + unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; - struct cpuidle_device *dev; switch (action & 0xf) { case CPU_ONLINE: - - if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) - smp_call_function_single(hotcpu, __setup_broadcast_timer, - (void *)true, 1); - - /* - * Some systems can hotplug a cpu at runtime after - * the kernel has booted, we have to initialize the - * driver in this case - */ - dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu); - if (!dev->registered) - intel_idle_cpu_init(hotcpu); - + smp_call_function_single(hotcpu, __setup_broadcast_timer, + (void *)true, 1); break; } return NOTIFY_OK; } -static struct notifier_block cpu_hotplug_notifier = { - .notifier_call = cpu_hotplug_notify, +static struct notifier_block setup_broadcast_notifier = { + .notifier_call = setup_broadcast_cpuhp_notify, }; static void auto_demotion_disable(void *dummy) @@ -419,10 +405,10 @@ static int intel_idle_probe(void) if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; - else + else { on_each_cpu(__setup_broadcast_timer, (void *)true, 1); - - register_cpu_notifier(&cpu_hotplug_notifier); + register_cpu_notifier(&setup_broadcast_notifier); + } pr_debug(PREFIX "v" INTEL_IDLE_VERSION " model 0x%X\n", boot_cpu_data.x86_model); @@ -508,7 +494,7 @@ static int intel_idle_cpuidle_driver_init(void) * allocate, initialize, register cpuidle_devices * @cpu: cpu/core to initialize */ -static int intel_idle_cpu_init(int cpu) +int intel_idle_cpu_init(int cpu) { int cstate; struct cpuidle_device *dev; @@ -553,6 +539,7 @@ static int intel_idle_cpu_init(int cpu) return 0; } +EXPORT_SYMBOL_GPL(intel_idle_cpu_init); static int __init intel_idle_init(void) { @@ -594,10 +581,10 @@ static void __exit intel_idle_exit(void) intel_idle_cpuidle_devices_uninit(); cpuidle_unregister_driver(&intel_idle_driver); - - if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) + if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) { on_each_cpu(__setup_broadcast_timer, (void *)false, 1); - unregister_cpu_notifier(&cpu_hotplug_notifier); + unregister_cpu_notifier(&setup_broadcast_notifier); + } return; } diff --git a/trunk/drivers/iio/Kconfig b/trunk/drivers/iio/Kconfig index 2ec93da41e2c..56eecefcec75 100644 --- a/trunk/drivers/iio/Kconfig +++ b/trunk/drivers/iio/Kconfig @@ -8,7 +8,8 @@ menuconfig IIO help The industrial I/O subsystem provides a unified framework for drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). + number of different physical interfaces (i2c, spi, etc). See + Documentation/iio for more information. if IIO diff --git a/trunk/drivers/iio/industrialio-core.c b/trunk/drivers/iio/industrialio-core.c index 4f947e4377ef..1ddd8861c71b 100644 --- a/trunk/drivers/iio/industrialio-core.c +++ b/trunk/drivers/iio/industrialio-core.c @@ -661,6 +661,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) * New channel registration method - relies on the fact a group does * not need to be initialized if it is name is NULL. */ + INIT_LIST_HEAD(&indio_dev->channel_attr_list); if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { ret = iio_device_add_channel_sysfs(indio_dev, @@ -724,16 +725,12 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - if (indio_dev->chrdev.dev) - cdev_del(&indio_dev->chrdev); + cdev_del(&indio_dev->chrdev); if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); iio_device_unregister_debugfs(indio_dev); - - ida_simple_remove(&iio_ida, indio_dev->id); - kfree(indio_dev); } static struct device_type iio_dev_type = { @@ -764,7 +761,6 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) dev_set_drvdata(&dev->dev, (void *)dev); mutex_init(&dev->mlock); mutex_init(&dev->info_exist_lock); - INIT_LIST_HEAD(&dev->channel_attr_list); dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); if (dev->id < 0) { @@ -782,8 +778,10 @@ EXPORT_SYMBOL(iio_device_alloc); void iio_device_free(struct iio_dev *dev) { - if (dev) - put_device(&dev->dev); + if (dev) { + ida_simple_remove(&iio_ida, dev->id); + kfree(dev); + } } EXPORT_SYMBOL(iio_device_free); @@ -904,7 +902,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_lock(&indio_dev->info_exist_lock); indio_dev->info = NULL; mutex_unlock(&indio_dev->info_exist_lock); - device_del(&indio_dev->dev); + device_unregister(&indio_dev->dev); } EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 2e826f9702c6..55d5642eb10a 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) { - return (((ib_event->event == IB_CM_REQ_RECEIVED) && + return (((ib_event->event == IB_CM_REQ_RECEIVED) || (ib_event->param.req_rcvd.qp_type == id->qp_type)) || ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && (id->qp_type == IB_QPT_UD)) || diff --git a/trunk/drivers/infiniband/hw/cxgb4/cm.c b/trunk/drivers/infiniband/hw/cxgb4/cm.c index b18870c455ad..55ab284e22f2 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/cm.c +++ b/trunk/drivers/infiniband/hw/cxgb4/cm.c @@ -1593,10 +1593,6 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, struct net_device *pdev; pdev = ip_dev_find(&init_net, peer_ip); - if (!pdev) { - err = -ENODEV; - goto out; - } ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, n, pdev, 0); if (!ep->l2t) diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index 3530c41fcd1f..ee1c577238f7 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -140,7 +140,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->max_mr_size = ~0ull; props->page_size_cap = dev->dev->caps.page_size_cap; props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; - props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; + props->max_qp_wr = dev->dev->caps.max_wqes; props->max_sge = min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg); props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; @@ -1084,9 +1084,12 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) int total_eqs = 0; int i, j, eq; - /* Legacy mode or comp_pool is not large enough */ - if (dev->caps.comp_pool == 0 || - dev->caps.num_ports > dev->caps.comp_pool) + /* Init eq table */ + ibdev->eq_table = NULL; + ibdev->eq_added = 0; + + /* Legacy mode? */ + if (dev->caps.comp_pool == 0) return; eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ @@ -1132,10 +1135,7 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) { int i; - - /* no additional eqs were added */ - if (!ibdev->eq_table) - return; + int total_eqs; /* Reset the advertised EQ number */ ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors; @@ -1148,7 +1148,12 @@ static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) mlx4_release_eq(dev, ibdev->eq_table[i]); } + total_eqs = dev->caps.num_comp_vectors + ibdev->eq_added; + memset(ibdev->eq_table, 0, total_eqs * sizeof(int)); kfree(ibdev->eq_table); + + ibdev->eq_table = NULL; + ibdev->eq_added = 0; } static void *mlx4_ib_add(struct mlx4_dev *dev) diff --git a/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h b/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h index ff36655d23d3..e62297cc77cc 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -44,14 +44,6 @@ #include #include -enum { - MLX4_IB_SQ_MIN_WQE_SHIFT = 6, - MLX4_IB_MAX_HEADROOM = 2048 -}; - -#define MLX4_IB_SQ_HEADROOM(shift) ((MLX4_IB_MAX_HEADROOM >> (shift)) + 1) -#define MLX4_IB_SQ_MAX_SPARE (MLX4_IB_SQ_HEADROOM(MLX4_IB_SQ_MIN_WQE_SHIFT)) - struct mlx4_ib_ucontext { struct ib_ucontext ibucontext; struct mlx4_uar uar; diff --git a/trunk/drivers/infiniband/hw/mlx4/qp.c b/trunk/drivers/infiniband/hw/mlx4/qp.c index 8d4ed24aef93..ceb33327091a 100644 --- a/trunk/drivers/infiniband/hw/mlx4/qp.c +++ b/trunk/drivers/infiniband/hw/mlx4/qp.c @@ -310,8 +310,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, int is_user, int has_rq, struct mlx4_ib_qp *qp) { /* Sanity check RQ size before proceeding */ - if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE || - cap->max_recv_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg)) + if (cap->max_recv_wr > dev->dev->caps.max_wqes || + cap->max_recv_sge > dev->dev->caps.max_rq_sg) return -EINVAL; if (!has_rq) { @@ -329,17 +329,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); } - /* leave userspace return values as they were, so as not to break ABI */ - if (is_user) { - cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; - cap->max_recv_sge = qp->rq.max_gs; - } else { - cap->max_recv_wr = qp->rq.max_post = - min(dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE, qp->rq.wqe_cnt); - cap->max_recv_sge = min(qp->rq.max_gs, - min(dev->dev->caps.max_sq_sg, - dev->dev->caps.max_rq_sg)); - } + cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; + cap->max_recv_sge = qp->rq.max_gs; return 0; } @@ -350,8 +341,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, int s; /* Sanity check SQ size before proceeding */ - if (cap->max_send_wr > (dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE) || - cap->max_send_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg) || + if (cap->max_send_wr > dev->dev->caps.max_wqes || + cap->max_send_sge > dev->dev->caps.max_sq_sg || cap->max_inline_data + send_wqe_overhead(type, qp->flags) + sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) return -EINVAL; diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h index 48970af23679..85a69c958559 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h @@ -61,7 +61,6 @@ struct ocrdma_dev_attr { u32 max_inline_data; int max_send_sge; int max_recv_sge; - int max_srq_sge; int max_mr; u64 max_mr_size; u32 max_num_mr_pbl; @@ -232,6 +231,7 @@ struct ocrdma_qp_hwq_info { u32 entry_size; u32 max_cnt; u32 max_wqe_idx; + u32 free_delta; u16 dbid; /* qid, where to ring the doorbell. */ u32 len; dma_addr_t pa; diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h index 517ab20b727c..a411a4e3193d 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h @@ -101,6 +101,8 @@ struct ocrdma_create_qp_uresp { u32 rsvd1; u32 num_wqe_allocated; u32 num_rqe_allocated; + u32 free_wqe_delta; + u32 free_rqe_delta; u32 db_sq_offset; u32 db_rq_offset; u32 db_shift; @@ -124,7 +126,8 @@ struct ocrdma_create_srq_uresp { u32 db_rq_offset; u32 db_shift; - u64 rsvd2; + u32 free_rqe_delta; + u32 rsvd2; u64 rsvd3; } __packed; diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 71942af4fce9..9b204b1ba336 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -732,7 +732,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev, break; case OCRDMA_SRQ_LIMIT_EVENT: ib_evt.element.srq = &qp->srq->ibsrq; - ib_evt.event = IB_EVENT_SRQ_LIMIT_REACHED; + ib_evt.event = IB_EVENT_QP_LAST_WQE_REACHED; srq_event = 1; qp_event = 0; break; @@ -990,6 +990,8 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, struct ocrdma_dev_attr *attr, struct ocrdma_mbx_query_config *rsp) { + int max_q_mem; + attr->max_pd = (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; @@ -1002,9 +1004,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_recv_sge = (rsp->max_write_send_sge & OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; - attr->max_srq_sge = (rsp->max_srq_rqe_sge & - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; @@ -1038,15 +1037,18 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_inline_data = attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + sizeof(struct ocrdma_sge)); + max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); + /* hw can queue one less then the configured size, + * so publish less by one to stack. + */ if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { + dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; attr->ird = 1; attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; - } - dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; - dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & - OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; + } else + dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; + dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; } static int ocrdma_check_fw_config(struct ocrdma_dev *dev, @@ -1988,12 +1990,19 @@ static void ocrdma_get_create_qp_rsp(struct ocrdma_create_qp_rsp *rsp, max_wqe_allocated = 1 << max_wqe_allocated; max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); + if (qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { + qp->sq.free_delta = 0; + qp->rq.free_delta = 1; + } else + qp->sq.free_delta = 1; + qp->sq.max_cnt = max_wqe_allocated; qp->sq.max_wqe_idx = max_wqe_allocated - 1; if (!attrs->srq) { qp->rq.max_cnt = max_rqe_allocated; qp->rq.max_wqe_idx = max_rqe_allocated - 1; + qp->rq.free_delta = 1; } } diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c index b050e629e9c3..a20d16eaae71 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -26,6 +26,7 @@ *******************************************************************/ #include +#include #include #include #include @@ -97,11 +98,13 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, sgid->raw[15] = mac_addr[5]; } -static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, +static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, bool is_vlan, u16 vlan_id) { int i; + bool found = false; union ib_gid new_sgid; + int free_idx = OCRDMA_MAX_SGID; unsigned long flags; memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); @@ -113,19 +116,23 @@ static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, sizeof(union ib_gid))) { /* found free entry */ - memcpy(&dev->sgid_tbl[i], &new_sgid, - sizeof(union ib_gid)); - spin_unlock_irqrestore(&dev->sgid_lock, flags); - return true; + if (!found) { + free_idx = i; + found = true; + break; + } } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, sizeof(union ib_gid))) { /* entry already present, no addition is required. */ spin_unlock_irqrestore(&dev->sgid_lock, flags); - return false; + return; } } + /* if entry doesn't exist and if table has some space, add entry */ + if (found) + memcpy(&dev->sgid_tbl[free_idx], &new_sgid, + sizeof(union ib_gid)); spin_unlock_irqrestore(&dev->sgid_lock, flags); - return false; } static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, @@ -161,8 +168,7 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) ocrdma_get_guid(dev, &sgid->raw[8]); } -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) +static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) { struct net_device *netdev, *tmp; u16 vlan_id; @@ -170,6 +176,8 @@ static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) netdev = dev->nic_info.netdev; + ocrdma_add_default_sgid(dev); + rcu_read_lock(); for_each_netdev_rcu(&init_net, tmp) { if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { @@ -187,23 +195,10 @@ static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) } } rcu_read_unlock(); -} -#else -static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) -{ - -} -#endif /* VLAN */ - -static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) -{ - ocrdma_add_default_sgid(dev); - ocrdma_add_vlan_sgids(dev); return 0; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ -defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static int ocrdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, void *ptr) @@ -214,7 +209,6 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, struct ib_event gid_event; struct ocrdma_dev *dev; bool found = false; - bool updated = false; bool is_vlan = false; u16 vid = 0; @@ -240,21 +234,23 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, mutex_lock(&dev->dev_lock); switch (event) { case NETDEV_UP: - updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); + ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); break; case NETDEV_DOWN: - updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); + found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); + if (found) { + /* found the matching entry, notify + * the consumers about it + */ + gid_event.device = &dev->ibdev; + gid_event.element.port_num = 1; + gid_event.event = IB_EVENT_GID_CHANGE; + ib_dispatch_event(&gid_event); + } break; default: break; } - if (updated) { - /* GID table updated, notify the consumers about it */ - gid_event.device = &dev->ibdev; - gid_event.element.port_num = 1; - gid_event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&gid_event); - } mutex_unlock(&dev->dev_lock); return NOTIFY_OK; } @@ -263,7 +259,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { .notifier_call = ocrdma_inet6addr_event }; -#endif /* IPV6 and VLAN */ +#endif /* IPV6 */ static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, u8 port_num) diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index c75cbdfa87e7..7fd80cc0f037 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -418,9 +418,6 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, - OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, - OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, @@ -461,7 +458,7 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET, + OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 2e2e7aecc990..e9f74d1b48f6 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port, dev = get_ocrdma_dev(ibdev); memset(sgid, 0, sizeof(*sgid)); - if (index >= OCRDMA_MAX_SGID) + if (index > OCRDMA_MAX_SGID) return -EINVAL; memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); @@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_LOCAL_DMA_LKEY; - attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge); - attr->max_sge_rd = 0; + attr->max_sge = dev->attr.max_send_sge; + attr->max_sge_rd = dev->attr.max_send_sge; attr->max_cq = dev->attr.max_cq; attr->max_cqe = dev->attr.max_cqe; attr->max_mr = dev->attr.max_mr; @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_srq_sge; + attr->max_srq_sge = attr->max_sge; attr->max_srq_wr = dev->attr.max_rqe; attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = 0; @@ -940,6 +940,8 @@ static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp, uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; uresp.db_shift = 16; } + uresp.free_wqe_delta = qp->sq.free_delta; + uresp.free_rqe_delta = qp->rq.free_delta; if (qp->dpp_enabled) { uresp.dpp_credit = dpp_credit_lmt; @@ -1305,6 +1307,8 @@ static int ocrdma_hwq_free_cnt(struct ocrdma_qp_hwq_info *q) free_cnt = (q->max_cnt - q->head) + q->tail; else free_cnt = q->tail - q->head; + if (q->free_delta) + free_cnt -= q->free_delta; return free_cnt; } @@ -1497,6 +1501,7 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_srq *srq, struct ib_udata *udata) (srq->pd->id * srq->dev->nic_info.db_page_size); uresp.db_page_size = srq->dev->nic_info.db_page_size; uresp.num_rqe_allocated = srq->rq.max_cnt; + uresp.free_rqe_delta = 1; if (srq->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ1_OFFSET; uresp.db_shift = 24; @@ -2301,10 +2306,8 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, *stop = true; expand = false; } - } else { - *polled = true; + } else expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); - } return expand; } diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h index 633f03d80274..e6483439f25f 100644 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h +++ b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h @@ -28,6 +28,7 @@ #ifndef __OCRDMA_VERBS_H__ #define __OCRDMA_VERBS_H__ +#include int ocrdma_post_send(struct ib_qp *, struct ib_send_wr *, struct ib_send_wr **bad_wr); int ocrdma_post_recv(struct ib_qp *, struct ib_recv_wr *, diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f10221f40803..5c1bc995e560 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -123,7 +123,7 @@ static void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv, skb_frag_size_set(frag, size); skb->data_len += size; - skb->truesize += PAGE_SIZE; + skb->truesize += size; } else skb_put(skb, length); @@ -156,18 +156,14 @@ static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id) struct ipoib_dev_priv *priv = netdev_priv(dev); struct sk_buff *skb; int buf_size; - int tailroom; u64 *mapping; - if (ipoib_ud_need_sg(priv->max_ib_mtu)) { + if (ipoib_ud_need_sg(priv->max_ib_mtu)) buf_size = IPOIB_UD_HEAD_SIZE; - tailroom = 128; /* reserve some tailroom for IP/TCP headers */ - } else { + else buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); - tailroom = 0; - } - skb = dev_alloc_skb(buf_size + tailroom + 4); + skb = dev_alloc_skb(buf_size + 4); if (unlikely(!skb)) return NULL; diff --git a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c index 7a0ce8d42887..5f6b7f63cdef 100644 --- a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1377,14 +1377,10 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) break; case SRPT_STATE_NEED_DATA: /* DMA_TO_DEVICE (write) - RDMA read error. */ - - /* XXX(hch): this is a horrible layering violation.. */ spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags); ioctx->cmd.transport_state |= CMD_T_LUN_STOP; - ioctx->cmd.transport_state &= ~CMD_T_ACTIVE; spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags); - - complete(&ioctx->cmd.transport_lun_stop_comp); + transport_generic_handle_data(&ioctx->cmd); break; case SRPT_STATE_CMD_RSP_SENT: /* @@ -1467,10 +1463,9 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, /** * srpt_handle_rdma_comp() - Process an IB RDMA completion notification. * - * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping - * the data that has been transferred via IB RDMA had to be postponed until the - * check_stop_free() callback. None of this is nessecary anymore and needs to - * be cleaned up. + * Note: transport_generic_handle_data() is asynchronous so unmapping the + * data that has been transferred via IB RDMA must be postponed until the + * check_stop_free() callback. */ static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, struct srpt_send_ioctx *ioctx, @@ -1482,7 +1477,7 @@ static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, if (opcode == SRPT_RDMA_READ_LAST) { if (srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA, SRPT_STATE_DATA_IN)) - target_execute_cmd(&ioctx->cmd); + transport_generic_handle_data(&ioctx->cmd); else printk(KERN_ERR "%s[%d]: wrong state = %d\n", __func__, __LINE__, srpt_get_cmd_state(ioctx)); diff --git a/trunk/drivers/input/joystick/as5011.c b/trunk/drivers/input/joystick/as5011.c index c96653b58867..57d19d4e0a2d 100644 --- a/trunk/drivers/input/joystick/as5011.c +++ b/trunk/drivers/input/joystick/as5011.c @@ -282,8 +282,7 @@ static int __devinit as5011_probe(struct i2c_client *client, error = request_threaded_irq(as5011->button_irq, NULL, as5011_button_interrupt, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "as5011_button", as5011); if (error < 0) { dev_err(&client->dev, @@ -297,7 +296,7 @@ static int __devinit as5011_probe(struct i2c_client *client, error = request_threaded_irq(as5011->axis_irq, NULL, as5011_axis_interrupt, - plat_data->axis_irqflags | IRQF_ONESHOT, + plat_data->axis_irqflags, "as5011_joystick", as5011); if (error) { dev_err(&client->dev, diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/input/joystick/xpad.c index 83811e45d633..ee16fb67b7ae 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/input/joystick/xpad.c @@ -142,7 +142,6 @@ static const struct xpad_device { { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, - { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, @@ -165,7 +164,6 @@ static const struct xpad_device { { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } }; @@ -240,14 +238,12 @@ static struct usb_device_id xpad_table [] = { XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ - { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ - XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ - XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ + XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ { } }; diff --git a/trunk/drivers/input/keyboard/mcs_touchkey.c b/trunk/drivers/input/keyboard/mcs_touchkey.c index 0d77f6c84950..64a0ca4c92f3 100644 --- a/trunk/drivers/input/keyboard/mcs_touchkey.c +++ b/trunk/drivers/input/keyboard/mcs_touchkey.c @@ -178,8 +178,7 @@ static int __devinit mcs_touchkey_probe(struct i2c_client *client, } error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - client->dev.driver->name, data); + IRQF_TRIGGER_FALLING, client->dev.driver->name, data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_free_mem; diff --git a/trunk/drivers/input/keyboard/mpr121_touchkey.c b/trunk/drivers/input/keyboard/mpr121_touchkey.c index 7613f1cac951..caa218a51b5a 100644 --- a/trunk/drivers/input/keyboard/mpr121_touchkey.c +++ b/trunk/drivers/input/keyboard/mpr121_touchkey.c @@ -248,7 +248,7 @@ static int __devinit mpr_touchkey_probe(struct i2c_client *client, error = request_threaded_irq(client->irq, NULL, mpr_touchkey_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING, client->dev.driver->name, mpr121); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); diff --git a/trunk/drivers/input/keyboard/qt1070.c b/trunk/drivers/input/keyboard/qt1070.c index ca68f2992d72..0b7b2f891752 100644 --- a/trunk/drivers/input/keyboard/qt1070.c +++ b/trunk/drivers/input/keyboard/qt1070.c @@ -201,8 +201,7 @@ static int __devinit qt1070_probe(struct i2c_client *client, msleep(QT1070_RESET_TIME); err = request_threaded_irq(client->irq, NULL, qt1070_interrupt, - IRQF_TRIGGER_NONE | IRQF_ONESHOT, - client->dev.driver->name, data); + IRQF_TRIGGER_NONE, client->dev.driver->name, data); if (err) { dev_err(&client->dev, "fail to request irq\n"); goto err_free_mem; diff --git a/trunk/drivers/input/keyboard/tca6416-keypad.c b/trunk/drivers/input/keyboard/tca6416-keypad.c index c355cdde8d22..3afea3f89718 100644 --- a/trunk/drivers/input/keyboard/tca6416-keypad.c +++ b/trunk/drivers/input/keyboard/tca6416-keypad.c @@ -278,8 +278,7 @@ static int __devinit tca6416_keypad_probe(struct i2c_client *client, error = request_threaded_irq(chip->irqnum, NULL, tca6416_keys_isr, - IRQF_TRIGGER_FALLING | - IRQF_ONESHOT, + IRQF_TRIGGER_FALLING, "tca6416-keypad", chip); if (error) { dev_dbg(&client->dev, diff --git a/trunk/drivers/input/keyboard/tca8418_keypad.c b/trunk/drivers/input/keyboard/tca8418_keypad.c index 893869b29ed9..5f87b28b3192 100644 --- a/trunk/drivers/input/keyboard/tca8418_keypad.c +++ b/trunk/drivers/input/keyboard/tca8418_keypad.c @@ -360,7 +360,7 @@ static int __devinit tca8418_keypad_probe(struct i2c_client *client, client->irq = gpio_to_irq(client->irq); error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING, client->name, keypad_data); if (error) { dev_dbg(&client->dev, diff --git a/trunk/drivers/input/keyboard/tnetv107x-keypad.c b/trunk/drivers/input/keyboard/tnetv107x-keypad.c index 4c34f21fbe2d..a4a445fb7020 100644 --- a/trunk/drivers/input/keyboard/tnetv107x-keypad.c +++ b/trunk/drivers/input/keyboard/tnetv107x-keypad.c @@ -227,15 +227,15 @@ static int __devinit keypad_probe(struct platform_device *pdev) goto error_clk; } - error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, - IRQF_ONESHOT, dev_name(dev), kp); + error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, + dev_name(dev), kp); if (error < 0) { dev_err(kp->dev, "Could not allocate keypad press key irq\n"); goto error_irq_press; } - error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, - IRQF_ONESHOT, dev_name(dev), kp); + error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, + dev_name(dev), kp); if (error < 0) { dev_err(kp->dev, "Could not allocate keypad release key irq\n"); goto error_irq_release; diff --git a/trunk/drivers/input/misc/ad714x.c b/trunk/drivers/input/misc/ad714x.c index 2e5d5e1de647..0ac75bbad4d6 100644 --- a/trunk/drivers/input/misc/ad714x.c +++ b/trunk/drivers/input/misc/ad714x.c @@ -972,7 +972,6 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, struct ad714x_platform_data *plat_data = dev->platform_data; struct ad714x_chip *ad714x; void *drv_mem; - unsigned long irqflags; struct ad714x_button_drv *bt_drv; struct ad714x_slider_drv *sd_drv; @@ -1163,11 +1162,10 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, alloc_idx++; } - irqflags = plat_data->irqflags ?: IRQF_TRIGGER_FALLING; - irqflags |= IRQF_ONESHOT; - error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, - irqflags, "ad714x_captouch", ad714x); + plat_data->irqflags ? + plat_data->irqflags : IRQF_TRIGGER_FALLING, + "ad714x_captouch", ad714x); if (error) { dev_err(dev, "can't allocate irq %d\n", ad714x->irq); goto err_unreg_dev; diff --git a/trunk/drivers/input/misc/dm355evm_keys.c b/trunk/drivers/input/misc/dm355evm_keys.c index c1313d8535c3..35083c6836c3 100644 --- a/trunk/drivers/input/misc/dm355evm_keys.c +++ b/trunk/drivers/input/misc/dm355evm_keys.c @@ -213,8 +213,7 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) /* REVISIT: flush the event queue? */ status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - dev_name(&pdev->dev), keys); + IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); if (status < 0) goto fail2; diff --git a/trunk/drivers/input/mouse/bcm5974.c b/trunk/drivers/input/mouse/bcm5974.c index d528c23e194f..2cf681d98c0d 100644 --- a/trunk/drivers/input/mouse/bcm5974.c +++ b/trunk/drivers/input/mouse/bcm5974.c @@ -79,10 +79,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 -/* MacbookPro10,1 (unibody, June 2012) */ -#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 -#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 -#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 #define BCM5974_DEVICE(prod) { \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ @@ -132,10 +128,6 @@ static const struct usb_device_id bcm5974_table[] = { BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), - /* MacbookPro10,1 */ - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), /* Terminating entry */ {} }; @@ -362,18 +354,6 @@ static const struct bcm5974_config bcm5974_config_table[] = { { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } }, - { - USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, - USB_DEVICE_ID_APPLE_WELLSPRING7_ISO, - USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, - HAS_INTEGRATED_BUTTON, - 0x84, sizeof(struct bt_data), - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } - }, {} }; diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index 8b31473a81fe..cad5602d3ce4 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -216,7 +216,7 @@ static void wacom_retrieve_report_data(struct usb_interface *intf, rep_data[0] = 12; result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, - rep_data[0], rep_data, 2, + rep_data[0], &rep_data, 2, WAC_MSG_RETRIES); if (result >= 0 && rep_data[1] > 2) @@ -401,9 +401,7 @@ static int wacom_parse_hid(struct usb_interface *intf, break; case HID_USAGE_CONTACTMAX: - /* leave touch_max as is if predefined */ - if (!features->touch_max) - wacom_retrieve_report_data(intf, features); + wacom_retrieve_report_data(intf, features); i++; break; } diff --git a/trunk/drivers/input/touchscreen/ad7879.c b/trunk/drivers/input/touchscreen/ad7879.c index bd4eb4277697..e2482b40da51 100644 --- a/trunk/drivers/input/touchscreen/ad7879.c +++ b/trunk/drivers/input/touchscreen/ad7879.c @@ -597,7 +597,7 @@ struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq, AD7879_TMR(ts->pen_down_acc_interval); err = request_threaded_irq(ts->irq, NULL, ad7879_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING, dev_name(dev), ts); if (err) { dev_err(dev, "irq %d busy?\n", ts->irq); diff --git a/trunk/drivers/input/touchscreen/atmel_mxt_ts.c b/trunk/drivers/input/touchscreen/atmel_mxt_ts.c index 25fd0561a17d..42e645062c20 100644 --- a/trunk/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/trunk/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1149,8 +1149,7 @@ static int __devinit mxt_probe(struct i2c_client *client, goto err_free_object; error = request_threaded_irq(client->irq, NULL, mxt_interrupt, - pdata->irqflags | IRQF_ONESHOT, - client->dev.driver->name, data); + pdata->irqflags, client->dev.driver->name, data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_free_object; diff --git a/trunk/drivers/input/touchscreen/bu21013_ts.c b/trunk/drivers/input/touchscreen/bu21013_ts.c index 5c487d23f11c..f2d03c06c2da 100644 --- a/trunk/drivers/input/touchscreen/bu21013_ts.c +++ b/trunk/drivers/input/touchscreen/bu21013_ts.c @@ -509,8 +509,7 @@ static int __devinit bu21013_probe(struct i2c_client *client, input_set_drvdata(in_dev, bu21013_data); error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, - IRQF_TRIGGER_FALLING | IRQF_SHARED | - IRQF_ONESHOT, + IRQF_TRIGGER_FALLING | IRQF_SHARED, DRIVER_TP, bu21013_data); if (error) { dev_err(&client->dev, "request irq %d failed\n", pdata->irq); diff --git a/trunk/drivers/input/touchscreen/cy8ctmg110_ts.c b/trunk/drivers/input/touchscreen/cy8ctmg110_ts.c index 464f1bf4b61d..237753ad1031 100644 --- a/trunk/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/trunk/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -251,8 +251,7 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, } err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "touch_reset_key", ts); + IRQF_TRIGGER_RISING, "touch_reset_key", ts); if (err < 0) { dev_err(&client->dev, "irq %d busy? error %d\n", client->irq, err); diff --git a/trunk/drivers/input/touchscreen/intel-mid-touch.c b/trunk/drivers/input/touchscreen/intel-mid-touch.c index cf299377fc49..3cd7a837f82b 100644 --- a/trunk/drivers/input/touchscreen/intel-mid-touch.c +++ b/trunk/drivers/input/touchscreen/intel-mid-touch.c @@ -620,7 +620,7 @@ static int __devinit mrstouch_probe(struct platform_device *pdev) MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, - IRQF_ONESHOT, "mrstouch", tsdev); + 0, "mrstouch", tsdev); if (err) { dev_err(tsdev->dev, "unable to allocate irq\n"); goto err_free_mem; diff --git a/trunk/drivers/input/touchscreen/pixcir_i2c_ts.c b/trunk/drivers/input/touchscreen/pixcir_i2c_ts.c index 953b4c105cad..72f6ba3a4709 100644 --- a/trunk/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/trunk/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -165,7 +165,7 @@ static int __devinit pixcir_i2c_ts_probe(struct i2c_client *client, input_set_drvdata(input, tsdata); error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING, client->name, tsdata); if (error) { dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); diff --git a/trunk/drivers/input/touchscreen/tnetv107x-ts.c b/trunk/drivers/input/touchscreen/tnetv107x-ts.c index 368d2c6cf780..7e7488097359 100644 --- a/trunk/drivers/input/touchscreen/tnetv107x-ts.c +++ b/trunk/drivers/input/touchscreen/tnetv107x-ts.c @@ -297,7 +297,7 @@ static int __devinit tsc_probe(struct platform_device *pdev) goto error_clk; } - error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, IRQF_ONESHOT, + error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, 0, dev_name(dev), ts); if (error < 0) { dev_err(ts->dev, "Could not allocate ts irq\n"); diff --git a/trunk/drivers/input/touchscreen/tsc2005.c b/trunk/drivers/input/touchscreen/tsc2005.c index 5ce3fa8ce646..b6adeaee9cc5 100644 --- a/trunk/drivers/input/touchscreen/tsc2005.c +++ b/trunk/drivers/input/touchscreen/tsc2005.c @@ -650,8 +650,7 @@ static int __devinit tsc2005_probe(struct spi_device *spi) tsc2005_stop_scan(ts); error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "tsc2005", ts); + IRQF_TRIGGER_RISING, "tsc2005", ts); if (error) { dev_err(&spi->dev, "Failed to request irq, err: %d\n", error); goto err_free_mem; diff --git a/trunk/drivers/iommu/amd_iommu.c b/trunk/drivers/iommu/amd_iommu.c index 625626391f2d..d90a421e9cac 100644 --- a/trunk/drivers/iommu/amd_iommu.c +++ b/trunk/drivers/iommu/amd_iommu.c @@ -83,8 +83,6 @@ static struct iommu_ops amd_iommu_ops; static ATOMIC_NOTIFIER_HEAD(ppr_notifier); int amd_iommu_max_glx_val = -1; -static struct dma_map_ops amd_iommu_dma_ops; - /* * general struct to manage commands send to an IOMMU */ @@ -404,7 +402,7 @@ static void amd_iommu_stats_init(void) return; de_fflush = debugfs_create_bool("fullflush", 0444, stats_dir, - &amd_iommu_unmap_flush); + (u32 *)&amd_iommu_unmap_flush); amd_iommu_stats_add(&compl_wait); amd_iommu_stats_add(&cnt_map_single); @@ -549,12 +547,26 @@ static void iommu_poll_events(struct amd_iommu *iommu) spin_unlock_irqrestore(&iommu->lock, flags); } -static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) +static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head) { struct amd_iommu_fault fault; + volatile u64 *raw; + int i; INC_STATS_COUNTER(pri_requests); + raw = (u64 *)(iommu->ppr_log + head); + + /* + * Hardware bug: Interrupt may arrive before the entry is written to + * memory. If this happens we need to wait for the entry to arrive. + */ + for (i = 0; i < LOOP_TIMEOUT; ++i) { + if (PPR_REQ_TYPE(raw[0]) != 0) + break; + udelay(1); + } + if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) { pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n"); return; @@ -566,6 +578,12 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) fault.tag = PPR_TAG(raw[0]); fault.flags = PPR_FLAGS(raw[0]); + /* + * To detect the hardware bug we need to clear the entry + * to back to zero. + */ + raw[0] = raw[1] = 0; + atomic_notifier_call_chain(&ppr_notifier, 0, &fault); } @@ -577,62 +595,25 @@ static void iommu_poll_ppr_log(struct amd_iommu *iommu) if (iommu->ppr_log == NULL) return; - /* enable ppr interrupts again */ - writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); - spin_lock_irqsave(&iommu->lock, flags); head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); while (head != tail) { - volatile u64 *raw; - u64 entry[2]; - int i; - - raw = (u64 *)(iommu->ppr_log + head); - - /* - * Hardware bug: Interrupt may arrive before the entry is - * written to memory. If this happens we need to wait for the - * entry to arrive. - */ - for (i = 0; i < LOOP_TIMEOUT; ++i) { - if (PPR_REQ_TYPE(raw[0]) != 0) - break; - udelay(1); - } - /* Avoid memcpy function-call overhead */ - entry[0] = raw[0]; - entry[1] = raw[1]; - - /* - * To detect the hardware bug we need to clear the entry - * back to zero. - */ - raw[0] = raw[1] = 0UL; + /* Handle PPR entry */ + iommu_handle_ppr_entry(iommu, head); - /* Update head pointer of hardware ring-buffer */ + /* Update and refresh ring-buffer state*/ head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); - - /* - * Release iommu->lock because ppr-handling might need to - * re-aquire it - */ - spin_unlock_irqrestore(&iommu->lock, flags); - - /* Handle PPR entry */ - iommu_handle_ppr_entry(iommu, entry); - - spin_lock_irqsave(&iommu->lock, flags); - - /* Refresh ring-buffer information */ - head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); } + /* enable ppr interrupts again */ + writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); + spin_unlock_irqrestore(&iommu->lock, flags); } @@ -2269,13 +2250,6 @@ static int device_change_notifier(struct notifier_block *nb, list_add_tail(&dma_domain->list, &iommu_pd_list); spin_unlock_irqrestore(&iommu_pd_list_lock, flags); - dev_data = get_dev_data(dev); - - if (!dev_data->passthrough) - dev->archdata.dma_ops = &amd_iommu_dma_ops; - else - dev->archdata.dma_ops = &nommu_dma_ops; - break; case BUS_NOTIFY_DEL_DEVICE: diff --git a/trunk/drivers/iommu/amd_iommu_init.c b/trunk/drivers/iommu/amd_iommu_init.c index a33612f3206f..c56790375e0f 100644 --- a/trunk/drivers/iommu/amd_iommu_init.c +++ b/trunk/drivers/iommu/amd_iommu_init.c @@ -129,7 +129,7 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have to handle */ LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings we find in ACPI */ -u32 amd_iommu_unmap_flush; /* if true, flush on every unmap */ +bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the system */ @@ -1029,9 +1029,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) if (!iommu->dev) return 1; - iommu->root_pdev = pci_get_bus_and_slot(iommu->dev->bus->number, - PCI_DEVFN(0, 0)); - iommu->cap_ptr = h->cap_ptr; iommu->pci_seg = h->pci_seg; iommu->mmio_phys = h->mmio_phys; @@ -1326,16 +1323,20 @@ static void iommu_apply_resume_quirks(struct amd_iommu *iommu) { int i, j; u32 ioc_feature_control; - struct pci_dev *pdev = iommu->root_pdev; + struct pci_dev *pdev = NULL; /* RD890 BIOSes may not have completely reconfigured the iommu */ - if (!is_rd890_iommu(iommu->dev) || !pdev) + if (!is_rd890_iommu(iommu->dev)) return; /* * First, we need to ensure that the iommu is enabled. This is * controlled by a register in the northbridge */ + pdev = pci_get_bus_and_slot(iommu->dev->bus->number, PCI_DEVFN(0, 0)); + + if (!pdev) + return; /* Select Northbridge indirect register 0x75 and enable writing */ pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7)); @@ -1345,6 +1346,8 @@ static void iommu_apply_resume_quirks(struct amd_iommu *iommu) if (!(ioc_feature_control & 0x1)) pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1); + pci_dev_put(pdev); + /* Restore the iommu BAR */ pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4, iommu->stored_addr_lo); @@ -1641,8 +1644,6 @@ static int __init amd_iommu_init(void) amd_iommu_init_api(); - x86_platform.iommu_shutdown = disable_iommus; - if (iommu_pass_through) goto out; @@ -1651,6 +1652,8 @@ static int __init amd_iommu_init(void) else printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n"); + x86_platform.iommu_shutdown = disable_iommus; + out: return ret; diff --git a/trunk/drivers/iommu/amd_iommu_types.h b/trunk/drivers/iommu/amd_iommu_types.h index c1b1d489817e..2452f3b71736 100644 --- a/trunk/drivers/iommu/amd_iommu_types.h +++ b/trunk/drivers/iommu/amd_iommu_types.h @@ -481,9 +481,6 @@ struct amd_iommu { /* Pointer to PCI device of this IOMMU */ struct pci_dev *dev; - /* Cache pdev to root device for resume quirks */ - struct pci_dev *root_pdev; - /* physical address of MMIO space */ u64 mmio_phys; /* virtual address of MMIO space */ @@ -652,7 +649,7 @@ extern unsigned long *amd_iommu_pd_alloc_bitmap; * If true, the addresses will be flushed on unmap time, not when * they are reused */ -extern u32 amd_iommu_unmap_flush; +extern bool amd_iommu_unmap_flush; /* Smallest number of PASIDs supported by any IOMMU in the system */ extern u32 amd_iommu_max_pasids; diff --git a/trunk/drivers/iommu/dmar.c b/trunk/drivers/iommu/dmar.c index 86e2f4a62b9a..3a74e4410fc0 100644 --- a/trunk/drivers/iommu/dmar.c +++ b/trunk/drivers/iommu/dmar.c @@ -26,8 +26,6 @@ * These routines are used by both DMA-remapping and Interrupt-remapping */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* has to precede printk.h */ - #include #include #include @@ -41,6 +39,8 @@ #include #include +#define PREFIX "DMAR: " + /* No locks are needed as DMA remapping hardware unit * list is constructed at boot time and hotplug of * these units are not supported by the architecture. @@ -83,12 +83,16 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, * ignore it */ if (!bus) { - pr_warn("Device scope bus [%d] not found\n", scope->bus); + printk(KERN_WARNING + PREFIX "Device scope bus [%d] not found\n", + scope->bus); break; } pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn)); if (!pdev) { - /* warning will be printed below */ + printk(KERN_WARNING PREFIX + "Device scope device [%04x:%02x:%02x.%02x] not found\n", + segment, bus->number, path->dev, path->fn); break; } path ++; @@ -96,8 +100,9 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, bus = pdev->subordinate; } if (!pdev) { - pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n", - segment, scope->bus, path->dev, path->fn); + printk(KERN_WARNING PREFIX + "Device scope device [%04x:%02x:%02x.%02x] not found\n", + segment, scope->bus, path->dev, path->fn); *dev = NULL; return 0; } @@ -105,8 +110,9 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, pdev->subordinate) || (scope->entry_type == \ ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) { pci_dev_put(pdev); - pr_warn("Device scope type does not match for %s\n", - pci_name(pdev)); + printk(KERN_WARNING PREFIX + "Device scope type does not match for %s\n", + pci_name(pdev)); return -EINVAL; } *dev = pdev; @@ -128,7 +134,8 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) (*cnt)++; else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) { - pr_warn("Unsupported device scope\n"); + printk(KERN_WARNING PREFIX + "Unsupported device scope\n"); } start += scope->length; } @@ -254,23 +261,25 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) case ACPI_DMAR_TYPE_HARDWARE_UNIT: drhd = container_of(header, struct acpi_dmar_hardware_unit, header); - pr_info("DRHD base: %#016Lx flags: %#x\n", + printk (KERN_INFO PREFIX + "DRHD base: %#016Lx flags: %#x\n", (unsigned long long)drhd->address, drhd->flags); break; case ACPI_DMAR_TYPE_RESERVED_MEMORY: rmrr = container_of(header, struct acpi_dmar_reserved_memory, header); - pr_info("RMRR base: %#016Lx end: %#016Lx\n", + printk (KERN_INFO PREFIX + "RMRR base: %#016Lx end: %#016Lx\n", (unsigned long long)rmrr->base_address, (unsigned long long)rmrr->end_address); break; case ACPI_DMAR_TYPE_ATSR: atsr = container_of(header, struct acpi_dmar_atsr, header); - pr_info("ATSR flags: %#x\n", atsr->flags); + printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags); break; case ACPI_DMAR_HARDWARE_AFFINITY: rhsa = container_of(header, struct acpi_dmar_rhsa, header); - pr_info("RHSA base: %#016Lx proximity domain: %#x\n", + printk(KERN_INFO PREFIX "RHSA base: %#016Lx proximity domain: %#x\n", (unsigned long long)rhsa->base_address, rhsa->proximity_domain); break; @@ -290,7 +299,7 @@ static int __init dmar_table_detect(void) &dmar_tbl_size); if (ACPI_SUCCESS(status) && !dmar_tbl) { - pr_warn("Unable to map DMAR\n"); + printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); status = AE_NOT_FOUND; } @@ -324,18 +333,20 @@ parse_dmar_table(void) return -ENODEV; if (dmar->width < PAGE_SHIFT - 1) { - pr_warn("Invalid DMAR haw\n"); + printk(KERN_WARNING PREFIX "Invalid DMAR haw\n"); return -EINVAL; } - pr_info("Host address width %d\n", dmar->width + 1); + printk (KERN_INFO PREFIX "Host address width %d\n", + dmar->width + 1); entry_header = (struct acpi_dmar_header *)(dmar + 1); while (((unsigned long)entry_header) < (((unsigned long)dmar) + dmar_tbl->length)) { /* Avoid looping forever on bad ACPI tables */ if (entry_header->length == 0) { - pr_warn("Invalid 0-length structure\n"); + printk(KERN_WARNING PREFIX + "Invalid 0-length structure\n"); ret = -EINVAL; break; } @@ -358,7 +369,8 @@ parse_dmar_table(void) #endif break; default: - pr_warn("Unknown DMAR structure type %d\n", + printk(KERN_WARNING PREFIX + "Unknown DMAR structure type %d\n", entry_header->type); ret = 0; /* for forward compatibility */ break; @@ -457,12 +469,12 @@ int __init dmar_table_init(void) ret = parse_dmar_table(); if (ret) { if (ret != -ENODEV) - pr_info("parse DMAR table failure.\n"); + printk(KERN_INFO PREFIX "parse DMAR table failure.\n"); return ret; } if (list_empty(&dmar_drhd_units)) { - pr_info("No DMAR devices found\n"); + printk(KERN_INFO PREFIX "No DMAR devices found\n"); return -ENODEV; } @@ -494,7 +506,8 @@ int __init check_zero_address(void) (((unsigned long)dmar) + dmar_tbl->length)) { /* Avoid looping forever on bad ACPI tables */ if (entry_header->length == 0) { - pr_warn("Invalid 0-length structure\n"); + printk(KERN_WARNING PREFIX + "Invalid 0-length structure\n"); return 0; } @@ -545,7 +558,8 @@ int __init detect_intel_iommu(void) if (ret && irq_remapping_enabled && cpu_has_x2apic && dmar->flags & 0x1) - pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); + printk(KERN_INFO + "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { iommu_detected = 1; @@ -565,89 +579,14 @@ int __init detect_intel_iommu(void) } -static void unmap_iommu(struct intel_iommu *iommu) -{ - iounmap(iommu->reg); - release_mem_region(iommu->reg_phys, iommu->reg_size); -} - -/** - * map_iommu: map the iommu's registers - * @iommu: the iommu to map - * @phys_addr: the physical address of the base resgister - * - * Memory map the iommu's registers. Start w/ a single page, and - * possibly expand if that turns out to be insufficent. - */ -static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) -{ - int map_size, err=0; - - iommu->reg_phys = phys_addr; - iommu->reg_size = VTD_PAGE_SIZE; - - if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) { - pr_err("IOMMU: can't reserve memory\n"); - err = -EBUSY; - goto out; - } - - iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); - if (!iommu->reg) { - pr_err("IOMMU: can't map the region\n"); - err = -ENOMEM; - goto release; - } - - iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); - iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); - - if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { - err = -EINVAL; - warn_invalid_dmar(phys_addr, " returns all ones"); - goto unmap; - } - - /* the registers might be more than one page */ - map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), - cap_max_fault_reg_offset(iommu->cap)); - map_size = VTD_PAGE_ALIGN(map_size); - if (map_size > iommu->reg_size) { - iounmap(iommu->reg); - release_mem_region(iommu->reg_phys, iommu->reg_size); - iommu->reg_size = map_size; - if (!request_mem_region(iommu->reg_phys, iommu->reg_size, - iommu->name)) { - pr_err("IOMMU: can't reserve memory\n"); - err = -EBUSY; - goto out; - } - iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); - if (!iommu->reg) { - pr_err("IOMMU: can't map the region\n"); - err = -ENOMEM; - goto release; - } - } - err = 0; - goto out; - -unmap: - iounmap(iommu->reg); -release: - release_mem_region(iommu->reg_phys, iommu->reg_size); -out: - return err; -} - int alloc_iommu(struct dmar_drhd_unit *drhd) { struct intel_iommu *iommu; + int map_size; u32 ver; static int iommu_allocated = 0; int agaw = 0; int msagaw = 0; - int err; if (!drhd->reg_base_addr) { warn_invalid_dmar(0, ""); @@ -661,22 +600,30 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->seq_id = iommu_allocated++; sprintf (iommu->name, "dmar%d", iommu->seq_id); - err = map_iommu(iommu, drhd->reg_base_addr); - if (err) { - pr_err("IOMMU: failed to map %s\n", iommu->name); + iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE); + if (!iommu->reg) { + printk(KERN_ERR "IOMMU: can't map the region\n"); goto error; } + iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); + iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); + + if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { + warn_invalid_dmar(drhd->reg_base_addr, " returns all ones"); + goto err_unmap; + } - err = -EINVAL; agaw = iommu_calculate_agaw(iommu); if (agaw < 0) { - pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", - iommu->seq_id); + printk(KERN_ERR + "Cannot get a valid agaw for iommu (seq_id = %d)\n", + iommu->seq_id); goto err_unmap; } msagaw = iommu_calculate_max_sagaw(iommu); if (msagaw < 0) { - pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n", + printk(KERN_ERR + "Cannot get a valid max agaw for iommu (seq_id = %d)\n", iommu->seq_id); goto err_unmap; } @@ -685,6 +632,19 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->node = -1; + /* the registers might be more than one page */ + map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), + cap_max_fault_reg_offset(iommu->cap)); + map_size = VTD_PAGE_ALIGN(map_size); + if (map_size > VTD_PAGE_SIZE) { + iounmap(iommu->reg); + iommu->reg = ioremap(drhd->reg_base_addr, map_size); + if (!iommu->reg) { + printk(KERN_ERR "IOMMU: can't map the region\n"); + goto error; + } + } + ver = readl(iommu->reg + DMAR_VER_REG); pr_info("IOMMU %d: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", iommu->seq_id, @@ -699,10 +659,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) return 0; err_unmap: - unmap_iommu(iommu); + iounmap(iommu->reg); error: kfree(iommu); - return err; + return -1; } void free_iommu(struct intel_iommu *iommu) @@ -713,8 +673,7 @@ void free_iommu(struct intel_iommu *iommu) free_dmar_iommu(iommu); if (iommu->reg) - unmap_iommu(iommu); - + iounmap(iommu->reg); kfree(iommu); } @@ -751,7 +710,7 @@ static int qi_check_fault(struct intel_iommu *iommu, int index) if (fault & DMA_FSTS_IQE) { head = readl(iommu->reg + DMAR_IQH_REG); if ((head >> DMAR_IQ_SHIFT) == index) { - pr_err("VT-d detected invalid descriptor: " + printk(KERN_ERR "VT-d detected invalid descriptor: " "low=%llx, high=%llx\n", (unsigned long long)qi->desc[index].low, (unsigned long long)qi->desc[index].high); @@ -1170,14 +1129,15 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type, reason = dmar_get_fault_reason(fault_reason, &fault_type); if (fault_type == INTR_REMAP) - pr_err("INTR-REMAP: Request device [[%02x:%02x.%d] " + printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] " "fault index %llx\n" "INTR-REMAP:[fault reason %02d] %s\n", (source_id >> 8), PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr >> 48, fault_reason, reason); else - pr_err("DMAR:[%s] Request device [%02x:%02x.%d] " + printk(KERN_ERR + "DMAR:[%s] Request device [%02x:%02x.%d] " "fault addr %llx \n" "DMAR:[fault reason %02d] %s\n", (type ? "DMA Read" : "DMA Write"), @@ -1197,7 +1157,8 @@ irqreturn_t dmar_fault(int irq, void *dev_id) raw_spin_lock_irqsave(&iommu->register_lock, flag); fault_status = readl(iommu->reg + DMAR_FSTS_REG); if (fault_status) - pr_err("DRHD: handling fault status reg %x\n", fault_status); + printk(KERN_ERR "DRHD: handling fault status reg %x\n", + fault_status); /* TBD: ignore advanced fault log currently */ if (!(fault_status & DMA_FSTS_PPF)) @@ -1263,7 +1224,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) irq = create_irq(); if (!irq) { - pr_err("IOMMU: no free vectors\n"); + printk(KERN_ERR "IOMMU: no free vectors\n"); return -EINVAL; } @@ -1280,7 +1241,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); if (ret) - pr_err("IOMMU: can't request irq\n"); + printk(KERN_ERR "IOMMU: can't request irq\n"); return ret; } @@ -1297,7 +1258,8 @@ int __init enable_drhd_fault_handling(void) ret = dmar_set_interrupt(iommu); if (ret) { - pr_err("DRHD %Lx: failed to enable fault, interrupt, ret %d\n", + printk(KERN_ERR "DRHD %Lx: failed to enable fault, " + " interrupt, ret %d\n", (unsigned long long)drhd->reg_base_addr, ret); return -1; } diff --git a/trunk/drivers/iommu/intel_irq_remapping.c b/trunk/drivers/iommu/intel_irq_remapping.c index e0b18f3ae9a8..6d347064b8b0 100644 --- a/trunk/drivers/iommu/intel_irq_remapping.c +++ b/trunk/drivers/iommu/intel_irq_remapping.c @@ -902,6 +902,7 @@ static int intel_setup_ioapic_entry(int irq, return 0; } +#ifdef CONFIG_SMP /* * Migrate the IO-APIC irq in the presence of intr-remapping. * @@ -923,10 +924,6 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irq_cfg *cfg = data->chip_data; unsigned int dest, irq = data->irq; struct irte irte; - int err; - - if (!config_enabled(CONFIG_SMP)) - return -EINVAL; if (!cpumask_intersects(mask, cpu_online_mask)) return -EINVAL; @@ -934,16 +931,10 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, if (get_irte(irq, &irte)) return -EBUSY; - err = assign_irq_vector(irq, cfg, mask); - if (err) - return err; + if (assign_irq_vector(irq, cfg, mask)) + return -EBUSY; - err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest); - if (err) { - if (assign_irq_vector(irq, cfg, data->affinity)) - pr_err("Failed to recover vector for irq %d\n", irq); - return err; - } + dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); irte.vector = cfg->vector; irte.dest_id = IRTE_DEST(dest); @@ -965,6 +956,7 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, cpumask_copy(data->affinity, mask); return 0; } +#endif static void intel_compose_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, @@ -1066,7 +1058,9 @@ struct irq_remap_ops intel_irq_remap_ops = { .reenable = reenable_irq_remapping, .enable_faulting = enable_drhd_fault_handling, .setup_ioapic_entry = intel_setup_ioapic_entry, +#ifdef CONFIG_SMP .set_affinity = intel_ioapic_set_affinity, +#endif .free_irq = free_irte, .compose_msi_msg = intel_compose_msi_msg, .msi_alloc_irq = intel_msi_alloc_irq, diff --git a/trunk/drivers/iommu/irq_remapping.c b/trunk/drivers/iommu/irq_remapping.c index 1d29b1c66e72..40cda8e98d87 100644 --- a/trunk/drivers/iommu/irq_remapping.c +++ b/trunk/drivers/iommu/irq_remapping.c @@ -111,15 +111,16 @@ int setup_ioapic_remapped_entry(int irq, vector, attr); } +#ifdef CONFIG_SMP int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - if (!config_enabled(CONFIG_SMP) || !remap_ops || - !remap_ops->set_affinity) + if (!remap_ops || !remap_ops->set_affinity) return 0; return remap_ops->set_affinity(data, mask, force); } +#endif void free_remapped_irq(int irq) { diff --git a/trunk/drivers/iommu/irq_remapping.h b/trunk/drivers/iommu/irq_remapping.h index b12974cc1dfe..be9d72950c51 100644 --- a/trunk/drivers/iommu/irq_remapping.h +++ b/trunk/drivers/iommu/irq_remapping.h @@ -59,9 +59,11 @@ struct irq_remap_ops { unsigned int, int, struct io_apic_irq_attr *); +#ifdef CONFIG_SMP /* Set the CPU affinity of a remapped interrupt */ int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, bool force); +#endif /* Free an IRQ */ int (*free_irq)(int); diff --git a/trunk/drivers/iommu/tegra-smmu.c b/trunk/drivers/iommu/tegra-smmu.c index 3f3d09d560ea..ecd679043d77 100644 --- a/trunk/drivers/iommu/tegra-smmu.c +++ b/trunk/drivers/iommu/tegra-smmu.c @@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as) return 0; as->pte_count = devm_kzalloc(smmu->dev, - sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC); + sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL); if (!as->pte_count) { dev_err(smmu->dev, "failed to allocate smmu_device PTE cunters\n"); return -ENOMEM; } - as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA); + as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA); if (!as->pdir_page) { dev_err(smmu->dev, "failed to allocate smmu_device page directory\n"); diff --git a/trunk/drivers/isdn/mISDN/stack.c b/trunk/drivers/isdn/mISDN/stack.c index 5f21f629b7ae..1a0ae4445ff2 100644 --- a/trunk/drivers/isdn/mISDN/stack.c +++ b/trunk/drivers/isdn/mISDN/stack.c @@ -135,8 +135,8 @@ send_layer2(struct mISDNstack *st, struct sk_buff *skb) skb = NULL; else if (*debug & DEBUG_SEND_ERR) printk(KERN_DEBUG - "%s mgr prim(%x) err %d\n", - __func__, hh->prim, ret); + "%s ch%d mgr prim(%x) addr(%x) err %d\n", + __func__, ch->nr, hh->prim, ch->addr, ret); } out: mutex_unlock(&st->lmutex); diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 12b2b55c519e..04cb8c88d74b 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -379,7 +379,7 @@ config LEDS_NETXBIG config LEDS_ASIC3 bool "LED support for the HTC ASIC3" - depends on LEDS_CLASS=y + depends on LEDS_CLASS depends on MFD_ASIC3 default y help @@ -390,7 +390,7 @@ config LEDS_ASIC3 config LEDS_RENESAS_TPU bool "LED support for Renesas TPU" - depends on LEDS_CLASS=y && HAVE_CLK && GENERIC_GPIO + depends on LEDS_CLASS && HAVE_CLK && GENERIC_GPIO help This option enables build of the LED TPU platform driver, suitable to drive any TPU channel on newer Renesas SoCs. diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c index e663e6f413e9..8ee92c81aec2 100644 --- a/trunk/drivers/leds/led-class.c +++ b/trunk/drivers/leds/led-class.c @@ -29,7 +29,7 @@ static void led_update_brightness(struct led_classdev *led_cdev) led_cdev->brightness = led_cdev->brightness_get(led_cdev); } -static ssize_t led_brightness_show(struct device *dev, +static ssize_t led_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); diff --git a/trunk/drivers/leds/led-core.c b/trunk/drivers/leds/led-core.c index d65353d8d3fc..d6860043f6f9 100644 --- a/trunk/drivers/leds/led-core.c +++ b/trunk/drivers/leds/led-core.c @@ -44,6 +44,13 @@ static void led_set_software_blink(struct led_classdev *led_cdev, if (!led_cdev->blink_brightness) led_cdev->blink_brightness = led_cdev->max_brightness; + if (led_get_trigger_data(led_cdev) && + delay_on == led_cdev->blink_delay_on && + delay_off == led_cdev->blink_delay_off) + return; + + led_stop_software_blink(led_cdev); + led_cdev->blink_delay_on = delay_on; led_cdev->blink_delay_off = delay_off; diff --git a/trunk/drivers/leds/ledtrig-heartbeat.c b/trunk/drivers/leds/ledtrig-heartbeat.c index a019fbb70880..41dc76db4311 100644 --- a/trunk/drivers/leds/ledtrig-heartbeat.c +++ b/trunk/drivers/leds/ledtrig-heartbeat.c @@ -21,8 +21,6 @@ #include #include "leds.h" -static int panic_heartbeats; - struct heartbeat_trig_data { unsigned int phase; unsigned int period; @@ -36,11 +34,6 @@ static void led_heartbeat_function(unsigned long data) unsigned long brightness = LED_OFF; unsigned long delay = 0; - if (unlikely(panic_heartbeats)) { - led_set_brightness(led_cdev, LED_OFF); - return; - } - /* acts like an actual heart beat -- ie thump-thump-pause... */ switch (heartbeat_data->phase) { case 0: @@ -118,19 +111,12 @@ static int heartbeat_reboot_notifier(struct notifier_block *nb, return NOTIFY_DONE; } -static int heartbeat_panic_notifier(struct notifier_block *nb, - unsigned long code, void *unused) -{ - panic_heartbeats = 1; - return NOTIFY_DONE; -} - static struct notifier_block heartbeat_reboot_nb = { .notifier_call = heartbeat_reboot_notifier, }; static struct notifier_block heartbeat_panic_nb = { - .notifier_call = heartbeat_panic_notifier, + .notifier_call = heartbeat_reboot_notifier, }; static int __init heartbeat_trig_init(void) diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index b58b7a33914a..d039de8322f0 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -1084,7 +1084,6 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->split_io = dm_rh_get_region_size(ms->rh); ti->num_flush_requests = 1; ti->num_discard_requests = 1; - ti->discard_zeroes_data_unsupported = 1; ms->kmirrord_wq = alloc_workqueue("kmirrord", WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); @@ -1215,7 +1214,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, * We need to dec pending if this was a write. */ if (rw == WRITE) { - if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) + if (!(bio->bi_rw & REQ_FLUSH)) dm_rh_dec(ms->rh, map_context->ll); return error; } diff --git a/trunk/drivers/md/dm-region-hash.c b/trunk/drivers/md/dm-region-hash.c index 69732e03eb34..7771ed212182 100644 --- a/trunk/drivers/md/dm-region-hash.c +++ b/trunk/drivers/md/dm-region-hash.c @@ -404,9 +404,6 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) return; } - if (bio->bi_rw & REQ_DISCARD) - return; - /* We must inform the log that the sync count has changed. */ log->type->set_region_sync(log, region, 0); @@ -527,7 +524,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) struct bio *bio; for (bio = bios->head; bio; bio = bio->bi_next) { - if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)) + if (bio->bi_rw & REQ_FLUSH) continue; rh_inc(rh, dm_rh_bio_to_region(rh, bio)); } diff --git a/trunk/drivers/md/dm-thin.c b/trunk/drivers/md/dm-thin.c index 68694da0d21d..37fdaf81bd1f 100644 --- a/trunk/drivers/md/dm-thin.c +++ b/trunk/drivers/md/dm-thin.c @@ -1245,10 +1245,7 @@ static void process_discard(struct thin_c *tc, struct bio *bio) cell_release_singleton(cell, bio); cell_release_singleton(cell2, bio); - if ((!lookup_result.shared) && pool->pf.discard_passdown) - remap_and_issue(tc, bio, lookup_result.block); - else - bio_endio(bio, 0); + remap_and_issue(tc, bio, lookup_result.block); } break; @@ -2295,13 +2292,6 @@ static int process_reserve_metadata_snap_mesg(unsigned argc, char **argv, struct if (r) return r; - r = dm_pool_commit_metadata(pool->pmd); - if (r) { - DMERR("%s: dm_pool_commit_metadata() failed, error = %d", - __func__, r); - return r; - } - r = dm_pool_reserve_metadata_snap(pool->pmd); if (r) DMWARN("reserve_metadata_snap message failed."); @@ -2631,7 +2621,6 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) if (tc->pool->pf.discard_enabled) { ti->discards_supported = 1; ti->num_discard_requests = 1; - ti->discard_zeroes_data_unsupported = 1; } dm_put(pool_md); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index d5ab4493c8be..1c2f9048e1ae 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -2931,7 +2931,6 @@ offset_store(struct md_rdev *rdev, const char *buf, size_t len) * can be sane */ return -EBUSY; rdev->data_offset = offset; - rdev->new_data_offset = offset; return len; } @@ -3927,8 +3926,8 @@ array_state_show(struct mddev *mddev, char *page) return sprintf(page, "%s\n", array_states[st]); } -static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev); -static int md_set_readonly(struct mddev * mddev, struct block_device *bdev); +static int do_md_stop(struct mddev * mddev, int ro, int is_open); +static int md_set_readonly(struct mddev * mddev, int is_open); static int do_md_run(struct mddev * mddev); static int restart_array(struct mddev *mddev); @@ -3944,14 +3943,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) /* stopping an active array */ if (atomic_read(&mddev->openers) > 0) return -EBUSY; - err = do_md_stop(mddev, 0, NULL); + err = do_md_stop(mddev, 0, 0); break; case inactive: /* stopping an active array */ if (mddev->pers) { if (atomic_read(&mddev->openers) > 0) return -EBUSY; - err = do_md_stop(mddev, 2, NULL); + err = do_md_stop(mddev, 2, 0); } else err = 0; /* already inactive */ break; @@ -3959,7 +3958,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) break; /* not supported yet */ case readonly: if (mddev->pers) - err = md_set_readonly(mddev, NULL); + err = md_set_readonly(mddev, 0); else { mddev->ro = 1; set_disk_ro(mddev->gendisk, 1); @@ -3969,7 +3968,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) case read_auto: if (mddev->pers) { if (mddev->ro == 0) - err = md_set_readonly(mddev, NULL); + err = md_set_readonly(mddev, 0); else if (mddev->ro == 1) err = restart_array(mddev); if (err == 0) { @@ -5352,17 +5351,15 @@ void md_stop(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_stop); -static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) +static int md_set_readonly(struct mddev *mddev, int is_open) { int err = 0; mutex_lock(&mddev->open_mutex); - if (atomic_read(&mddev->openers) > !!bdev) { + if (atomic_read(&mddev->openers) > is_open) { printk("md: %s still in use.\n",mdname(mddev)); err = -EBUSY; goto out; } - if (bdev) - sync_blockdev(bdev); if (mddev->pers) { __md_stop_writes(mddev); @@ -5384,26 +5381,18 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) * 0 - completely stop and dis-assemble array * 2 - stop but do not disassemble array */ -static int do_md_stop(struct mddev * mddev, int mode, - struct block_device *bdev) +static int do_md_stop(struct mddev * mddev, int mode, int is_open) { struct gendisk *disk = mddev->gendisk; struct md_rdev *rdev; mutex_lock(&mddev->open_mutex); - if (atomic_read(&mddev->openers) > !!bdev || + if (atomic_read(&mddev->openers) > is_open || mddev->sysfs_active) { printk("md: %s still in use.\n",mdname(mddev)); mutex_unlock(&mddev->open_mutex); return -EBUSY; } - if (bdev) - /* It is possible IO was issued on some other - * open file which was closed before we took ->open_mutex. - * As that was not the last close __blkdev_put will not - * have called sync_blockdev, so we must. - */ - sync_blockdev(bdev); if (mddev->pers) { if (mddev->ro) @@ -5477,7 +5466,7 @@ static void autorun_array(struct mddev *mddev) err = do_md_run(mddev); if (err) { printk(KERN_WARNING "md: do_md_run() returned %d\n", err); - do_md_stop(mddev, 0, NULL); + do_md_stop(mddev, 0, 0); } } @@ -5795,7 +5784,8 @@ static int add_new_disk(struct mddev * mddev, mdu_disk_info_t *info) super_types[mddev->major_version]. validate_super(mddev, rdev); if ((info->state & (1<raid_disk != info->raid_disk) { + (!test_bit(In_sync, &rdev->flags) || + rdev->raid_disk != info->raid_disk)) { /* This was a hot-add request, but events doesn't * match, so reject it. */ @@ -6492,11 +6482,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, goto done_unlock; case STOP_ARRAY: - err = do_md_stop(mddev, 0, bdev); + err = do_md_stop(mddev, 0, 1); goto done_unlock; case STOP_ARRAY_RO: - err = md_set_readonly(mddev, bdev); + err = md_set_readonly(mddev, 1); goto done_unlock; case BLKROSET: @@ -6761,7 +6751,7 @@ struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev thread->tsk = kthread_run(md_thread, thread, "%s_%s", mdname(thread->mddev), - name); + name ?: mddev->pers->name); if (IS_ERR(thread->tsk)) { kfree(thread); return NULL; @@ -7308,7 +7298,6 @@ void md_do_sync(struct mddev *mddev) int skipped = 0; struct md_rdev *rdev; char *desc; - struct blk_plug plug; /* just incase thread restarts... */ if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) @@ -7458,7 +7447,6 @@ void md_do_sync(struct mddev *mddev) } mddev->curr_resync_completed = j; - blk_start_plug(&plug); while (j < max_sectors) { sector_t sectors; @@ -7564,7 +7552,6 @@ void md_do_sync(struct mddev *mddev) * this also signals 'finished resyncing' to md_stop */ out: - blk_finish_plug(&plug); wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); /* tell personality that we are finished */ diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index 61a1833ebaf3..9339e67fcc79 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -474,8 +474,7 @@ static int multipath_run (struct mddev *mddev) } { - mddev->thread = md_register_thread(multipathd, mddev, - "multipath"); + mddev->thread = md_register_thread(multipathd, mddev, NULL); if (!mddev->thread) { printk(KERN_ERR "multipath: couldn't allocate thread" " for %s\n", mdname(mddev)); diff --git a/trunk/drivers/md/persistent-data/dm-space-map-checker.c b/trunk/drivers/md/persistent-data/dm-space-map-checker.c index fc90c11620ad..50ed53bf4aa2 100644 --- a/trunk/drivers/md/persistent-data/dm-space-map-checker.c +++ b/trunk/drivers/md/persistent-data/dm-space-map-checker.c @@ -8,7 +8,6 @@ #include #include -#include #ifdef CONFIG_DM_DEBUG_SPACE_MAPS @@ -90,23 +89,13 @@ static int ca_create(struct count_array *ca, struct dm_space_map *sm) ca->nr = nr_blocks; ca->nr_free = nr_blocks; - - if (!nr_blocks) - ca->counts = NULL; - else { - ca->counts = vzalloc(sizeof(*ca->counts) * nr_blocks); - if (!ca->counts) - return -ENOMEM; - } + ca->counts = kzalloc(sizeof(*ca->counts) * nr_blocks, GFP_KERNEL); + if (!ca->counts) + return -ENOMEM; return 0; } -static void ca_destroy(struct count_array *ca) -{ - vfree(ca->counts); -} - static int ca_load(struct count_array *ca, struct dm_space_map *sm) { int r; @@ -137,14 +126,12 @@ static int ca_load(struct count_array *ca, struct dm_space_map *sm) static int ca_extend(struct count_array *ca, dm_block_t extra_blocks) { dm_block_t nr_blocks = ca->nr + extra_blocks; - uint32_t *counts = vzalloc(sizeof(*counts) * nr_blocks); + uint32_t *counts = kzalloc(sizeof(*counts) * nr_blocks, GFP_KERNEL); if (!counts) return -ENOMEM; - if (ca->counts) { - memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); - ca_destroy(ca); - } + memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); + kfree(ca->counts); ca->nr = nr_blocks; ca->nr_free += extra_blocks; ca->counts = counts; @@ -164,6 +151,11 @@ static int ca_commit(struct count_array *old, struct count_array *new) return 0; } +static void ca_destroy(struct count_array *ca) +{ + kfree(ca->counts); +} + /*----------------------------------------------------------------*/ struct sm_checker { @@ -351,25 +343,25 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) int r; struct sm_checker *smc; - if (IS_ERR_OR_NULL(sm)) - return ERR_PTR(-EINVAL); + if (!sm) + return NULL; smc = kmalloc(sizeof(*smc), GFP_KERNEL); if (!smc) - return ERR_PTR(-ENOMEM); + return NULL; memcpy(&smc->sm, &ops_, sizeof(smc->sm)); r = ca_create(&smc->old_counts, sm); if (r) { kfree(smc); - return ERR_PTR(r); + return NULL; } r = ca_create(&smc->counts, sm); if (r) { ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } smc->real_sm = sm; @@ -379,7 +371,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) ca_destroy(&smc->counts); ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } r = ca_commit(&smc->old_counts, &smc->counts); @@ -387,7 +379,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) ca_destroy(&smc->counts); ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } return &smc->sm; @@ -399,25 +391,25 @@ struct dm_space_map *dm_sm_checker_create_fresh(struct dm_space_map *sm) int r; struct sm_checker *smc; - if (IS_ERR_OR_NULL(sm)) - return ERR_PTR(-EINVAL); + if (!sm) + return NULL; smc = kmalloc(sizeof(*smc), GFP_KERNEL); if (!smc) - return ERR_PTR(-ENOMEM); + return NULL; memcpy(&smc->sm, &ops_, sizeof(smc->sm)); r = ca_create(&smc->old_counts, sm); if (r) { kfree(smc); - return ERR_PTR(r); + return NULL; } r = ca_create(&smc->counts, sm); if (r) { ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } smc->real_sm = sm; diff --git a/trunk/drivers/md/persistent-data/dm-space-map-disk.c b/trunk/drivers/md/persistent-data/dm-space-map-disk.c index 3d0ed5332883..fc469ba9f627 100644 --- a/trunk/drivers/md/persistent-data/dm-space-map-disk.c +++ b/trunk/drivers/md/persistent-data/dm-space-map-disk.c @@ -290,16 +290,7 @@ struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm, dm_block_t nr_blocks) { struct dm_space_map *sm = dm_sm_disk_create_real(tm, nr_blocks); - struct dm_space_map *smc; - - if (IS_ERR_OR_NULL(sm)) - return sm; - - smc = dm_sm_checker_create_fresh(sm); - if (IS_ERR(smc)) - dm_sm_destroy(sm); - - return smc; + return dm_sm_checker_create_fresh(sm); } EXPORT_SYMBOL_GPL(dm_sm_disk_create); diff --git a/trunk/drivers/md/persistent-data/dm-transaction-manager.c b/trunk/drivers/md/persistent-data/dm-transaction-manager.c index e5604b32d91f..400fe144c0cd 100644 --- a/trunk/drivers/md/persistent-data/dm-transaction-manager.c +++ b/trunk/drivers/md/persistent-data/dm-transaction-manager.c @@ -138,9 +138,6 @@ EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone); void dm_tm_destroy(struct dm_transaction_manager *tm) { - if (!tm->is_clone) - wipe_shadow_table(tm); - kfree(tm); } EXPORT_SYMBOL_GPL(dm_tm_destroy); @@ -347,10 +344,8 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, } *sm = dm_sm_checker_create(inner); - if (IS_ERR(*sm)) { - r = PTR_ERR(*sm); + if (!*sm) goto bad2; - } } else { r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location, @@ -369,10 +364,8 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, } *sm = dm_sm_checker_create(inner); - if (IS_ERR(*sm)) { - r = PTR_ERR(*sm); + if (!*sm) goto bad2; - } } return 0; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index cacd008d6864..835de7168cd3 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -517,8 +517,8 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect int bad_sectors; int disk = start_disk + i; - if (disk >= conf->raid_disks * 2) - disk -= conf->raid_disks * 2; + if (disk >= conf->raid_disks) + disk -= conf->raid_disks; rdev = rcu_dereference(conf->mirrors[disk].rdev); if (r1_bio->bios[disk] == IO_BLOCKED @@ -883,6 +883,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); struct md_rdev *blocked_rdev; + int plugged; int first_clone; int sectors_handled; int max_sectors; @@ -1033,6 +1034,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) * the bad blocks. Each set of writes gets it's own r1bio * with a set of bios attached. */ + plugged = mddev_check_plugged(mddev); disks = conf->raid_disks * 2; retry_write: @@ -1189,8 +1191,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); } /* Mustn't call r1_bio_write_done before this next test, * as it could result in the bio being freed. @@ -1213,6 +1213,9 @@ static void make_request(struct mddev *mddev, struct bio * bio) /* In case raid1d snuck in to freeze_array */ wake_up(&conf->wait_barrier); + + if (do_sync || !bitmap || !plugged) + md_wakeup_thread(mddev->thread); } static void status(struct seq_file *seq, struct mddev *mddev) @@ -1818,14 +1821,8 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio) if (atomic_dec_and_test(&r1_bio->remaining)) { /* if we're here, all write(s) have completed, so clean up */ - int s = r1_bio->sectors; - if (test_bit(R1BIO_MadeGood, &r1_bio->state) || - test_bit(R1BIO_WriteError, &r1_bio->state)) - reschedule_retry(r1_bio); - else { - put_buf(r1_bio); - md_done_sync(mddev, s, 1); - } + md_done_sync(mddev, r1_bio->sectors, 1); + put_buf(r1_bio); } } @@ -2491,10 +2488,9 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp */ if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { atomic_set(&r1_bio->remaining, read_targets); - for (i = 0; i < conf->raid_disks * 2 && read_targets; i++) { + for (i = 0; i < conf->raid_disks * 2; i++) { bio = r1_bio->bios[i]; if (bio->bi_end_io == end_sync_read) { - read_targets--; md_sync_acct(bio->bi_bdev, nr_sectors); generic_make_request(bio); } @@ -2554,7 +2550,6 @@ static struct r1conf *setup_conf(struct mddev *mddev) err = -EINVAL; spin_lock_init(&conf->device_lock); rdev_for_each(rdev, mddev) { - struct request_queue *q; int disk_idx = rdev->raid_disk; if (disk_idx >= mddev->raid_disks || disk_idx < 0) @@ -2567,9 +2562,6 @@ static struct r1conf *setup_conf(struct mddev *mddev) if (disk->rdev) goto abort; disk->rdev = rdev; - q = bdev_get_queue(rdev->bdev); - if (q->merge_bvec_fn) - mddev->merge_check_needed = 1; disk->head_position = 0; } @@ -2625,7 +2617,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) goto abort; } err = -ENOMEM; - conf->thread = md_register_thread(raid1d, mddev, "raid1"); + conf->thread = md_register_thread(raid1d, mddev, NULL); if (!conf->thread) { printk(KERN_ERR "md/raid1:%s: couldn't allocate thread\n", diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 8da6282254c3..987db37cb875 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1039,6 +1039,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_fua = (bio->bi_rw & REQ_FUA); unsigned long flags; struct md_rdev *blocked_rdev; + int plugged; int sectors_handled; int max_sectors; int sectors; @@ -1238,6 +1239,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) * of r10_bios is recored in bio->bi_phys_segments just as with * the read case. */ + plugged = mddev_check_plugged(mddev); r10_bio->read_slot = -1; /* make sure repl_bio gets freed */ raid10_find_phys(conf, r10_bio); @@ -1394,8 +1396,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); if (!r10_bio->devs[i].repl_bio) continue; @@ -1423,8 +1423,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); } /* Don't remove the bias on 'remaining' (one_write_done) until @@ -1450,6 +1448,9 @@ static void make_request(struct mddev *mddev, struct bio * bio) /* In case raid10d snuck in to freeze_array */ wake_up(&conf->wait_barrier); + + if (do_sync || !mddev->bitmap || !plugged) + md_wakeup_thread(mddev->thread); } static void status(struct seq_file *seq, struct mddev *mddev) @@ -2309,7 +2310,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 if (r10_sync_page_io(rdev, r10_bio->devs[sl].addr + sect, - s, conf->tmppage, WRITE) + s<<9, conf->tmppage, WRITE) == 0) { /* Well, this device is dead */ printk(KERN_NOTICE @@ -2348,7 +2349,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 switch (r10_sync_page_io(rdev, r10_bio->devs[sl].addr + sect, - s, conf->tmppage, + s<<9, conf->tmppage, READ)) { case 0: /* Well, this device is dead */ @@ -2511,7 +2512,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) slot = r10_bio->read_slot; printk_ratelimited( KERN_ERR - "md/raid10:%s: %s: redirecting " + "md/raid10:%s: %s: redirecting" "sector %llu to another mirror\n", mdname(mddev), bdevname(rdev->bdev, b), @@ -2660,8 +2661,7 @@ static void raid10d(struct mddev *mddev) blk_start_plug(&plug); for (;;) { - if (atomic_read(&mddev->plug_cnt) == 0) - flush_pending_writes(conf); + flush_pending_writes(conf); spin_lock_irqsave(&conf->device_lock, flags); if (list_empty(head)) { @@ -2890,12 +2890,6 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, /* want to reconstruct this device */ rb2 = r10_bio; sect = raid10_find_virt(conf, sector_nr, i); - if (sect >= mddev->resync_max_sectors) { - /* last stripe is not complete - don't - * try to recover this sector. - */ - continue; - } /* Unless we are doing a full sync, or a replacement * we only need to recover the block if it is set in * the bitmap @@ -3427,7 +3421,7 @@ static struct r10conf *setup_conf(struct mddev *mddev) spin_lock_init(&conf->resync_lock); init_waitqueue_head(&conf->wait_barrier); - conf->thread = md_register_thread(raid10d, mddev, "raid10"); + conf->thread = md_register_thread(raid10d, mddev, NULL); if (!conf->thread) goto out; @@ -3481,7 +3475,6 @@ static int run(struct mddev *mddev) rdev_for_each(rdev, mddev) { long long diff; - struct request_queue *q; disk_idx = rdev->raid_disk; if (disk_idx < 0) @@ -3500,9 +3493,6 @@ static int run(struct mddev *mddev) goto out_free_conf; disk->rdev = rdev; } - q = bdev_get_queue(rdev->bdev); - if (q->merge_bvec_fn) - mddev->merge_check_needed = 1; diff = (rdev->new_data_offset - rdev->data_offset); if (!mddev->reshape_backwards) diff = -diff; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 04348d76bb30..d26767246d26 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -196,14 +196,12 @@ static void __release_stripe(struct r5conf *conf, struct stripe_head *sh) BUG_ON(!list_empty(&sh->lru)); BUG_ON(atomic_read(&conf->active_stripes)==0); if (test_bit(STRIPE_HANDLE, &sh->state)) { - if (test_bit(STRIPE_DELAYED, &sh->state) && - !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + if (test_bit(STRIPE_DELAYED, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && sh->bm_seq - conf->seq_write > 0) list_add_tail(&sh->lru, &conf->bitmap_list); else { - clear_bit(STRIPE_DELAYED, &sh->state); clear_bit(STRIPE_BIT_DELAY, &sh->state); list_add_tail(&sh->lru, &conf->handle_list); } @@ -608,12 +606,6 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) * a chance*/ md_check_recovery(conf->mddev); } - /* - * Because md_wait_for_blocked_rdev - * will dec nr_pending, we must - * increment it first. - */ - atomic_inc(&rdev->nr_pending); md_wait_for_blocked_rdev(rdev, conf->mddev); } else { /* Acknowledged bad block - skip the write */ @@ -1745,7 +1737,6 @@ static void raid5_end_read_request(struct bio * bi, int error) } else { const char *bdn = bdevname(rdev->bdev, b); int retry = 0; - int set_bad = 0; clear_bit(R5_UPTODATE, &sh->dev[i].flags); atomic_inc(&rdev->read_errors); @@ -1757,8 +1748,7 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - else if (conf->mddev->degraded >= conf->max_degraded) { - set_bad = 1; + else if (conf->mddev->degraded >= conf->max_degraded) printk_ratelimited( KERN_WARNING "md/raid:%s: read error not correctable " @@ -1766,9 +1756,8 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - } else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) { + else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) /* Oh, no!!! */ - set_bad = 1; printk_ratelimited( KERN_WARNING "md/raid:%s: read error NOT corrected!! " @@ -1776,7 +1765,7 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - } else if (atomic_read(&rdev->read_errors) + else if (atomic_read(&rdev->read_errors) > conf->max_nr_stripes) printk(KERN_WARNING "md/raid:%s: Too many read errors, failing device %s.\n", @@ -1788,11 +1777,7 @@ static void raid5_end_read_request(struct bio * bi, int error) else { clear_bit(R5_ReadError, &sh->dev[i].flags); clear_bit(R5_ReWrite, &sh->dev[i].flags); - if (!(set_bad - && test_bit(In_sync, &rdev->flags) - && rdev_set_badblocks( - rdev, sh->sector, STRIPE_SECTORS, 0))) - md_error(conf->mddev, rdev); + md_error(conf->mddev, rdev); } } rdev_dec_pending(rdev, conf->mddev); @@ -3597,18 +3582,8 @@ static void handle_stripe(struct stripe_head *sh) finish: /* wait for this device to become unblocked */ - if (unlikely(s.blocked_rdev)) { - if (conf->mddev->external) - md_wait_for_blocked_rdev(s.blocked_rdev, - conf->mddev); - else - /* Internal metadata will immediately - * be written by raid5d, so we don't - * need to wait here. - */ - rdev_dec_pending(s.blocked_rdev, - conf->mddev); - } + if (conf->mddev->external && unlikely(s.blocked_rdev)) + md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); if (s.handle_bad_blocks) for (i = disks; i--; ) { @@ -3906,6 +3881,8 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) raid_bio->bi_next = (void*)rdev; align_bi->bi_bdev = rdev->bdev; align_bi->bi_flags &= ~(1 << BIO_SEG_VALID); + /* No reshape active, so we can trust rdev->data_offset */ + align_bi->bi_sector += rdev->data_offset; if (!bio_fits_rdev(align_bi) || is_badblock(rdev, align_bi->bi_sector, align_bi->bi_size>>9, @@ -3916,9 +3893,6 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) return 0; } - /* No reshape active, so we can trust rdev->data_offset */ - align_bi->bi_sector += rdev->data_offset; - spin_lock_irq(&conf->device_lock); wait_event_lock_irq(conf->wait_for_stripe, conf->quiesce == 0, @@ -3997,6 +3971,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) struct stripe_head *sh; const int rw = bio_data_dir(bi); int remaining; + int plugged; if (unlikely(bi->bi_rw & REQ_FLUSH)) { md_flush_request(mddev, bi); @@ -4015,6 +3990,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) bi->bi_next = NULL; bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ + plugged = mddev_check_plugged(mddev); for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); int previous; @@ -4116,7 +4092,6 @@ static void make_request(struct mddev *mddev, struct bio * bi) if ((bi->bi_rw & REQ_SYNC) && !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) atomic_inc(&conf->preread_active_stripes); - mddev_check_plugged(mddev); release_stripe(sh); } else { /* cannot get stripe for read-ahead, just give-up */ @@ -4124,7 +4099,10 @@ static void make_request(struct mddev *mddev, struct bio * bi) finish_wait(&conf->wait_for_overlap, &w); break; } + } + if (!plugged) + md_wakeup_thread(mddev->thread); spin_lock_irq(&conf->device_lock); remaining = raid5_dec_bi_phys_segments(bi); @@ -4845,7 +4823,6 @@ static struct r5conf *setup_conf(struct mddev *mddev) int raid_disk, memory, max_disks; struct md_rdev *rdev; struct disk_info *disk; - char pers_name[6]; if (mddev->new_level != 5 && mddev->new_level != 4 @@ -4969,8 +4946,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) printk(KERN_INFO "md/raid:%s: allocated %dkB\n", mdname(mddev), memory); - sprintf(pers_name, "raid%d", mddev->new_level); - conf->thread = md_register_thread(raid5d, mddev, pers_name); + conf->thread = md_register_thread(raid5d, mddev, NULL); if (!conf->thread) { printk(KERN_ERR "md/raid:%s: couldn't allocate thread.\n", @@ -5489,9 +5465,10 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk >= 0 && rdev->saved_raid_disk >= first && conf->disks[rdev->saved_raid_disk].rdev == NULL) - first = rdev->saved_raid_disk; - - for (disk = first; disk <= last; disk++) { + disk = rdev->saved_raid_disk; + else + disk = first; + for ( ; disk <= last ; disk++) { p = conf->disks + disk; if (p->rdev == NULL) { clear_bit(In_sync, &rdev->flags); @@ -5500,11 +5477,8 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk != disk) conf->fullsync = 1; rcu_assign_pointer(p->rdev, rdev); - goto out; + break; } - } - for (disk = first; disk <= last; disk++) { - p = conf->disks + disk; if (test_bit(WantReplacement, &p->rdev->flags) && p->replacement == NULL) { clear_bit(In_sync, &rdev->flags); @@ -5516,7 +5490,6 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) break; } } -out: print_raid5_conf(conf); return err; } diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c index 0cdbd742974a..7d42c11c8684 100644 --- a/trunk/drivers/media/common/saa7146_fops.c +++ b/trunk/drivers/media/common/saa7146_fops.c @@ -198,6 +198,7 @@ static int fops_open(struct file *file) struct saa7146_dev *dev = video_drvdata(file); struct saa7146_fh *fh = NULL; int result = 0; + enum v4l2_buf_type type; DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); @@ -206,6 +207,10 @@ static int fops_open(struct file *file) DEB_D("using: %p\n", dev); + type = vdev->vfl_type == VFL_TYPE_GRABBER + ? V4L2_BUF_TYPE_VIDEO_CAPTURE + : V4L2_BUF_TYPE_VBI_CAPTURE; + /* check if an extension is registered */ if( NULL == dev->ext ) { DEB_S("no extension registered for this device\n"); diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index 39eab73b01ae..00a67326c193 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -243,7 +243,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if (minor == MAX_DVB_MINORS) { kfree(dvbdevfops); kfree(dvbdev); - up_write(&minor_rwsem); mutex_unlock(&dvbdev_register_lock); return -EINVAL; } diff --git a/trunk/drivers/media/dvb/frontends/cx24110.c b/trunk/drivers/media/dvb/frontends/cx24110.c index 3180f5b2a6a6..98ecaf0900d6 100644 --- a/trunk/drivers/media/dvb/frontends/cx24110.c +++ b/trunk/drivers/media/dvb/frontends/cx24110.c @@ -516,9 +516,9 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) if(cx24110_readreg(state,0x10)&0x40) { /* the RS error counter has finished one counting window */ cx24110_writereg(state,0x10,0x60); /* select the byer reg */ - (void)(cx24110_readreg(state, 0x12) | + cx24110_readreg(state, 0x12) | (cx24110_readreg(state, 0x13) << 8) | - (cx24110_readreg(state, 0x14) << 16)); + (cx24110_readreg(state, 0x14) << 16); cx24110_writereg(state,0x10,0x70); /* select the bler reg */ state->lastbler=cx24110_readreg(state,0x12)| (cx24110_readreg(state,0x13)<<8)| diff --git a/trunk/drivers/media/dvb/frontends/cxd2820r_c.c b/trunk/drivers/media/dvb/frontends/cxd2820r_c.c index ed3b0ba624de..945404991529 100644 --- a/trunk/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/trunk/drivers/media/dvb/frontends/cxd2820r_c.c @@ -121,7 +121,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe) if (ret) goto error; - switch ((buf[0] >> 0) & 0x07) { + switch ((buf[0] >> 0) & 0x03) { case 0: c->modulation = QAM_16; break; diff --git a/trunk/drivers/media/dvb/frontends/lg2160.c b/trunk/drivers/media/dvb/frontends/lg2160.c index cc11260e99df..a3ab1a5b6597 100644 --- a/trunk/drivers/media/dvb/frontends/lg2160.c +++ b/trunk/drivers/media/dvb/frontends/lg2160.c @@ -126,7 +126,7 @@ static int lg216x_write_regs(struct lg216x_state *state, lg_reg("writing %d registers...\n", len); - for (i = 0; i < len; i++) { + for (i = 0; i < len - 1; i++) { ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); if (lg_fail(ret)) return ret; diff --git a/trunk/drivers/media/dvb/siano/smsusb.c b/trunk/drivers/media/dvb/siano/smsusb.c index 664e460f247b..63c004a25e0b 100644 --- a/trunk/drivers/media/dvb/siano/smsusb.c +++ b/trunk/drivers/media/dvb/siano/smsusb.c @@ -544,8 +544,6 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xc0a0), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0xf5a0), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/media/radio/radio-maxiradio.c b/trunk/drivers/media/radio/radio-maxiradio.c index b415211d0c4b..740a3d5520c7 100644 --- a/trunk/drivers/media/radio/radio-maxiradio.c +++ b/trunk/drivers/media/radio/radio-maxiradio.c @@ -157,7 +157,7 @@ static int __devinit maxiradio_probe(struct pci_dev *pdev, const struct pci_devi goto err_out_free_region; dev->io = pci_resource_start(pdev, 0); - if (snd_tea575x_init(&dev->tea, THIS_MODULE)) { + if (snd_tea575x_init(&dev->tea)) { printk(KERN_ERR "radio-maxiradio: Unable to detect TEA575x tuner\n"); goto err_out_free_region; } diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c index 4efcbec74c52..52b8011f1b23 100644 --- a/trunk/drivers/media/radio/radio-sf16fmr2.c +++ b/trunk/drivers/media/radio/radio-sf16fmr2.c @@ -238,7 +238,7 @@ static int __devinit fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s", fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev)); - if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) { + if (snd_tea575x_init(&fmr2->tea)) { printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); release_region(fmr2->io, 2); return -ENODEV; diff --git a/trunk/drivers/media/radio/si470x/radio-si470x-usb.c b/trunk/drivers/media/radio/si470x/radio-si470x-usb.c index f412f7ab270b..e9f638761296 100644 --- a/trunk/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/trunk/drivers/media/radio/si470x/radio-si470x-usb.c @@ -51,8 +51,6 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, - /* Axentia ALERT FM USB Receiver */ - { USB_DEVICE_AND_INTERFACE_INFO(0x12cf, 0x7111, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; diff --git a/trunk/drivers/media/rc/winbond-cir.c b/trunk/drivers/media/rc/winbond-cir.c index 54ee34872d14..342c2c8c1ddf 100644 --- a/trunk/drivers/media/rc/winbond-cir.c +++ b/trunk/drivers/media/rc/winbond-cir.c @@ -232,7 +232,7 @@ MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); static bool txandrx; /* default = 0 */ module_param(txandrx, bool, 0444); -MODULE_PARM_DESC(txandrx, "Allow simultaneous TX and RX"); +MODULE_PARM_DESC(invert, "Allow simultaneous TX and RX"); static unsigned int wake_sc = 0x800F040C; module_param(wake_sc, uint, 0644); @@ -1032,8 +1032,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->tx_ir = wbcir_tx; data->dev->priv = data; data->dev->dev.parent = &device->dev; - data->dev->timeout = MS_TO_NS(100); - data->dev->allowed_protos = RC_TYPE_ALL; if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 856ab962cd63..ff2933ab705f 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -371,6 +371,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -383,6 +384,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -396,6 +398,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, + .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -411,6 +414,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, + .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -423,6 +427,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 1, 0, 1 }, .gpiomute = 3, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -435,6 +440,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0f, .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tvphone_audio, @@ -448,6 +454,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, + .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -462,6 +469,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0xc00, 0x800, 0x400 }, .gpiomute = 0xc00, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -474,6 +482,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 2, 3 }, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -487,6 +496,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -500,6 +510,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -513,6 +524,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -524,6 +536,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, + .needs_tvaudio = 1, .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -540,6 +553,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ .gpiomute = 4, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -553,6 +567,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 1, 0 }, .gpiomute = 10, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -568,6 +583,7 @@ struct tvcard bttv_tvcards[] = { /* 2003-10-20 by "Anton A. Arapov" */ .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -581,6 +597,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1, 0), .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, .gpiomute = 0xcfa007, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .volume_gpio = winview_volume, @@ -594,6 +611,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0, 0, 0 }, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -642,6 +660,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 0x800, 0x400 }, .gpiomute = 0xc00, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -672,6 +691,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0xc00, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -686,6 +706,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, + .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -699,6 +720,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, + .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -726,6 +748,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, .gpiomute = 0x40000, + .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -770,6 +793,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, + .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, @@ -810,6 +834,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, + .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -822,6 +847,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0, 0x300, 0x900 }, .gpiomute = 0x900, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -848,6 +874,7 @@ struct tvcard bttv_tvcards[] = { Note: There exists another variant "Winfast 2000" with tv stereo !? Note: eeprom only contains FF and pci subsystem id 107d:6606 */ + .needs_tvaudio = 0, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ @@ -907,6 +934,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0x551400, 0x551200, 0, 0 }, .gpiomute = 0x551c00, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -921,6 +949,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0xd0001, 0, 0 }, .gpiomute = 1, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -937,6 +966,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, + .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -950,6 +980,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 4, 11, 7 }, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -964,6 +995,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0}, + .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1034,6 +1066,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, + .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1051,6 +1084,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {2,0,0,0 }, .gpiomute = 1, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1129,6 +1163,7 @@ struct tvcard bttv_tvcards[] = { MUX2 (mask 0x30000): 0,2,3= from MSP34xx 1= FM stereo Radio from Tuner */ + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1144,6 +1179,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0x10, 8 }, .gpiomute = 4, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1182,6 +1218,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1213,6 +1250,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(3, 1), .gpiomux = { 0 }, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_ABSENT, @@ -1228,6 +1266,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0x800, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, @@ -1273,6 +1312,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2), .gpiomux = { }, .no_msp34xx = 1, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1289,6 +1329,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 1, 0, 4, 4 }, .gpiomute = 9, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1338,6 +1379,7 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x1800, .audio_mode_gpio= fv2000s_audio, .no_msp34xx = 1, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1351,6 +1393,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, .gpiomute = 0x900, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1434,6 +1477,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ .gpiomute = 13, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, @@ -1470,6 +1514,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, .gpiomute = 0x09, + .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1495,6 +1540,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, + .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -1521,6 +1567,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 4, + .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1550,6 +1597,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1571,6 +1619,7 @@ struct tvcard bttv_tvcards[] = { * btwincap uses 0x80000/0x80003 */ .gpiomute = 4, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1606,6 +1655,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .muxsel = MUXSEL(2, 0, 1, 1), + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1825,6 +1875,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3}, .gpiomute = 4, + .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1851,6 +1902,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1868,6 +1920,7 @@ struct tvcard bttv_tvcards[] = { /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, .gpiomute = 0x0f, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, @@ -1883,6 +1936,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), + .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1980,6 +2034,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1994,6 +2049,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2006,6 +2062,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2022,6 +2079,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2036,6 +2094,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2059,6 +2118,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, /* card has no svhs */ + .needs_tvaudio = 0, .no_msp34xx = 1, .no_tda7432 = 1, .gpiomask = 0x00, @@ -2108,6 +2168,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 1, 1 }, + .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_35, @@ -2149,6 +2210,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, .no_tda7432 = 1, + .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -2160,6 +2222,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .svhs = 2, + .needs_tvaudio = 0, .gpiomask = 0x68, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, @@ -2178,6 +2241,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2201,6 +2265,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, + .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2293,6 +2358,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2339,6 +2405,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .gpiomask = 0x008007, .gpiomux = { 0, 0x000001,0,0 }, + .needs_tvaudio = 1, .has_radio = 1, }, [BTTV_BOARD_TIBET_CS16] = { @@ -2451,6 +2518,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, @@ -2466,6 +2534,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, @@ -2546,6 +2615,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -2644,6 +2714,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, + .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -2675,6 +2746,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ .gpiomute = 3, /* CONTVFMi */ + .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2713,6 +2785,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(0, 2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2726,6 +2799,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2739,6 +2813,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(3, 2, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ + .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2802,6 +2877,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, + .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -3573,7 +3649,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) struct tuner_setup tun_setup; /* Load tuner module before issuing tuner config call! */ - if (btv->has_radio) + if (bttv_tvcards[btv->c.type].has_radio) v4l2_i2c_new_subdev(&btv->c.v4l2_dev, &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); @@ -3588,7 +3664,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) tun_setup.type = btv->tuner_type; tun_setup.addr = addr; - if (btv->has_radio) + if (bttv_tvcards[btv->c.type].has_radio) tun_setup.mode_mask |= T_RADIO; bttv_call_all(btv, tuner, s_type_addr, &tun_setup); @@ -3648,10 +3724,6 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; } - - /* The 61334 needs the msp3410 to do the radio demod to get sound */ - if (tv.model == 61334) - btv->radio_uses_msp_demodulator = 1; } static int terratec_active_radio_upgrade(struct bttv *btv) diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index ff7a589d8e0f..a9cfb0f4be48 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -1218,11 +1218,6 @@ audio_mux(struct bttv *btv, int input, int mute) For now this is sufficient. */ switch (input) { case TVAUDIO_INPUT_RADIO: - /* Some boards need the msp do to the radio demod */ - if (btv->radio_uses_msp_demodulator) { - in = MSP_INPUT_DEFAULT; - break; - } in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; diff --git a/trunk/drivers/media/video/bt8xx/bttv.h b/trunk/drivers/media/video/bt8xx/bttv.h index acfe2f3b92d9..c5171619ac79 100644 --- a/trunk/drivers/media/video/bt8xx/bttv.h +++ b/trunk/drivers/media/video/bt8xx/bttv.h @@ -236,6 +236,7 @@ struct tvcard { /* i2c audio flags */ unsigned int no_msp34xx:1; unsigned int no_tda7432:1; + unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; /* Note: currently no card definition needs to mark the presence of a RDS saa6588 chip. If this is ever needed, then add a new diff --git a/trunk/drivers/media/video/bt8xx/bttvp.h b/trunk/drivers/media/video/bt8xx/bttvp.h index 70fd4f23f605..db943a8d580d 100644 --- a/trunk/drivers/media/video/bt8xx/bttvp.h +++ b/trunk/drivers/media/video/bt8xx/bttvp.h @@ -440,7 +440,6 @@ struct bttv { /* radio data/state */ int has_radio; int radio_user; - int radio_uses_msp_demodulator; /* miro/pinnacle + Aimslab VHX philips matchbox (tea5757 radio tuner) support */ diff --git a/trunk/drivers/media/video/bw-qcam.c b/trunk/drivers/media/video/bw-qcam.c index 5b75a64b199b..2520219f01ba 100644 --- a/trunk/drivers/media/video/bw-qcam.c +++ b/trunk/drivers/media/video/bw-qcam.c @@ -607,9 +607,8 @@ static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) } o = i * pixels_per_line + pixels_read + k; if (o < len) { - u8 ch = invert - buffer[k]; got++; - put_user(ch << shift, buf + o); + put_user((invert - buffer[k]) << shift, buf + o); } } pixels_read += bytes; @@ -649,8 +648,8 @@ static int qcam_querycap(struct file *file, void *priv, struct qcam *qcam = video_drvdata(file); strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); - strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card)); - strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info)); + strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); + strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; @@ -689,8 +688,8 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f pix->height = qcam->height / qcam->transfer_scale; pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; pix->field = V4L2_FIELD_NONE; - pix->bytesperline = pix->width; - pix->sizeimage = pix->width * pix->height; + pix->bytesperline = qcam->width; + pix->sizeimage = qcam->width * qcam->height; /* Just a guess */ pix->colorspace = V4L2_COLORSPACE_SRGB; return 0; @@ -758,7 +757,7 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes "4-Bit Monochrome", V4L2_PIX_FMT_Y4, { 0, 0, 0, 0 } }, - { 1, 0, 0, + { 0, 0, 0, "6-Bit Monochrome", V4L2_PIX_FMT_Y6, { 0, 0, 0, 0 } }, @@ -773,25 +772,6 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes return 0; } -static int qcam_enum_framesizes(struct file *file, void *fh, - struct v4l2_frmsizeenum *fsize) -{ - static const struct v4l2_frmsize_discrete sizes[] = { - { 80, 60 }, - { 160, 120 }, - { 320, 240 }, - }; - - if (fsize->index > 2) - return -EINVAL; - if (fsize->pixel_format != V4L2_PIX_FMT_Y4 && - fsize->pixel_format != V4L2_PIX_FMT_Y6) - return -EINVAL; - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete = sizes[fsize->index]; - return 0; -} - static ssize_t qcam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -815,11 +795,6 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static unsigned int qcam_poll(struct file *filp, poll_table *wait) -{ - return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM; -} - static int qcam_s_ctrl(struct v4l2_ctrl *ctrl) { struct qcam *qcam = @@ -853,7 +828,7 @@ static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = v4l2_fh_release, - .poll = qcam_poll, + .poll = v4l2_ctrl_poll, .unlocked_ioctl = video_ioctl2, .read = qcam_read, }; @@ -864,7 +839,6 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = { .vidioc_s_input = qcam_s_input, .vidioc_enum_input = qcam_enum_input, .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, - .vidioc_enum_framesizes = qcam_enum_framesizes, .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, @@ -890,9 +864,9 @@ static struct qcam *qcam_init(struct parport *port) return NULL; v4l2_dev = &qcam->v4l2_dev; - snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams); + strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); - if (v4l2_device_register(port->dev, v4l2_dev) < 0) { + if (v4l2_device_register(NULL, v4l2_dev) < 0) { v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); kfree(qcam); return NULL; @@ -912,7 +886,7 @@ static struct qcam *qcam_init(struct parport *port) return NULL; } qcam->pport = port; - qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL, + qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, NULL, 0, NULL); if (qcam->pdev == NULL) { v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); @@ -1001,7 +975,6 @@ static int init_bwqcam(struct parport *port) return -ENODEV; } qc_calibrate(qcam); - v4l2_ctrl_handler_setup(&qcam->hdl); parport_release(qcam->pdev); diff --git a/trunk/drivers/media/video/cx18/cx18-driver.c b/trunk/drivers/media/video/cx18/cx18-driver.c index 7e5ffd6f5178..b55d57cc1a1c 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.c +++ b/trunk/drivers/media/video/cx18/cx18-driver.c @@ -838,10 +838,10 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, } CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%llx\n", + "irq: %d, latency: %d, memory: 0x%lx\n", cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), - cx->pci_dev->irq, pci_latency, (u64)cx->base_addr); + cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr); return 0; } @@ -938,7 +938,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, if (retval) goto err; - CX18_DEBUG_INFO("base addr: 0x%llx\n", (u64)cx->base_addr); + CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); /* PCI Device Setup */ retval = cx18_setup_pci(cx, pci_dev, pci_id); @@ -946,8 +946,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_workqueues; /* map io memory */ - CX18_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", - (u64)cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); + CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", + cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); if (!cx->enc_mem) { diff --git a/trunk/drivers/media/video/cx18/cx18-driver.h b/trunk/drivers/media/video/cx18/cx18-driver.h index 2767c64df0c8..7a37e0ee136f 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.h +++ b/trunk/drivers/media/video/cx18/cx18-driver.h @@ -622,7 +622,7 @@ struct cx18 { unique ID. Starts at 1, so 0 can be used as uninitialized value in the stream->id. */ - resource_size_t base_addr; + u32 base_addr; u8 card_rev; void __iomem *enc_mem, *reg_mem; diff --git a/trunk/drivers/media/video/cx18/cx18-firmware.c b/trunk/drivers/media/video/cx18/cx18-firmware.c index b85c292a849a..1b3fb502e6be 100644 --- a/trunk/drivers/media/video/cx18/cx18-firmware.c +++ b/trunk/drivers/media/video/cx18/cx18-firmware.c @@ -164,13 +164,8 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; while (offset + sizeof(seghdr) < fw->size) { - const u32 *shptr = src + offset / 4; - - seghdr.sync1 = le32_to_cpu(shptr[0]); - seghdr.sync2 = le32_to_cpu(shptr[1]); - seghdr.addr = le32_to_cpu(shptr[2]); - seghdr.size = le32_to_cpu(shptr[3]); - + /* TODO: byteswapping */ + memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); offset += sizeof(seghdr); if (seghdr.sync1 != APU_ROM_SYNC1 || seghdr.sync2 != APU_ROM_SYNC2) { diff --git a/trunk/drivers/media/video/cx18/cx18-mailbox.c b/trunk/drivers/media/video/cx18/cx18-mailbox.c index eabf00c6351b..ed8118390b02 100644 --- a/trunk/drivers/media/video/cx18/cx18-mailbox.c +++ b/trunk/drivers/media/video/cx18/cx18-mailbox.c @@ -434,7 +434,6 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) { u32 handle, mdl_ack_offset, mdl_ack_count; struct cx18_mailbox *mb; - int i; mb = &order->mb; handle = mb->args[0]; @@ -448,9 +447,8 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) return -1; } - for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32)) - ((u32 *)order->mdl_ack)[i / sizeof(u32)] = - cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i); + cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset, + sizeof(struct cx18_mdl_ack) * mdl_ack_count); if ((order->flags & CX18_F_EWO_MB_STALE) == 0) mb_ack_irq(cx, order); @@ -540,7 +538,6 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) struct cx18_mailbox *order_mb; struct cx18_in_work_order *order; int submit; - int i; switch (rpu) { case CPU: @@ -565,12 +562,10 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) order_mb = &order->mb; /* mb->cmd and mb->args[0] through mb->args[2] */ - for (i = 0; i < 4; i++) - (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i); - + cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32)); /* mb->request and mb->ack. N.B. we want to read mb->ack last */ - for (i = 0; i < 2; i++) - (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i); + cx18_memcpy_fromio(cx, &order_mb->request, &mb->request, + 2 * sizeof(u32)); if (order_mb->request == order_mb->ack) { CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-audio.c b/trunk/drivers/media/video/cx231xx/cx231xx-audio.c index b4c99c7270cf..068f78dc5d13 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx-audio.c +++ b/trunk/drivers/media/video/cx231xx/cx231xx-audio.c @@ -307,7 +307,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) urb->context = dev; urb->pipe = usb_rcvisocpipe(dev->udev, dev->adev.end_point_addr); - urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->interval = 1; urb->complete = cx231xx_audio_isocirq; @@ -368,7 +368,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) urb->context = dev; urb->pipe = usb_rcvbulkpipe(dev->udev, dev->adev.end_point_addr); - urb->transfer_flags = 0; + urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->complete = cx231xx_audio_bulkirq; urb->transfer_buffer_length = sb_size; diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-vbi.c b/trunk/drivers/media/video/cx231xx/cx231xx-vbi.c index ac7db52f404f..3d15314e1f88 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/trunk/drivers/media/video/cx231xx/cx231xx-vbi.c @@ -448,7 +448,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, return -ENOMEM; } dev->vbi_mode.bulk_ctl.urb[i] = urb; - urb->transfer_flags = 0; + urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); diff --git a/trunk/drivers/media/video/cx23885/cx23885-cards.c b/trunk/drivers/media/video/cx23885/cx23885-cards.c index 080e11157e5f..13739e002a63 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-cards.c +++ b/trunk/drivers/media/video/cx23885/cx23885-cards.c @@ -127,37 +127,22 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_HAUPPAUGE_HVR1250] = { .name = "Hauppauge WinTV-HVR1250", - .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, -#ifdef MT2131_NO_ANALOG_SUPPORT_YET - .tuner_type = TUNER_PHILIPS_TDA8290, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .tuner_bus = 1, -#endif - .force_bff = 1, .input = {{ -#ifdef MT2131_NO_ANALOG_SUPPORT_YET .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1, - .amux = CX25840_AUDIO8, + .vmux = 0, .gpio0 = 0xff00, }, { -#endif + .type = CX23885_VMUX_DEBUG, + .vmux = 0, + .gpio0 = 0xff01, + }, { .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .amux = CX25840_AUDIO7, + .vmux = 1, .gpio0 = 0xff02, }, { .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, + .vmux = 2, .gpio0 = 0xff02, } }, }, @@ -282,55 +267,7 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_HAUPPAUGE_HVR1255] = { .name = "Hauppauge WinTV-HVR1255", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_ABSENT, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1 | - CX25840_DIF_ON, - .amux = CX25840_AUDIO8, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .amux = CX25840_AUDIO7, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1255_22111] = { - .name = "Hauppauge WinTV-HVR1255", - .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_ABSENT, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1 | - CX25840_DIF_ON, - .amux = CX25840_AUDIO8, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1210] = { .name = "Hauppauge WinTV-HVR1210", @@ -687,7 +624,7 @@ struct cx23885_subid cx23885_subids[] = { }, { .subvendor = 0x0070, .subdevice = 0x2259, - .card = CX23885_BOARD_HAUPPAUGE_HVR1255_22111, + .card = CX23885_BOARD_HAUPPAUGE_HVR1255, }, { .subvendor = 0x0070, .subdevice = 0x2291, @@ -963,7 +900,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) struct cx23885_dev *dev = port->dev; u32 bitmask = 0; - if ((command == XC2028_RESET_CLK) || (command == XC2028_I2C_FLUSH)) + if (command == XC2028_RESET_CLK) return 0; if (command != 0) { @@ -1193,7 +1130,6 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ /* GPIO-6 I2C Gate which can isolate the demod from the bus */ @@ -1331,7 +1267,6 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* FIXME: Implement me */ break; @@ -1489,7 +1424,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: @@ -1577,7 +1511,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_HAUPPAUGE_HVR1290: @@ -1593,10 +1526,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) */ switch (dev->board) { case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: /* Currently only enabled for the integrated IR controller */ if (!enable_885_ir) break; - case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1700: @@ -1606,8 +1539,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_MYGICA_X8506: diff --git a/trunk/drivers/media/video/cx23885/cx23885-dvb.c b/trunk/drivers/media/video/cx23885/cx23885-dvb.c index cd542684ba02..a80a92c47455 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-dvb.c +++ b/trunk/drivers/media/video/cx23885/cx23885-dvb.c @@ -712,7 +712,6 @@ static int dvb_register(struct cx23885_tsport *port) } break; case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, @@ -722,11 +721,6 @@ static int dvb_register(struct cx23885_tsport *port) 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } - - tda18271_attach(&dev->ts1.analog_fe, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c index 22f8e7fbd665..c654bdc7ccb2 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-video.c +++ b/trunk/drivers/media/video/cx23885/cx23885-video.c @@ -505,9 +505,6 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) || (dev->board == CX23885_BOARD_MPX885) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1250) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) { /* Configure audio routing */ v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, @@ -1581,9 +1578,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, fe = vfe->dvb.frontend; - if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111)) + if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) fe = &dev->ts1.analog_fe; if (fe && fe->ops.tuner_ops.set_analog_params) { @@ -1613,8 +1608,6 @@ int cx23885_set_frequency(struct file *file, void *priv, int ret; switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1850: ret = cx23885_set_freq_via_ops(dev, f); break; diff --git a/trunk/drivers/media/video/cx23885/cx23885.h b/trunk/drivers/media/video/cx23885/cx23885.h index 13c37ec07ae7..d884784a1c85 100644 --- a/trunk/drivers/media/video/cx23885/cx23885.h +++ b/trunk/drivers/media/video/cx23885/cx23885.h @@ -90,7 +90,6 @@ #define CX23885_BOARD_MYGICA_X8507 33 #define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34 #define CX23885_BOARD_TEVII_S471 35 -#define CX23885_BOARD_HAUPPAUGE_HVR1255_22111 36 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 diff --git a/trunk/drivers/media/video/cx25821/cx25821-core.c b/trunk/drivers/media/video/cx25821/cx25821-core.c index f11f6f07e915..83c1aa6b2e6c 100644 --- a/trunk/drivers/media/video/cx25821/cx25821-core.c +++ b/trunk/drivers/media/video/cx25821/cx25821-core.c @@ -904,6 +904,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) list_add_tail(&dev->devlist, &cx25821_devlist); mutex_unlock(&cx25821_devlist_mutex); + strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown"); + strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821"); + if (dev->pci->device != 0x8210) { pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", __func__, dev->pci->device); diff --git a/trunk/drivers/media/video/cx25821/cx25821.h b/trunk/drivers/media/video/cx25821/cx25821.h index 029f2934a6d8..b9aa801b00a7 100644 --- a/trunk/drivers/media/video/cx25821/cx25821.h +++ b/trunk/drivers/media/video/cx25821/cx25821.h @@ -187,7 +187,7 @@ enum port { }; struct cx25821_board { - const char *name; + char *name; enum port porta; enum port portb; enum port portc; diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c index d8eac3e30a7e..fc1ff69cffd0 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.c +++ b/trunk/drivers/media/video/cx25840/cx25840-core.c @@ -84,7 +84,7 @@ MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); /* ----------------------------------------------------------------------- */ -static void cx23888_std_setup(struct i2c_client *client); +static void cx23885_std_setup(struct i2c_client *client); int cx25840_write(struct i2c_client *client, u16 addr, u8 value) { @@ -638,13 +638,10 @@ static void cx23885_initialize(struct i2c_client *client) finish_wait(&state->fw_wait, &wait); destroy_workqueue(q); - /* Call the cx23888 specific std setup func, we no longer rely on + /* Call the cx23885 specific std setup func, we no longer rely on * the generic cx24840 func. */ - if (is_cx23888(state)) - cx23888_std_setup(client); - else - cx25840_std_setup(client); + cx23885_std_setup(client); /* (re)set input */ set_input(client, state->vid_input, state->aud_input); @@ -1106,23 +1103,9 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp cx25840_write4(client, 0x410, 0xffff0dbf); cx25840_write4(client, 0x414, 0x00137d03); - - /* on the 887, 0x418 is HSCALE_CTRL, on the 888 it is - CHROMA_CTRL */ - if (is_cx23888(state)) - cx25840_write4(client, 0x418, 0x01008080); - else - cx25840_write4(client, 0x418, 0x01000000); - + cx25840_write4(client, 0x418, 0x01008080); cx25840_write4(client, 0x41c, 0x00000000); - - /* on the 887, 0x420 is CHROMA_CTRL, on the 888 it is - CRUSH_CTRL */ - if (is_cx23888(state)) - cx25840_write4(client, 0x420, 0x001c3e0f); - else - cx25840_write4(client, 0x420, 0x001c8282); - + cx25840_write4(client, 0x420, 0x001c3e0f); cx25840_write4(client, 0x42c, 0x42600000); cx25840_write4(client, 0x430, 0x0000039b); cx25840_write4(client, 0x438, 0x00000000); @@ -1250,7 +1233,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp cx25840_write4(client, 0x8d0, 0x1f063870); } - if (is_cx23888(state)) { + if (is_cx2388x(state)) { /* HVR1850 */ /* AUD_IO_CTRL - I2S Input, Parallel1*/ /* - Channel 1 src - Parallel1 (Merlin out) */ @@ -1315,8 +1298,8 @@ static int set_v4lstd(struct i2c_client *client) } cx25840_and_or(client, 0x400, ~0xf, fmt); cx25840_and_or(client, 0x403, ~0x3, pal_m); - if (is_cx23888(state)) - cx23888_std_setup(client); + if (is_cx2388x(state)) + cx23885_std_setup(client); else cx25840_std_setup(client); if (!is_cx2583x(state)) @@ -1329,7 +1312,6 @@ static int set_v4lstd(struct i2c_client *client) static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = to_sd(ctrl); - struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); switch (ctrl->id) { @@ -1342,20 +1324,12 @@ static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_SATURATION: - if (is_cx23888(state)) { - cx25840_write(client, 0x418, ctrl->val << 1); - cx25840_write(client, 0x419, ctrl->val << 1); - } else { - cx25840_write(client, 0x420, ctrl->val << 1); - cx25840_write(client, 0x421, ctrl->val << 1); - } + cx25840_write(client, 0x420, ctrl->val << 1); + cx25840_write(client, 0x421, ctrl->val << 1); break; case V4L2_CID_HUE: - if (is_cx23888(state)) - cx25840_write(client, 0x41a, ctrl->val); - else - cx25840_write(client, 0x422, ctrl->val); + cx25840_write(client, 0x422, ctrl->val); break; default: @@ -1380,21 +1354,11 @@ static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - if (is_cx23888(state)) { - Vsrc = (cx25840_read(client, 0x42a) & 0x3f) << 4; - Vsrc |= (cx25840_read(client, 0x429) & 0xf0) >> 4; - } else { - Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; - Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; - } + Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; + Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; - if (is_cx23888(state)) { - Hsrc = (cx25840_read(client, 0x426) & 0x3f) << 4; - Hsrc |= (cx25840_read(client, 0x425) & 0xf0) >> 4; - } else { - Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; - Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; - } + Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; + Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; Vlines = fmt->height + (is_50Hz ? 4 : 7); @@ -1818,8 +1782,8 @@ static int cx25840_s_video_routing(struct v4l2_subdev *sd, struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (is_cx23888(state)) - cx23888_std_setup(client); + if (is_cx2388x(state)) + cx23885_std_setup(client); return set_input(client, input, state->aud_input); } @@ -1830,8 +1794,8 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd, struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (is_cx23888(state)) - cx23888_std_setup(client); + if (is_cx2388x(state)) + cx23885_std_setup(client); return set_input(client, state->vid_input, input); } @@ -4975,7 +4939,7 @@ void cx23885_dif_setup(struct i2c_client *client, u32 ifHz) } } -static void cx23888_std_setup(struct i2c_client *client) +static void cx23885_std_setup(struct i2c_client *client) { struct cx25840_state *state = to_state(i2c_get_clientdata(client)); v4l2_std_id std = state->std; diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index ed7b2aa1ed83..e46446a449c0 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -471,7 +471,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) dprintk(1,"Loading firmware ...\n"); dataptr = (u32*)firmware->data; for (i = 0; i < (firmware->size >> 2); i++) { - value = le32_to_cpu(*dataptr); + value = *dataptr; checksum += ~value; memory_write(dev->core, i, value); dataptr++; diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index 862c6575c557..20a7e24de6fb 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -974,7 +974,6 @@ struct em28xx_board em28xx_boards[] = { [EM2884_BOARD_CINERGY_HTC_STICK] = { .name = "Terratec Cinergy HTC Stick", .has_dvb = 1, - .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, #if 0 .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x41, @@ -2893,7 +2892,7 @@ static void request_module_async(struct work_struct *work) if (dev->board.has_dvb) request_module("em28xx-dvb"); - if (dev->board.ir_codes && !disable_ir) + if (dev->board.has_ir_i2c && !disable_ir) request_module("em28xx-rc"); } diff --git a/trunk/drivers/media/video/em28xx/em28xx-input.c b/trunk/drivers/media/video/em28xx/em28xx-input.c index 5e30c4f3f248..fce5f7680c99 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-input.c +++ b/trunk/drivers/media/video/em28xx/em28xx-input.c @@ -527,8 +527,6 @@ static int em28xx_ir_init(struct em28xx *dev) if (dev->board.ir_codes == NULL) { /* No remote control support */ - em28xx_warn("Remote control support is not available for " - "this card.\n"); return 0; } diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c index 31721eadc597..137166d73945 100644 --- a/trunk/drivers/media/video/gspca/gspca.c +++ b/trunk/drivers/media/video/gspca/gspca.c @@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { struct gspca_dev *gspca_dev = video_drvdata(file); - int i, ret; + int ret; if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1678,8 +1678,6 @@ static int vidioc_streamoff(struct file *file, void *priv, wake_up_interruptible(&gspca_dev->wq); /* empty the transfer queues */ - for (i = 0; i < gspca_dev->nframes; i++) - gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; atomic_set(&gspca_dev->fr_q, 0); atomic_set(&gspca_dev->fr_i, 0); gspca_dev->fr_o = 0; diff --git a/trunk/drivers/media/video/gspca/ov534.c b/trunk/drivers/media/video/gspca/ov534.c index 80c81dd6d68b..b5acb1e4b4e7 100644 --- a/trunk/drivers/media/video/gspca/ov534.c +++ b/trunk/drivers/media/video/gspca/ov534.c @@ -96,7 +96,7 @@ static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setgain(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); -static void setagc(struct gspca_dev *gspca_dev); +static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val); static void setawb(struct gspca_dev *gspca_dev); static void setaec(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); @@ -189,7 +189,7 @@ static const struct ctrl sd_ctrls[] = { .step = 1, .default_value = 1, }, - .set_control = setagc + .set = sd_setagc }, [AWB] = { { @@ -851,7 +851,6 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { - msleep(10); data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); switch (data) { @@ -1243,6 +1242,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->ctrls = sd->ctrls; + /* the auto white balance control works only when auto gain is set */ + if (sd_ctrls[AGC].qctrl.default_value == 0) + gspca_dev->ctrl_inac |= (1 << AWB); + cam->cam_mode = ov772x_mode; cam->nmodes = ARRAY_SIZE(ov772x_mode); @@ -1483,6 +1486,29 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } while (remaining_len > 0); } +static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->ctrls[AGC].val = val; + + /* the auto white balance control works only + * when auto gain is set */ + if (val) { + gspca_dev->ctrl_inac &= ~(1 << AWB); + } else { + gspca_dev->ctrl_inac |= (1 << AWB); + if (sd->ctrls[AWB].val) { + sd->ctrls[AWB].val = 0; + if (gspca_dev->streaming) + setawb(gspca_dev); + } + } + if (gspca_dev->streaming) + setagc(gspca_dev); + return gspca_dev->usb_err; +} + static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { diff --git a/trunk/drivers/media/video/gspca/ov534_9.c b/trunk/drivers/media/video/gspca/ov534_9.c index 1fd41f0d2e95..b5797308a39b 100644 --- a/trunk/drivers/media/video/gspca/ov534_9.c +++ b/trunk/drivers/media/video/gspca/ov534_9.c @@ -1008,7 +1008,6 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { - msleep(10); data = reg_r(gspca_dev, OV534_REG_STATUS); switch (data) { diff --git a/trunk/drivers/media/video/gspca/pac7311.c b/trunk/drivers/media/video/gspca/pac7311.c index 115da169f32a..2cb7d95f7be7 100644 --- a/trunk/drivers/media/video/gspca/pac7311.c +++ b/trunk/drivers/media/video/gspca/pac7311.c @@ -418,7 +418,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); + v4l2_ctrl_handler_init(hdl, 4); sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, 15, 1, 7); diff --git a/trunk/drivers/media/video/gspca/sn9c20x.c b/trunk/drivers/media/video/gspca/sn9c20x.c index b9c6f17eabb2..ad098202d7f0 100644 --- a/trunk/drivers/media/video/gspca/sn9c20x.c +++ b/trunk/drivers/media/video/gspca/sn9c20x.c @@ -1761,6 +1761,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_SATURATION, 0, 255, 1, 127); sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0); + v4l2_ctrl_cluster(4, &sd->brightness); sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, 0, 255, 1, 0x10); @@ -1769,6 +1770,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); + v4l2_ctrl_cluster(2, &sd->blue); if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && @@ -1777,6 +1779,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_HFLIP, 0, 1, 1, 0); sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_cluster(2, &sd->hflip); } if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && @@ -1791,20 +1794,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_GAIN, 0, 28, 1, 0); sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - } - - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - v4l2_ctrl_cluster(4, &sd->brightness); - v4l2_ctrl_cluster(2, &sd->blue); - if (sd->hflip) - v4l2_ctrl_cluster(2, &sd->hflip); - if (sd->autogain) { if (sd->sensor == SENSOR_SOI968) /* this sensor doesn't have the exposure control and autogain is clustered with gain instead. This works @@ -1814,6 +1803,13 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) /* Otherwise autogain is clustered with exposure. */ v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); } + + sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } return 0; } @@ -2070,13 +2066,10 @@ static int sd_start(struct gspca_dev *gspca_dev) set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue), v4l2_ctrl_g_ctrl(sd->red)); - if (sd->gain) - set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); - if (sd->exposure) - set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); - if (sd->hflip) - set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), - v4l2_ctrl_g_ctrl(sd->vflip)); + set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); + set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); + set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), + v4l2_ctrl_g_ctrl(sd->vflip)); reg_w1(gspca_dev, 0x1007, 0x20); reg_w1(gspca_dev, 0x1061, 0x03); @@ -2179,7 +2172,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int avg_lum; - if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain)) + if (!v4l2_ctrl_g_ctrl(sd->autogain)) return; avg_lum = atomic_read(&sd->avg_lum); diff --git a/trunk/drivers/media/video/gspca/sonixj.c b/trunk/drivers/media/video/gspca/sonixj.c index f38faa9b37c3..4d1696d1a7f4 100644 --- a/trunk/drivers/media/video/gspca/sonixj.c +++ b/trunk/drivers/media/video/gspca/sonixj.c @@ -3120,7 +3120,7 @@ static const struct sd_desc sd_desc = { | (SENSOR_ ## sensor << 8) \ | (flags) static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)}, + {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)}, {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)}, diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.c b/trunk/drivers/media/video/ivtv/ivtv-driver.c index 5462ce2f60ea..057929e165ab 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.c +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.c @@ -866,10 +866,10 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, pci_write_config_dword(pdev, 0x40, 0xffff); IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%llx\n", + "irq: %d, latency: %d, memory: 0x%lx\n", pdev->device, pdev->revision, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev->irq, pci_latency, (u64)itv->base_addr); + pdev->irq, pci_latency, (unsigned long)itv->base_addr); return 0; } @@ -1007,7 +1007,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, itv->cxhdl.priv = itv; itv->cxhdl.func = ivtv_api_func; - IVTV_DEBUG_INFO("base addr: 0x%llx\n", (u64)itv->base_addr); + IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); /* PCI Device Setup */ retval = ivtv_setup_pci(itv, pdev, pci_id); @@ -1017,8 +1017,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, goto free_mem; /* map io memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", - (u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", + itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); if (!itv->enc_mem) { @@ -1034,8 +1034,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } if (itv->has_cx23415) { - IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", - (u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", + itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); if (!itv->dec_mem) { @@ -1056,8 +1056,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } /* map registers memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", - (u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", + itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); itv->reg_mem = ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (!itv->reg_mem) { diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.h b/trunk/drivers/media/video/ivtv/ivtv-driver.h index a7e00f8938f8..2e220028aad2 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.h +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.h @@ -622,7 +622,7 @@ struct ivtv { struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ struct v4l2_subdev *sd_audio; /* controlling audio subdev */ struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */ - resource_size_t base_addr; /* PCI resource base address */ + u32 base_addr; /* PCI resource base address */ volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ volatile void __iomem *reg_mem; /* pointer to mapped registers */ diff --git a/trunk/drivers/media/video/mem2mem_testdev.c b/trunk/drivers/media/video/mem2mem_testdev.c index 3945556f5733..d2dec585e61b 100644 --- a/trunk/drivers/media/video/mem2mem_testdev.c +++ b/trunk/drivers/media/video/mem2mem_testdev.c @@ -110,6 +110,22 @@ enum { V4L2_M2M_DST = 1, }; +/* Source and destination queue data */ +static struct m2mtest_q_data q_data[2]; + +static struct m2mtest_q_data *get_q_data(enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &q_data[V4L2_M2M_SRC]; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &q_data[V4L2_M2M_DST]; + default: + BUG(); + } + return NULL; +} + #define V4L2_CID_TRANS_TIME_MSEC V4L2_CID_PRIVATE_BASE #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE + 1) @@ -182,26 +198,8 @@ struct m2mtest_ctx { int aborting; struct v4l2_m2m_ctx *m2m_ctx; - - /* Source and destination queue data */ - struct m2mtest_q_data q_data[2]; }; -static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, - enum v4l2_buf_type type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - return &ctx->q_data[V4L2_M2M_SRC]; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &ctx->q_data[V4L2_M2M_DST]; - default: - BUG(); - } - return NULL; -} - - static struct v4l2_queryctrl *get_ctrl(int id) { int i; @@ -225,7 +223,7 @@ static int device_process(struct m2mtest_ctx *ctx, int tile_w, bytes_left; int width, height, bytesperline; - q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT); width = q_data->width; height = q_data->height; @@ -438,7 +436,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(ctx, f->type); + q_data = get_q_data(f->type); f->fmt.pix.width = q_data->width; f->fmt.pix.height = q_data->height; @@ -537,7 +535,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(ctx, f->type); + q_data = get_q_data(f->type); if (!q_data) return -EINVAL; @@ -749,7 +747,7 @@ static int m2mtest_queue_setup(struct vb2_queue *vq, struct m2mtest_q_data *q_data; unsigned int size, count = *nbuffers; - q_data = get_q_data(ctx, vq->type); + q_data = get_q_data(vq->type); size = q_data->width * q_data->height * q_data->fmt->depth >> 3; @@ -777,7 +775,7 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb) dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); - q_data = get_q_data(ctx, vb->vb2_queue->type); + q_data = get_q_data(vb->vb2_queue->type); if (vb2_plane_size(vb, 0) < q_data->sizeimage) { dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n", @@ -862,9 +860,6 @@ static int m2mtest_open(struct file *file) ctx->transtime = MEM2MEM_DEF_TRANSTIME; ctx->num_processed = 0; - ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; - ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; - ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); if (IS_ERR(ctx->m2m_ctx)) { @@ -991,6 +986,9 @@ static int m2mtest_probe(struct platform_device *pdev) goto err_m2m; } + q_data[V4L2_M2M_SRC].fmt = &formats[0]; + q_data[V4L2_M2M_DST].fmt = &formats[0]; + return 0; v4l2_m2m_release(dev->m2m_dev); diff --git a/trunk/drivers/media/video/mx2_camera.c b/trunk/drivers/media/video/mx2_camera.c index 637bde8aca28..ded26b7286fa 100644 --- a/trunk/drivers/media/video/mx2_camera.c +++ b/trunk/drivers/media/video/mx2_camera.c @@ -83,7 +83,6 @@ #define CSICR1_INV_DATA (1 << 3) #define CSICR1_INV_PCLK (1 << 2) #define CSICR1_REDGE (1 << 1) -#define CSICR1_FMT_MASK (CSICR1_PACK_DIR | CSICR1_SWAP16_EN) #define SHIFT_STATFF_LEVEL 22 #define SHIFT_RXFF_LEVEL 19 @@ -231,7 +230,6 @@ struct mx2_prp_cfg { u32 src_pixel; u32 ch1_pixel; u32 irq_flags; - u32 csicr1; }; /* prp resizing parameters */ @@ -332,7 +330,6 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { .ch1_pixel = 0x2ca00565, /* RGB565 */ .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR | PRP_INTR_CH1FC | PRP_INTR_LBOVF, - .csicr1 = 0, } }, { @@ -346,7 +343,6 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR | PRP_INTR_CH2FC | PRP_INTR_LBOVF | PRP_INTR_CH2OVF, - .csicr1 = CSICR1_PACK_DIR, } }, { @@ -360,7 +356,6 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR | PRP_INTR_CH2FC | PRP_INTR_LBOVF | PRP_INTR_CH2OVF, - .csicr1 = CSICR1_SWAP16_EN, } }, }; @@ -989,6 +984,7 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; + const struct soc_camera_format_xlate *xlate; unsigned long common_flags; int ret; int bytesperline; @@ -1033,7 +1029,24 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) return ret; } - csicr1 = (csicr1 & ~CSICR1_FMT_MASK) | pcdev->emma_prp->cfg.csicr1; + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(icd->parent, "Format %x not found\n", pixfmt); + return -EINVAL; + } + + if (xlate->code == V4L2_MBUS_FMT_YUYV8_2X8) { + csicr1 |= CSICR1_PACK_DIR; + csicr1 &= ~CSICR1_SWAP16_EN; + dev_dbg(icd->parent, "already yuyv format, don't convert\n"); + } else if (xlate->code == V4L2_MBUS_FMT_UYVY8_2X8) { + csicr1 &= ~CSICR1_PACK_DIR; + csicr1 |= CSICR1_SWAP16_EN; + dev_dbg(icd->parent, "convert uyvy mbus format into yuyv\n"); + } else { + dev_warn(icd->parent, "mbus format not supported\n"); + return -EINVAL; + } if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; @@ -1142,6 +1155,18 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, } } + if (code == V4L2_MBUS_FMT_UYVY8_2X8) { + formats++; + if (xlate) { + xlate->host_fmt = + soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8); + xlate->code = code; + dev_dbg(dev, "Providing host format %s for sensor code %d\n", + xlate->host_fmt->name, code); + xlate++; + } + } + /* Generic pass-trough */ formats++; if (xlate) { diff --git a/trunk/drivers/media/video/omap3isp/isppreview.c b/trunk/drivers/media/video/omap3isp/isppreview.c index dd91da26f1b0..8a4935ecc655 100644 --- a/trunk/drivers/media/video/omap3isp/isppreview.c +++ b/trunk/drivers/media/video/omap3isp/isppreview.c @@ -888,12 +888,12 @@ static const struct preview_update update_attrs[] = { preview_config_contrast, NULL, offsetof(struct prev_params, contrast), - 0, 0, true, + 0, true, }, /* OMAP3ISP_PREV_BRIGHTNESS */ { preview_config_brightness, NULL, offsetof(struct prev_params, brightness), - 0, 0, true, + 0, true, }, }; @@ -1102,7 +1102,7 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active) unsigned int elv = prev->crop.top + prev->crop.height - 1; u32 features; - if (format->code != V4L2_MBUS_FMT_Y10_1X10) { + if (format->code == V4L2_MBUS_FMT_Y10_1X10) { sph -= 2; eph += 2; slv -= 2; diff --git a/trunk/drivers/media/video/pms.c b/trunk/drivers/media/video/pms.c index b4c679b3fb0f..af2d9086d7e8 100644 --- a/trunk/drivers/media/video/pms.c +++ b/trunk/drivers/media/video/pms.c @@ -26,11 +26,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c index 725812aa0c30..354574591908 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c @@ -350,8 +350,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, if (pixm) sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); else - sizes[i] = max_t(u32, size, frame->payload[i]); - + sizes[i] = size; allocators[i] = ctx->fimc_dev->alloc_ctx; } @@ -480,39 +479,37 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc); static int fimc_capture_open(struct file *file) { struct fimc_dev *fimc = video_drvdata(file); - int ret; + int ret = v4l2_fh_open(file); + + if (ret) + return ret; dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); + /* Return if the corresponding video mem2mem node is already opened. */ if (fimc_m2m_active(fimc)) return -EBUSY; set_bit(ST_CAPT_BUSY, &fimc->state); - ret = pm_runtime_get_sync(&fimc->pdev->dev); - if (ret < 0) - return ret; - - ret = v4l2_fh_open(file); - if (ret) - return ret; + pm_runtime_get_sync(&fimc->pdev->dev); - if (++fimc->vid_cap.refcnt != 1) - return 0; + if (++fimc->vid_cap.refcnt == 1) { + ret = fimc_pipeline_initialize(&fimc->pipeline, + &fimc->vid_cap.vfd->entity, true); + if (ret < 0) { + dev_err(&fimc->pdev->dev, + "Video pipeline initialization failed\n"); + pm_runtime_put_sync(&fimc->pdev->dev); + fimc->vid_cap.refcnt--; + v4l2_fh_release(file); + clear_bit(ST_CAPT_BUSY, &fimc->state); + return ret; + } + ret = fimc_capture_ctrls_create(fimc); - ret = fimc_pipeline_initialize(&fimc->pipeline, - &fimc->vid_cap.vfd->entity, true); - if (ret < 0) { - clear_bit(ST_CAPT_BUSY, &fimc->state); - pm_runtime_put_sync(&fimc->pdev->dev); - fimc->vid_cap.refcnt--; - v4l2_fh_release(file); - return ret; + if (!ret && !fimc->vid_cap.user_subdev_api) + ret = fimc_capture_set_default_format(fimc); } - ret = fimc_capture_ctrls_create(fimc); - - if (!ret && !fimc->vid_cap.user_subdev_api) - ret = fimc_capture_set_default_format(fimc); - return ret; } @@ -821,6 +818,9 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh, struct fimc_dev *fimc = video_drvdata(file); struct fimc_ctx *ctx = fimc->vid_cap.ctx; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; + return fimc_fill_format(&ctx->d_frame, f); } @@ -833,6 +833,9 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, struct v4l2_mbus_framefmt mf; struct fimc_fmt *ffmt = NULL; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; + if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { fimc_capture_try_format(ctx, &pix->width, &pix->height, NULL, &pix->pixelformat, @@ -884,6 +887,8 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) struct fimc_fmt *s_fmt = NULL; int ret, i; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; if (vb2_is_busy(&fimc->vid_cap.vbq)) return -EBUSY; @@ -919,10 +924,10 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) pix->width = mf->width; pix->height = mf->height; } - fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); for (i = 0; i < ff->fmt->colplanes; i++) - ff->payload[i] = pix->plane_fmt[i].sizeimage; + ff->payload[i] = + (pix->width * pix->height * ff->fmt->depth[i]) / 8; set_frame_bounds(ff, pix->width, pix->height); /* Reset the composition rectangle if not yet configured */ @@ -1040,22 +1045,18 @@ static int fimc_cap_streamon(struct file *file, void *priv, { struct fimc_dev *fimc = video_drvdata(file); struct fimc_pipeline *p = &fimc->pipeline; - struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR]; int ret; if (fimc_capture_active(fimc)) return -EBUSY; - ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline); - if (ret < 0) - return ret; + media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, + p->m_pipeline); if (fimc->vid_cap.user_subdev_api) { ret = fimc_pipeline_validate(fimc); - if (ret < 0) { - media_entity_pipeline_stop(&sd->entity); + if (ret) return ret; - } } return vb2_streamon(&fimc->vid_cap.vbq, type); } diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-core.c b/trunk/drivers/media/video/s5p-fimc/fimc-core.c index a4646ca1d56f..fedcd561ba27 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-core.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-core.c @@ -153,7 +153,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr", + .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -161,7 +161,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr", + .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 2, 2 }, @@ -169,7 +169,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 3, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contig. 2p, tiled", + .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled", .fourcc = V4L2_PIX_FMT_NV12MT, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -615,7 +615,7 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS; if (!handler->error) { - v4l2_ctrl_cluster(2, &ctrls->colorfx); + v4l2_ctrl_cluster(3, &ctrls->colorfx); ctrls->ready = true; } @@ -641,7 +641,7 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) if (!ctrls->ready) return; - mutex_lock(ctrls->handler.lock); + mutex_lock(&ctrls->handler.lock); v4l2_ctrl_activate(ctrls->rotate, active); v4l2_ctrl_activate(ctrls->hflip, active); v4l2_ctrl_activate(ctrls->vflip, active); @@ -660,7 +660,7 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) ctx->hflip = 0; ctx->vflip = 0; } - mutex_unlock(ctrls->handler.lock); + mutex_unlock(&ctrls->handler.lock); } /* Update maximum value of the alpha color control */ @@ -741,8 +741,8 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, pix->width = width; for (i = 0; i < pix->num_planes; ++i) { - struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i]; - u32 bpl = plane_fmt->bytesperline; + u32 bpl = pix->plane_fmt[i].bytesperline; + u32 *sizeimage = &pix->plane_fmt[i].sizeimage; if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) bpl = pix->width; /* Planar */ @@ -754,9 +754,8 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, if (i == 0) /* Same bytesperline for each plane. */ bytesperline = bpl; - plane_fmt->bytesperline = bytesperline; - plane_fmt->sizeimage = max((pix->width * pix->height * - fmt->depth[i]) / 8, plane_fmt->sizeimage); + pix->plane_fmt[i].bytesperline = bytesperline; + *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8; } } diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-lite.c b/trunk/drivers/media/video/s5p-fimc/fimc-lite.c index 74ff310db30c..400d701aef04 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-lite.c @@ -451,44 +451,34 @@ static void fimc_lite_clear_event_counters(struct fimc_lite *fimc) static int fimc_lite_open(struct file *file) { struct fimc_lite *fimc = video_drvdata(file); - int ret; + int ret = v4l2_fh_open(file); - if (mutex_lock_interruptible(&fimc->lock)) - return -ERESTARTSYS; + if (ret) + return ret; set_bit(ST_FLITE_IN_USE, &fimc->state); - ret = pm_runtime_get_sync(&fimc->pdev->dev); - if (ret < 0) - goto done; + pm_runtime_get_sync(&fimc->pdev->dev); - ret = v4l2_fh_open(file); - if (ret < 0) - goto done; - - if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) { - ret = fimc_pipeline_initialize(&fimc->pipeline, - &fimc->vfd->entity, true); - if (ret < 0) { - pm_runtime_put_sync(&fimc->pdev->dev); - fimc->ref_count--; - v4l2_fh_release(file); - clear_bit(ST_FLITE_IN_USE, &fimc->state); - } + if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA) + return ret; - fimc_lite_clear_event_counters(fimc); + ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, + true); + if (ret < 0) { + v4l2_err(fimc->vfd, "Video pipeline initialization failed\n"); + pm_runtime_put_sync(&fimc->pdev->dev); + fimc->ref_count--; + v4l2_fh_release(file); + clear_bit(ST_FLITE_IN_USE, &fimc->state); } -done: - mutex_unlock(&fimc->lock); + + fimc_lite_clear_event_counters(fimc); return ret; } static int fimc_lite_close(struct file *file) { struct fimc_lite *fimc = video_drvdata(file); - int ret; - - if (mutex_lock_interruptible(&fimc->lock)) - return -ERESTARTSYS; if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { clear_bit(ST_FLITE_IN_USE, &fimc->state); @@ -502,39 +492,20 @@ static int fimc_lite_close(struct file *file) if (fimc->ref_count == 0) vb2_queue_release(&fimc->vb_queue); - ret = v4l2_fh_release(file); - - mutex_unlock(&fimc->lock); - return ret; + return v4l2_fh_release(file); } static unsigned int fimc_lite_poll(struct file *file, struct poll_table_struct *wait) { struct fimc_lite *fimc = video_drvdata(file); - int ret; - - if (mutex_lock_interruptible(&fimc->lock)) - return POLL_ERR; - - ret = vb2_poll(&fimc->vb_queue, file, wait); - mutex_unlock(&fimc->lock); - - return ret; + return vb2_poll(&fimc->vb_queue, file, wait); } static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma) { struct fimc_lite *fimc = video_drvdata(file); - int ret; - - if (mutex_lock_interruptible(&fimc->lock)) - return -ERESTARTSYS; - - ret = vb2_mmap(&fimc->vb_queue, vma); - mutex_unlock(&fimc->lock); - - return ret; + return vb2_mmap(&fimc->vb_queue, vma); } static const struct v4l2_file_operations fimc_lite_fops = { @@ -791,9 +762,7 @@ static int fimc_lite_streamon(struct file *file, void *priv, if (fimc_lite_active(fimc)) return -EBUSY; - ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline); - if (ret < 0) - return ret; + media_entity_pipeline_start(&sensor->entity, p->m_pipeline); ret = fimc_pipeline_validate(fimc); if (ret) { @@ -1539,7 +1508,7 @@ static int fimc_lite_suspend(struct device *dev) return 0; ret = fimc_lite_stop_capture(fimc, suspend); - if (ret < 0 || !fimc_lite_active(fimc)) + if (ret) return ret; return fimc_pipeline_shutdown(&fimc->pipeline); diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c index 52cef4865423..6753c45631b8 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -193,13 +193,9 @@ int __fimc_pipeline_shutdown(struct fimc_pipeline *p) int fimc_pipeline_shutdown(struct fimc_pipeline *p) { - struct media_entity *me; + struct media_entity *me = &p->subdevs[IDX_SENSOR]->entity; int ret; - if (!p || !p->subdevs[IDX_SENSOR]) - return -EINVAL; - - me = &p->subdevs[IDX_SENSOR]->entity; mutex_lock(&me->parent->graph_mutex); ret = __fimc_pipeline_shutdown(p); mutex_unlock(&me->parent->graph_mutex); @@ -502,12 +498,12 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) * @source: the source entity to create links to all fimc entities from * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null * @pad: the source entity pad index - * @link_mask: bitmask of the fimc devices for which link should be enabled + * @fimc_id: index of the fimc device for which link should be enabled */ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, struct media_entity *source, struct v4l2_subdev *sensor, - int pad, int link_mask) + int pad, int fimc_id) { struct fimc_sensor_info *s_info; struct media_entity *sink; @@ -524,7 +520,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc[i]->variant->has_cam_if) continue; - flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0; + flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; sink = &fmd->fimc[i]->vid_cap.subdev.entity; ret = media_entity_create_link(source, pad, sink, @@ -556,10 +552,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc_lite[i]) continue; - if (link_mask & (1 << (i + FIMC_MAX_DEVS))) - flags = MEDIA_LNK_FL_ENABLED; - else - flags = 0; + flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; sink = &fmd->fimc_lite[i]->subdev.entity; ret = media_entity_create_link(source, pad, sink, @@ -621,8 +614,9 @@ static int fimc_md_create_links(struct fimc_md *fmd) struct s5p_fimc_isp_info *pdata; struct fimc_sensor_info *s_info; struct media_entity *source, *sink; - int i, pad, fimc_id = 0, ret = 0; - u32 flags, link_mask = 0; + int i, pad, fimc_id = 0; + int ret = 0; + u32 flags; for (i = 0; i < fmd->num_sensors; i++) { if (fmd->sensor[i].subdev == NULL) @@ -674,20 +668,19 @@ static int fimc_md_create_links(struct fimc_md *fmd) if (source == NULL) continue; - link_mask = 1 << fimc_id++; ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor, - pad, link_mask); + pad, fimc_id++); } + fimc_id = 0; for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) { if (fmd->csis[i].sd == NULL) continue; source = &fmd->csis[i].sd->entity; pad = CSIS_PAD_SOURCE; - link_mask = 1 << fimc_id++; ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL, - pad, link_mask); + pad, fimc_id++); } /* Create immutable links between each FIMC's subdev and video node */ @@ -741,8 +734,8 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) } static int __fimc_md_set_camclk(struct fimc_md *fmd, - struct fimc_sensor_info *s_info, - bool on) + struct fimc_sensor_info *s_info, + bool on) { struct s5p_fimc_isp_info *pdata = s_info->pdata; struct fimc_camclk_info *camclk; @@ -751,10 +744,12 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL) return -EINVAL; + if (s_info->clk_on == on) + return 0; camclk = &fmd->camclk[pdata->clk_id]; - dbg("camclk %d, f: %lu, use_count: %d, on: %d", - pdata->clk_id, pdata->clk_frequency, camclk->use_count, on); + dbg("camclk %d, f: %lu, clk: %p, on: %d", + pdata->clk_id, pdata->clk_frequency, camclk, on); if (on) { if (camclk->use_count > 0 && @@ -765,9 +760,11 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, clk_set_rate(camclk->clock, pdata->clk_frequency); camclk->frequency = pdata->clk_frequency; ret = clk_enable(camclk->clock); - dbg("Enabled camclk %d: f: %lu", pdata->clk_id, - clk_get_rate(camclk->clock)); } + s_info->clk_on = 1; + dbg("Enabled camclk %d: f: %lu", pdata->clk_id, + clk_get_rate(camclk->clock)); + return ret; } @@ -776,6 +773,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (--camclk->use_count == 0) { clk_disable(camclk->clock); + s_info->clk_on = 0; dbg("Disabled camclk %d", pdata->clk_id); } return ret; @@ -791,6 +789,8 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, * devices to which sensors can be attached, either directly or through * the MIPI CSI receiver. The clock is allowed here to be used by * multiple sensors concurrently if they use same frequency. + * The per sensor subdev clk_on attribute helps to synchronize accesses + * to the sclk_cam clocks from the video and media device nodes. * This function should only be called when the graph mutex is held. */ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.h b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.h index 1f5dbaff5442..3b8a3492a176 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.h +++ b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.h @@ -47,6 +47,7 @@ struct fimc_camclk_info { * @pdata: sensor's atrributes passed as media device's platform data * @subdev: image sensor v4l2 subdev * @host: fimc device the sensor is currently linked to + * @clk_on: sclk_cam clock's state associated with this subdev * * This data structure applies to image sensor and the writeback subdevs. */ @@ -54,6 +55,7 @@ struct fimc_sensor_info { struct s5p_fimc_isp_info *pdata; struct v4l2_subdev *subdev; struct fimc_dev *host; + bool clk_on; }; /** diff --git a/trunk/drivers/media/video/s5p-mfc/regs-mfc.h b/trunk/drivers/media/video/s5p-mfc/regs-mfc.h index a19bece41ba9..053a8a872fd7 100644 --- a/trunk/drivers/media/video/s5p-mfc/regs-mfc.h +++ b/trunk/drivers/media/video/s5p-mfc/regs-mfc.h @@ -164,15 +164,10 @@ decoded pic */ #define S5P_FIMV_SI_DISPLAY_Y_ADR 0x2010 /* luma addr of displayed pic */ #define S5P_FIMV_SI_DISPLAY_C_ADR 0x2014 /* chroma addrof displayed pic */ - #define S5P_FIMV_SI_CONSUMED_BYTES 0x2018 /* Consumed number of bytes to decode a frame */ #define S5P_FIMV_SI_DISPLAY_STATUS 0x201c /* status of decoded picture */ -#define S5P_FIMV_SI_DECODE_Y_ADR 0x2024 /* luma addr of decoded pic */ -#define S5P_FIMV_SI_DECODE_C_ADR 0x2028 /* chroma addrof decoded pic */ -#define S5P_FIMV_SI_DECODE_STATUS 0x202c /* status of decoded picture */ - #define S5P_FIMV_SI_CH0_SB_ST_ADR 0x2044 /* start addr of stream buf */ #define S5P_FIMV_SI_CH0_SB_FRM_SIZE 0x2048 /* size of stream buf */ #define S5P_FIMV_SI_CH0_DESC_ADR 0x204c /* addr of descriptor buf */ diff --git a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index feea867f318c..c25ec022d267 100644 --- a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -627,13 +627,13 @@ static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY: - ctx->display_delay = ctrl->val; + ctx->loop_filter_mpeg4 = ctrl->val; break; case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE: ctx->display_delay_enable = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: - ctx->loop_filter_mpeg4 = ctrl->val; + ctx->display_delay = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: ctx->slice_interface = ctrl->val; @@ -996,7 +996,6 @@ int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx) for (i = 0; i < NUM_CTRLS; i++) { if (IS_MFC51_PRIV(controls[i].id)) { - memset(&cfg, 0, sizeof(struct v4l2_ctrl_config)); cfg.ops = &s5p_mfc_dec_ctrl_ops; cfg.id = controls[i].id; cfg.min = controls[i].minimum; diff --git a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 158b78989b89..acedb2004be3 100644 --- a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -243,6 +243,12 @@ static struct mfc_control controls[] = { .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0, .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_1) + ), }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, @@ -488,7 +494,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED, - .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, + .default_value = 0, .menu_skip_mask = 0, }, { @@ -528,7 +534,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, - .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, + .default_value = 0, .menu_skip_mask = 0, }, { @@ -901,8 +907,6 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_err("failed to try output format\n"); return -EINVAL; } - v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, - &pix_fmt_mp->height, 4, 1080, 1, 0); } else { mfc_err("invalid buf type\n"); return -EINVAL; @@ -1773,7 +1777,6 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx) } for (i = 0; i < NUM_CTRLS; i++) { if (IS_MFC51_PRIV(controls[i].id)) { - memset(&cfg, 0, sizeof(struct v4l2_ctrl_config)); cfg.ops = &s5p_mfc_enc_ctrl_ops; cfg.id = controls[i].id; cfg.min = controls[i].minimum; diff --git a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_opr.h index 5932d1c782c5..db83836e6a9f 100644 --- a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_opr.h +++ b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_opr.h @@ -57,12 +57,10 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq); S5P_FIMV_SI_DISPLAY_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \ - S5P_FIMV_SI_DECODE_Y_ADR) << \ + S5P_FIMV_SI_DISPLAY_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dspl_status() readl(dev->regs_base + \ S5P_FIMV_SI_DISPLAY_STATUS) -#define s5p_mfc_get_dec_status() readl(dev->regs_base + \ - S5P_FIMV_SI_DECODE_STATUS) #define s5p_mfc_get_frame_type() (readl(dev->regs_base + \ S5P_FIMV_DECODE_FRAME_TYPE) \ & S5P_FIMV_DECODE_FRAME_MASK) diff --git a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_shm.h index cf962a466276..764eac6bcc4c 100644 --- a/trunk/drivers/media/video/s5p-mfc/s5p_mfc_shm.h +++ b/trunk/drivers/media/video/s5p-mfc/s5p_mfc_shm.h @@ -13,7 +13,8 @@ #ifndef S5P_MFC_SHM_H_ #define S5P_MFC_SHM_H_ -enum MFC_SHM_OFS { +enum MFC_SHM_OFS +{ EXTENEDED_DECODE_STATUS = 0x00, /* D */ SET_FRAME_TAG = 0x04, /* D */ GET_FRAME_TAG_TOP = 0x08, /* D */ diff --git a/trunk/drivers/media/video/smiapp/Kconfig b/trunk/drivers/media/video/smiapp/Kconfig index fb99ff18be07..f7b35ff443bf 100644 --- a/trunk/drivers/media/video/smiapp/Kconfig +++ b/trunk/drivers/media/video/smiapp/Kconfig @@ -1,6 +1,6 @@ config VIDEO_SMIAPP tristate "SMIA++/SMIA sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API select VIDEO_SMIAPP_PLL ---help--- This is a generic driver for SMIA++/SMIA camera modules. diff --git a/trunk/drivers/media/video/smiapp/smiapp-core.c b/trunk/drivers/media/video/smiapp/smiapp-core.c index 9cf5bda35fbe..f518026cb67b 100644 --- a/trunk/drivers/media/video/smiapp/smiapp-core.c +++ b/trunk/drivers/media/video/smiapp/smiapp-core.c @@ -31,9 +31,7 @@ #include #include #include -#include #include -#include #include #include diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 1ad5ab6ce5cf..3e050e12153b 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -1178,7 +1178,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (vt->type != V4L2_TUNER_RADIO) { + if (t->mode != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; vt->rangelow = tv_range[0] * 16; vt->rangehigh = tv_range[1] * 16; diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index 0cbada18f6f5..5ccbd4629f9c 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -656,7 +656,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); - if (ops->vidioc_g_parm || vdev->vfl_type == VFL_TYPE_GRABBER) + if (ops->vidioc_g_parm || vdev->current_norm) set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); @@ -679,9 +679,6 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); - SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); - SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); - SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap); /* yes, really vidioc_subscribe_event */ SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); diff --git a/trunk/drivers/media/video/v4l2-ioctl.c b/trunk/drivers/media/video/v4l2-ioctl.c index d7fa8962d8b3..91be4e871f43 100644 --- a/trunk/drivers/media/video/v4l2-ioctl.c +++ b/trunk/drivers/media/video/v4l2-ioctl.c @@ -1680,7 +1680,6 @@ static long __video_do_ioctl(struct file *file, break; ret = 0; - p->parm.capture.readbuffers = 2; if (ops->vidioc_g_std) ret = ops->vidioc_g_std(file, fh, &std); if (ret == 0) diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c index aae1720b2f2d..4d7391ec8001 100644 --- a/trunk/drivers/media/video/vino.c +++ b/trunk/drivers/media/video/vino.c @@ -2561,7 +2561,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) } else if (vino_drvdata->decoder && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) { int input; - int data_norm = 0; + int data_norm; v4l2_std_id norm; input = VINO_INPUT_COMPOSITE; @@ -2651,7 +2651,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (vino_drvdata->decoder_owner == vcs->channel) { - int data_norm = 0; + int data_norm; v4l2_std_id norm; ret = decoder_call(video, s_routing, diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 08c10240e70f..0960d7f0d394 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -1149,14 +1149,10 @@ static ssize_t vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { struct vivi_dev *dev = video_drvdata(file); - int err; dprintk(dev, 1, "read called\n"); - mutex_lock(&dev->mutex); - err = vb2_read(&dev->vb_vidq, data, count, ppos, + return vb2_read(&dev->vb_vidq, data, count, ppos, file->f_flags & O_NONBLOCK); - mutex_unlock(&dev->mutex); - return err; } static unsigned int diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index 92144ed1ad46..e129c820df7d 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -286,7 +286,6 @@ config TWL6040_CORE depends on I2C=y && GENERIC_HARDIRQS select MFD_CORE select REGMAP_I2C - select IRQ_DOMAIN default n help Say yes here if you want support for Texas Instruments TWL6040 audio diff --git a/trunk/drivers/mfd/ab5500-core.h b/trunk/drivers/mfd/ab5500-core.h new file mode 100644 index 000000000000..63b30b17e4f3 --- /dev/null +++ b/trunk/drivers/mfd/ab5500-core.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Shared definitions and data structures for the AB5500 MFD driver + */ + +/* Read/write operation values. */ +#define AB5500_PERM_RD (0x01) +#define AB5500_PERM_WR (0x02) + +/* Read/write permissions. */ +#define AB5500_PERM_RO (AB5500_PERM_RD) +#define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR) + +#define AB5500_MASK_BASE (0x60) +#define AB5500_MASK_END (0x79) +#define AB5500_CHIP_ID (0x20) + +/** + * struct ab5500_reg_range + * @first: the first address of the range + * @last: the last address of the range + * @perm: access permissions for the range + */ +struct ab5500_reg_range { + u8 first; + u8 last; + u8 perm; +}; + +/** + * struct ab5500_i2c_ranges + * @count: the number of ranges in the list + * @range: the list of register ranges + */ +struct ab5500_i2c_ranges { + u8 nranges; + u8 bankid; + const struct ab5500_reg_range *range; +}; + +/** + * struct ab5500_i2c_banks + * @count: the number of ranges in the list + * @range: the list of register ranges + */ +struct ab5500_i2c_banks { + u8 nbanks; + const struct ab5500_i2c_ranges *bank; +}; + +/** + * struct ab5500_bank + * @slave_addr: I2C slave_addr found in AB5500 specification + * @name: Documentation name of the bank. For reference + */ +struct ab5500_bank { + u8 slave_addr; + const char *name; +}; + +static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = { + [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { + AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"}, + [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { + AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"}, + [AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"}, + [AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"}, + [AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"}, + [AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"}, + [AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"}, + [AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"}, + [AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"}, + [AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"}, + [AB5500_BANK_FG_BATTCOM_ACC] = { + AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"}, + [AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"}, + [AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"}, + [AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"}, + [AB5500_BANK_AUDIO_HEADSETUSB] = { + AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"}, +}; + +int ab5500_get_register_interruptible_raw(struct ab5500 *ab, u8 bank, u8 reg, + u8 *value); +int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues); diff --git a/trunk/drivers/mfd/mc13xxx-spi.c b/trunk/drivers/mfd/mc13xxx-spi.c index 03df422feb76..3fcdab3eb8eb 100644 --- a/trunk/drivers/mfd/mc13xxx-spi.c +++ b/trunk/drivers/mfd/mc13xxx-spi.c @@ -49,72 +49,10 @@ static struct regmap_config mc13xxx_regmap_spi_config = { .reg_bits = 7, .pad_bits = 1, .val_bits = 24, - .write_flag_mask = 0x80, .max_register = MC13XXX_NUMREGS, .cache_type = REGCACHE_NONE, - .use_single_rw = 1, -}; - -static int mc13xxx_spi_read(void *context, const void *reg, size_t reg_size, - void *val, size_t val_size) -{ - unsigned char w[4] = { *((unsigned char *) reg), 0, 0, 0}; - unsigned char r[4]; - unsigned char *p = val; - struct device *dev = context; - struct spi_device *spi = to_spi_device(dev); - struct spi_transfer t = { - .tx_buf = w, - .rx_buf = r, - .len = 4, - }; - - struct spi_message m; - int ret; - - if (val_size != 3 || reg_size != 1) - return -ENOTSUPP; - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - ret = spi_sync(spi, &m); - - memcpy(p, &r[1], 3); - - return ret; -} - -static int mc13xxx_spi_write(void *context, const void *data, size_t count) -{ - struct device *dev = context; - struct spi_device *spi = to_spi_device(dev); - - if (count != 4) - return -ENOTSUPP; - - return spi_write(spi, data, count); -} - -/* - * We cannot use regmap-spi generic bus implementation here. - * The MC13783 chip will get corrupted if CS signal is deasserted - * and on i.Mx31 SoC (the target SoC for MC13783 PMIC) the SPI controller - * has the following errata (DSPhl22960): - * "The CSPI negates SS when the FIFO becomes empty with - * SSCTL= 0. Software cannot guarantee that the FIFO will not - * drain because of higher priority interrupts and the - * non-realtime characteristics of the operating system. As a - * result, the SS will negate before all of the data has been - * transferred to/from the peripheral." - * We workaround this by accessing the SPI controller with a - * single transfert. - */ - -static struct regmap_bus regmap_mc13xxx_bus = { - .write = mc13xxx_spi_write, - .read = mc13xxx_spi_read, }; static int mc13xxx_spi_probe(struct spi_device *spi) @@ -135,13 +73,12 @@ static int mc13xxx_spi_probe(struct spi_device *spi) dev_set_drvdata(&spi->dev, mc13xxx); spi->mode = SPI_MODE_0 | SPI_CS_HIGH; + spi->bits_per_word = 32; mc13xxx->dev = &spi->dev; mutex_init(&mc13xxx->lock); - mc13xxx->regmap = regmap_init(&spi->dev, ®map_mc13xxx_bus, &spi->dev, - &mc13xxx_regmap_spi_config); - + mc13xxx->regmap = regmap_init_spi(spi, &mc13xxx_regmap_spi_config); if (IS_ERR(mc13xxx->regmap)) { ret = PTR_ERR(mc13xxx->regmap); dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", diff --git a/trunk/drivers/mfd/omap-usb-host.c b/trunk/drivers/mfd/omap-usb-host.c index 41088ecbb2a9..7e96bb229724 100644 --- a/trunk/drivers/mfd/omap-usb-host.c +++ b/trunk/drivers/mfd/omap-usb-host.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -501,21 +500,8 @@ static void omap_usbhs_init(struct device *dev) dev_dbg(dev, "starting TI HSUSB Controller\n"); pm_runtime_get_sync(dev); - - if (pdata->ehci_data->phy_reset) { - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_request_one(pdata->ehci_data->reset_gpio_port[0], - GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_request_one(pdata->ehci_data->reset_gpio_port[1], - GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); - } - spin_lock_irqsave(&omap->lock, flags); + omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -595,39 +581,9 @@ static void omap_usbhs_init(struct device *dev) } spin_unlock_irqrestore(&omap->lock, flags); - - if (pdata->ehci_data->phy_reset) { - /* Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_set_value_cansleep - (pdata->ehci_data->reset_gpio_port[0], 1); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_set_value_cansleep - (pdata->ehci_data->reset_gpio_port[1], 1); - } - pm_runtime_put_sync(dev); } -static void omap_usbhs_deinit(struct device *dev) -{ - struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); - struct usbhs_omap_platform_data *pdata = &omap->platdata; - - if (pdata->ehci_data->phy_reset) { - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_free(pdata->ehci_data->reset_gpio_port[0]); - - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_free(pdata->ehci_data->reset_gpio_port[1]); - } -} - /** * usbhs_omap_probe - initialize TI-based HCDs @@ -811,7 +767,6 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev) goto end_probe; err_alloc: - omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); err_tll: @@ -863,7 +818,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) { struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); - omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); iounmap(omap->uhh_base); clk_put(omap->init_60m_fclk); diff --git a/trunk/drivers/mfd/palmas.c b/trunk/drivers/mfd/palmas.c index c4a69f193a1d..00c0aba7eba0 100644 --- a/trunk/drivers/mfd/palmas.c +++ b/trunk/drivers/mfd/palmas.c @@ -356,14 +356,7 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, } } - /* Change IRQ into clear on read mode for efficiency */ - slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); - addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); - reg = PALMAS_INT_CTRL_INT_CLEAR; - - regmap_write(palmas->regmap[slave], addr, reg); - - ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, + ret = regmap_add_irq_chip(palmas->regmap[1], palmas->irq, IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) @@ -448,9 +441,6 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, goto err; } - children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; - children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); - ret = mfd_add_devices(palmas->dev, -1, children, ARRAY_SIZE(palmas_children), NULL, regmap_irq_chip_get_base(palmas->irq_data)); @@ -482,7 +472,6 @@ static const struct i2c_device_id palmas_i2c_id[] = { { "twl6035", }, { "twl6037", }, { "tps65913", }, - { /* end */ } }; MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); diff --git a/trunk/drivers/mfd/stmpe-i2c.c b/trunk/drivers/mfd/stmpe-i2c.c index 947a06a1845f..373f423b1181 100644 --- a/trunk/drivers/mfd/stmpe-i2c.c +++ b/trunk/drivers/mfd/stmpe-i2c.c @@ -6,7 +6,7 @@ * * License Terms: GNU General Public License, version 2 * Author: Rabin Vincent for ST-Ericsson - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include diff --git a/trunk/drivers/mfd/stmpe-spi.c b/trunk/drivers/mfd/stmpe-spi.c index 9edfe864cc05..afd459013ecb 100644 --- a/trunk/drivers/mfd/stmpe-spi.c +++ b/trunk/drivers/mfd/stmpe-spi.c @@ -4,7 +4,7 @@ * Copyright (C) ST Microelectronics SA 2011 * * License Terms: GNU General Public License, version 2 - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include @@ -146,4 +146,4 @@ module_exit(stmpe_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/trunk/drivers/mfd/tps65217.c b/trunk/drivers/mfd/tps65217.c index 61c097a98f5d..db194e433c08 100644 --- a/trunk/drivers/mfd/tps65217.c +++ b/trunk/drivers/mfd/tps65217.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -133,61 +132,6 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg, } EXPORT_SYMBOL_GPL(tps65217_clear_bits); -#ifdef CONFIG_OF -static struct of_regulator_match reg_matches[] = { - { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, - { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, - { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, - { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, - { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, - { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, - { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, -}; - -static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) -{ - struct device_node *node = client->dev.of_node; - struct tps65217_board *pdata; - struct device_node *regs; - int count = ARRAY_SIZE(reg_matches); - int ret, i; - - regs = of_find_node_by_name(node, "regulators"); - if (!regs) - return NULL; - - ret = of_regulator_match(&client->dev, regs, reg_matches, count); - of_node_put(regs); - if ((ret < 0) || (ret > count)) - return NULL; - - count = ret; - pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return NULL; - - for (i = 0; i < count; i++) { - if (!reg_matches[i].init_data || !reg_matches[i].of_node) - continue; - - pdata->tps65217_init_data[i] = reg_matches[i].init_data; - pdata->of_node[i] = reg_matches[i].of_node; - } - - return pdata; -} - -static struct of_device_id tps65217_of_match[] = { - { .compatible = "ti,tps65217", }, - { }, -}; -#else -static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) -{ - return NULL; -} -#endif - static struct regmap_config tps65217_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -197,14 +141,10 @@ static int __devinit tps65217_probe(struct i2c_client *client, const struct i2c_device_id *ids) { struct tps65217 *tps; - struct regulator_init_data *reg_data; struct tps65217_board *pdata = client->dev.platform_data; int i, ret; unsigned int version; - if (!pdata && client->dev.of_node) - pdata = tps65217_parse_dt(client); - tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); if (!tps) return -ENOMEM; @@ -242,9 +182,8 @@ static int __devinit tps65217_probe(struct i2c_client *client, } pdev->dev.parent = tps->dev; - pdev->dev.of_node = pdata->of_node[i]; - reg_data = pdata->tps65217_init_data[i]; - platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); + platform_device_add_data(pdev, &pdata->tps65217_init_data[i], + sizeof(pdata->tps65217_init_data[i])); tps->regulator_pdev[i] = pdev; platform_device_add(pdev); @@ -273,8 +212,6 @@ MODULE_DEVICE_TABLE(i2c, tps65217_id_table); static struct i2c_driver tps65217_driver = { .driver = { .name = "tps65217", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(tps65217_of_match), }, .id_table = tps65217_id_table, .probe = tps65217_probe, diff --git a/trunk/drivers/misc/mei/interrupt.c b/trunk/drivers/misc/mei/interrupt.c index 23f5463d4cae..93936f1b75eb 100644 --- a/trunk/drivers/misc/mei/interrupt.c +++ b/trunk/drivers/misc/mei/interrupt.c @@ -835,7 +835,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_io_list *cmpl_list) { - if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ list_del(&cb_pos->cb_list); diff --git a/trunk/drivers/misc/mei/main.c b/trunk/drivers/misc/mei/main.c index 783fcd7365bc..c70333228337 100644 --- a/trunk/drivers/misc/mei/main.c +++ b/trunk/drivers/misc/mei/main.c @@ -982,7 +982,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, err = request_threaded_irq(pdev->irq, NULL, mei_interrupt_thread_handler, - IRQF_ONESHOT, mei_driver_name, dev); + 0, mei_driver_name, dev); else err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, @@ -992,7 +992,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); - goto disable_msi; + goto unmap_memory; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { @@ -1023,8 +1023,8 @@ static int __devinit mei_probe(struct pci_dev *pdev, mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); -disable_msi: pci_disable_msi(pdev); +unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: kfree(dev); @@ -1101,8 +1101,6 @@ static void __devexit mei_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); - - misc_deregister(&mei_misc_device); } #ifdef CONFIG_PM static int mei_pci_suspend(struct device *device) @@ -1147,7 +1145,7 @@ static int mei_pci_resume(struct device *device) err = request_threaded_irq(pdev->irq, NULL, mei_interrupt_thread_handler, - IRQF_ONESHOT, mei_driver_name, dev); + 0, mei_driver_name, dev); else err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, @@ -1218,6 +1216,7 @@ module_init(mei_init_module); */ static void __exit mei_exit_module(void) { + misc_deregister(&mei_misc_device); pci_unregister_driver(&mei_driver); pr_debug("unloaded successfully.\n"); diff --git a/trunk/drivers/misc/mei/wd.c b/trunk/drivers/misc/mei/wd.c index e2ec0505eb5c..6be5605707b4 100644 --- a/trunk/drivers/misc/mei/wd.c +++ b/trunk/drivers/misc/mei/wd.c @@ -341,7 +341,7 @@ static const struct watchdog_ops wd_ops = { }; static const struct watchdog_info wd_info = { .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY, + .options = WDIOF_KEEPALIVEPING, }; static struct watchdog_device amt_wd_dev = { diff --git a/trunk/drivers/misc/sgi-xp/xpc_uv.c b/trunk/drivers/misc/sgi-xp/xpc_uv.c index 87b251ab6ec5..17bbacb1b4b1 100644 --- a/trunk/drivers/misc/sgi-xp/xpc_uv.c +++ b/trunk/drivers/misc/sgi-xp/xpc_uv.c @@ -452,9 +452,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, if (msg->activate_gru_mq_desc_gpa != part_uv->activate_gru_mq_desc_gpa) { - spin_lock(&part_uv->flags_lock); + spin_lock_irqsave(&part_uv->flags_lock, irq_flags); part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; - spin_unlock(&part_uv->flags_lock); + spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); part_uv->activate_gru_mq_desc_gpa = msg->activate_gru_mq_desc_gpa; } diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index 276d21ce6bc1..dd2d374dcc7a 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -554,6 +554,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) struct mmc_request mrq = {NULL}; struct mmc_command cmd = {0}; struct mmc_data data = {0}; + unsigned int timeout_us; struct scatterlist sg; @@ -573,12 +574,23 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + data.timeout_ns = card->csd.tacc_ns * 100; + data.timeout_clks = card->csd.tacc_clks * 100; + + timeout_us = data.timeout_ns / 1000; + timeout_us += data.timeout_clks * 1000 / + (card->host->ios.clock / 1000); + + if (timeout_us > 100000) { + data.timeout_ns = 100000000; + data.timeout_clks = 0; + } + data.blksz = 4; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; data.sg_len = 1; - mmc_set_data_timeout(&data, card); mrq.cmd = &cmd; mrq.data = &data; diff --git a/trunk/drivers/mmc/core/cd-gpio.c b/trunk/drivers/mmc/core/cd-gpio.c index 8f5dc08d6598..f13e38deceac 100644 --- a/trunk/drivers/mmc/core/cd-gpio.c +++ b/trunk/drivers/mmc/core/cd-gpio.c @@ -50,8 +50,8 @@ int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio) goto egpioreq; ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_ONESHOT, cd->label, host); + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + cd->label, host); if (ret < 0) goto eirqreq; diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c index 4f4489aa6bae..2d4a4b746750 100644 --- a/trunk/drivers/mmc/core/mmc.c +++ b/trunk/drivers/mmc/core/mmc.c @@ -717,6 +717,10 @@ static int mmc_select_powerclass(struct mmc_card *card, card->ext_csd.generic_cmd6_time); } + if (err) + pr_err("%s: power class selection for ext_csd_bus_width %d" + " failed\n", mmc_hostname(card->host), bus_width); + return err; } @@ -1100,9 +1104,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); if (err) - pr_warning("%s: power class selection to bus width %d" - " failed\n", mmc_hostname(card->host), - 1 << bus_width); + goto err; } /* @@ -1134,10 +1136,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_powerclass(card, ext_csd_bits[idx][0], ext_csd); if (err) - pr_warning("%s: power class selection to " - "bus width %d failed\n", - mmc_hostname(card->host), - 1 << bus_width); + goto err; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, @@ -1165,10 +1164,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_powerclass(card, ext_csd_bits[idx][1], ext_csd); if (err) - pr_warning("%s: power class selection to " - "bus width %d ddr %d failed\n", - mmc_hostname(card->host), - 1 << bus_width, ddr); + goto err; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, @@ -1330,7 +1326,7 @@ static int mmc_suspend(struct mmc_host *host) if (!err) mmc_card_set_sleep(host->card); } else if (!mmc_host_is_spi(host)) - err = mmc_deselect_cards(host); + mmc_deselect_cards(host); host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); mmc_release_host(host); diff --git a/trunk/drivers/mmc/core/sd.c b/trunk/drivers/mmc/core/sd.c index b2b43f624b9e..c272c6868ecf 100644 --- a/trunk/drivers/mmc/core/sd.c +++ b/trunk/drivers/mmc/core/sd.c @@ -1075,18 +1075,16 @@ static void mmc_sd_detect(struct mmc_host *host) */ static int mmc_sd_suspend(struct mmc_host *host) { - int err = 0; - BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (!mmc_host_is_spi(host)) - err = mmc_deselect_cards(host); + mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - return err; + return 0; } /* diff --git a/trunk/drivers/mmc/core/sdio.c b/trunk/drivers/mmc/core/sdio.c index 41c5fd8848f4..13d0e95380ab 100644 --- a/trunk/drivers/mmc/core/sdio.c +++ b/trunk/drivers/mmc/core/sdio.c @@ -218,12 +218,6 @@ static int sdio_enable_wide(struct mmc_card *card) if (ret) return ret; - if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) - pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", - mmc_hostname(card->host), ctrl); - - /* set as 4-bit bus width */ - ctrl &= ~SDIO_BUS_WIDTH_MASK; ctrl |= SDIO_BUS_WIDTH_4BIT; ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); diff --git a/trunk/drivers/mmc/host/atmel-mci-regs.h b/trunk/drivers/mmc/host/atmel-mci-regs.h index ab56f7db5315..787aba1682bb 100644 --- a/trunk/drivers/mmc/host/atmel-mci-regs.h +++ b/trunk/drivers/mmc/host/atmel-mci-regs.h @@ -140,18 +140,4 @@ #define atmci_writel(port,reg,value) \ __raw_writel((value), (port)->regs + reg) -/* - * Fix sconfig's burst size according to atmel MCI. We need to convert them as: - * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. - * - * This can be done by finding most significant bit set. - */ -static inline unsigned int atmci_convert_chksize(unsigned int maxburst) -{ - if (maxburst > 1) - return fls(maxburst) - 2; - else - return 0; -} - #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/trunk/drivers/mmc/host/atmel-mci.c b/trunk/drivers/mmc/host/atmel-mci.c index f2c115e06438..420aca642b14 100644 --- a/trunk/drivers/mmc/host/atmel-mci.c +++ b/trunk/drivers/mmc/host/atmel-mci.c @@ -910,7 +910,6 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) enum dma_data_direction direction; enum dma_transfer_direction slave_dirn; unsigned int sglen; - u32 maxburst; u32 iflags; data->error = -EINPROGRESS; @@ -944,18 +943,17 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) if (!chan) return -ENODEV; + if (host->caps.has_dma) + atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN); + if (data->flags & MMC_DATA_READ) { direction = DMA_FROM_DEVICE; host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM; - maxburst = atmci_convert_chksize(host->dma_conf.src_maxburst); } else { direction = DMA_TO_DEVICE; host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV; - maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst); } - atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN); - sglen = dma_map_sg(chan->device->dev, data->sg, data->sg_len, direction); @@ -2316,8 +2314,6 @@ static int __init atmci_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); - setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); - /* We need at least one slot to succeed */ nr_slots = 0; ret = -ENODEV; @@ -2356,6 +2352,8 @@ static int __init atmci_probe(struct platform_device *pdev) } } + setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); + dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", host->mapbase, irq, nr_slots); diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index 1ca5e72ceb65..9bbf45f8c538 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -418,8 +418,6 @@ static int dw_mci_idmac_init(struct dw_mci *host) p->des3 = host->sg_dma; p->des0 = IDMAC_DES0_ER; - mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET); - /* Mask out interrupts - get Tx & Rx complete only */ mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); @@ -617,15 +615,14 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) u32 div; if (slot->clock != host->current_speed) { - div = host->bus_hz / slot->clock; - if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) + if (host->bus_hz % slot->clock) /* * move the + 1 after the divide to prevent * over-clocking the card. */ - div += 1; - - div = (host->bus_hz != slot->clock) ? DIV_ROUND_UP(div, 2) : 0; + div = ((host->bus_hz / slot->clock) >> 1) + 1; + else + div = (host->bus_hz / slot->clock) >> 1; dev_info(&slot->mmc->class_dev, "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" @@ -942,8 +939,8 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd mdelay(20); if (cmd->data) { - dw_mci_stop_dma(host); host->data = NULL; + dw_mci_stop_dma(host); } } } @@ -1626,6 +1623,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); + set_bit(EVENT_DATA_COMPLETE, &host->pending_events); host->dma_ops->complete(host); } #endif @@ -1727,8 +1725,7 @@ static void dw_mci_work_routine_card(struct work_struct *work) #ifdef CONFIG_MMC_DW_IDMAC ctrl = mci_readl(host, BMOD); - /* Software reset of DMA */ - ctrl |= SDMMC_IDMAC_SWRESET; + ctrl |= 0x01; /* Software reset of DMA */ mci_writel(host, BMOD, ctrl); #endif @@ -1953,6 +1950,10 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); + + host->dma_ops = host->pdata->dma_ops; + dw_mci_init_dma(host); + /* * Get the host data width - this assumes that HCON has been set with * the correct values. @@ -1980,11 +1981,10 @@ int dw_mci_probe(struct dw_mci *host) } /* Reset all blocks */ - if (!mci_wait_reset(&host->dev, host)) - return -ENODEV; - - host->dma_ops = host->pdata->dma_ops; - dw_mci_init_dma(host); + if (!mci_wait_reset(&host->dev, host)) { + ret = -ENODEV; + goto err_dmaunmap; + } /* Clear the interrupts for the host controller */ mci_writel(host, RINTSTS, 0xFFFFFFFF); @@ -2170,14 +2170,14 @@ int dw_mci_resume(struct dw_mci *host) if (host->vmmc) regulator_enable(host->vmmc); + if (host->dma_ops->init) + host->dma_ops->init(host); + if (!mci_wait_reset(&host->dev, host)) { ret = -ENODEV; return ret; } - if (host->dma_ops->init) - host->dma_ops->init(host); - /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host->fifoth_val); diff --git a/trunk/drivers/mmc/host/mmci.c b/trunk/drivers/mmc/host/mmci.c index 50ff19a62368..f0fcce40cd8d 100644 --- a/trunk/drivers/mmc/host/mmci.c +++ b/trunk/drivers/mmc/host/mmci.c @@ -1216,7 +1216,12 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np, int bus_width = 0; pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); + if (!pdata->gpio_wp) + pdata->gpio_wp = -1; + pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0); + if (!pdata->gpio_cd) + pdata->gpio_cd = -1; if (of_get_property(np, "cd-inverted", NULL)) pdata->cd_invert = true; @@ -1271,12 +1276,6 @@ static int __devinit mmci_probe(struct amba_device *dev, return -EINVAL; } - if (!plat) { - plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); - if (!plat) - return -ENOMEM; - } - if (np) mmci_dt_populate_generic_pdata(np, plat); @@ -1425,10 +1424,6 @@ static int __devinit mmci_probe(struct amba_device *dev, writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); - if (plat->gpio_cd == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto err_gpio_cd; - } if (gpio_is_valid(plat->gpio_cd)) { ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); if (ret == 0) @@ -1452,10 +1447,6 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret >= 0) host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); } - if (plat->gpio_wp == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto err_gpio_wp; - } if (gpio_is_valid(plat->gpio_wp)) { ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); if (ret == 0) diff --git a/trunk/drivers/mmc/host/mxs-mmc.c b/trunk/drivers/mmc/host/mxs-mmc.c index 277161d279b8..34a90266ab11 100644 --- a/trunk/drivers/mmc/host/mxs-mmc.c +++ b/trunk/drivers/mmc/host/mxs-mmc.c @@ -894,8 +894,8 @@ static struct platform_driver mxs_mmc_driver = { .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &mxs_mmc_pm_ops, -#endif .of_match_table = mxs_mmc_dt_ids, +#endif }, }; diff --git a/trunk/drivers/mmc/host/omap.c b/trunk/drivers/mmc/host/omap.c index 3e8dcf8d2e05..552196c764d4 100644 --- a/trunk/drivers/mmc/host/omap.c +++ b/trunk/drivers/mmc/host/omap.c @@ -1300,7 +1300,7 @@ static const struct mmc_host_ops mmc_omap_ops = { .set_ios = mmc_omap_set_ios, }; -static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id) +static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) { struct mmc_omap_slot *slot = NULL; struct mmc_host *mmc; @@ -1485,26 +1485,24 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; - host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); - - host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); - if (!host->mmc_omap_wq) - goto err_plat_cleanup; - for (i = 0; i < pdata->nr_slots; i++) { ret = mmc_omap_new_slot(host, i); if (ret < 0) { while (--i >= 0) mmc_omap_remove_slot(host->slots[i]); - goto err_destroy_wq; + goto err_plat_cleanup; } } + host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); + + host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); + if (!host->mmc_omap_wq) + goto err_plat_cleanup; + return 0; -err_destroy_wq: - destroy_workqueue(host->mmc_omap_wq); err_plat_cleanup: if (pdata->cleanup) pdata->cleanup(&pdev->dev); diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index 389a3eedfc24..9a7a60aeb19e 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -85,6 +85,7 @@ #define BRR_ENABLE (1 << 5) #define DTO_ENABLE (1 << 20) #define INIT_STREAM (1 << 1) +#define ACEN_ACMD12 (1 << 2) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) #define DMA_EN 0x1 @@ -116,6 +117,7 @@ #define OMAP_MMC_MAX_CLOCK 52000000 #define DRIVER_NAME "omap_hsmmc" +#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -175,6 +177,7 @@ struct omap_hsmmc_host { int reqs_blocked; int use_reg; int req_in_progress; + unsigned int flags; struct omap_hsmmc_next next_data; struct omap_mmc_platform_data *pdata; @@ -770,6 +773,8 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); + if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode)) + cmdreg |= ACEN_ACMD12; if (data) { cmdreg |= DP_SELECT | MSBS | BCE; @@ -842,11 +847,14 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) else data->bytes_xfered = 0; - if (!data->stop) { + if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error)) { + omap_hsmmc_start_command(host, data->stop, NULL); + } else { + if (data->stop) + data->stop->resp[0] = OMAP_HSMMC_READ(host->base, + RSP76); omap_hsmmc_request_done(host, data->mrq); - return; } - omap_hsmmc_start_command(host, data->stop, NULL); } /* @@ -1851,6 +1859,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->mapbase = res->start + pdata->reg_offset; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; + host->flags = AUTO_CMD12; host->next_data.cookie = 1; platform_set_drvdata(pdev, host); diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c index a50c205ea208..55a164fcaa15 100644 --- a/trunk/drivers/mmc/host/sdhci-s3c.c +++ b/trunk/drivers/mmc/host/sdhci-s3c.c @@ -404,7 +404,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) if (sc->ext_cd_irq && request_threaded_irq(sc->ext_cd_irq, NULL, sdhci_s3c_gpio_card_detect_thread, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, dev_name(dev), sc) == 0) { int status = gpio_get_value(sc->ext_cd_gpio); if (pdata->ext_cd_gpio_invert) diff --git a/trunk/drivers/mmc/host/sdhci-spear.c b/trunk/drivers/mmc/host/sdhci-spear.c index 423da8194cd8..1fe32dfa7cd4 100644 --- a/trunk/drivers/mmc/host/sdhci-spear.c +++ b/trunk/drivers/mmc/host/sdhci-spear.c @@ -4,7 +4,7 @@ * Support of SDHCI platform devices for spear soc family * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired by sdhci-pltfm.c * @@ -289,5 +289,5 @@ static struct platform_driver sdhci_driver = { module_platform_driver(sdhci_driver); MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index f4b8b4db3a9a..e626732aff77 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -680,8 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) } if (count >= 0xF) { - DBG("%s: Too large timeout 0x%x requested for CMD%d!\n", - mmc_hostname(host->mmc), count, cmd->opcode); + pr_warning("%s: Too large timeout 0x%x requested for CMD%d!\n", + mmc_hostname(host->mmc), count, cmd->opcode); count = 0xE; } diff --git a/trunk/drivers/mtd/mtdoops.c b/trunk/drivers/mtd/mtdoops.c index 551e316e4454..ae36d7e1e913 100644 --- a/trunk/drivers/mtd/mtdoops.c +++ b/trunk/drivers/mtd/mtdoops.c @@ -304,17 +304,32 @@ static void find_next_position(struct mtdoops_context *cxt) } static void mtdoops_do_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason) + enum kmsg_dump_reason reason, const char *s1, unsigned long l1, + const char *s2, unsigned long l2) { struct mtdoops_context *cxt = container_of(dumper, struct mtdoops_context, dump); + unsigned long s1_start, s2_start; + unsigned long l1_cpy, l2_cpy; + char *dst; + + if (reason != KMSG_DUMP_OOPS && + reason != KMSG_DUMP_PANIC) + return; /* Only dump oopses if dump_oops is set */ if (reason == KMSG_DUMP_OOPS && !dump_oops) return; - kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, - record_size - MTDOOPS_HEADER_SIZE, NULL); + dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ + l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); + l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); + + s2_start = l2 - l2_cpy; + s1_start = l1 - l1_cpy; + + memcpy(dst, s1 + s1_start, l1_cpy); + memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); /* Panics must be written immediately */ if (reason != KMSG_DUMP_OOPS) @@ -360,7 +375,6 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } - cxt->dump.max_reason = KMSG_DUMP_OOPS; cxt->dump.dump = mtdoops_do_dump; err = kmsg_dump_register(&cxt->dump); if (err) { diff --git a/trunk/drivers/mtd/nand/cafe_nand.c b/trunk/drivers/mtd/nand/cafe_nand.c index f3f6cfedd69e..41371ba1a811 100644 --- a/trunk/drivers/mtd/nand/cafe_nand.c +++ b/trunk/drivers/mtd/nand/cafe_nand.c @@ -102,7 +102,7 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { struct cafe_priv *cafe = mtd->priv; - int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); + int result = !!(cafe_readl(cafe, NAND_STATUS) | 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs, NAND_IRQ); diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index a6cad5caba78..a05b7b444d4f 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -920,12 +920,12 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, */ memset(chip->oob_poi, ~0, mtd->oobsize); chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; - } - read_page_swap_end(this, buf, mtd->writesize, - this->payload_virt, this->payload_phys, - nfc_geo->payload_size, - payload_virt, payload_phys); + read_page_swap_end(this, buf, mtd->writesize, + this->payload_virt, this->payload_phys, + nfc_geo->payload_size, + payload_virt, payload_phys); + } exit_nfc: return ret; } diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index 6acc790c2fbb..c58e6a93f445 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -273,26 +273,6 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = { static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; -static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) -{ - int i; - u32 *t = trg; - const __iomem u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - *t++ = __raw_readl(s++); -} - -static void memcpy32_toio(void __iomem *trg, const void *src, int size) -{ - int i; - u32 __iomem *t = trg; - const u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - __raw_writel(*s++, t++); -} - static int check_int_v3(struct mxc_nand_host *host) { uint32_t tmp; @@ -539,7 +519,7 @@ static void send_read_id_v3(struct mxc_nand_host *host) wait_op_done(host, true); - memcpy32_fromio(host->data_buf, host->main_area0, 16); + memcpy_fromio(host->data_buf, host->main_area0, 16); } /* Request the NANDFC to perform a read of the NAND device ID. */ @@ -555,7 +535,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) /* Wait for operation to complete */ wait_op_done(host, true); - memcpy32_fromio(host->data_buf, host->main_area0, 16); + memcpy_fromio(host->data_buf, host->main_area0, 16); if (this->options & NAND_BUSWIDTH_16) { /* compress the ID info */ @@ -817,16 +797,16 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) if (bfrom) { for (i = 0; i < n - 1; i++) - memcpy32_fromio(d + i * j, s + i * t, j); + memcpy_fromio(d + i * j, s + i * t, j); /* the last section */ - memcpy32_fromio(d + i * j, s + i * t, mtd->oobsize - i * j); + memcpy_fromio(d + i * j, s + i * t, mtd->oobsize - i * j); } else { for (i = 0; i < n - 1; i++) - memcpy32_toio(&s[i * t], &d[i * j], j); + memcpy_toio(&s[i * t], &d[i * j], j); /* the last section */ - memcpy32_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j); + memcpy_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j); } } @@ -1090,8 +1070,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, host->devtype_data->send_page(mtd, NFC_OUTPUT); - memcpy32_fromio(host->data_buf, host->main_area0, - mtd->writesize); + memcpy_fromio(host->data_buf, host->main_area0, mtd->writesize); copy_spare(mtd, true); break; @@ -1107,7 +1086,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_PAGEPROG: - memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); + memcpy_toio(host->main_area0, host->data_buf, mtd->writesize); copy_spare(mtd, false); host->devtype_data->send_page(mtd, NFC_INPUT); host->devtype_data->send_cmd(host, command, true); diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index a11253a0fcab..d47586cf64ce 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -3501,13 +3501,6 @@ int nand_scan_tail(struct mtd_info *mtd) /* propagate ecc info to mtd_info */ mtd->ecclayout = chip->ecc.layout; mtd->ecc_strength = chip->ecc.strength; - /* - * Initialize bitflip_threshold to its default prior scan_bbt() call. - * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be - * properly set. - */ - if (!mtd->bitflip_threshold) - mtd->bitflip_threshold = mtd->ecc_strength; /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) diff --git a/trunk/drivers/mtd/nand/nandsim.c b/trunk/drivers/mtd/nand/nandsim.c index cf0cd3146817..6cc8fbfabb8e 100644 --- a/trunk/drivers/mtd/nand/nandsim.c +++ b/trunk/drivers/mtd/nand/nandsim.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -546,6 +546,12 @@ static char *get_partition_name(int i) return kstrdup(buf, GFP_KERNEL); } +static uint64_t divide(uint64_t n, uint32_t d) +{ + do_div(n, d); + return n; +} + /* * Initialize the nandsim structure. * @@ -574,7 +580,7 @@ static int init_nandsim(struct mtd_info *mtd) ns->geom.oobsz = mtd->oobsize; ns->geom.secsz = mtd->erasesize; ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; - ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); + ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; ns->geom.secshift = ffs(ns->geom.secsz) - 1; ns->geom.pgshift = chip->page_shift; @@ -915,7 +921,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) if (!rptwear) return 0; - wear_eb_count = div_u64(mtd->size, mtd->erasesize); + wear_eb_count = divide(mtd->size, mtd->erasesize); mem = wear_eb_count * sizeof(unsigned long); if (mem / sizeof(unsigned long) != wear_eb_count) { NS_ERR("Too many erase blocks for wear reporting\n"); diff --git a/trunk/drivers/mtd/ubi/debug.c b/trunk/drivers/mtd/ubi/debug.c index 7c1380305219..9f957c2d48e9 100644 --- a/trunk/drivers/mtd/ubi/debug.c +++ b/trunk/drivers/mtd/ubi/debug.c @@ -264,9 +264,6 @@ static struct dentry *dfs_rootdir; */ int ubi_debugfs_init(void) { - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; - dfs_rootdir = debugfs_create_dir("ubi", NULL); if (IS_ERR_OR_NULL(dfs_rootdir)) { int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); @@ -284,8 +281,7 @@ int ubi_debugfs_init(void) */ void ubi_debugfs_exit(void) { - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove(dfs_rootdir); + debugfs_remove(dfs_rootdir); } /* Read an UBI debugfs file */ @@ -407,9 +403,6 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) struct dentry *dent; struct ubi_debug_info *d = ubi->dbg; - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; - n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, ubi->ubi_num); if (n == UBI_DFS_DIR_LEN) { @@ -477,6 +470,5 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) */ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(ubi->dbg->dfs_dir); + debugfs_remove_recursive(ubi->dbg->dfs_dir); } diff --git a/trunk/drivers/mtd/ubi/wl.c b/trunk/drivers/mtd/ubi/wl.c index b6be644e7b85..9df100a4ec38 100644 --- a/trunk/drivers/mtd/ubi/wl.c +++ b/trunk/drivers/mtd/ubi/wl.c @@ -1262,11 +1262,11 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) dbg_wl("flush pending work for LEB %d:%d (%d pending works)", vol_id, lnum, ubi->works_count); + down_write(&ubi->work_sem); while (found) { struct ubi_work *wrk; found = 0; - down_read(&ubi->work_sem); spin_lock(&ubi->wl_lock); list_for_each_entry(wrk, &ubi->works, list) { if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && @@ -1277,27 +1277,18 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) spin_unlock(&ubi->wl_lock); err = wrk->func(ubi, wrk, 0); - if (err) { - up_read(&ubi->work_sem); - return err; - } - + if (err) + goto out; spin_lock(&ubi->wl_lock); found = 1; break; } } spin_unlock(&ubi->wl_lock); - up_read(&ubi->work_sem); } - /* - * Make sure all the works which have been done in parallel are - * finished. - */ - down_write(&ubi->work_sem); +out: up_write(&ubi->work_sem); - return err; } diff --git a/trunk/drivers/net/bonding/bond_debugfs.c b/trunk/drivers/net/bonding/bond_debugfs.c index 2cf084eb9d52..3680aa251dea 100644 --- a/trunk/drivers/net/bonding/bond_debugfs.c +++ b/trunk/drivers/net/bonding/bond_debugfs.c @@ -6,7 +6,7 @@ #include "bonding.h" #include "bond_alb.h" -#if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_NET_NS) +#ifdef CONFIG_DEBUG_FS #include #include diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 2ee76993f052..2ee8cf9e8a3b 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -76,7 +76,6 @@ #include #include #include -#include #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" @@ -382,6 +381,8 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) return next; } +#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb)) + /** * bond_dev_queue_xmit - Prepare skb for xmit. * @@ -394,9 +395,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, { skb->dev = slave_dev; - BUILD_BUG_ON(sizeof(skb->queue_mapping) != - sizeof(qdisc_skb_cb(skb)->bond_queue_mapping)); - skb->queue_mapping = qdisc_skb_cb(skb)->bond_queue_mapping; + skb->queue_mapping = bond_queue_mapping(skb); if (unlikely(netpoll_tx_running(slave_dev))) bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); @@ -3227,12 +3226,6 @@ static int bond_master_netdev_event(unsigned long event, switch (event) { case NETDEV_CHANGENAME: return bond_event_changename(event_bond); - case NETDEV_UNREGISTER: - bond_remove_proc_entry(event_bond); - break; - case NETDEV_REGISTER: - bond_create_proc_entry(event_bond); - break; default: break; } @@ -4178,7 +4171,7 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) /* * Save the original txq to restore before passing to the driver */ - qdisc_skb_cb(skb)->bond_queue_mapping = skb->queue_mapping; + bond_queue_mapping(skb) = skb->queue_mapping; if (unlikely(txq >= dev->real_num_tx_queues)) { do { @@ -4417,6 +4410,8 @@ static void bond_uninit(struct net_device *bond_dev) bond_work_cancel_all(bond); + bond_remove_proc_entry(bond); + bond_debug_unregister(bond); __hw_addr_flush(&bond->mc_list); @@ -4818,6 +4813,7 @@ static int bond_init(struct net_device *bond_dev) bond_set_lockdep_class(bond_dev); + bond_create_proc_entry(bond); list_add_tail(&bond->bond_list, &bn->dev_list); bond_prepare_sysfs_group(bond); diff --git a/trunk/drivers/net/bonding/bond_procfs.c b/trunk/drivers/net/bonding/bond_procfs.c index 3cea38d37344..ad284baafe87 100644 --- a/trunk/drivers/net/bonding/bond_procfs.c +++ b/trunk/drivers/net/bonding/bond_procfs.c @@ -150,25 +150,14 @@ static void bond_info_show_master(struct seq_file *seq) } } -static const char *bond_slave_link_status(s8 link) -{ - static const char * const status[] = { - [BOND_LINK_UP] = "up", - [BOND_LINK_FAIL] = "going down", - [BOND_LINK_DOWN] = "down", - [BOND_LINK_BACK] = "going back", - }; - - return status[link]; -} - static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave) { struct bonding *bond = seq->private; seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); - seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link)); + seq_printf(seq, "MII Status: %s\n", + (slave->link == BOND_LINK_UP) ? "up" : "down"); if (slave->speed == SPEED_UNKNOWN) seq_printf(seq, "Speed: %s\n", "Unknown"); else diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 485bedb8278c..aef42f045320 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -1082,12 +1082,8 @@ static ssize_t bonding_store_primary(struct device *d, } } - strncpy(bond->params.primary, ifname, IFNAMSIZ); - bond->params.primary[IFNAMSIZ - 1] = 0; - - pr_info("%s: Recording %s as primary, " - "but it has not been enslaved to %s yet.\n", - bond->dev->name, ifname, bond->dev->name); + pr_info("%s: Unable to set %.*s as primary slave.\n", + bond->dev->name, (int)strlen(buf) - 1, buf); out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); diff --git a/trunk/drivers/net/caif/caif_hsi.c b/trunk/drivers/net/caif/caif_hsi.c index 4a27adb7ae67..1520814c77c7 100644 --- a/trunk/drivers/net/caif/caif_hsi.c +++ b/trunk/drivers/net/caif/caif_hsi.c @@ -693,6 +693,8 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) */ memcpy(rx_buf, (u8 *)piggy_desc, CFHSI_DESC_SHORT_SZ); + /* Mark no embedded frame here */ + piggy_desc->offset = 0; if (desc_pld_len == -EPROTO) goto out_of_sync; } @@ -735,8 +737,6 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) /* Extract any payload in piggyback descriptor. */ if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0) goto out_of_sync; - /* Mark no embedded frame after extracting it */ - piggy_desc->offset = 0; } } @@ -1178,7 +1178,6 @@ int cfhsi_probe(struct platform_device *pdev) dev_err(&ndev->dev, "%s: Registration error: %d.\n", __func__, res); free_netdev(ndev); - return -ENODEV; } /* Add CAIF HSI device to list. */ spin_lock(&cfhsi_list_lock); diff --git a/trunk/drivers/net/can/c_can/c_can.c b/trunk/drivers/net/can/c_can/c_can.c index 86cd532c78f9..536bda072a16 100644 --- a/trunk/drivers/net/can/c_can/c_can.c +++ b/trunk/drivers/net/can/c_can/c_can.c @@ -590,8 +590,8 @@ static void c_can_chip_config(struct net_device *dev) priv->write_reg(priv, &priv->regs->control, CONTROL_ENABLE_AR); - if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && - (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { + if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & + CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); @@ -686,7 +686,7 @@ static int c_can_get_berr_counter(const struct net_device *dev, * * We iterate from priv->tx_echo to priv->tx_next and check if the * packet has been transmitted, echo it back to the CAN framework. - * If we discover a not yet transmitted packet, stop looking for more. + * If we discover a not yet transmitted package, stop looking for more. */ static void c_can_do_tx(struct net_device *dev) { @@ -698,7 +698,7 @@ static void c_can_do_tx(struct net_device *dev) for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); val = c_can_read_reg32(priv, &priv->regs->txrqst1); - if (!(val & (1 << (msg_obj_no - 1)))) { + if (!(val & (1 << msg_obj_no))) { can_get_echo_skb(dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); stats->tx_bytes += priv->read_reg(priv, @@ -706,8 +706,6 @@ static void c_can_do_tx(struct net_device *dev) & IF_MCONT_DLC_MASK; stats->tx_packets++; c_can_inval_msg_object(dev, 0, msg_obj_no); - } else { - break; } } @@ -952,7 +950,7 @@ static int c_can_poll(struct napi_struct *napi, int quota) struct net_device *dev = napi->dev; struct c_can_priv *priv = netdev_priv(dev); - irqstatus = priv->irqstatus; + irqstatus = priv->read_reg(priv, &priv->regs->interrupt); if (!irqstatus) goto end; @@ -1030,11 +1028,12 @@ static int c_can_poll(struct napi_struct *napi, int quota) static irqreturn_t c_can_isr(int irq, void *dev_id) { + u16 irqstatus; struct net_device *dev = (struct net_device *)dev_id; struct c_can_priv *priv = netdev_priv(dev); - priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt); - if (!priv->irqstatus) + irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + if (!irqstatus) return IRQ_NONE; /* disable all interrupts and schedule the NAPI */ @@ -1064,11 +1063,10 @@ static int c_can_open(struct net_device *dev) goto exit_irq_fail; } - napi_enable(&priv->napi); - /* start the c_can controller */ c_can_start(dev); + napi_enable(&priv->napi); netif_start_queue(dev); return 0; diff --git a/trunk/drivers/net/can/c_can/c_can.h b/trunk/drivers/net/can/c_can/c_can.h index 5f32d34af507..9b7fbef3d09a 100644 --- a/trunk/drivers/net/can/c_can/c_can.h +++ b/trunk/drivers/net/can/c_can/c_can.h @@ -76,7 +76,6 @@ struct c_can_priv { unsigned int tx_next; unsigned int tx_echo; void *priv; /* for board-specific data */ - u16 irqstatus; }; struct net_device *alloc_c_can_dev(void); diff --git a/trunk/drivers/net/can/cc770/cc770_platform.c b/trunk/drivers/net/can/cc770/cc770_platform.c index 688371cda37a..53115eee8075 100644 --- a/trunk/drivers/net/can/cc770/cc770_platform.c +++ b/trunk/drivers/net/can/cc770/cc770_platform.c @@ -154,7 +154,7 @@ static int __devinit cc770_get_platform_data(struct platform_device *pdev, struct cc770_platform_data *pdata = pdev->dev.platform_data; priv->can.clock.freq = pdata->osc_freq; - if (priv->cpu_interface & CPUIF_DSC) + if (priv->cpu_interface | CPUIF_DSC) priv->can.clock.freq /= 2; priv->clkout = pdata->cor; priv->bus_config = pdata->bcr; diff --git a/trunk/drivers/net/can/flexcan.c b/trunk/drivers/net/can/flexcan.c index 81d474102378..38c0690df5c8 100644 --- a/trunk/drivers/net/can/flexcan.c +++ b/trunk/drivers/net/can/flexcan.c @@ -939,12 +939,12 @@ static int __devinit flexcan_probe(struct platform_device *pdev) return PTR_ERR(pinctrl); if (pdev->dev.of_node) { - const __be32 *clock_freq_p; + const u32 *clock_freq_p; clock_freq_p = of_get_property(pdev->dev.of_node, "clock-frequency", NULL); if (clock_freq_p) - clock_freq = be32_to_cpup(clock_freq_p); + clock_freq = *clock_freq_p; } if (!clock_freq) { diff --git a/trunk/drivers/net/dummy.c b/trunk/drivers/net/dummy.c index bab0158f1cc3..442d91a2747b 100644 --- a/trunk/drivers/net/dummy.c +++ b/trunk/drivers/net/dummy.c @@ -187,10 +187,8 @@ static int __init dummy_init_module(void) rtnl_lock(); err = __rtnl_link_register(&dummy_link_ops); - for (i = 0; i < numdummies && !err; i++) { + for (i = 0; i < numdummies && !err; i++) err = dummy_init_one(); - cond_resched(); - } if (err < 0) __rtnl_link_unregister(&dummy_link_ops); rtnl_unlock(); diff --git a/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 1f78b63d5efe..9cc15701101b 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -261,6 +261,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) if ((phy_data & BMSR_LSTATUS) == 0) { /* link down */ netif_carrier_off(netdev); + netif_stop_queue(netdev); hw->hibernate = true; if (atl1c_reset_mac(hw) != 0) if (netif_msg_hw(adapter)) diff --git a/trunk/drivers/net/ethernet/broadcom/b44.c b/trunk/drivers/net/ethernet/broadcom/b44.c index d09c6b583d17..46b8b7d81633 100644 --- a/trunk/drivers/net/ethernet/broadcom/b44.c +++ b/trunk/drivers/net/ethernet/broadcom/b44.c @@ -656,7 +656,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ, DMA_FROM_DEVICE); dev_kfree_skb_any(skb); - skb = alloc_skb(RX_PKT_BUF_SZ, GFP_ATOMIC | GFP_DMA); + skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); if (skb == NULL) return -ENOMEM; mapping = dma_map_single(bp->sdev->dma_dev, skb->data, @@ -967,7 +967,7 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev) dma_unmap_single(bp->sdev->dma_dev, mapping, len, DMA_TO_DEVICE); - bounce_skb = alloc_skb(len, GFP_ATOMIC | GFP_DMA); + bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) goto err_out; diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2.c b/trunk/drivers/net/ethernet/broadcom/bnx2.c index 1fa4927a45b1..ac7b74488531 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2.c @@ -5372,7 +5372,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp) int k, last; if (skb == NULL) { - j = NEXT_TX_BD(j); + j++; continue; } @@ -5384,8 +5384,8 @@ bnx2_free_tx_skbs(struct bnx2 *bp) tx_buf->skb = NULL; last = tx_buf->nr_frags; - j = NEXT_TX_BD(j); - for (k = 0; k < last; k++, j = NEXT_TX_BD(j)) { + j++; + for (k = 0; k < last; k++, j++) { tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)]; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping), diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 7de824184979..e30e2a2f354c 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -747,6 +747,21 @@ struct bnx2x_fastpath { #define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG +#define BNX2X_IP_CSUM_ERR(cqe) \ + (!((cqe)->fast_path_cqe.status_flags & \ + ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \ + ((cqe)->fast_path_cqe.type_error_flags & \ + ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG)) + +#define BNX2X_L4_CSUM_ERR(cqe) \ + (!((cqe)->fast_path_cqe.status_flags & \ + ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \ + ((cqe)->fast_path_cqe.type_error_flags & \ + ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) + +#define BNX2X_RX_CSUM_OK(cqe) \ + (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe))) + #define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \ (((le16_to_cpu(flags) & \ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \ diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 8098eea9704d..ad0743bf4bde 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -190,7 +190,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) if ((netif_tx_queue_stopped(txq)) && (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) netif_tx_wake_queue(txq); __netif_tx_unlock(txq); @@ -617,25 +617,6 @@ static int bnx2x_alloc_rx_data(struct bnx2x *bp, return 0; } -static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, - struct bnx2x_fastpath *fp) -{ - /* Do nothing if no IP/L4 csum validation was done */ - - if (cqe->fast_path_cqe.status_flags & - (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | - ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)) - return; - - /* If both IP/L4 validation were done, check if an error was found. */ - - if (cqe->fast_path_cqe.type_error_flags & - (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | - ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) - fp->eth_q_stats.hw_csum_err++; - else - skb->ip_summed = CHECKSUM_UNNECESSARY; -} int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) { @@ -825,9 +806,13 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb_checksum_none_assert(skb); - if (bp->dev->features & NETIF_F_RXCSUM) - bnx2x_csum_validate(skb, cqe, fp); + if (bp->dev->features & NETIF_F_RXCSUM) { + if (likely(BNX2X_RX_CSUM_OK(cqe))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + fp->eth_q_stats.hw_csum_err++; + } skb_record_rx_queue(skb, fp->rx_queue); @@ -2516,6 +2501,8 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs + * So far this has only been observed to happen + * in Other Operating Systems(TM) */ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, @@ -3169,7 +3156,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) txdata->tx_bd_prod += nbd; - if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { netif_tx_stop_queue(txq); /* paired memory barrier is in bnx2x_tx_int(), we have to keep @@ -3178,7 +3165,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_mb(); fp->eth_q_stats.driver_xoff++; - if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) netif_tx_wake_queue(txq); } txdata->tx_pkt++; diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 6e7d5c0843b4..a3fb7215cd89 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -40,7 +40,6 @@ #define I2C_BSC0 0 #define I2C_BSC1 1 #define I2C_WA_RETRY_CNT 3 -#define I2C_WA_PWR_ITER (I2C_WA_RETRY_CNT - 1) #define MCPR_IMC_COMMAND_READ_OP 1 #define MCPR_IMC_COMMAND_WRITE_OP 2 @@ -7660,28 +7659,6 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } -static void bnx2x_warpcore_power_module(struct link_params *params, - struct bnx2x_phy *phy, - u8 power) -{ - u32 pin_cfg; - struct bnx2x *bp = params->bp; - - pin_cfg = (REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & - PORT_HW_CFG_E3_PWR_DIS_MASK) >> - PORT_HW_CFG_E3_PWR_DIS_SHIFT; - - if (pin_cfg == PIN_CFG_NA) - return; - DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", - power, pin_cfg); - /* Low ==> corresponding SFP+ module is powered - * high ==> the SFP+ module is powered down - */ - bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); -} static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, @@ -7701,12 +7678,6 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { - if (cnt == I2C_WA_PWR_ITER) { - bnx2x_warpcore_power_module(params, phy, 0); - /* Note that 100us are not enough here */ - usleep_range(1000,1000); - bnx2x_warpcore_power_module(params, phy, 1); - } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, data_array); } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); @@ -8229,6 +8200,29 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, bnx2x_set_e1e2_module_fault_led(params, gpio_mode); } +static void bnx2x_warpcore_power_module(struct link_params *params, + struct bnx2x_phy *phy, + u8 power) +{ + u32 pin_cfg; + struct bnx2x *bp = params->bp; + + pin_cfg = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_PWR_DIS_MASK) >> + PORT_HW_CFG_E3_PWR_DIS_SHIFT; + + if (pin_cfg == PIN_CFG_NA) + return; + DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", + power, pin_cfg); + /* Low ==> corresponding SFP+ module is powered + * high ==> the SFP+ module is powered down + */ + bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); +} + static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { @@ -9754,7 +9748,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, msleep(1); - if (!(CHIP_IS_E1x(bp))) + if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); else port = params->port; diff --git a/trunk/drivers/net/ethernet/broadcom/cnic.c b/trunk/drivers/net/ethernet/broadcom/cnic.c index 2c89d17cbb29..c95e7b5e2b85 100644 --- a/trunk/drivers/net/ethernet/broadcom/cnic.c +++ b/trunk/drivers/net/ethernet/broadcom/cnic.c @@ -534,8 +534,7 @@ int cnic_unregister_driver(int ulp_type) } if (atomic_read(&ulp_ops->ref_count) != 0) - pr_warn("%s: Failed waiting for ref count to go to zero\n", - __func__); + netdev_warn(dev->netdev, "Failed waiting for ref count to go to zero\n"); return 0; out_unlock: @@ -1054,13 +1053,12 @@ static int cnic_init_uio(struct cnic_dev *dev) uinfo = &udev->cnic_uinfo; - uinfo->mem[0].addr = pci_resource_start(dev->pcidev, 0); + uinfo->mem[0].addr = dev->netdev->base_addr; uinfo->mem[0].internal_addr = dev->regview; + uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; uinfo->mem[0].memtype = UIO_MEM_PHYS; if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { - uinfo->mem[0].size = MB_GET_CID_ADDR(TX_TSS_CID + - TX_MAX_TSS_RINGS + 1); uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & PAGE_MASK; if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) @@ -1070,8 +1068,6 @@ static int cnic_init_uio(struct cnic_dev *dev) uinfo->name = "bnx2_cnic"; } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { - uinfo->mem[0].size = pci_resource_len(dev->pcidev, 0); - uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & PAGE_MASK; uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index e47ff8be1d7b..edeeb516807a 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -14275,8 +14275,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } } - if (tg3_flag(tp, 5755_PLUS) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + if (tg3_flag(tp, 5755_PLUS)) tg3_flag_set(tp, SHORT_DMA_BUG); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c index 921c2082af4c..8d06ea381741 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -122,15 +122,15 @@ static int be_mcc_compl_process(struct be_adapter *adapter, goto done; if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { - dev_warn(&adapter->pdev->dev, - "opcode %d-%d is not permitted\n", - opcode, subsystem); + dev_warn(&adapter->pdev->dev, "This domain(VM) is not " + "permitted to execute this cmd (opcode %d)\n", + opcode); } else { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & CQE_STATUS_EXTD_MASK; - dev_err(&adapter->pdev->dev, - "opcode %d-%d failed:status %d-%d\n", - opcode, subsystem, compl_status, extd_status); + dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:" + "status %d, extd-status %d\n", + opcode, compl_status, extd_status); } } done: diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h index b3f3fc3d1323..9625bf420c16 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1566,7 +1566,7 @@ struct be_hw_stats_v1 { u32 rsvd0[BE_TXP_SW_SZ]; struct be_erx_stats_v1 erx; struct be_pmem_stats pmem; - u32 rsvd1[18]; + u32 rsvd1[3]; }; struct be_cmd_req_get_stats_v1 { diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 501dfa9c88ec..08efd308d78a 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -736,8 +736,6 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb); if (copied) { - int gso_segs = skb_shinfo(skb)->gso_segs; - /* record the sent skb in the sent_skb table */ BUG_ON(txo->sent_skb_list[start]); txo->sent_skb_list[start] = skb; @@ -755,7 +753,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, be_txq_notify(adapter, txq->id, wrb_cnt); - be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped); + be_tx_stats_update(txo, wrb_cnt, copied, + skb_shinfo(skb)->gso_segs, stopped); } else { txq->head = start; dev_kfree_skb_any(skb); @@ -3237,7 +3236,7 @@ static void be_netdev_init(struct net_device *netdev) netdev->flags |= IFF_MULTICAST; - netif_set_gso_max_size(netdev, 65535 - ETH_HLEN); + netif_set_gso_max_size(netdev, 65535); netdev->netdev_ops = &be_netdev_ops; diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index ab1d80ff0791..0741aded9eb0 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -1804,16 +1804,18 @@ void gfar_configure_coalescing(struct gfar_private *priv, if (priv->mode == MQ_MG_MODE) { baddr = ®s->txic0; for_each_set_bit(i, &tx_mask, priv->num_tx_queues) { - gfar_write(baddr + i, 0); - if (likely(priv->tx_queue[i]->txcoalescing)) + if (likely(priv->tx_queue[i]->txcoalescing)) { + gfar_write(baddr + i, 0); gfar_write(baddr + i, priv->tx_queue[i]->txic); + } } baddr = ®s->rxic0; for_each_set_bit(i, &rx_mask, priv->num_rx_queues) { - gfar_write(baddr + i, 0); - if (likely(priv->rx_queue[i]->rxcoalescing)) + if (likely(priv->rx_queue[i]->rxcoalescing)) { + gfar_write(baddr + i, 0); gfar_write(baddr + i, priv->rx_queue[i]->rxic); + } } } } @@ -2063,9 +2065,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - if (skb->sk) - skb_set_owner_w(skb_new, skb->sk); - consume_skb(skb); + /* Steal sock reference for processing TX time stamps */ + swap(skb_new->sk, skb->sk); + swap(skb_new->destructor, skb->destructor); + kfree_skb(skb); skb = skb_new; } diff --git a/trunk/drivers/net/ethernet/intel/Kconfig b/trunk/drivers/net/ethernet/intel/Kconfig index 0cafe4fe9406..79b07ec6726f 100644 --- a/trunk/drivers/net/ethernet/intel/Kconfig +++ b/trunk/drivers/net/ethernet/intel/Kconfig @@ -122,10 +122,8 @@ config IGB_DCA config IGB_PTP bool "PTP Hardware Clock (PHC)" - default n - depends on IGB && EXPERIMENTAL - select PPS - select PTP_1588_CLOCK + default y + depends on IGB && PTP_1588_CLOCK ---help--- Say Y here if you want to use PTP Hardware Clock (PHC) in the driver. Only the basic clock operations have been implemented. @@ -225,9 +223,7 @@ config IXGBE_DCB config IXGBE_PTP bool "PTP Clock Support" default n - depends on IXGBE && EXPERIMENTAL - select PPS - select PTP_1588_CLOCK + depends on IXGBE && PTP_1588_CLOCK ---help--- Say Y here if you want support for 1588 Timestamping with a PHC device, using the PTP 1588 Clock support. This is diff --git a/trunk/drivers/net/ethernet/intel/e1000e/82571.c b/trunk/drivers/net/ethernet/intel/e1000e/82571.c index 1f063dcd8f85..36db4df09aed 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/82571.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/82571.c @@ -1572,9 +1572,6 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) ctrl = er32(CTRL); status = er32(STATUS); rxcw = er32(RXCW); - /* SYNCH bit and IV bit are sticky */ - udelay(10); - rxcw = er32(RXCW); if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { diff --git a/trunk/drivers/net/ethernet/intel/e1000e/defines.h b/trunk/drivers/net/ethernet/intel/e1000e/defines.h index 76edbc1be33b..351a4097b2ba 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/defines.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/defines.h @@ -103,7 +103,6 @@ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ #define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ #define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ -#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c index 905e2147d918..d863075df7a4 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -258,8 +258,7 @@ static int e1000_set_settings(struct net_device *netdev, * When SoL/IDER sessions are active, autoneg/speed/duplex * cannot be changed */ - if (hw->phy.ops.check_reset_block && - hw->phy.ops.check_reset_block(hw)) { + if (hw->phy.ops.check_reset_block(hw)) { e_err("Cannot change link characteristics when SoL/IDER is active.\n"); return -EINVAL; } @@ -1616,8 +1615,7 @@ static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data) * PHY loopback cannot be performed if SoL/IDER * sessions are active */ - if (hw->phy.ops.check_reset_block && - hw->phy.ops.check_reset_block(hw)) { + if (hw->phy.ops.check_reset_block(hw)) { e_err("Cannot do PHY loopback test when SoL/IDER is active.\n"); *data = 0; goto out; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c index e3a7b07df629..238ab2f8a5e7 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -325,46 +325,24 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) **/ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) { - u16 phy_reg = 0; - u32 phy_id = 0; - s32 ret_val; - u16 retry_count; - - for (retry_count = 0; retry_count < 2; retry_count++) { - ret_val = e1e_rphy_locked(hw, PHY_ID1, &phy_reg); - if (ret_val || (phy_reg == 0xFFFF)) - continue; - phy_id = (u32)(phy_reg << 16); + u16 phy_reg; + u32 phy_id; - ret_val = e1e_rphy_locked(hw, PHY_ID2, &phy_reg); - if (ret_val || (phy_reg == 0xFFFF)) { - phy_id = 0; - continue; - } - phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); - break; - } + e1e_rphy_locked(hw, PHY_ID1, &phy_reg); + phy_id = (u32)(phy_reg << 16); + e1e_rphy_locked(hw, PHY_ID2, &phy_reg); + phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); if (hw->phy.id) { if (hw->phy.id == phy_id) return true; - } else if (phy_id) { - hw->phy.id = phy_id; - hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK); + } else { + if ((phy_id != 0) && (phy_id != PHY_REVISION_MASK)) + hw->phy.id = phy_id; return true; } - /* - * In case the PHY needs to be in mdio slow mode, - * set slow mode and try to get the PHY id again. - */ - hw->phy.ops.release(hw); - ret_val = e1000_set_mdio_slow_mode_hv(hw); - if (!ret_val) - ret_val = e1000e_get_phy_id(hw); - hw->phy.ops.acquire(hw); - - return !ret_val; + return false; } /** diff --git a/trunk/drivers/net/ethernet/intel/e1000e/mac.c b/trunk/drivers/net/ethernet/intel/e1000e/mac.c index a13439928488..026e8b3ab52e 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/mac.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/mac.c @@ -709,7 +709,7 @@ s32 e1000e_setup_link_generic(struct e1000_hw *hw) * In the case of the phy reset being blocked, we already have a link. * We do not need to set it up again. */ - if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) + if (hw->phy.ops.check_reset_block(hw)) return 0; /* diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 623e30b9964d..a4b0435b00dc 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -496,7 +496,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, * @sk_buff: socket buffer with received data **/ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, - struct sk_buff *skb) + __le16 csum, struct sk_buff *skb) { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); @@ -511,8 +511,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, if (status & E1000_RXD_STAT_IXSM) return; - /* TCP/UDP checksum error bit or IP checksum error bit is set */ - if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) { + /* TCP/UDP checksum error bit is set */ + if (errors & E1000_RXD_ERR_TCPE) { /* let the stack verify checksum errors */ adapter->hw_csum_err++; return; @@ -523,7 +523,19 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, return; /* It must be a TCP or UDP packet with a valid checksum */ - skb->ip_summed = CHECKSUM_UNNECESSARY; + if (status & E1000_RXD_STAT_TCPCS) { + /* TCP checksum is good */ + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + /* + * IP fragment with UDP payload + * Hardware complements the payload checksum, so we undo it + * and then put the value in host order for further stack use. + */ + __sum16 sum = (__force __sum16)swab16((__force u16)csum); + skb->csum = csum_unfold(~sum); + skb->ip_summed = CHECKSUM_COMPLETE; + } adapter->hw_csum_good++; } @@ -942,7 +954,8 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb_put(skb, length); /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, staterr, skb); + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1328,7 +1341,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, total_rx_bytes += skb->len; total_rx_packets++; - e1000_rx_checksum(adapter, staterr, skb); + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1498,8 +1512,9 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, } } - /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, staterr, skb); + /* Receive Checksum Offload XXX recompute due to CRC strip? */ + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -3083,10 +3098,19 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = er32(RXCSUM); - if (adapter->netdev->features & NETIF_F_RXCSUM) + if (adapter->netdev->features & NETIF_F_RXCSUM) { rxcsum |= E1000_RXCSUM_TUOFL; - else + + /* + * IPv4 payload checksum for UDP fragments must be + * used in conjunction with packet-split. + */ + if (adapter->rx_ps_pages) + rxcsum |= E1000_RXCSUM_IPPCSE; + } else { rxcsum &= ~E1000_RXCSUM_TUOFL; + /* no need to clear IPPCSE as it defaults to 0 */ + } ew32(RXCSUM, rxcsum); if (adapter->hw.mac.type == e1000_pch2lan) { @@ -5217,10 +5241,22 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ - if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && - !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); - return -EINVAL; + if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { + if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; + } + + /* + * IP payload checksum (enabled with jumbos/packet-split when + * Rx checksum is enabled) and generation of RSS hash is + * mutually exclusive in the hardware. + */ + if ((netdev->features & NETIF_F_RXCSUM) && + (netdev->features & NETIF_F_RXHASH)) { + e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled. Disable one of the receive offload features before enabling jumbos.\n"); + return -EINVAL; + } } /* Supported frame sizes */ @@ -5994,6 +6030,17 @@ static int e1000_set_features(struct net_device *netdev, NETIF_F_RXALL))) return 0; + /* + * IP payload checksum (enabled with jumbos/packet-split when Rx + * checksum is enabled) and generation of RSS hash is mutually + * exclusive in the hardware. + */ + if (adapter->rx_ps_pages && + (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) { + e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames. Disable jumbos or enable only one of the receive offload features.\n"); + return -EINVAL; + } + if (changed & NETIF_F_RXFCS) { if (features & NETIF_F_RXFCS) { adapter->flags2 &= ~FLAG2_CRC_STRIPPING; @@ -6190,7 +6237,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->hw.phy.ms_type = e1000_ms_hw_default; } - if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) + if (hw->phy.ops.check_reset_block(hw)) e_info("PHY reset is blocked due to SOL/IDER session.\n"); /* Set initial default active device features */ @@ -6357,7 +6404,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!(adapter->flags & FLAG_HAS_AMT)) e1000e_release_hw_control(adapter); err_eeprom: - if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw)) + if (!hw->phy.ops.check_reset_block(hw)) e1000_phy_hw_reset(&adapter->hw); err_hw_init: kfree(adapter->tx_ring); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/phy.c b/trunk/drivers/net/ethernet/intel/e1000e/phy.c index b860d4f7ea2a..0334d013bc3c 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/phy.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/phy.c @@ -2155,11 +2155,9 @@ s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw) s32 ret_val; u32 ctrl; - if (phy->ops.check_reset_block) { - ret_val = phy->ops.check_reset_block(hw); - if (ret_val) - return 0; - } + ret_val = phy->ops.check_reset_block(hw); + if (ret_val) + return 0; ret_val = phy->ops.acquire(hw); if (ret_val) diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c index 5e84eaac48c1..e65083958421 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -206,6 +206,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; break; case e1000_i350: + case e1000_i210: + case e1000_i211: mac->rar_entry_count = E1000_RAR_ENTRIES_I350; break; default: diff --git a/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c b/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c index 90eef07943f4..8ce67064b9c5 100644 --- a/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c @@ -357,28 +357,21 @@ static int igbvf_set_coalesce(struct net_device *netdev, struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) && - (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) { - adapter->current_itr = ec->rx_coalesce_usecs << 2; - adapter->requested_itr = 1000000000 / - (adapter->current_itr * 256); - } else if ((ec->rx_coalesce_usecs == 3) || - (ec->rx_coalesce_usecs == 2)) { + if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) || + ((ec->rx_coalesce_usecs > 3) && + (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) || + (ec->rx_coalesce_usecs == 2)) + return -EINVAL; + + /* convert to rate of irq's per second */ + if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) { adapter->current_itr = IGBVF_START_ITR; adapter->requested_itr = ec->rx_coalesce_usecs; - } else if (ec->rx_coalesce_usecs == 0) { - /* - * The user's desire is to turn off interrupt throttling - * altogether, but due to HW limitations, we can't do that. - * Instead we set a very small value in EITR, which would - * allow ~967k interrupts per second, but allow the adapter's - * internal clocking to still function properly. - */ - adapter->current_itr = 4; + } else { + adapter->current_itr = ec->rx_coalesce_usecs << 2; adapter->requested_itr = 1000000000 / (adapter->current_itr * 256); - } else - return -EINVAL; + } writel(adapter->current_itr, hw->hw_addr + adapter->rx_ring->itr_register); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 7af291e236bf..3ef3c5284e52 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -196,7 +196,7 @@ enum ixgbe_ring_state_t { __IXGBE_HANG_CHECK_ARMED, __IXGBE_RX_RSC_ENABLED, __IXGBE_RX_CSUM_UDP_ZERO_ERR, - __IXGBE_RX_FCOE, + __IXGBE_RX_FCOE_BUFSZ, }; #define check_for_tx_hang(ring) \ @@ -290,7 +290,7 @@ struct ixgbe_ring_feature { #if defined(IXGBE_FCOE) && (PAGE_SIZE < 8192) static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring) { - return test_bit(__IXGBE_RX_FCOE, &ring->state) ? 1 : 0; + return test_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state) ? 1 : 0; } #else #define ixgbe_rx_pg_order(_ring) 0 diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index c377706e81a8..af1a5314b494 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -634,7 +634,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, f = &adapter->ring_feature[RING_F_FCOE]; if ((rxr_idx >= f->mask) && (rxr_idx < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE, &ring->state); + set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); } #endif /* IXGBE_FCOE */ diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index e242104ab471..bf20457ea23a 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1058,17 +1058,17 @@ static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, #ifdef IXGBE_FCOE /** * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @ring: structure containing ring specific data + * @adapter: address of board private structure * @rx_desc: advanced rx descriptor * * Returns : true if it is FCoE pkt */ -static inline bool ixgbe_rx_is_fcoe(struct ixgbe_ring *ring, +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc) { __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; - return test_bit(__IXGBE_RX_FCOE, &ring->state) && + return (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); @@ -1148,7 +1148,7 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, /* alloc new page for storage */ if (likely(!page)) { - page = alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, + page = alloc_pages(GFP_ATOMIC | __GFP_COLD, ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; @@ -1390,8 +1390,6 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) { - struct net_device *dev = rx_ring->netdev; - ixgbe_update_rsc_stats(rx_ring, skb); ixgbe_rx_hash(rx_ring, rx_desc, skb); @@ -1403,15 +1401,14 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); #endif - if ((dev->features & NETIF_F_HW_VLAN_RX) && - ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { + if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); __vlan_hwaccel_put_tag(skb, vid); } skb_record_rx_queue(skb, rx_ring->queue_index); - skb->protocol = eth_type_trans(skb, dev); + skb->protocol = eth_type_trans(skb, rx_ring->netdev); } static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, @@ -1549,12 +1546,6 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring, skb->truesize -= ixgbe_rx_bufsz(rx_ring); } -#ifdef IXGBE_FCOE - /* do not attempt to pad FCoE Frames as this will disrupt DDP */ - if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) - return false; - -#endif /* if skb_pad returns an error the skb was freed */ if (unlikely(skb->len < 60)) { int pad_len = 60 - skb->len; @@ -1781,7 +1772,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) { + if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); if (!ddp_bytes) { dev_kfree_skb_any(skb); @@ -3616,6 +3607,10 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82598EB) netif_set_gso_max_size(adapter->netdev, 32768); + + /* Enable VLAN tag insert/strip */ + adapter->netdev->features |= NETIF_F_HW_VLAN_RX; + hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); #ifdef IXGBE_FCOE @@ -6647,11 +6642,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) return -EINVAL; } - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { - e_err(drv, "Enable failed, SR-IOV enabled\n"); - return -EINVAL; - } - /* Hardware supports up to 8 traffic classes */ if (tc > adapter->dcb_cfg.num_tcs.pg_tcs || (hw->mac.type == ixgbe_mac_82598EB && @@ -6711,6 +6701,11 @@ static netdev_features_t ixgbe_fix_features(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); +#ifdef CONFIG_DCB + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + features &= ~NETIF_F_HW_VLAN_RX; +#endif + /* return error if RXHASH is being enabled when RSS is not supported */ if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) features &= ~NETIF_F_RXHASH; @@ -6723,6 +6718,7 @@ static netdev_features_t ixgbe_fix_features(struct net_device *netdev, if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) features &= ~NETIF_F_LRO; + return features; } @@ -6770,11 +6766,6 @@ static int ixgbe_set_features(struct net_device *netdev, need_reset = true; } - if (features & NETIF_F_HW_VLAN_RX) - ixgbe_vlan_strip_enable(adapter); - else - ixgbe_vlan_strip_disable(adapter); - if (changed & NETIF_F_RXALL) need_reset = true; diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index dcebd128becf..ddc6a4d19302 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -708,7 +708,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 incval = 0; - u32 timinca = 0; u32 shift = 0; u32 cycle_speed; unsigned long flags; @@ -731,16 +730,8 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) break; } - /* - * grab the current TIMINCA value from the register so that it can be - * double checked. If the register value has been cleared, it must be - * reset to the correct value for generating a cyclecounter. If - * TIMINCA is zero, the SYSTIME registers do not increment at all. - */ - timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA); - - /* Bail if the cycle speed didn't change and TIMINCA is non-zero */ - if (adapter->cycle_speed == cycle_speed && timinca) + /* Bail if the cycle speed didn't change */ + if (adapter->cycle_speed == cycle_speed) return; /* disable the SDP clock out */ diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 41e32257a4e8..f69ec4288b10 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -201,9 +201,6 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, unsigned int i, eop, count = 0; unsigned int total_bytes = 0, total_packets = 0; - if (test_bit(__IXGBEVF_DOWN, &adapter->state)) - return true; - i = tx_ring->next_to_clean; eop = tx_ring->tx_buffer_info[i].next_to_watch; eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); @@ -972,6 +969,8 @@ static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data) r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { tx_ring = &(adapter->tx_ring[r_idx]); + tx_ring->total_bytes = 0; + tx_ring->total_packets = 0; ixgbevf_clean_tx_irq(adapter, tx_ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, r_idx + 1); @@ -995,6 +994,16 @@ static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data) struct ixgbe_hw *hw = &adapter->hw; struct ixgbevf_ring *rx_ring; int r_idx; + int i; + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + rx_ring = &(adapter->rx_ring[r_idx]); + rx_ring->total_bytes = 0; + rx_ring->total_packets = 0; + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } if (!q_vector->rxr_count) return IRQ_HANDLED; diff --git a/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c b/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c index f0f06b2bc28b..04d901d0ff63 100644 --- a/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/trunk/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -436,9 +436,7 @@ struct mv643xx_eth_private { /* * Hardware-specific parameters. */ -#if defined(CONFIG_HAVE_CLK) struct clk *clk; -#endif unsigned int t_clk; }; @@ -2897,17 +2895,17 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->dev = dev; /* - * Start with a default rate, and if there is a clock, allow - * it to override the default. + * Get the clk rate, if there is one, otherwise use the default. */ - mp->t_clk = 133000000; -#if defined(CONFIG_HAVE_CLK) mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0")); if (!IS_ERR(mp->clk)) { clk_prepare_enable(mp->clk); mp->t_clk = clk_get_rate(mp->clk); + } else { + mp->t_clk = 133000000; + printk(KERN_WARNING "Unable to get clock"); } -#endif + set_params(mp, pd); netif_set_real_num_tx_queues(dev, mp->txq_count); netif_set_real_num_rx_queues(dev, mp->rxq_count); @@ -2997,13 +2995,10 @@ static int mv643xx_eth_remove(struct platform_device *pdev) phy_detach(mp->phy); cancel_work_sync(&mp->tx_timeout_task); -#if defined(CONFIG_HAVE_CLK) if (!IS_ERR(mp->clk)) { clk_disable_unprepare(mp->clk); clk_put(mp->clk); } -#endif - free_netdev(mp->dev); platform_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/net/ethernet/marvell/sky2.c b/trunk/drivers/net/ethernet/marvell/sky2.c index 28a54451a3e5..cace36f2ab92 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.c +++ b/trunk/drivers/net/ethernet/marvell/sky2.c @@ -4381,12 +4381,10 @@ static int sky2_set_features(struct net_device *dev, netdev_features_t features) struct sky2_port *sky2 = netdev_priv(dev); netdev_features_t changed = dev->features ^ features; - if ((changed & NETIF_F_RXCSUM) && - !(sky2->hw->flags & SKY2_HW_NEW_LE)) { - sky2_write32(sky2->hw, - Q_ADDR(rxqaddr[sky2->port], Q_CSR), - (features & NETIF_F_RXCSUM) - ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + if (changed & NETIF_F_RXCSUM) { + bool on = features & NETIF_F_RXCSUM; + sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), + on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); } if (changed & NETIF_F_RXHASH) diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 073b85b45fc5..926d8aac941c 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -929,20 +929,15 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv) if (priv->rx_cq[i].buf) mlx4_en_destroy_cq(priv, &priv->rx_cq[i]); } - - if (priv->base_tx_qpn) { - mlx4_qp_release_range(priv->mdev->dev, priv->base_tx_qpn, priv->tx_ring_num); - priv->base_tx_qpn = 0; - } } int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) { struct mlx4_en_port_profile *prof = priv->prof; int i; - int err; + int base_tx_qpn, err; - err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &priv->base_tx_qpn); + err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &base_tx_qpn); if (err) { en_err(priv, "failed reserving range for TX rings\n"); return err; @@ -954,7 +949,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) prof->tx_ring_size, i, TX)) goto err; - if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], priv->base_tx_qpn + i, + if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], base_tx_qpn + i, prof->tx_ring_size, TXBB_SIZE)) goto err; } @@ -974,6 +969,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) err: en_err(priv, "Failed to allocate NIC resources\n"); + mlx4_qp_release_range(priv->mdev->dev, base_tx_qpn, priv->tx_ring_num); return -ENOMEM; } @@ -1208,11 +1204,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num); /* Configure port */ - mlx4_en_calc_rx_buf(dev); err = mlx4_SET_PORT_general(mdev->dev, priv->port, - priv->rx_skb_size + ETH_FCS_LEN, - prof->tx_pause, prof->tx_ppp, - prof->rx_pause, prof->rx_ppp); + MLX4_EN_MIN_MTU, + 0, 0, 0, 0); if (err) { en_err(priv, "Failed setting port general configurations " "for port %d, with error %d\n", priv->port, err); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index a0313de122de..ee6f4fe00837 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1975,8 +1975,6 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) && !mlx4_is_mfunc(dev)) { dev->flags &= ~MLX4_FLAG_MSI_X; - dev->caps.num_comp_vectors = 1; - dev->caps.comp_pool = 0; pci_disable_msix(pdev); err = mlx4_setup_hca(dev); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 225c20d47900..6ae350921b1a 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -495,7 +495,6 @@ struct mlx4_en_priv { int vids[128]; bool wol; struct device *ddev; - int base_tx_qpn; #ifdef CONFIG_MLX4_EN_DCB struct ieee_ets ets; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c index a8fb52992c64..1fe2c7a8b40c 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c @@ -697,10 +697,10 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, if (slave != dev->caps.function) memset(inbox->buf, 0, 256); if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { - *(u8 *) inbox->buf |= !!reset_qkey_viols << 6; + *(u8 *) inbox->buf = !!reset_qkey_viols << 6; ((__be32 *) inbox->buf)[2] = agg_cap_mask; } else { - ((u8 *) inbox->buf)[3] |= !!reset_qkey_viols; + ((u8 *) inbox->buf)[3] = !!reset_qkey_viols; ((__be32 *) inbox->buf)[1] = agg_cap_mask; } diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index 083d6715335c..8d2666fcffd7 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -946,16 +946,16 @@ static void __lpc_handle_xmit(struct net_device *ndev) /* Update stats */ ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; + + /* Free buffer */ + dev_kfree_skb_irq(skb); } - dev_kfree_skb_irq(skb); txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); } - if (pldat->num_used_tx_buffs <= ENET_TX_DESC/2) { - if (netif_queue_stopped(ndev)) - netif_wake_queue(ndev); - } + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); } static int __lpc_handle_recv(struct net_device *ndev, int budget) @@ -1320,7 +1320,6 @@ static const struct net_device_ops lpc_netdev_ops = { .ndo_set_rx_mode = lpc_eth_set_multicast_list, .ndo_do_ioctl = lpc_eth_ioctl, .ndo_set_mac_address = lpc_set_mac_address, - .ndo_change_mtu = eth_change_mtu, }; static int lpc_eth_drv_probe(struct platform_device *pdev) diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ad98f4d7919d..46e77a2c5121 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -479,7 +479,7 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { pfn = pci_info[i].id; - if (pfn >= QLCNIC_MAX_PCI_FUNC) { + if (pfn > QLCNIC_MAX_PCI_FUNC) { ret = QL_STATUS_INVALID_PARAM; goto err_eswitch; } diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index d7a04e091101..9757ce3543a0 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -3894,7 +3894,6 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_22: case RTL_GIGA_MAC_VER_23: case RTL_GIGA_MAC_VER_24: - case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; default: @@ -5890,7 +5889,11 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) if (status & LinkChg) __rtl8169_check_link_status(dev, tp, tp->mmio_addr, true); - rtl_irq_enable_all(tp); + napi_disable(&tp->napi); + rtl_irq_disable(tp); + + napi_enable(&tp->napi); + napi_schedule(&tp->napi); } static void rtl_task(struct work_struct *work) diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.c b/trunk/drivers/net/ethernet/renesas/sh_eth.c index 79bf09b41971..667169b82526 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.c +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.c @@ -1011,7 +1011,7 @@ static int sh_eth_txfree(struct net_device *ndev) } /* Packet receive function */ -static int sh_eth_rx(struct net_device *ndev, u32 intr_status) +static int sh_eth_rx(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_rxdesc *rxdesc; @@ -1102,11 +1102,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { - /* fix the values for the next receiving if RDE is set */ - if (intr_status & EESR_RDE) - mdp->cur_rx = mdp->dirty_rx = - (sh_eth_read(ndev, RDFAR) - - sh_eth_read(ndev, RDLAR)) >> 4; + /* fix the values for the next receiving */ + mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - + sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_write(ndev, EDRRR_R, EDRRR); } @@ -1275,7 +1273,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) EESR_RTSF | /* short frame recv */ EESR_PRE | /* PHY-LSI recv error */ EESR_CERF)){ /* recv frame CRC error */ - sh_eth_rx(ndev, intr_status); + sh_eth_rx(ndev); } /* Tx Check */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig b/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig index 9f448279e12a..036428348faa 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -13,7 +13,7 @@ config STMMAC_ETH if STMMAC_ETH config STMMAC_PLATFORM - bool "STMMAC Platform bus support" + tristate "STMMAC platform bus support" depends on STMMAC_ETH default y ---help--- @@ -26,7 +26,7 @@ config STMMAC_PLATFORM If unsure, say N. config STMMAC_PCI - bool "STMMAC PCI bus support (EXPERIMENTAL)" + tristate "STMMAC support on PCI bus (EXPERIMENTAL)" depends on STMMAC_ETH && PCI && EXPERIMENTAL ---help--- This is to select the Synopsys DWMAC available on PCI devices, diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/trunk/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index 4b785e10f2ed..fb8377da1687 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -51,7 +51,7 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum); - wmb(); + entry = (++priv->cur_tx) % txsize; desc = priv->dma_tx + entry; @@ -59,7 +59,6 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) len, DMA_TO_DEVICE); desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 0, len, csum); - wmb(); priv->hw->desc->set_tx_owner(desc); priv->tx_skbuff[entry] = NULL; } else { diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h index dc20c56efc9d..6b5d060ee9de 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -26,7 +26,6 @@ #include #include #include -#include #include "common.h" #ifdef CONFIG_STMMAC_TIMER #include "stmmac_timer.h" @@ -96,6 +95,7 @@ extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); extern const struct stmmac_desc_ops enh_desc_ops; extern const struct stmmac_desc_ops ndesc_ops; + int stmmac_freeze(struct net_device *ndev); int stmmac_restore(struct net_device *ndev); int stmmac_resume(struct net_device *ndev); @@ -109,7 +109,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, static inline int stmmac_clk_enable(struct stmmac_priv *priv) { if (!IS_ERR(priv->stmmac_clk)) - return clk_prepare_enable(priv->stmmac_clk); + return clk_enable(priv->stmmac_clk); return 0; } @@ -119,7 +119,7 @@ static inline void stmmac_clk_disable(struct stmmac_priv *priv) if (IS_ERR(priv->stmmac_clk)) return; - clk_disable_unprepare(priv->stmmac_clk); + clk_disable(priv->stmmac_clk); } static inline int stmmac_clk_get(struct stmmac_priv *priv) { @@ -143,60 +143,3 @@ static inline int stmmac_clk_get(struct stmmac_priv *priv) return 0; } #endif /* CONFIG_HAVE_CLK */ - - -#ifdef CONFIG_STMMAC_PLATFORM -extern struct platform_driver stmmac_pltfr_driver; -static inline int stmmac_register_platform(void) -{ - int err; - - err = platform_driver_register(&stmmac_pltfr_driver); - if (err) - pr_err("stmmac: failed to register the platform driver\n"); - - return err; -} -static inline void stmmac_unregister_platform(void) -{ - platform_driver_register(&stmmac_pltfr_driver); -} -#else -static inline int stmmac_register_platform(void) -{ - pr_debug("stmmac: do not register the platf driver\n"); - - return -EINVAL; -} -static inline void stmmac_unregister_platform(void) -{ -} -#endif /* CONFIG_STMMAC_PLATFORM */ - -#ifdef CONFIG_STMMAC_PCI -extern struct pci_driver stmmac_pci_driver; -static inline int stmmac_register_pci(void) -{ - int err; - - err = pci_register_driver(&stmmac_pci_driver); - if (err) - pr_err("stmmac: failed to register the PCI driver\n"); - - return err; -} -static inline void stmmac_unregister_pci(void) -{ - pci_unregister_driver(&stmmac_pci_driver); -} -#else -static inline int stmmac_register_pci(void) -{ - pr_debug("stmmac: do not register the PCI driver\n"); - - return -EINVAL; -} -static inline void stmmac_unregister_pci(void) -{ -} -#endif /* CONFIG_STMMAC_PCI */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index ea3003edde18..70966330f44e 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -833,9 +833,8 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) /** * stmmac_selec_desc_mode - * @priv : private structure - * Description: select the Enhanced/Alternate or Normal descriptors - */ + * @dev : device pointer + * Description: select the Enhanced/Alternate or Normal descriptors */ static void stmmac_selec_desc_mode(struct stmmac_priv *priv) { if (priv->plat->enh_desc) { @@ -1212,7 +1211,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); wmb(); priv->hw->desc->set_tx_owner(desc); - wmb(); } /* Interrupt on completition only for the latest segment */ @@ -1228,7 +1226,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) /* To avoid raise condition */ priv->hw->desc->set_tx_owner(first); - wmb(); priv->cur_tx++; @@ -1292,7 +1289,6 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) } wmb(); priv->hw->desc->set_rx_owner(p + entry); - wmb(); } } @@ -1865,8 +1861,6 @@ static int stmmac_hw_init(struct stmmac_priv *priv) /** * stmmac_dvr_probe * @device: device pointer - * @plat_dat: platform data pointer - * @addr: iobase memory address * Description: this is the main probe function used to * call the alloc_etherdev, allocate the priv structure. */ @@ -2096,34 +2090,6 @@ int stmmac_restore(struct net_device *ndev) } #endif /* CONFIG_PM */ -/* Driver can be configured w/ and w/ both PCI and Platf drivers - * depending on the configuration selected. - */ -static int __init stmmac_init(void) -{ - int err_plt = 0; - int err_pci = 0; - - err_plt = stmmac_register_platform(); - err_pci = stmmac_register_pci(); - - if ((err_pci) && (err_plt)) { - pr_err("stmmac: driver registration failed\n"); - return -EINVAL; - } - - return 0; -} - -static void __exit stmmac_exit(void) -{ - stmmac_unregister_platform(); - stmmac_unregister_pci(); -} - -module_init(stmmac_init); -module_exit(stmmac_exit); - #ifndef MODULE static int __init stmmac_cmdline_opt(char *str) { diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index cf826e6b6aa1..58fab5303e9c 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -179,7 +179,7 @@ static DEFINE_PCI_DEVICE_TABLE(stmmac_id_table) = { MODULE_DEVICE_TABLE(pci, stmmac_id_table); -struct pci_driver stmmac_pci_driver = { +static struct pci_driver stmmac_driver = { .name = STMMAC_RESOURCE_NAME, .id_table = stmmac_id_table, .probe = stmmac_pci_probe, @@ -190,6 +190,33 @@ struct pci_driver stmmac_pci_driver = { #endif }; +/** + * stmmac_init_module - Entry point for the driver + * Description: This function is the entry point for the driver. + */ +static int __init stmmac_init_module(void) +{ + int ret; + + ret = pci_register_driver(&stmmac_driver); + if (ret < 0) + pr_err("%s: ERROR: driver registration failed\n", __func__); + + return ret; +} + +/** + * stmmac_cleanup_module - Cleanup routine for the driver + * Description: This function is the cleanup routine for the driver. + */ +static void __exit stmmac_cleanup_module(void) +{ + pci_unregister_driver(&stmmac_driver); +} + +module_init(stmmac_init_module); +module_exit(stmmac_cleanup_module); + MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver"); MODULE_AUTHOR("Rayagond Kokatanur "); MODULE_AUTHOR("Giuseppe Cavallaro "); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 680d2b8dfe27..3dd8f0803808 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -255,7 +255,7 @@ static const struct of_device_id stmmac_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, stmmac_dt_ids); -struct platform_driver stmmac_pltfr_driver = { +static struct platform_driver stmmac_driver = { .probe = stmmac_pltfr_probe, .remove = stmmac_pltfr_remove, .driver = { @@ -266,6 +266,8 @@ struct platform_driver stmmac_pltfr_driver = { }, }; +module_platform_driver(stmmac_driver); + MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver"); MODULE_AUTHOR("Giuseppe Cavallaro "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/ethernet/sun/niu.c b/trunk/drivers/net/ethernet/sun/niu.c index 8c726b7004d3..703c8cce2a2c 100644 --- a/trunk/drivers/net/ethernet/sun/niu.c +++ b/trunk/drivers/net/ethernet/sun/niu.c @@ -3598,6 +3598,7 @@ static int release_tx_packet(struct niu *np, struct tx_ring_info *rp, int idx) static void niu_tx_work(struct niu *np, struct tx_ring_info *rp) { struct netdev_queue *txq; + unsigned int tx_bytes; u16 pkt_cnt, tmp; int cons, index; u64 cs; @@ -3620,12 +3621,18 @@ static void niu_tx_work(struct niu *np, struct tx_ring_info *rp) netif_printk(np, tx_done, KERN_DEBUG, np->dev, "%s() pkt_cnt[%u] cons[%d]\n", __func__, pkt_cnt, cons); - while (pkt_cnt--) + tx_bytes = 0; + tmp = pkt_cnt; + while (tmp--) { + tx_bytes += rp->tx_buffs[cons].skb->len; cons = release_tx_packet(np, rp, cons); + } rp->cons = cons; smp_mb(); + netdev_tx_completed_queue(txq, pkt_cnt, tx_bytes); + out: if (unlikely(netif_tx_queue_stopped(txq) && (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)))) { @@ -4326,6 +4333,7 @@ static void niu_free_channels(struct niu *np) struct tx_ring_info *rp = &np->tx_rings[i]; niu_free_tx_ring_info(np, rp); + netdev_tx_reset_queue(netdev_get_tx_queue(np->dev, i)); } kfree(np->tx_rings); np->tx_rings = NULL; @@ -6731,6 +6739,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, prod = NEXT_TX(rp, prod); } + netdev_tx_sent_queue(txq, skb->len); + if (prod < rp->prod) rp->wrap_bit ^= TX_RING_KICK_WRAP; rp->prod = prod; diff --git a/trunk/drivers/net/ethernet/ti/davinci_cpdma.c b/trunk/drivers/net/ethernet/ti/davinci_cpdma.c index 3b5c4571b55e..d614c374ed9d 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/trunk/drivers/net/ethernet/ti/davinci_cpdma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/net/ethernet/tile/Kconfig b/trunk/drivers/net/ethernet/tile/Kconfig index 098b1c42b393..2d9218f86bca 100644 --- a/trunk/drivers/net/ethernet/tile/Kconfig +++ b/trunk/drivers/net/ethernet/tile/Kconfig @@ -7,8 +7,6 @@ config TILE_NET depends on TILE default y select CRC32 - select TILE_GXIO_MPIPE if TILEGX - select HIGH_RES_TIMERS if TILEGX ---help--- This is a standard Linux network device driver for the on-chip Tilera Gigabit Ethernet and XAUI interfaces. diff --git a/trunk/drivers/net/ethernet/tile/Makefile b/trunk/drivers/net/ethernet/tile/Makefile index 0ef9eefd3211..f634f142cab4 100644 --- a/trunk/drivers/net/ethernet/tile/Makefile +++ b/trunk/drivers/net/ethernet/tile/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_TILE_NET) += tile_net.o ifdef CONFIG_TILEGX -tile_net-y := tilegx.o +tile_net-objs := tilegx.o mpipe.o iorpc_mpipe.o dma_queue.o else -tile_net-y := tilepro.o +tile_net-objs := tilepro.o endif diff --git a/trunk/drivers/net/ethernet/tile/tilegx.c b/trunk/drivers/net/ethernet/tile/tilegx.c deleted file mode 100644 index 83b4b388ad49..000000000000 --- a/trunk/drivers/net/ethernet/tile/tilegx.c +++ /dev/null @@ -1,1898 +0,0 @@ -/* - * Copyright 2012 Tilera Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - */ - -#include -#include -#include -#include -#include /* printk() */ -#include /* kmalloc() */ -#include /* error codes */ -#include /* size_t */ -#include -#include -#include -#include /* struct device, and other headers */ -#include /* eth_type_trans */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Default transmit lockup timeout period, in jiffies. */ -#define TILE_NET_TIMEOUT (5 * HZ) - -/* The maximum number of distinct channels (idesc.channel is 5 bits). */ -#define TILE_NET_CHANNELS 32 - -/* Maximum number of idescs to handle per "poll". */ -#define TILE_NET_BATCH 128 - -/* Maximum number of packets to handle per "poll". */ -#define TILE_NET_WEIGHT 64 - -/* Number of entries in each iqueue. */ -#define IQUEUE_ENTRIES 512 - -/* Number of entries in each equeue. */ -#define EQUEUE_ENTRIES 2048 - -/* Total header bytes per equeue slot. Must be big enough for 2 bytes - * of NET_IP_ALIGN alignment, plus 14 bytes (?) of L2 header, plus up to - * 60 bytes of actual TCP header. We round up to align to cache lines. - */ -#define HEADER_BYTES 128 - -/* Maximum completions per cpu per device (must be a power of two). - * ISSUE: What is the right number here? If this is too small, then - * egress might block waiting for free space in a completions array. - * ISSUE: At the least, allocate these only for initialized echannels. - */ -#define TILE_NET_MAX_COMPS 64 - -#define MAX_FRAGS (MAX_SKB_FRAGS + 1) - -/* Size of completions data to allocate. - * ISSUE: Probably more than needed since we don't use all the channels. - */ -#define COMPS_SIZE (TILE_NET_CHANNELS * sizeof(struct tile_net_comps)) - -/* Size of NotifRing data to allocate. */ -#define NOTIF_RING_SIZE (IQUEUE_ENTRIES * sizeof(gxio_mpipe_idesc_t)) - -/* Timeout to wake the per-device TX timer after we stop the queue. - * We don't want the timeout too short (adds overhead, and might end - * up causing stop/wake/stop/wake cycles) or too long (affects performance). - * For the 10 Gb NIC, 30 usec means roughly 30+ 1500-byte packets. - */ -#define TX_TIMER_DELAY_USEC 30 - -/* Timeout to wake the per-cpu egress timer to free completions. */ -#define EGRESS_TIMER_DELAY_USEC 1000 - -MODULE_AUTHOR("Tilera Corporation"); -MODULE_LICENSE("GPL"); - -/* A "packet fragment" (a chunk of memory). */ -struct frag { - void *buf; - size_t length; -}; - -/* A single completion. */ -struct tile_net_comp { - /* The "complete_count" when the completion will be complete. */ - s64 when; - /* The buffer to be freed when the completion is complete. */ - struct sk_buff *skb; -}; - -/* The completions for a given cpu and echannel. */ -struct tile_net_comps { - /* The completions. */ - struct tile_net_comp comp_queue[TILE_NET_MAX_COMPS]; - /* The number of completions used. */ - unsigned long comp_next; - /* The number of completions freed. */ - unsigned long comp_last; -}; - -/* The transmit wake timer for a given cpu and echannel. */ -struct tile_net_tx_wake { - struct hrtimer timer; - struct net_device *dev; -}; - -/* Info for a specific cpu. */ -struct tile_net_info { - /* The NAPI struct. */ - struct napi_struct napi; - /* Packet queue. */ - gxio_mpipe_iqueue_t iqueue; - /* Our cpu. */ - int my_cpu; - /* True if iqueue is valid. */ - bool has_iqueue; - /* NAPI flags. */ - bool napi_added; - bool napi_enabled; - /* Number of small sk_buffs which must still be provided. */ - unsigned int num_needed_small_buffers; - /* Number of large sk_buffs which must still be provided. */ - unsigned int num_needed_large_buffers; - /* A timer for handling egress completions. */ - struct hrtimer egress_timer; - /* True if "egress_timer" is scheduled. */ - bool egress_timer_scheduled; - /* Comps for each egress channel. */ - struct tile_net_comps *comps_for_echannel[TILE_NET_CHANNELS]; - /* Transmit wake timer for each egress channel. */ - struct tile_net_tx_wake tx_wake[TILE_NET_CHANNELS]; -}; - -/* Info for egress on a particular egress channel. */ -struct tile_net_egress { - /* The "equeue". */ - gxio_mpipe_equeue_t *equeue; - /* The headers for TSO. */ - unsigned char *headers; -}; - -/* Info for a specific device. */ -struct tile_net_priv { - /* Our network device. */ - struct net_device *dev; - /* The primary link. */ - gxio_mpipe_link_t link; - /* The primary channel, if open, else -1. */ - int channel; - /* The "loopify" egress link, if needed. */ - gxio_mpipe_link_t loopify_link; - /* The "loopify" egress channel, if open, else -1. */ - int loopify_channel; - /* The egress channel (channel or loopify_channel). */ - int echannel; - /* Total stats. */ - struct net_device_stats stats; -}; - -/* Egress info, indexed by "priv->echannel" (lazily created as needed). */ -static struct tile_net_egress egress_for_echannel[TILE_NET_CHANNELS]; - -/* Devices currently associated with each channel. - * NOTE: The array entry can become NULL after ifconfig down, but - * we do not free the underlying net_device structures, so it is - * safe to use a pointer after reading it from this array. - */ -static struct net_device *tile_net_devs_for_channel[TILE_NET_CHANNELS]; - -/* A mutex for "tile_net_devs_for_channel". */ -static DEFINE_MUTEX(tile_net_devs_for_channel_mutex); - -/* The per-cpu info. */ -static DEFINE_PER_CPU(struct tile_net_info, per_cpu_info); - -/* The "context" for all devices. */ -static gxio_mpipe_context_t context; - -/* Buffer sizes and mpipe enum codes for buffer stacks. - * See arch/tile/include/gxio/mpipe.h for the set of possible values. - */ -#define BUFFER_SIZE_SMALL_ENUM GXIO_MPIPE_BUFFER_SIZE_128 -#define BUFFER_SIZE_SMALL 128 -#define BUFFER_SIZE_LARGE_ENUM GXIO_MPIPE_BUFFER_SIZE_1664 -#define BUFFER_SIZE_LARGE 1664 - -/* The small/large "buffer stacks". */ -static int small_buffer_stack = -1; -static int large_buffer_stack = -1; - -/* Amount of memory allocated for each buffer stack. */ -static size_t buffer_stack_size; - -/* The actual memory allocated for the buffer stacks. */ -static void *small_buffer_stack_va; -static void *large_buffer_stack_va; - -/* The buckets. */ -static int first_bucket = -1; -static int num_buckets = 1; - -/* The ingress irq. */ -static int ingress_irq = -1; - -/* Text value of tile_net.cpus if passed as a module parameter. */ -static char *network_cpus_string; - -/* The actual cpus in "network_cpus". */ -static struct cpumask network_cpus_map; - -/* If "loopify=LINK" was specified, this is "LINK". */ -static char *loopify_link_name; - -/* If "tile_net.custom" was specified, this is non-NULL. */ -static char *custom_str; - -/* The "tile_net.cpus" argument specifies the cpus that are dedicated - * to handle ingress packets. - * - * The parameter should be in the form "tile_net.cpus=m-n[,x-y]", where - * m, n, x, y are integer numbers that represent the cpus that can be - * neither a dedicated cpu nor a dataplane cpu. - */ -static bool network_cpus_init(void) -{ - char buf[1024]; - int rc; - - if (network_cpus_string == NULL) - return false; - - rc = cpulist_parse_crop(network_cpus_string, &network_cpus_map); - if (rc != 0) { - pr_warn("tile_net.cpus=%s: malformed cpu list\n", - network_cpus_string); - return false; - } - - /* Remove dedicated cpus. */ - cpumask_and(&network_cpus_map, &network_cpus_map, cpu_possible_mask); - - if (cpumask_empty(&network_cpus_map)) { - pr_warn("Ignoring empty tile_net.cpus='%s'.\n", - network_cpus_string); - return false; - } - - cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map); - pr_info("Linux network CPUs: %s\n", buf); - return true; -} - -module_param_named(cpus, network_cpus_string, charp, 0444); -MODULE_PARM_DESC(cpus, "cpulist of cores that handle network interrupts"); - -/* The "tile_net.loopify=LINK" argument causes the named device to - * actually use "loop0" for ingress, and "loop1" for egress. This - * allows an app to sit between the actual link and linux, passing - * (some) packets along to linux, and forwarding (some) packets sent - * out by linux. - */ -module_param_named(loopify, loopify_link_name, charp, 0444); -MODULE_PARM_DESC(loopify, "name the device to use loop0/1 for ingress/egress"); - -/* The "tile_net.custom" argument causes us to ignore the "conventional" - * classifier metadata, in particular, the "l2_offset". - */ -module_param_named(custom, custom_str, charp, 0444); -MODULE_PARM_DESC(custom, "indicates a (heavily) customized classifier"); - -/* Atomically update a statistics field. - * Note that on TILE-Gx, this operation is fire-and-forget on the - * issuing core (single-cycle dispatch) and takes only a few cycles - * longer than a regular store when the request reaches the home cache. - * No expensive bus management overhead is required. - */ -static void tile_net_stats_add(unsigned long value, unsigned long *field) -{ - BUILD_BUG_ON(sizeof(atomic_long_t) != sizeof(unsigned long)); - atomic_long_add(value, (atomic_long_t *)field); -} - -/* Allocate and push a buffer. */ -static bool tile_net_provide_buffer(bool small) -{ - int stack = small ? small_buffer_stack : large_buffer_stack; - const unsigned long buffer_alignment = 128; - struct sk_buff *skb; - int len; - - len = sizeof(struct sk_buff **) + buffer_alignment; - len += (small ? BUFFER_SIZE_SMALL : BUFFER_SIZE_LARGE); - skb = dev_alloc_skb(len); - if (skb == NULL) - return false; - - /* Make room for a back-pointer to 'skb' and guarantee alignment. */ - skb_reserve(skb, sizeof(struct sk_buff **)); - skb_reserve(skb, -(long)skb->data & (buffer_alignment - 1)); - - /* Save a back-pointer to 'skb'. */ - *(struct sk_buff **)(skb->data - sizeof(struct sk_buff **)) = skb; - - /* Make sure "skb" and the back-pointer have been flushed. */ - wmb(); - - gxio_mpipe_push_buffer(&context, stack, - (void *)va_to_tile_io_addr(skb->data)); - - return true; -} - -/* Convert a raw mpipe buffer to its matching skb pointer. */ -static struct sk_buff *mpipe_buf_to_skb(void *va) -{ - /* Acquire the associated "skb". */ - struct sk_buff **skb_ptr = va - sizeof(*skb_ptr); - struct sk_buff *skb = *skb_ptr; - - /* Paranoia. */ - if (skb->data != va) { - /* Panic here since there's a reasonable chance - * that corrupt buffers means generic memory - * corruption, with unpredictable system effects. - */ - panic("Corrupt linux buffer! va=%p, skb=%p, skb->data=%p", - va, skb, skb->data); - } - - return skb; -} - -static void tile_net_pop_all_buffers(int stack) -{ - for (;;) { - tile_io_addr_t addr = - (tile_io_addr_t)gxio_mpipe_pop_buffer(&context, stack); - if (addr == 0) - break; - dev_kfree_skb_irq(mpipe_buf_to_skb(tile_io_addr_to_va(addr))); - } -} - -/* Provide linux buffers to mPIPE. */ -static void tile_net_provide_needed_buffers(void) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - - while (info->num_needed_small_buffers != 0) { - if (!tile_net_provide_buffer(true)) - goto oops; - info->num_needed_small_buffers--; - } - - while (info->num_needed_large_buffers != 0) { - if (!tile_net_provide_buffer(false)) - goto oops; - info->num_needed_large_buffers--; - } - - return; - -oops: - /* Add a description to the page allocation failure dump. */ - pr_notice("Tile %d still needs some buffers\n", info->my_cpu); -} - -static inline bool filter_packet(struct net_device *dev, void *buf) -{ - /* Filter packets received before we're up. */ - if (dev == NULL || !(dev->flags & IFF_UP)) - return true; - - /* Filter out packets that aren't for us. */ - if (!(dev->flags & IFF_PROMISC) && - !is_multicast_ether_addr(buf) && - compare_ether_addr(dev->dev_addr, buf) != 0) - return true; - - return false; -} - -static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb, - gxio_mpipe_idesc_t *idesc, unsigned long len) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - struct tile_net_priv *priv = netdev_priv(dev); - - /* Encode the actual packet length. */ - skb_put(skb, len); - - skb->protocol = eth_type_trans(skb, dev); - - /* Acknowledge "good" hardware checksums. */ - if (idesc->cs && idesc->csum_seed_val == 0xFFFF) - skb->ip_summed = CHECKSUM_UNNECESSARY; - - netif_receive_skb(skb); - - /* Update stats. */ - tile_net_stats_add(1, &priv->stats.rx_packets); - tile_net_stats_add(len, &priv->stats.rx_bytes); - - /* Need a new buffer. */ - if (idesc->size == BUFFER_SIZE_SMALL_ENUM) - info->num_needed_small_buffers++; - else - info->num_needed_large_buffers++; -} - -/* Handle a packet. Return true if "processed", false if "filtered". */ -static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - struct net_device *dev = tile_net_devs_for_channel[idesc->channel]; - uint8_t l2_offset; - void *va; - void *buf; - unsigned long len; - bool filter; - - /* Drop packets for which no buffer was available. - * NOTE: This happens under heavy load. - */ - if (idesc->be) { - struct tile_net_priv *priv = netdev_priv(dev); - tile_net_stats_add(1, &priv->stats.rx_dropped); - gxio_mpipe_iqueue_consume(&info->iqueue, idesc); - if (net_ratelimit()) - pr_info("Dropping packet (insufficient buffers).\n"); - return false; - } - - /* Get the "l2_offset", if allowed. */ - l2_offset = custom_str ? 0 : gxio_mpipe_idesc_get_l2_offset(idesc); - - /* Get the raw buffer VA (includes "headroom"). */ - va = tile_io_addr_to_va((unsigned long)(long)idesc->va); - - /* Get the actual packet start/length. */ - buf = va + l2_offset; - len = idesc->l2_size - l2_offset; - - /* Point "va" at the raw buffer. */ - va -= NET_IP_ALIGN; - - filter = filter_packet(dev, buf); - if (filter) { - gxio_mpipe_iqueue_drop(&info->iqueue, idesc); - } else { - struct sk_buff *skb = mpipe_buf_to_skb(va); - - /* Skip headroom, and any custom header. */ - skb_reserve(skb, NET_IP_ALIGN + l2_offset); - - tile_net_receive_skb(dev, skb, idesc, len); - } - - gxio_mpipe_iqueue_consume(&info->iqueue, idesc); - return !filter; -} - -/* Handle some packets for the current CPU. - * - * This function handles up to TILE_NET_BATCH idescs per call. - * - * ISSUE: Since we do not provide new buffers until this function is - * complete, we must initially provide enough buffers for each network - * cpu to fill its iqueue and also its batched idescs. - * - * ISSUE: The "rotting packet" race condition occurs if a packet - * arrives after the queue appears to be empty, and before the - * hypervisor interrupt is re-enabled. - */ -static int tile_net_poll(struct napi_struct *napi, int budget) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - unsigned int work = 0; - gxio_mpipe_idesc_t *idesc; - int i, n; - - /* Process packets. */ - while ((n = gxio_mpipe_iqueue_try_peek(&info->iqueue, &idesc)) > 0) { - for (i = 0; i < n; i++) { - if (i == TILE_NET_BATCH) - goto done; - if (tile_net_handle_packet(idesc + i)) { - if (++work >= budget) - goto done; - } - } - } - - /* There are no packets left. */ - napi_complete(&info->napi); - - /* Re-enable hypervisor interrupts. */ - gxio_mpipe_enable_notif_ring_interrupt(&context, info->iqueue.ring); - - /* HACK: Avoid the "rotting packet" problem. */ - if (gxio_mpipe_iqueue_try_peek(&info->iqueue, &idesc) > 0) - napi_schedule(&info->napi); - - /* ISSUE: Handle completions? */ - -done: - tile_net_provide_needed_buffers(); - - return work; -} - -/* Handle an ingress interrupt on the current cpu. */ -static irqreturn_t tile_net_handle_ingress_irq(int irq, void *unused) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - napi_schedule(&info->napi); - return IRQ_HANDLED; -} - -/* Free some completions. This must be called with interrupts blocked. */ -static int tile_net_free_comps(gxio_mpipe_equeue_t *equeue, - struct tile_net_comps *comps, - int limit, bool force_update) -{ - int n = 0; - while (comps->comp_last < comps->comp_next) { - unsigned int cid = comps->comp_last % TILE_NET_MAX_COMPS; - struct tile_net_comp *comp = &comps->comp_queue[cid]; - if (!gxio_mpipe_equeue_is_complete(equeue, comp->when, - force_update || n == 0)) - break; - dev_kfree_skb_irq(comp->skb); - comps->comp_last++; - if (++n == limit) - break; - } - return n; -} - -/* Add a completion. This must be called with interrupts blocked. - * tile_net_equeue_try_reserve() will have ensured a free completion entry. - */ -static void add_comp(gxio_mpipe_equeue_t *equeue, - struct tile_net_comps *comps, - uint64_t when, struct sk_buff *skb) -{ - int cid = comps->comp_next % TILE_NET_MAX_COMPS; - comps->comp_queue[cid].when = when; - comps->comp_queue[cid].skb = skb; - comps->comp_next++; -} - -static void tile_net_schedule_tx_wake_timer(struct net_device *dev) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - struct tile_net_priv *priv = netdev_priv(dev); - - hrtimer_start(&info->tx_wake[priv->echannel].timer, - ktime_set(0, TX_TIMER_DELAY_USEC * 1000UL), - HRTIMER_MODE_REL_PINNED); -} - -static enum hrtimer_restart tile_net_handle_tx_wake_timer(struct hrtimer *t) -{ - struct tile_net_tx_wake *tx_wake = - container_of(t, struct tile_net_tx_wake, timer); - netif_wake_subqueue(tx_wake->dev, smp_processor_id()); - return HRTIMER_NORESTART; -} - -/* Make sure the egress timer is scheduled. */ -static void tile_net_schedule_egress_timer(void) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - - if (!info->egress_timer_scheduled) { - hrtimer_start(&info->egress_timer, - ktime_set(0, EGRESS_TIMER_DELAY_USEC * 1000UL), - HRTIMER_MODE_REL_PINNED); - info->egress_timer_scheduled = true; - } -} - -/* The "function" for "info->egress_timer". - * - * This timer will reschedule itself as long as there are any pending - * completions expected for this tile. - */ -static enum hrtimer_restart tile_net_handle_egress_timer(struct hrtimer *t) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - unsigned long irqflags; - bool pending = false; - int i; - - local_irq_save(irqflags); - - /* The timer is no longer scheduled. */ - info->egress_timer_scheduled = false; - - /* Free all possible comps for this tile. */ - for (i = 0; i < TILE_NET_CHANNELS; i++) { - struct tile_net_egress *egress = &egress_for_echannel[i]; - struct tile_net_comps *comps = info->comps_for_echannel[i]; - if (comps->comp_last >= comps->comp_next) - continue; - tile_net_free_comps(egress->equeue, comps, -1, true); - pending = pending || (comps->comp_last < comps->comp_next); - } - - /* Reschedule timer if needed. */ - if (pending) - tile_net_schedule_egress_timer(); - - local_irq_restore(irqflags); - - return HRTIMER_NORESTART; -} - -/* Helper function for "tile_net_update()". - * "dev" (i.e. arg) is the device being brought up or down, - * or NULL if all devices are now down. - */ -static void tile_net_update_cpu(void *arg) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - struct net_device *dev = arg; - - if (!info->has_iqueue) - return; - - if (dev != NULL) { - if (!info->napi_added) { - netif_napi_add(dev, &info->napi, - tile_net_poll, TILE_NET_WEIGHT); - info->napi_added = true; - } - if (!info->napi_enabled) { - napi_enable(&info->napi); - info->napi_enabled = true; - } - enable_percpu_irq(ingress_irq, 0); - } else { - disable_percpu_irq(ingress_irq); - if (info->napi_enabled) { - napi_disable(&info->napi); - info->napi_enabled = false; - } - /* FIXME: Drain the iqueue. */ - } -} - -/* Helper function for tile_net_open() and tile_net_stop(). - * Always called under tile_net_devs_for_channel_mutex. - */ -static int tile_net_update(struct net_device *dev) -{ - static gxio_mpipe_rules_t rules; /* too big to fit on the stack */ - bool saw_channel = false; - int channel; - int rc; - int cpu; - - gxio_mpipe_rules_init(&rules, &context); - - for (channel = 0; channel < TILE_NET_CHANNELS; channel++) { - if (tile_net_devs_for_channel[channel] == NULL) - continue; - if (!saw_channel) { - saw_channel = true; - gxio_mpipe_rules_begin(&rules, first_bucket, - num_buckets, NULL); - gxio_mpipe_rules_set_headroom(&rules, NET_IP_ALIGN); - } - gxio_mpipe_rules_add_channel(&rules, channel); - } - - /* NOTE: This can fail if there is no classifier. - * ISSUE: Can anything else cause it to fail? - */ - rc = gxio_mpipe_rules_commit(&rules); - if (rc != 0) { - netdev_warn(dev, "gxio_mpipe_rules_commit failed: %d\n", rc); - return -EIO; - } - - /* Update all cpus, sequentially (to protect "netif_napi_add()"). */ - for_each_online_cpu(cpu) - smp_call_function_single(cpu, tile_net_update_cpu, - (saw_channel ? dev : NULL), 1); - - /* HACK: Allow packets to flow in the simulator. */ - if (saw_channel) - sim_enable_mpipe_links(0, -1); - - return 0; -} - -/* Allocate and initialize mpipe buffer stacks, and register them in - * the mPIPE TLBs, for both small and large packet sizes. - * This routine supports tile_net_init_mpipe(), below. - */ -static int init_buffer_stacks(struct net_device *dev, int num_buffers) -{ - pte_t hash_pte = pte_set_home((pte_t) { 0 }, PAGE_HOME_HASH); - int rc; - - /* Compute stack bytes; we round up to 64KB and then use - * alloc_pages() so we get the required 64KB alignment as well. - */ - buffer_stack_size = - ALIGN(gxio_mpipe_calc_buffer_stack_bytes(num_buffers), - 64 * 1024); - - /* Allocate two buffer stack indices. */ - rc = gxio_mpipe_alloc_buffer_stacks(&context, 2, 0, 0); - if (rc < 0) { - netdev_err(dev, "gxio_mpipe_alloc_buffer_stacks failed: %d\n", - rc); - return rc; - } - small_buffer_stack = rc; - large_buffer_stack = rc + 1; - - /* Allocate the small memory stack. */ - small_buffer_stack_va = - alloc_pages_exact(buffer_stack_size, GFP_KERNEL); - if (small_buffer_stack_va == NULL) { - netdev_err(dev, - "Could not alloc %zd bytes for buffer stacks\n", - buffer_stack_size); - return -ENOMEM; - } - rc = gxio_mpipe_init_buffer_stack(&context, small_buffer_stack, - BUFFER_SIZE_SMALL_ENUM, - small_buffer_stack_va, - buffer_stack_size, 0); - if (rc != 0) { - netdev_err(dev, "gxio_mpipe_init_buffer_stack: %d\n", rc); - return rc; - } - rc = gxio_mpipe_register_client_memory(&context, small_buffer_stack, - hash_pte, 0); - if (rc != 0) { - netdev_err(dev, - "gxio_mpipe_register_buffer_memory failed: %d\n", - rc); - return rc; - } - - /* Allocate the large buffer stack. */ - large_buffer_stack_va = - alloc_pages_exact(buffer_stack_size, GFP_KERNEL); - if (large_buffer_stack_va == NULL) { - netdev_err(dev, - "Could not alloc %zd bytes for buffer stacks\n", - buffer_stack_size); - return -ENOMEM; - } - rc = gxio_mpipe_init_buffer_stack(&context, large_buffer_stack, - BUFFER_SIZE_LARGE_ENUM, - large_buffer_stack_va, - buffer_stack_size, 0); - if (rc != 0) { - netdev_err(dev, "gxio_mpipe_init_buffer_stack failed: %d\n", - rc); - return rc; - } - rc = gxio_mpipe_register_client_memory(&context, large_buffer_stack, - hash_pte, 0); - if (rc != 0) { - netdev_err(dev, - "gxio_mpipe_register_buffer_memory failed: %d\n", - rc); - return rc; - } - - return 0; -} - -/* Allocate per-cpu resources (memory for completions and idescs). - * This routine supports tile_net_init_mpipe(), below. - */ -static int alloc_percpu_mpipe_resources(struct net_device *dev, - int cpu, int ring) -{ - struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); - int order, i, rc; - struct page *page; - void *addr; - - /* Allocate the "comps". */ - order = get_order(COMPS_SIZE); - page = homecache_alloc_pages(GFP_KERNEL, order, cpu); - if (page == NULL) { - netdev_err(dev, "Failed to alloc %zd bytes comps memory\n", - COMPS_SIZE); - return -ENOMEM; - } - addr = pfn_to_kaddr(page_to_pfn(page)); - memset(addr, 0, COMPS_SIZE); - for (i = 0; i < TILE_NET_CHANNELS; i++) - info->comps_for_echannel[i] = - addr + i * sizeof(struct tile_net_comps); - - /* If this is a network cpu, create an iqueue. */ - if (cpu_isset(cpu, network_cpus_map)) { - order = get_order(NOTIF_RING_SIZE); - page = homecache_alloc_pages(GFP_KERNEL, order, cpu); - if (page == NULL) { - netdev_err(dev, - "Failed to alloc %zd bytes iqueue memory\n", - NOTIF_RING_SIZE); - return -ENOMEM; - } - addr = pfn_to_kaddr(page_to_pfn(page)); - rc = gxio_mpipe_iqueue_init(&info->iqueue, &context, ring++, - addr, NOTIF_RING_SIZE, 0); - if (rc < 0) { - netdev_err(dev, - "gxio_mpipe_iqueue_init failed: %d\n", rc); - return rc; - } - info->has_iqueue = true; - } - - return ring; -} - -/* Initialize NotifGroup and buckets. - * This routine supports tile_net_init_mpipe(), below. - */ -static int init_notif_group_and_buckets(struct net_device *dev, - int ring, int network_cpus_count) -{ - int group, rc; - - /* Allocate one NotifGroup. */ - rc = gxio_mpipe_alloc_notif_groups(&context, 1, 0, 0); - if (rc < 0) { - netdev_err(dev, "gxio_mpipe_alloc_notif_groups failed: %d\n", - rc); - return rc; - } - group = rc; - - /* Initialize global num_buckets value. */ - if (network_cpus_count > 4) - num_buckets = 256; - else if (network_cpus_count > 1) - num_buckets = 16; - - /* Allocate some buckets, and set global first_bucket value. */ - rc = gxio_mpipe_alloc_buckets(&context, num_buckets, 0, 0); - if (rc < 0) { - netdev_err(dev, "gxio_mpipe_alloc_buckets failed: %d\n", rc); - return rc; - } - first_bucket = rc; - - /* Init group and buckets. */ - rc = gxio_mpipe_init_notif_group_and_buckets( - &context, group, ring, network_cpus_count, - first_bucket, num_buckets, - GXIO_MPIPE_BUCKET_STICKY_FLOW_LOCALITY); - if (rc != 0) { - netdev_err( - dev, - "gxio_mpipe_init_notif_group_and_buckets failed: %d\n", - rc); - return rc; - } - - return 0; -} - -/* Create an irq and register it, then activate the irq and request - * interrupts on all cores. Note that "ingress_irq" being initialized - * is how we know not to call tile_net_init_mpipe() again. - * This routine supports tile_net_init_mpipe(), below. - */ -static int tile_net_setup_interrupts(struct net_device *dev) -{ - int cpu, rc; - - rc = create_irq(); - if (rc < 0) { - netdev_err(dev, "create_irq failed: %d\n", rc); - return rc; - } - ingress_irq = rc; - tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); - rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, - 0, NULL, NULL); - if (rc != 0) { - netdev_err(dev, "request_irq failed: %d\n", rc); - destroy_irq(ingress_irq); - ingress_irq = -1; - return rc; - } - - for_each_online_cpu(cpu) { - struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); - if (info->has_iqueue) { - gxio_mpipe_request_notif_ring_interrupt( - &context, cpu_x(cpu), cpu_y(cpu), - 1, ingress_irq, info->iqueue.ring); - } - } - - return 0; -} - -/* Undo any state set up partially by a failed call to tile_net_init_mpipe. */ -static void tile_net_init_mpipe_fail(void) -{ - int cpu; - - /* Do cleanups that require the mpipe context first. */ - if (small_buffer_stack >= 0) - tile_net_pop_all_buffers(small_buffer_stack); - if (large_buffer_stack >= 0) - tile_net_pop_all_buffers(large_buffer_stack); - - /* Destroy mpipe context so the hardware no longer owns any memory. */ - gxio_mpipe_destroy(&context); - - for_each_online_cpu(cpu) { - struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); - free_pages((unsigned long)(info->comps_for_echannel[0]), - get_order(COMPS_SIZE)); - info->comps_for_echannel[0] = NULL; - free_pages((unsigned long)(info->iqueue.idescs), - get_order(NOTIF_RING_SIZE)); - info->iqueue.idescs = NULL; - } - - if (small_buffer_stack_va) - free_pages_exact(small_buffer_stack_va, buffer_stack_size); - if (large_buffer_stack_va) - free_pages_exact(large_buffer_stack_va, buffer_stack_size); - - small_buffer_stack_va = NULL; - large_buffer_stack_va = NULL; - large_buffer_stack = -1; - small_buffer_stack = -1; - first_bucket = -1; -} - -/* The first time any tilegx network device is opened, we initialize - * the global mpipe state. If this step fails, we fail to open the - * device, but if it succeeds, we never need to do it again, and since - * tile_net can't be unloaded, we never undo it. - * - * Note that some resources in this path (buffer stack indices, - * bindings from init_buffer_stack, etc.) are hypervisor resources - * that are freed implicitly by gxio_mpipe_destroy(). - */ -static int tile_net_init_mpipe(struct net_device *dev) -{ - int i, num_buffers, rc; - int cpu; - int first_ring, ring; - int network_cpus_count = cpus_weight(network_cpus_map); - - if (!hash_default) { - netdev_err(dev, "Networking requires hash_default!\n"); - return -EIO; - } - - rc = gxio_mpipe_init(&context, 0); - if (rc != 0) { - netdev_err(dev, "gxio_mpipe_init failed: %d\n", rc); - return -EIO; - } - - /* Set up the buffer stacks. */ - num_buffers = - network_cpus_count * (IQUEUE_ENTRIES + TILE_NET_BATCH); - rc = init_buffer_stacks(dev, num_buffers); - if (rc != 0) - goto fail; - - /* Provide initial buffers. */ - rc = -ENOMEM; - for (i = 0; i < num_buffers; i++) { - if (!tile_net_provide_buffer(true)) { - netdev_err(dev, "Cannot allocate initial sk_bufs!\n"); - goto fail; - } - } - for (i = 0; i < num_buffers; i++) { - if (!tile_net_provide_buffer(false)) { - netdev_err(dev, "Cannot allocate initial sk_bufs!\n"); - goto fail; - } - } - - /* Allocate one NotifRing for each network cpu. */ - rc = gxio_mpipe_alloc_notif_rings(&context, network_cpus_count, 0, 0); - if (rc < 0) { - netdev_err(dev, "gxio_mpipe_alloc_notif_rings failed %d\n", - rc); - goto fail; - } - - /* Init NotifRings per-cpu. */ - first_ring = rc; - ring = first_ring; - for_each_online_cpu(cpu) { - rc = alloc_percpu_mpipe_resources(dev, cpu, ring); - if (rc < 0) - goto fail; - ring = rc; - } - - /* Initialize NotifGroup and buckets. */ - rc = init_notif_group_and_buckets(dev, first_ring, network_cpus_count); - if (rc != 0) - goto fail; - - /* Create and enable interrupts. */ - rc = tile_net_setup_interrupts(dev); - if (rc != 0) - goto fail; - - return 0; - -fail: - tile_net_init_mpipe_fail(); - return rc; -} - -/* Create persistent egress info for a given egress channel. - * Note that this may be shared between, say, "gbe0" and "xgbe0". - * ISSUE: Defer header allocation until TSO is actually needed? - */ -static int tile_net_init_egress(struct net_device *dev, int echannel) -{ - struct page *headers_page, *edescs_page, *equeue_page; - gxio_mpipe_edesc_t *edescs; - gxio_mpipe_equeue_t *equeue; - unsigned char *headers; - int headers_order, edescs_order, equeue_order; - size_t edescs_size; - int edma; - int rc = -ENOMEM; - - /* Only initialize once. */ - if (egress_for_echannel[echannel].equeue != NULL) - return 0; - - /* Allocate memory for the "headers". */ - headers_order = get_order(EQUEUE_ENTRIES * HEADER_BYTES); - headers_page = alloc_pages(GFP_KERNEL, headers_order); - if (headers_page == NULL) { - netdev_warn(dev, - "Could not alloc %zd bytes for TSO headers.\n", - PAGE_SIZE << headers_order); - goto fail; - } - headers = pfn_to_kaddr(page_to_pfn(headers_page)); - - /* Allocate memory for the "edescs". */ - edescs_size = EQUEUE_ENTRIES * sizeof(*edescs); - edescs_order = get_order(edescs_size); - edescs_page = alloc_pages(GFP_KERNEL, edescs_order); - if (edescs_page == NULL) { - netdev_warn(dev, - "Could not alloc %zd bytes for eDMA ring.\n", - edescs_size); - goto fail_headers; - } - edescs = pfn_to_kaddr(page_to_pfn(edescs_page)); - - /* Allocate memory for the "equeue". */ - equeue_order = get_order(sizeof(*equeue)); - equeue_page = alloc_pages(GFP_KERNEL, equeue_order); - if (equeue_page == NULL) { - netdev_warn(dev, - "Could not alloc %zd bytes for equeue info.\n", - PAGE_SIZE << equeue_order); - goto fail_edescs; - } - equeue = pfn_to_kaddr(page_to_pfn(equeue_page)); - - /* Allocate an edma ring. Note that in practice this can't - * fail, which is good, because we will leak an edma ring if so. - */ - rc = gxio_mpipe_alloc_edma_rings(&context, 1, 0, 0); - if (rc < 0) { - netdev_warn(dev, "gxio_mpipe_alloc_edma_rings failed: %d\n", - rc); - goto fail_equeue; - } - edma = rc; - - /* Initialize the equeue. */ - rc = gxio_mpipe_equeue_init(equeue, &context, edma, echannel, - edescs, edescs_size, 0); - if (rc != 0) { - netdev_err(dev, "gxio_mpipe_equeue_init failed: %d\n", rc); - goto fail_equeue; - } - - /* Done. */ - egress_for_echannel[echannel].equeue = equeue; - egress_for_echannel[echannel].headers = headers; - return 0; - -fail_equeue: - __free_pages(equeue_page, equeue_order); - -fail_edescs: - __free_pages(edescs_page, edescs_order); - -fail_headers: - __free_pages(headers_page, headers_order); - -fail: - return rc; -} - -/* Return channel number for a newly-opened link. */ -static int tile_net_link_open(struct net_device *dev, gxio_mpipe_link_t *link, - const char *link_name) -{ - int rc = gxio_mpipe_link_open(link, &context, link_name, 0); - if (rc < 0) { - netdev_err(dev, "Failed to open '%s'\n", link_name); - return rc; - } - rc = gxio_mpipe_link_channel(link); - if (rc < 0 || rc >= TILE_NET_CHANNELS) { - netdev_err(dev, "gxio_mpipe_link_channel bad value: %d\n", rc); - gxio_mpipe_link_close(link); - return -EINVAL; - } - return rc; -} - -/* Help the kernel activate the given network interface. */ -static int tile_net_open(struct net_device *dev) -{ - struct tile_net_priv *priv = netdev_priv(dev); - int cpu, rc; - - mutex_lock(&tile_net_devs_for_channel_mutex); - - /* Do one-time initialization the first time any device is opened. */ - if (ingress_irq < 0) { - rc = tile_net_init_mpipe(dev); - if (rc != 0) - goto fail; - } - - /* Determine if this is the "loopify" device. */ - if (unlikely((loopify_link_name != NULL) && - !strcmp(dev->name, loopify_link_name))) { - rc = tile_net_link_open(dev, &priv->link, "loop0"); - if (rc < 0) - goto fail; - priv->channel = rc; - rc = tile_net_link_open(dev, &priv->loopify_link, "loop1"); - if (rc < 0) - goto fail; - priv->loopify_channel = rc; - priv->echannel = rc; - } else { - rc = tile_net_link_open(dev, &priv->link, dev->name); - if (rc < 0) - goto fail; - priv->channel = rc; - priv->echannel = rc; - } - - /* Initialize egress info (if needed). Once ever, per echannel. */ - rc = tile_net_init_egress(dev, priv->echannel); - if (rc != 0) - goto fail; - - tile_net_devs_for_channel[priv->channel] = dev; - - rc = tile_net_update(dev); - if (rc != 0) - goto fail; - - mutex_unlock(&tile_net_devs_for_channel_mutex); - - /* Initialize the transmit wake timer for this device for each cpu. */ - for_each_online_cpu(cpu) { - struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); - struct tile_net_tx_wake *tx_wake = - &info->tx_wake[priv->echannel]; - - hrtimer_init(&tx_wake->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - tx_wake->timer.function = tile_net_handle_tx_wake_timer; - tx_wake->dev = dev; - } - - for_each_online_cpu(cpu) - netif_start_subqueue(dev, cpu); - netif_carrier_on(dev); - return 0; - -fail: - if (priv->loopify_channel >= 0) { - if (gxio_mpipe_link_close(&priv->loopify_link) != 0) - netdev_warn(dev, "Failed to close loopify link!\n"); - priv->loopify_channel = -1; - } - if (priv->channel >= 0) { - if (gxio_mpipe_link_close(&priv->link) != 0) - netdev_warn(dev, "Failed to close link!\n"); - priv->channel = -1; - } - priv->echannel = -1; - tile_net_devs_for_channel[priv->channel] = NULL; - mutex_unlock(&tile_net_devs_for_channel_mutex); - - /* Don't return raw gxio error codes to generic Linux. */ - return (rc > -512) ? rc : -EIO; -} - -/* Help the kernel deactivate the given network interface. */ -static int tile_net_stop(struct net_device *dev) -{ - struct tile_net_priv *priv = netdev_priv(dev); - int cpu; - - for_each_online_cpu(cpu) { - struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); - struct tile_net_tx_wake *tx_wake = - &info->tx_wake[priv->echannel]; - - hrtimer_cancel(&tx_wake->timer); - netif_stop_subqueue(dev, cpu); - } - - mutex_lock(&tile_net_devs_for_channel_mutex); - tile_net_devs_for_channel[priv->channel] = NULL; - (void)tile_net_update(dev); - if (priv->loopify_channel >= 0) { - if (gxio_mpipe_link_close(&priv->loopify_link) != 0) - netdev_warn(dev, "Failed to close loopify link!\n"); - priv->loopify_channel = -1; - } - if (priv->channel >= 0) { - if (gxio_mpipe_link_close(&priv->link) != 0) - netdev_warn(dev, "Failed to close link!\n"); - priv->channel = -1; - } - priv->echannel = -1; - mutex_unlock(&tile_net_devs_for_channel_mutex); - - return 0; -} - -/* Determine the VA for a fragment. */ -static inline void *tile_net_frag_buf(skb_frag_t *f) -{ - unsigned long pfn = page_to_pfn(skb_frag_page(f)); - return pfn_to_kaddr(pfn) + f->page_offset; -} - -/* Acquire a completion entry and an egress slot, or if we can't, - * stop the queue and schedule the tx_wake timer. - */ -static s64 tile_net_equeue_try_reserve(struct net_device *dev, - struct tile_net_comps *comps, - gxio_mpipe_equeue_t *equeue, - int num_edescs) -{ - /* Try to acquire a completion entry. */ - if (comps->comp_next - comps->comp_last < TILE_NET_MAX_COMPS - 1 || - tile_net_free_comps(equeue, comps, 32, false) != 0) { - - /* Try to acquire an egress slot. */ - s64 slot = gxio_mpipe_equeue_try_reserve(equeue, num_edescs); - if (slot >= 0) - return slot; - - /* Freeing some completions gives the equeue time to drain. */ - tile_net_free_comps(equeue, comps, TILE_NET_MAX_COMPS, false); - - slot = gxio_mpipe_equeue_try_reserve(equeue, num_edescs); - if (slot >= 0) - return slot; - } - - /* Still nothing; give up and stop the queue for a short while. */ - netif_stop_subqueue(dev, smp_processor_id()); - tile_net_schedule_tx_wake_timer(dev); - return -1; -} - -/* Determine how many edesc's are needed for TSO. - * - * Sometimes, if "sendfile()" requires copying, we will be called with - * "data" containing the header and payload, with "frags" being empty. - * Sometimes, for example when using NFS over TCP, a single segment can - * span 3 fragments. This requires special care. - */ -static int tso_count_edescs(struct sk_buff *skb) -{ - struct skb_shared_info *sh = skb_shinfo(skb); - unsigned int data_len = skb->data_len; - unsigned int p_len = sh->gso_size; - long f_id = -1; /* id of the current fragment */ - long f_size = -1; /* size of the current fragment */ - long f_used = -1; /* bytes used from the current fragment */ - long n; /* size of the current piece of payload */ - int num_edescs = 0; - int segment; - - for (segment = 0; segment < sh->gso_segs; segment++) { - - unsigned int p_used = 0; - - /* One edesc for header and for each piece of the payload. */ - for (num_edescs++; p_used < p_len; num_edescs++) { - - /* Advance as needed. */ - while (f_used >= f_size) { - f_id++; - f_size = sh->frags[f_id].size; - f_used = 0; - } - - /* Use bytes from the current fragment. */ - n = p_len - p_used; - if (n > f_size - f_used) - n = f_size - f_used; - f_used += n; - p_used += n; - } - - /* The last segment may be less than gso_size. */ - data_len -= p_len; - if (data_len < p_len) - p_len = data_len; - } - - return num_edescs; -} - -/* Prepare modified copies of the skbuff headers. - * FIXME: add support for IPv6. - */ -static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, - s64 slot) -{ - struct skb_shared_info *sh = skb_shinfo(skb); - struct iphdr *ih; - struct tcphdr *th; - unsigned int data_len = skb->data_len; - unsigned char *data = skb->data; - unsigned int ih_off, th_off, sh_len, p_len; - unsigned int isum_seed, tsum_seed, id, seq; - long f_id = -1; /* id of the current fragment */ - long f_size = -1; /* size of the current fragment */ - long f_used = -1; /* bytes used from the current fragment */ - long n; /* size of the current piece of payload */ - int segment; - - /* Locate original headers and compute various lengths. */ - ih = ip_hdr(skb); - th = tcp_hdr(skb); - ih_off = skb_network_offset(skb); - th_off = skb_transport_offset(skb); - sh_len = th_off + tcp_hdrlen(skb); - p_len = sh->gso_size; - - /* Set up seed values for IP and TCP csum and initialize id and seq. */ - isum_seed = ((0xFFFF - ih->check) + - (0xFFFF - ih->tot_len) + - (0xFFFF - ih->id)); - tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); - id = ntohs(ih->id); - seq = ntohl(th->seq); - - /* Prepare all the headers. */ - for (segment = 0; segment < sh->gso_segs; segment++) { - unsigned char *buf; - unsigned int p_used = 0; - - /* Copy to the header memory for this segment. */ - buf = headers + (slot % EQUEUE_ENTRIES) * HEADER_BYTES + - NET_IP_ALIGN; - memcpy(buf, data, sh_len); - - /* Update copied ip header. */ - ih = (struct iphdr *)(buf + ih_off); - ih->tot_len = htons(sh_len + p_len - ih_off); - ih->id = htons(id); - ih->check = csum_long(isum_seed + ih->tot_len + - ih->id) ^ 0xffff; - - /* Update copied tcp header. */ - th = (struct tcphdr *)(buf + th_off); - th->seq = htonl(seq); - th->check = csum_long(tsum_seed + htons(sh_len + p_len)); - if (segment != sh->gso_segs - 1) { - th->fin = 0; - th->psh = 0; - } - - /* Skip past the header. */ - slot++; - - /* Skip past the payload. */ - while (p_used < p_len) { - - /* Advance as needed. */ - while (f_used >= f_size) { - f_id++; - f_size = sh->frags[f_id].size; - f_used = 0; - } - - /* Use bytes from the current fragment. */ - n = p_len - p_used; - if (n > f_size - f_used) - n = f_size - f_used; - f_used += n; - p_used += n; - - slot++; - } - - id++; - seq += p_len; - - /* The last segment may be less than gso_size. */ - data_len -= p_len; - if (data_len < p_len) - p_len = data_len; - } - - /* Flush the headers so they are ready for hardware DMA. */ - wmb(); -} - -/* Pass all the data to mpipe for egress. */ -static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, - struct sk_buff *skb, unsigned char *headers, s64 slot) -{ - struct tile_net_priv *priv = netdev_priv(dev); - struct skb_shared_info *sh = skb_shinfo(skb); - unsigned int data_len = skb->data_len; - unsigned int p_len = sh->gso_size; - gxio_mpipe_edesc_t edesc_head = { { 0 } }; - gxio_mpipe_edesc_t edesc_body = { { 0 } }; - long f_id = -1; /* id of the current fragment */ - long f_size = -1; /* size of the current fragment */ - long f_used = -1; /* bytes used from the current fragment */ - long n; /* size of the current piece of payload */ - unsigned long tx_packets = 0, tx_bytes = 0; - unsigned int csum_start, sh_len; - int segment; - - /* Prepare to egress the headers: set up header edesc. */ - csum_start = skb_checksum_start_offset(skb); - sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - edesc_head.csum = 1; - edesc_head.csum_start = csum_start; - edesc_head.csum_dest = csum_start + skb->csum_offset; - edesc_head.xfer_size = sh_len; - - /* This is only used to specify the TLB. */ - edesc_head.stack_idx = large_buffer_stack; - edesc_body.stack_idx = large_buffer_stack; - - /* Egress all the edescs. */ - for (segment = 0; segment < sh->gso_segs; segment++) { - void *va; - unsigned char *buf; - unsigned int p_used = 0; - - /* Egress the header. */ - buf = headers + (slot % EQUEUE_ENTRIES) * HEADER_BYTES + - NET_IP_ALIGN; - edesc_head.va = va_to_tile_io_addr(buf); - gxio_mpipe_equeue_put_at(equeue, edesc_head, slot); - slot++; - - /* Egress the payload. */ - while (p_used < p_len) { - - /* Advance as needed. */ - while (f_used >= f_size) { - f_id++; - f_size = sh->frags[f_id].size; - f_used = 0; - } - - va = tile_net_frag_buf(&sh->frags[f_id]) + f_used; - - /* Use bytes from the current fragment. */ - n = p_len - p_used; - if (n > f_size - f_used) - n = f_size - f_used; - f_used += n; - p_used += n; - - /* Egress a piece of the payload. */ - edesc_body.va = va_to_tile_io_addr(va); - edesc_body.xfer_size = n; - edesc_body.bound = !(p_used < p_len); - gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); - slot++; - } - - tx_packets++; - tx_bytes += sh_len + p_len; - - /* The last segment may be less than gso_size. */ - data_len -= p_len; - if (data_len < p_len) - p_len = data_len; - } - - /* Update stats. */ - tile_net_stats_add(tx_packets, &priv->stats.tx_packets); - tile_net_stats_add(tx_bytes, &priv->stats.tx_bytes); -} - -/* Do "TSO" handling for egress. - * - * Normally drivers set NETIF_F_TSO only to support hardware TSO; - * otherwise the stack uses scatter-gather to implement GSO in software. - * On our testing, enabling GSO support (via NETIF_F_SG) drops network - * performance down to around 7.5 Gbps on the 10G interfaces, although - * also dropping cpu utilization way down, to under 8%. But - * implementing "TSO" in the driver brings performance back up to line - * rate, while dropping cpu usage even further, to less than 4%. In - * practice, profiling of GSO shows that skb_segment() is what causes - * the performance overheads; we benefit in the driver from using - * preallocated memory to duplicate the TCP/IP headers. - */ -static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - struct tile_net_priv *priv = netdev_priv(dev); - int channel = priv->echannel; - struct tile_net_egress *egress = &egress_for_echannel[channel]; - struct tile_net_comps *comps = info->comps_for_echannel[channel]; - gxio_mpipe_equeue_t *equeue = egress->equeue; - unsigned long irqflags; - int num_edescs; - s64 slot; - - /* Determine how many mpipe edesc's are needed. */ - num_edescs = tso_count_edescs(skb); - - local_irq_save(irqflags); - - /* Try to acquire a completion entry and an egress slot. */ - slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs); - if (slot < 0) { - local_irq_restore(irqflags); - return NETDEV_TX_BUSY; - } - - /* Set up copies of header data properly. */ - tso_headers_prepare(skb, egress->headers, slot); - - /* Actually pass the data to the network hardware. */ - tso_egress(dev, equeue, skb, egress->headers, slot); - - /* Add a completion record. */ - add_comp(equeue, comps, slot + num_edescs - 1, skb); - - local_irq_restore(irqflags); - - /* Make sure the egress timer is scheduled. */ - tile_net_schedule_egress_timer(); - - return NETDEV_TX_OK; -} - -/* Analyze the body and frags for a transmit request. */ -static unsigned int tile_net_tx_frags(struct frag *frags, - struct sk_buff *skb, - void *b_data, unsigned int b_len) -{ - unsigned int i, n = 0; - - struct skb_shared_info *sh = skb_shinfo(skb); - - if (b_len != 0) { - frags[n].buf = b_data; - frags[n++].length = b_len; - } - - for (i = 0; i < sh->nr_frags; i++) { - skb_frag_t *f = &sh->frags[i]; - frags[n].buf = tile_net_frag_buf(f); - frags[n++].length = skb_frag_size(f); - } - - return n; -} - -/* Help the kernel transmit a packet. */ -static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - struct tile_net_priv *priv = netdev_priv(dev); - struct tile_net_egress *egress = &egress_for_echannel[priv->echannel]; - gxio_mpipe_equeue_t *equeue = egress->equeue; - struct tile_net_comps *comps = - info->comps_for_echannel[priv->echannel]; - unsigned int len = skb->len; - unsigned char *data = skb->data; - unsigned int num_edescs; - struct frag frags[MAX_FRAGS]; - gxio_mpipe_edesc_t edescs[MAX_FRAGS]; - unsigned long irqflags; - gxio_mpipe_edesc_t edesc = { { 0 } }; - unsigned int i; - s64 slot; - - if (skb_is_gso(skb)) - return tile_net_tx_tso(skb, dev); - - num_edescs = tile_net_tx_frags(frags, skb, data, skb_headlen(skb)); - - /* This is only used to specify the TLB. */ - edesc.stack_idx = large_buffer_stack; - - /* Prepare the edescs. */ - for (i = 0; i < num_edescs; i++) { - edesc.xfer_size = frags[i].length; - edesc.va = va_to_tile_io_addr(frags[i].buf); - edescs[i] = edesc; - } - - /* Mark the final edesc. */ - edescs[num_edescs - 1].bound = 1; - - /* Add checksum info to the initial edesc, if needed. */ - if (skb->ip_summed == CHECKSUM_PARTIAL) { - unsigned int csum_start = skb_checksum_start_offset(skb); - edescs[0].csum = 1; - edescs[0].csum_start = csum_start; - edescs[0].csum_dest = csum_start + skb->csum_offset; - } - - local_irq_save(irqflags); - - /* Try to acquire a completion entry and an egress slot. */ - slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs); - if (slot < 0) { - local_irq_restore(irqflags); - return NETDEV_TX_BUSY; - } - - for (i = 0; i < num_edescs; i++) - gxio_mpipe_equeue_put_at(equeue, edescs[i], slot++); - - /* Add a completion record. */ - add_comp(equeue, comps, slot - 1, skb); - - /* NOTE: Use ETH_ZLEN for short packets (e.g. 42 < 60). */ - tile_net_stats_add(1, &priv->stats.tx_packets); - tile_net_stats_add(max_t(unsigned int, len, ETH_ZLEN), - &priv->stats.tx_bytes); - - local_irq_restore(irqflags); - - /* Make sure the egress timer is scheduled. */ - tile_net_schedule_egress_timer(); - - return NETDEV_TX_OK; -} - -/* Return subqueue id on this core (one per core). */ -static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb) -{ - return smp_processor_id(); -} - -/* Deal with a transmit timeout. */ -static void tile_net_tx_timeout(struct net_device *dev) -{ - int cpu; - - for_each_online_cpu(cpu) - netif_wake_subqueue(dev, cpu); -} - -/* Ioctl commands. */ -static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - return -EOPNOTSUPP; -} - -/* Get system network statistics for device. */ -static struct net_device_stats *tile_net_get_stats(struct net_device *dev) -{ - struct tile_net_priv *priv = netdev_priv(dev); - return &priv->stats; -} - -/* Change the MTU. */ -static int tile_net_change_mtu(struct net_device *dev, int new_mtu) -{ - if ((new_mtu < 68) || (new_mtu > 1500)) - return -EINVAL; - dev->mtu = new_mtu; - return 0; -} - -/* Change the Ethernet address of the NIC. - * - * The hypervisor driver does not support changing MAC address. However, - * the hardware does not do anything with the MAC address, so the address - * which gets used on outgoing packets, and which is accepted on incoming - * packets, is completely up to us. - * - * Returns 0 on success, negative on failure. - */ -static int tile_net_set_mac_address(struct net_device *dev, void *p) -{ - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EINVAL; - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - return 0; -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -/* Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ -static void tile_net_netpoll(struct net_device *dev) -{ - disable_percpu_irq(ingress_irq); - tile_net_handle_ingress_irq(ingress_irq, NULL); - enable_percpu_irq(ingress_irq, 0); -} -#endif - -static const struct net_device_ops tile_net_ops = { - .ndo_open = tile_net_open, - .ndo_stop = tile_net_stop, - .ndo_start_xmit = tile_net_tx, - .ndo_select_queue = tile_net_select_queue, - .ndo_do_ioctl = tile_net_ioctl, - .ndo_get_stats = tile_net_get_stats, - .ndo_change_mtu = tile_net_change_mtu, - .ndo_tx_timeout = tile_net_tx_timeout, - .ndo_set_mac_address = tile_net_set_mac_address, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tile_net_netpoll, -#endif -}; - -/* The setup function. - * - * This uses ether_setup() to assign various fields in dev, including - * setting IFF_BROADCAST and IFF_MULTICAST, then sets some extra fields. - */ -static void tile_net_setup(struct net_device *dev) -{ - ether_setup(dev); - dev->netdev_ops = &tile_net_ops; - dev->watchdog_timeo = TILE_NET_TIMEOUT; - dev->features |= NETIF_F_LLTX; - dev->features |= NETIF_F_HW_CSUM; - dev->features |= NETIF_F_SG; - dev->features |= NETIF_F_TSO; - dev->mtu = 1500; -} - -/* Allocate the device structure, register the device, and obtain the - * MAC address from the hypervisor. - */ -static void tile_net_dev_init(const char *name, const uint8_t *mac) -{ - int ret; - int i; - int nz_addr = 0; - struct net_device *dev; - struct tile_net_priv *priv; - - /* HACK: Ignore "loop" links. */ - if (strncmp(name, "loop", 4) == 0) - return; - - /* Allocate the device structure. Normally, "name" is a - * template, instantiated by register_netdev(), but not for us. - */ - dev = alloc_netdev_mqs(sizeof(*priv), name, tile_net_setup, - NR_CPUS, 1); - if (!dev) { - pr_err("alloc_netdev_mqs(%s) failed\n", name); - return; - } - - /* Initialize "priv". */ - priv = netdev_priv(dev); - memset(priv, 0, sizeof(*priv)); - priv->dev = dev; - priv->channel = -1; - priv->loopify_channel = -1; - priv->echannel = -1; - - /* Get the MAC address and set it in the device struct; this must - * be done before the device is opened. If the MAC is all zeroes, - * we use a random address, since we're probably on the simulator. - */ - for (i = 0; i < 6; i++) - nz_addr |= mac[i]; - - if (nz_addr) { - memcpy(dev->dev_addr, mac, 6); - dev->addr_len = 6; - } else { - random_ether_addr(dev->dev_addr); - } - - /* Register the network device. */ - ret = register_netdev(dev); - if (ret) { - netdev_err(dev, "register_netdev failed %d\n", ret); - free_netdev(dev); - return; - } -} - -/* Per-cpu module initialization. */ -static void tile_net_init_module_percpu(void *unused) -{ - struct tile_net_info *info = &__get_cpu_var(per_cpu_info); - int my_cpu = smp_processor_id(); - - info->has_iqueue = false; - - info->my_cpu = my_cpu; - - /* Initialize the egress timer. */ - hrtimer_init(&info->egress_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - info->egress_timer.function = tile_net_handle_egress_timer; -} - -/* Module initialization. */ -static int __init tile_net_init_module(void) -{ - int i; - char name[GXIO_MPIPE_LINK_NAME_LEN]; - uint8_t mac[6]; - - pr_info("Tilera Network Driver\n"); - - mutex_init(&tile_net_devs_for_channel_mutex); - - /* Initialize each CPU. */ - on_each_cpu(tile_net_init_module_percpu, NULL, 1); - - /* Find out what devices we have, and initialize them. */ - for (i = 0; gxio_mpipe_link_enumerate_mac(i, name, mac) >= 0; i++) - tile_net_dev_init(name, mac); - - if (!network_cpus_init()) - network_cpus_map = *cpu_online_mask; - - return 0; -} - -module_init(tile_net_init_module); diff --git a/trunk/drivers/net/hyperv/hyperv_net.h b/trunk/drivers/net/hyperv/hyperv_net.h index 2857ab078aac..4ffcd57b011b 100644 --- a/trunk/drivers/net/hyperv/hyperv_net.h +++ b/trunk/drivers/net/hyperv/hyperv_net.h @@ -478,7 +478,6 @@ struct netvsc_device { u32 nvsp_version; atomic_t num_outstanding_sends; - wait_queue_head_t wait_drain; bool start_remove; bool destroy; /* diff --git a/trunk/drivers/net/hyperv/netvsc.c b/trunk/drivers/net/hyperv/netvsc.c index 0c569831db5a..8b919471472f 100644 --- a/trunk/drivers/net/hyperv/netvsc.c +++ b/trunk/drivers/net/hyperv/netvsc.c @@ -42,7 +42,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) if (!net_device) return NULL; - init_waitqueue_head(&net_device->wait_drain); net_device->start_remove = false; net_device->destroy = false; net_device->dev = device; @@ -388,8 +387,12 @@ int netvsc_device_remove(struct hv_device *device) spin_unlock_irqrestore(&device->channel->inbound_lock, flags); /* Wait for all send completions */ - wait_event(net_device->wait_drain, - atomic_read(&net_device->num_outstanding_sends) == 0); + while (atomic_read(&net_device->num_outstanding_sends)) { + dev_info(&device->device, + "waiting for %d requests to complete...\n", + atomic_read(&net_device->num_outstanding_sends)); + udelay(100); + } netvsc_disconnect_vsp(net_device); @@ -483,9 +486,6 @@ static void netvsc_send_completion(struct hv_device *device, num_outstanding_sends = atomic_dec_return(&net_device->num_outstanding_sends); - if (net_device->destroy && num_outstanding_sends == 0) - wake_up(&net_device->wait_drain); - if (netif_queue_stopped(ndev) && !net_device->start_remove && (hv_ringbuf_avail_percent(&device->channel->outbound) > RING_AVAIL_PERCENT_HIWATER || diff --git a/trunk/drivers/net/phy/icplus.c b/trunk/drivers/net/phy/icplus.c index 47f8e8939266..5ac46f5226f3 100644 --- a/trunk/drivers/net/phy/icplus.c +++ b/trunk/drivers/net/phy/icplus.c @@ -41,8 +41,6 @@ MODULE_LICENSE("GPL"); #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ -#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ -#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED static int ip175c_config_init(struct phy_device *phydev) { @@ -138,11 +136,6 @@ static int ip1001_config_init(struct phy_device *phydev) if (c < 0) return c; - /* INTR pin used: speed/link/duplex will cause an interrupt */ - c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); - if (c < 0) - return c; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { /* Additional delay (2ns) used to adjust RX clock phase * at RGMII interface */ diff --git a/trunk/drivers/net/phy/mdio-mux.c b/trunk/drivers/net/phy/mdio-mux.c index 5c120189ec86..39ea0674dcde 100644 --- a/trunk/drivers/net/phy/mdio-mux.c +++ b/trunk/drivers/net/phy/mdio-mux.c @@ -46,13 +46,7 @@ static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum) struct mdio_mux_parent_bus *pb = cb->parent; int r; - /* In theory multiple mdio_mux could be stacked, thus creating - * more than a single level of nesting. But in practice, - * SINGLE_DEPTH_NESTING will cover the vast majority of use - * cases. We use it, instead of trying to handle the general - * case. - */ - mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING); + mutex_lock(&pb->mii_bus->mdio_lock); r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); if (r) goto out; @@ -77,7 +71,7 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id, int r; - mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING); + mutex_lock(&pb->mii_bus->mdio_lock); r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); if (r) goto out; diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index 5061608f408c..683ef1ce5519 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -96,7 +96,7 @@ static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np) } /** * of_mdio_find_bus - Given an mii_bus node, find the mii_bus. - * @mdio_bus_np: Pointer to the mii_bus. + * @mdio_np: Pointer to the mii_bus. * * Returns a pointer to the mii_bus, or NULL if none found. * diff --git a/trunk/drivers/net/phy/micrel.c b/trunk/drivers/net/phy/micrel.c index 9d6c80c8a0cf..590f902deb6b 100644 --- a/trunk/drivers/net/phy/micrel.c +++ b/trunk/drivers/net/phy/micrel.c @@ -161,7 +161,7 @@ static struct phy_driver ks8051_driver = { static struct phy_driver ks8001_driver = { .phy_id = PHY_ID_KS8001, .name = "Micrel KS8001 or KS8721", - .phy_id_mask = 0x00ffffff, + .phy_id_mask = 0x00fffff0, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, @@ -174,7 +174,7 @@ static struct phy_driver ks8001_driver = { static struct phy_driver ksz9021_driver = { .phy_id = PHY_ID_KSZ9021, - .phy_id_mask = 0x000ffffe, + .phy_id_mask = 0x000fff10, .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), @@ -240,8 +240,8 @@ MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); static struct mdio_device_id __maybe_unused micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000ffffe }, - { PHY_ID_KS8001, 0x00ffffff }, + { PHY_ID_KSZ9021, 0x000fff10 }, + { PHY_ID_KS8001, 0x00fffff0 }, { PHY_ID_KS8737, 0x00fffff0 }, { PHY_ID_KS8041, 0x00fffff0 }, { PHY_ID_KS8051, 0x00fffff0 }, diff --git a/trunk/drivers/net/usb/ipheth.c b/trunk/drivers/net/usb/ipheth.c index a28a983d465e..964031e3da87 100644 --- a/trunk/drivers/net/usb/ipheth.c +++ b/trunk/drivers/net/usb/ipheth.c @@ -59,7 +59,6 @@ #define USB_PRODUCT_IPHONE_3G 0x1292 #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 -#define USB_PRODUCT_IPAD 0x129a #define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4S 0x12a0 @@ -101,10 +100,6 @@ static struct usb_device_id ipheth_table[] = { USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, - { USB_DEVICE_AND_INTERFACE_INFO( - USB_VENDOR_APPLE, USB_PRODUCT_IPAD, - IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, - IPHETH_USBINTF_PROTO) }, { USB_DEVICE_AND_INTERFACE_INFO( USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index a051cedd64bd..3b206786b5e7 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -197,10 +197,6 @@ static int qmi_wwan_manage_power(struct usbnet *dev, int on) static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) { struct usbnet *dev = usb_get_intfdata(intf); - - /* can be called while disconnecting */ - if (!dev) - return 0; return qmi_wwan_manage_power(dev, on); } @@ -261,6 +257,29 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) return rv; } +/* Gobi devices uses identical class/protocol codes for all interfaces regardless + * of function. Some of these are CDC ACM like and have the exact same endpoints + * we are looking for. This leaves two possible strategies for identifying the + * correct interface: + * a) hardcoding interface number, or + * b) use the fact that the wwan interface is the only one lacking additional + * (CDC functional) descriptors + * + * Let's see if we can get away with the generic b) solution. + */ +static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf) +{ + int rv = -EINVAL; + + /* ignore any interface with additional descriptors */ + if (intf->cur_altsetting->extralen) + goto err; + + rv = qmi_wwan_bind_shared(dev, intf); +err: + return rv; +} + static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) { struct usb_driver *subdriver = (void *)dev->data[0]; @@ -328,15 +347,15 @@ static const struct driver_info qmi_wwan_shared = { .manage_power = qmi_wwan_manage_power, }; -static const struct driver_info qmi_wwan_force_int0 = { - .description = "Qualcomm WWAN/QMI device", +static const struct driver_info qmi_wwan_gobi = { + .description = "Qualcomm Gobi wwan/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_shared, + .bind = qmi_wwan_bind_gobi, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, - .data = BIT(0), /* interface whitelist bitmap */ }; +/* ZTE suck at making USB descriptors */ static const struct driver_info qmi_wwan_force_int1 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -346,24 +365,6 @@ static const struct driver_info qmi_wwan_force_int1 = { .data = BIT(1), /* interface whitelist bitmap */ }; -static const struct driver_info qmi_wwan_force_int2 = { - .description = "Qualcomm WWAN/QMI device", - .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_shared, - .unbind = qmi_wwan_unbind_shared, - .manage_power = qmi_wwan_manage_power, - .data = BIT(2), /* interface whitelist bitmap */ -}; - -static const struct driver_info qmi_wwan_force_int3 = { - .description = "Qualcomm WWAN/QMI device", - .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_shared, - .unbind = qmi_wwan_unbind_shared, - .manage_power = qmi_wwan_manage_power, - .data = BIT(3), /* interface whitelist bitmap */ -}; - static const struct driver_info qmi_wwan_force_int4 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -389,23 +390,16 @@ static const struct driver_info qmi_wwan_force_int4 = { static const struct driver_info qmi_wwan_sierra = { .description = "Sierra Wireless wwan/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_shared, + .bind = qmi_wwan_bind_gobi, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ }; #define HUAWEI_VENDOR_ID 0x12D1 - -/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ -#define QMI_GOBI1K_DEVICE(vend, prod) \ - USB_DEVICE(vend, prod), \ - .driver_info = (unsigned long)&qmi_wwan_force_int3 - -/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ #define QMI_GOBI_DEVICE(vend, prod) \ USB_DEVICE(vend, prod), \ - .driver_info = (unsigned long)&qmi_wwan_force_int0 + .driver_info = (unsigned long)&qmi_wwan_gobi static const struct usb_device_id products[] = { { /* Huawei E392, E398 and possibly others sharing both device id and more... */ @@ -507,15 +501,6 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, - { /* ZTE MF60 */ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x19d2, - .idProduct = 0x1402, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0xff, - .bInterfaceProtocol = 0xff, - .driver_info = (unsigned long)&qmi_wwan_force_int2, - }, { /* Sierra Wireless MC77xx in QMI mode */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x1199, @@ -525,24 +510,20 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_sierra, }, - - /* Gobi 1000 devices */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ - {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ - {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ - {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ - - /* Gobi 2000 and 3000 devices */ + {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ + {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ + {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ + {QMI_GOBI_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ + {QMI_GOBI_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ + {QMI_GOBI_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ + {QMI_GOBI_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ + {QMI_GOBI_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ + {QMI_GOBI_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ + {QMI_GOBI_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ + {QMI_GOBI_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ + {QMI_GOBI_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ + {QMI_GOBI_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ + {QMI_GOBI_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ diff --git a/trunk/drivers/net/usb/sierra_net.c b/trunk/drivers/net/usb/sierra_net.c index d75d1f56becf..3faef5670d1f 100644 --- a/trunk/drivers/net/usb/sierra_net.c +++ b/trunk/drivers/net/usb/sierra_net.c @@ -946,7 +946,7 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, } static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; -static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { +static const struct sierra_net_info_data sierra_net_info_data_68A3 = { .rx_urb_size = 8 * 1024, .whitelist = { .infolen = ARRAY_SIZE(sierra_net_ifnum_list), @@ -954,7 +954,7 @@ static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { } }; -static const struct driver_info sierra_net_info_direct_ip = { +static const struct driver_info sierra_net_info_68A3 = { .description = "Sierra Wireless USB-to-WWAN Modem", .flags = FLAG_WWAN | FLAG_SEND_ZLP, .bind = sierra_net_bind, @@ -962,18 +962,12 @@ static const struct driver_info sierra_net_info_direct_ip = { .status = sierra_net_status, .rx_fixup = sierra_net_rx_fixup, .tx_fixup = sierra_net_tx_fixup, - .data = (unsigned long)&sierra_net_info_data_direct_ip, + .data = (unsigned long)&sierra_net_info_data_68A3, }; static const struct usb_device_id products[] = { {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + .driver_info = (unsigned long) &sierra_net_info_68A3}, {}, /* last item */ }; diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index aba769d77459..9f58330f1312 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -796,13 +796,11 @@ int usbnet_open (struct net_device *net) if (info->manage_power) { retval = info->manage_power(dev, 1); if (retval < 0) - goto done_manage_power_error; + goto done; usb_autopm_put_interface(dev->intf); } return retval; -done_manage_power_error: - clear_bit(EVENT_DEV_OPEN, &dev->flags); done: usb_autopm_put_interface(dev->intf); done_nopm: @@ -878,9 +876,9 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { struct usbnet *dev = netdev_priv(net); - strlcpy (info->driver, dev->driver_name, sizeof info->driver); - strlcpy (info->version, DRIVER_VERSION, sizeof info->version); - strlcpy (info->fw_version, dev->driver_info->description, + strncpy (info->driver, dev->driver_name, sizeof info->driver); + strncpy (info->version, DRIVER_VERSION, sizeof info->version); + strncpy (info->fw_version, dev->driver_info->description, sizeof info->fw_version); usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); } @@ -1204,21 +1202,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, } EXPORT_SYMBOL_GPL(usbnet_start_xmit); -static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) -{ - struct urb *urb; - int i; - - /* don't refill the queue all at once */ - for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { - urb = usb_alloc_urb(0, flags); - if (urb != NULL) { - if (rx_submit(dev, urb, flags) == -ENOLINK) - return; - } - } -} - /*-------------------------------------------------------------------------*/ // tasklet (work deferred from completions, in_irq) or timer @@ -1258,14 +1241,26 @@ static void usbnet_bh (unsigned long param) !timer_pending (&dev->delay) && !test_bit (EVENT_RX_HALT, &dev->flags)) { int temp = dev->rxq.qlen; - - if (temp < RX_QLEN(dev)) { - rx_alloc_submit(dev, GFP_ATOMIC); + int qlen = RX_QLEN (dev); + + if (temp < qlen) { + struct urb *urb; + int i; + + // don't refill the queue all at once + for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { + urb = usb_alloc_urb (0, GFP_ATOMIC); + if (urb != NULL) { + if (rx_submit (dev, urb, GFP_ATOMIC) == + -ENOLINK) + return; + } + } if (temp != dev->rxq.qlen) netif_dbg(dev, link, dev->net, "rxqlen %d --> %d\n", temp, dev->rxq.qlen); - if (dev->rxq.qlen < RX_QLEN(dev)) + if (dev->rxq.qlen < qlen) tasklet_schedule (&dev->bh); } if (dev->txq.qlen < TX_QLEN (dev)) @@ -1518,7 +1513,6 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) spin_lock_irq(&dev->txq.lock); /* don't autosuspend while transmitting */ if (dev->txq.qlen && PMSG_IS_AUTO(message)) { - dev->suspend_count--; spin_unlock_irq(&dev->txq.lock); return -EBUSY; } else { @@ -1575,13 +1569,6 @@ int usbnet_resume (struct usb_interface *intf) spin_unlock_irq(&dev->txq.lock); if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { - /* handle remote wakeup ASAP */ - if (!dev->wait && - netif_device_present(dev->net) && - !timer_pending(&dev->delay) && - !test_bit(EVENT_RX_HALT, &dev->flags)) - rx_alloc_submit(dev, GFP_KERNEL); - if (!(dev->txq.qlen >= TX_QLEN(dev))) netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index f18149ae2588..5214b1eceb95 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -42,8 +42,7 @@ module_param(gso, bool, 0444); #define VIRTNET_DRIVER_VERSION "1.0.0" struct virtnet_stats { - struct u64_stats_sync tx_syncp; - struct u64_stats_sync rx_syncp; + struct u64_stats_sync syncp; u64 tx_bytes; u64 tx_packets; @@ -301,10 +300,10 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) hdr = skb_vnet_hdr(skb); - u64_stats_update_begin(&stats->rx_syncp); + u64_stats_update_begin(&stats->syncp); stats->rx_bytes += skb->len; stats->rx_packets++; - u64_stats_update_end(&stats->rx_syncp); + u64_stats_update_end(&stats->syncp); if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { pr_debug("Needs csum!\n"); @@ -566,10 +565,10 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) { pr_debug("Sent skb %p\n", skb); - u64_stats_update_begin(&stats->tx_syncp); + u64_stats_update_begin(&stats->syncp); stats->tx_bytes += skb->len; stats->tx_packets++; - u64_stats_update_end(&stats->tx_syncp); + u64_stats_update_end(&stats->syncp); tot_sgs += skb_vnet_hdr(skb)->num_sg; dev_kfree_skb_any(skb); @@ -704,16 +703,12 @@ static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev, u64 tpackets, tbytes, rpackets, rbytes; do { - start = u64_stats_fetch_begin(&stats->tx_syncp); + start = u64_stats_fetch_begin(&stats->syncp); tpackets = stats->tx_packets; tbytes = stats->tx_bytes; - } while (u64_stats_fetch_retry(&stats->tx_syncp, start)); - - do { - start = u64_stats_fetch_begin(&stats->rx_syncp); rpackets = stats->rx_packets; rbytes = stats->rx_bytes; - } while (u64_stats_fetch_retry(&stats->rx_syncp, start)); + } while (u64_stats_fetch_retry(&stats->syncp, start)); tot->rx_packets += rpackets; tot->tx_packets += tpackets; diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index a747c632597a..520a4b2eb9cc 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -7233,8 +7233,8 @@ static int airo_get_aplist(struct net_device *dev, } } else { dwrq->flags = 1; /* Should be define'd */ - memcpy(extra + sizeof(struct sockaddr) * i, qual, - sizeof(struct iw_quality) * i); + memcpy(extra + sizeof(struct sockaddr)*i, + &qual, sizeof(struct iw_quality)*i); } dwrq->length = i; diff --git a/trunk/drivers/net/wireless/ath/ath.h b/trunk/drivers/net/wireless/ath/ath.h index 420d69b2674c..c54b7d37bff1 100644 --- a/trunk/drivers/net/wireless/ath/ath.h +++ b/trunk/drivers/net/wireless/ath/ath.h @@ -143,7 +143,6 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); - DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX); enum ath_crypt_caps crypt_caps; unsigned int clockrate; diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 44ad6fe0278f..fbaa30930076 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -1045,11 +1045,11 @@ ath5k_drain_tx_buffs(struct ath5k_hw *ah) ath5k_txbuf_free_skb(ah, bf); - spin_lock(&ah->txbuflock); + spin_lock_bh(&ah->txbuflock); list_move_tail(&bf->list, &ah->txbuf); ah->txbuf_len++; txq->txq_len--; - spin_unlock(&ah->txbuflock); + spin_unlock_bh(&ah->txbuflock); } txq->link = NULL; txq->txq_poll_mark = false; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 4866550ddd96..a277cf6f339d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -214,7 +214,6 @@ struct ath_frame_info { enum ath9k_key_type keytype; u8 keyix; u8 retries; - u8 rtscts_rate; }; struct ath_buf_state { diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c index abbd6effd60d..2b8f61c210e1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1496,7 +1496,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; if (priv->ah->opmode == NL80211_IFTYPE_STATION) { - ath9k_htc_choose_set_bssid(priv); if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) ath9k_htc_start_ani(priv); else if (priv->num_sta_assoc_vif == 0) @@ -1504,11 +1503,13 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_IBSS) { + if (changed & BSS_CHANGED_BSSID) { if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { common->curaid = bss_conf->aid; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); ath9k_htc_set_bssid(priv); + } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + ath9k_htc_choose_set_bssid(priv); } } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 995ca8e1302e..7db1890448f2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -622,7 +622,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && + ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; @@ -784,25 +784,13 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { - struct ath_common *common = ath9k_hw_common(ah); - int i = 0; - REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); udelay(100); REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) { - + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) udelay(100); - if (WARN_ON_ONCE(i >= 100)) { - ath_err(common, "PLL4 meaurement not done\n"); - break; - } - - i++; - } - return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index dac1a2709e3c..4de4473776ac 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -971,15 +971,6 @@ void ath_hw_pll_work(struct work_struct *work) hw_pll_work.work); u32 pll_sqsum; - /* - * ensure that the PLL WAR is executed only - * after the STA is associated (or) if the - * beaconing had started in interfaces that - * uses beacons. - */ - if (!(sc->sc_flags & SC_OP_BEACONS)) - return; - if (AR_SREV_9485(sc->sc_ah)) { ath9k_ps_wakeup(sc); @@ -1452,6 +1443,15 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, } } + if ((ah->opmode == NL80211_IFTYPE_ADHOC) || + ((vif->type == NL80211_IFTYPE_ADHOC) && + sc->nvifs > 0)) { + ath_err(common, "Cannot create ADHOC interface when other" + " interfaces already exist.\n"); + ret = -EINVAL; + goto out; + } + ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->nvifs++; @@ -1476,6 +1476,15 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); + /* See if new interface type is valid. */ + if ((new_type == NL80211_IFTYPE_ADHOC) && + (sc->nvifs > 1)) { + ath_err(common, "When using ADHOC, it must be the only" + " interface.\n"); + ret = -EINVAL; + goto out; + } + if (ath9k_uses_beacons(new_type) && !ath9k_uses_beacons(vif->type)) { if (sc->nbcnvifs >= ATH_BCBUF) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index 0735aeb3b26c..e1fcc68124dc 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -695,9 +695,9 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, __skb_unlink(skb, &rx_edma->rx_fifo); list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); + } else { + bf = NULL; } - - bf = NULL; } *dest = bf; @@ -822,8 +822,7 @@ static bool ath9k_rx_accept(struct ath_common *common, * descriptor does contain a valid key index. This has been observed * mostly with CCMP encryption. */ - if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || - !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) + if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID) rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; if (!rx_stats->rs_datalen) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 4d571394c7a8..d59dd01d6cde 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -938,7 +938,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, struct ieee80211_tx_rate *rates; const struct ieee80211_rate *rate; struct ieee80211_hdr *hdr; - struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); int i; u8 rix = 0; @@ -949,7 +948,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, /* set dur_update_en for l-sig computation except for PS-Poll frames */ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); - info->rtscts_rate = fi->rtscts_rate; + + /* + * We check if Short Preamble is needed for the CTS rate by + * checking the BSS's global flag. + * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. + */ + rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); + info->rtscts_rate = rate->hw_value; + + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) + info->rtscts_rate |= rate->hw_value_short; for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; @@ -991,13 +1001,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, } /* legacy rates */ - rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; if ((tx_info->band == IEEE80211_BAND_2GHZ) && !(rate->flags & IEEE80211_RATE_ERP_G)) phy = WLAN_RC_PHY_CCK; else phy = WLAN_RC_PHY_OFDM; + rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; info->rates[i].Rate = rate->hw_value; if (rate->hw_value_short) { if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) @@ -1766,22 +1776,10 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - const struct ieee80211_rate *rate; struct ath_frame_info *fi = get_frame_info(skb); struct ath_node *an = NULL; enum ath9k_key_type keytype; - bool short_preamble = false; - - /* - * We check if Short Preamble is needed for the CTS rate by - * checking the BSS's global flag. - * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. - */ - if (tx_info->control.vif && - tx_info->control.vif->bss_conf.use_short_preamble) - short_preamble = true; - rate = ieee80211_get_rts_cts_rate(hw, tx_info); keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (sta) @@ -1796,9 +1794,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; - fi->rtscts_rate = rate->hw_value; - if (short_preamble) - fi->rtscts_rate |= rate->hw_value_short; } u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) diff --git a/trunk/drivers/net/wireless/ath/key.c b/trunk/drivers/net/wireless/ath/key.c index 5c54aa43ca2d..0e81904956cf 100644 --- a/trunk/drivers/net/wireless/ath/key.c +++ b/trunk/drivers/net/wireless/ath/key.c @@ -556,9 +556,6 @@ int ath_key_config(struct ath_common *common, return -EIO; set_bit(idx, common->keymap); - if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - set_bit(idx, common->ccmp_keymap); - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); @@ -585,7 +582,6 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) return; clear_bit(key->hw_key_idx, common->keymap); - clear_bit(key->hw_key_idx, common->ccmp_keymap); if (key->cipher != WLAN_CIPHER_SUITE_TKIP) return; diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index c06b6cb5c91e..67c13af6f206 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -877,10 +877,6 @@ struct b43_wl { * from the mac80211 subsystem. */ u16 mac80211_initially_registered_queues; - /* Set this if we call ieee80211_register_hw() and check if we call - * ieee80211_unregister_hw(). */ - bool hw_registred; - /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 1b988f26bdf1..5a39b226b2e3 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -2437,7 +2437,6 @@ static void b43_request_firmware(struct work_struct *work) err = ieee80211_register_hw(wl->hw); if (err) goto err_one_core_detach; - wl->hw_registred = true; b43_leds_register(wl->current_dev); goto out; @@ -3767,7 +3766,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) if (prev_status >= B43_STAT_STARTED) { err = b43_wireless_core_start(up_dev); if (err) { - b43err(wl, "Fatal: Could not start device for " + b43err(wl, "Fatal: Coult not start device for " "selected %s-GHz band\n", band_to_string(chan->band)); b43_wireless_core_exit(up_dev); @@ -5300,7 +5299,6 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1; wl->mac80211_initially_registered_queues = hw->queues; - wl->hw_registred = false; hw->max_rates = 2; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) @@ -5372,15 +5370,12 @@ static void b43_bcma_remove(struct bcma_device *core) * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); - B43_WARN_ON(!wl); - if (wl->current_dev == wldev && wl->hw_registred) { - /* Restore the queues count before unregistering, because firmware detect - * might have modified it. Restoring is important, so the networking - * stack can properly free resources. */ - wl->hw->queues = wl->mac80211_initially_registered_queues; - b43_leds_stop(wldev); - ieee80211_unregister_hw(wl->hw); - } + /* Restore the queues count before unregistering, because firmware detect + * might have modified it. Restoring is important, so the networking + * stack can properly free resources. */ + wl->hw->queues = wl->mac80211_initially_registered_queues; + b43_leds_stop(wldev); + ieee80211_unregister_hw(wl->hw); b43_one_core_detach(wldev->dev); @@ -5451,7 +5446,7 @@ static void b43_ssb_remove(struct ssb_device *sdev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (wl->current_dev == wldev && wl->hw_registred) { + if (wl->current_dev == wldev) { /* Restore the queues count before unregistering, because firmware detect * might have modified it. Restoring is important, so the networking * stack can properly free resources. */ diff --git a/trunk/drivers/net/wireless/b43legacy/dma.c b/trunk/drivers/net/wireless/b43legacy/dma.c index c8baf020c20f..f1f8bd09bd87 100644 --- a/trunk/drivers/net/wireless/b43legacy/dma.c +++ b/trunk/drivers/net/wireless/b43legacy/dma.c @@ -1072,7 +1072,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { - bounce_skb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); + bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index eae691e2f7dd..cd9c9bc186d9 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -2633,7 +2633,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, if (prev_status >= B43legacy_STAT_STARTED) { err = b43legacy_wireless_core_start(up_dev); if (err) { - b43legacyerr(wl, "Fatal: Could not start device for " + b43legacyerr(wl, "Fatal: Coult not start device for " "newly selected %s-PHY mode\n", phymode_to_string(new_mode)); b43legacy_wireless_core_exit(up_dev); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 8e7e6928c936..e2480d196276 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -89,9 +89,9 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); - /* redirect, configure and enable io for interrupt signal */ + /* redirect, configure ane enable io for interrupt signal */ data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; - if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH) + if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH) data |= SDIO_SEPINT_ACT_HI; brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index 95aa8e1683ec..9cfae0c08707 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1903,6 +1903,14 @@ static void ipw2100_down(struct ipw2100_priv *priv) netif_stop_queue(priv->net_dev); } +/* Called by register_netdev() */ +static int ipw2100_net_init(struct net_device *dev) +{ + struct ipw2100_priv *priv = libipw_priv(dev); + + return ipw2100_up(priv, 1); +} + static int ipw2100_wdev_init(struct net_device *dev) { struct ipw2100_priv *priv = libipw_priv(dev); @@ -6079,6 +6087,7 @@ static const struct net_device_ops ipw2100_netdev_ops = { .ndo_stop = ipw2100_close, .ndo_start_xmit = libipw_xmit, .ndo_change_mtu = libipw_change_mtu, + .ndo_init = ipw2100_net_init, .ndo_tx_timeout = ipw2100_tx_timeout, .ndo_set_mac_address = ipw2100_set_address, .ndo_validate_addr = eth_validate_addr, @@ -6320,10 +6329,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2100 Network Connection\n"); - err = ipw2100_up(priv, 1); - if (err) - goto fail; - err = ipw2100_wdev_init(dev); if (err) goto fail; @@ -6333,7 +6338,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, * network device we would call ipw2100_up. This introduced a race * condition with newer hotplug configurations (network was coming * up and making calls before the device was initialized). - */ + * + * If we called ipw2100_up before we registered the device, then the + * device name wasn't registered. So, we instead use the net_dev->init + * member to call a function that then just turns and calls ipw2100_up. + * net_dev->init is called after name allocation but before the + * notifier chain is called */ err = register_netdev(dev); if (err) { printk(KERN_WARNING DRV_NAME diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index ff5d689e13f3..509301a5e7e2 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -3405,7 +3405,7 @@ il4965_remove_dynamic_key(struct il_priv *il, return 0; } - if (il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_INVALID) { + if (il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { IL_WARN("Removing wrong key %d 0x%x\n", keyconf->keyidx, key_flags); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -3420,7 +3420,7 @@ il4965_remove_dynamic_key(struct il_priv *il, memset(&il->stations[sta_id].sta.key, 0, sizeof(struct il4965_keyinfo)); il->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; - il->stations[sta_id].sta.key.key_offset = keyconf->hw_key_idx; + il->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; diff --git a/trunk/drivers/net/wireless/iwlegacy/common.c b/trunk/drivers/net/wireless/iwlegacy/common.c index 5d4807c2b56d..cbf2dc18341f 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.c +++ b/trunk/drivers/net/wireless/iwlegacy/common.c @@ -4767,12 +4767,14 @@ il_bg_watchdog(unsigned long data) return; /* monitor and check for other stuck queues */ - for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { - /* skip as we already checked the command queue */ - if (cnt == il->cmd_queue) - continue; - if (il_check_stuck_queue(il, cnt)) - return; + if (il_is_any_associated(il)) { + for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { + /* skip as we already checked the command queue */ + if (cnt == il->cmd_queue) + continue; + if (il_check_stuck_queue(il, cnt)) + return; + } } mod_timer(&il->watchdog, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index e5e8ada4aaf6..19f7ee84ae89 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -35,20 +35,17 @@ #define IWL6000_UCODE_API_MAX 6 #define IWL6050_UCODE_API_MAX 5 #define IWL6000G2_UCODE_API_MAX 6 -#define IWL6035_UCODE_API_MAX 6 /* Oldest version we won't warn about */ #define IWL6000_UCODE_API_OK 4 #define IWL6000G2_UCODE_API_OK 5 #define IWL6050_UCODE_API_OK 5 #define IWL6000G2B_UCODE_API_OK 6 -#define IWL6035_UCODE_API_OK 6 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4 -#define IWL6000G2_UCODE_API_MIN 5 -#define IWL6035_UCODE_API_MIN 6 +#define IWL6000G2_UCODE_API_MIN 4 /* EEPROM versions */ #define EEPROM_6000_TX_POWER_VERSION (4) @@ -230,25 +227,9 @@ const struct iwl_cfg iwl6030_2bg_cfg = { IWL_DEVICE_6030, }; -#define IWL_DEVICE_6035 \ - .fw_name_pre = IWL6030_FW_PRE, \ - .ucode_api_max = IWL6035_UCODE_API_MAX, \ - .ucode_api_ok = IWL6035_UCODE_API_OK, \ - .ucode_api_min = IWL6035_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ - .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .bt_params = &iwl6000_bt_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true - const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", - IWL_DEVICE_6035, + IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index eb6a8eaf42fc..aea07aab3c9e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1267,7 +1267,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, key_flags |= STA_KEY_MULTICAST_MSK; sta_cmd.key.key_flags = key_flags; - sta_cmd.key.key_offset = keyconf->hw_key_idx; + sta_cmd.key.key_offset = WEP_INVALID_OFFSET; sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; sta_cmd.mode = STA_CONTROL_MODIFY_MSK; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 7f97dec8534d..e7c157e5ebeb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2239,7 +2239,6 @@ static ssize_t iwl_dbgfs_echo_test_write(struct file *file, return count; } -#ifdef CONFIG_IWLWIFI_DEBUG static ssize_t iwl_dbgfs_log_event_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2277,7 +2276,6 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, return count; } -#endif static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, char __user *user_buf, @@ -2347,9 +2345,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); -#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); -#endif DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); /* @@ -2409,9 +2405,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); -#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); -#endif if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c index fac67a526a30..d742900969ea 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -861,18 +861,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* We have our copies now, allow OS release its copies */ release_firmware(ucode_raw); + complete(&drv->request_firmware_complete); drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); if (!drv->op_mode) - goto out_unbind; + goto out_free_fw; - /* - * Complete the firmware request last so that - * a driver unbind (stop) doesn't run while we - * are doing the start() above. - */ - complete(&drv->request_firmware_complete); return; try_again: diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c index b8e2b223ac36..50c58911e718 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -568,28 +568,28 @@ static int iwl_find_otp_image(struct iwl_trans *trans, * iwl_get_max_txpower_avg - get the highest tx power from all chains. * find the highest tx power from all chains for the channel */ -static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, +static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element, s8 *max_txpower_in_half_dbm) { s8 max_txpower_avg = 0; /* (dBm) */ /* Take the highest tx power from any valid chains */ - if ((priv->hw_params.valid_tx_ant & ANT_A) && + if ((cfg->valid_tx_ant & ANT_A) && (enhanced_txpower[element].chain_a_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].chain_a_max; - if ((priv->hw_params.valid_tx_ant & ANT_B) && + if ((cfg->valid_tx_ant & ANT_B) && (enhanced_txpower[element].chain_b_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].chain_b_max; - if ((priv->hw_params.valid_tx_ant & ANT_C) && + if ((cfg->valid_tx_ant & ANT_C) && (enhanced_txpower[element].chain_c_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].chain_c_max; - if (((priv->hw_params.valid_tx_ant == ANT_AB) | - (priv->hw_params.valid_tx_ant == ANT_BC) | - (priv->hw_params.valid_tx_ant == ANT_AC)) && + if (((cfg->valid_tx_ant == ANT_AB) | + (cfg->valid_tx_ant == ANT_BC) | + (cfg->valid_tx_ant == ANT_AC)) && (enhanced_txpower[element].mimo2_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].mimo2_max; - if ((priv->hw_params.valid_tx_ant == ANT_ABC) && + if ((cfg->valid_tx_ant == ANT_ABC) && (enhanced_txpower[element].mimo3_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].mimo3_max; @@ -691,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) ((txp->delta_20_in_40 & 0xf0) >> 4), (txp->delta_20_in_40 & 0x0f)); - max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, + max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, &max_txp_avg_halfdbm); /* diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 013680332f07..ab2f4d7500a4 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -199,7 +199,6 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; -#ifdef CONFIG_PM_SLEEP if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && priv->trans->ops->wowlan_suspend && device_can_wakeup(priv->trans->dev)) { @@ -218,7 +217,6 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->wiphy->wowlan.pattern_max_len = IWLAGN_WOWLAN_MAX_PATTERN_LEN; } -#endif if (iwlwifi_mod_params.power_save) hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; @@ -251,7 +249,6 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ret = ieee80211_register_hw(priv->hw); if (ret) { IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); - iwl_leds_exit(priv); return ret; } priv->mac80211_registered = 1; @@ -796,18 +793,6 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, switch (op) { case ADD: ret = iwlagn_mac_sta_add(hw, vif, sta); - if (ret) - break; - /* - * Clear the in-progress flag, the AP station entry was added - * but we'll initialize LQ only when we've associated (which - * would also clear the in-progress flag). This is necessary - * in case we never initialize LQ because association fails. - */ - spin_lock_bh(&priv->sta_lock); - priv->stations[iwl_sta_id(sta)].used &= - ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_bh(&priv->sta_lock); break; case REMOVE: ret = iwlagn_mac_sta_remove(hw, vif, sta); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h b/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h index dfd54662e3e6..3b1069290fa9 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -224,7 +224,6 @@ #define SCD_TXFACT (SCD_BASE + 0x10) #define SCD_ACTIVE (SCD_BASE + 0x14) #define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8) -#define SCD_CHAINEXT_EN (SCD_BASE + 0x244) #define SCD_AGGR_SEL (SCD_BASE + 0x248) #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 79c6b91417f9..ec6fb395b84d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1058,11 +1058,6 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); - /* The chain extension of the SCD doesn't work well. This feature is - * enabled by default by the HW, so we need to disable it manually. - */ - iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); - /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index a0b7cfd34685..fb787df01666 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -1555,7 +1555,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, hdr = (struct ieee80211_hdr *) skb->data; mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); } - txi->flags |= IEEE80211_TX_STAT_ACK; } ieee80211_tx_status_irqsafe(data2->hw, skb); return 0; @@ -1722,24 +1721,6 @@ static void hwsim_exit_netlink(void) "unregister family %i\n", ret); } -static const struct ieee80211_iface_limit hwsim_if_limits[] = { - { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, - { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | -#ifdef CONFIG_MAC80211_MESH - BIT(NL80211_IFTYPE_MESH_POINT) | -#endif - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO) }, -}; - -static const struct ieee80211_iface_combination hwsim_if_comb = { - .limits = hwsim_if_limits, - .n_limits = ARRAY_SIZE(hwsim_if_limits), - .max_interfaces = 2048, - .num_different_channels = 1, -}; - static int __init init_mac80211_hwsim(void) { int i, err = 0; @@ -1801,9 +1782,6 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->n_addresses = 2; hw->wiphy->addresses = data->addresses; - hw->wiphy->iface_combinations = &hwsim_if_comb; - hw->wiphy->n_iface_combinations = 1; - if (fake_hw_scan) { hw->wiphy->max_scan_ssids = 255; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c index 900ee129e825..9c44088054dd 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -256,8 +256,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, else last_seq = priv->rx_seq[tid]; - if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && - last_seq >= new_node->start_win) + if (last_seq >= new_node->start_win) new_node->start_win = last_seq + 1; new_node->win_size = win_size; @@ -597,5 +596,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); - mwifiex_reset_11n_rx_seq_num(priv); + memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); } diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h index 6c9815a0f5d8..f1bffebabc60 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -37,13 +37,6 @@ #define ADDBA_RSP_STATUS_ACCEPT 0 -#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff - -static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) -{ - memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); -} - int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 5c7fd185373c..87671446e24b 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -948,20 +948,6 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, bss_cfg->ssid.ssid_len = params->ssid_len; } - switch (params->hidden_ssid) { - case NL80211_HIDDEN_SSID_NOT_IN_USE: - bss_cfg->bcast_ssid_ctl = 1; - break; - case NL80211_HIDDEN_SSID_ZERO_LEN: - bss_cfg->bcast_ssid_ctl = 0; - break; - case NL80211_HIDDEN_SSID_ZERO_CONTENTS: - /* firmware doesn't support this type of hidden SSID */ - default: - kfree(bss_cfg); - return -EINVAL; - } - if (mwifiex_set_secure_params(priv, bss_cfg, params)) { kfree(bss_cfg); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); @@ -1485,7 +1471,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev; if (!adapter) - return ERR_PTR(-EFAULT); + return NULL; switch (type) { case NL80211_IFTYPE_UNSPECIFIED: @@ -1495,12 +1481,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple sta/adhoc ifaces\n"); - return ERR_PTR(-EINVAL); + return NULL; } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return ERR_PTR(-ENOMEM); + return NULL; wdev->wiphy = wiphy; priv->wdev = wdev; @@ -1523,12 +1509,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "Can't create multiple AP interfaces"); - return ERR_PTR(-EINVAL); + return NULL; } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return ERR_PTR(-ENOMEM); + return NULL; priv->wdev = wdev; wdev->wiphy = wiphy; @@ -1545,15 +1531,14 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, break; default: wiphy_err(wiphy, "type not supported\n"); - return ERR_PTR(-EINVAL); + return NULL; } dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - return ERR_PTR(-ENOMEM); + goto error; } mwifiex_init_priv_params(priv, dev); @@ -1584,9 +1569,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); - free_netdev(dev); - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - return ERR_PTR(-EFAULT); + goto error; } sema_init(&priv->async_sem, 1); @@ -1598,6 +1581,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, mwifiex_dev_debugfs_init(priv); #endif return dev; +error: + if (dev && (dev->reg_state == NETREG_UNREGISTERED)) + free_netdev(dev); + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + + return NULL; } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); diff --git a/trunk/drivers/net/wireless/mwifiex/fw.h b/trunk/drivers/net/wireless/mwifiex/fw.h index 561452a5c818..9f674bbebe65 100644 --- a/trunk/drivers/net/wireless/mwifiex/fw.h +++ b/trunk/drivers/net/wireless/mwifiex/fw.h @@ -122,7 +122,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) -#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) @@ -1210,11 +1209,6 @@ struct host_cmd_tlv_ssid { u8 ssid[0]; } __packed; -struct host_cmd_tlv_bcast_ssid { - struct host_cmd_tlv tlv; - u8 bcast_ctl; -} __packed; - struct host_cmd_tlv_beacon_period { struct host_cmd_tlv tlv; __le16 period; diff --git a/trunk/drivers/net/wireless/mwifiex/ie.c b/trunk/drivers/net/wireless/mwifiex/ie.c index 383820a52beb..ceb82cd749cc 100644 --- a/trunk/drivers/net/wireless/mwifiex/ie.c +++ b/trunk/drivers/net/wireless/mwifiex/ie.c @@ -213,7 +213,6 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, /* save assoc resp ie index after auto-indexing */ *assoc_idx = *((u16 *)pos); - kfree(ap_custom_ie); return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index fc8a9bfa1248..e0377473282f 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -978,10 +978,10 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "info: --- Rx: Event ---\n"); adapter->event_cause = *(u32 *) skb->data; + skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN); + if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) - memcpy(adapter->event_body, - skb->data + MWIFIEX_EVENT_HEADER_LEN, - skb->len); + memcpy(adapter->event_body, skb->data, skb->len); /* event cause has been saved to adapter->event_cause */ adapter->event_received = true; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_event.c b/trunk/drivers/net/wireless/mwifiex/sta_event.c index 11e731f3581c..4ace5a3dcd23 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_event.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_event.c @@ -406,9 +406,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_UAP_STA_ASSOC: + skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); memset(&sinfo, 0, sizeof(sinfo)); - event = (struct mwifiex_assoc_event *) - (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER); + event = (struct mwifiex_assoc_event *)adapter->event_skb->data; if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) { len = -1; @@ -433,8 +433,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) GFP_KERNEL); break; case EVENT_UAP_STA_DEAUTH: - cfg80211_del_sta(priv->netdev, adapter->event_body + - MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL); + skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); + cfg80211_del_sta(priv->netdev, adapter->event_skb->data, + GFP_KERNEL); break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; diff --git a/trunk/drivers/net/wireless/mwifiex/txrx.c b/trunk/drivers/net/wireless/mwifiex/txrx.c index cecb27283196..e2faec4db108 100644 --- a/trunk/drivers/net/wireless/mwifiex/txrx.c +++ b/trunk/drivers/net/wireless/mwifiex/txrx.c @@ -161,11 +161,15 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, goto done; for (i = 0; i < adapter->priv_num; i++) { + tpriv = adapter->priv[i]; - if (tpriv->media_connected && - netif_queue_stopped(tpriv->netdev)) - mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); + if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && + (tpriv->media_connected)) { + if (netif_queue_stopped(tpriv->netdev)) + mwifiex_wake_up_net_dev_queue(tpriv->netdev, + adapter); + } } done: dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c index 89f9a2a45de3..76dfbc42a732 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c @@ -27,17 +27,6 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { int i; - if (!params->privacy) { - bss_config->protocol = PROTOCOL_NO_SECURITY; - bss_config->key_mgmt = KEY_MGMT_NONE; - bss_config->wpa_cfg.length = 0; - priv->sec_info.wep_enabled = 0; - priv->sec_info.wpa_enabled = 0; - priv->sec_info.wpa2_enabled = 0; - - return 0; - } - switch (params->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: bss_config->auth_mode = WLAN_AUTH_OPEN; @@ -143,7 +132,6 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_dtim_period *dtim_period; struct host_cmd_tlv_beacon_period *beacon_period; struct host_cmd_tlv_ssid *ssid; - struct host_cmd_tlv_bcast_ssid *bcast_ssid; struct host_cmd_tlv_channel_band *chan_band; struct host_cmd_tlv_frag_threshold *frag_threshold; struct host_cmd_tlv_rts_threshold *rts_threshold; @@ -165,14 +153,6 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) cmd_size += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; - - bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv; - bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID); - bcast_ssid->tlv.len = - cpu_to_le16(sizeof(bcast_ssid->bcast_ctl)); - bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl; - cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid); - tlv += sizeof(struct host_cmd_tlv_bcast_ssid); } if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) { chan_band = (struct host_cmd_tlv_channel_band *)tlv; @@ -436,7 +416,6 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) if (!bss_cfg) return -ENOMEM; - mwifiex_set_sys_config_invalid_data(bss_cfg); bss_cfg->band_cfg = BAND_CONFIG_MANUAL; bss_cfg->channel = channel; diff --git a/trunk/drivers/net/wireless/mwifiex/usb.c b/trunk/drivers/net/wireless/mwifiex/usb.c index 22a5916564b8..49ebf20c56eb 100644 --- a/trunk/drivers/net/wireless/mwifiex/usb.c +++ b/trunk/drivers/net/wireless/mwifiex/usb.c @@ -49,7 +49,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, struct device *dev = adapter->dev; u32 recv_type; __le32 tmp; - int ret; if (adapter->hs_activated) mwifiex_process_hs_config(adapter); @@ -70,19 +69,16 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_CMD: if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) { dev_err(dev, "CMD: skb->len too large\n"); - ret = -1; - goto exit_restore_skb; + return -1; } else if (!adapter->curr_cmd) { dev_dbg(dev, "CMD: no curr_cmd\n"); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp( adapter, skb->data, skb->len); - ret = 0; - goto exit_restore_skb; + return 0; } - ret = -1; - goto exit_restore_skb; + return -1; } adapter->curr_cmd->resp_skb = skb; @@ -91,22 +87,20 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_EVENT: if (skb->len < sizeof(u32)) { dev_err(dev, "EVENT: skb->len too small\n"); - ret = -1; - goto exit_restore_skb; + return -1; } skb_copy_from_linear_data(skb, &tmp, sizeof(u32)); adapter->event_cause = le32_to_cpu(tmp); + skb_pull(skb, sizeof(u32)); dev_dbg(dev, "event_cause %#x\n", adapter->event_cause); if (skb->len > MAX_EVENT_SIZE) { dev_err(dev, "EVENT: event body too large\n"); - ret = -1; - goto exit_restore_skb; + return -1; } - memcpy(adapter->event_body, skb->data + - MWIFIEX_EVENT_HEADER_LEN, skb->len); - + skb_copy_from_linear_data(skb, adapter->event_body, + skb->len); adapter->event_received = true; adapter->event_skb = skb; break; @@ -130,12 +124,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, } return -EINPROGRESS; - -exit_restore_skb: - /* The buffer will be reused for further cmds/events */ - skb_push(skb, INTF_HEADER_LEN); - - return ret; } static void mwifiex_usb_rx_complete(struct urb *urb) diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index 3fa4d4176993..f3fc65515857 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -404,8 +404,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; - mwifiex_reset_11n_rx_seq_num(priv); - atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } @@ -1223,7 +1221,6 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) || - priv->wps.session_enable || ((priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)) { diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index dfcd02ab6cae..2e9e6af21362 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -2110,7 +2110,7 @@ static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (ether_addr_equal(bssid->mac, match_bssid)) + if (!ether_addr_equal(bssid->mac, match_bssid)) *matched = true; } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h index 8f754025b06e..ca36cccaba31 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h @@ -396,7 +396,8 @@ struct rt2x00_intf { * for hardware which doesn't support hardware * sequence counting. */ - atomic_t seqno; + spinlock_t seqlock; + u16 seqno; }; static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index dd24b2663b5e..b49773ef72f2 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -277,6 +277,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, else rt2x00dev->intf_sta_count++; + spin_lock_init(&intf->seqlock); mutex_init(&intf->beacon_skb_mutex); intf->beacon = entry; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c index 2fd830103415..4c662eccf53c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -207,7 +207,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); - u16 seqno; if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) return; @@ -239,13 +238,15 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, * sequence counting per-frame, since those will override the * sequence counter given by mac80211. */ - if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) - seqno = atomic_add_return(0x10, &intf->seqno); - else - seqno = atomic_read(&intf->seqno); + spin_lock(&intf->seqlock); + if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) + intf->seqno += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(seqno); + hdr->seq_ctrl |= cpu_to_le16(intf->seqno); + + spin_unlock(&intf->seqlock); + } static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c index 74ecc33fdd90..d357d1ed92f6 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -436,8 +436,8 @@ void rt2x00usb_kick_queue(struct data_queue *queue) case QID_RX: if (!rt2x00queue_full(queue)) rt2x00queue_for_each_entry(queue, - Q_INDEX, Q_INDEX_DONE, + Q_INDEX, NULL, rt2x00usb_kick_rx_entry); break; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187/leds.c b/trunk/drivers/net/wireless/rtl818x/rtl8187/leds.c index c2d5b495c179..2e0de2f5f0f9 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187/leds.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187/leds.c @@ -117,7 +117,7 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, radio_on = true; } else if (radio_on) { radio_on = false; - cancel_delayed_work(&priv->led_on); + cancel_delayed_work_sync(&priv->led_on); ieee80211_queue_delayed_work(hw, &priv->led_off, 0); } } else if (radio_on) { diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b1b199..d228358e6a40 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -301,11 +301,9 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ - {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ - {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ @@ -348,7 +346,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ - {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ diff --git a/trunk/drivers/net/wireless/ti/wl1251/acx.c b/trunk/drivers/net/wireless/ti/wl1251/acx.c index db6430c1a084..ad87a1ac6462 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/acx.c +++ b/trunk/drivers/net/wireless/ti/wl1251/acx.c @@ -869,7 +869,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) } *mactime = tsf_info->current_tsf_lsb | - ((u64)tsf_info->current_tsf_msb << 32); + (tsf_info->current_tsf_msb << 31); out: kfree(tsf_info); diff --git a/trunk/drivers/net/wireless/ti/wl1251/event.c b/trunk/drivers/net/wireless/ti/wl1251/event.c index 5ec50a476a69..9f15ccaf8f05 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/event.c +++ b/trunk/drivers/net/wireless/ti/wl1251/event.c @@ -76,7 +76,8 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) } } - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && + wl->station_mode != STATION_ACTIVE_MODE) { wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); /* indicate to the stack, that beacons have been lost */ diff --git a/trunk/drivers/net/wireless/ti/wl1251/spi.c b/trunk/drivers/net/wireless/ti/wl1251/spi.c index 567660cd2fcd..87f6305bda2c 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/spi.c +++ b/trunk/drivers/net/wireless/ti/wl1251/spi.c @@ -73,8 +73,6 @@ static void wl1251_spi_reset(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); - - kfree(cmd); } static void wl1251_spi_wake(struct wl1251 *wl) @@ -129,8 +127,6 @@ static void wl1251_spi_wake(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); - - kfree(cmd); } static void wl1251_spi_reset_wake(struct wl1251 *wl) diff --git a/trunk/drivers/net/wireless/ti/wlcore/Kconfig b/trunk/drivers/net/wireless/ti/wlcore/Kconfig index d7b907e67170..54156b0b5c2d 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/Kconfig +++ b/trunk/drivers/net/wireless/ti/wlcore/Kconfig @@ -1,6 +1,7 @@ config WLCORE tristate "TI wlcore support" depends on WL_TI && GENERIC_HARDIRQS && MAC80211 + depends on INET select FW_LOADER ---help--- This module contains the main code for TI WLAN chips. It abstracts diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index 30899901aef5..2027afe405fe 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -1935,14 +1935,14 @@ static int __devexit xennet_remove(struct xenbus_device *dev) dev_dbg(&dev->dev, "%s\n", dev->nodename); - xennet_disconnect_backend(info); - - xennet_sysfs_delif(info->netdev); - unregister_netdev(info->netdev); + xennet_disconnect_backend(info); + del_timer_sync(&info->rx_refill_timer); + xennet_sysfs_delif(info->netdev); + free_percpu(info->stats); free_netdev(info->netdev); diff --git a/trunk/drivers/of/platform.c b/trunk/drivers/of/platform.c index e44f8c2d239d..343ad29e211c 100644 --- a/trunk/drivers/of/platform.c +++ b/trunk/drivers/of/platform.c @@ -317,9 +317,10 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l for(; lookup->compatible != NULL; lookup++) { if (!of_device_is_compatible(np, lookup->compatible)) continue; - if (!of_address_to_resource(np, 0, &res)) - if (res.start != lookup->phys_addr) - continue; + if (of_address_to_resource(np, 0, &res)) + continue; + if (res.start != lookup->phys_addr) + continue; pr_debug("%s: devname=%s\n", np->full_name, lookup->name); return lookup; } @@ -461,5 +462,4 @@ int of_platform_populate(struct device_node *root, of_node_put(root); return rc; } -EXPORT_SYMBOL_GPL(of_platform_populate); #endif /* CONFIG_OF_ADDRESS */ diff --git a/trunk/drivers/oprofile/oprofile_perf.c b/trunk/drivers/oprofile/oprofile_perf.c index f3cfa0b9adfa..da14432806c6 100644 --- a/trunk/drivers/oprofile/oprofile_perf.c +++ b/trunk/drivers/oprofile/oprofile_perf.c @@ -1,6 +1,5 @@ /* * Copyright 2010 ARM Ltd. - * Copyright 2012 Advanced Micro Devices, Inc., Robert Richter * * Perf-events backend for OProfile. */ @@ -26,7 +25,7 @@ static int oprofile_perf_enabled; static DEFINE_MUTEX(oprofile_perf_mutex); static struct op_counter_config *counter_config; -static DEFINE_PER_CPU(struct perf_event **, perf_events); +static struct perf_event **perf_events[nr_cpumask_bits]; static int num_counters; /* @@ -39,7 +38,7 @@ static void op_overflow_handler(struct perf_event *event, u32 cpu = smp_processor_id(); for (id = 0; id < num_counters; ++id) - if (per_cpu(perf_events, cpu)[id] == event) + if (perf_events[cpu][id] == event) break; if (id != num_counters) @@ -75,7 +74,7 @@ static int op_create_counter(int cpu, int event) { struct perf_event *pevent; - if (!counter_config[event].enabled || per_cpu(perf_events, cpu)[event]) + if (!counter_config[event].enabled || perf_events[cpu][event]) return 0; pevent = perf_event_create_kernel_counter(&counter_config[event].attr, @@ -92,18 +91,18 @@ static int op_create_counter(int cpu, int event) return -EBUSY; } - per_cpu(perf_events, cpu)[event] = pevent; + perf_events[cpu][event] = pevent; return 0; } static void op_destroy_counter(int cpu, int event) { - struct perf_event *pevent = per_cpu(perf_events, cpu)[event]; + struct perf_event *pevent = perf_events[cpu][event]; if (pevent) { perf_event_release_kernel(pevent); - per_cpu(perf_events, cpu)[event] = NULL; + perf_events[cpu][event] = NULL; } } @@ -258,12 +257,12 @@ void oprofile_perf_exit(void) for_each_possible_cpu(cpu) { for (id = 0; id < num_counters; ++id) { - event = per_cpu(perf_events, cpu)[id]; + event = perf_events[cpu][id]; if (event) perf_event_release_kernel(event); } - kfree(per_cpu(perf_events, cpu)); + kfree(perf_events[cpu]); } kfree(counter_config); @@ -278,6 +277,8 @@ int __init oprofile_perf_init(struct oprofile_operations *ops) if (ret) return ret; + memset(&perf_events, 0, sizeof(perf_events)); + num_counters = perf_num_counters(); if (num_counters <= 0) { pr_info("oprofile: no performance counters\n"); @@ -297,9 +298,9 @@ int __init oprofile_perf_init(struct oprofile_operations *ops) } for_each_possible_cpu(cpu) { - per_cpu(perf_events, cpu) = kcalloc(num_counters, + perf_events[cpu] = kcalloc(num_counters, sizeof(struct perf_event *), GFP_KERNEL); - if (!per_cpu(perf_events, cpu)) { + if (!perf_events[cpu]) { pr_info("oprofile: failed to allocate %d perf events " "for cpu %d\n", num_counters, cpu); ret = -ENOMEM; diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 099f46cd8e87..bf0cee629b60 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -748,18 +748,6 @@ static int pci_pm_suspend_noirq(struct device *dev) pci_pm_set_unknown_state(pci_dev); - /* - * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's - * PCI COMMAND register isn't 0, the BIOS assumes that the controller - * hasn't been quiesced and tries to turn it off. If the controller - * is already in D3, this can hang or cause memory corruption. - * - * Since the value of the COMMAND register doesn't matter once the - * device has been suspended, we can safely set it to 0 here. - */ - if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) - pci_write_config_word(pci_dev, PCI_COMMAND, 0); - return 0; } diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index 0cc053af70bd..c3b331b74fa0 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -61,7 +61,7 @@ static LIST_HEAD(pinctrl_maps); list_for_each_entry(_maps_node_, &pinctrl_maps, node) \ for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \ _i_ < _maps_node_->num_maps; \ - _i_++, _map_ = &_maps_node_->maps[_i_]) + i++, _map_ = &_maps_node_->maps[_i_]) /** * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support diff --git a/trunk/drivers/pinctrl/pinctrl-imx.c b/trunk/drivers/pinctrl/pinctrl-imx.c index 90c837f469a6..f6e7c670906c 100644 --- a/trunk/drivers/pinctrl/pinctrl-imx.c +++ b/trunk/drivers/pinctrl/pinctrl-imx.c @@ -27,16 +27,16 @@ #include "core.h" #include "pinctrl-imx.h" -#define IMX_PMX_DUMP(info, p, m, c, n) \ -{ \ - int i, j; \ - printk(KERN_DEBUG "Format: Pin Mux Config\n"); \ - for (i = 0; i < n; i++) { \ - j = p[i]; \ - printk(KERN_DEBUG "%s %d 0x%lx\n", \ - info->pins[j].name, \ - m[i], c[i]); \ - } \ +#define IMX_PMX_DUMP(info, p, m, c, n) \ +{ \ + int i, j; \ + printk("Format: Pin Mux Config\n"); \ + for (i = 0; i < n; i++) { \ + j = p[i]; \ + printk("%s %d 0x%lx\n", \ + info->pins[j].name, \ + m[i], c[i]); \ + } \ } /* The bits in CONFIG cell defined in binding doc*/ @@ -173,10 +173,8 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, /* create mux map */ parent = of_get_parent(np); - if (!parent) { - kfree(new_map); + if (!parent) return -EINVAL; - } new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; new_map[0].data.mux.function = parent->name; new_map[0].data.mux.group = np->name; @@ -195,7 +193,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, } dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", - (*map)->data.mux.function, (*map)->data.mux.group, map_num); + new_map->data.mux.function, new_map->data.mux.group, map_num); return 0; } @@ -203,7 +201,10 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, static void imx_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { - kfree(map); + int i; + + for (i = 0; i < num_maps; i++) + kfree(map); } static struct pinctrl_ops imx_pctrl_ops = { @@ -477,7 +478,6 @@ static int __devinit imx_pinctrl_parse_groups(struct device_node *np, #ifdef DEBUG IMX_PMX_DUMP(info, grp->pins, grp->mux_mode, grp->configs, grp->npins); #endif - return 0; } diff --git a/trunk/drivers/pinctrl/pinctrl-imx6q.c b/trunk/drivers/pinctrl/pinctrl-imx6q.c index e9bf71fbedca..7737d4d71a3c 100644 --- a/trunk/drivers/pinctrl/pinctrl-imx6q.c +++ b/trunk/drivers/pinctrl/pinctrl-imx6q.c @@ -1950,8 +1950,6 @@ static struct imx_pin_reg imx6q_pin_regs[] = { IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__GPIO_1_12 */ IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__SJC_DONE */ IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 0, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_1__ANATOP_USBOTG_ID */ }; /* Pad names for the pinmux subsystem */ diff --git a/trunk/drivers/pinctrl/pinctrl-mxs.c b/trunk/drivers/pinctrl/pinctrl-mxs.c index 4ba4636b6a4a..556e45a213eb 100644 --- a/trunk/drivers/pinctrl/pinctrl-mxs.c +++ b/trunk/drivers/pinctrl/pinctrl-mxs.c @@ -107,10 +107,8 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, /* Compose group name */ group = kzalloc(length, GFP_KERNEL); - if (!group) { - ret = -ENOMEM; - goto free; - } + if (!group) + return -ENOMEM; snprintf(group, length, "%s.%d", np->name, reg); new_map[i].data.mux.group = group; i++; @@ -120,7 +118,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); if (!pconfig) { ret = -ENOMEM; - goto free_group; + goto free; } new_map[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; @@ -135,9 +133,6 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; -free_group: - if (!purecfg) - kfree(group); free: kfree(new_map); return ret; @@ -516,7 +511,6 @@ int __devinit mxs_pinctrl_probe(struct platform_device *pdev, return 0; err: - platform_set_drvdata(pdev, NULL); iounmap(d->base); return ret; } @@ -526,7 +520,6 @@ int __devexit mxs_pinctrl_remove(struct platform_device *pdev) { struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); pinctrl_unregister(d->pctl); iounmap(d->base); diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik.c b/trunk/drivers/pinctrl/pinctrl-nomadik.c index 3e7e47d6b385..b26395d16347 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik.c @@ -673,7 +673,7 @@ static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, * wakeup is anyhow controlled by the RIMSC and FIMSC registers. */ if (nmk_chip->sleepmode && on) { - __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP, + __nmk_gpio_set_slpm(nmk_chip, gpio % nmk_chip->chip.base, NMK_GPIO_SLPM_WAKEUP_ENABLE); } @@ -1246,7 +1246,6 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) ret = PTR_ERR(clk); goto out_unmap; } - clk_prepare(clk); nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { @@ -1438,27 +1437,7 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins); - /* - * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, - * we may pass through an undesired state. In this case we take - * some extra care. - * - * Safe sequence used to switch IOs between GPIO and Alternate-C mode: - * - Save SLPM registers (since we have a shadow register in the - * nmk_chip we're using that as backup) - * - Set SLPM=0 for the IOs you want to switch and others to 1 - * - Configure the GPIO registers for the IOs that are being switched - * - Set IOFORCE=1 - * - Modify the AFLSA/B registers for the IOs that are being switched - * - Set IOFORCE=0 - * - Restore SLPM registers - * - Any spurious wake up event during switch sequence to be ignored - * and cleared - * - * We REALLY need to save ALL slpm registers, because the external - * IOFORCE will switch *all* ports to their sleepmode setting to as - * to avoid glitches. (Not just one port!) - */ + /* Handle this special glitch on altfunction C */ glitch = (g->altsetting == NMK_GPIO_ALT_C); if (glitch) { diff --git a/trunk/drivers/pinctrl/pinctrl-sirf.c b/trunk/drivers/pinctrl/pinctrl-sirf.c index e9f8e7d11001..ba15b1a29e52 100644 --- a/trunk/drivers/pinctrl/pinctrl-sirf.c +++ b/trunk/drivers/pinctrl/pinctrl-sirf.c @@ -1184,7 +1184,7 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) return ret; } -static const struct of_device_id pinmux_ids[] __devinitconst = { +static const struct of_device_id pinmux_ids[] = { { .compatible = "sirf,prima2-gpio-pinmux" }, {} }; diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.c b/trunk/drivers/pinctrl/spear/pinctrl-spear.c index b3f6b2873fdd..5ae50aadf885 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired from: * - U300 Pinctl drivers diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.h b/trunk/drivers/pinctrl/spear/pinctrl-spear.h index d950eb78d939..9155783bb47f 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.h +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.h @@ -2,7 +2,7 @@ * Driver header file for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c index d6cca8c81b92..fff168be7f00 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -2192,7 +2192,7 @@ static void __exit spear1310_pinctrl_exit(void) } module_exit(spear1310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c index a0eb057e55bd..a8ab2a6f51bf 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1340 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -1983,7 +1983,7 @@ static void __exit spear1340_pinctrl_exit(void) } module_exit(spear1340_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear300.c b/trunk/drivers/pinctrl/spear/pinctrl-spear300.c index 4dfc2849b172..9c82a35e4e78 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear300.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr300 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -702,7 +702,7 @@ static void __exit spear300_pinctrl_exit(void) } module_exit(spear300_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear310.c b/trunk/drivers/pinctrl/spear/pinctrl-spear310.c index 96883693fb7e..1a9707605125 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -425,7 +425,7 @@ static void __exit spear310_pinctrl_exit(void) } module_exit(spear310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c index 020b1e0bdb3e..de726e6c283a 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr320 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -3462,7 +3462,7 @@ static void __exit spear320_pinctrl_exit(void) } module_exit(spear320_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c index 0242378f7cb8..91c883bc46a6 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h index 31f44347f17c..5d5fdd8df7b8 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -2,7 +2,7 @@ * Header file for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index c8f40c9c0428..ce875dc365e5 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -1877,7 +1877,8 @@ static int acer_platform_remove(struct platform_device *device) return 0; } -static int acer_suspend(struct device *dev) +static int acer_platform_suspend(struct platform_device *dev, +pm_message_t state) { u32 value; struct acer_data *data = &interface->data; @@ -1899,7 +1900,7 @@ static int acer_suspend(struct device *dev) return 0; } -static int acer_resume(struct device *dev) +static int acer_platform_resume(struct platform_device *device) { struct acer_data *data = &interface->data; @@ -1915,8 +1916,6 @@ static int acer_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); - static void acer_platform_shutdown(struct platform_device *device) { struct acer_data *data = &interface->data; @@ -1932,10 +1931,11 @@ static struct platform_driver acer_platform_driver = { .driver = { .name = "acer-wmi", .owner = THIS_MODULE, - .pm = &acer_pm, }, .probe = acer_platform_probe, .remove = acer_platform_remove, + .suspend = acer_platform_suspend, + .resume = acer_platform_resume, .shutdown = acer_platform_shutdown, }; diff --git a/trunk/drivers/platform/x86/acerhdf.c b/trunk/drivers/platform/x86/acerhdf.c index 2fd9d36acd15..639db4d0aa76 100644 --- a/trunk/drivers/platform/x86/acerhdf.c +++ b/trunk/drivers/platform/x86/acerhdf.c @@ -5,7 +5,7 @@ * * (C) 2009 - Peter Feuerer peter (a) piie.net * http://piie.net - * 2009 Borislav Petkov bp (a) alien8.de + * 2009 Borislav Petkov * * Inspired by and many thanks to: * o acerfand - Rachel Greenham diff --git a/trunk/drivers/platform/x86/classmate-laptop.c b/trunk/drivers/platform/x86/classmate-laptop.c index e2230a2b2f8e..94f93b621d7b 100644 --- a/trunk/drivers/platform/x86/classmate-laptop.c +++ b/trunk/drivers/platform/x86/classmate-laptop.c @@ -362,18 +362,15 @@ static int cmpc_tablet_remove(struct acpi_device *acpi, int type) return cmpc_remove_acpi_notify_device(acpi); } -static int cmpc_tablet_resume(struct device *dev) +static int cmpc_tablet_resume(struct acpi_device *acpi) { - struct input_dev *inputdev = dev_get_drvdata(dev); - + struct input_dev *inputdev = dev_get_drvdata(&acpi->dev); unsigned long long val = 0; - if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) + if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) input_report_switch(inputdev, SW_TABLET_MODE, !val); return 0; } -static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); - static const struct acpi_device_id cmpc_tablet_device_ids[] = { {CMPC_TABLET_HID, 0}, {"", 0} @@ -387,9 +384,9 @@ static struct acpi_driver cmpc_tablet_acpi_driver = { .ops = { .add = cmpc_tablet_add, .remove = cmpc_tablet_remove, + .resume = cmpc_tablet_resume, .notify = cmpc_tablet_handler, - }, - .drv.pm = &cmpc_tablet_pm, + } }; diff --git a/trunk/drivers/platform/x86/fujitsu-tablet.c b/trunk/drivers/platform/x86/fujitsu-tablet.c index d2e41735a47b..da267eae8ba8 100644 --- a/trunk/drivers/platform/x86/fujitsu-tablet.c +++ b/trunk/drivers/platform/x86/fujitsu-tablet.c @@ -440,14 +440,12 @@ static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) return 0; } -static int acpi_fujitsu_resume(struct device *dev) +static int acpi_fujitsu_resume(struct acpi_device *adev) { fujitsu_reset(); return 0; } -static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); - static struct acpi_driver acpi_fujitsu_driver = { .name = MODULENAME, .class = "hotkey", @@ -455,8 +453,8 @@ static struct acpi_driver acpi_fujitsu_driver = { .ops = { .add = acpi_fujitsu_add, .remove = acpi_fujitsu_remove, - }, - .drv.pm = &acpi_fujitsu_pm, + .resume = acpi_fujitsu_resume, + } }; static int __init fujitsu_module_init(void) diff --git a/trunk/drivers/platform/x86/hdaps.c b/trunk/drivers/platform/x86/hdaps.c index d9ab6f64dcec..24a3ae065f1b 100644 --- a/trunk/drivers/platform/x86/hdaps.c +++ b/trunk/drivers/platform/x86/hdaps.c @@ -305,19 +305,17 @@ static int hdaps_probe(struct platform_device *dev) return 0; } -static int hdaps_resume(struct device *dev) +static int hdaps_resume(struct platform_device *dev) { return hdaps_device_init(); } -static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume); - static struct platform_driver hdaps_driver = { .probe = hdaps_probe, + .resume = hdaps_resume, .driver = { .name = "hdaps", .owner = THIS_MODULE, - .pm = &hdaps_pm, }, }; diff --git a/trunk/drivers/platform/x86/hp_accel.c b/trunk/drivers/platform/x86/hp_accel.c index f4d91154ad67..22b2dfa73148 100644 --- a/trunk/drivers/platform/x86/hp_accel.c +++ b/trunk/drivers/platform/x86/hp_accel.c @@ -353,22 +353,20 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) #ifdef CONFIG_PM -static int lis3lv02d_suspend(struct device *dev) +static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) { /* make sure the device is off when we suspend */ lis3lv02d_poweroff(&lis3_dev); return 0; } -static int lis3lv02d_resume(struct device *dev) +static int lis3lv02d_resume(struct acpi_device *device) { return lis3lv02d_poweron(&lis3_dev); } - -static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); -#define HP_ACCEL_PM (&hp_accel_pm) #else -#define HP_ACCEL_PM NULL +#define lis3lv02d_suspend NULL +#define lis3lv02d_resume NULL #endif /* For the HP MDPS aka 3D Driveguard */ @@ -379,8 +377,9 @@ static struct acpi_driver lis3lv02d_driver = { .ops = { .add = lis3lv02d_add, .remove = lis3lv02d_remove, - }, - .drv.pm = HP_ACCEL_PM, + .suspend = lis3lv02d_suspend, + .resume = lis3lv02d_resume, + } }; static int __init lis3lv02d_init_module(void) diff --git a/trunk/drivers/platform/x86/ideapad-laptop.c b/trunk/drivers/platform/x86/ideapad-laptop.c index 17f6dfd8dbfb..4f20f8dd3d7c 100644 --- a/trunk/drivers/platform/x86/ideapad-laptop.c +++ b/trunk/drivers/platform/x86/ideapad-laptop.c @@ -694,10 +694,10 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); static int __devinit ideapad_acpi_add(struct acpi_device *adevice) { int ret, i; - int cfg; + unsigned long cfg; struct ideapad_private *priv; - if (read_method_int(adevice->handle, "_CFG", &cfg)) + if (read_method_int(adevice->handle, "_CFG", (int *)&cfg)) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -721,7 +721,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) goto input_failed; for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { - if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) + if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg)) ideapad_register_rfkill(adevice, i); else priv->rfk[i] = NULL; diff --git a/trunk/drivers/platform/x86/intel_ips.c b/trunk/drivers/platform/x86/intel_ips.c index 5051aa970e0a..0ffdb3cde2bb 100644 --- a/trunk/drivers/platform/x86/intel_ips.c +++ b/trunk/drivers/platform/x86/intel_ips.c @@ -72,7 +72,6 @@ #include #include #include -#include #include #include #include @@ -1486,24 +1485,6 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { MODULE_DEVICE_TABLE(pci, ips_id_table); -static int ips_blacklist_callback(const struct dmi_system_id *id) -{ - pr_info("Blacklisted intel_ips for %s\n", id->ident); - return 1; -} - -static const struct dmi_system_id ips_blacklist[] = { - { - .callback = ips_blacklist_callback, - .ident = "HP ProBook", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), - }, - }, - { } /* terminating entry */ -}; - static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) { u64 platform_info; @@ -1513,9 +1494,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) u16 htshi, trc, trc_required_mask; u8 tse; - if (dmi_check_system(ips_blacklist)) - return -ENODEV; - ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); if (!ips) return -ENOMEM; @@ -1719,6 +1697,21 @@ static void ips_remove(struct pci_dev *dev) dev_dbg(&dev->dev, "IPS driver removed\n"); } +#ifdef CONFIG_PM +static int ips_suspend(struct pci_dev *dev, pm_message_t state) +{ + return 0; +} + +static int ips_resume(struct pci_dev *dev) +{ + return 0; +} +#else +#define ips_suspend NULL +#define ips_resume NULL +#endif /* CONFIG_PM */ + static void ips_shutdown(struct pci_dev *dev) { } @@ -1728,6 +1721,8 @@ static struct pci_driver ips_pci_driver = { .id_table = ips_id_table, .probe = ips_probe, .remove = ips_remove, + .suspend = ips_suspend, + .resume = ips_resume, .shutdown = ips_shutdown, }; diff --git a/trunk/drivers/platform/x86/intel_mid_thermal.c b/trunk/drivers/platform/x86/intel_mid_thermal.c index ea7422f6fa03..5ae9cd9c7e6e 100644 --- a/trunk/drivers/platform/x86/intel_mid_thermal.c +++ b/trunk/drivers/platform/x86/intel_mid_thermal.c @@ -418,23 +418,23 @@ static struct thermal_device_info *initialize_sensor(int index) /** * mid_thermal_resume - resume routine - * @dev: device structure + * @pdev: platform device structure * * mid thermal resume: re-initializes the adc. Can sleep. */ -static int mid_thermal_resume(struct device *dev) +static int mid_thermal_resume(struct platform_device *pdev) { - return mid_initialize_adc(dev); + return mid_initialize_adc(&pdev->dev); } /** * mid_thermal_suspend - suspend routine - * @dev: device structure + * @pdev: platform device structure * * mid thermal suspend implements the suspend functionality * by stopping the ADC. Can sleep. */ -static int mid_thermal_suspend(struct device *dev) +static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) { /* * This just stops the ADC and does not disable it. @@ -444,9 +444,6 @@ static int mid_thermal_suspend(struct device *dev) return configure_adc(0); } -static SIMPLE_DEV_PM_OPS(mid_thermal_pm, - mid_thermal_suspend, mid_thermal_resume); - /** * read_curr_temp - reads the current temperature and stores in temp * @temp: holds the current temperature value after reading @@ -560,9 +557,10 @@ static struct platform_driver mid_thermal_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, - .pm = &mid_thermal_pm, }, .probe = mid_thermal_probe, + .suspend = mid_thermal_suspend, + .resume = mid_thermal_resume, .remove = __devexit_p(mid_thermal_remove), .id_table = therm_id_table, }; diff --git a/trunk/drivers/platform/x86/msi-laptop.c b/trunk/drivers/platform/x86/msi-laptop.c index f64441844317..bb5132128b33 100644 --- a/trunk/drivers/platform/x86/msi-laptop.c +++ b/trunk/drivers/platform/x86/msi-laptop.c @@ -85,8 +85,7 @@ #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 #define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) -static int msi_laptop_resume(struct device *device); -static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume); +static int msi_laptop_resume(struct platform_device *device); #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f @@ -438,8 +437,8 @@ static struct platform_driver msipf_driver = { .driver = { .name = "msi-laptop-pf", .owner = THIS_MODULE, - .pm = &msi_laptop_pm, }, + .resume = msi_laptop_resume, }; static struct platform_device *msipf_device; @@ -753,7 +752,7 @@ static int rfkill_init(struct platform_device *sdev) return retval; } -static int msi_laptop_resume(struct device *device) +static int msi_laptop_resume(struct platform_device *device) { u8 data; int result; diff --git a/trunk/drivers/platform/x86/panasonic-laptop.c b/trunk/drivers/platform/x86/panasonic-laptop.c index 24480074bcf0..ffff8b4b4949 100644 --- a/trunk/drivers/platform/x86/panasonic-laptop.c +++ b/trunk/drivers/platform/x86/panasonic-laptop.c @@ -177,6 +177,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, static int acpi_pcc_hotkey_add(struct acpi_device *device); static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); +static int acpi_pcc_hotkey_resume(struct acpi_device *device); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id pcc_device_ids[] = { @@ -188,9 +189,6 @@ static const struct acpi_device_id pcc_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, pcc_device_ids); -static int acpi_pcc_hotkey_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); - static struct acpi_driver acpi_pcc_driver = { .name = ACPI_PCC_DRIVER_NAME, .class = ACPI_PCC_CLASS, @@ -198,9 +196,9 @@ static struct acpi_driver acpi_pcc_driver = { .ops = { .add = acpi_pcc_hotkey_add, .remove = acpi_pcc_hotkey_remove, + .resume = acpi_pcc_hotkey_resume, .notify = acpi_pcc_hotkey_notify, }, - .drv.pm = &acpi_pcc_hotkey_pm, }; static const struct key_entry panasonic_keymap[] = { @@ -540,15 +538,11 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc) /* kernel module interface */ -static int acpi_pcc_hotkey_resume(struct device *dev) +static int acpi_pcc_hotkey_resume(struct acpi_device *device) { - struct pcc_acpi *pcc; - - if (!dev) - return -EINVAL; + struct pcc_acpi *pcc = acpi_driver_data(device); - pcc = acpi_driver_data(to_acpi_device(dev)); - if (!pcc) + if (device == NULL || pcc == NULL) return -EINVAL; ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n", diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index 9363969ad07a..210d4ae547c2 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -973,7 +973,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buffer, size_t count) { - int value; + unsigned long value = 0; int ret = 0; struct sony_nc_value *item = container_of(attr, struct sony_nc_value, devattr); @@ -984,7 +984,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, if (count > 31) return -EINVAL; - if (kstrtoint(buffer, 10, &value)) + if (kstrtoul(buffer, 10, &value)) return -EINVAL; if (item->validate) @@ -994,7 +994,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, return value; ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, - &value, NULL); + (int *)&value, NULL); if (ret < 0) return -EIO; @@ -1010,7 +1010,6 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, struct sony_backlight_props { struct backlight_device *dev; int handle; - int cmd_base; u8 offset; u8 maxlvl; }; @@ -1038,7 +1037,7 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) struct sony_backlight_props *sdev = (struct sony_backlight_props *)bl_get_data(bd); - sony_call_snc_handle(sdev->handle, sdev->cmd_base + 0x100, &result); + sony_call_snc_handle(sdev->handle, 0x0200, &result); return (result & 0xff) - sdev->offset; } @@ -1050,8 +1049,7 @@ static int sony_nc_update_status_ng(struct backlight_device *bd) (struct sony_backlight_props *)bl_get_data(bd); value = bd->props.brightness + sdev->offset; - if (sony_call_snc_handle(sdev->handle, sdev->cmd_base | (value << 0x10), - &result)) + if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) return -EIO; return value; @@ -1174,11 +1172,6 @@ static int sony_nc_hotkeys_decode(u32 event, unsigned int handle) /* * ACPI callbacks */ -enum event_types { - HOTKEY = 1, - KILLSWITCH, - GFX_SWITCH -}; static void sony_nc_notify(struct acpi_device *device, u32 event) { u32 real_ev = event; @@ -1203,7 +1196,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) /* hotkey event */ case 0x0100: case 0x0127: - ev_type = HOTKEY; + ev_type = 1; real_ev = sony_nc_hotkeys_decode(event, handle); if (real_ev > 0) @@ -1223,7 +1216,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) * update the rfkill device status when the * switch is moved. */ - ev_type = KILLSWITCH; + ev_type = 2; sony_call_snc_handle(handle, 0x0100, &result); real_ev = result & 0x03; @@ -1233,24 +1226,6 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) break; - case 0x0128: - case 0x0146: - /* Hybrid GFX switching */ - sony_call_snc_handle(handle, 0x0000, &result); - dprintk("GFX switch event received (reason: %s)\n", - (result & 0x01) ? - "switch change" : "unknown"); - - /* verify the switch state - * 1: discrete GFX - * 0: integrated GFX - */ - sony_call_snc_handle(handle, 0x0100, &result); - - ev_type = GFX_SWITCH; - real_ev = result & 0xff; - break; - default: dprintk("Unknown event 0x%x for handle 0x%x\n", event, handle); @@ -1263,7 +1238,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) } else { /* old style event */ - ev_type = HOTKEY; + ev_type = 1; sony_laptop_report_input_event(real_ev); } @@ -1477,7 +1452,7 @@ static void sony_nc_function_resume(void) &result); } -static int sony_nc_resume(struct device *dev) +static int sony_nc_resume(struct acpi_device *device) { struct sony_nc_value *item; acpi_handle handle; @@ -1509,8 +1484,6 @@ static int sony_nc_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); - static void sony_nc_rfkill_cleanup(void) { int i; @@ -1920,33 +1893,32 @@ static ssize_t sony_nc_battery_care_limit_store(struct device *dev, * bits 4,5: store the limit into the EC * bits 6,7: store the limit into the battery */ - cmd = 0; - - if (value > 0) { - if (value <= 50) - cmd = 0x20; - else if (value <= 80) - cmd = 0x10; + /* + * handle 0x0115 should allow storing on battery too; + * handle 0x0136 same as 0x0115 + health status; + * handle 0x013f, same as 0x0136 but no storing on the battery + * + * Store only inside the EC for now, regardless the handle number + */ + if (value == 0) + /* disable limits */ + cmd = 0x0; - else if (value <= 100) - cmd = 0x30; + else if (value <= 50) + cmd = 0x21; - else - return -EINVAL; + else if (value <= 80) + cmd = 0x11; - /* - * handle 0x0115 should allow storing on battery too; - * handle 0x0136 same as 0x0115 + health status; - * handle 0x013f, same as 0x0136 but no storing on the battery - */ - if (bcare_ctl->handle != 0x013f) - cmd = cmd | (cmd << 2); + else if (value <= 100) + cmd = 0x31; - cmd = (cmd | 0x1) << 0x10; - } + else + return -EINVAL; - if (sony_call_snc_handle(bcare_ctl->handle, cmd | 0x0100, &result)) + if (sony_call_snc_handle(bcare_ctl->handle, (cmd << 0x10) | 0x0100, + &result)) return -EIO; return count; @@ -2141,7 +2113,7 @@ static ssize_t sony_nc_thermal_mode_show(struct device *dev, struct device_attribute *attr, char *buffer) { ssize_t count = 0; - int mode = sony_nc_thermal_mode_get(); + unsigned int mode = sony_nc_thermal_mode_get(); if (mode < 0) return mode; @@ -2500,7 +2472,6 @@ static void sony_nc_backlight_ng_read_limits(int handle, { u64 offset; int i; - int lvl_table_len = 0; u8 min = 0xff, max = 0x00; unsigned char buffer[32] = { 0 }; @@ -2509,6 +2480,8 @@ static void sony_nc_backlight_ng_read_limits(int handle, props->maxlvl = 0xff; offset = sony_find_snc_handle(handle); + if (offset < 0) + return; /* try to read the boundaries from ACPI tables, if we fail the above * defaults should be reasonable @@ -2518,21 +2491,11 @@ static void sony_nc_backlight_ng_read_limits(int handle, if (i < 0) return; - switch (handle) { - case 0x012f: - case 0x0137: - lvl_table_len = 9; - break; - case 0x143: - lvl_table_len = 16; - break; - } - /* the buffer lists brightness levels available, brightness levels are * from position 0 to 8 in the array, other values are used by ALS * control. */ - for (i = 0; i < lvl_table_len && i < ARRAY_SIZE(buffer); i++) { + for (i = 0; i < 9 && i < ARRAY_SIZE(buffer); i++) { dprintk("Brightness level: %d\n", buffer[i]); @@ -2557,24 +2520,16 @@ static void sony_nc_backlight_setup(void) const struct backlight_ops *ops = NULL; struct backlight_properties props; - if (sony_find_snc_handle(0x12f) >= 0) { + if (sony_find_snc_handle(0x12f) != -1) { ops = &sony_backlight_ng_ops; - sony_bl_props.cmd_base = 0x0100; sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; - } else if (sony_find_snc_handle(0x137) >= 0) { + } else if (sony_find_snc_handle(0x137) != -1) { ops = &sony_backlight_ng_ops; - sony_bl_props.cmd_base = 0x0100; sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; - } else if (sony_find_snc_handle(0x143) >= 0) { - ops = &sony_backlight_ng_ops; - sony_bl_props.cmd_base = 0x3000; - sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props); - max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; - } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &unused))) { ops = &sony_backlight_ops; @@ -2642,12 +2597,6 @@ static int sony_nc_add(struct acpi_device *device) } } - result = sony_laptop_setup_input(device); - if (result) { - pr_err("Unable to create input devices\n"); - goto outplatform; - } - if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", &handle))) { int arg = 1; @@ -2665,6 +2614,12 @@ static int sony_nc_add(struct acpi_device *device) } /* setup input devices and helper fifo */ + result = sony_laptop_setup_input(device); + if (result) { + pr_err("Unable to create input devices\n"); + goto outsnc; + } + if (acpi_video_backlight_support()) { pr_info("brightness ignored, must be controlled by ACPI video driver\n"); } else { @@ -2712,21 +2667,22 @@ static int sony_nc_add(struct acpi_device *device) return 0; -out_sysfs: + out_sysfs: for (item = sony_nc_values; item->name; ++item) { device_remove_file(&sony_pf_device->dev, &item->devattr); } sony_nc_backlight_cleanup(); - sony_nc_function_cleanup(sony_pf_device); - sony_nc_handles_cleanup(sony_pf_device); -outplatform: sony_laptop_remove_input(); -outpresent: + outsnc: + sony_nc_function_cleanup(sony_pf_device); + sony_nc_handles_cleanup(sony_pf_device); + + outpresent: sony_pf_remove(); -outwalk: + outwalk: sony_nc_rfkill_cleanup(); return result; } @@ -2772,9 +2728,9 @@ static struct acpi_driver sony_nc_driver = { .ops = { .add = sony_nc_add, .remove = sony_nc_remove, + .resume = sony_nc_resume, .notify = sony_nc_notify, }, - .drv.pm = &sony_nc_pm, }; /*********** SPIC (SNY6001) Device ***********/ @@ -4287,22 +4243,19 @@ static int sony_pic_add(struct acpi_device *device) return result; } -static int sony_pic_suspend(struct device *dev) +static int sony_pic_suspend(struct acpi_device *device, pm_message_t state) { - if (sony_pic_disable(to_acpi_device(dev))) + if (sony_pic_disable(device)) return -ENXIO; return 0; } -static int sony_pic_resume(struct device *dev) +static int sony_pic_resume(struct acpi_device *device) { - sony_pic_enable(to_acpi_device(dev), - spic_dev.cur_ioport, spic_dev.cur_irq); + sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); return 0; } -static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); - static const struct acpi_device_id sony_pic_device_ids[] = { {SONY_PIC_HID, 0}, {"", 0}, @@ -4316,8 +4269,9 @@ static struct acpi_driver sony_pic_driver = { .ops = { .add = sony_pic_add, .remove = sony_pic_remove, + .suspend = sony_pic_suspend, + .resume = sony_pic_resume, }, - .drv.pm = &sony_pic_pm, }; static struct dmi_system_id __initdata sonypi_dmi_table[] = { diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index d5fd4a1193f8..8b5610d88418 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -277,7 +277,7 @@ struct ibm_struct { int (*write) (char *); void (*exit) (void); void (*resume) (void); - void (*suspend) (void); + void (*suspend) (pm_message_t state); void (*shutdown) (void); struct list_head all_drivers; @@ -922,7 +922,8 @@ static struct input_dev *tpacpi_inputdev; static struct mutex tpacpi_inputdev_send_mutex; static LIST_HEAD(tpacpi_all_drivers); -static int tpacpi_suspend_handler(struct device *dev) +static int tpacpi_suspend_handler(struct platform_device *pdev, + pm_message_t state) { struct ibm_struct *ibm, *itmp; @@ -930,13 +931,13 @@ static int tpacpi_suspend_handler(struct device *dev) &tpacpi_all_drivers, all_drivers) { if (ibm->suspend) - (ibm->suspend)(); + (ibm->suspend)(state); } return 0; } -static int tpacpi_resume_handler(struct device *dev) +static int tpacpi_resume_handler(struct platform_device *pdev) { struct ibm_struct *ibm, *itmp; @@ -950,9 +951,6 @@ static int tpacpi_resume_handler(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(tpacpi_pm, - tpacpi_suspend_handler, tpacpi_resume_handler); - static void tpacpi_shutdown_handler(struct platform_device *pdev) { struct ibm_struct *ibm, *itmp; @@ -969,8 +967,9 @@ static struct platform_driver tpacpi_pdriver = { .driver = { .name = TPACPI_DRVR_NAME, .owner = THIS_MODULE, - .pm = &tpacpi_pm, }, + .suspend = tpacpi_suspend_handler, + .resume = tpacpi_resume_handler, .shutdown = tpacpi_shutdown_handler, }; @@ -3759,7 +3758,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } } -static void hotkey_suspend(void) +static void hotkey_suspend(pm_message_t state) { /* Do these on suspend, we get the events on early resume! */ hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; @@ -6330,7 +6329,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) return 0; } -static void brightness_suspend(void) +static void brightness_suspend(pm_message_t state) { tpacpi_brightness_checkpoint_nvram(); } @@ -6749,7 +6748,7 @@ static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = { .get = volume_alsa_mute_get, }; -static void volume_suspend(void) +static void volume_suspend(pm_message_t state) { tpacpi_volume_checkpoint_nvram(); } @@ -8108,7 +8107,7 @@ static void fan_exit(void) flush_workqueue(tpacpi_wq); } -static void fan_suspend(void) +static void fan_suspend(pm_message_t state) { int rc; diff --git a/trunk/drivers/platform/x86/toshiba_acpi.c b/trunk/drivers/platform/x86/toshiba_acpi.c index c13ba5bac93f..dab10f6edcd4 100644 --- a/trunk/drivers/platform/x86/toshiba_acpi.c +++ b/trunk/drivers/platform/x86/toshiba_acpi.c @@ -1296,9 +1296,10 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) } } -static int toshiba_acpi_suspend(struct device *device) +static int toshiba_acpi_suspend(struct acpi_device *acpi_dev, + pm_message_t state) { - struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); + struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 result; if (dev->hotkey_dev) @@ -1307,9 +1308,9 @@ static int toshiba_acpi_suspend(struct device *device) return 0; } -static int toshiba_acpi_resume(struct device *device) +static int toshiba_acpi_resume(struct acpi_device *acpi_dev) { - struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); + struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 result; if (dev->hotkey_dev) @@ -1318,9 +1319,6 @@ static int toshiba_acpi_resume(struct device *device) return 0; } -static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, - toshiba_acpi_suspend, toshiba_acpi_resume); - static struct acpi_driver toshiba_acpi_driver = { .name = "Toshiba ACPI driver", .owner = THIS_MODULE, @@ -1330,8 +1328,9 @@ static struct acpi_driver toshiba_acpi_driver = { .add = toshiba_acpi_add, .remove = toshiba_acpi_remove, .notify = toshiba_acpi_notify, + .suspend = toshiba_acpi_suspend, + .resume = toshiba_acpi_resume, }, - .drv.pm = &toshiba_acpi_pm, }; static int __init toshiba_acpi_init(void) diff --git a/trunk/drivers/platform/x86/toshiba_bluetooth.c b/trunk/drivers/platform/x86/toshiba_bluetooth.c index 715a43cb5e3c..5fb7186694df 100644 --- a/trunk/drivers/platform/x86/toshiba_bluetooth.c +++ b/trunk/drivers/platform/x86/toshiba_bluetooth.c @@ -34,6 +34,7 @@ MODULE_LICENSE("GPL"); static int toshiba_bt_rfkill_add(struct acpi_device *device); static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type); static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); +static int toshiba_bt_resume(struct acpi_device *device); static const struct acpi_device_id bt_device_ids[] = { { "TOS6205", 0}, @@ -41,9 +42,6 @@ static const struct acpi_device_id bt_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, bt_device_ids); -static int toshiba_bt_resume(struct device *dev); -static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); - static struct acpi_driver toshiba_bt_rfkill_driver = { .name = "Toshiba BT", .class = "Toshiba", @@ -52,9 +50,9 @@ static struct acpi_driver toshiba_bt_rfkill_driver = { .add = toshiba_bt_rfkill_add, .remove = toshiba_bt_rfkill_remove, .notify = toshiba_bt_rfkill_notify, + .resume = toshiba_bt_resume, }, .owner = THIS_MODULE, - .drv.pm = &toshiba_bt_pm, }; @@ -90,9 +88,9 @@ static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) toshiba_bluetooth_enable(device->handle); } -static int toshiba_bt_resume(struct device *dev) +static int toshiba_bt_resume(struct acpi_device *device) { - return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); + return toshiba_bluetooth_enable(device->handle); } static int toshiba_bt_rfkill_add(struct acpi_device *device) diff --git a/trunk/drivers/platform/x86/xo15-ebook.c b/trunk/drivers/platform/x86/xo15-ebook.c index 849c07c13bf6..fad153dc0355 100644 --- a/trunk/drivers/platform/x86/xo15-ebook.c +++ b/trunk/drivers/platform/x86/xo15-ebook.c @@ -77,13 +77,11 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event) } } -static int ebook_switch_resume(struct device *dev) +static int ebook_switch_resume(struct acpi_device *device) { - return ebook_send_state(to_acpi_device(dev)); + return ebook_send_state(device); } -static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); - static int ebook_switch_add(struct acpi_device *device) { struct ebook_switch *button; @@ -163,10 +161,10 @@ static struct acpi_driver xo15_ebook_driver = { .ids = ebook_device_ids, .ops = { .add = ebook_switch_add, + .resume = ebook_switch_resume, .remove = ebook_switch_remove, .notify = ebook_switch_notify, }, - .drv.pm = &ebook_switch_pm, }; static int __init xo15_ebook_init(void) diff --git a/trunk/drivers/regulator/Kconfig b/trunk/drivers/regulator/Kconfig index f34c3be6c9fe..c86b8864e411 100644 --- a/trunk/drivers/regulator/Kconfig +++ b/trunk/drivers/regulator/Kconfig @@ -20,7 +20,6 @@ menuconfig REGULATOR If unsure, say no. - if REGULATOR config REGULATOR_DEBUG @@ -89,13 +88,6 @@ config REGULATOR_AAT2870 If you have a AnalogicTech AAT2870 say Y to enable the regulator driver. -config REGULATOR_ARIZONA - tristate "Wolfson Arizona class devices" - depends on MFD_ARIZONA - help - Support for the regulators found on Wolfson Arizona class - devices. - config REGULATOR_DA903X tristate "Dialog Semiconductor DA9030/DA9034 regulators" depends on PMIC_DA903X @@ -203,14 +195,6 @@ config REGULATOR_MAX8998 via I2C bus. The provided regulator is suitable for S3C6410 and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. -config REGULATOR_MAX77686 - tristate "Maxim 77686 regulator" - depends on MFD_MAX77686 - help - This driver controls a Maxim 77686 regulator - via I2C bus. The provided regulator is suitable for - Exynos-4 chips to control VARM and VINT voltages. - config REGULATOR_PCAP tristate "Motorola PCAP2 regulator driver" depends on EZX_PCAP @@ -232,19 +216,6 @@ config REGULATOR_LP3972 Say Y here to support the voltage regulators and convertors on National Semiconductors LP3972 PMIC -config REGULATOR_LP872X - bool "TI/National Semiconductor LP8720/LP8725 voltage regulators" - depends on I2C=y - select REGMAP_I2C - help - This driver supports LP8720/LP8725 PMIC - -config REGULATOR_LP8788 - bool "TI LP8788 Power Regulators" - depends on MFD_LP8788 - help - This driver supports LP8788 voltage regulator chip. - config REGULATOR_PCF50633 tristate "NXP PCF50633 regulator driver" depends on MFD_PCF50633 @@ -262,14 +233,6 @@ config REGULATOR_RC5T583 through regulator interface. The device supports multiple DCDC/LDO outputs which can be controlled by i2c communication. -config REGULATOR_S2MPS11 - tristate "Samsung S2MPS11 voltage regulator" - depends on MFD_SEC_CORE - help - This driver supports a Samsung S2MPS11 voltage output regulator - via I2C bus. S2MPS11 is comprised of high efficient Buck converters - including Dual-Phase Buck converter, Buck-Boost converter, various LDOs. - config REGULATOR_S5M8767 tristate "Samsung S5M8767A voltage regulator" depends on MFD_S5M_CORE diff --git a/trunk/drivers/regulator/Makefile b/trunk/drivers/regulator/Makefile index 3342615cf25e..977fd46909ab 100644 --- a/trunk/drivers/regulator/Makefile +++ b/trunk/drivers/regulator/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o -obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o @@ -24,9 +23,6 @@ obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o -obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o -obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o -obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o @@ -34,7 +30,6 @@ obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o -obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o @@ -42,7 +37,6 @@ obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o -obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o diff --git a/trunk/drivers/regulator/aat2870-regulator.c b/trunk/drivers/regulator/aat2870-regulator.c index 6f45bfd22e83..06776ca945f2 100644 --- a/trunk/drivers/regulator/aat2870-regulator.c +++ b/trunk/drivers/regulator/aat2870-regulator.c @@ -33,6 +33,11 @@ struct aat2870_regulator { struct aat2870_data *aat2870; struct regulator_desc desc; + const int *voltages; /* uV */ + + int min_uV; + int max_uV; + u8 enable_addr; u8 enable_shift; u8 enable_mask; @@ -42,6 +47,14 @@ struct aat2870_regulator { u8 voltage_mask; }; +static int aat2870_ldo_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + struct aat2870_regulator *ri = rdev_get_drvdata(rdev); + + return ri->voltages[selector]; +} + static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { @@ -98,7 +111,7 @@ static int aat2870_ldo_is_enabled(struct regulator_dev *rdev) } static struct regulator_ops aat2870_ldo_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = aat2870_ldo_list_voltage, .set_voltage_sel = aat2870_ldo_set_voltage_sel, .get_voltage_sel = aat2870_ldo_get_voltage_sel, .enable = aat2870_ldo_enable, @@ -106,7 +119,7 @@ static struct regulator_ops aat2870_ldo_ops = { .is_enabled = aat2870_ldo_is_enabled, }; -static const unsigned int aat2870_ldo_voltages[] = { +static const int aat2870_ldo_voltages[] = { 1200000, 1300000, 1500000, 1600000, 1800000, 2000000, 2200000, 2500000, 2600000, 2700000, 2800000, 2900000, @@ -119,11 +132,13 @@ static const unsigned int aat2870_ldo_voltages[] = { .name = #ids, \ .id = AAT2870_ID_##ids, \ .n_voltages = ARRAY_SIZE(aat2870_ldo_voltages), \ - .volt_table = aat2870_ldo_voltages, \ .ops = &aat2870_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ + .voltages = aat2870_ldo_voltages, \ + .min_uV = 1200000, \ + .max_uV = 3300000, \ } static struct aat2870_regulator aat2870_regulators[] = { diff --git a/trunk/drivers/regulator/ab3100.c b/trunk/drivers/regulator/ab3100.c index 182b553059c9..03f4d9c604ec 100644 --- a/trunk/drivers/regulator/ab3100.c +++ b/trunk/drivers/regulator/ab3100.c @@ -43,12 +43,20 @@ * @dev: handle to the device * @plfdata: AB3100 platform data passed in at probe time * @regreg: regulator register number in the AB3100 + * @fixed_voltage: a fixed voltage for this regulator, if this + * 0 the voltages array is used instead. + * @typ_voltages: an array of available typical voltages for + * this regulator + * @voltages_len: length of the array of available voltages */ struct ab3100_regulator { struct regulator_dev *rdev; struct device *dev; struct ab3100_platform_data *plfdata; u8 regreg; + int fixed_voltage; + int const *typ_voltages; + u8 voltages_len; }; /* The order in which registers are initialized */ @@ -72,7 +80,7 @@ static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = { #define LDO_C_VOLTAGE 2650000 #define LDO_D_VOLTAGE 2650000 -static const unsigned int ldo_e_buck_typ_voltages[] = { +static const int ldo_e_buck_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -82,7 +90,7 @@ static const unsigned int ldo_e_buck_typ_voltages[] = { 900000, }; -static const unsigned int ldo_f_typ_voltages[] = { +static const int ldo_f_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -93,21 +101,21 @@ static const unsigned int ldo_f_typ_voltages[] = { 2650000, }; -static const unsigned int ldo_g_typ_voltages[] = { +static const int ldo_g_typ_voltages[] = { 2850000, 2750000, 1800000, 1500000, }; -static const unsigned int ldo_h_typ_voltages[] = { +static const int ldo_h_typ_voltages[] = { 2750000, 1800000, 1500000, 1200000, }; -static const unsigned int ldo_k_typ_voltages[] = { +static const int ldo_k_typ_voltages[] = { 2750000, 1800000, }; @@ -118,27 +126,40 @@ static struct ab3100_regulator ab3100_regulators[AB3100_NUM_REGULATORS] = { { .regreg = AB3100_LDO_A, + .fixed_voltage = LDO_A_VOLTAGE, }, { .regreg = AB3100_LDO_C, + .fixed_voltage = LDO_C_VOLTAGE, }, { .regreg = AB3100_LDO_D, + .fixed_voltage = LDO_D_VOLTAGE, }, { .regreg = AB3100_LDO_E, + .typ_voltages = ldo_e_buck_typ_voltages, + .voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages), }, { .regreg = AB3100_LDO_F, + .typ_voltages = ldo_f_typ_voltages, + .voltages_len = ARRAY_SIZE(ldo_f_typ_voltages), }, { .regreg = AB3100_LDO_G, + .typ_voltages = ldo_g_typ_voltages, + .voltages_len = ARRAY_SIZE(ldo_g_typ_voltages), }, { .regreg = AB3100_LDO_H, + .typ_voltages = ldo_h_typ_voltages, + .voltages_len = ARRAY_SIZE(ldo_h_typ_voltages), }, { .regreg = AB3100_LDO_K, + .typ_voltages = ldo_k_typ_voltages, + .voltages_len = ARRAY_SIZE(ldo_k_typ_voltages), }, { .regreg = AB3100_LDO_EXT, @@ -146,6 +167,8 @@ ab3100_regulators[AB3100_NUM_REGULATORS] = { }, { .regreg = AB3100_BUCK, + .typ_voltages = ldo_e_buck_typ_voltages, + .voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages), }, }; @@ -155,7 +178,7 @@ ab3100_regulators[AB3100_NUM_REGULATORS] = { */ static int ab3100_enable_regulator(struct regulator_dev *reg) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; int err; u8 regval; @@ -186,7 +209,7 @@ static int ab3100_enable_regulator(struct regulator_dev *reg) static int ab3100_disable_regulator(struct regulator_dev *reg) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; int err; u8 regval; @@ -219,7 +242,7 @@ static int ab3100_disable_regulator(struct regulator_dev *reg) static int ab3100_is_enabled_regulator(struct regulator_dev *reg) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; u8 regval; int err; @@ -234,12 +257,26 @@ static int ab3100_is_enabled_regulator(struct regulator_dev *reg) return regval & AB3100_REG_ON_MASK; } +static int ab3100_list_voltage_regulator(struct regulator_dev *reg, + unsigned selector) +{ + struct ab3100_regulator *abreg = reg->reg_data; + + if (selector >= abreg->voltages_len) + return -EINVAL; + return abreg->typ_voltages[selector]; +} + static int ab3100_get_voltage_regulator(struct regulator_dev *reg) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; u8 regval; int err; + /* Return the voltage for fixed regulators immediately */ + if (abreg->fixed_voltage) + return abreg->fixed_voltage; + /* * For variable types, read out setting and index into * supplied voltage list. @@ -257,20 +294,20 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg) regval &= 0xE0; regval >>= 5; - if (regval >= reg->desc->n_voltages) { + if (regval >= abreg->voltages_len) { dev_err(®->dev, "regulator register %02x contains an illegal voltage setting\n", abreg->regreg); return -EINVAL; } - return reg->desc->volt_table[regval]; + return abreg->typ_voltages[regval]; } static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg, unsigned selector) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; u8 regval; int err; @@ -299,7 +336,7 @@ static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg, static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, int uV) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; u8 regval; int err; int bestindex; @@ -342,22 +379,42 @@ static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, */ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) { - struct ab3100_regulator *abreg = rdev_get_drvdata(reg); + struct ab3100_regulator *abreg = reg->reg_data; return abreg->plfdata->external_voltage; } -static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg) +static int ab3100_enable_time_regulator(struct regulator_dev *reg) { - return reg->desc->min_uV; + struct ab3100_regulator *abreg = reg->reg_data; + + /* Per-regulator power on delay from spec */ + switch (abreg->regreg) { + case AB3100_LDO_A: /* Fallthrough */ + case AB3100_LDO_C: /* Fallthrough */ + case AB3100_LDO_D: /* Fallthrough */ + case AB3100_LDO_E: /* Fallthrough */ + case AB3100_LDO_H: /* Fallthrough */ + case AB3100_LDO_K: + return 200; + case AB3100_LDO_F: + return 600; + case AB3100_LDO_G: + return 400; + case AB3100_BUCK: + return 1000; + default: + break; + } + return 0; } static struct regulator_ops regulator_ops_fixed = { - .list_voltage = regulator_list_voltage_linear, .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, - .get_voltage = ab3100_get_fixed_voltage_regulator, + .get_voltage = ab3100_get_voltage_regulator, + .enable_time = ab3100_enable_time_regulator, }; static struct regulator_ops regulator_ops_variable = { @@ -366,7 +423,8 @@ static struct regulator_ops regulator_ops_variable = { .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator, .set_voltage_sel = ab3100_set_voltage_regulator_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = ab3100_list_voltage_regulator, + .enable_time = ab3100_enable_time_regulator, }; static struct regulator_ops regulator_ops_variable_sleepable = { @@ -376,7 +434,8 @@ static struct regulator_ops regulator_ops_variable_sleepable = { .get_voltage = ab3100_get_voltage_regulator, .set_voltage_sel = ab3100_set_voltage_regulator_sel, .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, - .list_voltage = regulator_list_voltage_table, + .list_voltage = ab3100_list_voltage_regulator, + .enable_time = ab3100_enable_time_regulator, }; /* @@ -398,81 +457,62 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .name = "LDO_A", .id = AB3100_LDO_A, .ops = ®ulator_ops_fixed, - .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_A_VOLTAGE, - .enable_time = 200, }, { .name = "LDO_C", .id = AB3100_LDO_C, .ops = ®ulator_ops_fixed, - .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_C_VOLTAGE, - .enable_time = 200, }, { .name = "LDO_D", .id = AB3100_LDO_D, .ops = ®ulator_ops_fixed, - .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_D_VOLTAGE, - .enable_time = 200, }, { .name = "LDO_E", .id = AB3100_LDO_E, .ops = ®ulator_ops_variable_sleepable, .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), - .volt_table = ldo_e_buck_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .enable_time = 200, }, { .name = "LDO_F", .id = AB3100_LDO_F, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), - .volt_table = ldo_f_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .enable_time = 600, }, { .name = "LDO_G", .id = AB3100_LDO_G, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), - .volt_table = ldo_g_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .enable_time = 400, }, { .name = "LDO_H", .id = AB3100_LDO_H, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), - .volt_table = ldo_h_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .enable_time = 200, }, { .name = "LDO_K", .id = AB3100_LDO_K, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), - .volt_table = ldo_k_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .enable_time = 200, }, { .name = "LDO_EXT", @@ -488,7 +528,6 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .enable_time = 1000, }, }; diff --git a/trunk/drivers/regulator/ab8500.c b/trunk/drivers/regulator/ab8500.c index 13d424fc1c14..e1b8c54ace5a 100644 --- a/trunk/drivers/regulator/ab8500.c +++ b/trunk/drivers/regulator/ab8500.c @@ -30,6 +30,9 @@ * @dev: device pointer * @desc: regulator description * @regulator_dev: regulator device + * @max_uV: maximum voltage (for variable voltage supplies) + * @min_uV: minimum voltage (for variable voltage supplies) + * @fixed_uV: typical voltage (for fixed voltage supplies) * @update_bank: bank to control on/off * @update_reg: register to control on/off * @update_mask: mask to enable/disable regulator @@ -37,12 +40,17 @@ * @voltage_bank: bank to control regulator voltage * @voltage_reg: register to control regulator voltage * @voltage_mask: mask to control regulator voltage + * @voltages: supported voltage table + * @voltages_len: number of supported voltages for the regulator * @delay: startup/set voltage delay in us */ struct ab8500_regulator_info { struct device *dev; struct regulator_desc desc; struct regulator_dev *regulator; + int max_uV; + int min_uV; + int fixed_uV; u8 update_bank; u8 update_reg; u8 update_mask; @@ -50,11 +58,13 @@ struct ab8500_regulator_info { u8 voltage_bank; u8 voltage_reg; u8 voltage_mask; + int const *voltages; + int voltages_len; unsigned int delay; }; /* voltage tables for the vauxn/vintcore supplies */ -static const unsigned int ldo_vauxn_voltages[] = { +static const int ldo_vauxn_voltages[] = { 1100000, 1200000, 1300000, @@ -73,7 +83,7 @@ static const unsigned int ldo_vauxn_voltages[] = { 3300000, }; -static const unsigned int ldo_vaux3_voltages[] = { +static const int ldo_vaux3_voltages[] = { 1200000, 1500000, 1800000, @@ -84,7 +94,7 @@ static const unsigned int ldo_vaux3_voltages[] = { 2910000, }; -static const unsigned int ldo_vintcore_voltages[] = { +static const int ldo_vintcore_voltages[] = { 1200000, 1225000, 1250000, @@ -175,6 +185,25 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) return false; } +static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + /* return the uV for the fixed regulators */ + if (info->fixed_uV) + return info->fixed_uV; + + if (selector >= info->voltages_len) + return -EINVAL; + + return info->voltages[selector]; +} + static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) { int ret, val; @@ -250,7 +279,14 @@ static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int new_sel) { struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + /* If the regulator isn't on, it won't take time here */ + ret = ab8500_regulator_is_enabled(rdev); + if (ret < 0) + return ret; + if (!ret) + return 0; return info->delay; } @@ -260,14 +296,21 @@ static struct regulator_ops ab8500_regulator_ops = { .is_enabled = ab8500_regulator_is_enabled, .get_voltage_sel = ab8500_regulator_get_voltage_sel, .set_voltage_sel = ab8500_regulator_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = ab8500_list_voltage, .enable_time = ab8500_regulator_enable_time, .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) { - return rdev->desc->min_uV; + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + return info->fixed_uV; } static struct regulator_ops ab8500_regulator_fixed_ops = { @@ -275,8 +318,9 @@ static struct regulator_ops ab8500_regulator_fixed_ops = { .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .get_voltage = ab8500_fixed_get_voltage, - .list_voltage = regulator_list_voltage_linear, + .list_voltage = ab8500_list_voltage, .enable_time = ab8500_regulator_enable_time, + .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; static struct ab8500_regulator_info @@ -285,7 +329,7 @@ static struct ab8500_regulator_info * Variable Voltage Regulators * name, min mV, max mV, * update bank, reg, mask, enable val - * volt bank, reg, mask + * volt bank, reg, mask, table, table length */ [AB8500_LDO_AUX1] = { .desc = { @@ -295,8 +339,9 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUX1, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), - .volt_table = ldo_vauxn_voltages, }, + .min_uV = 1100000, + .max_uV = 3300000, .update_bank = 0x04, .update_reg = 0x09, .update_mask = 0x03, @@ -304,6 +349,8 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x1f, .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), }, [AB8500_LDO_AUX2] = { .desc = { @@ -313,8 +360,9 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUX2, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), - .volt_table = ldo_vauxn_voltages, }, + .min_uV = 1100000, + .max_uV = 3300000, .update_bank = 0x04, .update_reg = 0x09, .update_mask = 0x0c, @@ -322,6 +370,8 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x20, .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), }, [AB8500_LDO_AUX3] = { .desc = { @@ -331,8 +381,9 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUX3, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), - .volt_table = ldo_vaux3_voltages, }, + .min_uV = 1100000, + .max_uV = 3300000, .update_bank = 0x04, .update_reg = 0x0a, .update_mask = 0x03, @@ -340,6 +391,8 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x21, .voltage_mask = 0x07, + .voltages = ldo_vaux3_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux3_voltages), }, [AB8500_LDO_INTCORE] = { .desc = { @@ -349,8 +402,9 @@ static struct ab8500_regulator_info .id = AB8500_LDO_INTCORE, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), - .volt_table = ldo_vintcore_voltages, }, + .min_uV = 1100000, + .max_uV = 3300000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x44, @@ -358,6 +412,8 @@ static struct ab8500_regulator_info .voltage_bank = 0x03, .voltage_reg = 0x80, .voltage_mask = 0x38, + .voltages = ldo_vintcore_voltages, + .voltages_len = ARRAY_SIZE(ldo_vintcore_voltages), }, /* @@ -373,9 +429,9 @@ static struct ab8500_regulator_info .id = AB8500_LDO_TVOUT, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 2000000, }, .delay = 10000, + .fixed_uV = 2000000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x82, @@ -389,8 +445,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_USB, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 3300000, }, + .fixed_uV = 3300000, .update_bank = 0x03, .update_reg = 0x82, .update_mask = 0x03, @@ -404,8 +460,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUDIO, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 2000000, }, + .fixed_uV = 2000000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x02, @@ -419,8 +475,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_ANAMIC1, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 2050000, }, + .fixed_uV = 2050000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x08, @@ -434,8 +490,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_ANAMIC2, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 2050000, }, + .fixed_uV = 2050000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x10, @@ -449,8 +505,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_DMIC, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 1800000, }, + .fixed_uV = 1800000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x04, @@ -464,8 +520,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_ANA, .owner = THIS_MODULE, .n_voltages = 1, - .min_uV = 1200000, }, + .fixed_uV = 1200000, .update_bank = 0x04, .update_reg = 0x06, .update_mask = 0x0c, @@ -713,7 +769,9 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, if (info->desc.id == AB8500_LDO_AUX3) { info->desc.n_voltages = ARRAY_SIZE(ldo_vauxn_voltages); - info->desc.volt_table = ldo_vauxn_voltages; + info->voltages = ldo_vauxn_voltages; + info->voltages_len = + ARRAY_SIZE(ldo_vauxn_voltages); info->voltage_mask = 0xf; } } @@ -736,17 +794,17 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, + { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, + { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, + { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, + { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, + { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, + { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, + { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, + { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, + { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, + { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, }; static __devinit int diff --git a/trunk/drivers/regulator/ad5398.c b/trunk/drivers/regulator/ad5398.c index f123f7e3b752..46d05f38baf8 100644 --- a/trunk/drivers/regulator/ad5398.c +++ b/trunk/drivers/regulator/ad5398.c @@ -89,12 +89,9 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int unsigned short data; int ret; - if (min_uA < chip->min_uA) - min_uA = chip->min_uA; - if (max_uA > chip->max_uA) - max_uA = chip->max_uA; - - if (min_uA > chip->max_uA || max_uA < chip->min_uA) + if (min_uA > chip->max_uA || min_uA < chip->min_uA) + return -EINVAL; + if (max_uA > chip->max_uA || max_uA < chip->min_uA) return -EINVAL; selector = DIV_ROUND_UP((min_uA - chip->min_uA) * chip->current_level, diff --git a/trunk/drivers/regulator/anatop-regulator.c b/trunk/drivers/regulator/anatop-regulator.c index e9c2085f9dfb..3660bace123c 100644 --- a/trunk/drivers/regulator/anatop-regulator.c +++ b/trunk/drivers/regulator/anatop-regulator.c @@ -43,15 +43,33 @@ struct anatop_regulator { struct regulator_init_data *initdata; }; -static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) +static int anatop_set_voltage(struct regulator_dev *reg, int min_uV, + int max_uV, unsigned *selector) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - u32 val, mask; + u32 val, sel, mask; + int uv; + + uv = min_uV; + dev_dbg(®->dev, "%s: uv %d, min %d, max %d\n", __func__, + uv, anatop_reg->min_voltage, + anatop_reg->max_voltage); + + if (uv < anatop_reg->min_voltage) { + if (max_uV > anatop_reg->min_voltage) + uv = anatop_reg->min_voltage; + else + return -EINVAL; + } if (!anatop_reg->control_reg) return -ENOTSUPP; - val = anatop_reg->min_bit_val + selector; + sel = DIV_ROUND_UP(uv - anatop_reg->min_voltage, 25000); + if (sel * 25000 + anatop_reg->min_voltage > anatop_reg->max_voltage) + return -EINVAL; + val = anatop_reg->min_bit_val + sel; + *selector = sel; dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); mask = ((1 << anatop_reg->vol_bit_width) - 1) << anatop_reg->vol_bit_shift; @@ -76,11 +94,21 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg) return val - anatop_reg->min_bit_val; } +static int anatop_list_voltage(struct regulator_dev *reg, unsigned selector) +{ + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); + int uv; + + uv = anatop_reg->min_voltage + selector * 25000; + dev_dbg(®->dev, "vddio = %d, selector = %u\n", uv, selector); + + return uv; +} + static struct regulator_ops anatop_rops = { - .set_voltage_sel = anatop_set_voltage_sel, + .set_voltage = anatop_set_voltage, .get_voltage_sel = anatop_get_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .list_voltage = anatop_list_voltage, }; static int __devinit anatop_regulator_probe(struct platform_device *pdev) @@ -148,8 +176,6 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1; - rdesc->min_uV = sreg->min_voltage; - rdesc->uV_step = 25000; config.dev = &pdev->dev; config.init_data = initdata; @@ -198,7 +224,7 @@ static struct platform_driver anatop_regulator_driver = { .of_match_table = of_anatop_regulator_match_tbl, }, .probe = anatop_regulator_probe, - .remove = __devexit_p(anatop_regulator_remove), + .remove = anatop_regulator_remove, }; static int __init anatop_regulator_init(void) diff --git a/trunk/drivers/regulator/arizona-ldo1.c b/trunk/drivers/regulator/arizona-ldo1.c deleted file mode 100644 index c8f95c07adb6..000000000000 --- a/trunk/drivers/regulator/arizona-ldo1.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * arizona-ldo1.c -- LDO1 supply for Arizona devices - * - * Copyright 2012 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * 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 - -struct arizona_ldo1 { - struct regulator_dev *regulator; - struct arizona *arizona; - - struct regulator_consumer_supply supply; - struct regulator_init_data init_data; -}; - -static struct regulator_ops arizona_ldo1_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, -}; - -static const struct regulator_desc arizona_ldo1 = { - .name = "LDO1", - .supply_name = "LDOVDD", - .type = REGULATOR_VOLTAGE, - .ops = &arizona_ldo1_ops, - - .vsel_reg = ARIZONA_LDO1_CONTROL_1, - .vsel_mask = ARIZONA_LDO1_VSEL_MASK, - .min_uV = 900000, - .uV_step = 50000, - .n_voltages = 7, - - .owner = THIS_MODULE, -}; - -static const struct regulator_init_data arizona_ldo1_default = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = 1, -}; - -static __devinit int arizona_ldo1_probe(struct platform_device *pdev) -{ - struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; - struct arizona_ldo1 *ldo1; - int ret; - - ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); - if (ldo1 == NULL) { - dev_err(&pdev->dev, "Unable to allocate private data\n"); - return -ENOMEM; - } - - ldo1->arizona = arizona; - - /* - * Since the chip usually supplies itself we provide some - * default init_data for it. This will be overridden with - * platform data if provided. - */ - ldo1->init_data = arizona_ldo1_default; - ldo1->init_data.consumer_supplies = &ldo1->supply; - ldo1->supply.supply = "DCVDD"; - ldo1->supply.dev_name = dev_name(arizona->dev); - - config.dev = arizona->dev; - config.driver_data = ldo1; - config.regmap = arizona->regmap; - config.ena_gpio = arizona->pdata.ldoena; - - if (arizona->pdata.ldo1) - config.init_data = arizona->pdata.ldo1; - else - config.init_data = &ldo1->init_data; - - ldo1->regulator = regulator_register(&arizona_ldo1, &config); - if (IS_ERR(ldo1->regulator)) { - ret = PTR_ERR(ldo1->regulator); - dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", - ret); - return ret; - } - - platform_set_drvdata(pdev, ldo1); - - return 0; -} - -static __devexit int arizona_ldo1_remove(struct platform_device *pdev) -{ - struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev); - - regulator_unregister(ldo1->regulator); - - return 0; -} - -static struct platform_driver arizona_ldo1_driver = { - .probe = arizona_ldo1_probe, - .remove = __devexit_p(arizona_ldo1_remove), - .driver = { - .name = "arizona-ldo1", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(arizona_ldo1_driver); - -/* Module information */ -MODULE_AUTHOR("Mark Brown "); -MODULE_DESCRIPTION("Arizona LDO1 driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:arizona-ldo1"); diff --git a/trunk/drivers/regulator/arizona-micsupp.c b/trunk/drivers/regulator/arizona-micsupp.c deleted file mode 100644 index 450a069aa9b6..000000000000 --- a/trunk/drivers/regulator/arizona-micsupp.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * arizona-micsupp.c -- Microphone supply for Arizona devices - * - * Copyright 2012 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * 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 - -#define ARIZONA_MICSUPP_MAX_SELECTOR 0x1f - -struct arizona_micsupp { - struct regulator_dev *regulator; - struct arizona *arizona; - - struct regulator_consumer_supply supply; - struct regulator_init_data init_data; -}; - -static int arizona_micsupp_list_voltage(struct regulator_dev *rdev, - unsigned int selector) -{ - if (selector > ARIZONA_MICSUPP_MAX_SELECTOR) - return -EINVAL; - - if (selector == ARIZONA_MICSUPP_MAX_SELECTOR) - return 3300000; - else - return (selector * 50000) + 1700000; -} - -static int arizona_micsupp_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - unsigned int voltage; - int selector; - - if (min_uV < 1700000) - min_uV = 1700000; - - if (min_uV > 3200000) - selector = ARIZONA_MICSUPP_MAX_SELECTOR; - else - selector = DIV_ROUND_UP(min_uV - 1700000, 50000); - - if (selector < 0) - return -EINVAL; - - voltage = arizona_micsupp_list_voltage(rdev, selector); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return selector; -} - -static struct regulator_ops arizona_micsupp_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - - .list_voltage = arizona_micsupp_list_voltage, - .map_voltage = arizona_micsupp_map_voltage, - - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, -}; - -static const struct regulator_desc arizona_micsupp = { - .name = "MICVDD", - .supply_name = "CPVDD", - .type = REGULATOR_VOLTAGE, - .n_voltages = ARIZONA_MICSUPP_MAX_SELECTOR + 1, - .ops = &arizona_micsupp_ops, - - .vsel_reg = ARIZONA_LDO2_CONTROL_1, - .vsel_mask = ARIZONA_LDO2_VSEL_MASK, - .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, - .enable_mask = ARIZONA_CPMIC_ENA, - - .owner = THIS_MODULE, -}; - -static const struct regulator_init_data arizona_micsupp_default = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS | - REGULATOR_CHANGE_VOLTAGE, - .min_uV = 1700000, - .max_uV = 3300000, - }, - - .num_consumer_supplies = 1, -}; - -static __devinit int arizona_micsupp_probe(struct platform_device *pdev) -{ - struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; - struct arizona_micsupp *micsupp; - int ret; - - micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); - if (micsupp == NULL) { - dev_err(&pdev->dev, "Unable to allocate private data\n"); - return -ENOMEM; - } - - micsupp->arizona = arizona; - - /* - * Since the chip usually supplies itself we provide some - * default init_data for it. This will be overridden with - * platform data if provided. - */ - micsupp->init_data = arizona_micsupp_default; - micsupp->init_data.consumer_supplies = &micsupp->supply; - micsupp->supply.supply = "MICVDD"; - micsupp->supply.dev_name = dev_name(arizona->dev); - - config.dev = arizona->dev; - config.driver_data = micsupp; - config.regmap = arizona->regmap; - - if (arizona->pdata.micvdd) - config.init_data = arizona->pdata.micvdd; - else - config.init_data = &micsupp->init_data; - - /* Default to regulated mode until the API supports bypass */ - regmap_update_bits(arizona->regmap, ARIZONA_MIC_CHARGE_PUMP_1, - ARIZONA_CPMIC_BYPASS, 0); - - micsupp->regulator = regulator_register(&arizona_micsupp, &config); - if (IS_ERR(micsupp->regulator)) { - ret = PTR_ERR(micsupp->regulator); - dev_err(arizona->dev, "Failed to register mic supply: %d\n", - ret); - return ret; - } - - platform_set_drvdata(pdev, micsupp); - - return 0; -} - -static __devexit int arizona_micsupp_remove(struct platform_device *pdev) -{ - struct arizona_micsupp *micsupp = platform_get_drvdata(pdev); - - regulator_unregister(micsupp->regulator); - - return 0; -} - -static struct platform_driver arizona_micsupp_driver = { - .probe = arizona_micsupp_probe, - .remove = __devexit_p(arizona_micsupp_remove), - .driver = { - .name = "arizona-micsupp", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(arizona_micsupp_driver); - -/* Module information */ -MODULE_AUTHOR("Mark Brown "); -MODULE_DESCRIPTION("Arizona microphone supply driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:arizona-micsupp"); diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index 2e31dffbefe7..7584a74eec8a 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -109,6 +108,28 @@ static const char *rdev_get_name(struct regulator_dev *rdev) return ""; } +/* gets the regulator for a given consumer device */ +static struct regulator *get_device_regulator(struct device *dev) +{ + struct regulator *regulator = NULL; + struct regulator_dev *rdev; + + mutex_lock(®ulator_list_mutex); + list_for_each_entry(rdev, ®ulator_list, list) { + mutex_lock(&rdev->mutex); + list_for_each_entry(regulator, &rdev->consumer_list, list) { + if (regulator->dev == dev) { + mutex_unlock(&rdev->mutex); + mutex_unlock(®ulator_list_mutex); + return regulator; + } + } + mutex_unlock(&rdev->mutex); + } + mutex_unlock(®ulator_list_mutex); + return NULL; +} + /** * of_get_regulator - get a regulator device node based on supply name * @dev: Device pointer for the consumer (of regulator) device @@ -282,6 +303,18 @@ static int regulator_check_drms(struct regulator_dev *rdev) return 0; } +static ssize_t device_requested_uA_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct regulator *regulator; + + regulator = get_device_regulator(dev); + if (regulator == NULL) + return 0; + + return sprintf(buf, "%d\n", regulator->uA_load); +} + static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -394,9 +427,6 @@ static ssize_t regulator_status_show(struct device *dev, case REGULATOR_STATUS_STANDBY: label = "standby"; break; - case REGULATOR_STATUS_UNDEFINED: - label = "undefined"; - break; default: return -ERANGE; } @@ -937,14 +967,6 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } - if (rdev->constraints->ramp_delay && ops->set_ramp_delay) { - ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay); - if (ret < 0) { - rdev_err(rdev, "failed to set ramp_delay\n"); - goto out; - } - } - print_constraints(rdev); return 0; out: @@ -1075,29 +1097,48 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, list_add(®ulator->list, &rdev->consumer_list); if (dev) { + /* create a 'requested_microamps_name' sysfs entry */ + size = scnprintf(buf, REG_STR_SIZE, + "microamps_requested_%s-%s", + dev_name(dev), supply_name); + if (size >= REG_STR_SIZE) + goto overflow_err; + regulator->dev = dev; + sysfs_attr_init(®ulator->dev_attr.attr); + regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL); + if (regulator->dev_attr.attr.name == NULL) + goto attr_name_err; + + regulator->dev_attr.attr.mode = 0444; + regulator->dev_attr.show = device_requested_uA_show; + err = device_create_file(dev, ®ulator->dev_attr); + if (err < 0) { + rdev_warn(rdev, "could not add regulator_dev requested microamps sysfs entry\n"); + goto attr_name_err; + } - /* Add a link to the device sysfs entry */ + /* also add a link to the device sysfs entry */ size = scnprintf(buf, REG_STR_SIZE, "%s-%s", dev->kobj.name, supply_name); if (size >= REG_STR_SIZE) - goto overflow_err; + goto attr_err; regulator->supply_name = kstrdup(buf, GFP_KERNEL); if (regulator->supply_name == NULL) - goto overflow_err; + goto attr_err; err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj, buf); if (err) { rdev_warn(rdev, "could not add device link %s err %d\n", dev->kobj.name, err); - /* non-fatal */ + goto link_name_err; } } else { regulator->supply_name = kstrdup(supply_name, GFP_KERNEL); if (regulator->supply_name == NULL) - goto overflow_err; + goto attr_err; } regulator->debugfs = debugfs_create_dir(regulator->supply_name, @@ -1124,6 +1165,12 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, mutex_unlock(&rdev->mutex); return regulator; +link_name_err: + kfree(regulator->supply_name); +attr_err: + device_remove_file(regulator->dev, ®ulator->dev_attr); +attr_name_err: + kfree(regulator->dev_attr.attr.name); overflow_err: list_del(®ulator->list); kfree(regulator); @@ -1134,7 +1181,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, static int _regulator_get_enable_time(struct regulator_dev *rdev) { if (!rdev->desc->ops->enable_time) - return rdev->desc->enable_time; + return 0; return rdev->desc->ops->enable_time(rdev); } @@ -1373,8 +1420,11 @@ void regulator_put(struct regulator *regulator) debugfs_remove_recursive(regulator->debugfs); /* remove any sysfs entries */ - if (regulator->dev) + if (regulator->dev) { sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); + device_remove_file(regulator->dev, ®ulator->dev_attr); + kfree(regulator->dev_attr.attr.name); + } kfree(regulator->supply_name); list_del(®ulator->list); kfree(regulator); @@ -1409,61 +1459,19 @@ void devm_regulator_put(struct regulator *regulator) { int rc; - rc = devres_release(regulator->dev, devm_regulator_release, + rc = devres_destroy(regulator->dev, devm_regulator_release, devm_regulator_match, regulator); - if (rc != 0) + if (rc == 0) + regulator_put(regulator); + else WARN_ON(rc); } EXPORT_SYMBOL_GPL(devm_regulator_put); -static int _regulator_do_enable(struct regulator_dev *rdev) -{ - int ret, delay; - - /* Query before enabling in case configuration dependent. */ - ret = _regulator_get_enable_time(rdev); - if (ret >= 0) { - delay = ret; - } else { - rdev_warn(rdev, "enable_time() failed: %d\n", ret); - delay = 0; - } - - trace_regulator_enable(rdev_get_name(rdev)); - - if (rdev->ena_gpio) { - gpio_set_value_cansleep(rdev->ena_gpio, - !rdev->ena_gpio_invert); - rdev->ena_gpio_state = 1; - } else if (rdev->desc->ops->enable) { - ret = rdev->desc->ops->enable(rdev); - if (ret < 0) - return ret; - } else { - return -EINVAL; - } - - /* Allow the regulator to ramp; it would be useful to extend - * this for bulk operations so that the regulators can ramp - * together. */ - trace_regulator_enable_delay(rdev_get_name(rdev)); - - if (delay >= 1000) { - mdelay(delay / 1000); - udelay(delay % 1000); - } else if (delay) { - udelay(delay); - } - - trace_regulator_enable_complete(rdev_get_name(rdev)); - - return 0; -} - /* locks held by regulator_enable() */ static int _regulator_enable(struct regulator_dev *rdev) { - int ret; + int ret, delay; /* check voltage and requested load before enabling */ if (rdev->constraints && @@ -1477,10 +1485,40 @@ static int _regulator_enable(struct regulator_dev *rdev) if (!_regulator_can_change_status(rdev)) return -EPERM; - ret = _regulator_do_enable(rdev); + if (!rdev->desc->ops->enable) + return -EINVAL; + + /* Query before enabling in case configuration + * dependent. */ + ret = _regulator_get_enable_time(rdev); + if (ret >= 0) { + delay = ret; + } else { + rdev_warn(rdev, "enable_time() failed: %d\n", + ret); + delay = 0; + } + + trace_regulator_enable(rdev_get_name(rdev)); + + /* Allow the regulator to ramp; it would be useful + * to extend this for bulk operations so that the + * regulators can ramp together. */ + ret = rdev->desc->ops->enable(rdev); if (ret < 0) return ret; + trace_regulator_enable_delay(rdev_get_name(rdev)); + + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); + } + + trace_regulator_enable_complete(rdev_get_name(rdev)); + } else if (ret < 0) { rdev_err(rdev, "is_enabled() failed: %d\n", ret); return ret; @@ -1529,30 +1567,6 @@ int regulator_enable(struct regulator *regulator) } EXPORT_SYMBOL_GPL(regulator_enable); -static int _regulator_do_disable(struct regulator_dev *rdev) -{ - int ret; - - trace_regulator_disable(rdev_get_name(rdev)); - - if (rdev->ena_gpio) { - gpio_set_value_cansleep(rdev->ena_gpio, - rdev->ena_gpio_invert); - rdev->ena_gpio_state = 0; - - } else if (rdev->desc->ops->disable) { - ret = rdev->desc->ops->disable(rdev); - if (ret != 0) - return ret; - } - - trace_regulator_disable_complete(rdev_get_name(rdev)); - - _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, - NULL); - return 0; -} - /* locks held by regulator_disable() */ static int _regulator_disable(struct regulator_dev *rdev) { @@ -1567,12 +1581,20 @@ static int _regulator_disable(struct regulator_dev *rdev) (rdev->constraints && !rdev->constraints->always_on)) { /* we are last user */ - if (_regulator_can_change_status(rdev)) { - ret = _regulator_do_disable(rdev); + if (_regulator_can_change_status(rdev) && + rdev->desc->ops->disable) { + trace_regulator_disable(rdev_get_name(rdev)); + + ret = rdev->desc->ops->disable(rdev); if (ret < 0) { rdev_err(rdev, "failed to disable\n"); return ret; } + + trace_regulator_disable_complete(rdev_get_name(rdev)); + + _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, + NULL); } rdev->use_count = 0; @@ -1790,10 +1812,6 @@ EXPORT_SYMBOL_GPL(regulator_disable_regmap); static int _regulator_is_enabled(struct regulator_dev *rdev) { - /* A GPIO control always takes precedence */ - if (rdev->ena_gpio) - return rdev->ena_gpio_state; - /* If we don't know then assume that the regulator is always on */ if (!rdev->desc->ops->is_enabled) return 1; @@ -1864,31 +1882,6 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev, } EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); -/** - * regulator_list_voltage_table - List voltages with table based mapping - * - * @rdev: Regulator device - * @selector: Selector to convert into a voltage - * - * Regulators with table based mapping between voltages and - * selectors can set volt_table in the regulator descriptor - * and then use this function as their list_voltage() operation. - */ -int regulator_list_voltage_table(struct regulator_dev *rdev, - unsigned int selector) -{ - if (!rdev->desc->volt_table) { - BUG_ON(!rdev->desc->volt_table); - return -EINVAL; - } - - if (selector >= rdev->desc->n_voltages) - return -EINVAL; - - return rdev->desc->volt_table[selector]; -} -EXPORT_SYMBOL_GPL(regulator_list_voltage_table); - /** * regulator_list_voltage - enumerate supported voltages * @regulator: regulator source @@ -1935,18 +1928,8 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage); int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV) { - struct regulator_dev *rdev = regulator->rdev; int i, voltages, ret; - /* If we can't change voltage check the current voltage */ - if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { - ret = regulator_get_voltage(regulator); - if (ret >= 0) - return (min_uV >= ret && ret <= max_uV); - else - return ret; - } - ret = regulator_count_voltages(regulator); if (ret < 0) return ret; @@ -2062,22 +2045,11 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev, { int ret, voltage; - /* Allow uV_step to be 0 for fixed voltage */ - if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { - if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) - return 0; - else - return -EINVAL; - } - if (!rdev->desc->uV_step) { BUG_ON(!rdev->desc->uV_step); return -EINVAL; } - if (min_uV < rdev->desc->min_uV) - min_uV = rdev->desc->min_uV; - ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); if (ret < 0) return ret; @@ -2096,7 +2068,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, { int ret; int delay = 0; - int best_val = 0; + int best_val; unsigned int selector; int old_selector = -1; @@ -2109,8 +2081,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, * If we can't obtain the old selector there is not enough * info to call set_voltage_time_sel(). */ - if (_regulator_is_enabled(rdev) && - rdev->desc->ops->set_voltage_time_sel && + if (rdev->desc->ops->set_voltage_time_sel && rdev->desc->ops->get_voltage_sel) { old_selector = rdev->desc->ops->get_voltage_sel(rdev); if (old_selector < 0) @@ -2120,45 +2091,29 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, if (rdev->desc->ops->set_voltage) { ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); - - if (ret >= 0) { - if (rdev->desc->ops->list_voltage) - best_val = rdev->desc->ops->list_voltage(rdev, - selector); - else - best_val = _regulator_get_voltage(rdev); - } - } else if (rdev->desc->ops->set_voltage_sel) { - if (rdev->desc->ops->map_voltage) { + if (rdev->desc->ops->map_voltage) ret = rdev->desc->ops->map_voltage(rdev, min_uV, max_uV); - } else { - if (rdev->desc->ops->list_voltage == - regulator_list_voltage_linear) - ret = regulator_map_voltage_linear(rdev, - min_uV, max_uV); - else - ret = regulator_map_voltage_iterate(rdev, - min_uV, max_uV); - } + else + ret = regulator_map_voltage_iterate(rdev, min_uV, + max_uV); if (ret >= 0) { - best_val = rdev->desc->ops->list_voltage(rdev, ret); - if (min_uV <= best_val && max_uV >= best_val) { - selector = ret; - ret = rdev->desc->ops->set_voltage_sel(rdev, - ret); - } else { - ret = -EINVAL; - } + selector = ret; + ret = rdev->desc->ops->set_voltage_sel(rdev, ret); } } else { ret = -EINVAL; } + if (rdev->desc->ops->list_voltage) + best_val = rdev->desc->ops->list_voltage(rdev, selector); + else + best_val = -1; + /* Call set_voltage_time_sel if successfully obtained old_selector */ - if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 && + if (ret == 0 && old_selector >= 0 && rdev->desc->ops->set_voltage_time_sel) { delay = rdev->desc->ops->set_voltage_time_sel(rdev, @@ -2168,19 +2123,19 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, delay); delay = 0; } + } - /* Insert any necessary delays */ - if (delay >= 1000) { - mdelay(delay / 1000); - udelay(delay % 1000); - } else if (delay) { - udelay(delay); - } + /* Insert any necessary delays */ + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); } - if (ret == 0 && best_val >= 0) + if (ret == 0) _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, - (void *)best_val); + NULL); trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val); @@ -2290,46 +2245,6 @@ int regulator_set_voltage_time(struct regulator *regulator, } EXPORT_SYMBOL_GPL(regulator_set_voltage_time); -/** - *regulator_set_voltage_time_sel - get raise/fall time - * @regulator: regulator source - * @old_selector: selector for starting voltage - * @new_selector: selector for target voltage - * - * Provided with the starting and target voltage selectors, this function - * returns time in microseconds required to rise or fall to this new voltage - * - * Drivers providing ramp_delay in regulation_constraints can use this as their - * set_voltage_time_sel() operation. - */ -int regulator_set_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, - unsigned int new_selector) -{ - unsigned int ramp_delay = 0; - int old_volt, new_volt; - - if (rdev->constraints->ramp_delay) - ramp_delay = rdev->constraints->ramp_delay; - else if (rdev->desc->ramp_delay) - ramp_delay = rdev->desc->ramp_delay; - - if (ramp_delay == 0) { - rdev_warn(rdev, "ramp_delay not set\n"); - return 0; - } - - /* sanity check */ - if (!rdev->desc->ops->list_voltage) - return -EINVAL; - - old_volt = rdev->desc->ops->list_voltage(rdev, old_selector); - new_volt = rdev->desc->ops->list_voltage(rdev, new_selector); - - return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); -} -EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); - /** * regulator_sync_voltage - re-apply last regulator output voltage * @regulator: regulator source @@ -2601,12 +2516,9 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) { struct regulator_dev *rdev = regulator->rdev; struct regulator *consumer; - int ret, output_uV, input_uV = 0, total_uA_load = 0; + int ret, output_uV, input_uV, total_uA_load = 0; unsigned int mode; - if (rdev->supply) - input_uV = regulator_get_voltage(rdev->supply); - mutex_lock(&rdev->mutex); /* @@ -2639,7 +2551,10 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) goto out; } - /* No supply? Use constraint voltage */ + /* get input voltage */ + input_uV = 0; + if (rdev->supply) + input_uV = regulator_get_voltage(rdev->supply); if (input_uV <= 0) input_uV = rdev->constraints->input_uV; if (input_uV <= 0) { @@ -2710,7 +2625,7 @@ static void _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) { /* call rdev chain first */ - blocking_notifier_call_chain(&rdev->notifier, event, data); + blocking_notifier_call_chain(&rdev->notifier, event, NULL); } /** @@ -2991,10 +2906,10 @@ int regulator_mode_to_status(unsigned int mode) return REGULATOR_STATUS_NORMAL; case REGULATOR_MODE_IDLE: return REGULATOR_STATUS_IDLE; - case REGULATOR_MODE_STANDBY: + case REGULATOR_STATUS_STANDBY: return REGULATOR_STATUS_STANDBY; default: - return REGULATOR_STATUS_UNDEFINED; + return 0; } } EXPORT_SYMBOL_GPL(regulator_mode_to_status); @@ -3187,10 +3102,7 @@ regulator_register(const struct regulator_desc *regulator_desc, rdev->reg_data = config->driver_data; rdev->owner = regulator_desc->owner; rdev->desc = regulator_desc; - if (config->regmap) - rdev->regmap = config->regmap; - else - rdev->regmap = dev_get_regmap(dev, NULL); + rdev->regmap = config->regmap; INIT_LIST_HEAD(&rdev->consumer_list); INIT_LIST_HEAD(&rdev->list); BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); @@ -3217,26 +3129,6 @@ regulator_register(const struct regulator_desc *regulator_desc, dev_set_drvdata(&rdev->dev, rdev); - if (config->ena_gpio) { - ret = gpio_request_one(config->ena_gpio, - GPIOF_DIR_OUT | config->ena_gpio_flags, - rdev_get_name(rdev)); - if (ret != 0) { - rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", - config->ena_gpio, ret); - goto clean; - } - - rdev->ena_gpio = config->ena_gpio; - rdev->ena_gpio_invert = config->ena_gpio_invert; - - if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) - rdev->ena_gpio_state = 1; - - if (rdev->ena_gpio_invert) - rdev->ena_gpio_state = !rdev->ena_gpio_state; - } - /* set regulator constraints */ if (init_data) constraints = &init_data->constraints; @@ -3305,8 +3197,6 @@ regulator_register(const struct regulator_desc *regulator_desc, scrub: if (rdev->supply) regulator_put(rdev->supply); - if (rdev->ena_gpio) - gpio_free(rdev->ena_gpio); kfree(rdev->constraints); device_unregister(&rdev->dev); /* device core frees rdev */ @@ -3340,8 +3230,6 @@ void regulator_unregister(struct regulator_dev *rdev) unset_regulator_supplies(rdev); list_del(&rdev->list); kfree(rdev->constraints); - if (rdev->ena_gpio) - gpio_free(rdev->ena_gpio); device_unregister(&rdev->dev); mutex_unlock(®ulator_list_mutex); } @@ -3581,15 +3469,6 @@ static int __init regulator_init_complete(void) struct regulation_constraints *c; int enabled, ret; - /* - * Since DT doesn't provide an idiomatic mechanism for - * enabling full constraints and since it's much more natural - * with DT to provide them just assume that a DT enabled - * system has full constraints. - */ - if (of_have_populated_dt()) - has_full_constraints = true; - mutex_lock(®ulator_list_mutex); /* If we have a full configuration then disable any regulators diff --git a/trunk/drivers/regulator/da903x.c b/trunk/drivers/regulator/da903x.c index 36c5b92fe0af..1005f5f7e603 100644 --- a/trunk/drivers/regulator/da903x.c +++ b/trunk/drivers/regulator/da903x.c @@ -107,9 +107,6 @@ static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; - if (rdev->desc->n_voltages == 1) - return -EINVAL; - val = selector << info->vol_shift; mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; @@ -123,9 +120,6 @@ static int da903x_get_voltage_sel(struct regulator_dev *rdev) uint8_t val, mask; int ret; - if (rdev->desc->n_voltages == 1) - return 0; - ret = da903x_read(da9034_dev, info->vol_reg, &val); if (ret) return ret; diff --git a/trunk/drivers/regulator/da9052-regulator.c b/trunk/drivers/regulator/da9052-regulator.c index 903299cf15cf..88976d8d44ed 100644 --- a/trunk/drivers/regulator/da9052-regulator.c +++ b/trunk/drivers/regulator/da9052-regulator.c @@ -405,12 +405,12 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev) if (!nproot) return -ENODEV; - for_each_child_of_node(nproot, np) { + for (np = of_get_next_child(nproot, NULL); np; + np = of_get_next_child(nproot, np)) { if (!of_node_cmp(np->name, regulator->info->reg_desc.name)) { config.init_data = of_get_regulator_init_data( &pdev->dev, np); - config.of_node = np; break; } } diff --git a/trunk/drivers/regulator/db8500-prcmu.c b/trunk/drivers/regulator/db8500-prcmu.c index 9dbb491b6efa..968f97f3cb3d 100644 --- a/trunk/drivers/regulator/db8500-prcmu.c +++ b/trunk/drivers/regulator/db8500-prcmu.c @@ -452,26 +452,26 @@ static __devinit int db8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, + { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, + { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, + { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, + { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, + { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, + { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, + { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, + { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, + { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, + { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, + { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, + { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, + { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, + { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, + { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, + { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, + { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, + { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, + { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, + { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; static __devinit int diff --git a/trunk/drivers/regulator/fixed-helper.c b/trunk/drivers/regulator/fixed-helper.c index f9d027992aae..cacd33c9d042 100644 --- a/trunk/drivers/regulator/fixed-helper.c +++ b/trunk/drivers/regulator/fixed-helper.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -14,20 +13,17 @@ static void regulator_fixed_release(struct device *dev) { struct fixed_regulator_data *data = container_of(dev, struct fixed_regulator_data, pdev.dev); - kfree(data->cfg.supply_name); kfree(data); } /** - * regulator_register_fixed_name - register a no-op fixed regulator + * regulator_register_fixed - register a no-op fixed regulator * @id: platform device id - * @name: name to be used for the regulator * @supplies: consumers for this regulator * @num_supplies: number of consumers - * @uv: voltage in microvolts */ -struct platform_device *regulator_register_always_on(int id, const char *name, - struct regulator_consumer_supply *supplies, int num_supplies, int uv) +struct platform_device *regulator_register_fixed(int id, + struct regulator_consumer_supply *supplies, int num_supplies) { struct fixed_regulator_data *data; @@ -35,13 +31,8 @@ struct platform_device *regulator_register_always_on(int id, const char *name, if (!data) return NULL; - data->cfg.supply_name = kstrdup(name, GFP_KERNEL); - if (!data->cfg.supply_name) { - kfree(data); - return NULL; - } - - data->cfg.microvolts = uv; + data->cfg.supply_name = "fixed-dummy"; + data->cfg.microvolts = 0; data->cfg.gpio = -EINVAL; data->cfg.enabled_at_boot = 1; data->cfg.init_data = &data->init_data; diff --git a/trunk/drivers/regulator/fixed.c b/trunk/drivers/regulator/fixed.c index 185468c4d38f..f09fe7b20e82 100644 --- a/trunk/drivers/regulator/fixed.c +++ b/trunk/drivers/regulator/fixed.c @@ -35,6 +35,10 @@ struct fixed_voltage_data { struct regulator_desc desc; struct regulator_dev *dev; int microvolts; + int gpio; + unsigned startup_delay; + bool enable_high; + bool is_enabled; }; @@ -57,11 +61,11 @@ of_get_fixed_voltage_config(struct device *dev) config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), GFP_KERNEL); if (!config) - return ERR_PTR(-ENOMEM); + return NULL; config->init_data = of_get_regulator_init_data(dev, dev->of_node); if (!config->init_data) - return ERR_PTR(-EINVAL); + return NULL; init_data = config->init_data; init_data->constraints.apply_uV = 0; @@ -72,26 +76,13 @@ of_get_fixed_voltage_config(struct device *dev) } else { dev_err(dev, "Fixed regulator specified with variable voltages\n"); - return ERR_PTR(-EINVAL); + return NULL; } if (init_data->constraints.boot_on) config->enabled_at_boot = true; config->gpio = of_get_named_gpio(np, "gpio", 0); - /* - * of_get_named_gpio() currently returns ENODEV rather than - * EPROBE_DEFER. This code attempts to be compatible with both - * for now; the ENODEV check can be removed once the API is fixed. - * of_get_named_gpio() doesn't differentiate between a missing - * property (which would be fine here, since the GPIO is optional) - * and some other error. Patches have been posted for both issues. - * Once they are check in, we should replace this with: - * if (config->gpio < 0 && config->gpio != -ENOENT) - */ - if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER)) - return ERR_PTR(-EPROBE_DEFER); - delay = of_get_property(np, "startup-delay-us", NULL); if (delay) config->startup_delay = be32_to_cpu(*delay); @@ -102,12 +93,43 @@ of_get_fixed_voltage_config(struct device *dev) if (of_find_property(np, "gpio-open-drain", NULL)) config->gpio_is_open_drain = true; - if (of_find_property(np, "vin-supply", NULL)) - config->input_supply = "vin"; - return config; } +static int fixed_voltage_is_enabled(struct regulator_dev *dev) +{ + struct fixed_voltage_data *data = rdev_get_drvdata(dev); + + return data->is_enabled; +} + +static int fixed_voltage_enable(struct regulator_dev *dev) +{ + struct fixed_voltage_data *data = rdev_get_drvdata(dev); + + gpio_set_value_cansleep(data->gpio, data->enable_high); + data->is_enabled = true; + + return 0; +} + +static int fixed_voltage_disable(struct regulator_dev *dev) +{ + struct fixed_voltage_data *data = rdev_get_drvdata(dev); + + gpio_set_value_cansleep(data->gpio, !data->enable_high); + data->is_enabled = false; + + return 0; +} + +static int fixed_voltage_enable_time(struct regulator_dev *dev) +{ + struct fixed_voltage_data *data = rdev_get_drvdata(dev); + + return data->startup_delay; +} + static int fixed_voltage_get_voltage(struct regulator_dev *dev) { struct fixed_voltage_data *data = rdev_get_drvdata(dev); @@ -129,6 +151,15 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev, return data->microvolts; } +static struct regulator_ops fixed_voltage_gpio_ops = { + .is_enabled = fixed_voltage_is_enabled, + .enable = fixed_voltage_enable, + .disable = fixed_voltage_disable, + .enable_time = fixed_voltage_enable_time, + .get_voltage = fixed_voltage_get_voltage, + .list_voltage = fixed_voltage_list_voltage, +}; + static struct regulator_ops fixed_voltage_ops = { .get_voltage = fixed_voltage_get_voltage, .list_voltage = fixed_voltage_list_voltage, @@ -141,13 +172,10 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) struct regulator_config cfg = { }; int ret; - if (pdev->dev.of_node) { + if (pdev->dev.of_node) config = of_get_fixed_voltage_config(&pdev->dev); - if (IS_ERR(config)) - return PTR_ERR(config); - } else { + else config = pdev->dev.platform_data; - } if (!config) return -ENOMEM; @@ -168,44 +196,59 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) } drvdata->desc.type = REGULATOR_VOLTAGE; drvdata->desc.owner = THIS_MODULE; - drvdata->desc.ops = &fixed_voltage_ops; - drvdata->desc.enable_time = config->startup_delay; + if (config->microvolts) + drvdata->desc.n_voltages = 1; - if (config->input_supply) { - drvdata->desc.supply_name = kstrdup(config->input_supply, - GFP_KERNEL); - if (!drvdata->desc.supply_name) { + drvdata->microvolts = config->microvolts; + drvdata->gpio = config->gpio; + drvdata->startup_delay = config->startup_delay; + + if (gpio_is_valid(config->gpio)) { + int gpio_flag; + drvdata->enable_high = config->enable_high; + + /* FIXME: Remove below print warning + * + * config->gpio must be set to -EINVAL by platform code if + * GPIO control is not required. However, early adopters + * not requiring GPIO control may forget to initialize + * config->gpio to -EINVAL. This will cause GPIO 0 to be used + * for GPIO control. + * + * This warning will be removed once there are a couple of users + * for this driver. + */ + if (!config->gpio) + dev_warn(&pdev->dev, + "using GPIO 0 for regulator enable control\n"); + + /* + * set output direction without changing state + * to prevent glitch + */ + drvdata->is_enabled = config->enabled_at_boot; + ret = drvdata->is_enabled ? + config->enable_high : !config->enable_high; + gpio_flag = ret ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + + if (config->gpio_is_open_drain) + gpio_flag |= GPIOF_OPEN_DRAIN; + + ret = gpio_request_one(config->gpio, gpio_flag, + config->supply_name); + if (ret) { dev_err(&pdev->dev, - "Failed to allocate input supply\n"); - ret = -ENOMEM; + "Could not obtain regulator enable GPIO %d: %d\n", + config->gpio, ret); goto err_name; } - } - - if (config->microvolts) - drvdata->desc.n_voltages = 1; - drvdata->microvolts = config->microvolts; + drvdata->desc.ops = &fixed_voltage_gpio_ops; - if (config->gpio >= 0) - cfg.ena_gpio = config->gpio; - cfg.ena_gpio_invert = !config->enable_high; - if (config->enabled_at_boot) { - if (config->enable_high) { - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - } else { - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; - } } else { - if (config->enable_high) { - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; - } else { - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - } + drvdata->desc.ops = &fixed_voltage_ops; } - if (config->gpio_is_open_drain) - cfg.ena_gpio_flags |= GPIOF_OPEN_DRAIN; cfg.dev = &pdev->dev; cfg.init_data = config->init_data; @@ -216,7 +259,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) if (IS_ERR(drvdata->dev)) { ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); - goto err_input; + goto err_gpio; } platform_set_drvdata(pdev, drvdata); @@ -226,8 +269,9 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) return 0; -err_input: - kfree(drvdata->desc.supply_name); +err_gpio: + if (gpio_is_valid(config->gpio)) + gpio_free(config->gpio); err_name: kfree(drvdata->desc.name); err: @@ -239,7 +283,8 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev) struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev); regulator_unregister(drvdata->dev); - kfree(drvdata->desc.supply_name); + if (gpio_is_valid(drvdata->gpio)) + gpio_free(drvdata->gpio); kfree(drvdata->desc.name); return 0; @@ -251,6 +296,8 @@ static const struct of_device_id fixed_of_match[] __devinitconst = { {}, }; MODULE_DEVICE_TABLE(of, fixed_of_match); +#else +#define fixed_of_match NULL #endif static struct platform_driver regulator_fixed_voltage_driver = { @@ -259,7 +306,7 @@ static struct platform_driver regulator_fixed_voltage_driver = { .driver = { .name = "reg-fixed-voltage", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(fixed_of_match), + .of_match_table = fixed_of_match, }, }; diff --git a/trunk/drivers/regulator/gpio-regulator.c b/trunk/drivers/regulator/gpio-regulator.c index 34b67bee9323..9997d7aaca84 100644 --- a/trunk/drivers/regulator/gpio-regulator.c +++ b/trunk/drivers/regulator/gpio-regulator.c @@ -36,6 +36,11 @@ struct gpio_regulator_data { struct regulator_desc desc; struct regulator_dev *dev; + int enable_gpio; + bool enable_high; + bool is_enabled; + unsigned startup_delay; + struct gpio *gpios; int nr_gpios; @@ -45,6 +50,44 @@ struct gpio_regulator_data { int state; }; +static int gpio_regulator_is_enabled(struct regulator_dev *dev) +{ + struct gpio_regulator_data *data = rdev_get_drvdata(dev); + + return data->is_enabled; +} + +static int gpio_regulator_enable(struct regulator_dev *dev) +{ + struct gpio_regulator_data *data = rdev_get_drvdata(dev); + + if (gpio_is_valid(data->enable_gpio)) { + gpio_set_value_cansleep(data->enable_gpio, data->enable_high); + data->is_enabled = true; + } + + return 0; +} + +static int gpio_regulator_disable(struct regulator_dev *dev) +{ + struct gpio_regulator_data *data = rdev_get_drvdata(dev); + + if (gpio_is_valid(data->enable_gpio)) { + gpio_set_value_cansleep(data->enable_gpio, !data->enable_high); + data->is_enabled = false; + } + + return 0; +} + +static int gpio_regulator_enable_time(struct regulator_dev *dev) +{ + struct gpio_regulator_data *data = rdev_get_drvdata(dev); + + return data->startup_delay; +} + static int gpio_regulator_get_value(struct regulator_dev *dev) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); @@ -58,20 +101,16 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) } static int gpio_regulator_set_value(struct regulator_dev *dev, - int min, int max, unsigned *selector) + int min, int max) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); - int ptr, target = 0, state, best_val = INT_MAX; + int ptr, target, state, best_val = INT_MAX; for (ptr = 0; ptr < data->nr_states; ptr++) if (data->states[ptr].value < best_val && data->states[ptr].value >= min && - data->states[ptr].value <= max) { + data->states[ptr].value <= max) target = data->states[ptr].gpios; - best_val = data->states[ptr].value; - if (selector) - *selector = ptr; - } if (best_val == INT_MAX) return -EINVAL; @@ -89,7 +128,7 @@ static int gpio_regulator_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV, unsigned *selector) { - return gpio_regulator_set_value(dev, min_uV, max_uV, selector); + return gpio_regulator_set_value(dev, min_uV, max_uV); } static int gpio_regulator_list_voltage(struct regulator_dev *dev, @@ -106,16 +145,24 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, static int gpio_regulator_set_current_limit(struct regulator_dev *dev, int min_uA, int max_uA) { - return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); + return gpio_regulator_set_value(dev, min_uA, max_uA); } static struct regulator_ops gpio_regulator_voltage_ops = { + .is_enabled = gpio_regulator_is_enabled, + .enable = gpio_regulator_enable, + .disable = gpio_regulator_disable, + .enable_time = gpio_regulator_enable_time, .get_voltage = gpio_regulator_get_value, .set_voltage = gpio_regulator_set_voltage, .list_voltage = gpio_regulator_list_voltage, }; static struct regulator_ops gpio_regulator_current_ops = { + .is_enabled = gpio_regulator_is_enabled, + .enable = gpio_regulator_enable, + .disable = gpio_regulator_disable, + .enable_time = gpio_regulator_enable_time, .get_current_limit = gpio_regulator_get_value, .set_current_limit = gpio_regulator_set_current_limit, }; @@ -162,7 +209,6 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) drvdata->nr_states = config->nr_states; drvdata->desc.owner = THIS_MODULE; - drvdata->desc.enable_time = config->startup_delay; /* handle regulator type*/ switch (config->type) { @@ -182,12 +228,52 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) break; } + drvdata->enable_gpio = config->enable_gpio; + drvdata->startup_delay = config->startup_delay; + + if (gpio_is_valid(config->enable_gpio)) { + drvdata->enable_high = config->enable_high; + + ret = gpio_request(config->enable_gpio, config->supply_name); + if (ret) { + dev_err(&pdev->dev, + "Could not obtain regulator enable GPIO %d: %d\n", + config->enable_gpio, ret); + goto err_memstate; + } + + /* set output direction without changing state + * to prevent glitch + */ + if (config->enabled_at_boot) { + drvdata->is_enabled = true; + ret = gpio_direction_output(config->enable_gpio, + config->enable_high); + } else { + drvdata->is_enabled = false; + ret = gpio_direction_output(config->enable_gpio, + !config->enable_high); + } + + if (ret) { + dev_err(&pdev->dev, + "Could not configure regulator enable GPIO %d direction: %d\n", + config->enable_gpio, ret); + goto err_enablegpio; + } + } else { + /* Regulator without GPIO control is considered + * always enabled + */ + drvdata->is_enabled = true; + } + drvdata->nr_gpios = config->nr_gpios; ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); if (ret) { dev_err(&pdev->dev, "Could not obtain regulator setting GPIOs: %d\n", ret); - goto err_memstate; + goto err_enablegpio; } /* build initial state from gpio init data. */ @@ -200,22 +286,7 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) cfg.dev = &pdev->dev; cfg.init_data = config->init_data; - cfg.driver_data = drvdata; - - if (config->enable_gpio >= 0) - cfg.ena_gpio = config->enable_gpio; - cfg.ena_gpio_invert = !config->enable_high; - if (config->enabled_at_boot) { - if (config->enable_high) - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - else - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; - } else { - if (config->enable_high) - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; - else - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - } + cfg.driver_data = &drvdata; drvdata->dev = regulator_register(&drvdata->desc, &cfg); if (IS_ERR(drvdata->dev)) { @@ -230,6 +301,9 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) err_stategpio: gpio_free_array(drvdata->gpios, drvdata->nr_gpios); +err_enablegpio: + if (gpio_is_valid(config->enable_gpio)) + gpio_free(config->enable_gpio); err_memstate: kfree(drvdata->states); err_memgpio: @@ -251,6 +325,9 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) kfree(drvdata->states); kfree(drvdata->gpios); + if (gpio_is_valid(drvdata->enable_gpio)) + gpio_free(drvdata->enable_gpio); + kfree(drvdata->desc.name); return 0; diff --git a/trunk/drivers/regulator/isl6271a-regulator.c b/trunk/drivers/regulator/isl6271a-regulator.c index 1d145a07ada9..56d273f25603 100644 --- a/trunk/drivers/regulator/isl6271a-regulator.c +++ b/trunk/drivers/regulator/isl6271a-regulator.c @@ -75,12 +75,19 @@ static struct regulator_ops isl_core_ops = { static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) { - return dev->desc->min_uV; + int id = rdev_get_id(dev); + return (id == 1) ? 1100000 : 1300000; +} + +static int isl6271a_list_fixed_voltage(struct regulator_dev *dev, unsigned selector) +{ + int id = rdev_get_id(dev); + return (id == 1) ? 1100000 : 1300000; } static struct regulator_ops isl_fixed_ops = { .get_voltage = isl6271a_get_fixed_voltage, - .list_voltage = regulator_list_voltage_linear, + .list_voltage = isl6271a_list_fixed_voltage, }; static const struct regulator_desc isl_rd[] = { @@ -100,7 +107,6 @@ static const struct regulator_desc isl_rd[] = { .ops = &isl_fixed_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = 1100000, }, { .name = "LDO2", .id = 2, @@ -108,7 +114,6 @@ static const struct regulator_desc isl_rd[] = { .ops = &isl_fixed_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = 1300000, }, }; diff --git a/trunk/drivers/regulator/lp3971.c b/trunk/drivers/regulator/lp3971.c index 7c6e3b8ff484..981bea9cb9d7 100644 --- a/trunk/drivers/regulator/lp3971.c +++ b/trunk/drivers/regulator/lp3971.c @@ -65,11 +65,11 @@ static const int buck_base_addr[] = { #define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x]) #define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1) -static const unsigned int buck_voltage_map[] = { - 0, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, - 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, - 1550000, 1600000, 1650000, 1700000, 1800000, 1900000, 2500000, 2800000, - 3000000, 3300000, +static const int buck_voltage_map[] = { + 0, 800, 850, 900, 950, 1000, 1050, 1100, + 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, + 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800, + 3000, 3300, }; #define BUCK_TARGET_VOL_MASK 0x3f @@ -98,19 +98,39 @@ static const unsigned int buck_voltage_map[] = { #define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2) #define LDO_VOL_CONTR_MASK 0x0f -static const unsigned int ldo45_voltage_map[] = { - 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, - 1400000, 1500000, 1800000, 1900000, 2500000, 2800000, 3000000, 3300000, +static const int ldo45_voltage_map[] = { + 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, + 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300, }; -static const unsigned int ldo123_voltage_map[] = { - 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, - 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, +static const int ldo123_voltage_map[] = { + 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, + 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, }; +static const int *ldo_voltage_map[] = { + ldo123_voltage_map, /* LDO1 */ + ldo123_voltage_map, /* LDO2 */ + ldo123_voltage_map, /* LDO3 */ + ldo45_voltage_map, /* LDO4 */ + ldo45_voltage_map, /* LDO5 */ +}; + +#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)]) + #define LDO_VOL_MIN_IDX 0x00 #define LDO_VOL_MAX_IDX 0x0f +static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index) +{ + int ldo = rdev_get_id(dev) - LP3971_LDO1; + + if (index > LDO_VOL_MAX_IDX) + return -EINVAL; + + return 1000 * LDO_VOL_VALUE_MAP(ldo)[index]; +} + static int lp3971_ldo_is_enabled(struct regulator_dev *dev) { struct lp3971 *lp3971 = rdev_get_drvdata(dev); @@ -149,7 +169,7 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev) reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo)); val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK; - return dev->desc->volt_table[val]; + return 1000 * LDO_VOL_VALUE_MAP(ldo)[val]; } static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev, @@ -164,7 +184,7 @@ static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3971_ldo_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = lp3971_ldo_list_voltage, .is_enabled = lp3971_ldo_is_enabled, .enable = lp3971_ldo_enable, .disable = lp3971_ldo_disable, @@ -172,6 +192,14 @@ static struct regulator_ops lp3971_ldo_ops = { .set_voltage_sel = lp3971_ldo_set_voltage_sel, }; +static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index) +{ + if (index < BUCK_TARGET_VOL_MIN_IDX || index > BUCK_TARGET_VOL_MAX_IDX) + return -EINVAL; + + return 1000 * buck_voltage_map[index]; +} + static int lp3971_dcdc_is_enabled(struct regulator_dev *dev) { struct lp3971 *lp3971 = rdev_get_drvdata(dev); @@ -212,7 +240,7 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev) reg &= BUCK_TARGET_VOL_MASK; if (reg <= BUCK_TARGET_VOL_MAX_IDX) - val = buck_voltage_map[reg]; + val = 1000 * buck_voltage_map[reg]; else { val = 0; dev_warn(&dev->dev, "chip reported incorrect voltage value.\n"); @@ -245,7 +273,7 @@ static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3971_dcdc_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = lp3971_dcdc_list_voltage, .is_enabled = lp3971_dcdc_is_enabled, .enable = lp3971_dcdc_enable, .disable = lp3971_dcdc_disable, @@ -259,7 +287,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO1, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo123_voltage_map), - .volt_table = ldo123_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -268,7 +295,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO2, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo123_voltage_map), - .volt_table = ldo123_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -277,7 +303,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO3, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo123_voltage_map), - .volt_table = ldo123_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -286,7 +311,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO4, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo45_voltage_map), - .volt_table = ldo45_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -295,7 +319,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO5, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo45_voltage_map), - .volt_table = ldo45_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -304,7 +327,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_DCDC1, .ops = &lp3971_dcdc_ops, .n_voltages = ARRAY_SIZE(buck_voltage_map), - .volt_table = buck_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -313,7 +335,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_DCDC2, .ops = &lp3971_dcdc_ops, .n_voltages = ARRAY_SIZE(buck_voltage_map), - .volt_table = buck_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -322,7 +343,6 @@ static const struct regulator_desc regulators[] = { .id = LP3971_DCDC3, .ops = &lp3971_dcdc_ops, .n_voltages = ARRAY_SIZE(buck_voltage_map), - .volt_table = buck_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, diff --git a/trunk/drivers/regulator/lp3972.c b/trunk/drivers/regulator/lp3972.c index 3cdc755d9b22..de073df7d344 100644 --- a/trunk/drivers/regulator/lp3972.c +++ b/trunk/drivers/regulator/lp3972.c @@ -74,40 +74,54 @@ struct lp3972 { #define LP3972_OVER2_LDO4_EN BIT(4) #define LP3972_OVER1_S_EN BIT(2) -static const unsigned int ldo1_voltage_map[] = { - 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000, - 1900000, 1925000, 1950000, 1975000, 2000000, +static const int ldo1_voltage_map[] = { + 1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875, + 1900, 1925, 1950, 1975, 2000, }; -static const unsigned int ldo23_voltage_map[] = { - 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, - 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, +static const int ldo23_voltage_map[] = { + 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, + 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, }; -static const unsigned int ldo4_voltage_map[] = { - 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, - 1400000, 1500000, 1800000, 1900000, 2500000, 2800000, 3000000, 3300000, +static const int ldo4_voltage_map[] = { + 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, + 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300, }; -static const unsigned int ldo5_voltage_map[] = { - 0, 0, 0, 0, 0, 850000, 875000, 900000, - 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, - 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, - 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, +static const int ldo5_voltage_map[] = { + 0, 0, 0, 0, 0, 850, 875, 900, + 925, 950, 975, 1000, 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, }; -static const unsigned int buck1_voltage_map[] = { - 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, - 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, - 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, - 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, +static const int buck1_voltage_map[] = { + 725, 750, 775, 800, 825, 850, 875, 900, + 925, 950, 975, 1000, 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, }; -static const unsigned int buck23_voltage_map[] = { - 0, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, - 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, - 1550000, 1600000, 1650000, 1700000, 1800000, 1900000, 2500000, 2800000, - 3000000, 3300000, +static const int buck23_voltage_map[] = { + 0, 800, 850, 900, 950, 1000, 1050, 1100, + 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, + 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800, + 3000, 3300, +}; + +static const int *ldo_voltage_map[] = { + ldo1_voltage_map, + ldo23_voltage_map, + ldo23_voltage_map, + ldo4_voltage_map, + ldo5_voltage_map, +}; + +static const int *buck_voltage_map[] = { + buck1_voltage_map, + buck23_voltage_map, + buck23_voltage_map, }; static const int ldo_output_enable_mask[] = { @@ -146,6 +160,7 @@ static const int buck_base_addr[] = { LP3972_B3TV_REG, }; +#define LP3972_LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[x]) #define LP3972_LDO_OUTPUT_ENABLE_MASK(x) (ldo_output_enable_mask[x]) #define LP3972_LDO_OUTPUT_ENABLE_REG(x) (ldo_output_enable_addr[x]) @@ -162,6 +177,7 @@ static const int buck_base_addr[] = { #define LP3972_LDO_VOL_MIN_IDX(x) (((x) == 4) ? 0x05 : 0x00) #define LP3972_LDO_VOL_MAX_IDX(x) ((x) ? (((x) == 4) ? 0x1f : 0x0f) : 0x0c) +#define LP3972_BUCK_VOL_VALUE_MAP(x) (buck_voltage_map[x]) #define LP3972_BUCK_VOL_ENABLE_REG(x) (buck_vol_enable_addr[x]) #define LP3972_BUCK_VOL1_REG(x) (buck_base_addr[x]) #define LP3972_BUCK_VOL_MASK 0x1f @@ -226,6 +242,17 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val) return ret; } +static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index) +{ + int ldo = rdev_get_id(dev) - LP3972_LDO1; + + if (index < LP3972_LDO_VOL_MIN_IDX(ldo) || + index > LP3972_LDO_VOL_MAX_IDX(ldo)) + return -EINVAL; + + return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index]; +} + static int lp3972_ldo_is_enabled(struct regulator_dev *dev) { struct lp3972 *lp3972 = rdev_get_drvdata(dev); @@ -267,7 +294,7 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev) reg = lp3972_reg_read(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo)); val = (reg >> LP3972_LDO_VOL_CONTR_SHIFT(ldo)) & mask; - return dev->desc->volt_table[val]; + return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val]; } static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev, @@ -310,7 +337,7 @@ static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3972_ldo_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = lp3972_ldo_list_voltage, .is_enabled = lp3972_ldo_is_enabled, .enable = lp3972_ldo_enable, .disable = lp3972_ldo_disable, @@ -318,6 +345,17 @@ static struct regulator_ops lp3972_ldo_ops = { .set_voltage_sel = lp3972_ldo_set_voltage_sel, }; +static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index) +{ + int buck = rdev_get_id(dev) - LP3972_DCDC1; + + if (index < LP3972_BUCK_VOL_MIN_IDX(buck) || + index > LP3972_BUCK_VOL_MAX_IDX(buck)) + return -EINVAL; + + return 1000 * buck_voltage_map[buck][index]; +} + static int lp3972_dcdc_is_enabled(struct regulator_dev *dev) { struct lp3972 *lp3972 = rdev_get_drvdata(dev); @@ -363,7 +401,7 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev) reg = lp3972_reg_read(lp3972, LP3972_BUCK_VOL1_REG(buck)); reg &= LP3972_BUCK_VOL_MASK; if (reg <= LP3972_BUCK_VOL_MAX_IDX(buck)) - val = dev->desc->volt_table[reg]; + val = 1000 * buck_voltage_map[buck][reg]; else { val = 0; dev_warn(&dev->dev, "chip reported incorrect voltage value." @@ -398,7 +436,7 @@ static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3972_dcdc_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = lp3972_dcdc_list_voltage, .is_enabled = lp3972_dcdc_is_enabled, .enable = lp3972_dcdc_enable, .disable = lp3972_dcdc_disable, @@ -412,7 +450,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO1, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo1_voltage_map), - .volt_table = ldo1_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -421,7 +458,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO2, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo23_voltage_map), - .volt_table = ldo23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -430,7 +466,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO3, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo23_voltage_map), - .volt_table = ldo23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -439,7 +474,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO4, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo4_voltage_map), - .volt_table = ldo4_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -448,7 +482,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO5, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo5_voltage_map), - .volt_table = ldo5_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -457,7 +490,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_DCDC1, .ops = &lp3972_dcdc_ops, .n_voltages = ARRAY_SIZE(buck1_voltage_map), - .volt_table = buck1_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -466,7 +498,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_DCDC2, .ops = &lp3972_dcdc_ops, .n_voltages = ARRAY_SIZE(buck23_voltage_map), - .volt_table = buck23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -475,7 +506,6 @@ static const struct regulator_desc regulators[] = { .id = LP3972_DCDC3, .ops = &lp3972_dcdc_ops, .n_voltages = ARRAY_SIZE(buck23_voltage_map), - .volt_table = buck23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, diff --git a/trunk/drivers/regulator/lp872x.c b/trunk/drivers/regulator/lp872x.c deleted file mode 100644 index 212c38eaba70..000000000000 --- a/trunk/drivers/regulator/lp872x.c +++ /dev/null @@ -1,943 +0,0 @@ -/* - * Copyright 2012 Texas Instruments - * - * Author: Milo(Woogyom) Kim - * - * 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 - -/* Registers : LP8720/8725 shared */ -#define LP872X_GENERAL_CFG 0x00 -#define LP872X_LDO1_VOUT 0x01 -#define LP872X_LDO2_VOUT 0x02 -#define LP872X_LDO3_VOUT 0x03 -#define LP872X_LDO4_VOUT 0x04 -#define LP872X_LDO5_VOUT 0x05 - -/* Registers : LP8720 */ -#define LP8720_BUCK_VOUT1 0x06 -#define LP8720_BUCK_VOUT2 0x07 -#define LP8720_ENABLE 0x08 - -/* Registers : LP8725 */ -#define LP8725_LILO1_VOUT 0x06 -#define LP8725_LILO2_VOUT 0x07 -#define LP8725_BUCK1_VOUT1 0x08 -#define LP8725_BUCK1_VOUT2 0x09 -#define LP8725_BUCK2_VOUT1 0x0A -#define LP8725_BUCK2_VOUT2 0x0B -#define LP8725_BUCK_CTRL 0x0C -#define LP8725_LDO_CTRL 0x0D - -/* Mask/shift : LP8720/LP8725 shared */ -#define LP872X_VOUT_M 0x1F -#define LP872X_START_DELAY_M 0xE0 -#define LP872X_START_DELAY_S 5 -#define LP872X_EN_LDO1_M BIT(0) -#define LP872X_EN_LDO2_M BIT(1) -#define LP872X_EN_LDO3_M BIT(2) -#define LP872X_EN_LDO4_M BIT(3) -#define LP872X_EN_LDO5_M BIT(4) - -/* Mask/shift : LP8720 */ -#define LP8720_TIMESTEP_S 0 /* Addr 00h */ -#define LP8720_TIMESTEP_M BIT(0) -#define LP8720_EXT_DVS_M BIT(2) -#define LP8720_BUCK_FPWM_S 5 /* Addr 07h */ -#define LP8720_BUCK_FPWM_M BIT(5) -#define LP8720_EN_BUCK_M BIT(5) /* Addr 08h */ -#define LP8720_DVS_SEL_M BIT(7) - -/* Mask/shift : LP8725 */ -#define LP8725_TIMESTEP_M 0xC0 /* Addr 00h */ -#define LP8725_TIMESTEP_S 6 -#define LP8725_BUCK1_EN_M BIT(0) -#define LP8725_DVS1_M BIT(2) -#define LP8725_DVS2_M BIT(3) -#define LP8725_BUCK2_EN_M BIT(4) -#define LP8725_BUCK_CL_M 0xC0 /* Addr 09h, 0Bh */ -#define LP8725_BUCK_CL_S 6 -#define LP8725_BUCK1_FPWM_S 1 /* Addr 0Ch */ -#define LP8725_BUCK1_FPWM_M BIT(1) -#define LP8725_BUCK2_FPWM_S 5 -#define LP8725_BUCK2_FPWM_M BIT(5) -#define LP8725_EN_LILO1_M BIT(5) /* Addr 0Dh */ -#define LP8725_EN_LILO2_M BIT(6) - -/* PWM mode */ -#define LP872X_FORCE_PWM 1 -#define LP872X_AUTO_PWM 0 - -#define LP8720_NUM_REGULATORS 6 -#define LP8725_NUM_REGULATORS 9 -#define EXTERN_DVS_USED 0 -#define MAX_DELAY 6 - -/* dump registers in regmap-debugfs */ -#define MAX_REGISTERS 0x0F - -enum lp872x_id { - LP8720, - LP8725, -}; - -struct lp872x { - struct regmap *regmap; - struct device *dev; - enum lp872x_id chipid; - struct lp872x_platform_data *pdata; - struct regulator_dev **regulators; - int num_regulators; - enum lp872x_dvs_state dvs_pin; - int dvs_gpio; -}; - -/* LP8720/LP8725 shared voltage table for LDOs */ -static const unsigned int lp872x_ldo_vtbl[] = { - 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000, - 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 2000000, - 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2650000, 2700000, - 2750000, 2800000, 2850000, 2900000, 2950000, 3000000, 3100000, 3300000, -}; - -/* LP8720 LDO4 voltage table */ -static const unsigned int lp8720_ldo4_vtbl[] = { - 800000, 850000, 900000, 1000000, 1100000, 1200000, 1250000, 1300000, - 1350000, 1400000, 1450000, 1500000, 1550000, 1600000, 1650000, 1700000, - 1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000, - 2400000, 2500000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, -}; - -/* LP8725 LILO(Low Input Low Output) voltage table */ -static const unsigned int lp8725_lilo_vtbl[] = { - 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, - 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000, - 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, - 2600000, 2700000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000, -}; - -/* LP8720 BUCK voltage table */ -#define EXT_R 0 /* external resistor divider */ -static const unsigned int lp8720_buck_vtbl[] = { - EXT_R, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, - 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, - 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, - 1950000, 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, -}; - -/* LP8725 BUCK voltage table */ -static const unsigned int lp8725_buck_vtbl[] = { - 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, - 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000, - 1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000, - 2400000, 2500000, 2600000, 2700000, 2800000, 2850000, 2900000, 3000000, -}; - -/* LP8725 BUCK current limit */ -static const unsigned int lp8725_buck_uA[] = { - 460000, 780000, 1050000, 1370000, -}; - -static int lp872x_read_byte(struct lp872x *lp, u8 addr, u8 *data) -{ - int ret; - unsigned int val; - - ret = regmap_read(lp->regmap, addr, &val); - if (ret < 0) { - dev_err(lp->dev, "failed to read 0x%.2x\n", addr); - return ret; - } - - *data = (u8)val; - return 0; -} - -static inline int lp872x_write_byte(struct lp872x *lp, u8 addr, u8 data) -{ - return regmap_write(lp->regmap, addr, data); -} - -static inline int lp872x_update_bits(struct lp872x *lp, u8 addr, - unsigned int mask, u8 data) -{ - return regmap_update_bits(lp->regmap, addr, mask, data); -} - -static int _rdev_to_offset(struct regulator_dev *rdev) -{ - enum lp872x_regulator_id id = rdev_get_id(rdev); - - switch (id) { - case LP8720_ID_LDO1 ... LP8720_ID_BUCK: - return id; - case LP8725_ID_LDO1 ... LP8725_ID_BUCK2: - return id - LP8725_ID_BASE; - default: - return -EINVAL; - } -} - -static int lp872x_get_timestep_usec(struct lp872x *lp) -{ - enum lp872x_id chip = lp->chipid; - u8 val, mask, shift; - int *time_usec, size, ret; - int lp8720_time_usec[] = { 25, 50 }; - int lp8725_time_usec[] = { 32, 64, 128, 256 }; - - switch (chip) { - case LP8720: - mask = LP8720_TIMESTEP_M; - shift = LP8720_TIMESTEP_S; - time_usec = &lp8720_time_usec[0]; - size = ARRAY_SIZE(lp8720_time_usec); - break; - case LP8725: - mask = LP8725_TIMESTEP_M; - shift = LP8725_TIMESTEP_S; - time_usec = &lp8725_time_usec[0]; - size = ARRAY_SIZE(lp8725_time_usec); - break; - default: - return -EINVAL; - } - - ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); - if (ret) - return -EINVAL; - - val = (val & mask) >> shift; - if (val >= size) - return -EINVAL; - - return *(time_usec + val); -} - -static int lp872x_regulator_enable_time(struct regulator_dev *rdev) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id regulator = rdev_get_id(rdev); - int time_step_us = lp872x_get_timestep_usec(lp); - int ret, offset; - u8 addr, val; - - if (time_step_us < 0) - return -EINVAL; - - switch (regulator) { - case LP8720_ID_LDO1 ... LP8720_ID_LDO5: - case LP8725_ID_LDO1 ... LP8725_ID_LILO2: - offset = _rdev_to_offset(rdev); - if (offset < 0) - return -EINVAL; - - addr = LP872X_LDO1_VOUT + offset; - break; - case LP8720_ID_BUCK: - addr = LP8720_BUCK_VOUT1; - break; - case LP8725_ID_BUCK1: - addr = LP8725_BUCK1_VOUT1; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK2_VOUT1; - break; - default: - return -EINVAL; - } - - ret = lp872x_read_byte(lp, addr, &val); - if (ret) - return ret; - - val = (val & LP872X_START_DELAY_M) >> LP872X_START_DELAY_S; - - return val > MAX_DELAY ? 0 : val * time_step_us; -} - -static void lp872x_set_dvs(struct lp872x *lp, int gpio) -{ - enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel; - enum lp872x_dvs_state state; - - state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW; - gpio_set_value(gpio, state); - lp->dvs_pin = state; -} - -static u8 lp872x_select_buck_vout_addr(struct lp872x *lp, - enum lp872x_regulator_id buck) -{ - u8 val, addr; - - if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val)) - return 0; - - switch (buck) { - case LP8720_ID_BUCK: - if (val & LP8720_EXT_DVS_M) { - addr = (lp->dvs_pin == DVS_HIGH) ? - LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; - } else { - if (lp872x_read_byte(lp, LP8720_ENABLE, &val)) - return 0; - - addr = val & LP8720_DVS_SEL_M ? - LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; - } - break; - case LP8725_ID_BUCK1: - if (val & LP8725_DVS1_M) - addr = LP8725_BUCK1_VOUT1; - else - addr = (lp->dvs_pin == DVS_HIGH) ? - LP8725_BUCK1_VOUT1 : LP8725_BUCK1_VOUT2; - break; - case LP8725_ID_BUCK2: - addr = val & LP8725_DVS2_M ? - LP8725_BUCK2_VOUT1 : LP8725_BUCK2_VOUT2; - break; - default: - return 0; - } - - return addr; -} - -static bool lp872x_is_valid_buck_addr(u8 addr) -{ - switch (addr) { - case LP8720_BUCK_VOUT1: - case LP8720_BUCK_VOUT2: - case LP8725_BUCK1_VOUT1: - case LP8725_BUCK1_VOUT2: - case LP8725_BUCK2_VOUT1: - case LP8725_BUCK2_VOUT2: - return true; - default: - return false; - } -} - -static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, mask = LP872X_VOUT_M; - struct lp872x_dvs *dvs = lp->pdata->dvs; - - if (dvs && gpio_is_valid(dvs->gpio)) - lp872x_set_dvs(lp, dvs->gpio); - - addr = lp872x_select_buck_vout_addr(lp, buck); - if (!lp872x_is_valid_buck_addr(addr)) - return -EINVAL; - - return lp872x_update_bits(lp, addr, mask, selector); -} - -static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, val; - int ret; - - addr = lp872x_select_buck_vout_addr(lp, buck); - if (!lp872x_is_valid_buck_addr(addr)) - return -EINVAL; - - ret = lp872x_read_byte(lp, addr, &val); - if (ret) - return ret; - - return val & LP872X_VOUT_M; -} - -static int lp8725_buck_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - int i, max = ARRAY_SIZE(lp8725_buck_uA); - u8 addr, val; - - switch (buck) { - case LP8725_ID_BUCK1: - addr = LP8725_BUCK1_VOUT2; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK2_VOUT2; - break; - default: - return -EINVAL; - } - - for (i = 0 ; i < max ; i++) - if (lp8725_buck_uA[i] >= min_uA && - lp8725_buck_uA[i] <= max_uA) - break; - - if (i == max) - return -EINVAL; - - val = i << LP8725_BUCK_CL_S; - - return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val); -} - -static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, val; - int ret; - - switch (buck) { - case LP8725_ID_BUCK1: - addr = LP8725_BUCK1_VOUT2; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK2_VOUT2; - break; - default: - return -EINVAL; - } - - ret = lp872x_read_byte(lp, addr, &val); - if (ret) - return ret; - - val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S; - - return (val < ARRAY_SIZE(lp8725_buck_uA)) ? - lp8725_buck_uA[val] : -EINVAL; -} - -static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, mask, shift, val; - - switch (buck) { - case LP8720_ID_BUCK: - addr = LP8720_BUCK_VOUT2; - mask = LP8720_BUCK_FPWM_M; - shift = LP8720_BUCK_FPWM_S; - break; - case LP8725_ID_BUCK1: - addr = LP8725_BUCK_CTRL; - mask = LP8725_BUCK1_FPWM_M; - shift = LP8725_BUCK1_FPWM_S; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK_CTRL; - mask = LP8725_BUCK2_FPWM_M; - shift = LP8725_BUCK2_FPWM_S; - break; - default: - return -EINVAL; - } - - if (mode == REGULATOR_MODE_FAST) - val = LP872X_FORCE_PWM << shift; - else if (mode == REGULATOR_MODE_NORMAL) - val = LP872X_AUTO_PWM << shift; - else - return -EINVAL; - - return lp872x_update_bits(lp, addr, mask, val); -} - -static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, mask, val; - int ret; - - switch (buck) { - case LP8720_ID_BUCK: - addr = LP8720_BUCK_VOUT2; - mask = LP8720_BUCK_FPWM_M; - break; - case LP8725_ID_BUCK1: - addr = LP8725_BUCK_CTRL; - mask = LP8725_BUCK1_FPWM_M; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK_CTRL; - mask = LP8725_BUCK2_FPWM_M; - break; - default: - return -EINVAL; - } - - ret = lp872x_read_byte(lp, addr, &val); - if (ret) - return ret; - - return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; -} - -static struct regulator_ops lp872x_ldo_ops = { - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .enable_time = lp872x_regulator_enable_time, -}; - -static struct regulator_ops lp8720_buck_ops = { - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = lp872x_buck_set_voltage_sel, - .get_voltage_sel = lp872x_buck_get_voltage_sel, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .enable_time = lp872x_regulator_enable_time, - .set_mode = lp872x_buck_set_mode, - .get_mode = lp872x_buck_get_mode, -}; - -static struct regulator_ops lp8725_buck_ops = { - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = lp872x_buck_set_voltage_sel, - .get_voltage_sel = lp872x_buck_get_voltage_sel, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .enable_time = lp872x_regulator_enable_time, - .set_mode = lp872x_buck_set_mode, - .get_mode = lp872x_buck_get_mode, - .set_current_limit = lp8725_buck_set_current_limit, - .get_current_limit = lp8725_buck_get_current_limit, -}; - -static struct regulator_desc lp8720_regulator_desc[] = { - { - .name = "ldo1", - .id = LP8720_ID_LDO1, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO1_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO1_M, - }, - { - .name = "ldo2", - .id = LP8720_ID_LDO2, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO2_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO2_M, - }, - { - .name = "ldo3", - .id = LP8720_ID_LDO3, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO3_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO3_M, - }, - { - .name = "ldo4", - .id = LP8720_ID_LDO4, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), - .volt_table = lp8720_ldo4_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO4_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO4_M, - }, - { - .name = "ldo5", - .id = LP8720_ID_LDO5, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO5_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO5_M, - }, - { - .name = "buck", - .id = LP8720_ID_BUCK, - .ops = &lp8720_buck_ops, - .n_voltages = ARRAY_SIZE(lp8720_buck_vtbl), - .volt_table = lp8720_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP8720_EN_BUCK_M, - }, -}; - -static struct regulator_desc lp8725_regulator_desc[] = { - { - .name = "ldo1", - .id = LP8725_ID_LDO1, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO1_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO1_M, - }, - { - .name = "ldo2", - .id = LP8725_ID_LDO2, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO2_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO2_M, - }, - { - .name = "ldo3", - .id = LP8725_ID_LDO3, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO3_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO3_M, - }, - { - .name = "ldo4", - .id = LP8725_ID_LDO4, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO4_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO4_M, - }, - { - .name = "ldo5", - .id = LP8725_ID_LDO5, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO5_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO5_M, - }, - { - .name = "lilo1", - .id = LP8725_ID_LILO1, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), - .volt_table = lp8725_lilo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8725_LILO1_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP8725_EN_LILO1_M, - }, - { - .name = "lilo2", - .id = LP8725_ID_LILO2, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), - .volt_table = lp8725_lilo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8725_LILO2_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP8725_EN_LILO2_M, - }, - { - .name = "buck1", - .id = LP8725_ID_BUCK1, - .ops = &lp8725_buck_ops, - .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), - .volt_table = lp8725_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP872X_GENERAL_CFG, - .enable_mask = LP8725_BUCK1_EN_M, - }, - { - .name = "buck2", - .id = LP8725_ID_BUCK2, - .ops = &lp8725_buck_ops, - .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), - .volt_table = lp8725_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP872X_GENERAL_CFG, - .enable_mask = LP8725_BUCK2_EN_M, - }, -}; - -static int lp872x_check_dvs_validity(struct lp872x *lp) -{ - struct lp872x_dvs *dvs = lp->pdata->dvs; - u8 val = 0; - int ret; - - ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); - if (ret) - return ret; - - ret = 0; - if (lp->chipid == LP8720) { - if (val & LP8720_EXT_DVS_M) - ret = dvs ? 0 : -EINVAL; - } else { - if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED) - ret = dvs ? 0 : -EINVAL; - } - - return ret; -} - -static int lp872x_init_dvs(struct lp872x *lp) -{ - int ret, gpio; - struct lp872x_dvs *dvs = lp->pdata->dvs; - enum lp872x_dvs_state pinstate; - - ret = lp872x_check_dvs_validity(lp); - if (ret) { - dev_warn(lp->dev, "invalid dvs data: %d\n", ret); - return ret; - } - - gpio = dvs->gpio; - if (!gpio_is_valid(gpio)) { - dev_err(lp->dev, "invalid gpio: %d\n", gpio); - return -EINVAL; - } - - pinstate = dvs->init_state; - ret = devm_gpio_request_one(lp->dev, gpio, pinstate, "LP872X DVS"); - if (ret) { - dev_err(lp->dev, "gpio request err: %d\n", ret); - return ret; - } - - lp->dvs_pin = pinstate; - lp->dvs_gpio = gpio; - - return 0; -} - -static int lp872x_config(struct lp872x *lp) -{ - struct lp872x_platform_data *pdata = lp->pdata; - int ret; - - if (!pdata->update_config) - return 0; - - ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config); - if (ret) - return ret; - - return lp872x_init_dvs(lp); -} - -static struct regulator_init_data -*lp872x_find_regulator_init_data(int id, struct lp872x *lp) -{ - int i; - - for (i = 0; i < lp->num_regulators; i++) { - if (lp->pdata->regulator_data[i].id == id) - return lp->pdata->regulator_data[i].init_data; - } - - return NULL; -} - -static int lp872x_regulator_register(struct lp872x *lp) -{ - struct regulator_desc *desc; - struct regulator_config cfg = { }; - struct regulator_dev *rdev; - int i, ret; - - for (i = 0 ; i < lp->num_regulators ; i++) { - desc = (lp->chipid == LP8720) ? &lp8720_regulator_desc[i] : - &lp8725_regulator_desc[i]; - - cfg.dev = lp->dev; - cfg.init_data = lp872x_find_regulator_init_data(desc->id, lp); - cfg.driver_data = lp; - cfg.regmap = lp->regmap; - - rdev = regulator_register(desc, &cfg); - if (IS_ERR(rdev)) { - dev_err(lp->dev, "regulator register err"); - ret = PTR_ERR(rdev); - goto err; - } - - *(lp->regulators + i) = rdev; - } - - return 0; -err: - while (--i >= 0) { - rdev = *(lp->regulators + i); - regulator_unregister(rdev); - } - return ret; -} - -static void lp872x_regulator_unregister(struct lp872x *lp) -{ - struct regulator_dev *rdev; - int i; - - for (i = 0 ; i < lp->num_regulators ; i++) { - rdev = *(lp->regulators + i); - regulator_unregister(rdev); - } -} - -static const struct regmap_config lp872x_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = MAX_REGISTERS, -}; - -static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) -{ - struct lp872x *lp; - struct lp872x_platform_data *pdata = cl->dev.platform_data; - int ret, size, num_regulators; - const int lp872x_num_regulators[] = { - [LP8720] = LP8720_NUM_REGULATORS, - [LP8725] = LP8725_NUM_REGULATORS, - }; - - if (!pdata) { - dev_err(&cl->dev, "no platform data\n"); - return -EINVAL; - } - - lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); - if (!lp) - goto err_mem; - - num_regulators = lp872x_num_regulators[id->driver_data]; - size = sizeof(struct regulator_dev *) * num_regulators; - - lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL); - if (!lp->regulators) - goto err_mem; - - lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); - if (IS_ERR(lp->regmap)) { - ret = PTR_ERR(lp->regmap); - dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); - goto err_dev; - } - - lp->dev = &cl->dev; - lp->pdata = pdata; - lp->chipid = id->driver_data; - lp->num_regulators = num_regulators; - i2c_set_clientdata(cl, lp); - - ret = lp872x_config(lp); - if (ret) - goto err_dev; - - return lp872x_regulator_register(lp); - -err_mem: - return -ENOMEM; -err_dev: - return ret; -} - -static int __devexit lp872x_remove(struct i2c_client *cl) -{ - struct lp872x *lp = i2c_get_clientdata(cl); - - lp872x_regulator_unregister(lp); - return 0; -} - -static const struct i2c_device_id lp872x_ids[] = { - {"lp8720", LP8720}, - {"lp8725", LP8725}, - { } -}; -MODULE_DEVICE_TABLE(i2c, lp872x_ids); - -static struct i2c_driver lp872x_driver = { - .driver = { - .name = "lp872x", - .owner = THIS_MODULE, - }, - .probe = lp872x_probe, - .remove = __devexit_p(lp872x_remove), - .id_table = lp872x_ids, -}; - -module_i2c_driver(lp872x_driver); - -MODULE_DESCRIPTION("TI/National Semiconductor LP872x PMU Regulator Driver"); -MODULE_AUTHOR("Milo Kim"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/regulator/lp8788-buck.c b/trunk/drivers/regulator/lp8788-buck.c deleted file mode 100644 index 6356e821400f..000000000000 --- a/trunk/drivers/regulator/lp8788-buck.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * TI LP8788 MFD - buck regulator driver - * - * Copyright 2012 Texas Instruments - * - * Author: Milo(Woogyom) Kim - * - * 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 - -/* register address */ -#define LP8788_EN_BUCK 0x0C -#define LP8788_BUCK_DVS_SEL 0x1D -#define LP8788_BUCK1_VOUT0 0x1E -#define LP8788_BUCK1_VOUT1 0x1F -#define LP8788_BUCK1_VOUT2 0x20 -#define LP8788_BUCK1_VOUT3 0x21 -#define LP8788_BUCK2_VOUT0 0x22 -#define LP8788_BUCK2_VOUT1 0x23 -#define LP8788_BUCK2_VOUT2 0x24 -#define LP8788_BUCK2_VOUT3 0x25 -#define LP8788_BUCK3_VOUT 0x26 -#define LP8788_BUCK4_VOUT 0x27 -#define LP8788_BUCK1_TIMESTEP 0x28 -#define LP8788_BUCK_PWM 0x2D - -/* mask/shift bits */ -#define LP8788_EN_BUCK1_M BIT(0) /* Addr 0Ch */ -#define LP8788_EN_BUCK2_M BIT(1) -#define LP8788_EN_BUCK3_M BIT(2) -#define LP8788_EN_BUCK4_M BIT(3) -#define LP8788_BUCK1_DVS_SEL_M 0x04 /* Addr 1Dh */ -#define LP8788_BUCK1_DVS_M 0x03 -#define LP8788_BUCK1_DVS_S 0 -#define LP8788_BUCK2_DVS_SEL_M 0x40 -#define LP8788_BUCK2_DVS_M 0x30 -#define LP8788_BUCK2_DVS_S 4 -#define LP8788_BUCK1_DVS_I2C BIT(2) -#define LP8788_BUCK2_DVS_I2C BIT(6) -#define LP8788_BUCK1_DVS_PIN (0 << 2) -#define LP8788_BUCK2_DVS_PIN (0 << 6) -#define LP8788_VOUT_M 0x1F /* Addr 1Eh ~ 27h */ -#define LP8788_STARTUP_TIME_M 0xF8 /* Addr 28h ~ 2Bh */ -#define LP8788_STARTUP_TIME_S 3 -#define LP8788_FPWM_BUCK1_M BIT(0) /* Addr 2Dh */ -#define LP8788_FPWM_BUCK1_S 0 -#define LP8788_FPWM_BUCK2_M BIT(1) -#define LP8788_FPWM_BUCK2_S 1 -#define LP8788_FPWM_BUCK3_M BIT(2) -#define LP8788_FPWM_BUCK3_S 2 -#define LP8788_FPWM_BUCK4_M BIT(3) -#define LP8788_FPWM_BUCK4_S 3 - -#define INVALID_ADDR 0xFF -#define LP8788_FORCE_PWM 1 -#define LP8788_AUTO_PWM 0 -#define PIN_LOW 0 -#define PIN_HIGH 1 -#define ENABLE_TIME_USEC 32 - -enum lp8788_dvs_state { - DVS_LOW = GPIOF_OUT_INIT_LOW, - DVS_HIGH = GPIOF_OUT_INIT_HIGH, -}; - -enum lp8788_dvs_mode { - REGISTER, - EXTPIN, -}; - -enum lp8788_buck_id { - BUCK1, - BUCK2, - BUCK3, - BUCK4, -}; - -struct lp8788_pwm_map { - u8 mask; - u8 shift; -}; - -struct lp8788_buck { - struct lp8788 *lp; - struct regulator_dev *regulator; - struct lp8788_pwm_map *pmap; - void *dvs; -}; - -/* BUCK 1 ~ 4 voltage table */ -static const int lp8788_buck_vtbl[] = { - 500000, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, - 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, - 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, - 1950000, 2000000, -}; - -/* buck pwm mode selection : used for set/get_mode in regulator ops - * @forced pwm : fast mode - * @auto pwm : normal mode - */ -static struct lp8788_pwm_map buck_pmap[] = { - [BUCK1] = { - .mask = LP8788_FPWM_BUCK1_M, - .shift = LP8788_FPWM_BUCK1_S, - }, - [BUCK2] = { - .mask = LP8788_FPWM_BUCK2_M, - .shift = LP8788_FPWM_BUCK2_S, - }, - [BUCK3] = { - .mask = LP8788_FPWM_BUCK3_M, - .shift = LP8788_FPWM_BUCK3_S, - }, - [BUCK4] = { - .mask = LP8788_FPWM_BUCK4_M, - .shift = LP8788_FPWM_BUCK4_S, - }, -}; - -static const u8 buck1_vout_addr[] = { - LP8788_BUCK1_VOUT0, LP8788_BUCK1_VOUT1, - LP8788_BUCK1_VOUT2, LP8788_BUCK1_VOUT3, -}; - -static const u8 buck2_vout_addr[] = { - LP8788_BUCK2_VOUT0, LP8788_BUCK2_VOUT1, - LP8788_BUCK2_VOUT2, LP8788_BUCK2_VOUT3, -}; - -static void lp8788_buck1_set_dvs(struct lp8788_buck *buck) -{ - struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs; - enum lp8788_dvs_state pinstate; - - if (!dvs) - return; - - pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH; - if (gpio_is_valid(dvs->gpio)) - gpio_set_value(dvs->gpio, pinstate); -} - -static void lp8788_buck2_set_dvs(struct lp8788_buck *buck) -{ - struct lp8788_buck2_dvs *dvs = (struct lp8788_buck2_dvs *)buck->dvs; - enum lp8788_dvs_state pin1, pin2; - - if (!dvs) - return; - - switch (dvs->vsel) { - case DVS_SEL_V0: - pin1 = DVS_LOW; - pin2 = DVS_LOW; - break; - case DVS_SEL_V1: - pin1 = DVS_HIGH; - pin2 = DVS_LOW; - break; - case DVS_SEL_V2: - pin1 = DVS_LOW; - pin2 = DVS_HIGH; - break; - case DVS_SEL_V3: - pin1 = DVS_HIGH; - pin2 = DVS_HIGH; - break; - default: - return; - } - - if (gpio_is_valid(dvs->gpio[0])) - gpio_set_value(dvs->gpio[0], pin1); - - if (gpio_is_valid(dvs->gpio[1])) - gpio_set_value(dvs->gpio[1], pin2); -} - -static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id) -{ - switch (id) { - case BUCK1: - lp8788_buck1_set_dvs(buck); - break; - case BUCK2: - lp8788_buck2_set_dvs(buck); - break; - default: - break; - } -} - -static enum lp8788_dvs_mode -lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck *buck, enum lp8788_buck_id id) -{ - u8 val, mask; - - switch (id) { - case BUCK1: - mask = LP8788_BUCK1_DVS_SEL_M; - break; - case BUCK2: - mask = LP8788_BUCK2_DVS_SEL_M; - break; - default: - return REGISTER; - } - - lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); - - return val & mask ? REGISTER : EXTPIN; -} - -static bool lp8788_is_valid_buck_addr(u8 addr) -{ - switch (addr) { - case LP8788_BUCK1_VOUT0: - case LP8788_BUCK1_VOUT1: - case LP8788_BUCK1_VOUT2: - case LP8788_BUCK1_VOUT3: - case LP8788_BUCK2_VOUT0: - case LP8788_BUCK2_VOUT1: - case LP8788_BUCK2_VOUT2: - case LP8788_BUCK2_VOUT3: - return true; - default: - return false; - } -} - -static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck, - enum lp8788_buck_id id) -{ - enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id); - struct lp8788_buck1_dvs *b1_dvs; - struct lp8788_buck2_dvs *b2_dvs; - u8 val, idx, addr; - int pin1, pin2; - - switch (id) { - case BUCK1: - if (mode == EXTPIN) { - b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs; - if (!b1_dvs) - goto err; - - idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0; - } else { - lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); - idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S; - } - addr = buck1_vout_addr[idx]; - break; - case BUCK2: - if (mode == EXTPIN) { - b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs; - if (!b2_dvs) - goto err; - - pin1 = gpio_get_value(b2_dvs->gpio[0]); - pin2 = gpio_get_value(b2_dvs->gpio[1]); - - if (pin1 == PIN_LOW && pin2 == PIN_LOW) - idx = 0; - else if (pin1 == PIN_LOW && pin2 == PIN_HIGH) - idx = 2; - else if (pin1 == PIN_HIGH && pin2 == PIN_LOW) - idx = 1; - else - idx = 3; - } else { - lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); - idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S; - } - addr = buck2_vout_addr[idx]; - break; - default: - goto err; - } - - return addr; -err: - return INVALID_ADDR; -} - -static int lp8788_buck12_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) -{ - struct lp8788_buck *buck = rdev_get_drvdata(rdev); - enum lp8788_buck_id id = rdev_get_id(rdev); - u8 addr; - - if (buck->dvs) - lp8788_set_dvs(buck, id); - - addr = lp8788_select_buck_vout_addr(buck, id); - if (!lp8788_is_valid_buck_addr(addr)) - return -EINVAL; - - return lp8788_update_bits(buck->lp, addr, LP8788_VOUT_M, selector); -} - -static int lp8788_buck12_get_voltage_sel(struct regulator_dev *rdev) -{ - struct lp8788_buck *buck = rdev_get_drvdata(rdev); - enum lp8788_buck_id id = rdev_get_id(rdev); - int ret; - u8 val, addr; - - addr = lp8788_select_buck_vout_addr(buck, id); - if (!lp8788_is_valid_buck_addr(addr)) - return -EINVAL; - - ret = lp8788_read_byte(buck->lp, addr, &val); - if (ret) - return ret; - - return val & LP8788_VOUT_M; -} - -static int lp8788_buck_enable_time(struct regulator_dev *rdev) -{ - struct lp8788_buck *buck = rdev_get_drvdata(rdev); - enum lp8788_buck_id id = rdev_get_id(rdev); - u8 val, addr = LP8788_BUCK1_TIMESTEP + id; - - if (lp8788_read_byte(buck->lp, addr, &val)) - return -EINVAL; - - val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S; - - return ENABLE_TIME_USEC * val; -} - -static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) -{ - struct lp8788_buck *buck = rdev_get_drvdata(rdev); - struct lp8788_pwm_map *pmap = buck->pmap; - u8 val; - - if (!pmap) - return -EINVAL; - - switch (mode) { - case REGULATOR_MODE_FAST: - val = LP8788_FORCE_PWM << pmap->shift; - break; - case REGULATOR_MODE_NORMAL: - val = LP8788_AUTO_PWM << pmap->shift; - break; - default: - return -EINVAL; - } - - return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, pmap->mask, val); -} - -static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev) -{ - struct lp8788_buck *buck = rdev_get_drvdata(rdev); - struct lp8788_pwm_map *pmap = buck->pmap; - u8 val; - int ret; - - if (!pmap) - return -EINVAL; - - ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val); - if (ret) - return ret; - - return val & pmap->mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; -} - -static struct regulator_ops lp8788_buck12_ops = { - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = lp8788_buck12_set_voltage_sel, - .get_voltage_sel = lp8788_buck12_get_voltage_sel, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .enable_time = lp8788_buck_enable_time, - .set_mode = lp8788_buck_set_mode, - .get_mode = lp8788_buck_get_mode, -}; - -static struct regulator_ops lp8788_buck34_ops = { - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .enable_time = lp8788_buck_enable_time, - .set_mode = lp8788_buck_set_mode, - .get_mode = lp8788_buck_get_mode, -}; - -static struct regulator_desc lp8788_buck_desc[] = { - { - .name = "buck1", - .id = BUCK1, - .ops = &lp8788_buck12_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_BUCK, - .enable_mask = LP8788_EN_BUCK1_M, - }, - { - .name = "buck2", - .id = BUCK2, - .ops = &lp8788_buck12_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_BUCK, - .enable_mask = LP8788_EN_BUCK2_M, - }, - { - .name = "buck3", - .id = BUCK3, - .ops = &lp8788_buck34_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_BUCK3_VOUT, - .vsel_mask = LP8788_VOUT_M, - .enable_reg = LP8788_EN_BUCK, - .enable_mask = LP8788_EN_BUCK3_M, - }, - { - .name = "buck4", - .id = BUCK4, - .ops = &lp8788_buck34_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_BUCK4_VOUT, - .vsel_mask = LP8788_VOUT_M, - .enable_reg = LP8788_EN_BUCK, - .enable_mask = LP8788_EN_BUCK4_M, - }, -}; - -static int lp8788_set_default_dvs_ctrl_mode(struct lp8788 *lp, - enum lp8788_buck_id id) -{ - u8 mask, val; - - switch (id) { - case BUCK1: - mask = LP8788_BUCK1_DVS_SEL_M; - val = LP8788_BUCK1_DVS_I2C; - break; - case BUCK2: - mask = LP8788_BUCK2_DVS_SEL_M; - val = LP8788_BUCK2_DVS_I2C; - break; - default: - return 0; - } - - return lp8788_update_bits(lp, LP8788_BUCK_DVS_SEL, mask, val); -} - -static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name) -{ - struct device *dev = buck->lp->dev; - - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio: %d\n", gpio); - return -EINVAL; - } - - return devm_gpio_request_one(dev, gpio, DVS_LOW, name); -} - -static int lp8788_dvs_gpio_request(struct lp8788_buck *buck, - enum lp8788_buck_id id) -{ - struct lp8788_platform_data *pdata = buck->lp->pdata; - char *b1_name = "LP8788_B1_DVS"; - char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" }; - int i, gpio, ret; - - switch (id) { - case BUCK1: - gpio = pdata->buck1_dvs->gpio; - ret = _gpio_request(buck, gpio, b1_name); - if (ret) - return ret; - - buck->dvs = pdata->buck1_dvs; - break; - case BUCK2: - for (i = 0 ; i < LP8788_NUM_BUCK2_DVS ; i++) { - gpio = pdata->buck2_dvs->gpio[i]; - ret = _gpio_request(buck, gpio, b2_name[i]); - if (ret) - return ret; - } - buck->dvs = pdata->buck2_dvs; - break; - default: - break; - } - - return 0; -} - -static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id) -{ - struct lp8788_platform_data *pdata = buck->lp->pdata; - u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M }; - u8 val[] = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN }; - - /* no dvs for buck3, 4 */ - if (id == BUCK3 || id == BUCK4) - return 0; - - /* no dvs platform data, then dvs will be selected by I2C registers */ - if (!pdata) - goto set_default_dvs_mode; - - if ((id == BUCK1 && !pdata->buck1_dvs) || - (id == BUCK2 && !pdata->buck2_dvs)) - goto set_default_dvs_mode; - - if (lp8788_dvs_gpio_request(buck, id)) - goto set_default_dvs_mode; - - return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id], - val[id]); - -set_default_dvs_mode: - return lp8788_set_default_dvs_ctrl_mode(buck->lp, id); -} - -static __devinit int lp8788_buck_probe(struct platform_device *pdev) -{ - struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); - int id = pdev->id; - struct lp8788_buck *buck; - struct regulator_config cfg = { }; - struct regulator_dev *rdev; - int ret; - - buck = devm_kzalloc(lp->dev, sizeof(struct lp8788_buck), GFP_KERNEL); - if (!buck) - return -ENOMEM; - - buck->lp = lp; - buck->pmap = &buck_pmap[id]; - - ret = lp8788_init_dvs(buck, id); - if (ret) - return ret; - - cfg.dev = lp->dev; - cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL; - cfg.driver_data = buck; - cfg.regmap = lp->regmap; - - rdev = regulator_register(&lp8788_buck_desc[id], &cfg); - if (IS_ERR(rdev)) { - ret = PTR_ERR(rdev); - dev_err(lp->dev, "BUCK%d regulator register err = %d\n", - id + 1, ret); - return ret; - } - - buck->regulator = rdev; - platform_set_drvdata(pdev, buck); - - return 0; -} - -static int __devexit lp8788_buck_remove(struct platform_device *pdev) -{ - struct lp8788_buck *buck = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - regulator_unregister(buck->regulator); - - return 0; -} - -static struct platform_driver lp8788_buck_driver = { - .probe = lp8788_buck_probe, - .remove = __devexit_p(lp8788_buck_remove), - .driver = { - .name = LP8788_DEV_BUCK, - .owner = THIS_MODULE, - }, -}; - -static int __init lp8788_buck_init(void) -{ - return platform_driver_register(&lp8788_buck_driver); -} -subsys_initcall(lp8788_buck_init); - -static void __exit lp8788_buck_exit(void) -{ - platform_driver_unregister(&lp8788_buck_driver); -} -module_exit(lp8788_buck_exit); - -MODULE_DESCRIPTION("TI LP8788 BUCK Driver"); -MODULE_AUTHOR("Milo Kim"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:lp8788-buck"); diff --git a/trunk/drivers/regulator/lp8788-ldo.c b/trunk/drivers/regulator/lp8788-ldo.c deleted file mode 100644 index d2122e41a96d..000000000000 --- a/trunk/drivers/regulator/lp8788-ldo.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * TI LP8788 MFD - ldo regulator driver - * - * Copyright 2012 Texas Instruments - * - * Author: Milo(Woogyom) Kim - * - * 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 - -/* register address */ -#define LP8788_EN_LDO_A 0x0D /* DLDO 1 ~ 8 */ -#define LP8788_EN_LDO_B 0x0E /* DLDO 9 ~ 12, ALDO 1 ~ 4 */ -#define LP8788_EN_LDO_C 0x0F /* ALDO 5 ~ 10 */ -#define LP8788_EN_SEL 0x10 -#define LP8788_DLDO1_VOUT 0x2E -#define LP8788_DLDO2_VOUT 0x2F -#define LP8788_DLDO3_VOUT 0x30 -#define LP8788_DLDO4_VOUT 0x31 -#define LP8788_DLDO5_VOUT 0x32 -#define LP8788_DLDO6_VOUT 0x33 -#define LP8788_DLDO7_VOUT 0x34 -#define LP8788_DLDO8_VOUT 0x35 -#define LP8788_DLDO9_VOUT 0x36 -#define LP8788_DLDO10_VOUT 0x37 -#define LP8788_DLDO11_VOUT 0x38 -#define LP8788_DLDO12_VOUT 0x39 -#define LP8788_ALDO1_VOUT 0x3A -#define LP8788_ALDO2_VOUT 0x3B -#define LP8788_ALDO3_VOUT 0x3C -#define LP8788_ALDO4_VOUT 0x3D -#define LP8788_ALDO5_VOUT 0x3E -#define LP8788_ALDO6_VOUT 0x3F -#define LP8788_ALDO7_VOUT 0x40 -#define LP8788_ALDO8_VOUT 0x41 -#define LP8788_ALDO9_VOUT 0x42 -#define LP8788_ALDO10_VOUT 0x43 -#define LP8788_DLDO1_TIMESTEP 0x44 - -/* mask/shift bits */ -#define LP8788_EN_DLDO1_M BIT(0) /* Addr 0Dh ~ 0Fh */ -#define LP8788_EN_DLDO2_M BIT(1) -#define LP8788_EN_DLDO3_M BIT(2) -#define LP8788_EN_DLDO4_M BIT(3) -#define LP8788_EN_DLDO5_M BIT(4) -#define LP8788_EN_DLDO6_M BIT(5) -#define LP8788_EN_DLDO7_M BIT(6) -#define LP8788_EN_DLDO8_M BIT(7) -#define LP8788_EN_DLDO9_M BIT(0) -#define LP8788_EN_DLDO10_M BIT(1) -#define LP8788_EN_DLDO11_M BIT(2) -#define LP8788_EN_DLDO12_M BIT(3) -#define LP8788_EN_ALDO1_M BIT(4) -#define LP8788_EN_ALDO2_M BIT(5) -#define LP8788_EN_ALDO3_M BIT(6) -#define LP8788_EN_ALDO4_M BIT(7) -#define LP8788_EN_ALDO5_M BIT(0) -#define LP8788_EN_ALDO6_M BIT(1) -#define LP8788_EN_ALDO7_M BIT(2) -#define LP8788_EN_ALDO8_M BIT(3) -#define LP8788_EN_ALDO9_M BIT(4) -#define LP8788_EN_ALDO10_M BIT(5) -#define LP8788_EN_SEL_DLDO911_M BIT(0) /* Addr 10h */ -#define LP8788_EN_SEL_DLDO7_M BIT(1) -#define LP8788_EN_SEL_ALDO7_M BIT(2) -#define LP8788_EN_SEL_ALDO5_M BIT(3) -#define LP8788_EN_SEL_ALDO234_M BIT(4) -#define LP8788_EN_SEL_ALDO1_M BIT(5) -#define LP8788_VOUT_5BIT_M 0x1F /* Addr 2Eh ~ 43h */ -#define LP8788_VOUT_4BIT_M 0x0F -#define LP8788_VOUT_3BIT_M 0x07 -#define LP8788_VOUT_1BIT_M 0x01 -#define LP8788_STARTUP_TIME_M 0xF8 /* Addr 44h ~ 59h */ -#define LP8788_STARTUP_TIME_S 3 - -#define ENABLE_TIME_USEC 32 -#define ENABLE GPIOF_OUT_INIT_HIGH -#define DISABLE GPIOF_OUT_INIT_LOW - -enum lp8788_enable_mode { - REGISTER, - EXTPIN, -}; - -enum lp8788_ldo_id { - DLDO1, - DLDO2, - DLDO3, - DLDO4, - DLDO5, - DLDO6, - DLDO7, - DLDO8, - DLDO9, - DLDO10, - DLDO11, - DLDO12, - ALDO1, - ALDO2, - ALDO3, - ALDO4, - ALDO5, - ALDO6, - ALDO7, - ALDO8, - ALDO9, - ALDO10, -}; - -struct lp8788_ldo { - struct lp8788 *lp; - struct regulator_desc *desc; - struct regulator_dev *regulator; - struct lp8788_ldo_enable_pin *en_pin; -}; - -/* DLDO 1, 2, 3, 9 voltage table */ -const int lp8788_dldo1239_vtbl[] = { - 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, - 2600000, 2700000, 2800000, 2900000, 3000000, 2850000, 2850000, 2850000, - 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, - 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, -}; - -/* DLDO 4 voltage table */ -static const int lp8788_dldo4_vtbl[] = { 1800000, 3000000 }; - -/* DLDO 5, 7, 8 and ALDO 6 voltage table */ -static const int lp8788_dldo578_aldo6_vtbl[] = { - 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, - 2600000, 2700000, 2800000, 2900000, 3000000, 3000000, 3000000, 3000000, -}; - -/* DLDO 6 voltage table */ -static const int lp8788_dldo6_vtbl[] = { - 3000000, 3100000, 3200000, 3300000, 3400000, 3500000, 3600000, 3600000, -}; - -/* DLDO 10, 11 voltage table */ -static const int lp8788_dldo1011_vtbl[] = { - 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, - 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, -}; - -/* ALDO 1 voltage table */ -static const int lp8788_aldo1_vtbl[] = { 1800000, 2850000 }; - -/* ALDO 7 voltage table */ -static const int lp8788_aldo7_vtbl[] = { - 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000, -}; - -static enum lp8788_ldo_id lp8788_dldo_id[] = { - DLDO1, - DLDO2, - DLDO3, - DLDO4, - DLDO5, - DLDO6, - DLDO7, - DLDO8, - DLDO9, - DLDO10, - DLDO11, - DLDO12, -}; - -static enum lp8788_ldo_id lp8788_aldo_id[] = { - ALDO1, - ALDO2, - ALDO3, - ALDO4, - ALDO5, - ALDO6, - ALDO7, - ALDO8, - ALDO9, - ALDO10, -}; - -/* DLDO 7, 9 and 11, ALDO 1 ~ 5 and 7 - : can be enabled either by external pin or by i2c register */ -static enum lp8788_enable_mode -lp8788_get_ldo_enable_mode(struct lp8788_ldo *ldo, enum lp8788_ldo_id id) -{ - int ret; - u8 val, mask; - - ret = lp8788_read_byte(ldo->lp, LP8788_EN_SEL, &val); - if (ret) - return ret; - - switch (id) { - case DLDO7: - mask = LP8788_EN_SEL_DLDO7_M; - break; - case DLDO9: - case DLDO11: - mask = LP8788_EN_SEL_DLDO911_M; - break; - case ALDO1: - mask = LP8788_EN_SEL_ALDO1_M; - break; - case ALDO2 ... ALDO4: - mask = LP8788_EN_SEL_ALDO234_M; - break; - case ALDO5: - mask = LP8788_EN_SEL_ALDO5_M; - break; - case ALDO7: - mask = LP8788_EN_SEL_ALDO7_M; - break; - default: - return REGISTER; - } - - return val & mask ? EXTPIN : REGISTER; -} - -static int lp8788_ldo_ctrl_by_extern_pin(struct lp8788_ldo *ldo, int pinstate) -{ - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - - if (!pin) - return -EINVAL; - - if (gpio_is_valid(pin->gpio)) - gpio_set_value(pin->gpio, pinstate); - - return 0; -} - -static int lp8788_ldo_is_enabled_by_extern_pin(struct lp8788_ldo *ldo) -{ - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - - if (!pin) - return -EINVAL; - - return gpio_get_value(pin->gpio) ? 1 : 0; -} - -static int lp8788_ldo_enable(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id); - - switch (mode) { - case EXTPIN: - return lp8788_ldo_ctrl_by_extern_pin(ldo, ENABLE); - case REGISTER: - return regulator_enable_regmap(rdev); - default: - return -EINVAL; - } -} - -static int lp8788_ldo_disable(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id); - - switch (mode) { - case EXTPIN: - return lp8788_ldo_ctrl_by_extern_pin(ldo, DISABLE); - case REGISTER: - return regulator_disable_regmap(rdev); - default: - return -EINVAL; - } -} - -static int lp8788_ldo_is_enabled(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id); - - switch (mode) { - case EXTPIN: - return lp8788_ldo_is_enabled_by_extern_pin(ldo); - case REGISTER: - return regulator_is_enabled_regmap(rdev); - default: - return -EINVAL; - } -} - -static int lp8788_ldo_enable_time(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - enum lp8788_ldo_id id = rdev_get_id(rdev); - u8 val, addr = LP8788_DLDO1_TIMESTEP + id; - - if (lp8788_read_byte(ldo->lp, addr, &val)) - return -EINVAL; - - val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S; - - return ENABLE_TIME_USEC * val; -} - -static int lp8788_ldo_fixed_get_voltage(struct regulator_dev *rdev) -{ - enum lp8788_ldo_id id = rdev_get_id(rdev); - - switch (id) { - case ALDO2 ... ALDO5: - return 2850000; - case DLDO12: - case ALDO8 ... ALDO9: - return 2500000; - case ALDO10: - return 1100000; - default: - return -EINVAL; - } -} - -static struct regulator_ops lp8788_ldo_voltage_table_ops = { - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = lp8788_ldo_enable, - .disable = lp8788_ldo_disable, - .is_enabled = lp8788_ldo_is_enabled, - .enable_time = lp8788_ldo_enable_time, -}; - -static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { - .get_voltage = lp8788_ldo_fixed_get_voltage, - .enable = lp8788_ldo_enable, - .disable = lp8788_ldo_disable, - .is_enabled = lp8788_ldo_is_enabled, - .enable_time = lp8788_ldo_enable_time, -}; - -static struct regulator_desc lp8788_dldo_desc[] = { - { - .name = "dldo1", - .id = DLDO1, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl), - .volt_table = lp8788_dldo1239_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO1_VOUT, - .vsel_mask = LP8788_VOUT_5BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO1_M, - }, - { - .name = "dldo2", - .id = DLDO2, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl), - .volt_table = lp8788_dldo1239_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO2_VOUT, - .vsel_mask = LP8788_VOUT_5BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO2_M, - }, - { - .name = "dldo3", - .id = DLDO3, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl), - .volt_table = lp8788_dldo1239_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO3_VOUT, - .vsel_mask = LP8788_VOUT_5BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO3_M, - }, - { - .name = "dldo4", - .id = DLDO4, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo4_vtbl), - .volt_table = lp8788_dldo4_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO4_VOUT, - .vsel_mask = LP8788_VOUT_1BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO4_M, - }, - { - .name = "dldo5", - .id = DLDO5, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl), - .volt_table = lp8788_dldo578_aldo6_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO5_VOUT, - .vsel_mask = LP8788_VOUT_4BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO5_M, - }, - { - .name = "dldo6", - .id = DLDO6, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo6_vtbl), - .volt_table = lp8788_dldo6_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO6_VOUT, - .vsel_mask = LP8788_VOUT_3BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO6_M, - }, - { - .name = "dldo7", - .id = DLDO7, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl), - .volt_table = lp8788_dldo578_aldo6_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO7_VOUT, - .vsel_mask = LP8788_VOUT_4BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO7_M, - }, - { - .name = "dldo8", - .id = DLDO8, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl), - .volt_table = lp8788_dldo578_aldo6_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO8_VOUT, - .vsel_mask = LP8788_VOUT_4BIT_M, - .enable_reg = LP8788_EN_LDO_A, - .enable_mask = LP8788_EN_DLDO8_M, - }, - { - .name = "dldo9", - .id = DLDO9, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl), - .volt_table = lp8788_dldo1239_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO9_VOUT, - .vsel_mask = LP8788_VOUT_5BIT_M, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_DLDO9_M, - }, - { - .name = "dldo10", - .id = DLDO10, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl), - .volt_table = lp8788_dldo1011_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO10_VOUT, - .vsel_mask = LP8788_VOUT_4BIT_M, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_DLDO10_M, - }, - { - .name = "dldo11", - .id = DLDO11, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl), - .volt_table = lp8788_dldo1011_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_DLDO11_VOUT, - .vsel_mask = LP8788_VOUT_4BIT_M, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_DLDO11_M, - }, - { - .name = "dldo12", - .id = DLDO12, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_DLDO12_M, - }, -}; - -static struct regulator_desc lp8788_aldo_desc[] = { - { - .name = "aldo1", - .id = ALDO1, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_aldo1_vtbl), - .volt_table = lp8788_aldo1_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_ALDO1_VOUT, - .vsel_mask = LP8788_VOUT_1BIT_M, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_ALDO1_M, - }, - { - .name = "aldo2", - .id = ALDO2, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_ALDO2_M, - }, - { - .name = "aldo3", - .id = ALDO3, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_ALDO3_M, - }, - { - .name = "aldo4", - .id = ALDO4, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_B, - .enable_mask = LP8788_EN_ALDO4_M, - }, - { - .name = "aldo5", - .id = ALDO5, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_C, - .enable_mask = LP8788_EN_ALDO5_M, - }, - { - .name = "aldo6", - .id = ALDO6, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl), - .volt_table = lp8788_dldo578_aldo6_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_ALDO6_VOUT, - .vsel_mask = LP8788_VOUT_4BIT_M, - .enable_reg = LP8788_EN_LDO_C, - .enable_mask = LP8788_EN_ALDO6_M, - }, - { - .name = "aldo7", - .id = ALDO7, - .ops = &lp8788_ldo_voltage_table_ops, - .n_voltages = ARRAY_SIZE(lp8788_aldo7_vtbl), - .volt_table = lp8788_aldo7_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8788_ALDO7_VOUT, - .vsel_mask = LP8788_VOUT_3BIT_M, - .enable_reg = LP8788_EN_LDO_C, - .enable_mask = LP8788_EN_ALDO7_M, - }, - { - .name = "aldo8", - .id = ALDO8, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_C, - .enable_mask = LP8788_EN_ALDO8_M, - }, - { - .name = "aldo9", - .id = ALDO9, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_C, - .enable_mask = LP8788_EN_ALDO9_M, - }, - { - .name = "aldo10", - .id = ALDO10, - .ops = &lp8788_ldo_voltage_fixed_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP8788_EN_LDO_C, - .enable_mask = LP8788_EN_ALDO10_M, - }, -}; - -static int lp8788_gpio_request_ldo_en(struct lp8788_ldo *ldo, - enum lp8788_ext_ldo_en_id id) -{ - struct device *dev = ldo->lp->dev; - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - int ret, gpio, pinstate; - char *name[] = { - [EN_ALDO1] = "LP8788_EN_ALDO1", - [EN_ALDO234] = "LP8788_EN_ALDO234", - [EN_ALDO5] = "LP8788_EN_ALDO5", - [EN_ALDO7] = "LP8788_EN_ALDO7", - [EN_DLDO7] = "LP8788_EN_DLDO7", - [EN_DLDO911] = "LP8788_EN_DLDO911", - }; - - gpio = pin->gpio; - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio: %d\n", gpio); - return -EINVAL; - } - - pinstate = pin->init_state; - ret = devm_gpio_request_one(dev, gpio, pinstate, name[id]); - if (ret == -EBUSY) { - dev_warn(dev, "gpio%d already used\n", gpio); - return 0; - } - - return ret; -} - -static int lp8788_config_ldo_enable_mode(struct lp8788_ldo *ldo, - enum lp8788_ldo_id id) -{ - int ret; - struct lp8788 *lp = ldo->lp; - struct lp8788_platform_data *pdata = lp->pdata; - enum lp8788_ext_ldo_en_id enable_id; - u8 en_mask[] = { - [EN_ALDO1] = LP8788_EN_SEL_ALDO1_M, - [EN_ALDO234] = LP8788_EN_SEL_ALDO234_M, - [EN_ALDO5] = LP8788_EN_SEL_ALDO5_M, - [EN_ALDO7] = LP8788_EN_SEL_ALDO7_M, - [EN_DLDO7] = LP8788_EN_SEL_DLDO7_M, - [EN_DLDO911] = LP8788_EN_SEL_DLDO911_M, - }; - u8 val[] = { - [EN_ALDO1] = 0 << 5, - [EN_ALDO234] = 0 << 4, - [EN_ALDO5] = 0 << 3, - [EN_ALDO7] = 0 << 2, - [EN_DLDO7] = 0 << 1, - [EN_DLDO911] = 0 << 0, - }; - - switch (id) { - case DLDO7: - enable_id = EN_DLDO7; - break; - case DLDO9: - case DLDO11: - enable_id = EN_DLDO911; - break; - case ALDO1: - enable_id = EN_ALDO1; - break; - case ALDO2 ... ALDO4: - enable_id = EN_ALDO234; - break; - case ALDO5: - enable_id = EN_ALDO5; - break; - case ALDO7: - enable_id = EN_ALDO7; - break; - default: - return 0; - } - - /* if no platform data for ldo pin, then set default enable mode */ - if (!pdata || !pdata->ldo_pin || !pdata->ldo_pin[enable_id]) - goto set_default_ldo_enable_mode; - - ldo->en_pin = pdata->ldo_pin[enable_id]; - - ret = lp8788_gpio_request_ldo_en(ldo, enable_id); - if (ret) - goto set_default_ldo_enable_mode; - - return ret; - -set_default_ldo_enable_mode: - return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], - val[enable_id]); -} - -static __devinit int lp8788_dldo_probe(struct platform_device *pdev) -{ - struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); - int id = pdev->id; - struct lp8788_ldo *ldo; - struct regulator_config cfg = { }; - struct regulator_dev *rdev; - int ret; - - ldo = devm_kzalloc(lp->dev, sizeof(struct lp8788_ldo), GFP_KERNEL); - if (!ldo) - return -ENOMEM; - - ldo->lp = lp; - ret = lp8788_config_ldo_enable_mode(ldo, lp8788_dldo_id[id]); - if (ret) - return ret; - - cfg.dev = lp->dev; - cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL; - cfg.driver_data = ldo; - cfg.regmap = lp->regmap; - - rdev = regulator_register(&lp8788_dldo_desc[id], &cfg); - if (IS_ERR(rdev)) { - ret = PTR_ERR(rdev); - dev_err(lp->dev, "DLDO%d regulator register err = %d\n", - id + 1, ret); - return ret; - } - - ldo->regulator = rdev; - platform_set_drvdata(pdev, ldo); - - return 0; -} - -static int __devexit lp8788_dldo_remove(struct platform_device *pdev) -{ - struct lp8788_ldo *ldo = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - regulator_unregister(ldo->regulator); - - return 0; -} - -static struct platform_driver lp8788_dldo_driver = { - .probe = lp8788_dldo_probe, - .remove = __devexit_p(lp8788_dldo_remove), - .driver = { - .name = LP8788_DEV_DLDO, - .owner = THIS_MODULE, - }, -}; - -static __devinit int lp8788_aldo_probe(struct platform_device *pdev) -{ - struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); - int id = pdev->id; - struct lp8788_ldo *ldo; - struct regulator_config cfg = { }; - struct regulator_dev *rdev; - int ret; - - ldo = devm_kzalloc(lp->dev, sizeof(struct lp8788_ldo), GFP_KERNEL); - if (!ldo) - return -ENOMEM; - - ldo->lp = lp; - ret = lp8788_config_ldo_enable_mode(ldo, lp8788_aldo_id[id]); - if (ret) - return ret; - - cfg.dev = lp->dev; - cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL; - cfg.driver_data = ldo; - cfg.regmap = lp->regmap; - - rdev = regulator_register(&lp8788_aldo_desc[id], &cfg); - if (IS_ERR(rdev)) { - ret = PTR_ERR(rdev); - dev_err(lp->dev, "ALDO%d regulator register err = %d\n", - id + 1, ret); - return ret; - } - - ldo->regulator = rdev; - platform_set_drvdata(pdev, ldo); - - return 0; -} - -static int __devexit lp8788_aldo_remove(struct platform_device *pdev) -{ - struct lp8788_ldo *ldo = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - regulator_unregister(ldo->regulator); - - return 0; -} - -static struct platform_driver lp8788_aldo_driver = { - .probe = lp8788_aldo_probe, - .remove = __devexit_p(lp8788_aldo_remove), - .driver = { - .name = LP8788_DEV_ALDO, - .owner = THIS_MODULE, - }, -}; - -static int __init lp8788_ldo_init(void) -{ - int ret; - - ret = platform_driver_register(&lp8788_dldo_driver); - if (ret) - return ret; - - return platform_driver_register(&lp8788_aldo_driver); -} -subsys_initcall(lp8788_ldo_init); - -static void __exit lp8788_ldo_exit(void) -{ - platform_driver_unregister(&lp8788_aldo_driver); - platform_driver_unregister(&lp8788_dldo_driver); -} -module_exit(lp8788_ldo_exit); - -MODULE_DESCRIPTION("TI LP8788 LDO Driver"); -MODULE_AUTHOR("Milo Kim"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:lp8788-dldo"); -MODULE_ALIAS("platform:lp8788-aldo"); diff --git a/trunk/drivers/regulator/max1586.c b/trunk/drivers/regulator/max1586.c index f67af3c1b963..b9444ee08da9 100644 --- a/trunk/drivers/regulator/max1586.c +++ b/trunk/drivers/regulator/max1586.c @@ -47,14 +47,6 @@ struct max1586_data { struct regulator_dev *rdev[0]; }; -/* - * V6 voltage - * On I2C bus, sending a "x" byte to the max1586 means : - * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3) - * As regulator framework doesn't accept voltages to be 0V, we use 1uV. - */ -static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; - /* * V3 voltage * On I2C bus, sending a "x" byte to the max1586 means : @@ -63,49 +55,113 @@ static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; * R24 and R25=100kOhm as described in the data sheet. * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm */ -static int max1586_v3_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int max1586_v3_calc_voltage(struct max1586_data *max1586, + unsigned selector) +{ + unsigned range_uV = max1586->max_uV - max1586->min_uV; + + return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL); +} + +static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned *selector) { struct max1586_data *max1586 = rdev_get_drvdata(rdev); struct i2c_client *client = max1586->client; + unsigned range_uV = max1586->max_uV - max1586->min_uV; u8 v3_prog; + if (min_uV > max1586->max_uV || max_uV < max1586->min_uV) + return -EINVAL; + if (min_uV < max1586->min_uV) + min_uV = max1586->min_uV; + + *selector = DIV_ROUND_UP((min_uV - max1586->min_uV) * + MAX1586_V3_MAX_VSEL, range_uV); + if (max1586_v3_calc_voltage(max1586, *selector) > max_uV) + return -EINVAL; + dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", - regulator_list_voltage_linear(rdev, selector) / 1000); + max1586_v3_calc_voltage(max1586, *selector) / 1000); - v3_prog = I2C_V3_SELECT | (u8) selector; + v3_prog = I2C_V3_SELECT | (u8) *selector; return i2c_smbus_write_byte(client, v3_prog); } -static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) +static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector) +{ + struct max1586_data *max1586 = rdev_get_drvdata(rdev); + + if (selector > MAX1586_V3_MAX_VSEL) + return -EINVAL; + return max1586_v3_calc_voltage(max1586, selector); +} + +/* + * V6 voltage + * On I2C bus, sending a "x" byte to the max1586 means : + * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3) + * As regulator framework doesn't accept voltages to be 0V, we use 1uV. + */ +static int max1586_v6_calc_voltage(unsigned selector) +{ + static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; + + return voltages_uv[selector]; +} + +static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned int *selector) { struct i2c_client *client = rdev_get_drvdata(rdev); u8 v6_prog; + if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV) + return -EINVAL; + if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV) + return -EINVAL; + + if (min_uV < 1800000) + *selector = 0; + else if (min_uV < 2500000) + *selector = 1; + else if (min_uV < 3000000) + *selector = 2; + else if (min_uV >= 3000000) + *selector = 3; + + if (max1586_v6_calc_voltage(*selector) > max_uV) + return -EINVAL; + dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", - rdev->desc->volt_table[selector] / 1000); + max1586_v6_calc_voltage(*selector) / 1000); - v6_prog = I2C_V6_SELECT | (u8) selector; + v6_prog = I2C_V6_SELECT | (u8) *selector; return i2c_smbus_write_byte(client, v6_prog); } +static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector) +{ + if (selector > MAX1586_V6_MAX_VSEL) + return -EINVAL; + return max1586_v6_calc_voltage(selector); +} + /* * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back * the set up value. */ static struct regulator_ops max1586_v3_ops = { - .set_voltage_sel = max1586_v3_set_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .set_voltage = max1586_v3_set, + .list_voltage = max1586_v3_list, }; static struct regulator_ops max1586_v6_ops = { - .set_voltage_sel = max1586_v6_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .set_voltage = max1586_v6_set, + .list_voltage = max1586_v6_list, }; -static struct regulator_desc max1586_reg[] = { +static const struct regulator_desc max1586_reg[] = { { .name = "Output_V3", .id = MAX1586_V3, @@ -120,7 +176,6 @@ static struct regulator_desc max1586_reg[] = { .ops = &max1586_v6_ops, .type = REGULATOR_VOLTAGE, .n_voltages = MAX1586_V6_MAX_VSEL + 1, - .volt_table = v6_voltages_uv, .owner = THIS_MODULE, }, }; @@ -158,13 +213,6 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, goto err; } - if (id == MAX1586_V3) { - max1586_reg[id].min_uV = max1586->min_uV; - max1586_reg[id].uV_step = - (max1586->max_uV - max1586->min_uV) / - MAX1586_V3_MAX_VSEL; - } - config.dev = &client->dev; config.init_data = pdata->subdevs[i].platform_data; config.driver_data = max1586; diff --git a/trunk/drivers/regulator/max77686.c b/trunk/drivers/regulator/max77686.c deleted file mode 100644 index c564af6f05a3..000000000000 --- a/trunk/drivers/regulator/max77686.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * max77686.c - Regulator driver for the Maxim 77686 - * - * Copyright (C) 2012 Samsung Electronics - * Chiwoong Byun - * Jonghwa Lee - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8997.c - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX77686_LDO_MINUV 800000 -#define MAX77686_LDO_UVSTEP 50000 -#define MAX77686_LDO_LOW_MINUV 800000 -#define MAX77686_LDO_LOW_UVSTEP 25000 -#define MAX77686_BUCK_MINUV 750000 -#define MAX77686_BUCK_UVSTEP 50000 -#define MAX77686_RAMP_DELAY 100000 /* uV/us */ -#define MAX77686_DVS_RAMP_DELAY 27500 /* uV/us */ -#define MAX77686_DVS_MINUV 600000 -#define MAX77686_DVS_UVSTEP 12500 - -#define MAX77686_OPMODE_SHIFT 6 -#define MAX77686_OPMODE_BUCK234_SHIFT 4 -#define MAX77686_OPMODE_MASK 0x3 - -#define MAX77686_VSEL_MASK 0x3F -#define MAX77686_DVS_VSEL_MASK 0xFF - -#define MAX77686_RAMP_RATE_MASK 0xC0 - -#define MAX77686_REGULATORS MAX77686_REG_MAX -#define MAX77686_LDOS 26 - -enum max77686_ramp_rate { - RAMP_RATE_13P75MV, - RAMP_RATE_27P5MV, - RAMP_RATE_55MV, - RAMP_RATE_NO_CTRL, /* 100mV/us */ -}; - -struct max77686_data { - struct regulator_dev **rdev; -}; - -static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) -{ - unsigned int ramp_value = RAMP_RATE_NO_CTRL; - - switch (ramp_delay) { - case 1 ... 13750: - ramp_value = RAMP_RATE_13P75MV; - break; - case 13751 ... 27500: - ramp_value = RAMP_RATE_27P5MV; - break; - case 27501 ... 55000: - ramp_value = RAMP_RATE_55MV; - break; - case 55001 ... 100000: - break; - default: - pr_warn("%s: ramp_delay: %d not supported, setting 100000\n", - rdev->desc->name, ramp_delay); - } - - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, - MAX77686_RAMP_RATE_MASK, ramp_value << 6); -} - -static struct regulator_ops max77686_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static struct regulator_ops max77686_buck_dvs_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, - .set_ramp_delay = max77686_set_ramp_delay, -}; - -#define regulator_desc_ldo(num) { \ - .name = "LDO"#num, \ - .id = MAX77686_LDO##num, \ - .ops = &max77686_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MAX77686_LDO_MINUV, \ - .uV_step = MAX77686_LDO_UVSTEP, \ - .ramp_delay = MAX77686_RAMP_DELAY, \ - .n_voltages = MAX77686_VSEL_MASK + 1, \ - .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ - .vsel_mask = MAX77686_VSEL_MASK, \ - .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ - .enable_mask = MAX77686_OPMODE_MASK \ - << MAX77686_OPMODE_SHIFT, \ -} -#define regulator_desc_ldo_low(num) { \ - .name = "LDO"#num, \ - .id = MAX77686_LDO##num, \ - .ops = &max77686_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MAX77686_LDO_LOW_MINUV, \ - .uV_step = MAX77686_LDO_LOW_UVSTEP, \ - .ramp_delay = MAX77686_RAMP_DELAY, \ - .n_voltages = MAX77686_VSEL_MASK + 1, \ - .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ - .vsel_mask = MAX77686_VSEL_MASK, \ - .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ - .enable_mask = MAX77686_OPMODE_MASK \ - << MAX77686_OPMODE_SHIFT, \ -} -#define regulator_desc_buck(num) { \ - .name = "BUCK"#num, \ - .id = MAX77686_BUCK##num, \ - .ops = &max77686_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MAX77686_BUCK_MINUV, \ - .uV_step = MAX77686_BUCK_UVSTEP, \ - .ramp_delay = MAX77686_RAMP_DELAY, \ - .n_voltages = MAX77686_VSEL_MASK + 1, \ - .vsel_reg = MAX77686_REG_BUCK5OUT + (num - 5) * 2, \ - .vsel_mask = MAX77686_VSEL_MASK, \ - .enable_reg = MAX77686_REG_BUCK5CTRL + (num - 5) * 2, \ - .enable_mask = MAX77686_OPMODE_MASK, \ -} -#define regulator_desc_buck1(num) { \ - .name = "BUCK"#num, \ - .id = MAX77686_BUCK##num, \ - .ops = &max77686_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MAX77686_BUCK_MINUV, \ - .uV_step = MAX77686_BUCK_UVSTEP, \ - .ramp_delay = MAX77686_RAMP_DELAY, \ - .n_voltages = MAX77686_VSEL_MASK + 1, \ - .vsel_reg = MAX77686_REG_BUCK1OUT, \ - .vsel_mask = MAX77686_VSEL_MASK, \ - .enable_reg = MAX77686_REG_BUCK1CTRL, \ - .enable_mask = MAX77686_OPMODE_MASK, \ -} -#define regulator_desc_buck_dvs(num) { \ - .name = "BUCK"#num, \ - .id = MAX77686_BUCK##num, \ - .ops = &max77686_buck_dvs_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MAX77686_DVS_MINUV, \ - .uV_step = MAX77686_DVS_UVSTEP, \ - .ramp_delay = MAX77686_DVS_RAMP_DELAY, \ - .n_voltages = MAX77686_DVS_VSEL_MASK + 1, \ - .vsel_reg = MAX77686_REG_BUCK2DVS1 + (num - 2) * 10, \ - .vsel_mask = MAX77686_DVS_VSEL_MASK, \ - .enable_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \ - .enable_mask = MAX77686_OPMODE_MASK \ - << MAX77686_OPMODE_BUCK234_SHIFT, \ -} - -static struct regulator_desc regulators[] = { - regulator_desc_ldo_low(1), - regulator_desc_ldo_low(2), - regulator_desc_ldo(3), - regulator_desc_ldo(4), - regulator_desc_ldo(5), - regulator_desc_ldo_low(6), - regulator_desc_ldo_low(7), - regulator_desc_ldo_low(8), - regulator_desc_ldo(9), - regulator_desc_ldo(10), - regulator_desc_ldo(11), - regulator_desc_ldo(12), - regulator_desc_ldo(13), - regulator_desc_ldo(14), - regulator_desc_ldo_low(15), - regulator_desc_ldo(16), - regulator_desc_ldo(17), - regulator_desc_ldo(18), - regulator_desc_ldo(19), - regulator_desc_ldo(20), - regulator_desc_ldo(21), - regulator_desc_ldo(22), - regulator_desc_ldo(23), - regulator_desc_ldo(24), - regulator_desc_ldo(25), - regulator_desc_ldo(26), - regulator_desc_buck1(1), - regulator_desc_buck_dvs(2), - regulator_desc_buck_dvs(3), - regulator_desc_buck_dvs(4), - regulator_desc_buck(5), - regulator_desc_buck(6), - regulator_desc_buck(7), - regulator_desc_buck(8), - regulator_desc_buck(9), -}; - -#ifdef CONFIG_OF -static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, - struct max77686_platform_data *pdata) -{ - struct device_node *pmic_np, *regulators_np; - struct max77686_regulator_data *rdata; - struct of_regulator_match rmatch; - unsigned int i; - - pmic_np = iodev->dev->of_node; - regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators"); - if (!regulators_np) { - dev_err(iodev->dev, "could not find regulators sub-node\n"); - return -EINVAL; - } - - pdata->num_regulators = ARRAY_SIZE(regulators); - rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * - pdata->num_regulators, GFP_KERNEL); - if (!rdata) { - dev_err(iodev->dev, - "could not allocate memory for regulator data\n"); - return -ENOMEM; - } - - for (i = 0; i < pdata->num_regulators; i++) { - rmatch.name = regulators[i].name; - rmatch.init_data = NULL; - rmatch.of_node = NULL; - of_regulator_match(iodev->dev, regulators_np, &rmatch, 1); - rdata[i].initdata = rmatch.init_data; - } - - pdata->regulators = rdata; - - return 0; -} -#else -static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, - struct max77686_platform_data *pdata) -{ - return 0; -} -#endif /* CONFIG_OF */ - -static __devinit int max77686_pmic_probe(struct platform_device *pdev) -{ - struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); - struct regulator_dev **rdev; - struct max77686_data *max77686; - int i, size; - int ret = 0; - struct regulator_config config = { }; - - dev_dbg(&pdev->dev, "%s\n", __func__); - - if (!pdata) { - dev_err(&pdev->dev, "no platform data found for regulator\n"); - return -ENODEV; - } - - if (iodev->dev->of_node) { - ret = max77686_pmic_dt_parse_pdata(iodev, pdata); - if (ret) - return ret; - } - - if (pdata->num_regulators != MAX77686_REGULATORS) { - dev_err(&pdev->dev, - "Invalid initial data for regulator's initialiation\n"); - return -EINVAL; - } - - max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data), - GFP_KERNEL); - if (!max77686) - return -ENOMEM; - - size = sizeof(struct regulator_dev *) * MAX77686_REGULATORS; - max77686->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!max77686->rdev) - return -ENOMEM; - - rdev = max77686->rdev; - config.dev = &pdev->dev; - config.regmap = iodev->regmap; - platform_set_drvdata(pdev, max77686); - - for (i = 0; i < MAX77686_REGULATORS; i++) { - config.init_data = pdata->regulators[i].initdata; - - rdev[i] = regulator_register(®ulators[i], &config); - if (IS_ERR(rdev[i])) { - ret = PTR_ERR(rdev[i]); - dev_err(&pdev->dev, - "regulator init failed for %d\n", i); - rdev[i] = NULL; - goto err; - } - } - - return 0; -err: - while (--i >= 0) - regulator_unregister(rdev[i]); - return ret; -} - -static int __devexit max77686_pmic_remove(struct platform_device *pdev) -{ - struct max77686_data *max77686 = platform_get_drvdata(pdev); - struct regulator_dev **rdev = max77686->rdev; - int i; - - for (i = 0; i < MAX77686_REGULATORS; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - - return 0; -} - -static const struct platform_device_id max77686_pmic_id[] = { - {"max77686-pmic", 0}, - { }, -}; -MODULE_DEVICE_TABLE(platform, max77686_pmic_id); - -static struct platform_driver max77686_pmic_driver = { - .driver = { - .name = "max77686-pmic", - .owner = THIS_MODULE, - }, - .probe = max77686_pmic_probe, - .remove = __devexit_p(max77686_pmic_remove), - .id_table = max77686_pmic_id, -}; - -static int __init max77686_pmic_init(void) -{ - return platform_driver_register(&max77686_pmic_driver); -} -subsys_initcall(max77686_pmic_init); - -static void __exit max77686_pmic_cleanup(void) -{ - platform_driver_unregister(&max77686_pmic_driver); -} -module_exit(max77686_pmic_cleanup); - -MODULE_DESCRIPTION("MAXIM 77686 Regulator Driver"); -MODULE_AUTHOR("Chiwoong Byun "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/regulator/max8649.c b/trunk/drivers/regulator/max8649.c index 9d540cd02dab..1f4bb80457b3 100644 --- a/trunk/drivers/regulator/max8649.c +++ b/trunk/drivers/regulator/max8649.c @@ -259,7 +259,6 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, config.dev = &client->dev; config.init_data = pdata->regulator; config.driver_data = info; - config.regmap = info->regmap; info->regulator = regulator_register(&dcdc_desc, &config); if (IS_ERR(info->regulator)) { diff --git a/trunk/drivers/regulator/max8952.c b/trunk/drivers/regulator/max8952.c index 355ca7bad9d5..910c9b26d499 100644 --- a/trunk/drivers/regulator/max8952.c +++ b/trunk/drivers/regulator/max8952.c @@ -51,6 +51,7 @@ struct max8952_data { bool vid0; bool vid1; + bool en; }; static int max8952_read_reg(struct max8952_data *max8952, u8 reg) @@ -79,6 +80,38 @@ static int max8952_list_voltage(struct regulator_dev *rdev, return (max8952->pdata->dvs_mode[selector] * 10 + 770) * 1000; } +static int max8952_is_enabled(struct regulator_dev *rdev) +{ + struct max8952_data *max8952 = rdev_get_drvdata(rdev); + return max8952->en; +} + +static int max8952_enable(struct regulator_dev *rdev) +{ + struct max8952_data *max8952 = rdev_get_drvdata(rdev); + + /* If not valid, assume "ALWAYS_HIGH" */ + if (gpio_is_valid(max8952->pdata->gpio_en)) + gpio_set_value(max8952->pdata->gpio_en, 1); + + max8952->en = true; + return 0; +} + +static int max8952_disable(struct regulator_dev *rdev) +{ + struct max8952_data *max8952 = rdev_get_drvdata(rdev); + + /* If not valid, assume "ALWAYS_HIGH" -> not permitted */ + if (gpio_is_valid(max8952->pdata->gpio_en)) + gpio_set_value(max8952->pdata->gpio_en, 0); + else + return -EPERM; + + max8952->en = false; + return 0; +} + static int max8952_get_voltage_sel(struct regulator_dev *rdev) { struct max8952_data *max8952 = rdev_get_drvdata(rdev); @@ -113,8 +146,12 @@ static int max8952_set_voltage_sel(struct regulator_dev *rdev, static struct regulator_ops max8952_ops = { .list_voltage = max8952_list_voltage, + .is_enabled = max8952_is_enabled, + .enable = max8952_enable, + .disable = max8952_disable, .get_voltage_sel = max8952_get_voltage_sel, .set_voltage_sel = max8952_set_voltage_sel, + .set_suspend_disable = max8952_disable, }; static const struct regulator_desc regulator = { @@ -157,10 +194,6 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, config.init_data = &pdata->reg_data; config.driver_data = max8952; - config.ena_gpio = pdata->gpio_en; - if (pdata->reg_data.constraints.boot_on) - config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - max8952->rdev = regulator_register(®ulator, &config); if (IS_ERR(max8952->rdev)) { @@ -169,9 +202,27 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, return ret; } + max8952->en = !!(pdata->reg_data.constraints.boot_on); max8952->vid0 = pdata->default_mode & 0x1; max8952->vid1 = (pdata->default_mode >> 1) & 0x1; + if (gpio_is_valid(pdata->gpio_en)) { + if (!gpio_request(pdata->gpio_en, "MAX8952 EN")) + gpio_direction_output(pdata->gpio_en, max8952->en); + else + err = 1; + } else + err = 2; + + if (err) { + dev_info(max8952->dev, "EN gpio invalid: assume that EN" + "is always High\n"); + max8952->en = 1; + pdata->gpio_en = -1; /* Mark invalid */ + } + + err = 0; + if (gpio_is_valid(pdata->gpio_vid0) && gpio_is_valid(pdata->gpio_vid1)) { if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0")) @@ -257,6 +308,7 @@ static int __devexit max8952_pmic_remove(struct i2c_client *client) gpio_free(pdata->gpio_vid0); gpio_free(pdata->gpio_vid1); + gpio_free(pdata->gpio_en); return 0; } diff --git a/trunk/drivers/regulator/max8997.c b/trunk/drivers/regulator/max8997.c index e39a0c7260dc..704cd49ef375 100644 --- a/trunk/drivers/regulator/max8997.c +++ b/trunk/drivers/regulator/max8997.c @@ -1025,6 +1025,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) */ if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || pdata->buck5_gpiodvs) { + bool gpio1set = false, gpio2set = false; if (!gpio_is_valid(pdata->buck125_gpios[0]) || !gpio_is_valid(pdata->buck125_gpios[1]) || @@ -1034,20 +1035,40 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) goto err_out; } - ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[0], - "MAX8997 SET1"); - if (ret) + ret = gpio_request(pdata->buck125_gpios[0], + "MAX8997 SET1"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request" + " on SET1\n"); + else if (ret) goto err_out; - - ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[1], - "MAX8997 SET2"); - if (ret) + else + gpio1set = true; + + ret = gpio_request(pdata->buck125_gpios[1], + "MAX8997 SET2"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request" + " on SET2\n"); + else if (ret) { + if (gpio1set) + gpio_free(pdata->buck125_gpios[0]); goto err_out; + } else + gpio2set = true; - ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[2], + ret = gpio_request(pdata->buck125_gpios[2], "MAX8997 SET3"); - if (ret) + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request" + " on SET3\n"); + else if (ret) { + if (gpio1set) + gpio_free(pdata->buck125_gpios[0]); + if (gpio2set) + gpio_free(pdata->buck125_gpios[1]); goto err_out; + } gpio_direction_output(pdata->buck125_gpios[0], (max8997->buck125_gpioindex >> 2) @@ -1058,6 +1079,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) gpio_direction_output(pdata->buck125_gpios[2], (max8997->buck125_gpioindex >> 0) & 0x1); /* SET3 */ + ret = 0; } /* DVS-GPIO disabled */ diff --git a/trunk/drivers/regulator/max8998.c b/trunk/drivers/regulator/max8998.c index 5dfa920ff0c8..18bb58b9b96e 100644 --- a/trunk/drivers/regulator/max8998.c +++ b/trunk/drivers/regulator/max8998.c @@ -111,6 +111,27 @@ static const struct voltage_map_desc *ldo_voltage_map[] = { &buck4_voltage_map_desc, /* BUCK4 */ }; +static int max8998_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + const struct voltage_map_desc *desc; + int ldo = rdev_get_id(rdev); + int val; + + if (ldo >= ARRAY_SIZE(ldo_voltage_map)) + return -EINVAL; + + desc = ldo_voltage_map[ldo]; + if (desc == NULL) + return -EINVAL; + + val = desc->min + desc->step * selector; + if (val > desc->max) + return -EINVAL; + + return val * 1000; +} + static int max8998_get_enable_register(struct regulator_dev *rdev, int *reg, int *shift) { @@ -276,18 +297,41 @@ static int max8998_get_voltage_sel(struct regulator_dev *rdev) return val; } -static int max8998_set_voltage_ldo_sel(struct regulator_dev *rdev, - unsigned selector) +static int max8998_set_voltage_ldo(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c; - int reg, shift = 0, mask, ret; + int min_vol = min_uV / 1000, max_vol = max_uV / 1000; + const struct voltage_map_desc *desc; + int ldo = rdev_get_id(rdev); + int reg, shift = 0, mask, ret, i; + + if (ldo >= ARRAY_SIZE(ldo_voltage_map)) + return -EINVAL; + + desc = ldo_voltage_map[ldo]; + if (desc == NULL) + return -EINVAL; + + if (max_vol < desc->min || min_vol > desc->max) + return -EINVAL; + + if (min_vol < desc->min) + min_vol = desc->min; + + i = DIV_ROUND_UP(min_vol - desc->min, desc->step); + + if (desc->min + desc->step*i > max_vol) + return -EINVAL; + + *selector = i; ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); if (ret) return ret; - ret = max8998_update_reg(i2c, reg, selector<iodev->dev); struct i2c_client *i2c = max8998->iodev->i2c; + int min_vol = min_uV / 1000, max_vol = max_uV / 1000; + const struct voltage_map_desc *desc; int buck = rdev_get_id(rdev); int reg, shift = 0, mask, ret; - int j, previous_sel; + int i, j, previous_sel; static u8 buck1_last_val; + if (buck >= ARRAY_SIZE(ldo_voltage_map)) + return -EINVAL; + + desc = ldo_voltage_map[buck]; + + if (desc == NULL) + return -EINVAL; + + if (max_vol < desc->min || min_vol > desc->max) + return -EINVAL; + + if (min_vol < desc->min) + min_vol = desc->min; + + i = DIV_ROUND_UP(min_vol - desc->min, desc->step); + + if (desc->min + desc->step*i > max_vol) + return -EINVAL; + + *selector = i; + ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); if (ret) return ret; @@ -323,19 +390,19 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, /* Check if voltage needs to be changed */ /* if previous_voltage equal new voltage, return */ - if (previous_sel == selector) { + if (previous_sel == i) { dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n", - regulator_list_voltage_linear(rdev, previous_sel), - regulator_list_voltage_linear(rdev, selector)); + max8998_list_voltage(rdev, previous_sel), + max8998_list_voltage(rdev, i)); return ret; } switch (buck) { case MAX8998_BUCK1: dev_dbg(max8998->dev, - "BUCK1, selector:%d, buck1_vol1:%d, buck1_vol2:%d\n" + "BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n" "buck1_vol3:%d, buck1_vol4:%d\n", - selector, max8998->buck1_vol[0], max8998->buck1_vol[1], + i, max8998->buck1_vol[0], max8998->buck1_vol[1], max8998->buck1_vol[2], max8998->buck1_vol[3]); if (gpio_is_valid(pdata->buck1_set1) && @@ -344,7 +411,7 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, /* check if requested voltage */ /* value is already defined */ for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) { - if (max8998->buck1_vol[j] == selector) { + if (max8998->buck1_vol[j] == i) { max8998->buck1_idx = j; buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, j); @@ -359,11 +426,11 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, max8998->buck1_idx = (buck1_last_val % 2) + 2; dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", max8998->buck1_idx); - max8998->buck1_vol[max8998->buck1_idx] = selector; + max8998->buck1_vol[max8998->buck1_idx] = i; ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); - ret = max8998_write_reg(i2c, reg, selector); + ret = max8998_write_reg(i2c, reg, i); buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, max8998->buck1_idx); buck1_last_val++; @@ -373,20 +440,20 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, gpio_get_value(pdata->buck1_set2)); break; } else { - ret = max8998_write_reg(i2c, reg, selector); + ret = max8998_write_reg(i2c, reg, i); } break; case MAX8998_BUCK2: dev_dbg(max8998->dev, - "BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n", - selector, max8998->buck2_vol[0], max8998->buck2_vol[1]); + "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" + , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); if (gpio_is_valid(pdata->buck2_set3)) { /* check if requested voltage */ /* value is already defined */ for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) { - if (max8998->buck2_vol[j] == selector) { + if (max8998->buck2_vol[j] == i) { max8998->buck2_idx = j; buck2_gpio_set(pdata->buck2_set3, j); goto buck2_exit; @@ -398,21 +465,20 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, max8998_get_voltage_register(rdev, ®, &shift, &mask); - ret = max8998_write_reg(i2c, reg, selector); - max8998->buck2_vol[max8998->buck2_idx] = selector; + ret = max8998_write_reg(i2c, reg, i); + max8998->buck2_vol[max8998->buck2_idx] = i; buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx); buck2_exit: dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, gpio_get_value(pdata->buck2_set3)); } else { - ret = max8998_write_reg(i2c, reg, selector); + ret = max8998_write_reg(i2c, reg, i); } break; case MAX8998_BUCK3: case MAX8998_BUCK4: - ret = max8998_update_reg(i2c, reg, selector<max - desc->min) / desc->step + 1; - regulators[index].n_voltages = count; - regulators[index].min_uV = desc->min * 1000; - regulators[index].uV_step = desc->step * 1000; } config.dev = max8998->dev; diff --git a/trunk/drivers/regulator/mc13783-regulator.c b/trunk/drivers/regulator/mc13783-regulator.c index 4932e3449fe1..7dcdfa283e93 100644 --- a/trunk/drivers/regulator/mc13783-regulator.c +++ b/trunk/drivers/regulator/mc13783-regulator.c @@ -93,78 +93,78 @@ /* Voltage Values */ -static const unsigned int mc13783_sw3_val[] = { +static const int mc13783_sw3_val[] = { 5000000, 5000000, 5000000, 5500000, }; -static const unsigned int mc13783_vaudio_val[] = { +static const int mc13783_vaudio_val[] = { 2775000, }; -static const unsigned int mc13783_viohi_val[] = { +static const int mc13783_viohi_val[] = { 2775000, }; -static const unsigned int mc13783_violo_val[] = { +static const int mc13783_violo_val[] = { 1200000, 1300000, 1500000, 1800000, }; -static const unsigned int mc13783_vdig_val[] = { +static const int mc13783_vdig_val[] = { 1200000, 1300000, 1500000, 1800000, }; -static const unsigned int mc13783_vgen_val[] = { +static const int mc13783_vgen_val[] = { 1200000, 1300000, 1500000, 1800000, 1100000, 2000000, 2775000, 2400000, }; -static const unsigned int mc13783_vrfdig_val[] = { +static const int mc13783_vrfdig_val[] = { 1200000, 1500000, 1800000, 1875000, }; -static const unsigned int mc13783_vrfref_val[] = { +static const int mc13783_vrfref_val[] = { 2475000, 2600000, 2700000, 2775000, }; -static const unsigned int mc13783_vrfcp_val[] = { +static const int mc13783_vrfcp_val[] = { 2700000, 2775000, }; -static const unsigned int mc13783_vsim_val[] = { +static const int mc13783_vsim_val[] = { 1800000, 2900000, 3000000, }; -static const unsigned int mc13783_vesim_val[] = { +static const int mc13783_vesim_val[] = { 1800000, 2900000, }; -static const unsigned int mc13783_vcam_val[] = { +static const int mc13783_vcam_val[] = { 1500000, 1800000, 2500000, 2550000, 2600000, 2750000, 2800000, 3000000, }; -static const unsigned int mc13783_vrfbg_val[] = { +static const int mc13783_vrfbg_val[] = { 1250000, }; -static const unsigned int mc13783_vvib_val[] = { +static const int mc13783_vvib_val[] = { 1300000, 1800000, 2000000, 3000000, }; -static const unsigned int mc13783_vmmc_val[] = { +static const int mc13783_vmmc_val[] = { 1600000, 1800000, 2000000, 2600000, 2700000, 2800000, 2900000, 3000000, }; -static const unsigned int mc13783_vrf_val[] = { +static const int mc13783_vrf_val[] = { 1500000, 1875000, 2700000, 2775000, }; -static const unsigned int mc13783_gpo_val[] = { +static const int mc13783_gpo_val[] = { 3100000, }; -static const unsigned int mc13783_pwgtdrv_val[] = { +static const int mc13783_pwgtdrv_val[] = { 5500000, }; @@ -328,7 +328,7 @@ static struct regulator_ops mc13783_gpo_regulator_ops = { .enable = mc13783_gpo_regulator_enable, .disable = mc13783_gpo_regulator_disable, .is_enabled = mc13783_gpo_regulator_is_enabled, - .list_voltage = regulator_list_voltage_table, + .list_voltage = mc13xxx_regulator_list_voltage, .set_voltage = mc13xxx_fixed_regulator_set_voltage, .get_voltage = mc13xxx_fixed_regulator_get_voltage, }; diff --git a/trunk/drivers/regulator/mc13892-regulator.c b/trunk/drivers/regulator/mc13892-regulator.c index b388b746452e..970a233dbe46 100644 --- a/trunk/drivers/regulator/mc13892-regulator.c +++ b/trunk/drivers/regulator/mc13892-regulator.c @@ -150,12 +150,12 @@ #define MC13892_USB1 50 #define MC13892_USB1_VUSBEN (1<<3) -static const unsigned int mc13892_vcoincell[] = { +static const int mc13892_vcoincell[] = { 2500000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, }; -static const unsigned int mc13892_sw1[] = { +static const int mc13892_sw1[] = { 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, @@ -164,7 +164,7 @@ static const unsigned int mc13892_sw1[] = { 1350000, 1375000 }; -static const unsigned int mc13892_sw[] = { +static const int mc13892_sw[] = { 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, @@ -176,65 +176,65 @@ static const unsigned int mc13892_sw[] = { 1800000, 1825000, 1850000, 1875000 }; -static const unsigned int mc13892_swbst[] = { +static const int mc13892_swbst[] = { 5000000, }; -static const unsigned int mc13892_viohi[] = { +static const int mc13892_viohi[] = { 2775000, }; -static const unsigned int mc13892_vpll[] = { +static const int mc13892_vpll[] = { 1050000, 1250000, 1650000, 1800000, }; -static const unsigned int mc13892_vdig[] = { +static const int mc13892_vdig[] = { 1050000, 1250000, 1650000, 1800000, }; -static const unsigned int mc13892_vsd[] = { +static const int mc13892_vsd[] = { 1800000, 2000000, 2600000, 2700000, 2800000, 2900000, 3000000, 3150000, }; -static const unsigned int mc13892_vusb2[] = { +static const int mc13892_vusb2[] = { 2400000, 2600000, 2700000, 2775000, }; -static const unsigned int mc13892_vvideo[] = { +static const int mc13892_vvideo[] = { 2700000, 2775000, 2500000, 2600000, }; -static const unsigned int mc13892_vaudio[] = { +static const int mc13892_vaudio[] = { 2300000, 2500000, 2775000, 3000000, }; -static const unsigned int mc13892_vcam[] = { +static const int mc13892_vcam[] = { 2500000, 2600000, 2750000, 3000000, }; -static const unsigned int mc13892_vgen1[] = { +static const int mc13892_vgen1[] = { 1200000, 1500000, 2775000, 3150000, }; -static const unsigned int mc13892_vgen2[] = { +static const int mc13892_vgen2[] = { 1200000, 1500000, 1600000, 1800000, 2700000, 2800000, 3000000, 3150000, }; -static const unsigned int mc13892_vgen3[] = { +static const int mc13892_vgen3[] = { 1800000, 2900000, }; -static const unsigned int mc13892_vusb[] = { +static const int mc13892_vusb[] = { 3300000, }; -static const unsigned int mc13892_gpo[] = { +static const int mc13892_gpo[] = { 2750000, }; -static const unsigned int mc13892_pwgtdrv[] = { +static const int mc13892_pwgtdrv[] = { 5000000, }; @@ -394,7 +394,7 @@ static struct regulator_ops mc13892_gpo_regulator_ops = { .enable = mc13892_gpo_regulator_enable, .disable = mc13892_gpo_regulator_disable, .is_enabled = mc13892_gpo_regulator_is_enabled, - .list_voltage = regulator_list_voltage_table, + .list_voltage = mc13xxx_regulator_list_voltage, .set_voltage = mc13xxx_fixed_regulator_set_voltage, .get_voltage = mc13xxx_fixed_regulator_get_voltage, }; @@ -436,7 +436,7 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, u32 valread; int ret; - value = rdev->desc->volt_table[selector]; + value = mc13892_regulators[id].voltages[selector]; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, @@ -469,7 +469,8 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, } static struct regulator_ops mc13892_sw_regulator_ops = { - .list_voltage = regulator_list_voltage_table, + .is_enabled = mc13xxx_sw_regulator_is_enabled, + .list_voltage = mc13xxx_regulator_list_voltage, .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, .get_voltage = mc13892_sw_regulator_get_voltage, }; diff --git a/trunk/drivers/regulator/mc13xxx-regulator-core.c b/trunk/drivers/regulator/mc13xxx-regulator-core.c index d6eda28ca5d0..4fa9704739bc 100644 --- a/trunk/drivers/regulator/mc13xxx-regulator-core.c +++ b/trunk/drivers/regulator/mc13xxx-regulator-core.c @@ -80,6 +80,20 @@ static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) return (val & mc13xxx_regulators[id].enable_bit) != 0; } +int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + int id = rdev_get_id(rdev); + struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); + struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; + + if (selector >= mc13xxx_regulators[id].desc.n_voltages) + return -EINVAL; + + return mc13xxx_regulators[id].voltages[selector]; +} +EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage); + static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { @@ -121,14 +135,14 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages); - return rdev->desc->volt_table[val]; + return mc13xxx_regulators[id].voltages[val]; } struct regulator_ops mc13xxx_regulator_ops = { .enable = mc13xxx_regulator_enable, .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, - .list_voltage = regulator_list_voltage_table, + .list_voltage = mc13xxx_regulator_list_voltage, .set_voltage_sel = mc13xxx_regulator_set_voltage_sel, .get_voltage = mc13xxx_regulator_get_voltage, }; @@ -137,13 +151,15 @@ EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops); int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { + struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); + struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", __func__, id, min_uV, max_uV); - if (min_uV <= rdev->desc->volt_table[0] && - rdev->desc->volt_table[0] <= max_uV) + if (min_uV >= mc13xxx_regulators[id].voltages[0] && + max_uV <= mc13xxx_regulators[id].voltages[0]) return 0; else return -EINVAL; @@ -152,11 +168,13 @@ EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev) { + struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); + struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - return rdev->desc->volt_table[0]; + return mc13xxx_regulators[id].voltages[0]; } EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage); @@ -164,12 +182,18 @@ struct regulator_ops mc13xxx_fixed_regulator_ops = { .enable = mc13xxx_regulator_enable, .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, - .list_voltage = regulator_list_voltage_table, + .list_voltage = mc13xxx_regulator_list_voltage, .set_voltage = mc13xxx_fixed_regulator_set_voltage, .get_voltage = mc13xxx_fixed_regulator_get_voltage, }; EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); +int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev) +{ + return 1; +} +EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled); + #ifdef CONFIG_OF int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) { diff --git a/trunk/drivers/regulator/mc13xxx.h b/trunk/drivers/regulator/mc13xxx.h index eaff5510b6df..044aba4d28ec 100644 --- a/trunk/drivers/regulator/mc13xxx.h +++ b/trunk/drivers/regulator/mc13xxx.h @@ -22,6 +22,7 @@ struct mc13xxx_regulator { int vsel_shift; int vsel_mask; int hi_bit; + int const *voltages; }; struct mc13xxx_regulator_priv { @@ -32,6 +33,10 @@ struct mc13xxx_regulator_priv { struct regulator_dev *regulators[]; }; +extern int mc13xxx_sw_regulator(struct regulator_dev *rdev); +extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev); +extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, + unsigned selector); extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector); extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev); @@ -63,7 +68,6 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .desc = { \ .name = #_name, \ .n_voltages = ARRAY_SIZE(_voltages), \ - .volt_table = _voltages, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .id = prefix ## _name, \ @@ -74,6 +78,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .vsel_reg = prefix ## _vsel_reg, \ .vsel_shift = prefix ## _vsel_reg ## _ ## _name ## VSEL,\ .vsel_mask = prefix ## _vsel_reg ## _ ## _name ## VSEL_M,\ + .voltages = _voltages, \ } #define MC13xxx_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops) \ @@ -81,7 +86,6 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .desc = { \ .name = #_name, \ .n_voltages = ARRAY_SIZE(_voltages), \ - .volt_table = _voltages, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .id = prefix ## _name, \ @@ -89,6 +93,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; }, \ .reg = prefix ## _reg, \ .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ + .voltages = _voltages, \ } #define MC13xxx_GPO_DEFINE(prefix, _name, _reg, _voltages, _ops) \ @@ -96,7 +101,6 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .desc = { \ .name = #_name, \ .n_voltages = ARRAY_SIZE(_voltages), \ - .volt_table = _voltages, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .id = prefix ## _name, \ @@ -104,6 +108,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; }, \ .reg = prefix ## _reg, \ .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ + .voltages = _voltages, \ } #define MC13xxx_DEFINE_SW(_name, _reg, _vsel_reg, _voltages, ops) \ diff --git a/trunk/drivers/regulator/of_regulator.c b/trunk/drivers/regulator/of_regulator.c index 3e4106f2bda9..56593b75168a 100644 --- a/trunk/drivers/regulator/of_regulator.c +++ b/trunk/drivers/regulator/of_regulator.c @@ -20,7 +20,7 @@ static void of_get_regulation_constraints(struct device_node *np, struct regulator_init_data **init_data) { const __be32 *min_uV, *max_uV, *uV_offset; - const __be32 *min_uA, *max_uA, *ramp_delay; + const __be32 *min_uA, *max_uA; struct regulation_constraints *constraints = &(*init_data)->constraints; constraints->name = of_get_property(np, "regulator-name", NULL); @@ -60,10 +60,6 @@ static void of_get_regulation_constraints(struct device_node *np, constraints->always_on = true; else /* status change should be possible if not always on. */ constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; - - ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL); - if (ramp_delay) - constraints->ramp_delay = be32_to_cpu(*ramp_delay); } /** @@ -92,17 +88,15 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, EXPORT_SYMBOL_GPL(of_get_regulator_init_data); /** - * of_regulator_match - extract regulator init data when node - * property "regulator-compatible" matches with the regulator name. + * of_regulator_match - extract regulator init data * @dev: device requesting the data * @node: parent device node of the regulators * @matches: match table for the regulators * @num_matches: number of entries in match table * * This function uses a match table specified by the regulator driver and - * looks up the corresponding init data in the device tree if - * regulator-compatible matches. Note that the match table is modified - * in place. + * looks up the corresponding init data in the device tree. Note that the + * match table is modified in place. * * Returns the number of matches found or a negative error code on failure. */ @@ -112,40 +106,27 @@ int of_regulator_match(struct device *dev, struct device_node *node, { unsigned int count = 0; unsigned int i; - const char *regulator_comp; - struct device_node *child; if (!dev || !node) return -EINVAL; - for_each_child_of_node(node, child) { - regulator_comp = of_get_property(child, - "regulator-compatible", NULL); - if (!regulator_comp) { - dev_err(dev, "regulator-compatible is missing for node %s\n", - child->name); + for (i = 0; i < num_matches; i++) { + struct of_regulator_match *match = &matches[i]; + struct device_node *child; + + child = of_find_node_by_name(node, match->name); + if (!child) continue; + + match->init_data = of_get_regulator_init_data(dev, child); + if (!match->init_data) { + dev_err(dev, "failed to parse DT for regulator %s\n", + child->name); + return -EINVAL; } - for (i = 0; i < num_matches; i++) { - struct of_regulator_match *match = &matches[i]; - if (match->of_node) - continue; - - if (strcmp(match->name, regulator_comp)) - continue; - - match->init_data = - of_get_regulator_init_data(dev, child); - if (!match->init_data) { - dev_err(dev, - "failed to parse DT for regulator %s\n", - child->name); - return -EINVAL; - } - match->of_node = child; - count++; - break; - } + + match->of_node = child; + count++; } return count; diff --git a/trunk/drivers/regulator/palmas-regulator.c b/trunk/drivers/regulator/palmas-regulator.c index 17d19fbbc490..c4435f608df7 100644 --- a/trunk/drivers/regulator/palmas-regulator.c +++ b/trunk/drivers/regulator/palmas-regulator.c @@ -257,7 +257,8 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) unsigned int reg; palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + reg &= ~PALMAS_SMPS12_CTRL_STATUS_MASK; + reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; switch (mode) { case REGULATOR_MODE_NORMAL: @@ -373,22 +374,11 @@ static int palmas_set_voltage_smps_sel(struct regulator_dev *dev, static int palmas_map_voltage_smps(struct regulator_dev *rdev, int min_uV, int max_uV) { - struct palmas_pmic *pmic = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); int ret, voltage; - if (min_uV == 0) - return 0; - - if (pmic->range[id]) { /* RANGE is x2 */ - if (min_uV < 1000000) - min_uV = 1000000; - ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 1; - } else { /* RANGE is x1 */ - if (min_uV < 500000) - min_uV = 500000; - ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 1; - } + ret = ((min_uV - 500000) / 10000) + 1; + if (ret < 0) + return ret; /* Map back into a voltage to verify we're still in bounds */ voltage = palmas_list_voltage_smps(rdev, ret); @@ -410,14 +400,19 @@ static struct regulator_ops palmas_ops_smps = { .map_voltage = palmas_map_voltage_smps, }; +static int palmas_list_voltage_smps10(struct regulator_dev *dev, + unsigned selector) +{ + return 3750000 + (selector * 1250000); +} + static struct regulator_ops palmas_ops_smps10 = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .list_voltage = palmas_list_voltage_smps10, }; static int palmas_is_enabled_ldo(struct regulator_dev *dev) @@ -527,15 +522,7 @@ static int palmas_smps_init(struct palmas *palmas, int id, if (ret) return ret; - switch (id) { - case PALMAS_REG_SMPS10: - if (reg_init->mode_sleep) { - reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK; - reg |= reg_init->mode_sleep << - PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT; - } - break; - default: + if (id != PALMAS_REG_SMPS10) { if (reg_init->warm_reset) reg |= PALMAS_SMPS12_CTRL_WR_S; @@ -547,8 +534,14 @@ static int palmas_smps_init(struct palmas *palmas, int id, reg |= reg_init->mode_sleep << PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT; } - } + } else { + if (reg_init->mode_sleep) { + reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK; + reg |= reg_init->mode_sleep << + PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT; + } + } ret = palmas_smps_write(palmas, addr, reg); if (ret) return ret; @@ -672,22 +665,16 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].name = palmas_regs_info[id].name; pmic->desc[id].id = id; - switch (id) { - case PALMAS_REG_SMPS10: + if (id != PALMAS_REG_SMPS10) { + pmic->desc[id].ops = &palmas_ops_smps; + pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; + } else { pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; pmic->desc[id].ops = &palmas_ops_smps10; pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; pmic->desc[id].vsel_mask = SMPS10_VSEL; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - PALMAS_SMPS10_STATUS); + pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS; pmic->desc[id].enable_mask = SMPS10_BOOST_EN; - pmic->desc[id].min_uV = 3750000; - pmic->desc[id].uV_step = 1250000; - break; - default: - pmic->desc[id].ops = &palmas_ops_smps; - pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; } pmic->desc[id].type = REGULATOR_VOLTAGE; @@ -752,8 +739,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; - pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr; pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; if (pdata && pdata->reg_data) @@ -789,6 +775,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) err_unregister_regulator: while (--id >= 0) regulator_unregister(pmic->rdev[id]); + kfree(pmic->rdev); + kfree(pmic->desc); + kfree(pmic); return ret; } @@ -799,6 +788,10 @@ static int __devexit palmas_remove(struct platform_device *pdev) for (id = 0; id < PALMAS_NUM_REGS; id++) regulator_unregister(pmic->rdev[id]); + + kfree(pmic->rdev); + kfree(pmic->desc); + kfree(pmic); return 0; } diff --git a/trunk/drivers/regulator/pcap-regulator.c b/trunk/drivers/regulator/pcap-regulator.c index 68777acc099f..8211101121f0 100644 --- a/trunk/drivers/regulator/pcap-regulator.c +++ b/trunk/drivers/regulator/pcap-regulator.c @@ -18,80 +18,80 @@ #include #include -static const unsigned int V1_table[] = { - 2775000, 1275000, 1600000, 1725000, 1825000, 1925000, 2075000, 2275000, +static const u16 V1_table[] = { + 2775, 1275, 1600, 1725, 1825, 1925, 2075, 2275, }; -static const unsigned int V2_table[] = { - 2500000, 2775000, +static const u16 V2_table[] = { + 2500, 2775, }; -static const unsigned int V3_table[] = { - 1075000, 1275000, 1550000, 1725000, 1876000, 1950000, 2075000, 2275000, +static const u16 V3_table[] = { + 1075, 1275, 1550, 1725, 1876, 1950, 2075, 2275, }; -static const unsigned int V4_table[] = { - 1275000, 1550000, 1725000, 1875000, 1950000, 2075000, 2275000, 2775000, +static const u16 V4_table[] = { + 1275, 1550, 1725, 1875, 1950, 2075, 2275, 2775, }; -static const unsigned int V5_table[] = { - 1875000, 2275000, 2475000, 2775000, +static const u16 V5_table[] = { + 1875, 2275, 2475, 2775, }; -static const unsigned int V6_table[] = { - 2475000, 2775000, +static const u16 V6_table[] = { + 2475, 2775, }; -static const unsigned int V7_table[] = { - 1875000, 2775000, +static const u16 V7_table[] = { + 1875, 2775, }; #define V8_table V4_table -static const unsigned int V9_table[] = { - 1575000, 1875000, 2475000, 2775000, +static const u16 V9_table[] = { + 1575, 1875, 2475, 2775, }; -static const unsigned int V10_table[] = { - 5000000, +static const u16 V10_table[] = { + 5000, }; -static const unsigned int VAUX1_table[] = { - 1875000, 2475000, 2775000, 3000000, +static const u16 VAUX1_table[] = { + 1875, 2475, 2775, 3000, }; #define VAUX2_table VAUX1_table -static const unsigned int VAUX3_table[] = { - 1200000, 1200000, 1200000, 1200000, 1400000, 1600000, 1800000, 2000000, - 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, +static const u16 VAUX3_table[] = { + 1200, 1200, 1200, 1200, 1400, 1600, 1800, 2000, + 2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600, }; -static const unsigned int VAUX4_table[] = { - 1800000, 1800000, 3000000, 5000000, +static const u16 VAUX4_table[] = { + 1800, 1800, 3000, 5000, }; -static const unsigned int VSIM_table[] = { - 1875000, 3000000, +static const u16 VSIM_table[] = { + 1875, 3000, }; -static const unsigned int VSIM2_table[] = { - 1875000, +static const u16 VSIM2_table[] = { + 1875, }; -static const unsigned int VVIB_table[] = { - 1300000, 1800000, 2000000, 3000000, +static const u16 VVIB_table[] = { + 1300, 1800, 2000, 3000, }; -static const unsigned int SW1_table[] = { - 900000, 950000, 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, - 1300000, 1350000, 1400000, 1450000, 1500000, 1600000, 1875000, 2250000, +static const u16 SW1_table[] = { + 900, 950, 1000, 1050, 1100, 1150, 1200, 1250, + 1300, 1350, 1400, 1450, 1500, 1600, 1875, 2250, }; #define SW2_table SW1_table -static const unsigned int SW3_table[] = { - 4000000, 4500000, 5000000, 5500000, +static const u16 SW3_table[] = { + 4000, 4500, 5000, 5500, }; struct pcap_regulator { @@ -100,6 +100,8 @@ struct pcap_regulator { const u8 index; const u8 stby; const u8 lowpwr; + const u8 n_voltages; + const u16 *voltage_table; }; #define NA 0xff @@ -111,6 +113,8 @@ struct pcap_regulator { .index = _index, \ .stby = _stby, \ .lowpwr = _lowpwr, \ + .n_voltages = ARRAY_SIZE(_vreg##_table), \ + .voltage_table = _vreg##_table, \ } static struct pcap_regulator vreg_table[] = { @@ -153,11 +157,11 @@ static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev, void *pcap = rdev_get_drvdata(rdev); /* the regulator doesn't support voltage switching */ - if (rdev->desc->n_voltages == 1) + if (vreg->n_voltages == 1) return -EINVAL; return ezx_pcap_set_bits(pcap, vreg->reg, - (rdev->desc->n_voltages - 1) << vreg->index, + (vreg->n_voltages - 1) << vreg->index, selector << vreg->index); } @@ -167,11 +171,11 @@ static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev) void *pcap = rdev_get_drvdata(rdev); u32 tmp; - if (rdev->desc->n_voltages == 1) + if (vreg->n_voltages == 1) return 0; ezx_pcap_read(pcap, vreg->reg, &tmp); - tmp = ((tmp >> vreg->index) & (rdev->desc->n_voltages - 1)); + tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1)); return tmp; } @@ -210,8 +214,16 @@ static int pcap_regulator_is_enabled(struct regulator_dev *rdev) return (tmp >> vreg->en) & 1; } +static int pcap_regulator_list_voltage(struct regulator_dev *rdev, + unsigned int index) +{ + struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)]; + + return vreg->voltage_table[index] * 1000; +} + static struct regulator_ops pcap_regulator_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = pcap_regulator_list_voltage, .set_voltage_sel = pcap_regulator_set_voltage_sel, .get_voltage_sel = pcap_regulator_get_voltage_sel, .enable = pcap_regulator_enable, @@ -224,7 +236,6 @@ static struct regulator_ops pcap_regulator_ops = { .name = #_vreg, \ .id = _vreg, \ .n_voltages = ARRAY_SIZE(_vreg##_table), \ - .volt_table = _vreg##_table, \ .ops = &pcap_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ diff --git a/trunk/drivers/regulator/pcf50633-regulator.c b/trunk/drivers/regulator/pcf50633-regulator.c index 092e5cb848a1..3c9d14c0017b 100644 --- a/trunk/drivers/regulator/pcf50633-regulator.c +++ b/trunk/drivers/regulator/pcf50633-regulator.c @@ -100,12 +100,13 @@ static unsigned int ldo_voltage_value(u8 bits) return 900 + (bits * 100); } -static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) { struct pcf50633 *pcf; int regulator_id, millivolts; - u8 volt_bits; + u8 volt_bits, regnr; pcf = rdev_get_drvdata(rdev); @@ -115,11 +116,15 @@ static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, millivolts = min_uV / 1000; + regnr = rdev->desc->vsel_reg; + switch (regulator_id) { case PCF50633_REGULATOR_AUTO: volt_bits = auto_voltage_bits(millivolts); break; case PCF50633_REGULATOR_DOWN1: + volt_bits = down_voltage_bits(millivolts); + break; case PCF50633_REGULATOR_DOWN2: volt_bits = down_voltage_bits(millivolts); break; @@ -137,7 +142,9 @@ static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, return -EINVAL; } - return volt_bits; + *selector = volt_bits; + + return pcf50633_reg_write(pcf, regnr, volt_bits); } static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, @@ -152,6 +159,8 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, millivolts = auto_voltage_value(index); break; case PCF50633_REGULATOR_DOWN1: + millivolts = down_voltage_value(index); + break; case PCF50633_REGULATOR_DOWN2: millivolts = down_voltage_value(index); break; @@ -173,10 +182,9 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, } static struct regulator_ops pcf50633_regulator_ops = { - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage = pcf50633_regulator_set_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = pcf50633_regulator_list_voltage, - .map_voltage = pcf50633_regulator_map_voltage, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/trunk/drivers/regulator/rc5t583-regulator.c b/trunk/drivers/regulator/rc5t583-regulator.c index 8bf4e8c9de9a..1d34e64a1307 100644 --- a/trunk/drivers/regulator/rc5t583-regulator.c +++ b/trunk/drivers/regulator/rc5t583-regulator.c @@ -42,6 +42,7 @@ struct rc5t583_regulator_info { /* Regulator specific turn-on delay and voltage settling time*/ int enable_uv_per_us; + int change_uv_per_us; /* Used by regulator core */ struct regulator_desc desc; @@ -65,6 +66,25 @@ static int rc5t583_regulator_enable_time(struct regulator_dev *rdev) return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us); } +static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, unsigned int new_selector) +{ + struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); + int old_uV, new_uV; + old_uV = regulator_list_voltage_linear(rdev, old_selector); + + if (old_uV < 0) + return old_uV; + + new_uV = regulator_list_voltage_linear(rdev, new_selector); + if (new_uV < 0) + return new_uV; + + return DIV_ROUND_UP(abs(old_uV - new_uV), + reg->reg_info->change_uv_per_us); +} + + static struct regulator_ops rc5t583_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, @@ -74,7 +94,7 @@ static struct regulator_ops rc5t583_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, - .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_voltage_time_sel = rc5t583_set_voltage_time_sel, }; #define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \ @@ -84,6 +104,7 @@ static struct regulator_ops rc5t583_ops = { .disc_bit = _disc_bit, \ .deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \ .enable_uv_per_us = _enable_mv * 1000, \ + .change_uv_per_us = 40 * 1000, \ .deepsleep_id = RC5T583_DS_##_id, \ .desc = { \ .name = "rc5t583-regulator-"#_id, \ @@ -98,7 +119,6 @@ static struct regulator_ops rc5t583_ops = { .enable_mask = BIT(_en_bit), \ .min_uV = _min_mv * 1000, \ .uV_step = _step_uV, \ - .ramp_delay = 40 * 1000, \ }, \ } diff --git a/trunk/drivers/regulator/s2mps11.c b/trunk/drivers/regulator/s2mps11.c deleted file mode 100644 index 4669dc9ac74a..000000000000 --- a/trunk/drivers/regulator/s2mps11.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * s2mps11.c - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd - * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct s2mps11_info { - struct regulator_dev **rdev; - - int ramp_delay2; - int ramp_delay34; - int ramp_delay5; - int ramp_delay16; - int ramp_delay7810; - int ramp_delay9; - - bool buck6_ramp; - bool buck2_ramp; - bool buck3_ramp; - bool buck4_ramp; -}; - -static int get_ramp_delay(int ramp_delay) -{ - unsigned char cnt = 0; - - ramp_delay /= 6; - - while (true) { - ramp_delay = ramp_delay >> 1; - if (ramp_delay == 0) - break; - cnt++; - } - return cnt; -} - -static struct regulator_ops s2mps11_ldo_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static struct regulator_ops s2mps11_buck_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -#define regulator_desc_ldo1(num) { \ - .name = "LDO"#num, \ - .id = S2MPS11_LDO##num, \ - .ops = &s2mps11_ldo_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_LDO_MIN, \ - .uV_step = S2MPS11_LDO_STEP1, \ - .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ - .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} -#define regulator_desc_ldo2(num) { \ - .name = "LDO"#num, \ - .id = S2MPS11_LDO##num, \ - .ops = &s2mps11_ldo_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_LDO_MIN, \ - .uV_step = S2MPS11_LDO_STEP2, \ - .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ - .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -#define regulator_desc_buck1_4(num) { \ - .name = "BUCK"#num, \ - .id = S2MPS11_BUCK##num, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN1, \ - .uV_step = S2MPS11_BUCK_STEP1, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_B1CTRL2 + (num - 1) * 2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B1CTRL1 + (num - 1) * 2, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -#define regulator_desc_buck5 { \ - .name = "BUCK5", \ - .id = S2MPS11_BUCK5, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN1, \ - .uV_step = S2MPS11_BUCK_STEP1, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_B5CTRL2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B5CTRL1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -#define regulator_desc_buck6_8(num) { \ - .name = "BUCK"#num, \ - .id = S2MPS11_BUCK##num, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN1, \ - .uV_step = S2MPS11_BUCK_STEP1, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_B6CTRL2 + (num - 6) * 2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B6CTRL1 + (num - 6) * 2, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -#define regulator_desc_buck9 { \ - .name = "BUCK9", \ - .id = S2MPS11_BUCK9, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN3, \ - .uV_step = S2MPS11_BUCK_STEP3, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_B9CTRL2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B9CTRL1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -#define regulator_desc_buck10 { \ - .name = "BUCK10", \ - .id = S2MPS11_BUCK10, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN2, \ - .uV_step = S2MPS11_BUCK_STEP2, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_B9CTRL2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B9CTRL1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -static struct regulator_desc regulators[] = { - regulator_desc_ldo2(1), - regulator_desc_ldo1(2), - regulator_desc_ldo1(3), - regulator_desc_ldo1(4), - regulator_desc_ldo1(5), - regulator_desc_ldo2(6), - regulator_desc_ldo1(7), - regulator_desc_ldo1(8), - regulator_desc_ldo1(9), - regulator_desc_ldo1(10), - regulator_desc_ldo2(11), - regulator_desc_ldo1(12), - regulator_desc_ldo1(13), - regulator_desc_ldo1(14), - regulator_desc_ldo1(15), - regulator_desc_ldo1(16), - regulator_desc_ldo1(17), - regulator_desc_ldo1(18), - regulator_desc_ldo1(19), - regulator_desc_ldo1(20), - regulator_desc_ldo1(21), - regulator_desc_ldo2(22), - regulator_desc_ldo2(23), - regulator_desc_ldo1(24), - regulator_desc_ldo1(25), - regulator_desc_ldo1(26), - regulator_desc_ldo2(27), - regulator_desc_ldo1(28), - regulator_desc_ldo1(29), - regulator_desc_ldo1(30), - regulator_desc_ldo1(31), - regulator_desc_ldo1(32), - regulator_desc_ldo1(33), - regulator_desc_ldo1(34), - regulator_desc_ldo1(35), - regulator_desc_ldo1(36), - regulator_desc_ldo1(37), - regulator_desc_ldo1(38), - regulator_desc_buck1_4(1), - regulator_desc_buck1_4(2), - regulator_desc_buck1_4(3), - regulator_desc_buck1_4(4), - regulator_desc_buck5, - regulator_desc_buck6_8(6), - regulator_desc_buck6_8(7), - regulator_desc_buck6_8(8), - regulator_desc_buck9, - regulator_desc_buck10, -}; - -static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) -{ - struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); - struct regulator_config config = { }; - struct regulator_dev **rdev; - struct s2mps11_info *s2mps11; - int i, ret, size; - unsigned char ramp_enable, ramp_reg = 0; - - if (!pdata) { - dev_err(pdev->dev.parent, "Platform data not supplied\n"); - return -ENODEV; - } - - s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), - GFP_KERNEL); - if (!s2mps11) - return -ENOMEM; - - size = sizeof(struct regulator_dev *) * S2MPS11_REGULATOR_MAX; - s2mps11->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!s2mps11->rdev) { - return -ENOMEM; - } - - rdev = s2mps11->rdev; - platform_set_drvdata(pdev, s2mps11); - - s2mps11->ramp_delay2 = pdata->buck2_ramp_delay; - s2mps11->ramp_delay34 = pdata->buck34_ramp_delay; - s2mps11->ramp_delay5 = pdata->buck5_ramp_delay; - s2mps11->ramp_delay16 = pdata->buck16_ramp_delay; - s2mps11->ramp_delay7810 = pdata->buck7810_ramp_delay; - s2mps11->ramp_delay9 = pdata->buck9_ramp_delay; - - s2mps11->buck6_ramp = pdata->buck6_ramp_enable; - s2mps11->buck2_ramp = pdata->buck2_ramp_enable; - s2mps11->buck3_ramp = pdata->buck3_ramp_enable; - s2mps11->buck4_ramp = pdata->buck4_ramp_enable; - - ramp_enable = (s2mps11->buck2_ramp << 3) | (s2mps11->buck3_ramp << 2) | - (s2mps11->buck4_ramp << 1) | s2mps11->buck6_ramp ; - - if (ramp_enable) { - if (s2mps11->buck2_ramp) - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) >> 6; - if (s2mps11->buck3_ramp || s2mps11->buck4_ramp) - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) >> 4; - sec_reg_write(iodev, S2MPS11_REG_RAMP, ramp_reg | ramp_enable); - } - - ramp_reg &= 0x00; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) >> 6; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) >> 4; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) >> 2; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay9); - sec_reg_write(iodev, S2MPS11_REG_RAMP_BUCK, ramp_reg); - - for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { - - config.dev = &pdev->dev; - config.regmap = iodev->regmap; - config.init_data = pdata->regulators[i].initdata; - config.driver_data = s2mps11; - - rdev[i] = regulator_register(®ulators[i], &config); - if (IS_ERR(rdev[i])) { - ret = PTR_ERR(rdev[i]); - dev_err(&pdev->dev, "regulator init failed for %d\n", - i); - rdev[i] = NULL; - goto err; - } - } - - return 0; -err: - for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - - return ret; -} - -static int __devexit s2mps11_pmic_remove(struct platform_device *pdev) -{ - struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev); - struct regulator_dev **rdev = s2mps11->rdev; - int i; - - for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - - return 0; -} - -static const struct platform_device_id s2mps11_pmic_id[] = { - { "s2mps11-pmic", 0}, - { }, -}; -MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); - -static struct platform_driver s2mps11_pmic_driver = { - .driver = { - .name = "s2mps11-pmic", - .owner = THIS_MODULE, - }, - .probe = s2mps11_pmic_probe, - .remove = __devexit_p(s2mps11_pmic_remove), - .id_table = s2mps11_pmic_id, -}; - -static int __init s2mps11_pmic_init(void) -{ - return platform_driver_register(&s2mps11_pmic_driver); -} -subsys_initcall(s2mps11_pmic_init); - -static void __exit s2mps11_pmic_exit(void) -{ - platform_driver_unregister(&s2mps11_pmic_driver); -} -module_exit(s2mps11_pmic_exit); - -/* Module information */ -MODULE_AUTHOR("Sangbeom Kim "); -MODULE_DESCRIPTION("SAMSUNG S2MPS11 Regulator Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/regulator/s5m8767.c b/trunk/drivers/regulator/s5m8767.c index 102287fa7ecb..290d6fc01029 100644 --- a/trunk/drivers/regulator/s5m8767.c +++ b/trunk/drivers/regulator/s5m8767.c @@ -41,7 +41,6 @@ struct s5m8767_info { u8 buck3_vol[8]; u8 buck4_vol[8]; int buck_gpios[3]; - int buck_ds[3]; int buck_gpioindex; }; @@ -121,6 +120,27 @@ static const struct s5m_voltage_desc *reg_voltage_map[] = { [S5M8767_BUCK9] = &buck_voltage_val3, }; +static int s5m8767_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + const struct s5m_voltage_desc *desc; + int reg_id = rdev_get_id(rdev); + int val; + + if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) + return -EINVAL; + + desc = reg_voltage_map[reg_id]; + if (desc == NULL) + return -EINVAL; + + val = desc->min + desc->step * selector; + if (val > desc->max) + return -EINVAL; + + return val; +} + static unsigned int s5m8767_opmode_reg[][4] = { /* {OFF, ON, LOWPOWER, SUSPEND} */ /* LDO1 ... LDO28 */ @@ -263,17 +283,17 @@ static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) reg = S5M8767_REG_BUCK1CTRL2; break; case S5M8767_BUCK2: - reg = S5M8767_REG_BUCK2DVS2; + reg = S5M8767_REG_BUCK2DVS1; if (s5m8767->buck2_gpiodvs) reg += s5m8767->buck_gpioindex; break; case S5M8767_BUCK3: - reg = S5M8767_REG_BUCK3DVS2; + reg = S5M8767_REG_BUCK3DVS1; if (s5m8767->buck3_gpiodvs) reg += s5m8767->buck_gpioindex; break; case S5M8767_BUCK4: - reg = S5M8767_REG_BUCK4DVS2; + reg = S5M8767_REG_BUCK4DVS1; if (s5m8767->buck4_gpiodvs) reg += s5m8767->buck_gpioindex; break; @@ -337,34 +357,32 @@ static int s5m8767_convert_voltage_to_sel( return selector; } -static inline int s5m8767_set_high(struct s5m8767_info *s5m8767) +static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) { int temp_index = s5m8767->buck_gpioindex; gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); - - return 0; } -static inline int s5m8767_set_low(struct s5m8767_info *s5m8767) +static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) { int temp_index = s5m8767->buck_gpioindex; gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); - - return 0; } -static int s5m8767_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int s5m8767_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + const struct s5m_voltage_desc *desc; int reg_id = rdev_get_id(rdev); - int reg, mask, ret = 0, old_index, index = 0; + int sel, reg, mask, ret = 0, old_index, index = 0; + u8 val; u8 *buck234_vol = NULL; switch (reg_id) { @@ -389,9 +407,15 @@ static int s5m8767_set_voltage_sel(struct regulator_dev *rdev, return -EINVAL; } + desc = reg_voltage_map[reg_id]; + + sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); + if (sel < 0) + return sel; + /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */ if (buck234_vol) { - while (*buck234_vol != selector) { + while (*buck234_vol != sel) { buck234_vol++; index++; } @@ -399,16 +423,22 @@ static int s5m8767_set_voltage_sel(struct regulator_dev *rdev, s5m8767->buck_gpioindex = index; if (index > old_index) - return s5m8767_set_high(s5m8767); + s5m8767_set_high(s5m8767); else - return s5m8767_set_low(s5m8767); + s5m8767_set_low(s5m8767); } else { ret = s5m8767_get_voltage_register(rdev, ®); if (ret) return ret; - return s5m_reg_update(s5m8767->iodev, reg, selector, mask); + s5m_reg_read(s5m8767->iodev, reg, &val); + val = (val & ~mask) | sel; + + ret = s5m_reg_write(s5m8767->iodev, reg, val); } + + *selector = sel; + return ret; } static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, @@ -421,28 +451,22 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - if ((old_sel < new_sel) && s5m8767->ramp_delay) + if (old_sel < new_sel) return DIV_ROUND_UP(desc->step * (new_sel - old_sel), s5m8767->ramp_delay * 1000); return 0; } static struct regulator_ops s5m8767_ops = { - .list_voltage = regulator_list_voltage_linear, + .list_voltage = s5m8767_list_voltage, .is_enabled = s5m8767_reg_is_enabled, .enable = s5m8767_reg_enable, .disable = s5m8767_reg_disable, .get_voltage_sel = s5m8767_get_voltage_sel, - .set_voltage_sel = s5m8767_set_voltage_sel, + .set_voltage = s5m8767_set_voltage, .set_voltage_time_sel = s5m8767_set_voltage_time_sel, }; -static struct regulator_ops s5m8767_buck78_ops = { - .is_enabled = s5m8767_reg_is_enabled, - .enable = s5m8767_reg_enable, - .disable = s5m8767_reg_disable, -}; - #define s5m8767_regulator_desc(_name) { \ .name = #_name, \ .id = S5M8767_##_name, \ @@ -451,14 +475,6 @@ static struct regulator_ops s5m8767_buck78_ops = { .owner = THIS_MODULE, \ } -#define s5m8767_regulator_buck78_desc(_name) { \ - .name = #_name, \ - .id = S5M8767_##_name, \ - .ops = &s5m8767_buck78_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ -} - static struct regulator_desc regulators[] = { s5m8767_regulator_desc(LDO1), s5m8767_regulator_desc(LDO2), @@ -494,8 +510,8 @@ static struct regulator_desc regulators[] = { s5m8767_regulator_desc(BUCK4), s5m8767_regulator_desc(BUCK5), s5m8767_regulator_desc(BUCK6), - s5m8767_regulator_buck78_desc(BUCK7), - s5m8767_regulator_buck78_desc(BUCK8), + s5m8767_regulator_desc(BUCK7), + s5m8767_regulator_desc(BUCK8), s5m8767_regulator_desc(BUCK9), }; @@ -506,7 +522,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) struct regulator_config config = { }; struct regulator_dev **rdev; struct s5m8767_info *s5m8767; - int i, ret, size, buck_init; + int i, ret, size; if (!pdata) { dev_err(pdev->dev.parent, "Platform data not supplied\n"); @@ -557,37 +573,12 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) s5m8767->buck_gpios[0] = pdata->buck_gpios[0]; s5m8767->buck_gpios[1] = pdata->buck_gpios[1]; s5m8767->buck_gpios[2] = pdata->buck_gpios[2]; - s5m8767->buck_ds[0] = pdata->buck_ds[0]; - s5m8767->buck_ds[1] = pdata->buck_ds[1]; - s5m8767->buck_ds[2] = pdata->buck_ds[2]; - s5m8767->ramp_delay = pdata->buck_ramp_delay; s5m8767->buck2_ramp = pdata->buck2_ramp_enable; s5m8767->buck3_ramp = pdata->buck3_ramp_enable; s5m8767->buck4_ramp = pdata->buck4_ramp_enable; s5m8767->opmode = pdata->opmode; - buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, - pdata->buck2_init, - pdata->buck2_init + - buck_voltage_val2.step); - - s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS2, buck_init); - - buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, - pdata->buck3_init, - pdata->buck3_init + - buck_voltage_val2.step); - - s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS2, buck_init); - - buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, - pdata->buck4_init, - pdata->buck4_init + - buck_voltage_val2.step); - - s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS2, buck_init); - for (i = 0; i < 8; i++) { if (s5m8767->buck2_gpiodvs) { s5m8767->buck2_vol[i] = @@ -617,70 +608,48 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) } } - if (gpio_is_valid(pdata->buck_gpios[0]) && - gpio_is_valid(pdata->buck_gpios[1]) && - gpio_is_valid(pdata->buck_gpios[2])) { - ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[0], - "S5M8767 SET1"); - if (ret) - return ret; - - ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[1], - "S5M8767 SET2"); - if (ret) - return ret; - - ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[2], - "S5M8767 SET3"); - if (ret) + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || + pdata->buck4_gpiodvs) { + if (gpio_is_valid(pdata->buck_gpios[0]) && + gpio_is_valid(pdata->buck_gpios[1]) && + gpio_is_valid(pdata->buck_gpios[2])) { + ret = gpio_request(pdata->buck_gpios[0], + "S5M8767 SET1"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n"); + + ret = gpio_request(pdata->buck_gpios[1], + "S5M8767 SET2"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n"); + + ret = gpio_request(pdata->buck_gpios[2], + "S5M8767 SET3"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n"); + /* SET1 GPIO */ + gpio_direction_output(pdata->buck_gpios[0], + (s5m8767->buck_gpioindex >> 2) & 0x1); + /* SET2 GPIO */ + gpio_direction_output(pdata->buck_gpios[1], + (s5m8767->buck_gpioindex >> 1) & 0x1); + /* SET3 GPIO */ + gpio_direction_output(pdata->buck_gpios[2], + (s5m8767->buck_gpioindex >> 0) & 0x1); + ret = 0; + } else { + dev_err(&pdev->dev, "GPIO NOT VALID\n"); + ret = -EINVAL; return ret; - - /* SET1 GPIO */ - gpio_direction_output(pdata->buck_gpios[0], - (s5m8767->buck_gpioindex >> 2) & 0x1); - /* SET2 GPIO */ - gpio_direction_output(pdata->buck_gpios[1], - (s5m8767->buck_gpioindex >> 1) & 0x1); - /* SET3 GPIO */ - gpio_direction_output(pdata->buck_gpios[2], - (s5m8767->buck_gpioindex >> 0) & 0x1); - } else { - dev_err(&pdev->dev, "GPIO NOT VALID\n"); - ret = -EINVAL; - return ret; + } } - ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[0], "S5M8767 DS2"); - if (ret) - return ret; - - ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[1], "S5M8767 DS3"); - if (ret) - return ret; - - ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[2], "S5M8767 DS4"); - if (ret) - return ret; - - /* DS2 GPIO */ - gpio_direction_output(pdata->buck_ds[0], 0x0); - /* DS3 GPIO */ - gpio_direction_output(pdata->buck_ds[1], 0x0); - /* DS4 GPIO */ - gpio_direction_output(pdata->buck_ds[2], 0x0); - - if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || - pdata->buck4_gpiodvs) { - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, - (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), - 1 << 1); - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, - (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), - 1 << 1); - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, - (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), - 1 << 1); - } + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); /* Initialize GPIO DVS registers */ for (i = 0; i < 8; i++) { @@ -699,6 +668,9 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) s5m8767->buck4_vol[i]); } } + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff); if (s5m8767->buck2_ramp) s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08); @@ -712,13 +684,9 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) if (s5m8767->buck2_ramp || s5m8767->buck3_ramp || s5m8767->buck4_ramp) { switch (s5m8767->ramp_delay) { - case 5: + case 15: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, - 0x40, 0xf0); - break; - case 10: - s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, - 0x90, 0xf0); + 0xc0, 0xf0); break; case 25: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, @@ -743,12 +711,9 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) int id = pdata->regulators[i].id; desc = reg_voltage_map[id]; - if (desc) { + if (desc) regulators[id].n_voltages = (desc->max - desc->min) / desc->step + 1; - regulators[id].min_uV = desc->min; - regulators[id].uV_step = desc->step; - } config.dev = s5m8767->dev; config.init_data = pdata->regulators[i].initdata; diff --git a/trunk/drivers/regulator/tps6105x-regulator.c b/trunk/drivers/regulator/tps6105x-regulator.c index 1378409efaec..d840d8440a91 100644 --- a/trunk/drivers/regulator/tps6105x-regulator.c +++ b/trunk/drivers/regulator/tps6105x-regulator.c @@ -20,7 +20,7 @@ #include #include -static const unsigned int tps6105x_voltages[] = { +static const int tps6105x_voltages[] = { 4500000, 5000000, 5250000, @@ -105,13 +105,22 @@ static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev, return 0; } +static int tps6105x_regulator_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector >= ARRAY_SIZE(tps6105x_voltages)) + return -EINVAL; + + return tps6105x_voltages[selector]; +} + static struct regulator_ops tps6105x_regulator_ops = { .enable = tps6105x_regulator_enable, .disable = tps6105x_regulator_disable, .is_enabled = tps6105x_regulator_is_enabled, .get_voltage_sel = tps6105x_regulator_get_voltage_sel, .set_voltage_sel = tps6105x_regulator_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps6105x_regulator_list_voltage, }; static const struct regulator_desc tps6105x_regulator_desc = { @@ -121,7 +130,6 @@ static const struct regulator_desc tps6105x_regulator_desc = { .id = 0, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(tps6105x_voltages), - .volt_table = tps6105x_voltages, }; /* diff --git a/trunk/drivers/regulator/tps62360-regulator.c b/trunk/drivers/regulator/tps62360-regulator.c index 68729a7c8709..e534269ed44a 100644 --- a/trunk/drivers/regulator/tps62360-regulator.c +++ b/trunk/drivers/regulator/tps62360-regulator.c @@ -65,8 +65,10 @@ struct tps62360_chip { struct regulator_desc desc; struct regulator_dev *rdev; struct regmap *regmap; + int chip_id; int vsel0_gpio; int vsel1_gpio; + int voltage_base; u8 voltage_reg_mask; bool en_internal_pulldn; bool en_discharge; @@ -74,6 +76,7 @@ struct tps62360_chip { int lru_index[4]; int curr_vset_vsel[4]; int curr_vset_id; + int change_uv_per_us; }; /* @@ -172,6 +175,23 @@ static int tps62360_dcdc_set_voltage_sel(struct regulator_dev *dev, return 0; } +static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, unsigned int new_selector) +{ + struct tps62360_chip *tps = rdev_get_drvdata(rdev); + int old_uV, new_uV; + + old_uV = regulator_list_voltage_linear(rdev, old_selector); + if (old_uV < 0) + return old_uV; + + new_uV = regulator_list_voltage_linear(rdev, new_selector); + if (new_uV < 0) + return new_uV; + + return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); +} + static int tps62360_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct tps62360_chip *tps = rdev_get_drvdata(rdev); @@ -238,7 +258,7 @@ static struct regulator_ops tps62360_dcdc_ops = { .set_voltage_sel = tps62360_dcdc_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, - .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_voltage_time_sel = tps62360_set_voltage_time_sel, .set_mode = tps62360_set_mode, .get_mode = tps62360_get_mode, }; @@ -281,7 +301,7 @@ static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, ramp_ctrl = (ramp_ctrl >> 4) & 0x7; /* ramp mV/us = 32/(2^ramp_ctrl) */ - tps->desc.ramp_delay = DIV_ROUND_UP(32000, BIT(ramp_ctrl)); + tps->change_uv_per_us = DIV_ROUND_UP(32000, BIT(ramp_ctrl)); return ret; } @@ -388,13 +408,13 @@ static int __devinit tps62360_probe(struct i2c_client *client, switch (chip_id) { case TPS62360: case TPS62362: - tps->desc.min_uV = TPS62360_BASE_VOLTAGE; + tps->voltage_base = TPS62360_BASE_VOLTAGE; tps->voltage_reg_mask = 0x3F; tps->desc.n_voltages = TPS62360_N_VOLTAGES; break; case TPS62361: case TPS62363: - tps->desc.min_uV = TPS62361_BASE_VOLTAGE; + tps->voltage_base = TPS62361_BASE_VOLTAGE; tps->voltage_reg_mask = 0x7F; tps->desc.n_voltages = TPS62361_N_VOLTAGES; break; @@ -407,6 +427,7 @@ static int __devinit tps62360_probe(struct i2c_client *client, tps->desc.ops = &tps62360_dcdc_ops; tps->desc.type = REGULATOR_VOLTAGE; tps->desc.owner = THIS_MODULE; + tps->desc.min_uV = tps->voltage_base; tps->desc.uV_step = 10000; tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); @@ -428,24 +449,24 @@ static int __devinit tps62360_probe(struct i2c_client *client, int gpio_flags; gpio_flags = (pdata->vsel0_def_state) ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - ret = devm_gpio_request_one(&client->dev, tps->vsel0_gpio, + ret = gpio_request_one(tps->vsel0_gpio, gpio_flags, "tps62360-vsel0"); if (ret) { dev_err(&client->dev, "%s(): Could not obtain vsel0 GPIO %d: %d\n", __func__, tps->vsel0_gpio, ret); - return ret; + goto err_gpio0; } gpio_flags = (pdata->vsel1_def_state) ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - ret = devm_gpio_request_one(&client->dev, tps->vsel1_gpio, + ret = gpio_request_one(tps->vsel1_gpio, gpio_flags, "tps62360-vsel1"); if (ret) { dev_err(&client->dev, "%s(): Could not obtain vsel1 GPIO %d: %d\n", __func__, tps->vsel1_gpio, ret); - return ret; + goto err_gpio1; } tps->valid_gpios = true; @@ -463,7 +484,7 @@ static int __devinit tps62360_probe(struct i2c_client *client, if (ret < 0) { dev_err(tps->dev, "%s(): Init failed with err = %d\n", __func__, ret); - return ret; + goto err_init; } config.dev = &client->dev; @@ -477,11 +498,21 @@ static int __devinit tps62360_probe(struct i2c_client *client, dev_err(tps->dev, "%s(): regulator register failed with err %s\n", __func__, id->name); - return PTR_ERR(rdev); + ret = PTR_ERR(rdev); + goto err_init; } tps->rdev = rdev; return 0; + +err_init: + if (gpio_is_valid(tps->vsel1_gpio)) + gpio_free(tps->vsel1_gpio); +err_gpio1: + if (gpio_is_valid(tps->vsel0_gpio)) + gpio_free(tps->vsel0_gpio); +err_gpio0: + return ret; } /** @@ -494,6 +525,12 @@ static int __devexit tps62360_remove(struct i2c_client *client) { struct tps62360_chip *tps = i2c_get_clientdata(client); + if (gpio_is_valid(tps->vsel1_gpio)) + gpio_free(tps->vsel1_gpio); + + if (gpio_is_valid(tps->vsel0_gpio)) + gpio_free(tps->vsel0_gpio); + regulator_unregister(tps->rdev); return 0; } diff --git a/trunk/drivers/regulator/tps65023-regulator.c b/trunk/drivers/regulator/tps65023-regulator.c index 6998d579d07b..f841bd0db6aa 100644 --- a/trunk/drivers/regulator/tps65023-regulator.c +++ b/trunk/drivers/regulator/tps65023-regulator.c @@ -69,6 +69,10 @@ #define TPS65023_REG_CTRL2_DCDC1 BIT(1) #define TPS65023_REG_CTRL2_DCDC3 BIT(0) +/* LDO_CTRL bitfields */ +#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) +#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4)) + /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 /* Number of LDO voltage regulators available */ @@ -87,53 +91,48 @@ #define TPS65023_MAX_REG_ID TPS65023_LDO_2 /* Supported voltage values for regulators */ -static const unsigned int VCORE_VSEL_table[] = { - 800000, 825000, 850000, 875000, - 900000, 925000, 950000, 975000, - 1000000, 1025000, 1050000, 1075000, - 1100000, 1125000, 1150000, 1175000, - 1200000, 1225000, 1250000, 1275000, - 1300000, 1325000, 1350000, 1375000, - 1400000, 1425000, 1450000, 1475000, - 1500000, 1525000, 1550000, 1600000, -}; - -static const unsigned int DCDC_FIXED_3300000_VSEL_table[] = { - 3300000, -}; - -static const unsigned int DCDC_FIXED_1800000_VSEL_table[] = { - 1800000, +static const u16 VCORE_VSEL_table[] = { + 800, 825, 850, 875, + 900, 925, 950, 975, + 1000, 1025, 1050, 1075, + 1100, 1125, 1150, 1175, + 1200, 1225, 1250, 1275, + 1300, 1325, 1350, 1375, + 1400, 1425, 1450, 1475, + 1500, 1525, 1550, 1600, }; /* Supported voltage values for LDO regulators for tps65020 */ -static const unsigned int TPS65020_LDO1_VSEL_table[] = { - 1000000, 1050000, 1100000, 1300000, - 1800000, 2500000, 3000000, 3300000, +static const u16 TPS65020_LDO1_VSEL_table[] = { + 1000, 1050, 1100, 1300, + 1800, 2500, 3000, 3300, }; -static const unsigned int TPS65020_LDO2_VSEL_table[] = { - 1000000, 1050000, 1100000, 1300000, - 1800000, 2500000, 3000000, 3300000, +static const u16 TPS65020_LDO2_VSEL_table[] = { + 1000, 1050, 1100, 1300, + 1800, 2500, 3000, 3300, }; /* Supported voltage values for LDO regulators * for tps65021 and tps65023 */ -static const unsigned int TPS65023_LDO1_VSEL_table[] = { - 1000000, 1100000, 1300000, 1800000, - 2200000, 2600000, 2800000, 3150000, +static const u16 TPS65023_LDO1_VSEL_table[] = { + 1000, 1100, 1300, 1800, + 2200, 2600, 2800, 3150, }; -static const unsigned int TPS65023_LDO2_VSEL_table[] = { - 1050000, 1200000, 1300000, 1800000, - 2500000, 2800000, 3000000, 3300000, +static const u16 TPS65023_LDO2_VSEL_table[] = { + 1050, 1200, 1300, 1800, + 2500, 2800, 3000, 3300, }; /* Regulator specific details */ struct tps_info { const char *name; + unsigned min_uV; + unsigned max_uV; + bool fixed; u8 table_len; - const unsigned int *table; + const u16 *table; }; /* PMIC details */ @@ -151,7 +150,7 @@ struct tps_driver_data { u8 core_regulator; }; -static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev) +static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) { struct tps_pmic *tps = rdev_get_drvdata(dev); int ret; @@ -165,9 +164,9 @@ static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev) if (ret != 0) return ret; data &= (tps->info[dcdc]->table_len - 1); - return data; + return tps->info[dcdc]->table[data] * 1000; } else - return 0; + return tps->info[dcdc]->min_uV; } static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, @@ -194,14 +193,76 @@ static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, return ret; } +static int tps65023_ldo_get_voltage(struct regulator_dev *dev) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int data, ldo = rdev_get_id(dev); + int ret; + + if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) + return -EINVAL; + + ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data); + if (ret != 0) + return ret; + + data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)); + data &= (tps->info[ldo]->table_len - 1); + return tps->info[ldo]->table[data] * 1000; +} + +static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1; + + return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL, + TPS65023_LDO_CTRL_LDOx_MASK(ldo_index), + selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index)); +} + +static int tps65023_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) + return -EINVAL; + + if (dcdc == tps->core_regulator) { + if (selector >= tps->info[dcdc]->table_len) + return -EINVAL; + else + return tps->info[dcdc]->table[selector] * 1000; + } else + return tps->info[dcdc]->min_uV; +} + +static int tps65023_ldo_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int ldo = rdev_get_id(dev); + + if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) + return -EINVAL; + + if (selector >= tps->info[ldo]->table_len) + return -EINVAL; + else + return tps->info[ldo]->table[selector] * 1000; +} + /* Operations permitted on VDCDCx */ static struct regulator_ops tps65023_dcdc_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage_sel = tps65023_dcdc_get_voltage_sel, + .get_voltage = tps65023_dcdc_get_voltage, .set_voltage_sel = tps65023_dcdc_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps65023_dcdc_list_voltage, }; /* Operations permitted on LDOx */ @@ -209,9 +270,9 @@ static struct regulator_ops tps65023_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = regulator_list_voltage_table, + .get_voltage = tps65023_ldo_get_voltage, + .set_voltage_sel = tps65023_ldo_set_voltage_sel, + .list_voltage = tps65023_ldo_list_voltage, }; static struct regmap_config tps65023_regmap_config = { @@ -264,28 +325,19 @@ static int __devinit tps_65023_probe(struct i2c_client *client, tps->desc[i].name = info->name; tps->desc[i].id = i; tps->desc[i].n_voltages = info->table_len; - tps->desc[i].volt_table = info->table; tps->desc[i].ops = (i > TPS65023_DCDC_3 ? &tps65023_ldo_ops : &tps65023_dcdc_ops); tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL; - switch (i) { - case TPS65023_LDO_1: - tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; - tps->desc[i].vsel_mask = 0x07; + if (i == TPS65023_LDO_1) tps->desc[i].enable_mask = 1 << 1; - break; - case TPS65023_LDO_2: - tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; - tps->desc[i].vsel_mask = 0x70; + else if (i == TPS65023_LDO_2) tps->desc[i].enable_mask = 1 << 2; - break; - default: /* DCDCx */ + else /* DCDCx */ tps->desc[i].enable_mask = 1 << (TPS65023_NUM_REGULATOR - i); - } config.dev = &client->dev; config.init_data = init_data; @@ -332,26 +384,35 @@ static int __devexit tps_65023_remove(struct i2c_client *client) static const struct tps_info tps65020_regs[] = { { .name = "VDCDC1", - .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), - .table = DCDC_FIXED_3300000_VSEL_table, + .min_uV = 3300000, + .max_uV = 3300000, + .fixed = 1, }, { .name = "VDCDC2", - .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), - .table = DCDC_FIXED_1800000_VSEL_table, + .min_uV = 1800000, + .max_uV = 1800000, + .fixed = 1, }, { .name = "VDCDC3", + .min_uV = 800000, + .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, + { .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table), .table = TPS65020_LDO1_VSEL_table, }, { .name = "LDO2", + .min_uV = 1050000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table), .table = TPS65020_LDO2_VSEL_table, }, @@ -360,26 +421,34 @@ static const struct tps_info tps65020_regs[] = { static const struct tps_info tps65021_regs[] = { { .name = "VDCDC1", - .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), - .table = DCDC_FIXED_3300000_VSEL_table, + .min_uV = 3300000, + .max_uV = 3300000, + .fixed = 1, }, { .name = "VDCDC2", - .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), - .table = DCDC_FIXED_1800000_VSEL_table, + .min_uV = 1800000, + .max_uV = 1800000, + .fixed = 1, }, { .name = "VDCDC3", + .min_uV = 800000, + .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, { .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), .table = TPS65023_LDO1_VSEL_table, }, { .name = "LDO2", + .min_uV = 1050000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), .table = TPS65023_LDO2_VSEL_table, }, @@ -388,26 +457,34 @@ static const struct tps_info tps65021_regs[] = { static const struct tps_info tps65023_regs[] = { { .name = "VDCDC1", + .min_uV = 800000, + .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, { .name = "VDCDC2", - .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), - .table = DCDC_FIXED_3300000_VSEL_table, + .min_uV = 3300000, + .max_uV = 3300000, + .fixed = 1, }, { .name = "VDCDC3", - .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), - .table = DCDC_FIXED_1800000_VSEL_table, + .min_uV = 1800000, + .max_uV = 1800000, + .fixed = 1, }, { .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), .table = TPS65023_LDO1_VSEL_table, }, { .name = "LDO2", + .min_uV = 1050000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), .table = TPS65023_LDO2_VSEL_table, }, diff --git a/trunk/drivers/regulator/tps6507x-regulator.c b/trunk/drivers/regulator/tps6507x-regulator.c index 07d01ccdf308..da38be1016aa 100644 --- a/trunk/drivers/regulator/tps6507x-regulator.c +++ b/trunk/drivers/regulator/tps6507x-regulator.c @@ -43,40 +43,58 @@ /* Number of total regulators available */ #define TPS6507X_NUM_REGULATOR (TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO) -/* Supported voltage values for regulators (in microVolts) */ -static const unsigned int VDCDCx_VSEL_table[] = { - 725000, 750000, 775000, 800000, - 825000, 850000, 875000, 900000, - 925000, 950000, 975000, 1000000, - 1025000, 1050000, 1075000, 1100000, - 1125000, 1150000, 1175000, 1200000, - 1225000, 1250000, 1275000, 1300000, - 1325000, 1350000, 1375000, 1400000, - 1425000, 1450000, 1475000, 1500000, - 1550000, 1600000, 1650000, 1700000, - 1750000, 1800000, 1850000, 1900000, - 1950000, 2000000, 2050000, 2100000, - 2150000, 2200000, 2250000, 2300000, - 2350000, 2400000, 2450000, 2500000, - 2550000, 2600000, 2650000, 2700000, - 2750000, 2800000, 2850000, 2900000, - 3000000, 3100000, 3200000, 3300000, +/* Supported voltage values for regulators (in milliVolts) */ +static const u16 VDCDCx_VSEL_table[] = { + 725, 750, 775, 800, + 825, 850, 875, 900, + 925, 950, 975, 1000, + 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, + 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, + 1425, 1450, 1475, 1500, + 1550, 1600, 1650, 1700, + 1750, 1800, 1850, 1900, + 1950, 2000, 2050, 2100, + 2150, 2200, 2250, 2300, + 2350, 2400, 2450, 2500, + 2550, 2600, 2650, 2700, + 2750, 2800, 2850, 2900, + 3000, 3100, 3200, 3300, }; -static const unsigned int LDO1_VSEL_table[] = { - 1000000, 1100000, 1200000, 1250000, - 1300000, 1350000, 1400000, 1500000, - 1600000, 1800000, 2500000, 2750000, - 2800000, 3000000, 3100000, 3300000, +static const u16 LDO1_VSEL_table[] = { + 1000, 1100, 1200, 1250, + 1300, 1350, 1400, 1500, + 1600, 1800, 2500, 2750, + 2800, 3000, 3100, 3300, }; -/* The voltage mapping table for LDO2 is the same as VDCDCx */ -#define LDO2_VSEL_table VDCDCx_VSEL_table +static const u16 LDO2_VSEL_table[] = { + 725, 750, 775, 800, + 825, 850, 875, 900, + 925, 950, 975, 1000, + 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, + 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, + 1425, 1450, 1475, 1500, + 1550, 1600, 1650, 1700, + 1750, 1800, 1850, 1900, + 1950, 2000, 2050, 2100, + 2150, 2200, 2250, 2300, + 2350, 2400, 2450, 2500, + 2550, 2600, 2650, 2700, + 2750, 2800, 2850, 2900, + 3000, 3100, 3200, 3300, +}; struct tps_info { const char *name; + unsigned min_uV; + unsigned max_uV; u8 table_len; - const unsigned int *table; + const u16 *table; /* Does DCDC high or the low register defines output voltage? */ bool defdcdc_default; @@ -85,26 +103,36 @@ struct tps_info { static struct tps_info tps6507x_pmic_regs[] = { { .name = "VDCDC1", + .min_uV = 725000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), .table = VDCDCx_VSEL_table, }, { .name = "VDCDC2", + .min_uV = 725000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), .table = VDCDCx_VSEL_table, }, { .name = "VDCDC3", + .min_uV = 725000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), .table = VDCDCx_VSEL_table, }, { .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(LDO1_VSEL_table), .table = LDO1_VSEL_table, }, { .name = "LDO2", + .min_uV = 725000, + .max_uV = 3300000, .table_len = ARRAY_SIZE(LDO2_VSEL_table), .table = LDO2_VSEL_table, }, @@ -347,13 +375,28 @@ static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, return tps6507x_pmic_reg_write(tps, reg, data); } +static int tps6507x_pmic_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); + int rid = rdev_get_id(dev); + + if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2) + return -EINVAL; + + if (selector >= tps->info[rid]->table_len) + return -EINVAL; + else + return tps->info[rid]->table[selector] * 1000; +} + static struct regulator_ops tps6507x_pmic_ops = { .is_enabled = tps6507x_pmic_is_enabled, .enable = tps6507x_pmic_enable, .disable = tps6507x_pmic_disable, .get_voltage_sel = tps6507x_pmic_get_voltage_sel, .set_voltage_sel = tps6507x_pmic_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps6507x_pmic_list_voltage, }; static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) @@ -406,7 +449,6 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) tps->desc[i].name = info->name; tps->desc[i].id = i; tps->desc[i].n_voltages = info->table_len; - tps->desc[i].volt_table = info->table; tps->desc[i].ops = &tps6507x_pmic_ops; tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; diff --git a/trunk/drivers/regulator/tps65217-regulator.c b/trunk/drivers/regulator/tps65217-regulator.c index 6caa222af77a..9d371d2cbcae 100644 --- a/trunk/drivers/regulator/tps65217-regulator.c +++ b/trunk/drivers/regulator/tps65217-regulator.c @@ -26,7 +26,7 @@ #include #include -#define TPS65217_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _em, _t) \ +#define TPS65217_REGULATOR(_name, _id, _ops, _n) \ { \ .name = _name, \ .id = _id, \ @@ -34,23 +34,23 @@ .n_voltages = _n, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .vsel_reg = _vr, \ - .vsel_mask = _vm, \ - .enable_reg = TPS65217_REG_ENABLE, \ - .enable_mask = _em, \ - .volt_table = _t, \ } \ -#define TPS65217_INFO(_nm, _min, _max, _f1, _f2) \ +#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm) \ { \ .name = _nm, \ .min_uV = _min, \ .max_uV = _max, \ .vsel_to_uv = _f1, \ .uv_to_vsel = _f2, \ + .table = _t, \ + .table_len = _n, \ + .enable_mask = _em, \ + .set_vout_reg = _vr, \ + .set_vout_mask = _vm, \ } -static const unsigned int LDO1_VSEL_table[] = { +static const int LDO1_VSEL_table[] = { 1000000, 1100000, 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1800000, 2500000, 2750000, @@ -78,7 +78,7 @@ static int tps65217_vsel_to_uv1(unsigned int vsel) static int tps65217_uv_to_vsel1(int uV, unsigned int *vsel) { - if (uV < 0 || uV > 3300000) + if ((uV < 0) && (uV > 3300000)) return -EINVAL; if (uV <= 1500000) @@ -112,7 +112,7 @@ static int tps65217_vsel_to_uv2(unsigned int vsel) static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel) { - if (uV < 0 || uV > 3300000) + if ((uV < 0) && (uV > 3300000)) return -EINVAL; if (uV <= 1900000) @@ -127,20 +127,46 @@ static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel) static struct tps_info tps65217_pmic_regs[] = { TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1), + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN, + TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK), TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1), + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN, + TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK), TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1), - TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL), + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN, + TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table, + 16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1, + TPS65217_DEFLDO1_LDO1_MASK), TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1), + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN, + TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK), TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2, - tps65217_uv_to_vsel2), + tps65217_uv_to_vsel2, NULL, 32, + TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, + TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK), TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2, - tps65217_uv_to_vsel2), + tps65217_uv_to_vsel2, NULL, 32, + TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, + TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK), }; +static int tps65217_pmic_is_enabled(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int data, rid = rdev_get_id(dev); + + if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) + return -EINVAL; + + ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); + if (ret) + return ret; + + return (data & tps->info[rid]->enable_mask) ? 1 : 0; +} + static int tps65217_pmic_enable(struct regulator_dev *dev) { struct tps65217 *tps = rdev_get_drvdata(dev); @@ -151,8 +177,9 @@ static int tps65217_pmic_enable(struct regulator_dev *dev) /* Enable the regulator and password protection is level 1 */ return tps65217_set_bits(tps, TPS65217_REG_ENABLE, - dev->desc->enable_mask, dev->desc->enable_mask, - TPS65217_PROTECT_L1); + tps->info[rid]->enable_mask, + tps->info[rid]->enable_mask, + TPS65217_PROTECT_L1); } static int tps65217_pmic_disable(struct regulator_dev *dev) @@ -165,7 +192,25 @@ static int tps65217_pmic_disable(struct regulator_dev *dev) /* Disable the regulator and password protection is level 1 */ return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, - dev->desc->enable_mask, TPS65217_PROTECT_L1); + tps->info[rid]->enable_mask, TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_get_voltage_sel(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int selector, rid = rdev_get_id(dev); + + if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) + return -EINVAL; + + ret = tps65217_reg_read(tps, tps->info[rid]->set_vout_reg, &selector); + if (ret) + return ret; + + selector &= tps->info[rid]->set_vout_mask; + + return selector; } static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, @@ -176,7 +221,8 @@ static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, unsigned int rid = rdev_get_id(dev); /* Set the voltage based on vsel value and write protect level is 2 */ - ret = tps65217_set_bits(tps, dev->desc->vsel_reg, dev->desc->vsel_mask, + ret = tps65217_set_bits(tps, tps->info[rid]->set_vout_reg, + tps->info[rid]->set_vout_mask, selector, TPS65217_PROTECT_L2); /* Set GO bit for DCDCx to initiate voltage transistion */ @@ -206,10 +252,10 @@ static int tps65217_pmic_map_voltage(struct regulator_dev *dev, if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) return -EINVAL; - if (min_uV < tps->info[rid]->min_uV) - min_uV = tps->info[rid]->min_uV; + if (min_uV < tps->info[rid]->min_uV || min_uV > tps->info[rid]->max_uV) + return -EINVAL; - if (max_uV < tps->info[rid]->min_uV || min_uV > tps->info[rid]->max_uV) + if (max_uV < tps->info[rid]->min_uV || max_uV > tps->info[rid]->max_uV) return -EINVAL; ret = tps->info[rid]->uv_to_vsel(min_uV, &sel); @@ -228,18 +274,21 @@ static int tps65217_pmic_list_voltage(struct regulator_dev *dev, if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) return -EINVAL; - if (selector >= dev->desc->n_voltages) + if (selector >= tps->info[rid]->table_len) return -EINVAL; + if (tps->info[rid]->table) + return tps->info[rid]->table[selector]; + return tps->info[rid]->vsel_to_uv(selector); } /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ static struct regulator_ops tps65217_pmic_ops = { - .is_enabled = regulator_is_enabled_regmap, + .is_enabled = tps65217_pmic_is_enabled, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .get_voltage_sel = tps65217_pmic_get_voltage_sel, .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = tps65217_pmic_list_voltage, .map_voltage = tps65217_pmic_map_voltage, @@ -247,38 +296,22 @@ static struct regulator_ops tps65217_pmic_ops = { /* Operations permitted on LDO1 */ static struct regulator_ops tps65217_pmic_ldo1_ops = { - .is_enabled = regulator_is_enabled_regmap, + .is_enabled = tps65217_pmic_is_enabled, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .get_voltage_sel = tps65217_pmic_get_voltage_sel, .set_voltage_sel = tps65217_pmic_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps65217_pmic_list_voltage, }; static const struct regulator_desc regulators[] = { - TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64, - TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK, - TPS65217_ENABLE_DC1_EN, NULL), - TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64, - TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK, - TPS65217_ENABLE_DC2_EN, NULL), - TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64, - TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK, - TPS65217_ENABLE_DC3_EN, NULL), - TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16, - TPS65217_REG_DEFLDO1, TPS65217_DEFLDO1_LDO1_MASK, - TPS65217_ENABLE_LDO1_EN, LDO1_VSEL_table), - TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64, - TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK, - TPS65217_ENABLE_LDO2_EN, NULL), - TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32, - TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, - TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, - NULL), - TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32, - TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, - TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, - NULL), + TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64), + TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64), + TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64), + TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16), + TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64), + TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32), + TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32), }; static int __devinit tps65217_regulator_probe(struct platform_device *pdev) @@ -293,7 +326,6 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev) tps->info[pdev->id] = info; config.dev = &pdev->dev; - config.of_node = pdev->dev.of_node; config.init_data = pdev->dev.platform_data; config.driver_data = tps; diff --git a/trunk/drivers/regulator/tps6524x-regulator.c b/trunk/drivers/regulator/tps6524x-regulator.c index 947ece933d90..b88b3df82381 100644 --- a/trunk/drivers/regulator/tps6524x-regulator.c +++ b/trunk/drivers/regulator/tps6524x-regulator.c @@ -110,6 +110,9 @@ #define N_SWITCH 2 #define N_REGULATORS (N_DCDC + N_LDO + N_SWITCH) +#define FIXED_ILIMSEL BIT(0) +#define FIXED_VOLTAGE BIT(1) + #define CMD_READ(reg) ((reg) << 6) #define CMD_WRITE(reg) (BIT(5) | (reg) << 6) #define STAT_CLK BIT(3) @@ -126,9 +129,12 @@ struct field { struct supply_info { const char *name; int n_voltages; - const unsigned int *voltages; + const int *voltages; + int fixed_voltage; int n_ilimsels; - const unsigned int *ilimsels; + const int *ilimsels; + int fixed_ilimsel; + int flags; struct field enable, voltage, ilimsel; }; @@ -301,7 +307,7 @@ static int write_field(struct tps6524x *hw, const struct field *field, val << field->shift); } -static const unsigned int dcdc1_voltages[] = { +static const int dcdc1_voltages[] = { 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, @@ -312,7 +318,7 @@ static const unsigned int dcdc1_voltages[] = { 1500000, 1525000, 1550000, 1575000, }; -static const unsigned int dcdc2_voltages[] = { +static const int dcdc2_voltages[] = { 1400000, 1450000, 1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000, @@ -323,7 +329,7 @@ static const unsigned int dcdc2_voltages[] = { 2800000, 2850000, 2900000, 2950000, }; -static const unsigned int dcdc3_voltages[] = { +static const int dcdc3_voltages[] = { 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, 2900000, 2950000, 3000000, 3050000, 3100000, @@ -331,54 +337,38 @@ static const unsigned int dcdc3_voltages[] = { 3400000, 3450000, 3500000, 3550000, 3600000, }; -static const unsigned int ldo1_voltages[] = { +static const int ldo1_voltages[] = { 4300000, 4350000, 4400000, 4450000, 4500000, 4550000, 4600000, 4650000, 4700000, 4750000, 4800000, 4850000, 4900000, 4950000, 5000000, 5050000, }; -static const unsigned int ldo2_voltages[] = { +static const int ldo2_voltages[] = { 1100000, 1150000, 1200000, 1250000, 1300000, 1700000, 1750000, 1800000, 1850000, 1900000, 3150000, 3200000, 3250000, 3300000, 3350000, 3400000, }; -static const unsigned int fixed_5000000_voltage[] = { - 5000000 -}; - -static const unsigned int ldo_ilimsel[] = { +static const int ldo_ilimsel[] = { 400000, 1500000 }; -static const unsigned int usb_ilimsel[] = { +static const int usb_ilimsel[] = { 200000, 400000, 800000, 1000000 }; -static const unsigned int fixed_2400000_ilimsel[] = { - 2400000 -}; - -static const unsigned int fixed_1200000_ilimsel[] = { - 1200000 -}; - -static const unsigned int fixed_400000_ilimsel[] = { - 400000 -}; - #define __MK_FIELD(_reg, _mask, _shift) \ { .reg = (_reg), .mask = (_mask), .shift = (_shift), } static const struct supply_info supply_info[N_REGULATORS] = { { .name = "DCDC1", + .flags = FIXED_ILIMSEL, .n_voltages = ARRAY_SIZE(dcdc1_voltages), .voltages = dcdc1_voltages, - .n_ilimsels = ARRAY_SIZE(fixed_2400000_ilimsel), - .ilimsels = fixed_2400000_ilimsel, + .fixed_ilimsel = 2400000, .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, DCDCDCDC1_EN_SHIFT), .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, @@ -386,10 +376,10 @@ static const struct supply_info supply_info[N_REGULATORS] = { }, { .name = "DCDC2", + .flags = FIXED_ILIMSEL, .n_voltages = ARRAY_SIZE(dcdc2_voltages), .voltages = dcdc2_voltages, - .n_ilimsels = ARRAY_SIZE(fixed_1200000_ilimsel), - .ilimsels = fixed_1200000_ilimsel, + .fixed_ilimsel = 1200000, .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, DCDCDCDC2_EN_SHIFT), .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, @@ -397,10 +387,10 @@ static const struct supply_info supply_info[N_REGULATORS] = { }, { .name = "DCDC3", + .flags = FIXED_ILIMSEL, .n_voltages = ARRAY_SIZE(dcdc3_voltages), .voltages = dcdc3_voltages, - .n_ilimsels = ARRAY_SIZE(fixed_1200000_ilimsel), - .ilimsels = fixed_1200000_ilimsel, + .fixed_ilimsel = 1200000, .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, DCDCDCDC3_EN_SHIFT), .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, @@ -434,8 +424,8 @@ static const struct supply_info supply_info[N_REGULATORS] = { }, { .name = "USB", - .n_voltages = ARRAY_SIZE(fixed_5000000_voltage), - .voltages = fixed_5000000_voltage, + .flags = FIXED_VOLTAGE, + .fixed_voltage = 5000000, .n_ilimsels = ARRAY_SIZE(usb_ilimsel), .ilimsels = usb_ilimsel, .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, @@ -445,15 +435,29 @@ static const struct supply_info supply_info[N_REGULATORS] = { }, { .name = "LCD", - .n_voltages = ARRAY_SIZE(fixed_5000000_voltage), - .voltages = fixed_5000000_voltage, - .n_ilimsels = ARRAY_SIZE(fixed_400000_ilimsel), - .ilimsels = fixed_400000_ilimsel, + .flags = FIXED_VOLTAGE | FIXED_ILIMSEL, + .fixed_voltage = 5000000, + .fixed_ilimsel = 400000, .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, BLOCK_LCD_SHIFT), }, }; +static int list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return selector ? -EINVAL : info->fixed_voltage; + + return ((selector < info->n_voltages) ? + info->voltages[selector] : -EINVAL); +} + static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { const struct supply_info *info; @@ -462,7 +466,7 @@ static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector) hw = rdev_get_drvdata(rdev); info = &supply_info[rdev_get_id(rdev)]; - if (rdev->desc->n_voltages == 1) + if (info->flags & FIXED_VOLTAGE) return -EINVAL; return write_field(hw, &info->voltage, selector); @@ -477,8 +481,8 @@ static int get_voltage_sel(struct regulator_dev *rdev) hw = rdev_get_drvdata(rdev); info = &supply_info[rdev_get_id(rdev)]; - if (rdev->desc->n_voltages == 1) - return 0; + if (info->flags & FIXED_VOLTAGE) + return info->fixed_voltage; ret = read_field(hw, &info->voltage); if (ret < 0) @@ -499,7 +503,7 @@ static int set_current_limit(struct regulator_dev *rdev, int min_uA, hw = rdev_get_drvdata(rdev); info = &supply_info[rdev_get_id(rdev)]; - if (info->n_ilimsels == 1) + if (info->flags & FIXED_ILIMSEL) return -EINVAL; for (i = 0; i < info->n_ilimsels; i++) @@ -522,8 +526,8 @@ static int get_current_limit(struct regulator_dev *rdev) hw = rdev_get_drvdata(rdev); info = &supply_info[rdev_get_id(rdev)]; - if (info->n_ilimsels == 1) - return info->ilimsels[0]; + if (info->flags & FIXED_ILIMSEL) + return info->fixed_ilimsel; ret = read_field(hw, &info->ilimsel); if (ret < 0) @@ -573,7 +577,7 @@ static struct regulator_ops regulator_ops = { .disable = disable_supply, .get_voltage_sel = get_voltage_sel, .set_voltage_sel = set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = list_voltage, .set_current_limit = set_current_limit, .get_current_limit = get_current_limit, }; @@ -625,11 +629,13 @@ static int __devinit pmic_probe(struct spi_device *spi) hw->desc[i].name = info->name; hw->desc[i].id = i; hw->desc[i].n_voltages = info->n_voltages; - hw->desc[i].volt_table = info->voltages; hw->desc[i].ops = ®ulator_ops; hw->desc[i].type = REGULATOR_VOLTAGE; hw->desc[i].owner = THIS_MODULE; + if (info->flags & FIXED_VOLTAGE) + hw->desc[i].n_voltages = 1; + config.dev = dev; config.init_data = init_data; config.driver_data = hw; diff --git a/trunk/drivers/regulator/tps6586x-regulator.c b/trunk/drivers/regulator/tps6586x-regulator.c index e6da90ab5153..c0a214575380 100644 --- a/trunk/drivers/regulator/tps6586x-regulator.c +++ b/trunk/drivers/regulator/tps6586x-regulator.c @@ -63,6 +63,8 @@ struct tps6586x_regulator { int enable_bit[2]; int enable_reg[2]; + int *voltages; + /* for DVM regulators */ int go_reg; int go_bit; @@ -70,9 +72,22 @@ struct tps6586x_regulator { static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev) { - return rdev_get_dev(rdev)->parent; + return rdev_get_dev(rdev)->parent->parent; } +static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + struct tps6586x_regulator *info = rdev_get_drvdata(rdev); + int rid = rdev_get_id(rdev); + + /* LDO0 has minimal voltage 1.2V rather than 1.25V */ + if ((rid == TPS6586X_ID_LDO_0) && (selector == 0)) + return (info->voltages[0] - 50) * 1000; + + return info->voltages[selector] * 1000; +} + + static int tps6586x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { @@ -153,7 +168,7 @@ static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev) } static struct regulator_ops tps6586x_regulator_ops = { - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps6586x_list_voltage, .get_voltage_sel = tps6586x_get_voltage_sel, .set_voltage_sel = tps6586x_set_voltage_sel, @@ -162,45 +177,39 @@ static struct regulator_ops tps6586x_regulator_ops = { .disable = tps6586x_regulator_disable, }; -static const unsigned int tps6586x_ldo0_voltages[] = { - 1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, -}; - -static const unsigned int tps6586x_ldo4_voltages[] = { - 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000, - 1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000, - 2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000, - 2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000, +static int tps6586x_ldo_voltages[] = { + 1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300, }; -static const unsigned int tps6586x_ldo_voltages[] = { - 1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, +static int tps6586x_ldo4_voltages[] = { + 1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875, + 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075, + 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275, + 2300, 2325, 2350, 2375, 2400, 2425, 2450, 2475, }; -static const unsigned int tps6586x_sm2_voltages[] = { - 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000, - 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000, - 3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000, - 4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000, +static int tps6586x_sm2_voltages[] = { + 3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350, + 3400, 3450, 3500, 3550, 3600, 3650, 3700, 3750, + 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, + 4200, 4250, 4300, 4350, 4400, 4450, 4500, 4550, }; -static const unsigned int tps6586x_dvm_voltages[] = { - 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, - 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, - 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, - 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, +static int tps6586x_dvm_voltages[] = { + 725, 750, 775, 800, 825, 850, 875, 900, + 925, 950, 975, 1000, 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, }; -#define TPS6586X_REGULATOR(_id, _pin_name, vdata, vreg, shift, nbits, \ +#define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ .desc = { \ - .supply_name = _pin_name, \ .name = "REG-" #_id, \ .ops = &tps6586x_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .id = TPS6586X_ID_##_id, \ .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ - .volt_table = tps6586x_##vdata##_voltages, \ .owner = THIS_MODULE, \ }, \ .volt_reg = TPS6586X_##vreg, \ @@ -209,45 +218,44 @@ static const unsigned int tps6586x_dvm_voltages[] = { .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ .enable_bit[0] = (ebit0), \ .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ - .enable_bit[1] = (ebit1), + .enable_bit[1] = (ebit1), \ + .voltages = tps6586x_##vdata##_voltages, #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ .go_reg = TPS6586X_##goreg, \ .go_bit = (gobit), -#define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits, \ +#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ { \ - TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits, \ + TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ } -#define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits, \ +#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ { \ - TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits, \ + TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ } static struct tps6586x_regulator tps6586x_regulator[] = { - TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), - TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), - TPS6586X_LDO(LDO_5, NULL, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), - TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), - TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), - TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), - TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), - TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), - TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), - TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), - - TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, - ENB, 3, VCC2, 6), - TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, - END, 3, VCC1, 6), - TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), - TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), + TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), + TPS6586X_LDO(LDO_3, ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), + TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), + TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), + TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), + TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), + TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), + TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), + TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), + TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), + + TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), + TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), + TPS6586X_DVM(SM_0, dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), + TPS6586X_DVM(SM_1, dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), }; /* @@ -354,7 +362,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) if (err) return err; - config.dev = pdev->dev.parent; + config.dev = &pdev->dev; config.of_node = pdev->dev.of_node; config.init_data = pdev->dev.platform_data; config.driver_data = ri; diff --git a/trunk/drivers/regulator/tps65910-regulator.c b/trunk/drivers/regulator/tps65910-regulator.c index 793adda560c3..6bf864b4bdf6 100644 --- a/trunk/drivers/regulator/tps65910-regulator.c +++ b/trunk/drivers/regulator/tps65910-regulator.c @@ -31,147 +31,160 @@ TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \ TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) -/* supported VIO voltages in microvolts */ -static const unsigned int VIO_VSEL_table[] = { - 1500000, 1800000, 2500000, 3300000, +/* supported VIO voltages in millivolts */ +static const u16 VIO_VSEL_table[] = { + 1500, 1800, 2500, 3300, }; /* VSEL tables for TPS65910 specific LDOs and dcdc's */ -/* supported VDD3 voltages in microvolts */ -static const unsigned int VDD3_VSEL_table[] = { - 5000000, +/* supported VDD3 voltages in millivolts */ +static const u16 VDD3_VSEL_table[] = { + 5000, }; -/* supported VDIG1 voltages in microvolts */ -static const unsigned int VDIG1_VSEL_table[] = { - 1200000, 1500000, 1800000, 2700000, +/* supported VDIG1 voltages in millivolts */ +static const u16 VDIG1_VSEL_table[] = { + 1200, 1500, 1800, 2700, }; -/* supported VDIG2 voltages in microvolts */ -static const unsigned int VDIG2_VSEL_table[] = { - 1000000, 1100000, 1200000, 1800000, +/* supported VDIG2 voltages in millivolts */ +static const u16 VDIG2_VSEL_table[] = { + 1000, 1100, 1200, 1800, }; -/* supported VPLL voltages in microvolts */ -static const unsigned int VPLL_VSEL_table[] = { - 1000000, 1100000, 1800000, 2500000, +/* supported VPLL voltages in millivolts */ +static const u16 VPLL_VSEL_table[] = { + 1000, 1100, 1800, 2500, }; -/* supported VDAC voltages in microvolts */ -static const unsigned int VDAC_VSEL_table[] = { - 1800000, 2600000, 2800000, 2850000, +/* supported VDAC voltages in millivolts */ +static const u16 VDAC_VSEL_table[] = { + 1800, 2600, 2800, 2850, }; -/* supported VAUX1 voltages in microvolts */ -static const unsigned int VAUX1_VSEL_table[] = { - 1800000, 2500000, 2800000, 2850000, +/* supported VAUX1 voltages in millivolts */ +static const u16 VAUX1_VSEL_table[] = { + 1800, 2500, 2800, 2850, }; -/* supported VAUX2 voltages in microvolts */ -static const unsigned int VAUX2_VSEL_table[] = { - 1800000, 2800000, 2900000, 3300000, +/* supported VAUX2 voltages in millivolts */ +static const u16 VAUX2_VSEL_table[] = { + 1800, 2800, 2900, 3300, }; -/* supported VAUX33 voltages in microvolts */ -static const unsigned int VAUX33_VSEL_table[] = { - 1800000, 2000000, 2800000, 3300000, +/* supported VAUX33 voltages in millivolts */ +static const u16 VAUX33_VSEL_table[] = { + 1800, 2000, 2800, 3300, }; -/* supported VMMC voltages in microvolts */ -static const unsigned int VMMC_VSEL_table[] = { - 1800000, 2800000, 3000000, 3300000, +/* supported VMMC voltages in millivolts */ +static const u16 VMMC_VSEL_table[] = { + 1800, 2800, 3000, 3300, }; struct tps_info { const char *name; - const char *vin_name; + unsigned min_uV; + unsigned max_uV; u8 n_voltages; - const unsigned int *voltage_table; + const u16 *voltage_table; int enable_time_us; }; static struct tps_info tps65910_regs[] = { { .name = "vrtc", - .vin_name = "vcc7", .enable_time_us = 2200, }, { .name = "vio", - .vin_name = "vccio", + .min_uV = 1500000, + .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, .enable_time_us = 350, }, { .name = "vdd1", - .vin_name = "vcc1", + .min_uV = 600000, + .max_uV = 4500000, .enable_time_us = 350, }, { .name = "vdd2", - .vin_name = "vcc2", + .min_uV = 600000, + .max_uV = 4500000, .enable_time_us = 350, }, { .name = "vdd3", + .min_uV = 5000000, + .max_uV = 5000000, .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), .voltage_table = VDD3_VSEL_table, .enable_time_us = 200, }, { .name = "vdig1", - .vin_name = "vcc6", + .min_uV = 1200000, + .max_uV = 2700000, .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), .voltage_table = VDIG1_VSEL_table, .enable_time_us = 100, }, { .name = "vdig2", - .vin_name = "vcc6", + .min_uV = 1000000, + .max_uV = 1800000, .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), .voltage_table = VDIG2_VSEL_table, .enable_time_us = 100, }, { .name = "vpll", - .vin_name = "vcc5", + .min_uV = 1000000, + .max_uV = 2500000, .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), .voltage_table = VPLL_VSEL_table, .enable_time_us = 100, }, { .name = "vdac", - .vin_name = "vcc5", + .min_uV = 1800000, + .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), .voltage_table = VDAC_VSEL_table, .enable_time_us = 100, }, { .name = "vaux1", - .vin_name = "vcc4", + .min_uV = 1800000, + .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), .voltage_table = VAUX1_VSEL_table, .enable_time_us = 100, }, { .name = "vaux2", - .vin_name = "vcc4", + .min_uV = 1800000, + .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), .voltage_table = VAUX2_VSEL_table, .enable_time_us = 100, }, { .name = "vaux33", - .vin_name = "vcc3", + .min_uV = 1800000, + .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), .voltage_table = VAUX33_VSEL_table, .enable_time_us = 100, }, { .name = "vmmc", - .vin_name = "vcc3", + .min_uV = 1800000, + .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), .voltage_table = VMMC_VSEL_table, .enable_time_us = 100, @@ -181,79 +194,91 @@ static struct tps_info tps65910_regs[] = { static struct tps_info tps65911_regs[] = { { .name = "vrtc", - .vin_name = "vcc7", .enable_time_us = 2200, }, { .name = "vio", - .vin_name = "vccio", + .min_uV = 1500000, + .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, .enable_time_us = 350, }, { .name = "vdd1", - .vin_name = "vcc1", - .n_voltages = 0x4C, + .min_uV = 600000, + .max_uV = 4500000, + .n_voltages = 73, .enable_time_us = 350, }, { .name = "vdd2", - .vin_name = "vcc2", - .n_voltages = 0x4C, + .min_uV = 600000, + .max_uV = 4500000, + .n_voltages = 73, .enable_time_us = 350, }, { .name = "vddctrl", - .n_voltages = 0x44, + .min_uV = 600000, + .max_uV = 1400000, + .n_voltages = 65, .enable_time_us = 900, }, { .name = "ldo1", - .vin_name = "vcc6", - .n_voltages = 0x33, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 47, .enable_time_us = 420, }, { .name = "ldo2", - .vin_name = "vcc6", - .n_voltages = 0x33, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 47, .enable_time_us = 420, }, { .name = "ldo3", - .vin_name = "vcc5", - .n_voltages = 0x1A, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo4", - .vin_name = "vcc5", - .n_voltages = 0x33, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 47, .enable_time_us = 230, }, { .name = "ldo5", - .vin_name = "vcc4", - .n_voltages = 0x1A, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo6", - .vin_name = "vcc3", - .n_voltages = 0x1A, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo7", - .vin_name = "vcc3", - .n_voltages = 0x1A, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo8", - .vin_name = "vcc3", - .n_voltages = 0x1A, + .min_uV = 1000000, + .max_uV = 3300000, + .n_voltages = 24, .enable_time_us = 230, }, }; @@ -296,6 +321,7 @@ struct tps65910_reg { struct tps65910 *mfd; struct regulator_dev **rdev; struct tps_info **info; + struct mutex mutex; int num_regulators; int mode; int (*get_ctrl_reg)(int); @@ -303,6 +329,71 @@ struct tps65910_reg { unsigned int board_ext_control[TPS65910_NUM_REGS]; }; +static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) +{ + unsigned int val; + int err; + + err = tps65910_reg_read(pmic->mfd, reg, &val); + if (err) + return err; + + return val; +} + +static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, + u8 set_mask, u8 clear_mask) +{ + int err, data; + + mutex_lock(&pmic->mutex); + + data = tps65910_read(pmic, reg); + if (data < 0) { + dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); + err = data; + goto out; + } + + data &= ~clear_mask; + data |= set_mask; + err = tps65910_reg_write(pmic->mfd, reg, data); + if (err) + dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); + +out: + mutex_unlock(&pmic->mutex); + return err; +} + +static int tps65910_reg_read_locked(struct tps65910_reg *pmic, u8 reg) +{ + int data; + + mutex_lock(&pmic->mutex); + + data = tps65910_read(pmic, reg); + if (data < 0) + dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); + + mutex_unlock(&pmic->mutex); + return data; +} + +static int tps65910_reg_write_locked(struct tps65910_reg *pmic, u8 reg, u8 val) +{ + int err; + + mutex_lock(&pmic->mutex); + + err = tps65910_reg_write(pmic->mfd, reg, val); + if (err < 0) + dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); + + mutex_unlock(&pmic->mutex); + return err; +} + static int tps65910_get_ctrl_register(int id) { switch (id) { @@ -371,6 +462,13 @@ static int tps65911_get_ctrl_register(int id) } } +static int tps65910_enable_time(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int id = rdev_get_id(dev); + return pmic->info[id]->enable_time_us; +} + static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); @@ -383,9 +481,8 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) switch (mode) { case REGULATOR_MODE_NORMAL: - return tps65910_reg_update_bits(pmic->mfd, reg, - LDO_ST_MODE_BIT | LDO_ST_ON_BIT, - LDO_ST_ON_BIT); + return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT, + LDO_ST_MODE_BIT); case REGULATOR_MODE_IDLE: value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; return tps65910_reg_set_bits(mfd, reg, value); @@ -399,15 +496,15 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) static unsigned int tps65910_get_mode(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int ret, reg, value, id = rdev_get_id(dev); + int reg, value, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; - ret = tps65910_reg_read(pmic->mfd, reg, &value); - if (ret < 0) - return ret; + value = tps65910_reg_read_locked(pmic, reg); + if (value < 0) + return value; if (!(value & LDO_ST_ON_BIT)) return REGULATOR_MODE_STANDBY; @@ -420,51 +517,33 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int ret, id = rdev_get_id(dev); + int id = rdev_get_id(dev); int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; switch (id) { case TPS65910_REG_VDD1: - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_OP, &opvsel); - if (ret < 0) - return ret; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1, &mult); - if (ret < 0) - return ret; + opvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD1_OP); + mult = tps65910_reg_read_locked(pmic, TPS65910_VDD1); mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_SR, &srvsel); - if (ret < 0) - return ret; + srvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD1_SR); sr = opvsel & VDD1_OP_CMD_MASK; opvsel &= VDD1_OP_SEL_MASK; srvsel &= VDD1_SR_SEL_MASK; vselmax = 75; break; case TPS65910_REG_VDD2: - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_OP, &opvsel); - if (ret < 0) - return ret; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2, &mult); - if (ret < 0) - return ret; + opvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD2_OP); + mult = tps65910_reg_read_locked(pmic, TPS65910_VDD2); mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_SR, &srvsel); - if (ret < 0) - return ret; + srvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD2_SR); sr = opvsel & VDD2_OP_CMD_MASK; opvsel &= VDD2_OP_SEL_MASK; srvsel &= VDD2_SR_SEL_MASK; vselmax = 75; break; case TPS65911_REG_VDDCTRL: - ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_OP, - &opvsel); - if (ret < 0) - return ret; - ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_SR, - &srvsel); - if (ret < 0) - return ret; + opvsel = tps65910_reg_read_locked(pmic, TPS65911_VDDCTRL_OP); + srvsel = tps65910_reg_read_locked(pmic, TPS65911_VDDCTRL_SR); sr = opvsel & VDDCTRL_OP_CMD_MASK; opvsel &= VDDCTRL_OP_SEL_MASK; srvsel &= VDDCTRL_SR_SEL_MASK; @@ -498,15 +577,15 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) static int tps65910_get_voltage_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int ret, reg, value, id = rdev_get_id(dev); + int reg, value, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; - ret = tps65910_reg_read(pmic->mfd, reg, &value); - if (ret < 0) - return ret; + value = tps65910_reg_read_locked(pmic, reg); + if (value < 0) + return value; switch (id) { case TPS65910_REG_VIO: @@ -530,20 +609,18 @@ static int tps65910_get_voltage_sel(struct regulator_dev *dev) static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) { - return dev->desc->volt_table[0]; + return 5 * 1000 * 1000; } static int tps65911_get_voltage_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int ret, id = rdev_get_id(dev); - unsigned int value, reg; + int id = rdev_get_id(dev); + u8 value, reg; reg = pmic->get_ctrl_reg(id); - ret = tps65910_reg_read(pmic->mfd, reg, &value); - if (ret < 0) - return ret; + value = tps65910_reg_read_locked(pmic, reg); switch (id) { case TPS65911_REG_LDO1: @@ -585,10 +662,10 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, dcdc_mult--; vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; - tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD1, - VDD1_VGAIN_SEL_MASK, - dcdc_mult << VDD1_VGAIN_SEL_SHIFT); - tps65910_reg_write(pmic->mfd, TPS65910_VDD1_OP, vsel); + tps65910_modify_bits(pmic, TPS65910_VDD1, + (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), + VDD1_VGAIN_SEL_MASK); + tps65910_reg_write_locked(pmic, TPS65910_VDD1_OP, vsel); break; case TPS65910_REG_VDD2: dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; @@ -596,14 +673,14 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, dcdc_mult--; vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; - tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD2, - VDD1_VGAIN_SEL_MASK, - dcdc_mult << VDD2_VGAIN_SEL_SHIFT); - tps65910_reg_write(pmic->mfd, TPS65910_VDD2_OP, vsel); + tps65910_modify_bits(pmic, TPS65910_VDD2, + (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), + VDD1_VGAIN_SEL_MASK); + tps65910_reg_write_locked(pmic, TPS65910_VDD2_OP, vsel); break; case TPS65911_REG_VDDCTRL: vsel = selector + 3; - tps65910_reg_write(pmic->mfd, TPS65911_VDDCTRL_OP, vsel); + tps65910_reg_write_locked(pmic, TPS65911_VDDCTRL_OP, vsel); } return 0; @@ -629,8 +706,8 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev, case TPS65910_REG_VAUX2: case TPS65910_REG_VAUX33: case TPS65910_REG_VMMC: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, - selector << LDO_SEL_SHIFT); + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); } return -EINVAL; @@ -650,18 +727,18 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev, case TPS65911_REG_LDO1: case TPS65911_REG_LDO2: case TPS65911_REG_LDO4: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO1_SEL_MASK, - selector << LDO_SEL_SHIFT); + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO1_SEL_MASK); case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: case TPS65911_REG_LDO6: case TPS65911_REG_LDO7: case TPS65911_REG_LDO8: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO3_SEL_MASK, - selector << LDO_SEL_SHIFT); + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); case TPS65910_REG_VIO: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, - selector << LDO_SEL_SHIFT); + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); } return -EINVAL; @@ -691,6 +768,23 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, return volt * 100 * mult; } +static int tps65910_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int id = rdev_get_id(dev), voltage; + + if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) + return -EINVAL; + + if (selector >= pmic->info[id]->n_voltages) + return -EINVAL; + else + voltage = pmic->info[id]->voltage_table[selector] * 1000; + + return voltage; +} + static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); @@ -722,7 +816,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->voltage_table[selector]; + return pmic->info[id]->voltage_table[selector] * 1000; default: return -EINVAL; } @@ -730,16 +824,42 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) return (LDO_MIN_VOLT + selector * step_mv) * 1000; } +static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev, + unsigned int old_selector, unsigned int new_selector) +{ + int id = rdev_get_id(dev); + int old_volt, new_volt; + + old_volt = tps65910_list_voltage_dcdc(dev, old_selector); + if (old_volt < 0) + return old_volt; + + new_volt = tps65910_list_voltage_dcdc(dev, new_selector); + if (new_volt < 0) + return new_volt; + + /* VDD1 and VDD2 are 12.5mV/us, VDDCTRL is 100mV/20us */ + switch (id) { + case TPS65910_REG_VDD1: + case TPS65910_REG_VDD2: + return DIV_ROUND_UP(abs(old_volt - new_volt), 12500); + case TPS65911_REG_VDDCTRL: + return DIV_ROUND_UP(abs(old_volt - new_volt), 5000); + } + return -EINVAL; +} + /* Regulator ops (except VRTC) */ static struct regulator_ops tps65910_ops_dcdc = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage_sel = tps65910_get_voltage_dcdc_sel, .set_voltage_sel = tps65910_set_voltage_dcdc_sel, - .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_voltage_time_sel = tps65910_set_voltage_dcdc_time_sel, .list_voltage = tps65910_list_voltage_dcdc, }; @@ -747,27 +867,30 @@ static struct regulator_ops tps65910_ops_vdd3 = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage_vdd3, - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps65910_list_voltage, }; static struct regulator_ops tps65910_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage_sel = tps65910_get_voltage_sel, .set_voltage_sel = tps65910_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = tps65910_list_voltage, }; static struct regulator_ops tps65911_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, + .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage_sel = tps65911_get_voltage_sel, @@ -873,27 +996,19 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, (tps65910_chip_id(mfd) == TPS65911))) { int op_reg_add = pmic->get_ctrl_reg(id) + 1; int sr_reg_add = pmic->get_ctrl_reg(id) + 2; - int opvsel, srvsel; - - ret = tps65910_reg_read(pmic->mfd, op_reg_add, &opvsel); - if (ret < 0) - return ret; - ret = tps65910_reg_read(pmic->mfd, sr_reg_add, &srvsel); - if (ret < 0) - return ret; - + int opvsel = tps65910_reg_read_locked(pmic, op_reg_add); + int srvsel = tps65910_reg_read_locked(pmic, sr_reg_add); if (opvsel & VDD1_OP_CMD_MASK) { u8 reg_val = srvsel & VDD1_OP_SEL_MASK; - - ret = tps65910_reg_write(pmic->mfd, op_reg_add, - reg_val); + ret = tps65910_reg_write_locked(pmic, op_reg_add, + reg_val); if (ret < 0) { dev_err(mfd->dev, "Error in configuring op register\n"); return ret; } } - ret = tps65910_reg_write(pmic->mfd, sr_reg_add, 0); + ret = tps65910_reg_write_locked(pmic, sr_reg_add, 0); if (ret < 0) { dev_err(mfd->dev, "Error in settting sr register\n"); return ret; @@ -1011,7 +1126,6 @@ static struct tps65910_board *tps65910_parse_dt_reg_data( "ti,regulator-ext-sleep-control", &prop); if (!ret) pmic_plat_data->regulator_ext_sleep_control[idx] = prop; - } return pmic_plat_data; @@ -1022,7 +1136,7 @@ static inline struct tps65910_board *tps65910_parse_dt_reg_data( struct of_regulator_match **tps65910_reg_matches) { *tps65910_reg_matches = NULL; - return NULL; + return 0; } #endif @@ -1054,6 +1168,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) return -ENOMEM; } + mutex_init(&pmic->mutex); pmic->mfd = tps65910; platform_set_drvdata(pdev, pmic); @@ -1114,31 +1229,23 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->info[i] = info; pmic->desc[i].name = info->name; - pmic->desc[i].supply_name = info->vin_name; pmic->desc[i].id = i; pmic->desc[i].n_voltages = info->n_voltages; - pmic->desc[i].enable_time = info->enable_time_us; if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { pmic->desc[i].ops = &tps65910_ops_dcdc; pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE * VDD1_2_NUM_VOLT_COARSE; - pmic->desc[i].ramp_delay = 12500; } else if (i == TPS65910_REG_VDD3) { - if (tps65910_chip_id(tps65910) == TPS65910) { + if (tps65910_chip_id(tps65910) == TPS65910) pmic->desc[i].ops = &tps65910_ops_vdd3; - pmic->desc[i].volt_table = info->voltage_table; - } else { + else pmic->desc[i].ops = &tps65910_ops_dcdc; - pmic->desc[i].ramp_delay = 5000; - } } else { - if (tps65910_chip_id(tps65910) == TPS65910) { + if (tps65910_chip_id(tps65910) == TPS65910) pmic->desc[i].ops = &tps65910_ops; - pmic->desc[i].volt_table = info->voltage_table; - } else { + else pmic->desc[i].ops = &tps65911_ops; - } } err = tps65910_set_ext_sleep_config(pmic, i, diff --git a/trunk/drivers/regulator/twl-regulator.c b/trunk/drivers/regulator/twl-regulator.c index 242fe90dc565..c7390711d954 100644 --- a/trunk/drivers/regulator/twl-regulator.c +++ b/trunk/drivers/regulator/twl-regulator.c @@ -43,6 +43,9 @@ struct twlreg_info { u8 table_len; const u16 *table; + /* regulator specific turn-on delay */ + u16 delay; + /* State REMAP default configuration */ u8 remap; @@ -220,6 +223,20 @@ static int twl6030reg_enable(struct regulator_dev *rdev) return ret; } +static int twl4030reg_enable_time(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + + return info->delay; +} + +static int twl6030reg_enable_time(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + + return info->delay; +} + static int twl4030reg_disable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); @@ -491,6 +508,7 @@ static struct regulator_ops twl4030ldo_ops = { .enable = twl4030reg_enable, .disable = twl4030reg_disable, .is_enabled = twl4030reg_is_enabled, + .enable_time = twl4030reg_enable_time, .set_mode = twl4030reg_set_mode, @@ -559,53 +577,59 @@ static struct regulator_ops twl6030coresmps_ops = { .get_voltage = twl6030coresmps_get_voltage, }; -static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) +static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) { - struct twlreg_info *info = rdev_get_drvdata(rdev); + struct twlreg_info *info = rdev_get_drvdata(rdev); - switch (sel) { - case 0: - return 0; - case 1 ... 24: - /* Linear mapping from 00000001 to 00011000: - * Absolute voltage value = 1.0 V + 0.1 V × (sel – 00000001) - */ - return (info->min_mV + 100 * (sel - 1)) * 1000; - case 25 ... 30: - return -EINVAL; - case 31: - return 2750000; - default: - return -EINVAL; - } + return ((info->min_mV + (index * 100)) * 1000); } static int -twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) +twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned *selector) { struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel; + + if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV)) + return -EDOM; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + vsel = (min_uV/1000 - 1000)/100 + 1; + *selector = vsel; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); - return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, - selector); } -static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev) +static int twl6030ldo_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); - int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE); + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, + VREG_VOLTAGE); + + if (vsel < 0) + return vsel; - return vsel; + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + return (1000 + (100 * (vsel - 1))) * 1000; } static struct regulator_ops twl6030ldo_ops = { .list_voltage = twl6030ldo_list_voltage, - .set_voltage_sel = twl6030ldo_set_voltage_sel, - .get_voltage_sel = twl6030ldo_get_voltage_sel, + .set_voltage = twl6030ldo_set_voltage, + .get_voltage = twl6030ldo_get_voltage, .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -639,6 +663,7 @@ static struct regulator_ops twl4030fixed_ops = { .enable = twl4030reg_enable, .disable = twl4030reg_disable, .is_enabled = twl4030reg_is_enabled, + .enable_time = twl4030reg_enable_time, .set_mode = twl4030reg_set_mode, @@ -653,6 +678,7 @@ static struct regulator_ops twl6030fixed_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -663,6 +689,7 @@ static struct regulator_ops twl6030_fixed_resource = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .get_status = twl6030reg_get_status, }; @@ -859,6 +886,7 @@ static struct regulator_ops twlsmps_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -881,6 +909,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ .table = label##_VSEL_table, \ + .delay = turnon_delay, \ .remap = remap_conf, \ .desc = { \ .name = #label, \ @@ -889,7 +918,6 @@ static struct twlreg_info TWL4030_INFO_##label = { \ .ops = &twl4030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .enable_time = turnon_delay, \ }, \ } @@ -897,6 +925,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \ static struct twlreg_info TWL4030_INFO_##label = { \ .base = offset, \ .id = num, \ + .delay = turnon_delay, \ .remap = remap_conf, \ .desc = { \ .name = #label, \ @@ -904,7 +933,6 @@ static struct twlreg_info TWL4030_INFO_##label = { \ .ops = &twl4030smps_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .enable_time = turnon_delay, \ }, \ } @@ -927,7 +955,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \ .desc = { \ .name = #label, \ .id = TWL6030_REG_##label, \ - .n_voltages = 32, \ + .n_voltages = (max_mVolts - min_mVolts)/100 + 1, \ .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ @@ -942,7 +970,7 @@ static struct twlreg_info TWL6025_INFO_##label = { \ .desc = { \ .name = #label, \ .id = TWL6025_REG_##label, \ - .n_voltages = 32, \ + .n_voltages = ((max_mVolts - min_mVolts)/100) + 1, \ .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ @@ -955,6 +983,7 @@ static struct twlreg_info TWLFIXED_INFO_##label = { \ .base = offset, \ .id = num, \ .min_mV = mVolts, \ + .delay = turnon_delay, \ .remap = remap_conf, \ .desc = { \ .name = #label, \ @@ -963,20 +992,19 @@ static struct twlreg_info TWLFIXED_INFO_##label = { \ .ops = &operations, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .enable_time = turnon_delay, \ }, \ } #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \ static struct twlreg_info TWLRES_INFO_##label = { \ .base = offset, \ + .delay = turnon_delay, \ .desc = { \ .name = #label, \ .id = TWL6030_REG_##label, \ .ops = &twl6030_fixed_resource, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .enable_time = turnon_delay, \ }, \ } @@ -1081,6 +1109,7 @@ static u8 twl_get_smps_mult(void) #define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label) #define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label) #define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label) +#define TWLRES_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLRES, label) #define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label) static const struct of_device_id twl_of_match[] __devinitconst = { @@ -1128,6 +1157,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = { TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB), TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8), TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1), + TWLRES_OF_MATCH("ti,twl6030-clk32kg", CLK32KG), TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3), TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4), TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO), diff --git a/trunk/drivers/regulator/wm831x-dcdc.c b/trunk/drivers/regulator/wm831x-dcdc.c index 7413885be01b..099da11e989f 100644 --- a/trunk/drivers/regulator/wm831x-dcdc.c +++ b/trunk/drivers/regulator/wm831x-dcdc.c @@ -215,8 +215,8 @@ static int wm831x_buckv_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_buckv_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) { u16 vsel; @@ -251,14 +251,20 @@ static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) return 0; } -static int wm831x_buckv_set_voltage_sel(struct regulator_dev *rdev, - unsigned vsel) +static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); struct wm831x *wm831x = dcdc->wm831x; int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG; int dvs_reg = dcdc->base + WM831X_DCDC_DVS_CONTROL; - int ret; + int vsel, ret; + + vsel = wm831x_buckv_select_min_voltage(rdev, min_uV, max_uV); + if (vsel < 0) + return vsel; + + *selector = vsel; /* If this value is already set then do a GPIO update if we can */ if (dcdc->dvs_gpio && dcdc->on_vsel == vsel) @@ -309,7 +315,7 @@ static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; int vsel; - vsel = wm831x_buckv_map_voltage(rdev, uV, uV); + vsel = wm831x_buckv_select_min_voltage(rdev, uV, uV); if (vsel < 0) return vsel; @@ -367,10 +373,9 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) } static struct regulator_ops wm831x_buckv_ops = { - .set_voltage_sel = wm831x_buckv_set_voltage_sel, + .set_voltage = wm831x_buckv_set_voltage, .get_voltage_sel = wm831x_buckv_get_voltage_sel, .list_voltage = wm831x_buckv_list_voltage, - .map_voltage = wm831x_buckv_map_voltage, .set_suspend_voltage = wm831x_buckv_set_suspend_voltage, .set_current_limit = wm831x_buckv_set_current_limit, .get_current_limit = wm831x_buckv_get_current_limit, @@ -594,25 +599,60 @@ static struct platform_driver wm831x_buckv_driver = { * BUCKP specifics */ -static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, int uV) +static int wm831x_buckp_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector <= WM831X_BUCKP_MAX_SELECTOR) + return 850000 + (selector * 25000); + else + return -EINVAL; +} + +static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, + int min_uV, int max_uV, int *selector) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); struct wm831x *wm831x = dcdc->wm831x; - u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; - int sel; + u16 vsel; + + if (min_uV <= 34000000) + vsel = (min_uV - 850000) / 25000; + else + return -EINVAL; - sel = regulator_map_voltage_linear(rdev, uV, uV); - if (sel < 0) - return sel; + if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV) + return -EINVAL; + + *selector = vsel; + + return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel); +} + +static int wm831x_buckp_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; + + return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV, + selector); +} + +static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, + int uV) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; + unsigned selector; - return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, sel); + return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector); } static struct regulator_ops wm831x_buckp_ops = { - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage = wm831x_buckp_set_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .list_voltage = wm831x_buckp_list_voltage, .set_suspend_voltage = wm831x_buckp_set_suspend_voltage, .is_enabled = regulator_is_enabled_regmap, @@ -675,8 +715,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) dcdc->desc.vsel_mask = WM831X_DC3_ON_VSEL_MASK; dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; dcdc->desc.enable_mask = 1 << id; - dcdc->desc.min_uV = 850000; - dcdc->desc.uV_step = 25000; config.dev = pdev->dev.parent; if (pdata) diff --git a/trunk/drivers/regulator/wm831x-ldo.c b/trunk/drivers/regulator/wm831x-ldo.c index 5cb70ca1e98d..a9a28d8ac185 100644 --- a/trunk/drivers/regulator/wm831x-ldo.c +++ b/trunk/drivers/regulator/wm831x-ldo.c @@ -78,10 +78,13 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_gp_ldo_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, + int min_uV, int max_uV, + unsigned *selector) { - int volt, vsel; + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int vsel, ret; if (min_uV < 900000) vsel = 0; @@ -91,25 +94,36 @@ static int wm831x_gp_ldo_map_voltage(struct regulator_dev *rdev, vsel = ((min_uV - 1700000) / 100000) + WM831X_GP_LDO_SELECTOR_LOW + 1; - volt = wm831x_gp_ldo_list_voltage(rdev, vsel); - if (volt < min_uV || volt > max_uV) + ret = wm831x_gp_ldo_list_voltage(rdev, vsel); + if (ret < 0) + return ret; + if (ret < min_uV || ret > max_uV) return -EINVAL; - return vsel; + *selector = vsel; + + return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, vsel); +} + +static int wm831x_gp_ldo_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + int reg = ldo->base + WM831X_LDO_ON_CONTROL; + + return wm831x_gp_ldo_set_voltage_int(rdev, reg, min_uV, max_uV, + selector); } static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - struct wm831x *wm831x = ldo->wm831x; - int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; + int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; + unsigned int selector; - sel = wm831x_gp_ldo_map_voltage(rdev, uV, uV); - if (sel < 0) - return sel; - - return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, sel); + return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); } static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev) @@ -229,9 +243,8 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev, static struct regulator_ops wm831x_gp_ldo_ops = { .list_voltage = wm831x_gp_ldo_list_voltage, - .map_voltage = wm831x_gp_ldo_map_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage = wm831x_gp_ldo_set_voltage, .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage, .get_mode = wm831x_gp_ldo_get_mode, .set_mode = wm831x_gp_ldo_set_mode, @@ -371,10 +384,13 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_aldo_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg, + int min_uV, int max_uV, + unsigned *selector) { - int volt, vsel; + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int vsel, ret; if (min_uV < 1000000) vsel = 0; @@ -384,26 +400,35 @@ static int wm831x_aldo_map_voltage(struct regulator_dev *rdev, vsel = ((min_uV - 1700000) / 100000) + WM831X_ALDO_SELECTOR_LOW + 1; - volt = wm831x_aldo_list_voltage(rdev, vsel); - if (volt < min_uV || volt > max_uV) + ret = wm831x_aldo_list_voltage(rdev, vsel); + if (ret < 0) + return ret; + if (ret < min_uV || ret > max_uV) return -EINVAL; - return vsel; + *selector = vsel; + + return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, vsel); +} + +static int wm831x_aldo_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + int reg = ldo->base + WM831X_LDO_ON_CONTROL; + return wm831x_aldo_set_voltage_int(rdev, reg, min_uV, max_uV, + selector); } static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - struct wm831x *wm831x = ldo->wm831x; - int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; - - sel = wm831x_aldo_map_voltage(rdev, uV, uV); - if (sel < 0) - return sel; + int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; + unsigned int selector; - return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, sel); + return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector); } static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) @@ -481,9 +506,8 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev) static struct regulator_ops wm831x_aldo_ops = { .list_voltage = wm831x_aldo_list_voltage, - .map_voltage = wm831x_aldo_map_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage = wm831x_aldo_set_voltage, .set_suspend_voltage = wm831x_aldo_set_suspend_voltage, .get_mode = wm831x_aldo_get_mode, .set_mode = wm831x_aldo_set_mode, @@ -604,18 +628,47 @@ static struct platform_driver wm831x_aldo_driver = { #define WM831X_ALIVE_LDO_MAX_SELECTOR 0xf -static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, - int uV) +static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, + int reg, + int min_uV, int max_uV, + unsigned *selector) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; - int sel, reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL; + int vsel, ret; + + vsel = (min_uV - 800000) / 50000; - sel = regulator_map_voltage_linear(rdev, uV, uV); - if (sel < 0) - return sel; + ret = regulator_list_voltage_linear(rdev, vsel); + if (ret < 0) + return ret; + if (ret < min_uV || ret > max_uV) + return -EINVAL; + + *selector = vsel; + + return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, vsel); +} + +static int wm831x_alive_ldo_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL; + + return wm831x_alive_ldo_set_voltage_int(rdev, reg, min_uV, max_uV, + selector); +} + +static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, + int uV) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + int reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL; + unsigned selector; - return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, sel); + return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); } static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) @@ -637,9 +690,8 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) static struct regulator_ops wm831x_alive_ldo_ops = { .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage = wm831x_alive_ldo_set_voltage, .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage, .get_status = wm831x_alive_ldo_get_status, @@ -701,7 +753,6 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) ldo->desc.enable_mask = 1 << id; ldo->desc.min_uV = 800000; ldo->desc.uV_step = 50000; - ldo->desc.enable_time = 1000; config.dev = pdev->dev.parent; if (pdata) diff --git a/trunk/drivers/regulator/wm8350-regulator.c b/trunk/drivers/regulator/wm8350-regulator.c index 7f0fa22ef2aa..94e550dc70b6 100644 --- a/trunk/drivers/regulator/wm8350-regulator.c +++ b/trunk/drivers/regulator/wm8350-regulator.c @@ -108,6 +108,33 @@ static int get_isink_val(int min_uA, int max_uA, u16 *setting) return -EINVAL; } +static inline int wm8350_ldo_val_to_mvolts(unsigned int val) +{ + if (val < 16) + return (val * 50) + 900; + else + return ((val - 16) * 100) + 1800; + +} + +static inline unsigned int wm8350_ldo_mvolts_to_val(int mV) +{ + if (mV < 1800) + return (mV - 900) / 50; + else + return ((mV - 1800) / 100) + 16; +} + +static inline int wm8350_dcdc_val_to_mvolts(unsigned int val) +{ + return (val * 25) + 850; +} + +static inline unsigned int wm8350_dcdc_mvolts_to_val(int mV) +{ + return (mV - 850) / 25; +} + static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA, int max_uA) { @@ -332,13 +359,104 @@ int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode, } EXPORT_SYMBOL_GPL(wm8350_isink_set_flash); +static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned *selector) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int volt_reg, dcdc = rdev_get_id(rdev), mV, + min_mV = min_uV / 1000, max_mV = max_uV / 1000; + u16 val; + + if (min_mV < 850 || min_mV > 4025) + return -EINVAL; + if (max_mV < 850 || max_mV > 4025) + return -EINVAL; + + /* step size is 25mV */ + mV = (min_mV - 826) / 25; + if (wm8350_dcdc_val_to_mvolts(mV) > max_mV) + return -EINVAL; + BUG_ON(wm8350_dcdc_val_to_mvolts(mV) < min_mV); + + switch (dcdc) { + case WM8350_DCDC_1: + volt_reg = WM8350_DCDC1_CONTROL; + break; + case WM8350_DCDC_3: + volt_reg = WM8350_DCDC3_CONTROL; + break; + case WM8350_DCDC_4: + volt_reg = WM8350_DCDC4_CONTROL; + break; + case WM8350_DCDC_6: + volt_reg = WM8350_DCDC6_CONTROL; + break; + case WM8350_DCDC_2: + case WM8350_DCDC_5: + default: + return -EINVAL; + } + + *selector = mV; + + /* all DCDCs have same mV bits */ + val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; + wm8350_reg_write(wm8350, volt_reg, val | mV); + return 0; +} + +static int wm8350_dcdc_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int volt_reg, dcdc = rdev_get_id(rdev); + + switch (dcdc) { + case WM8350_DCDC_1: + volt_reg = WM8350_DCDC1_CONTROL; + break; + case WM8350_DCDC_3: + volt_reg = WM8350_DCDC3_CONTROL; + break; + case WM8350_DCDC_4: + volt_reg = WM8350_DCDC4_CONTROL; + break; + case WM8350_DCDC_6: + volt_reg = WM8350_DCDC6_CONTROL; + break; + case WM8350_DCDC_2: + case WM8350_DCDC_5: + default: + return -EINVAL; + } + + /* all DCDCs have same mV bits */ + return wm8350_reg_read(wm8350, volt_reg) & WM8350_DC1_VSEL_MASK; +} + +static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector > WM8350_DCDC_MAX_VSEL) + return -EINVAL; + return wm8350_dcdc_val_to_mvolts(selector) * 1000; +} + static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int sel, volt_reg, dcdc = rdev_get_id(rdev); + int volt_reg, mV = uV / 1000, dcdc = rdev_get_id(rdev); u16 val; - dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000); + dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, mV); + + if (mV && (mV < 850 || mV > 4025)) { + dev_err(wm8350->dev, + "DCDC%d suspend voltage %d mV out of range\n", + dcdc, mV); + return -EINVAL; + } + if (mV == 0) + mV = 850; switch (dcdc) { case WM8350_DCDC_1: @@ -359,13 +477,10 @@ static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) return -EINVAL; } - sel = regulator_map_voltage_linear(rdev, uV, uV); - if (sel < 0) - return -EINVAL; - /* all DCDCs have same mV bits */ val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, val | sel); + wm8350_reg_write(wm8350, volt_reg, + val | wm8350_dcdc_mvolts_to_val(mV)); return 0; } @@ -542,49 +657,19 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev, return 0; } -static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector > WM8350_LDO1_VSEL_MASK) - return -EINVAL; - - if (selector < 16) - return (selector * 50000) + 900000; - else - return ((selector - 16) * 100000) + 1800000; -} - -static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV) -{ - int volt, sel; - int min_mV = min_uV / 1000; - int max_mV = max_uV / 1000; - - if (min_mV < 900 || min_mV > 3300) - return -EINVAL; - if (max_mV < 900 || max_mV > 3300) - return -EINVAL; - - if (min_mV < 1800) /* step size is 50mV < 1800mV */ - sel = DIV_ROUND_UP(min_uV - 900, 50); - else /* step size is 100mV > 1800mV */ - sel = DIV_ROUND_UP(min_uV - 1800, 100) + 16; - - volt = wm8350_ldo_list_voltage(rdev, sel); - if (volt < min_uV || volt > max_uV) - return -EINVAL; - - return sel; -} - static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int sel, volt_reg, ldo = rdev_get_id(rdev); + int volt_reg, mV = uV / 1000, ldo = rdev_get_id(rdev); u16 val; - dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000); + dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, mV); + + if (mV < 900 || mV > 3300) { + dev_err(wm8350->dev, "LDO%d voltage %d mV out of range\n", + ldo, mV); + return -EINVAL; + } switch (ldo) { case WM8350_LDO_1: @@ -603,13 +688,10 @@ static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) return -EINVAL; } - sel = wm8350_ldo_map_voltage(rdev, uV, uV); - if (sel < 0) - return -EINVAL; - /* all LDOs have same mV bits */ val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, val | sel); + wm8350_reg_write(wm8350, volt_reg, + val | wm8350_ldo_mvolts_to_val(mV)); return 0; } @@ -671,6 +753,92 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) return 0; } +static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned *selector) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int volt_reg, ldo = rdev_get_id(rdev), mV, min_mV = min_uV / 1000, + max_mV = max_uV / 1000; + u16 val; + + if (min_mV < 900 || min_mV > 3300) + return -EINVAL; + if (max_mV < 900 || max_mV > 3300) + return -EINVAL; + + if (min_mV < 1800) { + /* step size is 50mV < 1800mV */ + mV = (min_mV - 851) / 50; + if (wm8350_ldo_val_to_mvolts(mV) > max_mV) + return -EINVAL; + BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); + } else { + /* step size is 100mV > 1800mV */ + mV = ((min_mV - 1701) / 100) + 16; + if (wm8350_ldo_val_to_mvolts(mV) > max_mV) + return -EINVAL; + BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); + } + + switch (ldo) { + case WM8350_LDO_1: + volt_reg = WM8350_LDO1_CONTROL; + break; + case WM8350_LDO_2: + volt_reg = WM8350_LDO2_CONTROL; + break; + case WM8350_LDO_3: + volt_reg = WM8350_LDO3_CONTROL; + break; + case WM8350_LDO_4: + volt_reg = WM8350_LDO4_CONTROL; + break; + default: + return -EINVAL; + } + + *selector = mV; + + /* all LDOs have same mV bits */ + val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; + wm8350_reg_write(wm8350, volt_reg, val | mV); + return 0; +} + +static int wm8350_ldo_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int volt_reg, ldo = rdev_get_id(rdev); + + switch (ldo) { + case WM8350_LDO_1: + volt_reg = WM8350_LDO1_CONTROL; + break; + case WM8350_LDO_2: + volt_reg = WM8350_LDO2_CONTROL; + break; + case WM8350_LDO_3: + volt_reg = WM8350_LDO3_CONTROL; + break; + case WM8350_LDO_4: + volt_reg = WM8350_LDO4_CONTROL; + break; + default: + return -EINVAL; + } + + /* all LDOs have same mV bits */ + return wm8350_reg_read(wm8350, volt_reg) & WM8350_LDO1_VSEL_MASK; +} + +static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector > WM8350_LDO1_VSEL_MASK) + return -EINVAL; + return wm8350_ldo_val_to_mvolts(selector) * 1000; +} + int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start, u16 stop, u16 fault) { @@ -791,6 +959,63 @@ int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode, } EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode); +static int wm8350_dcdc_enable(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int dcdc = rdev_get_id(rdev); + u16 shift; + + if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) + return -EINVAL; + + shift = dcdc - WM8350_DCDC_1; + wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); + return 0; +} + +static int wm8350_dcdc_disable(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int dcdc = rdev_get_id(rdev); + u16 shift; + + if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) + return -EINVAL; + + shift = dcdc - WM8350_DCDC_1; + wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); + + return 0; +} + +static int wm8350_ldo_enable(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int ldo = rdev_get_id(rdev); + u16 shift; + + if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) + return -EINVAL; + + shift = (ldo - WM8350_LDO_1) + 8; + wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); + return 0; +} + +static int wm8350_ldo_disable(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int ldo = rdev_get_id(rdev); + u16 shift; + + if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) + return -EINVAL; + + shift = (ldo - WM8350_LDO_1) + 8; + wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); + return 0; +} + static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable) { int reg = 0, ret; @@ -972,17 +1197,42 @@ static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev, return mode; } +static int wm8350_dcdc_is_enabled(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int dcdc = rdev_get_id(rdev), shift; + + if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) + return -EINVAL; + + shift = dcdc - WM8350_DCDC_1; + return wm8350_reg_read(wm8350, WM8350_DCDC_LDO_REQUESTED) + & (1 << shift); +} + +static int wm8350_ldo_is_enabled(struct regulator_dev *rdev) +{ + struct wm8350 *wm8350 = rdev_get_drvdata(rdev); + int ldo = rdev_get_id(rdev), shift; + + if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) + return -EINVAL; + + shift = (ldo - WM8350_LDO_1) + 8; + return wm8350_reg_read(wm8350, WM8350_DCDC_LDO_REQUESTED) + & (1 << shift); +} + static struct regulator_ops wm8350_dcdc_ops = { - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .set_voltage = wm8350_dcdc_set_voltage, + .get_voltage_sel = wm8350_dcdc_get_voltage_sel, + .list_voltage = wm8350_dcdc_list_voltage, + .enable = wm8350_dcdc_enable, + .disable = wm8350_dcdc_disable, .get_mode = wm8350_dcdc_get_mode, .set_mode = wm8350_dcdc_set_mode, .get_optimum_mode = wm8350_dcdc_get_optimum_mode, + .is_enabled = wm8350_dcdc_is_enabled, .set_suspend_voltage = wm8350_dcdc_set_suspend_voltage, .set_suspend_enable = wm8350_dcdc_set_suspend_enable, .set_suspend_disable = wm8350_dcdc_set_suspend_disable, @@ -990,21 +1240,20 @@ static struct regulator_ops wm8350_dcdc_ops = { }; static struct regulator_ops wm8350_dcdc2_5_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .enable = wm8350_dcdc_enable, + .disable = wm8350_dcdc_disable, + .is_enabled = wm8350_dcdc_is_enabled, .set_suspend_enable = wm8350_dcdc25_set_suspend_enable, .set_suspend_disable = wm8350_dcdc25_set_suspend_disable, }; static struct regulator_ops wm8350_ldo_ops = { - .map_voltage = wm8350_ldo_map_voltage, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage = wm8350_ldo_set_voltage, + .get_voltage_sel = wm8350_ldo_get_voltage_sel, .list_voltage = wm8350_ldo_list_voltage, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .enable = wm8350_ldo_enable, + .disable = wm8350_ldo_disable, + .is_enabled = wm8350_ldo_is_enabled, .get_mode = wm8350_ldo_get_mode, .set_suspend_voltage = wm8350_ldo_set_suspend_voltage, .set_suspend_enable = wm8350_ldo_set_suspend_enable, @@ -1028,12 +1277,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC1, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, - .min_uV = 850000, - .uV_step = 25000, - .vsel_reg = WM8350_DCDC1_CONTROL, - .vsel_mask = WM8350_DC1_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_DC1_ENA, .owner = THIS_MODULE, }, { @@ -1042,8 +1285,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .ops = &wm8350_dcdc2_5_ops, .irq = WM8350_IRQ_UV_DC2, .type = REGULATOR_VOLTAGE, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_DC2_ENA, .owner = THIS_MODULE, }, { @@ -1053,12 +1294,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC3, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, - .min_uV = 850000, - .uV_step = 25000, - .vsel_reg = WM8350_DCDC3_CONTROL, - .vsel_mask = WM8350_DC3_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_DC3_ENA, .owner = THIS_MODULE, }, { @@ -1068,12 +1303,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC4, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, - .min_uV = 850000, - .uV_step = 25000, - .vsel_reg = WM8350_DCDC4_CONTROL, - .vsel_mask = WM8350_DC4_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_DC4_ENA, .owner = THIS_MODULE, }, { @@ -1082,8 +1311,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .ops = &wm8350_dcdc2_5_ops, .irq = WM8350_IRQ_UV_DC5, .type = REGULATOR_VOLTAGE, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_DC5_ENA, .owner = THIS_MODULE, }, { @@ -1093,12 +1320,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC6, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, - .min_uV = 850000, - .uV_step = 25000, - .vsel_reg = WM8350_DCDC6_CONTROL, - .vsel_mask = WM8350_DC6_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_DC6_ENA, .owner = THIS_MODULE, }, { @@ -1108,10 +1329,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO1, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO1_VSEL_MASK + 1, - .vsel_reg = WM8350_LDO1_CONTROL, - .vsel_mask = WM8350_LDO1_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_LDO1_ENA, .owner = THIS_MODULE, }, { @@ -1121,10 +1338,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO2, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO2_VSEL_MASK + 1, - .vsel_reg = WM8350_LDO2_CONTROL, - .vsel_mask = WM8350_LDO2_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_LDO2_ENA, .owner = THIS_MODULE, }, { @@ -1134,10 +1347,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO3, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO3_VSEL_MASK + 1, - .vsel_reg = WM8350_LDO3_CONTROL, - .vsel_mask = WM8350_LDO3_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_LDO3_ENA, .owner = THIS_MODULE, }, { @@ -1147,10 +1356,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO4, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO4_VSEL_MASK + 1, - .vsel_reg = WM8350_LDO4_CONTROL, - .vsel_mask = WM8350_LDO4_VSEL_MASK, - .enable_reg = WM8350_DCDC_LDO_REQUESTED, - .enable_mask = WM8350_LDO4_ENA, .owner = THIS_MODULE, }, { @@ -1224,7 +1429,6 @@ static int wm8350_regulator_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.init_data = pdev->dev.platform_data; config.driver_data = dev_get_drvdata(&pdev->dev); - config.regmap = wm8350->regmap; /* register regulator */ rdev = regulator_register(&wm8350_reg[pdev->id], &config); diff --git a/trunk/drivers/regulator/wm8400-regulator.c b/trunk/drivers/regulator/wm8400-regulator.c index 9035dd053611..69a2b7ce5e4a 100644 --- a/trunk/drivers/regulator/wm8400-regulator.c +++ b/trunk/drivers/regulator/wm8400-regulator.c @@ -28,26 +28,34 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev, if (selector < 15) return 900000 + (selector * 50000); else - return 1700000 + ((selector - 15) * 100000); + return 1600000 + ((selector - 14) * 100000); } static int wm8400_ldo_map_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { u16 val; - int volt; if (min_uV < 900000 || min_uV > 3300000) return -EINVAL; - if (min_uV < 1700000) /* Steps of 50mV from 900mV; */ + if (min_uV < 1700000) { + /* Steps of 50mV from 900mV; */ val = DIV_ROUND_UP(min_uV - 900000, 50000); - else /* Steps of 100mV from 1700mV */ - val = DIV_ROUND_UP(min_uV - 1700000, 100000) + 15; - volt = wm8400_ldo_list_voltage(dev, val); - if (volt < min_uV || volt > max_uV) - return -EINVAL; + if ((val * 50000) + 900000 > max_uV) + return -EINVAL; + BUG_ON((val * 50000) + 900000 < min_uV); + } else { + /* Steps of 100mV from 1700mV */ + val = DIV_ROUND_UP(min_uV - 1700000, 100000); + + if ((val * 100000) + 1700000 > max_uV) + return -EINVAL; + BUG_ON((val * 100000) + 1700000 < min_uV); + + val += 0xf; + } return val; } @@ -144,7 +152,6 @@ static struct regulator_ops wm8400_dcdc_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_mode = wm8400_dcdc_get_mode, diff --git a/trunk/drivers/regulator/wm8994-regulator.c b/trunk/drivers/regulator/wm8994-regulator.c index 86bb48db149e..9a994316e63c 100644 --- a/trunk/drivers/regulator/wm8994-regulator.c +++ b/trunk/drivers/regulator/wm8994-regulator.c @@ -26,6 +26,8 @@ #include struct wm8994_ldo { + int enable; + bool is_enabled; struct regulator_dev *regulator; struct wm8994 *wm8994; }; @@ -33,9 +35,64 @@ struct wm8994_ldo { #define WM8994_LDO1_MAX_SELECTOR 0x7 #define WM8994_LDO2_MAX_SELECTOR 0x3 +static int wm8994_ldo_enable(struct regulator_dev *rdev) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + + /* If we have no soft control assume that the LDO is always enabled. */ + if (!ldo->enable) + return 0; + + gpio_set_value_cansleep(ldo->enable, 1); + ldo->is_enabled = true; + + return 0; +} + +static int wm8994_ldo_disable(struct regulator_dev *rdev) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + + /* If we have no soft control assume that the LDO is always enabled. */ + if (!ldo->enable) + return -EINVAL; + + gpio_set_value_cansleep(ldo->enable, 0); + ldo->is_enabled = false; + + return 0; +} + +static int wm8994_ldo_is_enabled(struct regulator_dev *rdev) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + + return ldo->is_enabled; +} + +static int wm8994_ldo_enable_time(struct regulator_dev *rdev) +{ + /* 3ms is fairly conservative but this shouldn't be too performance + * critical; can be tweaked per-system if required. */ + return 3000; +} + +static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector > WM8994_LDO1_MAX_SELECTOR) + return -EINVAL; + + return (selector * 100000) + 2400000; +} + static struct regulator_ops wm8994_ldo1_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .enable = wm8994_ldo_enable, + .disable = wm8994_ldo_disable, + .is_enabled = wm8994_ldo_is_enabled, + .enable_time = wm8994_ldo_enable_time, + + .list_voltage = wm8994_ldo1_list_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, }; @@ -67,6 +124,11 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, } static struct regulator_ops wm8994_ldo2_ops = { + .enable = wm8994_ldo_enable, + .disable = wm8994_ldo_disable, + .is_enabled = wm8994_ldo_is_enabled, + .enable_time = wm8994_ldo_enable_time, + .list_voltage = wm8994_ldo2_list_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -81,9 +143,6 @@ static const struct regulator_desc wm8994_ldo_desc[] = { .vsel_reg = WM8994_LDO_1, .vsel_mask = WM8994_LDO1_VSEL_MASK, .ops = &wm8994_ldo1_ops, - .min_uV = 2400000, - .uV_step = 100000, - .enable_time = 3000, .owner = THIS_MODULE, }, { @@ -94,7 +153,6 @@ static const struct regulator_desc wm8994_ldo_desc[] = { .vsel_reg = WM8994_LDO_2, .vsel_mask = WM8994_LDO2_VSEL_MASK, .ops = &wm8994_ldo2_ops, - .enable_time = 3000, .owner = THIS_MODULE, }, }; @@ -118,26 +176,39 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) ldo->wm8994 = wm8994; + if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) { + ldo->enable = pdata->ldo[id].enable; + + ret = gpio_request_one(ldo->enable, 0, "WM8994 LDO enable"); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", + ret); + goto err; + } + } else + ldo->is_enabled = true; + config.dev = wm8994->dev; config.driver_data = ldo; config.regmap = wm8994->regmap; - if (pdata) { + if (pdata) config.init_data = pdata->ldo[id].init_data; - config.ena_gpio = pdata->ldo[id].enable; - } ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm8994->dev, "Failed to register LDO%d: %d\n", id + 1, ret); - goto err; + goto err_gpio; } platform_set_drvdata(pdev, ldo); return 0; +err_gpio: + if (gpio_is_valid(ldo->enable)) + gpio_free(ldo->enable); err: return ret; } @@ -149,6 +220,8 @@ static __devexit int wm8994_ldo_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); regulator_unregister(ldo->regulator); + if (gpio_is_valid(ldo->enable)) + gpio_free(ldo->enable); return 0; } diff --git a/trunk/drivers/remoteproc/Kconfig b/trunk/drivers/remoteproc/Kconfig index f8d818abf98c..24d880e78ec6 100644 --- a/trunk/drivers/remoteproc/Kconfig +++ b/trunk/drivers/remoteproc/Kconfig @@ -4,11 +4,9 @@ menu "Remoteproc drivers (EXPERIMENTAL)" config REMOTEPROC tristate depends on EXPERIMENTAL - select FW_CONFIG config OMAP_REMOTEPROC tristate "OMAP remoteproc support" - depends on EXPERIMENTAL depends on ARCH_OMAP4 depends on OMAP_IOMMU select REMOTEPROC diff --git a/trunk/drivers/remoteproc/omap_remoteproc.c b/trunk/drivers/remoteproc/omap_remoteproc.c index de138e30d3e6..69425c4e86f3 100644 --- a/trunk/drivers/remoteproc/omap_remoteproc.c +++ b/trunk/drivers/remoteproc/omap_remoteproc.c @@ -182,7 +182,7 @@ static int __devinit omap_rproc_probe(struct platform_device *pdev) ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret); + dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); return ret; } diff --git a/trunk/drivers/remoteproc/remoteproc_core.c b/trunk/drivers/remoteproc/remoteproc_core.c index 66324ee4678f..8ea7bccc7100 100644 --- a/trunk/drivers/remoteproc/remoteproc_core.c +++ b/trunk/drivers/remoteproc/remoteproc_core.c @@ -247,7 +247,7 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) } if (offset + filesz > len) { - dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", + dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", offset + filesz, len); ret = -EINVAL; break; @@ -934,7 +934,7 @@ static void rproc_resource_cleanup(struct rproc *rproc) unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); if (unmapped != entry->len) { /* nothing much to do besides complaining */ - dev_err(dev, "failed to unmap %u/%zu\n", entry->len, + dev_err(dev, "failed to unmap %u/%u\n", entry->len, unmapped); } @@ -1020,7 +1020,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) ehdr = (struct elf32_hdr *)fw->data; - dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size); + dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); /* * if enabling an IOMMU isn't relevant for this rproc, this is @@ -1041,10 +1041,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) /* look for the resource table */ table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); - if (!table) { - ret = -EINVAL; + if (!table) goto clean_up; - } /* handle fw resources which are required to boot rproc */ ret = rproc_handle_boot_rsc(rproc, table, tablesz); diff --git a/trunk/drivers/rpmsg/virtio_rpmsg_bus.c b/trunk/drivers/rpmsg/virtio_rpmsg_bus.c index f56c8ba3a861..75506ec2840e 100644 --- a/trunk/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/trunk/drivers/rpmsg/virtio_rpmsg_bus.c @@ -188,26 +188,6 @@ static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env) rpdev->id.name); } -/** - * __ept_release() - deallocate an rpmsg endpoint - * @kref: the ept's reference count - * - * This function deallocates an ept, and is invoked when its @kref refcount - * drops to zero. - * - * Never invoke this function directly! - */ -static void __ept_release(struct kref *kref) -{ - struct rpmsg_endpoint *ept = container_of(kref, struct rpmsg_endpoint, - refcount); - /* - * At this point no one holds a reference to ept anymore, - * so we can directly free it - */ - kfree(ept); -} - /* for more info, see below documentation of rpmsg_create_ept() */ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb, @@ -226,9 +206,6 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, return NULL; } - kref_init(&ept->refcount); - mutex_init(&ept->cb_lock); - ept->rpdev = rpdev; ept->cb = cb; ept->priv = priv; @@ -261,7 +238,7 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, idr_remove(&vrp->endpoints, request); free_ept: mutex_unlock(&vrp->endpoints_lock); - kref_put(&ept->refcount, __ept_release); + kfree(ept); return NULL; } @@ -325,17 +302,11 @@ EXPORT_SYMBOL(rpmsg_create_ept); static void __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept) { - /* make sure new inbound messages can't find this ept anymore */ mutex_lock(&vrp->endpoints_lock); idr_remove(&vrp->endpoints, ept->addr); mutex_unlock(&vrp->endpoints_lock); - /* make sure in-flight inbound messages won't invoke cb anymore */ - mutex_lock(&ept->cb_lock); - ept->cb = NULL; - mutex_unlock(&ept->cb_lock); - - kref_put(&ept->refcount, __ept_release); + kfree(ept); } /** @@ -819,28 +790,12 @@ static void rpmsg_recv_done(struct virtqueue *rvq) /* use the dst addr to fetch the callback of the appropriate user */ mutex_lock(&vrp->endpoints_lock); - ept = idr_find(&vrp->endpoints, msg->dst); - - /* let's make sure no one deallocates ept while we use it */ - if (ept) - kref_get(&ept->refcount); - mutex_unlock(&vrp->endpoints_lock); - if (ept) { - /* make sure ept->cb doesn't go away while we use it */ - mutex_lock(&ept->cb_lock); - - if (ept->cb) - ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, - msg->src); - - mutex_unlock(&ept->cb_lock); - - /* farewell, ept, we don't need you anymore */ - kref_put(&ept->refcount, __ept_release); - } else + if (ept && ept->cb) + ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src); + else dev_warn(dev, "msg received with no recepient\n"); /* publish the real size of the buffer */ @@ -1085,7 +1040,7 @@ static int __init rpmsg_init(void) return ret; } -subsys_initcall(rpmsg_init); +module_init(rpmsg_init); static void __exit rpmsg_fini(void) { diff --git a/trunk/drivers/rtc/rtc-ab8500.c b/trunk/drivers/rtc/rtc-ab8500.c index 370889d0489b..4bcf9ca2818a 100644 --- a/trunk/drivers/rtc/rtc-ab8500.c +++ b/trunk/drivers/rtc/rtc-ab8500.c @@ -17,7 +17,6 @@ #include #include #include -#include #define AB8500_RTC_SOFF_STAT_REG 0x00 #define AB8500_RTC_CC_CONF_REG 0x01 @@ -423,7 +422,7 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev) } err = request_threaded_irq(irq, NULL, rtc_alarm_handler, - IRQF_NO_SUSPEND | IRQF_ONESHOT, "ab8500-rtc", rtc); + IRQF_NO_SUSPEND, "ab8500-rtc", rtc); if (err < 0) { rtc_device_unregister(rtc); return err; @@ -431,6 +430,7 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); + err = ab8500_sysfs_rtc_register(&pdev->dev); if (err) { dev_err(&pdev->dev, "sysfs RTC failed to register\n"); @@ -454,16 +454,10 @@ static int __devexit ab8500_rtc_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id ab8500_rtc_match[] = { - { .compatible = "stericsson,ab8500-rtc", }, - {} -}; - static struct platform_driver ab8500_rtc_driver = { .driver = { .name = "ab8500-rtc", .owner = THIS_MODULE, - .of_match_table = ab8500_rtc_match, }, .probe = ab8500_rtc_probe, .remove = __devexit_p(ab8500_rtc_remove), diff --git a/trunk/drivers/rtc/rtc-cmos.c b/trunk/drivers/rtc/rtc-cmos.c index 132333d75408..7d5f56edb8ef 100644 --- a/trunk/drivers/rtc/rtc-cmos.c +++ b/trunk/drivers/rtc/rtc-cmos.c @@ -568,7 +568,6 @@ static irqreturn_t cmos_interrupt(int irq, void *p) hpet_mask_rtc_irq_bit(RTC_AIE); CMOS_READ(RTC_INTR_FLAGS); - pm_wakeup_event(cmos_rtc.dev, 0); } spin_unlock(&rtc_lock); @@ -911,17 +910,14 @@ static inline int cmos_poweroff(struct device *dev) static u32 rtc_handler(void *context) { - struct device *dev = context; - - pm_wakeup_event(dev, 0); acpi_clear_event(ACPI_EVENT_RTC); acpi_disable_event(ACPI_EVENT_RTC, 0); return ACPI_INTERRUPT_HANDLED; } -static inline void rtc_wake_setup(struct device *dev) +static inline void rtc_wake_setup(void) { - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev); + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); /* * After the RTC handler is installed, the Fixed_RTC event should * be disabled. Only when the RTC alarm is set will it be enabled. @@ -954,7 +950,7 @@ cmos_wake_setup(struct device *dev) if (acpi_disabled) return; - rtc_wake_setup(dev); + rtc_wake_setup(); acpi_rtc_info.wake_on = rtc_wake_on; acpi_rtc_info.wake_off = rtc_wake_off; diff --git a/trunk/drivers/rtc/rtc-mxc.c b/trunk/drivers/rtc/rtc-mxc.c index e3e50d69baf8..5e1d64ee5228 100644 --- a/trunk/drivers/rtc/rtc-mxc.c +++ b/trunk/drivers/rtc/rtc-mxc.c @@ -202,11 +202,10 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) struct platform_device *pdev = dev_id; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - unsigned long flags; u32 status; u32 events = 0; - spin_lock_irqsave(&pdata->rtc->irq_lock, flags); + spin_lock_irq(&pdata->rtc->irq_lock); status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); /* clear interrupt sources */ writew(status, ioaddr + RTC_RTCISR); @@ -225,7 +224,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) events |= (RTC_PF | RTC_IRQF); rtc_update_irq(pdata->rtc, 1, events); - spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); + spin_unlock_irq(&pdata->rtc->irq_lock); return IRQ_HANDLED; } diff --git a/trunk/drivers/rtc/rtc-spear.c b/trunk/drivers/rtc/rtc-spear.c index e2785479113c..1f76320e545b 100644 --- a/trunk/drivers/rtc/rtc-spear.c +++ b/trunk/drivers/rtc/rtc-spear.c @@ -458,12 +458,12 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev) clk_disable(config->clk); clk_put(config->clk); iounmap(config->ioaddr); + kfree(config); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); platform_set_drvdata(pdev, NULL); rtc_device_unregister(config->rtc); - kfree(config); return 0; } diff --git a/trunk/drivers/rtc/rtc-twl.c b/trunk/drivers/rtc/rtc-twl.c index c5d06fe83bba..258abeabf624 100644 --- a/trunk/drivers/rtc/rtc-twl.c +++ b/trunk/drivers/rtc/rtc-twl.c @@ -510,7 +510,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) } ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING, dev_name(&rtc->dev), rtc); if (ret < 0) { dev_err(&pdev->dev, "IRQ is not free.\n"); diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_task.c b/trunk/drivers/scsi/aic94xx/aic94xx_task.c index 393e7ce8e95a..532d212b6b2c 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_task.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_task.c @@ -201,7 +201,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb, if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { resp->frame_len = le16_to_cpu(*(__le16 *)(r+6)); - memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE); + memcpy(&resp->ending_fis[0], r+16, 24); ts->buf_valid_size = sizeof(*resp); } } diff --git a/trunk/drivers/scsi/bnx2i/bnx2i.h b/trunk/drivers/scsi/bnx2i/bnx2i.h index 7e77cf620291..0c53c28dc3d3 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i.h +++ b/trunk/drivers/scsi/bnx2i/bnx2i.h @@ -350,7 +350,6 @@ struct bnx2i_hba { struct pci_dev *pcidev; struct net_device *netdev; void __iomem *regview; - resource_size_t reg_base; u32 age; unsigned long cnic_dev_type; diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c b/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c index 86a12b48e477..ece47e502282 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2724,6 +2724,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) goto arm_cq; } + reg_base = ep->hba->netdev->base_addr; if ((test_bit(BNX2I_NX2_DEV_5709, &ep->hba->cnic_dev_type)) && (ep->hba->mail_queue_access == BNX2I_MQ_BIN_MODE)) { config2 = REG_RD(ep->hba, BNX2_MQ_CONFIG2); @@ -2739,7 +2740,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) /* 5709 device in normal node and 5706/5708 devices */ reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num); - ep->qp.ctx_base = ioremap_nocache(ep->hba->reg_base + reg_off, + ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, MB_KERNEL_CTX_SIZE); if (!ep->qp.ctx_base) return -ENOMEM; diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c b/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c index 621538b8b544..f8d516b53161 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -811,13 +811,13 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) bnx2i_identify_device(hba); bnx2i_setup_host_queue_size(hba, shost); - hba->reg_base = pci_resource_start(hba->pcidev, 0); if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) { - hba->regview = pci_iomap(hba->pcidev, 0, BNX2_MQ_CONFIG2); + hba->regview = ioremap_nocache(hba->netdev->base_addr, + BNX2_MQ_CONFIG2); if (!hba->regview) goto ioreg_map_err; } else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { - hba->regview = pci_iomap(hba->pcidev, 0, 4096); + hba->regview = ioremap_nocache(hba->netdev->base_addr, 4096); if (!hba->regview) goto ioreg_map_err; } @@ -884,7 +884,7 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) bnx2i_free_mp_bdt(hba); mp_bdt_mem_err: if (hba->regview) { - pci_iounmap(hba->pcidev, hba->regview); + iounmap(hba->regview); hba->regview = NULL; } ioreg_map_err: @@ -910,7 +910,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba) pci_dev_put(hba->pcidev); if (hba->regview) { - pci_iounmap(hba->pcidev, hba->regview); + iounmap(hba->regview); hba->regview = NULL; } bnx2i_free_mp_bdt(hba); diff --git a/trunk/drivers/scsi/libsas/sas_ata.c b/trunk/drivers/scsi/libsas/sas_ata.c index d109cc3a17b6..441d88ad99a7 100644 --- a/trunk/drivers/scsi/libsas/sas_ata.c +++ b/trunk/drivers/scsi/libsas/sas_ata.c @@ -139,12 +139,12 @@ static void sas_ata_task_done(struct sas_task *task) if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || ((stat->stat == SAM_STAT_CHECK_CONDITION && dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { - memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE); + ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); if (!link->sactive) { - qc->err_mask |= ac_err_mask(dev->sata_dev.fis[2]); + qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); } else { - link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.fis[2]); + link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command); if (unlikely(link->eh_info.err_mask)) qc->flags |= ATA_QCFLAG_FAILED; } @@ -161,8 +161,8 @@ static void sas_ata_task_done(struct sas_task *task) qc->flags |= ATA_QCFLAG_FAILED; } - dev->sata_dev.fis[3] = 0x04; /* status err */ - dev->sata_dev.fis[2] = ATA_ERR; + dev->sata_dev.tf.feature = 0x04; /* status err */ + dev->sata_dev.tf.command = ATA_ERR; } } @@ -269,7 +269,7 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) { struct domain_device *dev = qc->ap->private_data; - ata_tf_from_fis(dev->sata_dev.fis, &qc->result_tf); + memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf)); return true; } diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe7755..6102ef2cb2d8 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -1792,7 +1792,7 @@ static inline void _base_writeq(__u64 b, volatile void __iomem *addr, static inline u8 _base_get_msix_index(struct MPT2SAS_ADAPTER *ioc) { - return ioc->cpu_msix_table[raw_smp_processor_id()]; + return ioc->cpu_msix_table[smp_processor_id()]; } /** diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.c b/trunk/drivers/scsi/qla2xxx/qla_target.c index 5b30132960c7..04f80ebf09eb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_target.c +++ b/trunk/drivers/scsi/qla2xxx/qla_target.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -2476,9 +2477,11 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, } cmd = qlt_ctio_to_cmd(vha, handle, ctio); - if (cmd == NULL) + if (cmd == NULL) { + if (status != CTIO_SUCCESS) + qlt_term_ctio_exchange(vha, ctio, NULL, status); return; - + } se_cmd = &cmd->se_cmd; tfo = se_cmd->se_tfo; @@ -2643,9 +2646,19 @@ static void qlt_do_work(struct work_struct *work) spin_lock_irqsave(&ha->hardware_lock, flags); sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, atio->u.isp24.fcp_hdr.s_id); - /* Do kref_get() before dropping qla_hw_data->hardware_lock. */ - if (sess) - kref_get(&sess->se_sess->sess_kref); + if (sess) { + if (unlikely(sess->tearing_down)) { + sess = NULL; + spin_unlock_irqrestore(&ha->hardware_lock, flags); + goto out_term; + } else { + /* + * Do the extra kref_get() before dropping + * qla_hw_data->hardware_lock. + */ + kref_get(&sess->se_sess->sess_kref); + } + } spin_unlock_irqrestore(&ha->hardware_lock, flags); if (unlikely(!sess)) { @@ -2714,12 +2727,10 @@ static void qlt_do_work(struct work_struct *work) out_term: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf020, "Terminating work cmd %p", cmd); /* - * cmd has not sent to target yet, so pass NULL as the second - * argument to qlt_send_term_exchange() and free the memory here. + * cmd has not sent to target yet, so pass NULL as the second argument */ spin_lock_irqsave(&ha->hardware_lock, flags); qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); - kmem_cache_free(qla_tgt_cmd_cachep, cmd); spin_unlock_irqrestore(&ha->hardware_lock, flags); if (sess) ha->tgt.tgt_ops->put_sess(sess); @@ -3950,7 +3961,7 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, { struct qla_hw_data *ha = vha->hw; struct qla_tgt *tgt = ha->tgt.qla_tgt; - int login_code; + int reason_code; ql_dbg(ql_dbg_tgt, vha, 0xe039, "scsi(%ld): ha state %d init_done %d oper_mode %d topo %d\n", @@ -3993,9 +4004,9 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, { ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03b, "qla_target(%d): Async LOOP_UP occured " - "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, - le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), - le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); + "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, + le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); if (tgt->link_reinit_iocb_pending) { qlt_send_notify_ack(vha, (void *)&tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0); @@ -4010,24 +4021,23 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, case MBA_RSCN_UPDATE: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03c, "qla_target(%d): Async event %#x occured " - "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, code, - le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), - le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); + "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, code, + le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); break; case MBA_PORT_UPDATE: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03d, "qla_target(%d): Port update async event %#x " - "occured: updating the ports database (m[0]=%x, m[1]=%x, " - "m[2]=%x, m[3]=%x)", vha->vp_idx, code, - le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), - le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); - - login_code = le16_to_cpu(mailbox[2]); - if (login_code == 0x4) + "occured: updating the ports database (m[1]=%x, m[2]=%x, " + "m[3]=%x, m[4]=%x)", vha->vp_idx, code, + le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); + reason_code = le16_to_cpu(mailbox[2]); + if (reason_code == 0x4) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03e, "Async MB 2: Got PLOGI Complete\n"); - else if (login_code == 0x7) + else if (reason_code == 0x7) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03f, "Async MB 2: Port Logged Out\n"); break; @@ -4035,9 +4045,9 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, default: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf040, "qla_target(%d): Async event %#x occured: " - "ignore (m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, - code, le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), - le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); + "ignore (m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, + code, le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); break; } diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.h b/trunk/drivers/scsi/qla2xxx/qla_target.h index 170af1571214..9ec19bc2f0fe 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_target.h +++ b/trunk/drivers/scsi/qla2xxx/qla_target.h @@ -639,7 +639,7 @@ struct qla_tgt_func_tmpl { int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, unsigned char *, uint32_t, int, int, int); - void (*handle_data)(struct qla_tgt_cmd *); + int (*handle_data)(struct qla_tgt_cmd *); int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t, uint32_t); void (*free_cmd)(struct qla_tgt_cmd *); @@ -813,6 +813,7 @@ struct qla_tgt_sess { unsigned int conf_compl_supported:1; unsigned int deleted:1; unsigned int local:1; + unsigned int tearing_down:1; struct se_session *se_sess; struct scsi_qla_host *vha; @@ -918,6 +919,7 @@ struct qla_tgt_srr_ctio { #define QLA_TGT_XMIT_STATUS 2 #define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA) +#include extern struct qla_tgt_data qla_target; /* diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 4752f65a9272..436598f57404 100644 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include #include @@ -135,15 +137,13 @@ static char *tcm_qla2xxx_get_fabric_name(void) */ static int tcm_qla2xxx_npiv_extract_wwn(const char *ns, u64 *nm) { - unsigned int i, j; + unsigned int i, j, value; u8 wwn[8]; memset(wwn, 0, sizeof(wwn)); /* Validate and store the new name */ for (i = 0, j = 0; i < 16; i++) { - int value; - value = hex_to_bin(*ns++); if (value >= 0) j = (j << 4) | value; @@ -464,7 +464,8 @@ static int tcm_qla2xxx_shutdown_session(struct se_session *se_sess) vha = sess->vha; spin_lock_irqsave(&vha->hw->hardware_lock, flags); - target_sess_cmd_list_set_waiting(se_sess); + sess->tearing_down = 1; + target_splice_sess_cmd_list(se_sess); spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); return 1; @@ -597,15 +598,28 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, return -EINVAL; } - return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0], + target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0], cmd->unpacked_lun, data_length, fcp_task_attr, data_dir, flags); + return 0; } -static void tcm_qla2xxx_handle_data_work(struct work_struct *work) +static void tcm_qla2xxx_do_rsp(struct work_struct *work) { struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); + /* + * Dispatch ->queue_status from workqueue process context + */ + transport_generic_request_failure(&cmd->se_cmd); +} +/* + * Called from qla_target.c:qlt_do_ctio_completion() + */ +static int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) +{ + struct se_cmd *se_cmd = &cmd->se_cmd; + unsigned long flags; /* * Ensure that the complete FCP WRITE payload has been received. * Otherwise return an exception via CHECK_CONDITION status. @@ -615,33 +629,31 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work) * Check if se_cmd has already been aborted via LUN_RESET, and * waiting upon completion in tcm_qla2xxx_write_pending_status() */ - if (cmd->se_cmd.transport_state & CMD_T_ABORTED) { - complete(&cmd->se_cmd.t_transport_stop_comp); - return; + spin_lock_irqsave(&se_cmd->t_state_lock, flags); + if (se_cmd->transport_state & CMD_T_ABORTED) { + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); + complete(&se_cmd->t_transport_stop_comp); + return 0; } + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); - cmd->se_cmd.scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD; - transport_generic_request_failure(&cmd->se_cmd); - return; + se_cmd->scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD; + INIT_WORK(&cmd->work, tcm_qla2xxx_do_rsp); + queue_work(tcm_qla2xxx_free_wq, &cmd->work); + return 0; } - - return target_execute_cmd(&cmd->se_cmd); -} - -/* - * Called from qla_target.c:qlt_do_ctio_completion() - */ -static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) -{ - INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work); - queue_work(tcm_qla2xxx_free_wq, &cmd->work); + /* + * We now tell TCM to queue this WRITE CDB with TRANSPORT_PROCESS_WRITE + * status to the backstore processing thread. + */ + return transport_generic_handle_data(&cmd->se_cmd); } /* * Called from qla_target.c:qlt_issue_task_mgmt() */ -static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, - uint8_t tmr_func, uint32_t tag) +int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, + uint8_t tmr_func, uint32_t tag) { struct qla_tgt_sess *sess = mcmd->sess; struct se_cmd *se_cmd = &mcmd->se_cmd; @@ -750,8 +762,65 @@ static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; -static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, - struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *); +static int tcm_qla2xxx_setup_nacl_from_rport( + struct se_portal_group *se_tpg, + struct se_node_acl *se_nacl, + struct tcm_qla2xxx_lport *lport, + struct tcm_qla2xxx_nacl *nacl, + u64 rport_wwnn) +{ + struct scsi_qla_host *vha = lport->qla_vha; + struct Scsi_Host *sh = vha->host; + struct fc_host_attrs *fc_host = shost_to_fc_host(sh); + struct fc_rport *rport; + unsigned long flags; + void *node; + int rc; + + /* + * Scan the existing rports, and create a session for the + * explict NodeACL is an matching rport->node_name already + * exists. + */ + spin_lock_irqsave(sh->host_lock, flags); + list_for_each_entry(rport, &fc_host->rports, peers) { + if (rport_wwnn != rport->node_name) + continue; + + pr_debug("Located existing rport_wwpn and rport->node_name: 0x%016LX, port_id: 0x%04x\n", + rport->node_name, rport->port_id); + nacl->nport_id = rport->port_id; + + spin_unlock_irqrestore(sh->host_lock, flags); + + spin_lock_irqsave(&vha->hw->hardware_lock, flags); + node = btree_lookup32(&lport->lport_fcport_map, rport->port_id); + if (node) { + rc = btree_update32(&lport->lport_fcport_map, + rport->port_id, se_nacl); + } else { + rc = btree_insert32(&lport->lport_fcport_map, + rport->port_id, se_nacl, + GFP_ATOMIC); + } + spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); + + if (rc) { + pr_err("Unable to insert se_nacl into fcport_map"); + WARN_ON(rc > 0); + return rc; + } + + pr_debug("Inserted into fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%08x\n", + se_nacl, rport_wwnn, nacl->nport_id); + + return 1; + } + spin_unlock_irqrestore(sh->host_lock, flags); + + return 0; +} + /* * Expected to be called with struct qla_hw_data->hardware_lock held */ @@ -773,40 +842,11 @@ static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess) pr_debug("Removed from fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%06x\n", se_nacl, nacl->nport_wwnn, nacl->nport_id); - /* - * Now clear the se_nacl and session pointers from our HW lport lookup - * table mapping for this initiator's fabric S_ID and LOOP_ID entries. - * - * This is done ahead of callbacks into tcm_qla2xxx_free_session() -> - * target_wait_for_sess_cmds() before the session waits for outstanding - * I/O to complete, to avoid a race between session shutdown execution - * and incoming ATIOs or TMRs picking up a stale se_node_act reference. - */ - tcm_qla2xxx_clear_sess_lookup(lport, nacl, sess); -} - -static void tcm_qla2xxx_release_session(struct kref *kref) -{ - struct se_session *se_sess = container_of(kref, - struct se_session, sess_kref); - - qlt_unreg_sess(se_sess->fabric_sess_ptr); -} - -static void tcm_qla2xxx_put_session(struct se_session *se_sess) -{ - struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; - struct qla_hw_data *ha = sess->vha->hw; - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - kref_put(&se_sess->sess_kref, tcm_qla2xxx_release_session); - spin_unlock_irqrestore(&ha->hardware_lock, flags); } static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) { - tcm_qla2xxx_put_session(sess->se_sess); + target_put_session(sess->se_sess); } static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) @@ -819,10 +859,14 @@ static struct se_node_acl *tcm_qla2xxx_make_nodeacl( struct config_group *group, const char *name) { + struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; + struct tcm_qla2xxx_lport *lport = container_of(se_wwn, + struct tcm_qla2xxx_lport, lport_wwn); struct se_node_acl *se_nacl, *se_nacl_new; struct tcm_qla2xxx_nacl *nacl; u64 wwnn; u32 qla2xxx_nexus_depth; + int rc; if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0) return ERR_PTR(-EINVAL); @@ -849,6 +893,16 @@ static struct se_node_acl *tcm_qla2xxx_make_nodeacl( nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); nacl->nport_wwnn = wwnn; tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn); + /* + * Setup a se_nacl handle based on an a matching struct fc_rport setup + * via drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() + */ + rc = tcm_qla2xxx_setup_nacl_from_rport(se_tpg, se_nacl, lport, + nacl, wwnn); + if (rc < 0) { + tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); + return ERR_PTR(rc); + } return se_nacl; } @@ -1336,25 +1390,6 @@ static void tcm_qla2xxx_set_sess_by_loop_id( nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); } -/* - * Should always be called with qla_hw_data->hardware_lock held. - */ -static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport, - struct tcm_qla2xxx_nacl *nacl, struct qla_tgt_sess *sess) -{ - struct se_session *se_sess = sess->se_sess; - unsigned char be_sid[3]; - - be_sid[0] = sess->s_id.b.domain; - be_sid[1] = sess->s_id.b.area; - be_sid[2] = sess->s_id.b.al_pa; - - tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, - sess, be_sid); - tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, - sess, sess->loop_id); -} - static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) { struct qla_tgt *tgt = sess->tgt; @@ -1363,6 +1398,8 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) struct se_node_acl *se_nacl; struct tcm_qla2xxx_lport *lport; struct tcm_qla2xxx_nacl *nacl; + unsigned char be_sid[3]; + unsigned long flags; BUG_ON(in_interrupt()); @@ -1382,6 +1419,21 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) return; } target_wait_for_sess_cmds(se_sess, 0); + /* + * And now clear the se_nacl and session pointers from our HW lport + * mappings for fabric S_ID and LOOP_ID. + */ + memset(&be_sid, 0, 3); + be_sid[0] = sess->s_id.b.domain; + be_sid[1] = sess->s_id.b.area; + be_sid[2] = sess->s_id.b.al_pa; + + spin_lock_irqsave(&ha->hardware_lock, flags); + tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, + sess, be_sid); + tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, + sess, sess->loop_id); + spin_unlock_irqrestore(&ha->hardware_lock, flags); transport_deregister_session_configfs(sess->se_sess); transport_deregister_session(sess->se_sess); @@ -1676,9 +1728,9 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, + .new_cmd_map = NULL, .check_stop_free = tcm_qla2xxx_check_stop_free, .release_cmd = tcm_qla2xxx_release_cmd, - .put_session = tcm_qla2xxx_put_session, .shutdown_session = tcm_qla2xxx_shutdown_session, .close_session = tcm_qla2xxx_close_session, .sess_get_index = tcm_qla2xxx_sess_get_index, @@ -1727,7 +1779,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, .release_cmd = tcm_qla2xxx_release_cmd, - .put_session = tcm_qla2xxx_put_session, .shutdown_session = tcm_qla2xxx_shutdown_session, .close_session = tcm_qla2xxx_close_session, .sess_get_index = tcm_qla2xxx_sess_get_index, diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index bbbc9c918d4c..61c82a345f82 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -90,9 +90,11 @@ unsigned int scsi_logging_level; EXPORT_SYMBOL(scsi_logging_level); #endif -/* sd, scsi core and power management need to coordinate flushing async actions */ +#if IS_ENABLED(CONFIG_PM) || IS_ENABLED(CONFIG_BLK_DEV_SD) +/* sd and scsi_pm need to coordinate flushing async actions */ LIST_HEAD(scsi_sd_probe_domain); EXPORT_SYMBOL(scsi_sd_probe_domain); +#endif /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. * You may not alter any existing entry (although adding new ones is diff --git a/trunk/drivers/scsi/scsi_wait_scan.c b/trunk/drivers/scsi/scsi_wait_scan.c index 072734538876..ae7814874618 100644 --- a/trunk/drivers/scsi/scsi_wait_scan.c +++ b/trunk/drivers/scsi/scsi_wait_scan.c @@ -22,6 +22,11 @@ static int __init wait_scan_init(void) * and might not yet have reached the scsi async scanning */ wait_for_device_probe(); + /* + * and then we wait for the actual asynchronous scsi scan + * to finish. + */ + scsi_complete_async_scans(); return 0; } diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 6f72b80121a0..6f0a4c612b3b 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -1899,8 +1899,6 @@ static int sd_try_rc16_first(struct scsi_device *sdp) { if (sdp->host->max_cmd_len < 16) return 0; - if (sdp->try_rc_10_first) - return 0; if (sdp->scsi_level > SCSI_SPC_2) return 1; if (scsi_device_protection(sdp)) diff --git a/trunk/drivers/spi/spi-omap2-mcspi.c b/trunk/drivers/spi/spi-omap2-mcspi.c index 0c73dd4f43a0..46ef5fe51db5 100644 --- a/trunk/drivers/spi/spi-omap2-mcspi.c +++ b/trunk/drivers/spi/spi-omap2-mcspi.c @@ -801,7 +801,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) mcspi_dma = &mcspi->dma_channels[spi->chip_select]; if (!cs) { - cs = kzalloc(sizeof *cs, GFP_KERNEL); + cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; @@ -842,7 +842,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) cs = spi->controller_state; list_del(&cs->node); - kfree(cs); } if (spi->chip_select < spi->master->num_chipselect) { diff --git a/trunk/drivers/staging/comedi/drivers.c b/trunk/drivers/staging/comedi/drivers.c index aeac1caba3f9..1c3d6386ea36 100644 --- a/trunk/drivers/staging/comedi/drivers.c +++ b/trunk/drivers/staging/comedi/drivers.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -982,8 +981,6 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); -#if IS_ENABLED(CONFIG_USB) - static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { @@ -1046,5 +1043,3 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); - -#endif diff --git a/trunk/drivers/staging/gdm72xx/netlink_k.c b/trunk/drivers/staging/gdm72xx/netlink_k.c index 51665132c61b..292af0f7f451 100644 --- a/trunk/drivers/staging/gdm72xx/netlink_k.c +++ b/trunk/drivers/staging/gdm72xx/netlink_k.c @@ -104,7 +104,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void netlink_exit(struct sock *sock) { - netlink_kernel_release(sock); + sock_release(sock->sk_socket); } int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) diff --git a/trunk/drivers/staging/iio/Documentation/device.txt b/trunk/drivers/staging/iio/Documentation/device.txt index f03fbd3bb454..0338c7cd0a8b 100644 --- a/trunk/drivers/staging/iio/Documentation/device.txt +++ b/trunk/drivers/staging/iio/Documentation/device.txt @@ -29,6 +29,8 @@ Then fill in the following: * info->driver_module: Set to THIS_MODULE. Used to ensure correct ownership of various resources allocate by the core. + * info->num_interrupt_lines: + Number of event triggering hardware lines the device has. * info->event_attrs: Attributes used to enable / disable hardware events. * info->attrs: diff --git a/trunk/drivers/staging/iio/adc/Kconfig b/trunk/drivers/staging/iio/adc/Kconfig index 8f1b3af02f29..2490dd25093b 100644 --- a/trunk/drivers/staging/iio/adc/Kconfig +++ b/trunk/drivers/staging/iio/adc/Kconfig @@ -13,7 +13,6 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI - select IIO_KFIFO_BUF if IIO_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. diff --git a/trunk/drivers/staging/iio/adc/ad7606_core.c b/trunk/drivers/staging/iio/adc/ad7606_core.c index a13afff2dfe6..10ab6dc823b9 100644 --- a/trunk/drivers/staging/iio/adc/ad7606_core.c +++ b/trunk/drivers/staging/iio/adc/ad7606_core.c @@ -235,8 +235,7 @@ static const struct attribute_group ad7606_attribute_group_range = { .indexed = 1, \ .channel = num, \ .address = num, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ .scan_index = num, \ .scan_type = IIO_ST('s', 16, 16, 0), \ } diff --git a/trunk/drivers/staging/media/lirc/lirc_serial.c b/trunk/drivers/staging/media/lirc/lirc_serial.c index 97ef67036e3f..3295ea63f3eb 100644 --- a/trunk/drivers/staging/media/lirc/lirc_serial.c +++ b/trunk/drivers/staging/media/lirc/lirc_serial.c @@ -129,7 +129,6 @@ static void send_space_homebrew(long length); static struct lirc_serial hardware[] = { [LIRC_HOMEBREW] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_HOMEBREW].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -146,7 +145,6 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = UART_MCR_OUT2, @@ -158,7 +156,6 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO_REMOTE] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO_REMOTE].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), @@ -170,7 +167,6 @@ static struct lirc_serial hardware[] = { }, [LIRC_ANIMAX] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_ANIMAX].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = 0, @@ -181,7 +177,6 @@ static struct lirc_serial hardware[] = { }, [LIRC_IGOR] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IGOR].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -206,7 +201,6 @@ static struct lirc_serial hardware[] = { * See also http://www.nslu2-linux.org for this device */ [LIRC_NSLU2] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_NSLU2].lock), .signal_pin = UART_MSR_CTS, .signal_pin_change = UART_MSR_DCTS, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), diff --git a/trunk/drivers/staging/omapdrm/omap_fbdev.c b/trunk/drivers/staging/omapdrm/omap_fbdev.c index 8c6ed3b0c6f6..11acd4c35ed2 100644 --- a/trunk/drivers/staging/omapdrm/omap_fbdev.c +++ b/trunk/drivers/staging/omapdrm/omap_fbdev.c @@ -208,8 +208,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, */ ret = omap_gem_get_paddr(fbdev->bo, &paddr, true); if (ret) { - dev_err(dev->dev, - "could not map (paddr)! Skipping framebuffer alloc\n"); + dev_err(dev->dev, "could not map (paddr)!\n"); ret = -ENOMEM; goto fail; } @@ -389,11 +388,8 @@ void omap_fbdev_free(struct drm_device *dev) fbi = helper->fbdev; - /* only cleanup framebuffer if it is present */ - if (fbi) { - unregister_framebuffer(fbi); - framebuffer_release(fbi); - } + unregister_framebuffer(fbi); + framebuffer_release(fbi); drm_fb_helper_fini(helper); diff --git a/trunk/drivers/staging/ramster/zcache-main.c b/trunk/drivers/staging/ramster/zcache-main.c index d46764b5aaba..4e7ef0e6b79c 100644 --- a/trunk/drivers/staging/ramster/zcache-main.c +++ b/trunk/drivers/staging/ramster/zcache-main.c @@ -3002,7 +3002,7 @@ static inline struct tmem_oid oswiz(unsigned type, u32 ind) return oid; } -static int zcache_frontswap_store(unsigned type, pgoff_t offset, +static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, struct page *page) { u64 ind64 = (u64)offset; @@ -3025,7 +3025,7 @@ static int zcache_frontswap_store(unsigned type, pgoff_t offset, /* returns 0 if the page was successfully gotten from frontswap, -1 if * was not present (should never happen!) */ -static int zcache_frontswap_load(unsigned type, pgoff_t offset, +static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, struct page *page) { u64 ind64 = (u64)offset; @@ -3080,8 +3080,8 @@ static void zcache_frontswap_init(unsigned ignored) } static struct frontswap_ops zcache_frontswap_ops = { - .store = zcache_frontswap_store, - .load = zcache_frontswap_load, + .put_page = zcache_frontswap_put_page, + .get_page = zcache_frontswap_get_page, .invalidate_page = zcache_frontswap_flush_page, .invalidate_area = zcache_frontswap_flush_area, .init = zcache_frontswap_init diff --git a/trunk/drivers/staging/rtl8712/usb_intf.c b/trunk/drivers/staging/rtl8712/usb_intf.c index 69f616c6964e..9bd18e2d0513 100644 --- a/trunk/drivers/staging/rtl8712/usb_intf.c +++ b/trunk/drivers/staging/rtl8712/usb_intf.c @@ -102,8 +102,6 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { /* - */ {USB_DEVICE(0x20F4, 0x646B)}, {USB_DEVICE(0x083A, 0xC512)}, - {USB_DEVICE(0x25D4, 0x4CA1)}, - {USB_DEVICE(0x25D4, 0x4CAB)}, /* RTL8191SU */ /* Realtek */ diff --git a/trunk/drivers/staging/zcache/zcache-main.c b/trunk/drivers/staging/zcache/zcache-main.c index 784c796b9848..2734dacacbaf 100644 --- a/trunk/drivers/staging/zcache/zcache-main.c +++ b/trunk/drivers/staging/zcache/zcache-main.c @@ -1835,7 +1835,7 @@ static int zcache_frontswap_poolid = -1; * Swizzling increases objects per swaptype, increasing tmem concurrency * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS * Setting SWIZ_BITS to 27 basically reconstructs the swap entry from - * frontswap_load(), but has side-effects. Hence using 8. + * frontswap_get_page(), but has side-effects. Hence using 8. */ #define SWIZ_BITS 8 #define SWIZ_MASK ((1 << SWIZ_BITS) - 1) @@ -1849,7 +1849,7 @@ static inline struct tmem_oid oswiz(unsigned type, u32 ind) return oid; } -static int zcache_frontswap_store(unsigned type, pgoff_t offset, +static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, struct page *page) { u64 ind64 = (u64)offset; @@ -1870,7 +1870,7 @@ static int zcache_frontswap_store(unsigned type, pgoff_t offset, /* returns 0 if the page was successfully gotten from frontswap, -1 if * was not present (should never happen!) */ -static int zcache_frontswap_load(unsigned type, pgoff_t offset, +static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, struct page *page) { u64 ind64 = (u64)offset; @@ -1919,8 +1919,8 @@ static void zcache_frontswap_init(unsigned ignored) } static struct frontswap_ops zcache_frontswap_ops = { - .store = zcache_frontswap_store, - .load = zcache_frontswap_load, + .put_page = zcache_frontswap_put_page, + .get_page = zcache_frontswap_get_page, .invalidate_page = zcache_frontswap_flush_page, .invalidate_area = zcache_frontswap_flush_area, .init = zcache_frontswap_init diff --git a/trunk/drivers/target/Makefile b/trunk/drivers/target/Makefile index 9fdcb561422f..61648d84fbb6 100644 --- a/trunk/drivers/target/Makefile +++ b/trunk/drivers/target/Makefile @@ -9,8 +9,7 @@ target_core_mod-y := target_core_configfs.o \ target_core_tmr.o \ target_core_tpg.o \ target_core_transport.o \ - target_core_sbc.o \ - target_core_spc.o \ + target_core_cdb.o \ target_core_ua.o \ target_core_rd.o \ target_core_stat.o diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index 97c0f78c3c9c..d57d10cb2e47 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -429,8 +429,19 @@ int iscsit_reset_np_thread( int iscsit_del_np_comm(struct iscsi_np *np) { - if (np->np_socket) - sock_release(np->np_socket); + if (!np->np_socket) + return 0; + + /* + * Some network transports allocate their own struct sock->file, + * see if we need to free any additional allocated resources. + */ + if (np->np_flags & NPF_SCTP_STRUCT_FILE) { + kfree(np->np_socket->file); + np->np_socket->file = NULL; + } + + sock_release(np->np_socket); return 0; } @@ -1402,10 +1413,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) spin_unlock_bh(&cmd->istate_lock); iscsit_stop_dataout_timer(cmd); - if (ooo_cmdsn) - return 0; - target_execute_cmd(&cmd->se_cmd); - return 0; + return (!ooo_cmdsn) ? transport_generic_handle_data( + &cmd->se_cmd) : 0; } else /* DATAOUT_CANNOT_RECOVER */ return -1; @@ -2674,7 +2683,7 @@ static int iscsit_send_logout_response( */ logout_conn = iscsit_get_conn_from_cid_rcfr(sess, cmd->logout_cid); - if (logout_conn) { + if ((logout_conn)) { iscsit_connection_reinstatement_rcfr(logout_conn); iscsit_dec_conn_usage_count(logout_conn); } @@ -4068,8 +4077,13 @@ int iscsit_close_connection( kfree(conn->conn_ops); conn->conn_ops = NULL; - if (conn->sock) + if (conn->sock) { + if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) { + kfree(conn->sock->file); + conn->sock->file = NULL; + } sock_release(conn->sock); + } conn->thread_set = NULL; pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); diff --git a/trunk/drivers/target/iscsi/iscsi_target_configfs.c b/trunk/drivers/target/iscsi/iscsi_target_configfs.c index a7b25e783b58..69dc8e35c03a 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_configfs.c +++ b/trunk/drivers/target/iscsi/iscsi_target_configfs.c @@ -47,6 +47,28 @@ struct lio_target_configfs_attribute { ssize_t (*store)(void *, const char *, size_t); }; +struct iscsi_portal_group *lio_get_tpg_from_tpg_item( + struct config_item *item, + struct iscsi_tiqn **tiqn_out) +{ + struct se_portal_group *se_tpg = container_of(to_config_group(item), + struct se_portal_group, tpg_group); + struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr; + int ret; + + if (!tpg) { + pr_err("Unable to locate struct iscsi_portal_group " + "pointer\n"); + return NULL; + } + ret = iscsit_get_tpg(tpg); + if (ret < 0) + return NULL; + + *tiqn_out = tpg->tpg_tiqn; + return tpg; +} + /* Start items for lio_target_portal_cit */ static ssize_t lio_target_np_show_sctp( diff --git a/trunk/drivers/target/iscsi/iscsi_target_core.h b/trunk/drivers/target/iscsi/iscsi_target_core.h index 8a908b28d8b2..1c70144cdaf1 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_core.h +++ b/trunk/drivers/target/iscsi/iscsi_target_core.h @@ -224,6 +224,7 @@ enum iscsi_timer_flags_table { /* Used for struct iscsi_np->np_flags */ enum np_flags_table { NPF_IP_NETWORK = 0x00, + NPF_SCTP_STRUCT_FILE = 0x01 /* Bugfix */ }; /* Used for struct iscsi_np->np_thread_state */ @@ -480,7 +481,6 @@ struct iscsi_tmr_req { bool task_reassign:1; u32 ref_cmd_sn; u32 exp_data_sn; - struct iscsi_cmd *ref_cmd; struct iscsi_conn_recovery *conn_recovery; struct se_tmr_req *se_tmr_req; }; @@ -503,6 +503,7 @@ struct iscsi_conn { u16 local_port; int net_size; u32 auth_id; +#define CONNFLAG_SCTP_STRUCT_FILE 0x01 u32 conn_flags; /* Used for iscsi_tx_login_rsp() */ u32 login_itt; diff --git a/trunk/drivers/target/iscsi/iscsi_target_erl1.c b/trunk/drivers/target/iscsi/iscsi_target_erl1.c index 3df8a2cef86f..ecdd46deedda 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_erl1.c +++ b/trunk/drivers/target/iscsi/iscsi_target_erl1.c @@ -965,8 +965,8 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) if (cmd->immediate_data) { if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) { spin_unlock_bh(&cmd->istate_lock); - target_execute_cmd(&cmd->se_cmd); - return 0; + return transport_generic_handle_data( + &cmd->se_cmd); } spin_unlock_bh(&cmd->istate_lock); diff --git a/trunk/drivers/target/iscsi/iscsi_target_login.c b/trunk/drivers/target/iscsi/iscsi_target_login.c index 0694d9b1bce6..a3656c9903a1 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_login.c +++ b/trunk/drivers/target/iscsi/iscsi_target_login.c @@ -518,7 +518,7 @@ int iscsi_login_post_auth_non_zero_tsih( * initiator and release the new connection. */ conn_ptr = iscsit_get_conn_from_cid_rcfr(sess, cid); - if (conn_ptr) { + if ((conn_ptr)) { pr_err("Connection exists with CID %hu for %s," " performing connection reinstatement.\n", conn_ptr->cid, sess->sess_ops->InitiatorName); @@ -539,7 +539,7 @@ int iscsi_login_post_auth_non_zero_tsih( if (sess->sess_ops->ErrorRecoveryLevel == 2) { cr = iscsit_get_inactive_connection_recovery_entry( sess, cid); - if (cr) { + if ((cr)) { pr_debug("Performing implicit logout" " for connection recovery on CID: %hu\n", conn->cid); @@ -794,6 +794,22 @@ int iscsi_target_setup_login_socket( return ret; } np->np_socket = sock; + /* + * The SCTP stack needs struct socket->file. + */ + if ((np->np_network_transport == ISCSI_SCTP_TCP) || + (np->np_network_transport == ISCSI_SCTP_UDP)) { + if (!sock->file) { + sock->file = kzalloc(sizeof(struct file), GFP_KERNEL); + if (!sock->file) { + pr_err("Unable to allocate struct" + " file for SCTP\n"); + ret = -ENOMEM; + goto fail; + } + np->np_flags |= NPF_SCTP_STRUCT_FILE; + } + } /* * Setup the np->np_sockaddr from the passed sockaddr setup * in iscsi_target_configfs.c code.. @@ -853,15 +869,21 @@ int iscsi_target_setup_login_socket( fail: np->np_socket = NULL; - if (sock) + if (sock) { + if (np->np_flags & NPF_SCTP_STRUCT_FILE) { + kfree(sock->file); + sock->file = NULL; + } + sock_release(sock); + } return ret; } static int __iscsi_target_login_thread(struct iscsi_np *np) { u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0; - int err, ret = 0, stop; + int err, ret = 0, set_sctp_conn_flag, stop; struct iscsi_conn *conn = NULL; struct iscsi_login *login; struct iscsi_portal_group *tpg = NULL; @@ -872,6 +894,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) struct sockaddr_in6 sock_in6; flush_signals(current); + set_sctp_conn_flag = 0; sock = np->np_socket; spin_lock_bh(&np->np_thread_lock); @@ -894,12 +917,35 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) spin_unlock_bh(&np->np_thread_lock); goto out; } + /* + * The SCTP stack needs struct socket->file. + */ + if ((np->np_network_transport == ISCSI_SCTP_TCP) || + (np->np_network_transport == ISCSI_SCTP_UDP)) { + if (!new_sock->file) { + new_sock->file = kzalloc( + sizeof(struct file), GFP_KERNEL); + if (!new_sock->file) { + pr_err("Unable to allocate struct" + " file for SCTP\n"); + sock_release(new_sock); + /* Get another socket */ + return 1; + } + set_sctp_conn_flag = 1; + } + } + iscsi_start_login_thread_timer(np); conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL); if (!conn) { pr_err("Could not allocate memory for" " new connection\n"); + if (set_sctp_conn_flag) { + kfree(new_sock->file); + new_sock->file = NULL; + } sock_release(new_sock); /* Get another socket */ return 1; @@ -909,6 +955,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) conn->conn_state = TARG_CONN_STATE_FREE; conn->sock = new_sock; + if (set_sctp_conn_flag) + conn->conn_flags |= CONNFLAG_SCTP_STRUCT_FILE; + pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n"); conn->conn_state = TARG_CONN_STATE_XPT_UP; @@ -1032,7 +1081,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) goto new_sess_out; zero_tsih = (pdu->tsih == 0x0000); - if (zero_tsih) { + if ((zero_tsih)) { /* * This is the leading connection of a new session. * We wait until after authentication to check for @@ -1156,8 +1205,13 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) iscsi_release_param_list(conn->param_list); conn->param_list = NULL; } - if (conn->sock) + if (conn->sock) { + if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) { + kfree(conn->sock->file); + conn->sock->file = NULL; + } sock_release(conn->sock); + } kfree(conn); if (tpg) { diff --git a/trunk/drivers/target/iscsi/iscsi_target_parameters.c b/trunk/drivers/target/iscsi/iscsi_target_parameters.c index 0c4760fabfc0..ed5241e7f12a 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_parameters.c +++ b/trunk/drivers/target/iscsi/iscsi_target_parameters.c @@ -681,7 +681,7 @@ int iscsi_update_param_value(struct iscsi_param *param, char *value) param->value = kzalloc(strlen(value) + 1, GFP_KERNEL); if (!param->value) { pr_err("Unable to allocate memory for value.\n"); - return -ENOMEM; + return -1; } memcpy(param->value, value, strlen(value)); diff --git a/trunk/drivers/target/iscsi/iscsi_target_tmr.c b/trunk/drivers/target/iscsi/iscsi_target_tmr.c index f62fe123d902..f4e640b51fd1 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_tmr.c +++ b/trunk/drivers/target/iscsi/iscsi_target_tmr.c @@ -19,7 +19,6 @@ ******************************************************************************/ #include -#include #include #include #include @@ -62,7 +61,7 @@ u8 iscsit_tmr_abort_task( } se_tmr->ref_task_tag = hdr->rtt; - tmr_req->ref_cmd = ref_cmd; + se_tmr->ref_cmd = &ref_cmd->se_cmd; tmr_req->ref_cmd_sn = hdr->refcmdsn; tmr_req->exp_data_sn = hdr->exp_datasn; @@ -122,7 +121,7 @@ u8 iscsit_tmr_task_reassign( struct iscsi_tmr_req *tmr_req = cmd->tmr_req; struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req; struct iscsi_tm *hdr = (struct iscsi_tm *) buf; - int ret, ref_lun; + int ret; pr_debug("Got TASK_REASSIGN TMR ITT: 0x%08x," " RefTaskTag: 0x%08x, ExpDataSN: 0x%08x, CID: %hu\n", @@ -156,16 +155,9 @@ u8 iscsit_tmr_task_reassign( return ISCSI_TMF_RSP_REJECTED; } - ref_lun = scsilun_to_int(&hdr->lun); - if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) { - pr_err("Unable to perform connection recovery for" - " differing ref_lun: %d ref_cmd orig_fe_lun: %u\n", - ref_lun, ref_cmd->se_cmd.orig_fe_lun); - return ISCSI_TMF_RSP_REJECTED; - } - se_tmr->ref_task_tag = hdr->rtt; - tmr_req->ref_cmd = ref_cmd; + se_tmr->ref_cmd = &ref_cmd->se_cmd; + se_tmr->ref_task_lun = get_unaligned_le64(&hdr->lun); tmr_req->ref_cmd_sn = hdr->refcmdsn; tmr_req->exp_data_sn = hdr->exp_datasn; tmr_req->conn_recovery = cr; @@ -199,7 +191,9 @@ static int iscsit_task_reassign_complete_nop_out( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { - struct iscsi_cmd *cmd = tmr_req->ref_cmd; + struct se_tmr_req *se_tmr = tmr_req->se_tmr_req; + struct se_cmd *se_cmd = se_tmr->ref_cmd; + struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_conn_recovery *cr; if (!cmd->cr) { @@ -257,8 +251,7 @@ static int iscsit_task_reassign_complete_write( pr_debug("WRITE ITT: 0x%08x: t_state: %d" " never sent to transport\n", cmd->init_task_tag, cmd->se_cmd.t_state); - target_execute_cmd(se_cmd); - return 0; + return transport_generic_handle_data(se_cmd); } cmd->i_state = ISTATE_SEND_STATUS; @@ -367,7 +360,9 @@ static int iscsit_task_reassign_complete_scsi_cmnd( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { - struct iscsi_cmd *cmd = tmr_req->ref_cmd; + struct se_tmr_req *se_tmr = tmr_req->se_tmr_req; + struct se_cmd *se_cmd = se_tmr->ref_cmd; + struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_conn_recovery *cr; if (!cmd->cr) { @@ -390,7 +385,7 @@ static int iscsit_task_reassign_complete_scsi_cmnd( list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); - if (cmd->se_cmd.se_cmd_flags & SCF_SENT_CHECK_CONDITION) { + if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { cmd->i_state = ISTATE_SEND_STATUS; iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); return 0; @@ -416,14 +411,17 @@ static int iscsit_task_reassign_complete( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { + struct se_tmr_req *se_tmr = tmr_req->se_tmr_req; + struct se_cmd *se_cmd; struct iscsi_cmd *cmd; int ret = 0; - if (!tmr_req->ref_cmd) { + if (!se_tmr->ref_cmd) { pr_err("TMR Request is missing a RefCmd struct iscsi_cmd.\n"); return -1; } - cmd = tmr_req->ref_cmd; + se_cmd = se_tmr->ref_cmd; + cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); cmd->conn = conn; @@ -549,7 +547,9 @@ int iscsit_task_reassign_prepare_write( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { - struct iscsi_cmd *cmd = tmr_req->ref_cmd; + struct se_tmr_req *se_tmr = tmr_req->se_tmr_req; + struct se_cmd *se_cmd = se_tmr->ref_cmd; + struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_pdu *pdu = NULL; struct iscsi_r2t *r2t = NULL, *r2t_tmp; int first_incomplete_r2t = 1, i = 0; @@ -782,12 +782,14 @@ int iscsit_check_task_reassign_expdatasn( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { - struct iscsi_cmd *ref_cmd = tmr_req->ref_cmd; + struct se_tmr_req *se_tmr = tmr_req->se_tmr_req; + struct se_cmd *se_cmd = se_tmr->ref_cmd; + struct iscsi_cmd *ref_cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); if (ref_cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD) return 0; - if (ref_cmd->se_cmd.se_cmd_flags & SCF_SENT_CHECK_CONDITION) + if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) return 0; if (ref_cmd->data_direction == DMA_NONE) diff --git a/trunk/drivers/target/iscsi/iscsi_target_tpg.c b/trunk/drivers/target/iscsi/iscsi_target_tpg.c index a38a3f8ab0d9..879d8d0fa3fe 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_tpg.c +++ b/trunk/drivers/target/iscsi/iscsi_target_tpg.c @@ -303,7 +303,6 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) { struct iscsi_param *param; struct iscsi_tiqn *tiqn = tpg->tpg_tiqn; - int ret; spin_lock(&tpg->tpg_state_lock); if (tpg->tpg_state == TPG_STATE_ACTIVE) { @@ -320,19 +319,19 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list); if (!param) { spin_unlock(&tpg->tpg_state_lock); - return -EINVAL; + return -ENOMEM; } if (ISCSI_TPG_ATTRIB(tpg)->authentication) { - if (!strcmp(param->value, NONE)) { - ret = iscsi_update_param_value(param, CHAP); - if (ret) - goto err; + if (!strcmp(param->value, NONE)) + if (iscsi_update_param_value(param, CHAP) < 0) { + spin_unlock(&tpg->tpg_state_lock); + return -ENOMEM; + } + if (iscsit_ta_authentication(tpg, 1) < 0) { + spin_unlock(&tpg->tpg_state_lock); + return -ENOMEM; } - - ret = iscsit_ta_authentication(tpg, 1); - if (ret < 0) - goto err; } tpg->tpg_state = TPG_STATE_ACTIVE; @@ -345,10 +344,6 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) spin_unlock(&tiqn->tiqn_tpg_lock); return 0; - -err: - spin_unlock(&tpg->tpg_state_lock); - return ret; } int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force) @@ -563,7 +558,7 @@ int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication) if ((authentication != 1) && (authentication != 0)) { pr_err("Illegal value for authentication parameter:" " %u, ignoring request.\n", authentication); - return -EINVAL; + return -1; } memset(buf1, 0, sizeof(buf1)); @@ -598,7 +593,7 @@ int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication) } else { snprintf(buf1, sizeof(buf1), "%s", param->value); none = strstr(buf1, NONE); - if (none) + if ((none)) goto out; strncat(buf1, ",", strlen(",")); strncat(buf1, NONE, strlen(NONE)); diff --git a/trunk/drivers/target/loopback/tcm_loop.c b/trunk/drivers/target/loopback/tcm_loop.c index 5491c632a15e..38dfac2b0a1c 100644 --- a/trunk/drivers/target/loopback/tcm_loop.c +++ b/trunk/drivers/target/loopback/tcm_loop.c @@ -211,11 +211,12 @@ static void tcm_loop_submission_work(struct work_struct *work) /* * Because some userspace code via scsi-generic do not memset their * associated read buffers, go ahead and do that here for type - * non-data CDBs. Also note that this is currently guaranteed to be a - * single SGL for this case by target core in - * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer(). + * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently + * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB + * by target core in target_setup_cmd_from_cdb() -> + * transport_generic_cmd_sequencer(). */ - if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && + if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB && se_cmd->data_direction == DMA_FROM_DEVICE) { struct scatterlist *sg = scsi_sglist(sc); unsigned char *buf = kmap(sg_page(sg)) + sg->offset; @@ -778,7 +779,7 @@ static int tcm_loop_write_pending(struct se_cmd *se_cmd) * We now tell TCM to add this WRITE CDB directly into the TCM storage * object execution queue. */ - target_execute_cmd(se_cmd); + transport_generic_process_write(se_cmd); return 0; } diff --git a/trunk/drivers/target/sbp/sbp_target.c b/trunk/drivers/target/sbp/sbp_target.c index 39ddba584b30..37c609898f84 100644 --- a/trunk/drivers/target/sbp/sbp_target.c +++ b/trunk/drivers/target/sbp/sbp_target.c @@ -587,14 +587,14 @@ static void sbp_management_request_logout( { struct sbp_tport *tport = agent->tport; struct sbp_tpg *tpg = tport->tpg; - int id; + int login_id; struct sbp_login_descriptor *login; - id = LOGOUT_ORB_LOGIN_ID(be32_to_cpu(req->orb.misc)); + login_id = LOGOUT_ORB_LOGIN_ID(be32_to_cpu(req->orb.misc)); - login = sbp_login_find_by_id(tpg, id); + login = sbp_login_find_by_id(tpg, login_id); if (!login) { - pr_warn("cannot find login: %d\n", id); + pr_warn("cannot find login: %d\n", login_id); req->status.status = cpu_to_be32( STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) | @@ -1219,14 +1219,28 @@ static void sbp_handle_command(struct sbp_target_request *req) ret = sbp_fetch_command(req); if (ret) { pr_debug("sbp_handle_command: fetch command failed: %d\n", ret); - goto err; + req->status.status |= cpu_to_be32( + STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) | + STATUS_BLOCK_DEAD(0) | + STATUS_BLOCK_LEN(1) | + STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR)); + sbp_send_status(req); + sbp_free_request(req); + return; } ret = sbp_fetch_page_table(req); if (ret) { pr_debug("sbp_handle_command: fetch page table failed: %d\n", ret); - goto err; + req->status.status |= cpu_to_be32( + STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) | + STATUS_BLOCK_DEAD(0) | + STATUS_BLOCK_LEN(1) | + STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR)); + sbp_send_status(req); + sbp_free_request(req); + return; } unpacked_lun = req->login->lun->unpacked_lun; @@ -1235,21 +1249,9 @@ static void sbp_handle_command(struct sbp_target_request *req) pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n", req->orb_pointer, unpacked_lun, data_length, data_dir); - if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, - req->sense_buf, unpacked_lun, data_length, - MSG_SIMPLE_TAG, data_dir, 0)) - goto err; - - return; - -err: - req->status.status |= cpu_to_be32( - STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) | - STATUS_BLOCK_DEAD(0) | - STATUS_BLOCK_LEN(1) | - STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR)); - sbp_send_status(req); - sbp_free_request(req); + target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, + req->sense_buf, unpacked_lun, data_length, + MSG_SIMPLE_TAG, data_dir, 0); } /* @@ -1782,7 +1784,8 @@ static int sbp_write_pending(struct se_cmd *se_cmd) return ret; } - target_execute_cmd(se_cmd); + transport_generic_process_write(se_cmd); + return 0; } diff --git a/trunk/drivers/target/target_core_alua.c b/trunk/drivers/target/target_core_alua.c index 91799973081a..e624b836469c 100644 --- a/trunk/drivers/target/target_core_alua.c +++ b/trunk/drivers/target/target_core_alua.c @@ -374,9 +374,8 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) out: transport_kunmap_data_sg(cmd); - if (!rc) - target_complete_cmd(cmd, GOOD); - return rc; + target_complete_cmd(cmd, GOOD); + return 0; } static inline int core_alua_state_nonoptimized( diff --git a/trunk/drivers/target/target_core_spc.c b/trunk/drivers/target/target_core_cdb.c similarity index 76% rename from trunk/drivers/target/target_core_spc.c rename to trunk/drivers/target/target_core_cdb.c index 4c861de538c9..9888693a18fe 100644 --- a/trunk/drivers/target/target_core_spc.c +++ b/trunk/drivers/target/target_core_cdb.c @@ -1,5 +1,5 @@ /* - * SCSI Primary Commands (SPC) parsing and emulation. + * CDB emulation for non-READ/WRITE commands. * * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. * Copyright (c) 2005, 2006, 2007 SBE, Inc. @@ -26,21 +26,17 @@ #include #include #include - #include -#include #include #include #include #include "target_core_internal.h" -#include "target_core_alua.h" -#include "target_core_pr.h" #include "target_core_ua.h" - -static void spc_fill_alua_data(struct se_port *port, unsigned char *buf) +static void +target_fill_alua_data(struct se_port *port, unsigned char *buf) { struct t10_alua_tg_pt_gp *tg_pt_gp; struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; @@ -69,7 +65,8 @@ static void spc_fill_alua_data(struct se_port *port, unsigned char *buf) spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); } -static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) +static int +target_emulate_inquiry_std(struct se_cmd *cmd, char *buf) { struct se_lun *lun = cmd->se_lun; struct se_device *dev = cmd->se_dev; @@ -96,7 +93,7 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) * Enable SCCS and TPGS fields for Emulated ALUA */ if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) - spc_fill_alua_data(lun->lun_sep, buf); + target_fill_alua_data(lun->lun_sep, buf); buf[7] = 0x2; /* CmdQue=1 */ @@ -109,7 +106,8 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) } /* unit serial number */ -static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; u16 len = 0; @@ -129,8 +127,8 @@ static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) return 0; } -static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, - unsigned char *buf) +static void +target_parse_naa_6h_vendor_specific(struct se_device *dev, unsigned char *buf) { unsigned char *p = &dev->se_sub_dev->t10_wwn.unit_serial[0]; int cnt; @@ -164,7 +162,8 @@ static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, * Device identification VPD, for a complete list of * DESIGNATOR TYPEs see spc4r17 Table 459. */ -static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; struct se_lun *lun = cmd->se_lun; @@ -221,7 +220,7 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) * VENDOR_SPECIFIC_IDENTIFIER and * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION */ - spc_parse_naa_6h_vendor_specific(dev, &buf[off]); + target_parse_naa_6h_vendor_specific(dev, &buf[off]); len = 20; off = (len + 4); @@ -415,7 +414,8 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) } /* Extended INQUIRY Data VPD Page */ -static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) { buf[3] = 0x3c; /* Set HEADSUP, ORDSUP, SIMPSUP */ @@ -428,14 +428,15 @@ static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) } /* Block Limits VPD page */ -static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; u32 max_sectors; int have_tp = 0; /* - * Following spc3r22 section 6.5.3 Block Limits VPD page, when + * Following sbc3r22 section 6.5.3 Block Limits VPD page, when * emulate_tpu=1 or emulate_tpws=1 we will be expect a * different page length for Thin Provisioning. */ @@ -499,7 +500,8 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) } /* Block Device Characteristics VPD page */ -static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; @@ -511,12 +513,13 @@ static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) } /* Thin Provisioning VPD */ -static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; /* - * From spc3r22 section 6.5.4 Thin Provisioning VPD page: + * From sbc3r22 section 6.5.4 Thin Provisioning VPD page: * * The PAGE LENGTH field is defined in SPC-4. If the DP bit is set to * zero, then the page length shall be set to 0004h. If the DP bit @@ -561,23 +564,25 @@ static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) return 0; } -static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); +static int +target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); static struct { uint8_t page; int (*emulate)(struct se_cmd *, unsigned char *); } evpd_handlers[] = { - { .page = 0x00, .emulate = spc_emulate_evpd_00 }, - { .page = 0x80, .emulate = spc_emulate_evpd_80 }, - { .page = 0x83, .emulate = spc_emulate_evpd_83 }, - { .page = 0x86, .emulate = spc_emulate_evpd_86 }, - { .page = 0xb0, .emulate = spc_emulate_evpd_b0 }, - { .page = 0xb1, .emulate = spc_emulate_evpd_b1 }, - { .page = 0xb2, .emulate = spc_emulate_evpd_b2 }, + { .page = 0x00, .emulate = target_emulate_evpd_00 }, + { .page = 0x80, .emulate = target_emulate_evpd_80 }, + { .page = 0x83, .emulate = target_emulate_evpd_83 }, + { .page = 0x86, .emulate = target_emulate_evpd_86 }, + { .page = 0xb0, .emulate = target_emulate_evpd_b0 }, + { .page = 0xb1, .emulate = target_emulate_evpd_b1 }, + { .page = 0xb2, .emulate = target_emulate_evpd_b2 }, }; /* supported vital product data pages */ -static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) +static int +target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) { int p; @@ -596,7 +601,7 @@ static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) return 0; } -static int spc_emulate_inquiry(struct se_cmd *cmd) +int target_emulate_inquiry(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; @@ -638,7 +643,7 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) goto out; } - ret = spc_emulate_inquiry_std(cmd, buf); + ret = target_emulate_inquiry_std(cmd, buf); goto out; } @@ -666,7 +671,70 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) return ret; } -static int spc_modesense_rwrecovery(unsigned char *p) +int target_emulate_readcapacity(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + unsigned char *buf; + unsigned long long blocks_long = dev->transport->get_blocks(dev); + u32 blocks; + + if (blocks_long >= 0x00000000ffffffff) + blocks = 0xffffffff; + else + blocks = (u32)blocks_long; + + buf = transport_kmap_data_sg(cmd); + + buf[0] = (blocks >> 24) & 0xff; + buf[1] = (blocks >> 16) & 0xff; + buf[2] = (blocks >> 8) & 0xff; + buf[3] = blocks & 0xff; + buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; + buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; + buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; + buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; + + transport_kunmap_data_sg(cmd); + + target_complete_cmd(cmd, GOOD); + return 0; +} + +int target_emulate_readcapacity_16(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + unsigned char *buf; + unsigned long long blocks = dev->transport->get_blocks(dev); + + buf = transport_kmap_data_sg(cmd); + + buf[0] = (blocks >> 56) & 0xff; + buf[1] = (blocks >> 48) & 0xff; + buf[2] = (blocks >> 40) & 0xff; + buf[3] = (blocks >> 32) & 0xff; + buf[4] = (blocks >> 24) & 0xff; + buf[5] = (blocks >> 16) & 0xff; + buf[6] = (blocks >> 8) & 0xff; + buf[7] = blocks & 0xff; + buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; + buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; + buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; + buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; + /* + * Set Thin Provisioning Enable bit following sbc3r22 in section + * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled. + */ + if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) + buf[14] = 0x80; + + transport_kunmap_data_sg(cmd); + + target_complete_cmd(cmd, GOOD); + return 0; +} + +static int +target_modesense_rwrecovery(unsigned char *p) { p[0] = 0x01; p[1] = 0x0a; @@ -674,7 +742,8 @@ static int spc_modesense_rwrecovery(unsigned char *p) return 12; } -static int spc_modesense_control(struct se_device *dev, unsigned char *p) +static int +target_modesense_control(struct se_device *dev, unsigned char *p) { p[0] = 0x0a; p[1] = 0x0a; @@ -759,7 +828,8 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p) return 12; } -static int spc_modesense_caching(struct se_device *dev, unsigned char *p) +static int +target_modesense_caching(struct se_device *dev, unsigned char *p) { p[0] = 0x08; p[1] = 0x12; @@ -770,7 +840,8 @@ static int spc_modesense_caching(struct se_device *dev, unsigned char *p) return 20; } -static void spc_modesense_write_protect(unsigned char *buf, int type) +static void +target_modesense_write_protect(unsigned char *buf, int type) { /* * I believe that the WP bit (bit 7) in the mode header is the same for @@ -785,7 +856,8 @@ static void spc_modesense_write_protect(unsigned char *buf, int type) } } -static void spc_modesense_dpofua(unsigned char *buf, int type) +static void +target_modesense_dpofua(unsigned char *buf, int type) { switch (type) { case TYPE_DISK: @@ -796,7 +868,7 @@ static void spc_modesense_dpofua(unsigned char *buf, int type) } } -static int spc_emulate_modesense(struct se_cmd *cmd) +int target_emulate_modesense(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; char *cdb = cmd->t_task_cdb; @@ -811,18 +883,18 @@ static int spc_emulate_modesense(struct se_cmd *cmd) switch (cdb[2] & 0x3f) { case 0x01: - length = spc_modesense_rwrecovery(&buf[offset]); + length = target_modesense_rwrecovery(&buf[offset]); break; case 0x08: - length = spc_modesense_caching(dev, &buf[offset]); + length = target_modesense_caching(dev, &buf[offset]); break; case 0x0a: - length = spc_modesense_control(dev, &buf[offset]); + length = target_modesense_control(dev, &buf[offset]); break; case 0x3f: - length = spc_modesense_rwrecovery(&buf[offset]); - length += spc_modesense_caching(dev, &buf[offset+length]); - length += spc_modesense_control(dev, &buf[offset+length]); + length = target_modesense_rwrecovery(&buf[offset]); + length += target_modesense_caching(dev, &buf[offset+length]); + length += target_modesense_control(dev, &buf[offset+length]); break; default: pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", @@ -840,11 +912,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd) if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) - spc_modesense_write_protect(&buf[3], type); + target_modesense_write_protect(&buf[3], type); if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) - spc_modesense_dpofua(&buf[3], type); + target_modesense_dpofua(&buf[3], type); if ((offset + 2) > cmd->data_length) offset = cmd->data_length; @@ -856,11 +928,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd) if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) - spc_modesense_write_protect(&buf[2], type); + target_modesense_write_protect(&buf[2], type); if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) - spc_modesense_dpofua(&buf[2], type); + target_modesense_dpofua(&buf[2], type); if ((offset + 1) > cmd->data_length) offset = cmd->data_length; @@ -874,7 +946,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd) return 0; } -static int spc_emulate_request_sense(struct se_cmd *cmd) +int target_emulate_request_sense(struct se_cmd *cmd) { unsigned char *cdb = cmd->t_task_cdb; unsigned char *buf; @@ -933,172 +1005,126 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) return 0; } -static int spc_emulate_testunitready(struct se_cmd *cmd) +/* + * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. + * Note this is not used for TCM/pSCSI passthrough + */ +int target_emulate_unmap(struct se_cmd *cmd) { - target_complete_cmd(cmd, GOOD); - return 0; + struct se_device *dev = cmd->se_dev; + unsigned char *buf, *ptr = NULL; + unsigned char *cdb = &cmd->t_task_cdb[0]; + sector_t lba; + unsigned int size = cmd->data_length, range; + int ret = 0, offset; + unsigned short dl, bd_dl; + + if (!dev->transport->do_discard) { + pr_err("UNMAP emulation not supported for: %s\n", + dev->transport->name); + cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; + return -ENOSYS; + } + + /* First UNMAP block descriptor starts at 8 byte offset */ + offset = 8; + size -= 8; + dl = get_unaligned_be16(&cdb[0]); + bd_dl = get_unaligned_be16(&cdb[2]); + + buf = transport_kmap_data_sg(cmd); + + ptr = &buf[offset]; + pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu" + " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); + + while (size) { + lba = get_unaligned_be64(&ptr[0]); + range = get_unaligned_be32(&ptr[8]); + pr_debug("UNMAP: Using lba: %llu and range: %u\n", + (unsigned long long)lba, range); + + ret = dev->transport->do_discard(dev, lba, range); + if (ret < 0) { + pr_err("blkdev_issue_discard() failed: %d\n", + ret); + goto err; + } + + ptr += 16; + size -= 16; + } + +err: + transport_kunmap_data_sg(cmd); + if (!ret) + target_complete_cmd(cmd, GOOD); + return ret; } -int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) +/* + * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. + * Note this is not used for TCM/pSCSI passthrough + */ +int target_emulate_write_same(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - struct se_subsystem_dev *su_dev = dev->se_sub_dev; - unsigned char *cdb = cmd->t_task_cdb; + sector_t range; + sector_t lba = cmd->t_task_lba; + u32 num_blocks; + int ret; + + if (!dev->transport->do_discard) { + pr_err("WRITE_SAME emulation not supported" + " for: %s\n", dev->transport->name); + cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; + return -ENOSYS; + } - switch (cdb[0]) { - case MODE_SELECT: - *size = cdb[4]; - break; - case MODE_SELECT_10: - *size = (cdb[7] << 8) + cdb[8]; - break; - case MODE_SENSE: - *size = cdb[4]; - cmd->execute_cmd = spc_emulate_modesense; - break; - case MODE_SENSE_10: - *size = (cdb[7] << 8) + cdb[8]; - cmd->execute_cmd = spc_emulate_modesense; - break; - case LOG_SELECT: - case LOG_SENSE: - *size = (cdb[7] << 8) + cdb[8]; - break; - case PERSISTENT_RESERVE_IN: - if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) - cmd->execute_cmd = target_scsi3_emulate_pr_in; - *size = (cdb[7] << 8) + cdb[8]; - break; - case PERSISTENT_RESERVE_OUT: - if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) - cmd->execute_cmd = target_scsi3_emulate_pr_out; - *size = (cdb[7] << 8) + cdb[8]; - break; - case RELEASE: - case RELEASE_10: - if (cdb[0] == RELEASE_10) - *size = (cdb[7] << 8) | cdb[8]; - else - *size = cmd->data_length; - - if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) - cmd->execute_cmd = target_scsi2_reservation_release; - break; - case RESERVE: - case RESERVE_10: - /* - * The SPC-2 RESERVE does not contain a size in the SCSI CDB. - * Assume the passthrough or $FABRIC_MOD will tell us about it. - */ - if (cdb[0] == RESERVE_10) - *size = (cdb[7] << 8) | cdb[8]; - else - *size = cmd->data_length; + if (cmd->t_task_cdb[0] == WRITE_SAME) + num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); + else if (cmd->t_task_cdb[0] == WRITE_SAME_16) + num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); + else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */ + num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); - /* - * Setup the legacy emulated handler for SPC-2 and - * >= SPC-3 compatible reservation handling (CRH=1) - * Otherwise, we assume the underlying SCSI logic is - * is running in SPC_PASSTHROUGH, and wants reservations - * emulation disabled. - */ - if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) - cmd->execute_cmd = target_scsi2_reservation_reserve; - break; - case REQUEST_SENSE: - *size = cdb[4]; - cmd->execute_cmd = spc_emulate_request_sense; - break; - case INQUIRY: - *size = (cdb[3] << 8) + cdb[4]; + /* + * Use the explicit range when non zero is supplied, otherwise calculate + * the remaining range based on ->get_blocks() - starting LBA. + */ + if (num_blocks != 0) + range = num_blocks; + else + range = (dev->transport->get_blocks(dev) - lba); - /* - * Do implict HEAD_OF_QUEUE processing for INQUIRY. - * See spc4r17 section 5.3 - */ - if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) - cmd->sam_task_attr = MSG_HEAD_TAG; - cmd->execute_cmd = spc_emulate_inquiry; - break; - case SECURITY_PROTOCOL_IN: - case SECURITY_PROTOCOL_OUT: - *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - break; - case EXTENDED_COPY: - case READ_ATTRIBUTE: - case RECEIVE_COPY_RESULTS: - case WRITE_ATTRIBUTE: - *size = (cdb[10] << 24) | (cdb[11] << 16) | - (cdb[12] << 8) | cdb[13]; - break; - case RECEIVE_DIAGNOSTIC: - case SEND_DIAGNOSTIC: - *size = (cdb[3] << 8) | cdb[4]; - break; - case WRITE_BUFFER: - *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; - break; - case REPORT_LUNS: - cmd->execute_cmd = target_report_luns; - *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - /* - * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS - * See spc4r17 section 5.3 - */ - if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) - cmd->sam_task_attr = MSG_HEAD_TAG; - break; - case TEST_UNIT_READY: - cmd->execute_cmd = spc_emulate_testunitready; - *size = 0; - break; - case MAINTENANCE_IN: - if (dev->transport->get_device_type(dev) != TYPE_ROM) { - /* - * MAINTENANCE_IN from SCC-2 - * Check for emulated MI_REPORT_TARGET_PGS - */ - if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS && - su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { - cmd->execute_cmd = - target_emulate_report_target_port_groups; - } - *size = get_unaligned_be32(&cdb[6]); - } else { - /* - * GPCMD_SEND_KEY from multi media commands - */ - *size = get_unaligned_be16(&cdb[8]); - } - break; - case MAINTENANCE_OUT: - if (dev->transport->get_device_type(dev) != TYPE_ROM) { - /* - * MAINTENANCE_OUT from SCC-2 - * Check for emulated MO_SET_TARGET_PGS. - */ - if (cdb[1] == MO_SET_TARGET_PGS && - su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { - cmd->execute_cmd = - target_emulate_set_target_port_groups; - } - *size = get_unaligned_be32(&cdb[6]); - } else { - /* - * GPCMD_SEND_KEY from multi media commands - */ - *size = get_unaligned_be16(&cdb[8]); - } - break; - default: - pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" - " 0x%02x, sending CHECK_CONDITION.\n", - cmd->se_tfo->get_fabric_name(), cdb[0]); - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", + (unsigned long long)lba, (unsigned long long)range); + + ret = dev->transport->do_discard(dev, lba, range); + if (ret < 0) { + pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); + return ret; + } + + target_complete_cmd(cmd, GOOD); + return 0; +} + +int target_emulate_synchronize_cache(struct se_cmd *cmd) +{ + if (!cmd->se_dev->transport->do_sync_cache) { + pr_err("SYNCHRONIZE_CACHE emulation not supported" + " for: %s\n", cmd->se_dev->transport->name); cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - return -EINVAL; + return -ENOSYS; } + cmd->se_dev->transport->do_sync_cache(cmd); + return 0; +} + +int target_emulate_noop(struct se_cmd *cmd) +{ + target_complete_cmd(cmd, GOOD); return 0; } -EXPORT_SYMBOL(spc_parse_cdb); diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index cf2c66f3c116..5ad972856a8d 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -300,8 +300,8 @@ int core_free_device_list_for_node( lun = deve->se_lun; spin_unlock_irq(&nacl->device_list_lock); - core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, - TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); + core_update_device_list_for_node(lun, NULL, deve->mapped_lun, + TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg, 0); spin_lock_irq(&nacl->device_list_lock); } spin_unlock_irq(&nacl->device_list_lock); @@ -342,46 +342,72 @@ void core_update_device_list_access( spin_unlock_irq(&nacl->device_list_lock); } -/* core_enable_device_list_for_node(): +/* core_update_device_list_for_node(): * * */ -int core_enable_device_list_for_node( +int core_update_device_list_for_node( struct se_lun *lun, struct se_lun_acl *lun_acl, u32 mapped_lun, u32 lun_access, struct se_node_acl *nacl, - struct se_portal_group *tpg) + struct se_portal_group *tpg, + int enable) { struct se_port *port = lun->lun_sep; - struct se_dev_entry *deve; - - spin_lock_irq(&nacl->device_list_lock); - - deve = nacl->device_list[mapped_lun]; - + struct se_dev_entry *deve = nacl->device_list[mapped_lun]; + int trans = 0; /* - * Check if the call is handling demo mode -> explict LUN ACL - * transition. This transition must be for the same struct se_lun - * + mapped_lun that was setup in demo mode.. + * If the MappedLUN entry is being disabled, the entry in + * port->sep_alua_list must be removed now before clearing the + * struct se_dev_entry pointers below as logic in + * core_alua_do_transition_tg_pt() depends on these being present. */ - if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { - if (deve->se_lun_acl != NULL) { - pr_err("struct se_dev_entry->se_lun_acl" - " already set for demo mode -> explict" - " LUN ACL transition\n"); - spin_unlock_irq(&nacl->device_list_lock); - return -EINVAL; - } - if (deve->se_lun != lun) { - pr_err("struct se_dev_entry->se_lun does" - " match passed struct se_lun for demo mode" - " -> explict LUN ACL transition\n"); - spin_unlock_irq(&nacl->device_list_lock); - return -EINVAL; + if (!enable) { + /* + * deve->se_lun_acl will be NULL for demo-mode created LUNs + * that have not been explicitly concerted to MappedLUNs -> + * struct se_lun_acl, but we remove deve->alua_port_list from + * port->sep_alua_list. This also means that active UAs and + * NodeACL context specific PR metadata for demo-mode + * MappedLUN *deve will be released below.. + */ + spin_lock_bh(&port->sep_alua_lock); + list_del(&deve->alua_port_list); + spin_unlock_bh(&port->sep_alua_lock); + } + + spin_lock_irq(&nacl->device_list_lock); + if (enable) { + /* + * Check if the call is handling demo mode -> explict LUN ACL + * transition. This transition must be for the same struct se_lun + * + mapped_lun that was setup in demo mode.. + */ + if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { + if (deve->se_lun_acl != NULL) { + pr_err("struct se_dev_entry->se_lun_acl" + " already set for demo mode -> explict" + " LUN ACL transition\n"); + spin_unlock_irq(&nacl->device_list_lock); + return -EINVAL; + } + if (deve->se_lun != lun) { + pr_err("struct se_dev_entry->se_lun does" + " match passed struct se_lun for demo mode" + " -> explict LUN ACL transition\n"); + spin_unlock_irq(&nacl->device_list_lock); + return -EINVAL; + } + deve->se_lun_acl = lun_acl; + trans = 1; + } else { + deve->se_lun = lun; + deve->se_lun_acl = lun_acl; + deve->mapped_lun = mapped_lun; + deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; } - deve->se_lun_acl = lun_acl; if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; @@ -391,72 +417,27 @@ int core_enable_device_list_for_node( deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; } + if (trans) { + spin_unlock_irq(&nacl->device_list_lock); + return 0; + } + deve->creation_time = get_jiffies_64(); + deve->attach_count++; spin_unlock_irq(&nacl->device_list_lock); - return 0; - } - deve->se_lun = lun; - deve->se_lun_acl = lun_acl; - deve->mapped_lun = mapped_lun; - deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; + spin_lock_bh(&port->sep_alua_lock); + list_add_tail(&deve->alua_port_list, &port->sep_alua_list); + spin_unlock_bh(&port->sep_alua_lock); - if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; - } else { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; + return 0; } - - deve->creation_time = get_jiffies_64(); - deve->attach_count++; - spin_unlock_irq(&nacl->device_list_lock); - - spin_lock_bh(&port->sep_alua_lock); - list_add_tail(&deve->alua_port_list, &port->sep_alua_list); - spin_unlock_bh(&port->sep_alua_lock); - - return 0; -} - -/* core_disable_device_list_for_node(): - * - * - */ -int core_disable_device_list_for_node( - struct se_lun *lun, - struct se_lun_acl *lun_acl, - u32 mapped_lun, - u32 lun_access, - struct se_node_acl *nacl, - struct se_portal_group *tpg) -{ - struct se_port *port = lun->lun_sep; - struct se_dev_entry *deve = nacl->device_list[mapped_lun]; - - /* - * If the MappedLUN entry is being disabled, the entry in - * port->sep_alua_list must be removed now before clearing the - * struct se_dev_entry pointers below as logic in - * core_alua_do_transition_tg_pt() depends on these being present. - * - * deve->se_lun_acl will be NULL for demo-mode created LUNs - * that have not been explicitly converted to MappedLUNs -> - * struct se_lun_acl, but we remove deve->alua_port_list from - * port->sep_alua_list. This also means that active UAs and - * NodeACL context specific PR metadata for demo-mode - * MappedLUN *deve will be released below.. - */ - spin_lock_bh(&port->sep_alua_lock); - list_del(&deve->alua_port_list); - spin_unlock_bh(&port->sep_alua_lock); /* * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE * PR operation to complete. */ + spin_unlock_irq(&nacl->device_list_lock); while (atomic_read(&deve->pr_ref_count) != 0) cpu_relax(); - spin_lock_irq(&nacl->device_list_lock); /* * Disable struct se_dev_entry LUN ACL mapping @@ -494,9 +475,9 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) continue; spin_unlock_irq(&nacl->device_list_lock); - core_disable_device_list_for_node(lun, NULL, + core_update_device_list_for_node(lun, NULL, deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, - nacl, tpg); + nacl, tpg, 0); spin_lock_irq(&nacl->device_list_lock); } @@ -734,7 +715,7 @@ void se_release_device_for_hba(struct se_device *dev) se_dev_stop(dev); if (dev->dev_ptr) { - destroy_workqueue(dev->tmr_wq); + kthread_stop(dev->process_thread); if (dev->transport->free_device) dev->transport->free_device(dev->dev_ptr); } @@ -841,7 +822,7 @@ int se_dev_check_shutdown(struct se_device *dev) return ret; } -static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) +u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) { u32 tmp, aligned_max_sectors; /* @@ -1292,6 +1273,7 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size) struct se_lun *core_dev_add_lun( struct se_portal_group *tpg, + struct se_hba *hba, struct se_device *dev, u32 lun) { @@ -1316,7 +1298,7 @@ struct se_lun *core_dev_add_lun( pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun_p->unpacked_lun, - tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); + tpg->se_tpg_tfo->get_fabric_name(), hba->hba_id); /* * Update LUN maps for dynamically added initiators when * generate_node_acl is enabled. @@ -1488,8 +1470,8 @@ int core_dev_add_initiator_node_lun_acl( lacl->se_lun = lun; - if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun, - lun_access, nacl, tpg) < 0) + if (core_update_device_list_for_node(lun, lacl, lacl->mapped_lun, + lun_access, nacl, tpg, 1) < 0) return -EINVAL; spin_lock(&lun->lun_acl_lock); @@ -1532,8 +1514,8 @@ int core_dev_del_initiator_node_lun_acl( smp_mb__after_atomic_dec(); spin_unlock(&lun->lun_acl_lock); - core_disable_device_list_for_node(lun, NULL, lacl->mapped_lun, - TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); + core_update_device_list_for_node(lun, NULL, lacl->mapped_lun, + TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg, 0); lacl->se_lun = NULL; diff --git a/trunk/drivers/target/target_core_fabric_configfs.c b/trunk/drivers/target/target_core_fabric_configfs.c index ea479e54f5fd..405cc98eaed6 100644 --- a/trunk/drivers/target/target_core_fabric_configfs.c +++ b/trunk/drivers/target/target_core_fabric_configfs.c @@ -764,7 +764,8 @@ static int target_fabric_port_link( goto out; } - lun_p = core_dev_add_lun(se_tpg, dev, lun->unpacked_lun); + lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev, + lun->unpacked_lun); if (IS_ERR(lun_p)) { pr_err("core_dev_add_lun() failed\n"); ret = PTR_ERR(lun_p); diff --git a/trunk/drivers/target/target_core_file.c b/trunk/drivers/target/target_core_file.c index 9e2100551c78..686dba189f8e 100644 --- a/trunk/drivers/target/target_core_file.c +++ b/trunk/drivers/target/target_core_file.c @@ -133,11 +133,16 @@ static struct se_device *fd_create_virtdevice( ret = PTR_ERR(dev_p); goto fail; } + + /* O_DIRECT too? */ + flags = O_RDWR | O_CREAT | O_LARGEFILE; + /* - * Use O_DSYNC by default instead of O_SYNC to forgo syncing - * of pure timestamp updates. + * If fd_buffered_io=1 has not been set explicitly (the default), + * use O_SYNC to force FILEIO writes to disk. */ - flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; + if (!(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO)) + flags |= O_SYNC; file = filp_open(dev_p, flags, 0600); if (IS_ERR(file)) { @@ -331,7 +336,7 @@ static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl, return 1; } -static int fd_execute_sync_cache(struct se_cmd *cmd) +static void fd_emulate_sync_cache(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct fd_dev *fd_dev = dev->dev_ptr; @@ -365,7 +370,7 @@ static int fd_execute_sync_cache(struct se_cmd *cmd) pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); if (immed) - return 0; + return; if (ret) { cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; @@ -373,15 +378,28 @@ static int fd_execute_sync_cache(struct se_cmd *cmd) } else { target_complete_cmd(cmd, SAM_STAT_GOOD); } +} - return 0; +static void fd_emulate_write_fua(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + struct fd_dev *fd_dev = dev->dev_ptr; + loff_t start = cmd->t_task_lba * + dev->se_sub_dev->se_dev_attrib.block_size; + loff_t end = start + cmd->data_length; + int ret; + + pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n", + cmd->t_task_lba, cmd->data_length); + + ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1); + if (ret != 0) + pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); } -static int fd_execute_rw(struct se_cmd *cmd) +static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, + u32 sgl_nents, enum dma_data_direction data_direction) { - struct scatterlist *sgl = cmd->t_data_sg; - u32 sgl_nents = cmd->t_data_nents; - enum dma_data_direction data_direction = cmd->data_direction; struct se_device *dev = cmd->se_dev; int ret = 0; @@ -393,21 +411,19 @@ static int fd_execute_rw(struct se_cmd *cmd) ret = fd_do_readv(cmd, sgl, sgl_nents); } else { ret = fd_do_writev(cmd, sgl, sgl_nents); - /* - * Perform implict vfs_fsync_range() for fd_do_writev() ops - * for SCSI WRITEs with Forced Unit Access (FUA) set. - * Allow this to happen independent of WCE=0 setting. - */ + if (ret > 0 && + dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && (cmd->se_cmd_flags & SCF_FUA)) { - struct fd_dev *fd_dev = dev->dev_ptr; - loff_t start = cmd->t_task_lba * - dev->se_sub_dev->se_dev_attrib.block_size; - loff_t end = start + cmd->data_length; - - vfs_fsync_range(fd_dev->fd_file, start, end, 1); + /* + * We might need to be a bit smarter here + * and return some sense data to let the initiator + * know the FUA WRITE cache sync failed..? + */ + fd_emulate_write_fua(cmd); } + } if (ret < 0) { @@ -426,6 +442,7 @@ enum { static match_table_t tokens = { {Opt_fd_dev_name, "fd_dev_name=%s"}, {Opt_fd_dev_size, "fd_dev_size=%s"}, + {Opt_fd_buffered_io, "fd_buffered_io=%d"}, {Opt_err, NULL} }; @@ -437,7 +454,7 @@ static ssize_t fd_set_configfs_dev_params( struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; char *orig, *ptr, *arg_p, *opts; substring_t args[MAX_OPT_ARGS]; - int ret = 0, token; + int ret = 0, arg, token; opts = kstrdup(page, GFP_KERNEL); if (!opts) @@ -481,6 +498,19 @@ static ssize_t fd_set_configfs_dev_params( " bytes\n", fd_dev->fd_dev_size); fd_dev->fbd_flags |= FBDF_HAS_SIZE; break; + case Opt_fd_buffered_io: + match_int(args, &arg); + if (arg != 1) { + pr_err("bogus fd_buffered_io=%d value\n", arg); + ret = -EINVAL; + goto out; + } + + pr_debug("FILEIO: Using buffered I/O" + " operations for struct fd_dev\n"); + + fd_dev->fbd_flags |= FDBD_USE_BUFFERED_IO; + break; default: break; } @@ -512,8 +542,10 @@ static ssize_t fd_show_configfs_dev_params( ssize_t bl = 0; bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); - bl += sprintf(b + bl, " File: %s Size: %llu Mode: O_DSYNC\n", - fd_dev->fd_dev_name, fd_dev->fd_dev_size); + bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n", + fd_dev->fd_dev_name, fd_dev->fd_dev_size, + (fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO) ? + "Buffered" : "Synchronous"); return bl; } @@ -554,16 +586,6 @@ static sector_t fd_get_blocks(struct se_device *dev) return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size); } -static struct spc_ops fd_spc_ops = { - .execute_rw = fd_execute_rw, - .execute_sync_cache = fd_execute_sync_cache, -}; - -static int fd_parse_cdb(struct se_cmd *cmd) -{ - return sbc_parse_cdb(cmd, &fd_spc_ops); -} - static struct se_subsystem_api fileio_template = { .name = "fileio", .owner = THIS_MODULE, @@ -575,7 +597,8 @@ static struct se_subsystem_api fileio_template = { .allocate_virtdevice = fd_allocate_virtdevice, .create_virtdevice = fd_create_virtdevice, .free_device = fd_free_device, - .parse_cdb = fd_parse_cdb, + .execute_cmd = fd_execute_cmd, + .do_sync_cache = fd_emulate_sync_cache, .check_configfs_dev_params = fd_check_configfs_dev_params, .set_configfs_dev_params = fd_set_configfs_dev_params, .show_configfs_dev_params = fd_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_file.h b/trunk/drivers/target/target_core_file.h index 70ce7fd7111d..fbd59ef7d8be 100644 --- a/trunk/drivers/target/target_core_file.h +++ b/trunk/drivers/target/target_core_file.h @@ -14,6 +14,7 @@ #define FBDF_HAS_PATH 0x01 #define FBDF_HAS_SIZE 0x02 +#define FDBD_USE_BUFFERED_IO 0x04 struct fd_dev { u32 fbd_flags; diff --git a/trunk/drivers/target/target_core_iblock.c b/trunk/drivers/target/target_core_iblock.c index 76db75e836ed..fd47950727b4 100644 --- a/trunk/drivers/target/target_core_iblock.c +++ b/trunk/drivers/target/target_core_iblock.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -97,7 +96,6 @@ static struct se_device *iblock_create_virtdevice( struct request_queue *q; struct queue_limits *limits; u32 dev_flags = 0; - fmode_t mode; int ret = -EINVAL; if (!ib_dev) { @@ -119,11 +117,8 @@ static struct se_device *iblock_create_virtdevice( pr_debug( "IBLOCK: Claiming struct block_device: %s\n", ib_dev->ibd_udev_path); - mode = FMODE_READ|FMODE_EXCL; - if (!ib_dev->ibd_readonly) - mode |= FMODE_WRITE; - - bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); + bd = blkdev_get_by_path(ib_dev->ibd_udev_path, + FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); if (IS_ERR(bd)) { ret = PTR_ERR(bd); goto failed; @@ -297,7 +292,7 @@ static void iblock_end_io_flush(struct bio *bio, int err) * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must * always flush the whole cache. */ -static int iblock_execute_sync_cache(struct se_cmd *cmd) +static void iblock_emulate_sync_cache(struct se_cmd *cmd) { struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr; int immed = (cmd->t_task_cdb[1] & 0x2); @@ -316,98 +311,23 @@ static int iblock_execute_sync_cache(struct se_cmd *cmd) if (!immed) bio->bi_private = cmd; submit_bio(WRITE_FLUSH, bio); - return 0; } -static int iblock_execute_unmap(struct se_cmd *cmd) +static int iblock_do_discard(struct se_device *dev, sector_t lba, u32 range) { - struct se_device *dev = cmd->se_dev; struct iblock_dev *ibd = dev->dev_ptr; - unsigned char *buf, *ptr = NULL; - sector_t lba; - int size = cmd->data_length; - u32 range; - int ret = 0; - int dl, bd_dl; - - buf = transport_kmap_data_sg(cmd); - - dl = get_unaligned_be16(&buf[0]); - bd_dl = get_unaligned_be16(&buf[2]); - - size = min(size - 8, bd_dl); - if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; - goto err; - } - - /* First UNMAP block descriptor starts at 8 byte offset */ - ptr = &buf[8]; - pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u" - " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); - - while (size >= 16) { - lba = get_unaligned_be64(&ptr[0]); - range = get_unaligned_be32(&ptr[8]); - pr_debug("UNMAP: Using lba: %llu and range: %u\n", - (unsigned long long)lba, range); - - if (range > dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count) { - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; - goto err; - } - - if (lba + range > dev->transport->get_blocks(dev) + 1) { - cmd->scsi_sense_reason = TCM_ADDRESS_OUT_OF_RANGE; - ret = -EINVAL; - goto err; - } - - ret = blkdev_issue_discard(ibd->ibd_bd, lba, range, - GFP_KERNEL, 0); - if (ret < 0) { - pr_err("blkdev_issue_discard() failed: %d\n", - ret); - goto err; - } - - ptr += 16; - size -= 16; - } - -err: - transport_kunmap_data_sg(cmd); - if (!ret) - target_complete_cmd(cmd, GOOD); - return ret; -} - -static int iblock_execute_write_same(struct se_cmd *cmd) -{ - struct iblock_dev *ibd = cmd->se_dev->dev_ptr; - int ret; - - ret = blkdev_issue_discard(ibd->ibd_bd, cmd->t_task_lba, - spc_get_write_same_sectors(cmd), GFP_KERNEL, - 0); - if (ret < 0) { - pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); - return ret; - } + struct block_device *bd = ibd->ibd_bd; + int barrier = 0; - target_complete_cmd(cmd, GOOD); - return 0; + return blkdev_issue_discard(bd, lba, range, GFP_KERNEL, barrier); } enum { - Opt_udev_path, Opt_readonly, Opt_force, Opt_err + Opt_udev_path, Opt_force, Opt_err }; static match_table_t tokens = { {Opt_udev_path, "udev_path=%s"}, - {Opt_readonly, "readonly=%d"}, {Opt_force, "force=%d"}, {Opt_err, NULL} }; @@ -420,7 +340,6 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, char *orig, *ptr, *arg_p, *opts; substring_t args[MAX_OPT_ARGS]; int ret = 0, token; - unsigned long tmp_readonly; opts = kstrdup(page, GFP_KERNEL); if (!opts) @@ -453,22 +372,6 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, ib_dev->ibd_udev_path); ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; break; - case Opt_readonly: - arg_p = match_strdup(&args[0]); - if (!arg_p) { - ret = -ENOMEM; - break; - } - ret = strict_strtoul(arg_p, 0, &tmp_readonly); - kfree(arg_p); - if (ret < 0) { - pr_err("strict_strtoul() failed for" - " readonly=\n"); - goto out; - } - ib_dev->ibd_readonly = tmp_readonly; - pr_debug("IBLOCK: readonly: %d\n", ib_dev->ibd_readonly); - break; case Opt_force: break; default: @@ -508,10 +411,11 @@ static ssize_t iblock_show_configfs_dev_params( if (bd) bl += sprintf(b + bl, "iBlock device: %s", bdevname(bd, buf)); - if (ibd->ibd_flags & IBDF_HAS_UDEV_PATH) - bl += sprintf(b + bl, " UDEV PATH: %s", + if (ibd->ibd_flags & IBDF_HAS_UDEV_PATH) { + bl += sprintf(b + bl, " UDEV PATH: %s\n", ibd->ibd_udev_path); - bl += sprintf(b + bl, " readonly: %d\n", ibd->ibd_readonly); + } else + bl += sprintf(b + bl, "\n"); bl += sprintf(b + bl, " "); if (bd) { @@ -589,11 +493,9 @@ static void iblock_submit_bios(struct bio_list *list, int rw) blk_finish_plug(&plug); } -static int iblock_execute_rw(struct se_cmd *cmd) +static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, + u32 sgl_nents, enum dma_data_direction data_direction) { - struct scatterlist *sgl = cmd->t_data_sg; - u32 sgl_nents = cmd->t_data_nents; - enum dma_data_direction data_direction = cmd->data_direction; struct se_device *dev = cmd->se_dev; struct iblock_req *ibr; struct bio *bio; @@ -740,18 +642,6 @@ static void iblock_bio_done(struct bio *bio, int err) iblock_complete_cmd(cmd); } -static struct spc_ops iblock_spc_ops = { - .execute_rw = iblock_execute_rw, - .execute_sync_cache = iblock_execute_sync_cache, - .execute_write_same = iblock_execute_write_same, - .execute_unmap = iblock_execute_unmap, -}; - -static int iblock_parse_cdb(struct se_cmd *cmd) -{ - return sbc_parse_cdb(cmd, &iblock_spc_ops); -} - static struct se_subsystem_api iblock_template = { .name = "iblock", .owner = THIS_MODULE, @@ -763,7 +653,9 @@ static struct se_subsystem_api iblock_template = { .allocate_virtdevice = iblock_allocate_virtdevice, .create_virtdevice = iblock_create_virtdevice, .free_device = iblock_free_device, - .parse_cdb = iblock_parse_cdb, + .execute_cmd = iblock_execute_cmd, + .do_discard = iblock_do_discard, + .do_sync_cache = iblock_emulate_sync_cache, .check_configfs_dev_params = iblock_check_configfs_dev_params, .set_configfs_dev_params = iblock_set_configfs_dev_params, .show_configfs_dev_params = iblock_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_iblock.h b/trunk/drivers/target/target_core_iblock.h index 533627ae79ec..66cf7b9e205e 100644 --- a/trunk/drivers/target/target_core_iblock.h +++ b/trunk/drivers/target/target_core_iblock.h @@ -18,7 +18,6 @@ struct iblock_dev { u32 ibd_flags; struct bio_set *ibd_bio_set; struct block_device *ibd_bd; - bool ibd_readonly; } ____cacheline_aligned; #endif /* TARGET_CORE_IBLOCK_H */ diff --git a/trunk/drivers/target/target_core_internal.h b/trunk/drivers/target/target_core_internal.h index 0fd428225d11..165e82429687 100644 --- a/trunk/drivers/target/target_core_internal.h +++ b/trunk/drivers/target/target_core_internal.h @@ -4,16 +4,25 @@ /* target_core_alua.c */ extern struct t10_alua_lu_gp *default_lu_gp; +/* target_core_cdb.c */ +int target_emulate_inquiry(struct se_cmd *cmd); +int target_emulate_readcapacity(struct se_cmd *cmd); +int target_emulate_readcapacity_16(struct se_cmd *cmd); +int target_emulate_modesense(struct se_cmd *cmd); +int target_emulate_request_sense(struct se_cmd *cmd); +int target_emulate_unmap(struct se_cmd *cmd); +int target_emulate_write_same(struct se_cmd *cmd); +int target_emulate_synchronize_cache(struct se_cmd *cmd); +int target_emulate_noop(struct se_cmd *cmd); + /* target_core_device.c */ struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); int core_free_device_list_for_node(struct se_node_acl *, struct se_portal_group *); void core_dec_lacl_count(struct se_node_acl *, struct se_cmd *); void core_update_device_list_access(u32, u32, struct se_node_acl *); -int core_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *, - u32, u32, struct se_node_acl *, struct se_portal_group *); -int core_disable_device_list_for_node(struct se_lun *, struct se_lun_acl *, - u32, u32, struct se_node_acl *, struct se_portal_group *); +int core_update_device_list_for_node(struct se_lun *, struct se_lun_acl *, + u32, u32, struct se_node_acl *, struct se_portal_group *, int); void core_clear_lun_from_tpg(struct se_lun *, struct se_portal_group *); int core_dev_export(struct se_device *, struct se_portal_group *, struct se_lun *); @@ -47,7 +56,8 @@ int se_dev_set_max_sectors(struct se_device *, u32); int se_dev_set_fabric_max_sectors(struct se_device *, u32); int se_dev_set_optimal_sectors(struct se_device *, u32); int se_dev_set_block_size(struct se_device *, u32); -struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, u32); +struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_hba *, + struct se_device *, u32); int core_dev_del_lun(struct se_portal_group *, u32); struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, @@ -94,6 +104,7 @@ void release_se_kmem_caches(void); u32 scsi_get_new_index(scsi_index_t); void transport_subsystem_check_init(void); void transport_cmd_finish_abort(struct se_cmd *, int); +void __target_remove_from_execute_list(struct se_cmd *); unsigned char *transport_dump_cmd_direction(struct se_cmd *); void transport_dump_dev_state(struct se_device *, char *, int *); void transport_dump_dev_info(struct se_device *, struct se_lun *, @@ -105,7 +116,6 @@ int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); int transport_clear_lun_from_sessions(struct se_lun *); void transport_send_task_abort(struct se_cmd *); -int target_cmd_size_check(struct se_cmd *cmd, unsigned int size); /* target_core_stat.c */ void target_stat_setup_dev_default_groups(struct se_subsystem_dev *); diff --git a/trunk/drivers/target/target_core_pr.c b/trunk/drivers/target/target_core_pr.c index 1e946502c378..85564998500a 100644 --- a/trunk/drivers/target/target_core_pr.c +++ b/trunk/drivers/target/target_core_pr.c @@ -507,7 +507,7 @@ static int core_scsi3_pr_seq_non_holder( * Check if write exclusive initiator ports *NOT* holding the * WRITE_EXCLUSIVE_* reservation. */ - if (we && !registered_nexus) { + if ((we) && !(registered_nexus)) { if (cmd->data_direction == DMA_TO_DEVICE) { /* * Conflict for write exclusive @@ -2031,7 +2031,7 @@ static int __core_scsi3_write_aptpl_to_file( if (IS_ERR(file) || !file || !file->f_dentry) { pr_err("filp_open(%s) for APTPL metadata" " failed\n", path); - return IS_ERR(file) ? PTR_ERR(file) : -ENOENT; + return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT); } iov[0].iov_base = &buf[0]; @@ -2486,7 +2486,7 @@ static int core_scsi3_pro_reserve( */ spin_lock(&dev->dev_reservation_lock); pr_res_holder = dev->dev_pr_res_holder; - if (pr_res_holder) { + if ((pr_res_holder)) { /* * From spc4r17 Section 5.7.9: Reserving: * @@ -3818,7 +3818,7 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) " SPC-2 reservation is held, returning" " RESERVATION_CONFLICT\n"); cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - ret = -EINVAL; + ret = EINVAL; goto out; } @@ -3828,8 +3828,7 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) */ if (!cmd->se_sess) { cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -EINVAL; - goto out; + return -EINVAL; } if (cmd->data_length < 24) { @@ -4030,7 +4029,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) spin_lock(&se_dev->dev_reservation_lock); pr_reg = se_dev->dev_pr_res_holder; - if (pr_reg) { + if ((pr_reg)) { /* * Set the hardcoded Additional Length */ diff --git a/trunk/drivers/target/target_core_pscsi.c b/trunk/drivers/target/target_core_pscsi.c index 6e32ff6f2fa0..4ce2cf642fce 100644 --- a/trunk/drivers/target/target_core_pscsi.c +++ b/trunk/drivers/target/target_core_pscsi.c @@ -35,10 +35,8 @@ #include #include #include -#include +#include #include -#include - #include #include #include @@ -48,14 +46,12 @@ #include #include -#include "target_core_alua.h" #include "target_core_pscsi.h" #define ISPRINT(a) ((a >= ' ') && (a <= '~')) static struct se_subsystem_api pscsi_template; -static int pscsi_execute_cmd(struct se_cmd *cmd); static void pscsi_req_done(struct request *, int); /* pscsi_attach_hba(): @@ -1023,79 +1019,9 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, return -ENOMEM; } -/* - * Clear a lun set in the cdb if the initiator talking to use spoke - * and old standards version, as we can't assume the underlying device - * won't choke up on it. - */ -static inline void pscsi_clear_cdb_lun(unsigned char *cdb) -{ - switch (cdb[0]) { - case READ_10: /* SBC - RDProtect */ - case READ_12: /* SBC - RDProtect */ - case READ_16: /* SBC - RDProtect */ - case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */ - case VERIFY: /* SBC - VRProtect */ - case VERIFY_16: /* SBC - VRProtect */ - case WRITE_VERIFY: /* SBC - VRProtect */ - case WRITE_VERIFY_12: /* SBC - VRProtect */ - case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ - break; - default: - cdb[1] &= 0x1f; /* clear logical unit number */ - break; - } -} - -static int pscsi_parse_cdb(struct se_cmd *cmd) -{ - unsigned char *cdb = cmd->t_task_cdb; - unsigned int dummy_size; - int ret; - - if (cmd->se_cmd_flags & SCF_BIDI) { - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - return -EINVAL; - } - - pscsi_clear_cdb_lun(cdb); - - /* - * For REPORT LUNS we always need to emulate the response, for everything - * else the default for pSCSI is to pass the command to the underlying - * LLD / physical hardware. - */ - switch (cdb[0]) { - case REPORT_LUNS: - ret = spc_parse_cdb(cmd, &dummy_size); - if (ret) - return ret; - break; - case READ_6: - case READ_10: - case READ_12: - case READ_16: - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_16: - case WRITE_VERIFY: - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - /* FALLTHROUGH*/ - default: - cmd->execute_cmd = pscsi_execute_cmd; - break; - } - - return 0; -} - -static int pscsi_execute_cmd(struct se_cmd *cmd) +static int pscsi_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, + u32 sgl_nents, enum dma_data_direction data_direction) { - struct scatterlist *sgl = cmd->t_data_sg; - u32 sgl_nents = cmd->t_data_nents; - enum dma_data_direction data_direction = cmd->data_direction; struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; struct pscsi_plugin_task *pt; struct request *req; @@ -1116,7 +1042,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd) memcpy(pt->pscsi_cdb, cmd->t_task_cdb, scsi_command_size(cmd->t_task_cdb)); - if (!sgl) { + if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) { req = blk_get_request(pdv->pdv_sd->request_queue, (data_direction == DMA_TO_DEVICE), GFP_KERNEL); @@ -1262,7 +1188,7 @@ static struct se_subsystem_api pscsi_template = { .create_virtdevice = pscsi_create_virtdevice, .free_device = pscsi_free_device, .transport_complete = pscsi_transport_complete, - .parse_cdb = pscsi_parse_cdb, + .execute_cmd = pscsi_execute_cmd, .check_configfs_dev_params = pscsi_check_configfs_dev_params, .set_configfs_dev_params = pscsi_set_configfs_dev_params, .show_configfs_dev_params = pscsi_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_rd.c b/trunk/drivers/target/target_core_rd.c index d00bbe33ff8b..d0ceb873c0e5 100644 --- a/trunk/drivers/target/target_core_rd.c +++ b/trunk/drivers/target/target_core_rd.c @@ -284,11 +284,9 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) return NULL; } -static int rd_execute_rw(struct se_cmd *cmd) +static int rd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, + u32 sgl_nents, enum dma_data_direction data_direction) { - struct scatterlist *sgl = cmd->t_data_sg; - u32 sgl_nents = cmd->t_data_nents; - enum dma_data_direction data_direction = cmd->data_direction; struct se_device *se_dev = cmd->se_dev; struct rd_dev *dev = se_dev->dev_ptr; struct rd_dev_sg_table *table; @@ -462,15 +460,6 @@ static sector_t rd_get_blocks(struct se_device *dev) return blocks_long; } -static struct spc_ops rd_spc_ops = { - .execute_rw = rd_execute_rw, -}; - -static int rd_parse_cdb(struct se_cmd *cmd) -{ - return sbc_parse_cdb(cmd, &rd_spc_ops); -} - static struct se_subsystem_api rd_mcp_template = { .name = "rd_mcp", .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, @@ -479,7 +468,7 @@ static struct se_subsystem_api rd_mcp_template = { .allocate_virtdevice = rd_allocate_virtdevice, .create_virtdevice = rd_create_virtdevice, .free_device = rd_free_device, - .parse_cdb = rd_parse_cdb, + .execute_cmd = rd_execute_cmd, .check_configfs_dev_params = rd_check_configfs_dev_params, .set_configfs_dev_params = rd_set_configfs_dev_params, .show_configfs_dev_params = rd_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_sbc.c b/trunk/drivers/target/target_core_sbc.c deleted file mode 100644 index a9dd9469e3bd..000000000000 --- a/trunk/drivers/target/target_core_sbc.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * SCSI Block Commands (SBC) parsing and emulation. - * - * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. - * Copyright (c) 2005, 2006, 2007 SBE, Inc. - * Copyright (c) 2007-2010 Rising Tide Systems - * Copyright (c) 2008-2010 Linux-iSCSI.org - * - * Nicholas A. Bellinger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "target_core_internal.h" -#include "target_core_ua.h" - - -static int sbc_emulate_readcapacity(struct se_cmd *cmd) -{ - struct se_device *dev = cmd->se_dev; - unsigned char *buf; - unsigned long long blocks_long = dev->transport->get_blocks(dev); - u32 blocks; - - if (blocks_long >= 0x00000000ffffffff) - blocks = 0xffffffff; - else - blocks = (u32)blocks_long; - - buf = transport_kmap_data_sg(cmd); - - buf[0] = (blocks >> 24) & 0xff; - buf[1] = (blocks >> 16) & 0xff; - buf[2] = (blocks >> 8) & 0xff; - buf[3] = blocks & 0xff; - buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; - buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; - buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; - buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; - - transport_kunmap_data_sg(cmd); - - target_complete_cmd(cmd, GOOD); - return 0; -} - -static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) -{ - struct se_device *dev = cmd->se_dev; - unsigned char *buf; - unsigned long long blocks = dev->transport->get_blocks(dev); - - buf = transport_kmap_data_sg(cmd); - - buf[0] = (blocks >> 56) & 0xff; - buf[1] = (blocks >> 48) & 0xff; - buf[2] = (blocks >> 40) & 0xff; - buf[3] = (blocks >> 32) & 0xff; - buf[4] = (blocks >> 24) & 0xff; - buf[5] = (blocks >> 16) & 0xff; - buf[6] = (blocks >> 8) & 0xff; - buf[7] = blocks & 0xff; - buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; - buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; - buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; - buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; - /* - * Set Thin Provisioning Enable bit following sbc3r22 in section - * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled. - */ - if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) - buf[14] = 0x80; - - transport_kunmap_data_sg(cmd); - - target_complete_cmd(cmd, GOOD); - return 0; -} - -int spc_get_write_same_sectors(struct se_cmd *cmd) -{ - u32 num_blocks; - - if (cmd->t_task_cdb[0] == WRITE_SAME) - num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); - else if (cmd->t_task_cdb[0] == WRITE_SAME_16) - num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); - else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */ - num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); - - /* - * Use the explicit range when non zero is supplied, otherwise calculate - * the remaining range based on ->get_blocks() - starting LBA. - */ - if (num_blocks) - return num_blocks; - - return cmd->se_dev->transport->get_blocks(cmd->se_dev) - - cmd->t_task_lba + 1; -} -EXPORT_SYMBOL(spc_get_write_same_sectors); - -static int sbc_emulate_verify(struct se_cmd *cmd) -{ - target_complete_cmd(cmd, GOOD); - return 0; -} - -static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) -{ - return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; -} - -static int sbc_check_valid_sectors(struct se_cmd *cmd) -{ - struct se_device *dev = cmd->se_dev; - unsigned long long end_lba; - u32 sectors; - - sectors = cmd->data_length / dev->se_sub_dev->se_dev_attrib.block_size; - end_lba = dev->transport->get_blocks(dev) + 1; - - if (cmd->t_task_lba + sectors > end_lba) { - pr_err("target: lba %llu, sectors %u exceeds end lba %llu\n", - cmd->t_task_lba, sectors, end_lba); - return -EINVAL; - } - - return 0; -} - -static inline u32 transport_get_sectors_6(unsigned char *cdb) -{ - /* - * Use 8-bit sector value. SBC-3 says: - * - * A TRANSFER LENGTH field set to zero specifies that 256 - * logical blocks shall be written. Any other value - * specifies the number of logical blocks that shall be - * written. - */ - return cdb[4] ? : 256; -} - -static inline u32 transport_get_sectors_10(unsigned char *cdb) -{ - return (u32)(cdb[7] << 8) + cdb[8]; -} - -static inline u32 transport_get_sectors_12(unsigned char *cdb) -{ - return (u32)(cdb[6] << 24) + (cdb[7] << 16) + (cdb[8] << 8) + cdb[9]; -} - -static inline u32 transport_get_sectors_16(unsigned char *cdb) -{ - return (u32)(cdb[10] << 24) + (cdb[11] << 16) + - (cdb[12] << 8) + cdb[13]; -} - -/* - * Used for VARIABLE_LENGTH_CDB WRITE_32 and READ_32 variants - */ -static inline u32 transport_get_sectors_32(unsigned char *cdb) -{ - return (u32)(cdb[28] << 24) + (cdb[29] << 16) + - (cdb[30] << 8) + cdb[31]; - -} - -static inline u32 transport_lba_21(unsigned char *cdb) -{ - return ((cdb[1] & 0x1f) << 16) | (cdb[2] << 8) | cdb[3]; -} - -static inline u32 transport_lba_32(unsigned char *cdb) -{ - return (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; -} - -static inline unsigned long long transport_lba_64(unsigned char *cdb) -{ - unsigned int __v1, __v2; - - __v1 = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - __v2 = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; -} - -/* - * For VARIABLE_LENGTH_CDB w/ 32 byte extended CDBs - */ -static inline unsigned long long transport_lba_64_ext(unsigned char *cdb) -{ - unsigned int __v1, __v2; - - __v1 = (cdb[12] << 24) | (cdb[13] << 16) | (cdb[14] << 8) | cdb[15]; - __v2 = (cdb[16] << 24) | (cdb[17] << 16) | (cdb[18] << 8) | cdb[19]; - - return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; -} - -static int sbc_write_same_supported(struct se_device *dev, - unsigned char *flags) -{ - if ((flags[0] & 0x04) || (flags[0] & 0x02)) { - pr_err("WRITE_SAME PBDATA and LBDATA" - " bits not supported for Block Discard" - " Emulation\n"); - return -ENOSYS; - } - - /* - * Currently for the emulated case we only accept - * tpws with the UNMAP=1 bit set. - */ - if (!(flags[0] & 0x08)) { - pr_err("WRITE_SAME w/o UNMAP bit not" - " supported for Block Discard Emulation\n"); - return -ENOSYS; - } - - return 0; -} - -static void xdreadwrite_callback(struct se_cmd *cmd) -{ - unsigned char *buf, *addr; - struct scatterlist *sg; - unsigned int offset; - int i; - int count; - /* - * From sbc3r22.pdf section 5.48 XDWRITEREAD (10) command - * - * 1) read the specified logical block(s); - * 2) transfer logical blocks from the data-out buffer; - * 3) XOR the logical blocks transferred from the data-out buffer with - * the logical blocks read, storing the resulting XOR data in a buffer; - * 4) if the DISABLE WRITE bit is set to zero, then write the logical - * blocks transferred from the data-out buffer; and - * 5) transfer the resulting XOR data to the data-in buffer. - */ - buf = kmalloc(cmd->data_length, GFP_KERNEL); - if (!buf) { - pr_err("Unable to allocate xor_callback buf\n"); - return; - } - /* - * Copy the scatterlist WRITE buffer located at cmd->t_data_sg - * into the locally allocated *buf - */ - sg_copy_to_buffer(cmd->t_data_sg, - cmd->t_data_nents, - buf, - cmd->data_length); - - /* - * Now perform the XOR against the BIDI read memory located at - * cmd->t_mem_bidi_list - */ - - offset = 0; - for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) { - addr = kmap_atomic(sg_page(sg)); - if (!addr) - goto out; - - for (i = 0; i < sg->length; i++) - *(addr + sg->offset + i) ^= *(buf + offset + i); - - offset += sg->length; - kunmap_atomic(addr); - } - -out: - kfree(buf); -} - -int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) -{ - struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; - struct se_device *dev = cmd->se_dev; - unsigned char *cdb = cmd->t_task_cdb; - unsigned int size; - u32 sectors = 0; - int ret; - - switch (cdb[0]) { - case READ_6: - sectors = transport_get_sectors_6(cdb); - cmd->t_task_lba = transport_lba_21(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case READ_10: - sectors = transport_get_sectors_10(cdb); - cmd->t_task_lba = transport_lba_32(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case READ_12: - sectors = transport_get_sectors_12(cdb); - cmd->t_task_lba = transport_lba_32(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case READ_16: - sectors = transport_get_sectors_16(cdb); - cmd->t_task_lba = transport_lba_64(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case WRITE_6: - sectors = transport_get_sectors_6(cdb); - cmd->t_task_lba = transport_lba_21(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case WRITE_10: - case WRITE_VERIFY: - sectors = transport_get_sectors_10(cdb); - cmd->t_task_lba = transport_lba_32(cdb); - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case WRITE_12: - sectors = transport_get_sectors_12(cdb); - cmd->t_task_lba = transport_lba_32(cdb); - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case WRITE_16: - sectors = transport_get_sectors_16(cdb); - cmd->t_task_lba = transport_lba_64(cdb); - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - cmd->execute_cmd = ops->execute_rw; - break; - case XDWRITEREAD_10: - if ((cmd->data_direction != DMA_TO_DEVICE) || - !(cmd->se_cmd_flags & SCF_BIDI)) - goto out_invalid_cdb_field; - sectors = transport_get_sectors_10(cdb); - - cmd->t_task_lba = transport_lba_32(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - - /* - * Setup BIDI XOR callback to be run after I/O completion. - */ - cmd->execute_cmd = ops->execute_rw; - cmd->transport_complete_callback = &xdreadwrite_callback; - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; - break; - case VARIABLE_LENGTH_CMD: - { - u16 service_action = get_unaligned_be16(&cdb[8]); - switch (service_action) { - case XDWRITEREAD_32: - sectors = transport_get_sectors_32(cdb); - - /* - * Use WRITE_32 and READ_32 opcodes for the emulated - * XDWRITE_READ_32 logic. - */ - cmd->t_task_lba = transport_lba_64_ext(cdb); - cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; - - /* - * Setup BIDI XOR callback to be run during after I/O - * completion. - */ - cmd->execute_cmd = ops->execute_rw; - cmd->transport_complete_callback = &xdreadwrite_callback; - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; - break; - case WRITE_SAME_32: - if (!ops->execute_write_same) - goto out_unsupported_cdb; - - sectors = transport_get_sectors_32(cdb); - if (!sectors) { - pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" - " supported\n"); - goto out_invalid_cdb_field; - } - - size = sbc_get_size(cmd, 1); - cmd->t_task_lba = get_unaligned_be64(&cdb[12]); - - if (sbc_write_same_supported(dev, &cdb[10]) < 0) - goto out_unsupported_cdb; - cmd->execute_cmd = ops->execute_write_same; - break; - default: - pr_err("VARIABLE_LENGTH_CMD service action" - " 0x%04x not supported\n", service_action); - goto out_unsupported_cdb; - } - break; - } - case READ_CAPACITY: - size = READ_CAP_LEN; - cmd->execute_cmd = sbc_emulate_readcapacity; - break; - case SERVICE_ACTION_IN: - switch (cmd->t_task_cdb[1] & 0x1f) { - case SAI_READ_CAPACITY_16: - cmd->execute_cmd = sbc_emulate_readcapacity_16; - break; - default: - pr_err("Unsupported SA: 0x%02x\n", - cmd->t_task_cdb[1] & 0x1f); - goto out_invalid_cdb_field; - } - size = (cdb[10] << 24) | (cdb[11] << 16) | - (cdb[12] << 8) | cdb[13]; - break; - case SYNCHRONIZE_CACHE: - case SYNCHRONIZE_CACHE_16: - if (!ops->execute_sync_cache) - goto out_unsupported_cdb; - - /* - * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE - */ - if (cdb[0] == SYNCHRONIZE_CACHE) { - sectors = transport_get_sectors_10(cdb); - cmd->t_task_lba = transport_lba_32(cdb); - } else { - sectors = transport_get_sectors_16(cdb); - cmd->t_task_lba = transport_lba_64(cdb); - } - - size = sbc_get_size(cmd, sectors); - - /* - * Check to ensure that LBA + Range does not exceed past end of - * device for IBLOCK and FILEIO ->do_sync_cache() backend calls - */ - if (cmd->t_task_lba || sectors) { - if (sbc_check_valid_sectors(cmd) < 0) - goto out_invalid_cdb_field; - } - cmd->execute_cmd = ops->execute_sync_cache; - break; - case UNMAP: - if (!ops->execute_unmap) - goto out_unsupported_cdb; - - size = get_unaligned_be16(&cdb[7]); - cmd->execute_cmd = ops->execute_unmap; - break; - case WRITE_SAME_16: - if (!ops->execute_write_same) - goto out_unsupported_cdb; - - sectors = transport_get_sectors_16(cdb); - if (!sectors) { - pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); - goto out_invalid_cdb_field; - } - - size = sbc_get_size(cmd, 1); - cmd->t_task_lba = get_unaligned_be64(&cdb[2]); - - if (sbc_write_same_supported(dev, &cdb[1]) < 0) - goto out_unsupported_cdb; - cmd->execute_cmd = ops->execute_write_same; - break; - case WRITE_SAME: - if (!ops->execute_write_same) - goto out_unsupported_cdb; - - sectors = transport_get_sectors_10(cdb); - if (!sectors) { - pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); - goto out_invalid_cdb_field; - } - - size = sbc_get_size(cmd, 1); - cmd->t_task_lba = get_unaligned_be32(&cdb[2]); - - /* - * Follow sbcr26 with WRITE_SAME (10) and check for the existence - * of byte 1 bit 3 UNMAP instead of original reserved field - */ - if (sbc_write_same_supported(dev, &cdb[1]) < 0) - goto out_unsupported_cdb; - cmd->execute_cmd = ops->execute_write_same; - break; - case VERIFY: - size = 0; - cmd->execute_cmd = sbc_emulate_verify; - break; - default: - ret = spc_parse_cdb(cmd, &size); - if (ret) - return ret; - } - - /* reject any command that we don't have a handler for */ - if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->execute_cmd) - goto out_unsupported_cdb; - - if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { - unsigned long long end_lba; - - if (sectors > su_dev->se_dev_attrib.fabric_max_sectors) { - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" - " big sectors %u exceeds fabric_max_sectors:" - " %u\n", cdb[0], sectors, - su_dev->se_dev_attrib.fabric_max_sectors); - goto out_invalid_cdb_field; - } - if (sectors > su_dev->se_dev_attrib.hw_max_sectors) { - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" - " big sectors %u exceeds backend hw_max_sectors:" - " %u\n", cdb[0], sectors, - su_dev->se_dev_attrib.hw_max_sectors); - goto out_invalid_cdb_field; - } - - end_lba = dev->transport->get_blocks(dev) + 1; - if (cmd->t_task_lba + sectors > end_lba) { - pr_err("cmd exceeds last lba %llu " - "(lba %llu, sectors %u)\n", - end_lba, cmd->t_task_lba, sectors); - goto out_invalid_cdb_field; - } - - size = sbc_get_size(cmd, sectors); - } - - ret = target_cmd_size_check(cmd, size); - if (ret < 0) - return ret; - - return 0; - -out_unsupported_cdb: - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - return -EINVAL; -out_invalid_cdb_field: - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; -} -EXPORT_SYMBOL(sbc_parse_cdb); diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index 1c59a3c23b2c..84caf1bed9a3 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -295,6 +295,9 @@ static void core_tmr_drain_state_list( list_move_tail(&cmd->state_list, &drain_task_list); cmd->state_active = false; + + if (!list_empty(&cmd->execute_list)) + __target_remove_from_execute_list(cmd); } spin_unlock_irqrestore(&dev->execute_task_lock, flags); @@ -351,6 +354,57 @@ static void core_tmr_drain_state_list( } } +static void core_tmr_drain_cmd_list( + struct se_device *dev, + struct se_cmd *prout_cmd, + struct se_node_acl *tmr_nacl, + int tas, + struct list_head *preempt_and_abort_list) +{ + LIST_HEAD(drain_cmd_list); + struct se_queue_obj *qobj = &dev->dev_queue_obj; + struct se_cmd *cmd, *tcmd; + unsigned long flags; + + /* + * Release all commands remaining in the per-device command queue. + * + * This follows the same logic as above for the state list. + */ + spin_lock_irqsave(&qobj->cmd_queue_lock, flags); + list_for_each_entry_safe(cmd, tcmd, &qobj->qobj_list, se_queue_node) { + /* + * For PREEMPT_AND_ABORT usage, only process commands + * with a matching reservation key. + */ + if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) + continue; + /* + * Not aborting PROUT PREEMPT_AND_ABORT CDB.. + */ + if (prout_cmd == cmd) + continue; + + cmd->transport_state &= ~CMD_T_QUEUED; + atomic_dec(&qobj->queue_cnt); + list_move_tail(&cmd->se_queue_node, &drain_cmd_list); + } + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); + + while (!list_empty(&drain_cmd_list)) { + cmd = list_entry(drain_cmd_list.next, struct se_cmd, se_queue_node); + list_del_init(&cmd->se_queue_node); + + pr_debug("LUN_RESET: %s from Device Queue: cmd: %p t_state:" + " %d t_fe_count: %d\n", (preempt_and_abort_list) ? + "Preempt" : "", cmd, cmd->t_state, + atomic_read(&cmd->t_fe_count)); + + core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, + atomic_read(&cmd->t_fe_count)); + } +} + int core_tmr_lun_reset( struct se_device *dev, struct se_tmr_req *tmr, @@ -393,7 +447,8 @@ int core_tmr_lun_reset( core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas, preempt_and_abort_list); - + core_tmr_drain_cmd_list(dev, prout_cmd, tmr_nacl, tas, + preempt_and_abort_list); /* * Clear any legacy SPC-2 reservation when called during * LOGICAL UNIT RESET diff --git a/trunk/drivers/target/target_core_tpg.c b/trunk/drivers/target/target_core_tpg.c index b8628a5014b9..8bd58e284185 100644 --- a/trunk/drivers/target/target_core_tpg.c +++ b/trunk/drivers/target/target_core_tpg.c @@ -77,8 +77,8 @@ static void core_clear_initiator_node_from_tpg( lun = deve->se_lun; spin_unlock_irq(&nacl->device_list_lock); - core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, - TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); + core_update_device_list_for_node(lun, NULL, deve->mapped_lun, + TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg, 0); spin_lock_irq(&nacl->device_list_lock); } @@ -172,8 +172,8 @@ void core_tpg_add_node_to_devs( (lun_access == TRANSPORT_LUNFLAGS_READ_WRITE) ? "READ-WRITE" : "READ-ONLY"); - core_enable_device_list_for_node(lun, NULL, lun->unpacked_lun, - lun_access, acl, tpg); + core_update_device_list_for_node(lun, NULL, lun->unpacked_lun, + lun_access, acl, tpg, 1); spin_lock(&tpg->tpg_lun_lock); } spin_unlock(&tpg->tpg_lun_lock); @@ -306,8 +306,10 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( * TPG LUNs if the fabric is not explictly asking for * tpg_check_demo_mode_login_only() == 1. */ - if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only == NULL) || - (tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg) != 1)) + if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only != NULL) && + (tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg) == 1)) + do { ; } while (0); + else core_tpg_add_node_to_devs(acl, tpg); spin_lock_irq(&tpg->acl_node_lock); diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 0eaae23d12b5..b05fdc0c05d3 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -66,12 +66,15 @@ struct kmem_cache *t10_alua_lu_gp_mem_cache; struct kmem_cache *t10_alua_tg_pt_gp_cache; struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; +static int transport_generic_write_pending(struct se_cmd *); +static int transport_processing_thread(void *param); +static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *); static void transport_complete_task_attr(struct se_cmd *cmd); static void transport_handle_queue_full(struct se_cmd *cmd, struct se_device *dev); static int transport_generic_get_mem(struct se_cmd *cmd); -static int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool); static void transport_put_cmd(struct se_cmd *cmd); +static void transport_remove_cmd_from_queue(struct se_cmd *cmd); static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); static void target_complete_ok_work(struct work_struct *work); @@ -192,6 +195,14 @@ u32 scsi_get_new_index(scsi_index_t type) return new_index; } +static void transport_init_queue_obj(struct se_queue_obj *qobj) +{ + atomic_set(&qobj->queue_cnt, 0); + INIT_LIST_HEAD(&qobj->qobj_list); + init_waitqueue_head(&qobj->thread_wq); + spin_lock_init(&qobj->cmd_queue_lock); +} + void transport_subsystem_check_init(void) { int ret; @@ -232,6 +243,7 @@ struct se_session *transport_init_session(void) INIT_LIST_HEAD(&se_sess->sess_list); INIT_LIST_HEAD(&se_sess->sess_acl_list); INIT_LIST_HEAD(&se_sess->sess_cmd_list); + INIT_LIST_HEAD(&se_sess->sess_wait_list); spin_lock_init(&se_sess->sess_cmd_lock); kref_init(&se_sess->sess_kref); @@ -303,7 +315,7 @@ void transport_register_session( } EXPORT_SYMBOL(transport_register_session); -void target_release_session(struct kref *kref) +static void target_release_session(struct kref *kref) { struct se_session *se_sess = container_of(kref, struct se_session, sess_kref); @@ -320,12 +332,6 @@ EXPORT_SYMBOL(target_get_session); void target_put_session(struct se_session *se_sess) { - struct se_portal_group *tpg = se_sess->se_tpg; - - if (tpg->se_tpg_tfo->put_session != NULL) { - tpg->se_tpg_tfo->put_session(se_sess); - return; - } kref_put(&se_sess->sess_kref, target_release_session); } EXPORT_SYMBOL(target_put_session); @@ -456,7 +462,18 @@ static void target_remove_from_state_list(struct se_cmd *cmd) spin_unlock_irqrestore(&dev->execute_task_lock, flags); } -static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists) +/* transport_cmd_check_stop(): + * + * 'transport_off = 1' determines if CMD_T_ACTIVE should be cleared. + * 'transport_off = 2' determines if task_dev_state should be removed. + * + * A non-zero u8 t_state sets cmd->t_state. + * Returns 1 when command is stopped, else 0. + */ +static int transport_cmd_check_stop( + struct se_cmd *cmd, + int transport_off, + u8 t_state) { unsigned long flags; @@ -470,23 +487,13 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists) __func__, __LINE__, cmd->se_tfo->get_task_tag(cmd)); cmd->transport_state &= ~CMD_T_ACTIVE; - if (remove_from_lists) + if (transport_off == 2) target_remove_from_state_list(cmd); spin_unlock_irqrestore(&cmd->t_state_lock, flags); complete(&cmd->transport_lun_stop_comp); return 1; } - - if (remove_from_lists) { - target_remove_from_state_list(cmd); - - /* - * Clear struct se_cmd->se_lun before the handoff to FE. - */ - cmd->se_lun = NULL; - } - /* * Determine if frontend context caller is requesting the stopping of * this command for frontend exceptions. @@ -496,36 +503,58 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists) __func__, __LINE__, cmd->se_tfo->get_task_tag(cmd)); + if (transport_off == 2) + target_remove_from_state_list(cmd); + + /* + * Clear struct se_cmd->se_lun before the transport_off == 2 handoff + * to FE. + */ + if (transport_off == 2) + cmd->se_lun = NULL; spin_unlock_irqrestore(&cmd->t_state_lock, flags); complete(&cmd->t_transport_stop_comp); return 1; } - - cmd->transport_state &= ~CMD_T_ACTIVE; - if (remove_from_lists) { - /* - * Some fabric modules like tcm_loop can release - * their internally allocated I/O reference now and - * struct se_cmd now. - * - * Fabric modules are expected to return '1' here if the - * se_cmd being passed is released at this point, - * or zero if not being released. - */ - if (cmd->se_tfo->check_stop_free != NULL) { - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - return cmd->se_tfo->check_stop_free(cmd); + if (transport_off) { + cmd->transport_state &= ~CMD_T_ACTIVE; + if (transport_off == 2) { + target_remove_from_state_list(cmd); + /* + * Clear struct se_cmd->se_lun before the transport_off == 2 + * handoff to fabric module. + */ + cmd->se_lun = NULL; + /* + * Some fabric modules like tcm_loop can release + * their internally allocated I/O reference now and + * struct se_cmd now. + * + * Fabric modules are expected to return '1' here if the + * se_cmd being passed is released at this point, + * or zero if not being released. + */ + if (cmd->se_tfo->check_stop_free != NULL) { + spin_unlock_irqrestore( + &cmd->t_state_lock, flags); + + return cmd->se_tfo->check_stop_free(cmd); + } } - } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return 0; + } else if (t_state) + cmd->t_state = t_state; spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return 0; } static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd) { - return transport_cmd_check_stop(cmd, true); + return transport_cmd_check_stop(cmd, 2, 0); } static void transport_lun_remove_cmd(struct se_cmd *cmd) @@ -556,8 +585,79 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) if (transport_cmd_check_stop_to_fabric(cmd)) return; - if (remove) + if (remove) { + transport_remove_cmd_from_queue(cmd); transport_put_cmd(cmd); + } +} + +static void transport_add_cmd_to_queue(struct se_cmd *cmd, int t_state, + bool at_head) +{ + struct se_device *dev = cmd->se_dev; + struct se_queue_obj *qobj = &dev->dev_queue_obj; + unsigned long flags; + + if (t_state) { + spin_lock_irqsave(&cmd->t_state_lock, flags); + cmd->t_state = t_state; + cmd->transport_state |= CMD_T_ACTIVE; + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + } + + spin_lock_irqsave(&qobj->cmd_queue_lock, flags); + + /* If the cmd is already on the list, remove it before we add it */ + if (!list_empty(&cmd->se_queue_node)) + list_del(&cmd->se_queue_node); + else + atomic_inc(&qobj->queue_cnt); + + if (at_head) + list_add(&cmd->se_queue_node, &qobj->qobj_list); + else + list_add_tail(&cmd->se_queue_node, &qobj->qobj_list); + cmd->transport_state |= CMD_T_QUEUED; + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); + + wake_up_interruptible(&qobj->thread_wq); +} + +static struct se_cmd * +transport_get_cmd_from_queue(struct se_queue_obj *qobj) +{ + struct se_cmd *cmd; + unsigned long flags; + + spin_lock_irqsave(&qobj->cmd_queue_lock, flags); + if (list_empty(&qobj->qobj_list)) { + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); + return NULL; + } + cmd = list_first_entry(&qobj->qobj_list, struct se_cmd, se_queue_node); + + cmd->transport_state &= ~CMD_T_QUEUED; + list_del_init(&cmd->se_queue_node); + atomic_dec(&qobj->queue_cnt); + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); + + return cmd; +} + +static void transport_remove_cmd_from_queue(struct se_cmd *cmd) +{ + struct se_queue_obj *qobj = &cmd->se_dev->dev_queue_obj; + unsigned long flags; + + spin_lock_irqsave(&qobj->cmd_queue_lock, flags); + if (!(cmd->transport_state & CMD_T_QUEUED)) { + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); + return; + } + cmd->transport_state &= ~CMD_T_QUEUED; + atomic_dec(&qobj->queue_cnt); + list_del_init(&cmd->se_queue_node); + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); } static void target_complete_failure_work(struct work_struct *work) @@ -636,11 +736,68 @@ static void target_add_to_state_list(struct se_cmd *cmd) spin_unlock_irqrestore(&dev->execute_task_lock, flags); } +static void __target_add_to_execute_list(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + bool head_of_queue = false; + + if (!list_empty(&cmd->execute_list)) + return; + + if (dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED && + cmd->sam_task_attr == MSG_HEAD_TAG) + head_of_queue = true; + + if (head_of_queue) + list_add(&cmd->execute_list, &dev->execute_list); + else + list_add_tail(&cmd->execute_list, &dev->execute_list); + + atomic_inc(&dev->execute_tasks); + + if (cmd->state_active) + return; + + if (head_of_queue) + list_add(&cmd->state_list, &dev->state_list); + else + list_add_tail(&cmd->state_list, &dev->state_list); + + cmd->state_active = true; +} + +static void target_add_to_execute_list(struct se_cmd *cmd) +{ + unsigned long flags; + struct se_device *dev = cmd->se_dev; + + spin_lock_irqsave(&dev->execute_task_lock, flags); + __target_add_to_execute_list(cmd); + spin_unlock_irqrestore(&dev->execute_task_lock, flags); +} + +void __target_remove_from_execute_list(struct se_cmd *cmd) +{ + list_del_init(&cmd->execute_list); + atomic_dec(&cmd->se_dev->execute_tasks); +} + +static void target_remove_from_execute_list(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + unsigned long flags; + + if (WARN_ON(list_empty(&cmd->execute_list))) + return; + + spin_lock_irqsave(&dev->execute_task_lock, flags); + __target_remove_from_execute_list(cmd); + spin_unlock_irqrestore(&dev->execute_task_lock, flags); +} + /* * Handle QUEUE_FULL / -EAGAIN and -ENOMEM status */ -static void transport_write_pending_qf(struct se_cmd *cmd); -static void transport_complete_qf(struct se_cmd *cmd); static void target_qf_do_work(struct work_struct *work) { @@ -664,10 +821,7 @@ static void target_qf_do_work(struct work_struct *work) (cmd->t_state == TRANSPORT_COMPLETE_QF_WP) ? "WRITE_PENDING" : "UNKNOWN"); - if (cmd->t_state == TRANSPORT_COMPLETE_QF_WP) - transport_write_pending_qf(cmd); - else if (cmd->t_state == TRANSPORT_COMPLETE_QF_OK) - transport_complete_qf(cmd); + transport_add_cmd_to_queue(cmd, cmd->t_state, true); } } @@ -714,7 +868,8 @@ void transport_dump_dev_state( break; } - *bl += sprintf(b + *bl, " Max Queue Depth: %d", dev->queue_depth); + *bl += sprintf(b + *bl, " Execute/Max Queue Depth: %d/%d", + atomic_read(&dev->execute_tasks), dev->queue_depth); *bl += sprintf(b + *bl, " SectorSize: %u HwMaxSectors: %u\n", dev->se_sub_dev->se_dev_attrib.block_size, dev->se_sub_dev->se_dev_attrib.hw_max_sectors); @@ -1051,6 +1206,7 @@ struct se_device *transport_add_device_to_core_hba( return NULL; } + transport_init_queue_obj(&dev->dev_queue_obj); dev->dev_flags = device_flags; dev->dev_status |= TRANSPORT_DEVICE_DEACTIVATED; dev->dev_ptr = transport_dev; @@ -1060,6 +1216,7 @@ struct se_device *transport_add_device_to_core_hba( INIT_LIST_HEAD(&dev->dev_list); INIT_LIST_HEAD(&dev->dev_sep_list); INIT_LIST_HEAD(&dev->dev_tmr_list); + INIT_LIST_HEAD(&dev->execute_list); INIT_LIST_HEAD(&dev->delayed_cmd_list); INIT_LIST_HEAD(&dev->state_list); INIT_LIST_HEAD(&dev->qf_cmd_list); @@ -1098,17 +1255,17 @@ struct se_device *transport_add_device_to_core_hba( * Setup the Asymmetric Logical Unit Assignment for struct se_device */ if (core_setup_alua(dev, force_pt) < 0) - goto err_dev_list; + goto out; /* * Startup the struct se_device processing thread */ - dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, - dev->transport->name); - if (!dev->tmr_wq) { - pr_err("Unable to create tmr workqueue for %s\n", + dev->process_thread = kthread_run(transport_processing_thread, dev, + "LIO_%s", dev->transport->name); + if (IS_ERR(dev->process_thread)) { + pr_err("Unable to create kthread: LIO_%s\n", dev->transport->name); - goto err_dev_list; + goto out; } /* * Setup work_queue for QUEUE_FULL @@ -1126,7 +1283,7 @@ struct se_device *transport_add_device_to_core_hba( if (!inquiry_prod || !inquiry_rev) { pr_err("All non TCM/pSCSI plugins require" " INQUIRY consts\n"); - goto err_wq; + goto out; } strncpy(&dev->se_sub_dev->t10_wwn.vendor[0], "LIO-ORG", 8); @@ -1136,10 +1293,9 @@ struct se_device *transport_add_device_to_core_hba( scsi_dump_inquiry(dev); return dev; +out: + kthread_stop(dev->process_thread); -err_wq: - destroy_workqueue(dev->tmr_wq); -err_dev_list: spin_lock(&hba->device_lock); list_del(&dev->dev_list); hba->dev_count--; @@ -1153,55 +1309,36 @@ struct se_device *transport_add_device_to_core_hba( } EXPORT_SYMBOL(transport_add_device_to_core_hba); -int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) +/* transport_generic_prepare_cdb(): + * + * Since the Initiator sees iSCSI devices as LUNs, the SCSI CDB will + * contain the iSCSI LUN in bits 7-5 of byte 1 as per SAM-2. + * The point of this is since we are mapping iSCSI LUNs to + * SCSI Target IDs having a non-zero LUN in the CDB will throw the + * devices and HBAs for a loop. + */ +static inline void transport_generic_prepare_cdb( + unsigned char *cdb) { - struct se_device *dev = cmd->se_dev; - - if (cmd->unknown_data_length) { - cmd->data_length = size; - } else if (size != cmd->data_length) { - pr_warn("TARGET_CORE[%s]: Expected Transfer Length:" - " %u does not match SCSI CDB Length: %u for SAM Opcode:" - " 0x%02x\n", cmd->se_tfo->get_fabric_name(), - cmd->data_length, size, cmd->t_task_cdb[0]); - - cmd->cmd_spdtl = size; - - if (cmd->data_direction == DMA_TO_DEVICE) { - pr_err("Rejecting underflow/overflow" - " WRITE data\n"); - goto out_invalid_cdb_field; - } - /* - * Reject READ_* or WRITE_* with overflow/underflow for - * type SCF_SCSI_DATA_CDB. - */ - if (dev->se_sub_dev->se_dev_attrib.block_size != 512) { - pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" - " CDB on non 512-byte sector setup subsystem" - " plugin: %s\n", dev->transport->name); - /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ - goto out_invalid_cdb_field; - } - - if (size > cmd->data_length) { - cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; - cmd->residual_count = (size - cmd->data_length); - } else { - cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; - cmd->residual_count = (cmd->data_length - size); - } - cmd->data_length = size; + switch (cdb[0]) { + case READ_10: /* SBC - RDProtect */ + case READ_12: /* SBC - RDProtect */ + case READ_16: /* SBC - RDProtect */ + case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */ + case VERIFY: /* SBC - VRProtect */ + case VERIFY_16: /* SBC - VRProtect */ + case WRITE_VERIFY: /* SBC - VRProtect */ + case WRITE_VERIFY_12: /* SBC - VRProtect */ + case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ + break; + default: + cdb[1] &= 0x1f; /* clear logical unit number */ + break; } - - return 0; - -out_invalid_cdb_field: - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; } +static int transport_generic_cmd_sequencer(struct se_cmd *, unsigned char *); + /* * Used by fabric modules containing a local struct se_cmd within their * fabric dependent per I/O descriptor. @@ -1218,7 +1355,9 @@ void transport_init_se_cmd( INIT_LIST_HEAD(&cmd->se_lun_node); INIT_LIST_HEAD(&cmd->se_delayed_node); INIT_LIST_HEAD(&cmd->se_qf_node); + INIT_LIST_HEAD(&cmd->se_queue_node); INIT_LIST_HEAD(&cmd->se_cmd_list); + INIT_LIST_HEAD(&cmd->execute_list); INIT_LIST_HEAD(&cmd->state_list); init_completion(&cmd->transport_lun_fe_stop_comp); init_completion(&cmd->transport_lun_stop_comp); @@ -1273,12 +1412,9 @@ int target_setup_cmd_from_cdb( struct se_cmd *cmd, unsigned char *cdb) { - struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; - u32 pr_reg_type = 0; - u8 alua_ascq = 0; - unsigned long flags; int ret; + transport_generic_prepare_cdb(cdb); /* * Ensure that the received CDB is less than the max (252 + 8) bytes * for VARIABLE_LENGTH_CMD @@ -1315,66 +1451,15 @@ int target_setup_cmd_from_cdb( * Copy the original CDB into cmd-> */ memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb)); - - /* - * Check for an existing UNIT ATTENTION condition - */ - if (core_scsi3_ua_check(cmd, cdb) < 0) { - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; - return -EINVAL; - } - - ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq); - if (ret != 0) { - /* - * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; - * The ALUA additional sense code qualifier (ASCQ) is determined - * by the ALUA primary or secondary access state.. - */ - if (ret > 0) { - pr_debug("[%s]: ALUA TG Port not available, " - "SenseKey: NOT_READY, ASC/ASCQ: " - "0x04/0x%02x\n", - cmd->se_tfo->get_fabric_name(), alua_ascq); - - transport_set_sense_codes(cmd, 0x04, alua_ascq); - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; - return -EINVAL; - } - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; - } - /* - * Check status for SPC-3 Persistent Reservations + * Setup the received CDB based on SCSI defined opcodes and + * perform unit attention, persistent reservations and ALUA + * checks for virtual device backends. The cmd->t_task_cdb + * pointer is expected to be setup before we reach this point. */ - if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) { - if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( - cmd, cdb, pr_reg_type) != 0) { - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; - cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EBUSY; - } - /* - * This means the CDB is allowed for the SCSI Initiator port - * when said port is *NOT* holding the legacy SPC-2 or - * SPC-3 Persistent Reservation. - */ - } - - ret = cmd->se_dev->transport->parse_cdb(cmd); + ret = transport_generic_cmd_sequencer(cmd, cdb); if (ret < 0) return ret; - - spin_lock_irqsave(&cmd->t_state_lock, flags); - cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - /* * Check for SAM Task Attribute Emulation */ @@ -1412,9 +1497,10 @@ int transport_handle_cdb_direct( return -EINVAL; } /* - * Set TRANSPORT_NEW_CMD state and CMD_T_ACTIVE to ensure that - * outstanding descriptors are handled correctly during shutdown via - * transport_wait_for_tasks() + * Set TRANSPORT_NEW_CMD state and CMD_T_ACTIVE following + * transport_generic_handle_cdb*() -> transport_add_cmd_to_queue() + * in existing usage to ensure that outstanding descriptors are handled + * correctly during shutdown via transport_wait_for_tasks() * * Also, we don't take cmd->t_state_lock here as we only expect * this to be called for initial descriptor submission. @@ -1448,14 +1534,10 @@ EXPORT_SYMBOL(transport_handle_cdb_direct); * @data_dir: DMA data direction * @flags: flags for command submission from target_sc_flags_tables * - * Returns non zero to signal active I/O shutdown failure. All other - * setup exceptions will be returned as a SCSI CHECK_CONDITION response, - * but still return zero here. - * * This may only be called from process context, and also currently * assumes internal allocation of fabric payload buffer by target-core. **/ -int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, +void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags) { @@ -1481,9 +1563,7 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, * for fabrics using TARGET_SCF_ACK_KREF that expect a second * kref_put() to happen during fabric packet acknowledgement. */ - rc = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); - if (rc) - return rc; + target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); /* * Signal bidirectional data payloads to target-core */ @@ -1496,13 +1576,16 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, transport_send_check_condition_and_sense(se_cmd, se_cmd->scsi_sense_reason, 0); target_put_sess_cmd(se_sess, se_cmd); - return 0; + return; } - + /* + * Sanitize CDBs via transport_generic_cmd_sequencer() and + * allocate the necessary tasks to complete the received CDB+data + */ rc = target_setup_cmd_from_cdb(se_cmd, cdb); if (rc != 0) { transport_generic_request_failure(se_cmd); - return 0; + return; } /* @@ -1511,8 +1594,14 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, */ core_alua_check_nonop_delay(se_cmd); + /* + * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend + * for immediate execution of READs, otherwise wait for + * transport_generic_handle_data() to be called for WRITEs + * when fabric has filled the incoming buffer. + */ transport_handle_cdb_direct(se_cmd); - return 0; + return; } EXPORT_SYMBOL(target_submit_cmd); @@ -1567,11 +1656,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, se_cmd->se_tmr_req->ref_task_tag = tag; /* See target_submit_cmd for commentary */ - ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); - if (ret) { - core_tmr_release_req(se_cmd->se_tmr_req); - return ret; - } + target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); ret = transport_lookup_tmr_lun(se_cmd, unpacked_lun); if (ret) { @@ -1589,40 +1674,101 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, EXPORT_SYMBOL(target_submit_tmr); /* - * If the cmd is active, request it to be stopped and sleep until it - * has completed. + * Used by fabric module frontends defining a TFO->new_cmd_map() caller + * to queue up a newly setup se_cmd w/ TRANSPORT_NEW_CMD_MAP in order to + * complete setup in TCM process context w/ TFO->new_cmd_map(). */ -bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) +int transport_generic_handle_cdb_map( + struct se_cmd *cmd) { - bool was_active = false; - - if (cmd->transport_state & CMD_T_BUSY) { - cmd->transport_state |= CMD_T_REQUEST_STOP; - spin_unlock_irqrestore(&cmd->t_state_lock, *flags); - - pr_debug("cmd %p waiting to complete\n", cmd); - wait_for_completion(&cmd->task_stop_comp); - pr_debug("cmd %p stopped successfully\n", cmd); - - spin_lock_irqsave(&cmd->t_state_lock, *flags); - cmd->transport_state &= ~CMD_T_REQUEST_STOP; - cmd->transport_state &= ~CMD_T_BUSY; - was_active = true; + if (!cmd->se_lun) { + dump_stack(); + pr_err("cmd->se_lun is NULL\n"); + return -EINVAL; } - return was_active; + transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD_MAP, false); + return 0; } +EXPORT_SYMBOL(transport_generic_handle_cdb_map); -/* - * Handle SAM-esque emulation for generic transport request failures. +/* transport_generic_handle_data(): + * + * */ -void transport_generic_request_failure(struct se_cmd *cmd) +int transport_generic_handle_data( + struct se_cmd *cmd) { - int ret = 0; - - pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" - " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), - cmd->t_task_cdb[0]); + /* + * For the software fabric case, then we assume the nexus is being + * failed/shutdown when signals are pending from the kthread context + * caller, so we return a failure. For the HW target mode case running + * in interrupt code, the signal_pending() check is skipped. + */ + if (!in_interrupt() && signal_pending(current)) + return -EPERM; + /* + * If the received CDB has aleady been ABORTED by the generic + * target engine, we now call transport_check_aborted_status() + * to queue any delated TASK_ABORTED status for the received CDB to the + * fabric module as we are expecting no further incoming DATA OUT + * sequences at this point. + */ + if (transport_check_aborted_status(cmd, 1) != 0) + return 0; + + transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_WRITE, false); + return 0; +} +EXPORT_SYMBOL(transport_generic_handle_data); + +/* transport_generic_handle_tmr(): + * + * + */ +int transport_generic_handle_tmr( + struct se_cmd *cmd) +{ + transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR, false); + return 0; +} +EXPORT_SYMBOL(transport_generic_handle_tmr); + +/* + * If the cmd is active, request it to be stopped and sleep until it + * has completed. + */ +bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) +{ + bool was_active = false; + + if (cmd->transport_state & CMD_T_BUSY) { + cmd->transport_state |= CMD_T_REQUEST_STOP; + spin_unlock_irqrestore(&cmd->t_state_lock, *flags); + + pr_debug("cmd %p waiting to complete\n", cmd); + wait_for_completion(&cmd->task_stop_comp); + pr_debug("cmd %p stopped successfully\n", cmd); + + spin_lock_irqsave(&cmd->t_state_lock, *flags); + cmd->transport_state &= ~CMD_T_REQUEST_STOP; + cmd->transport_state &= ~CMD_T_BUSY; + was_active = true; + } + + return was_active; +} + +/* + * Handle SAM-esque emulation for generic transport request failures. + */ +void transport_generic_request_failure(struct se_cmd *cmd) +{ + int ret = 0; + + pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" + " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), + cmd->t_task_cdb[0]); pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", cmd->se_tfo->get_cmd_state(cmd), cmd->t_state, cmd->scsi_sense_reason); @@ -1645,7 +1791,6 @@ void transport_generic_request_failure(struct se_cmd *cmd) case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: case TCM_UNKNOWN_MODE_PAGE: case TCM_WRITE_PROTECTED: - case TCM_ADDRESS_OUT_OF_RANGE: case TCM_CHECK_CONDITION_ABORT_CMD: case TCM_CHECK_CONDITION_UNIT_ATTENTION: case TCM_CHECK_CONDITION_NOT_READY: @@ -1681,7 +1826,13 @@ void transport_generic_request_failure(struct se_cmd *cmd) cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; break; } - + /* + * If a fabric does not define a cmd->se_tfo->new_cmd_map caller, + * make the call to transport_send_check_condition_and_sense() + * directly. Otherwise expect the fabric to make the call to + * transport_send_check_condition_and_sense() after handling + * possible unsoliticied write data payloads. + */ ret = transport_send_check_condition_and_sense(cmd, cmd->scsi_sense_reason, 0); if (ret == -EAGAIN || ret == -ENOMEM) @@ -1699,123 +1850,406 @@ void transport_generic_request_failure(struct se_cmd *cmd) } EXPORT_SYMBOL(transport_generic_request_failure); -static void __target_execute_cmd(struct se_cmd *cmd) +static inline u32 transport_lba_21(unsigned char *cdb) +{ + return ((cdb[1] & 0x1f) << 16) | (cdb[2] << 8) | cdb[3]; +} + +static inline u32 transport_lba_32(unsigned char *cdb) +{ + return (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; +} + +static inline unsigned long long transport_lba_64(unsigned char *cdb) +{ + unsigned int __v1, __v2; + + __v1 = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + __v2 = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + + return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; +} + +/* + * For VARIABLE_LENGTH_CDB w/ 32 byte extended CDBs + */ +static inline unsigned long long transport_lba_64_ext(unsigned char *cdb) +{ + unsigned int __v1, __v2; + + __v1 = (cdb[12] << 24) | (cdb[13] << 16) | (cdb[14] << 8) | cdb[15]; + __v2 = (cdb[16] << 24) | (cdb[17] << 16) | (cdb[18] << 8) | cdb[19]; + + return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; +} + +static void transport_set_supported_SAM_opcode(struct se_cmd *se_cmd) { - int error = 0; + unsigned long flags; - spin_lock_irq(&cmd->t_state_lock); - cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT); - spin_unlock_irq(&cmd->t_state_lock); + spin_lock_irqsave(&se_cmd->t_state_lock, flags); + se_cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); +} + +/* + * Called from Fabric Module context from transport_execute_tasks() + * + * The return of this function determins if the tasks from struct se_cmd + * get added to the execution queue in transport_execute_tasks(), + * or are added to the delayed or ordered lists here. + */ +static inline int transport_execute_task_attr(struct se_cmd *cmd) +{ + if (cmd->se_dev->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) + return 1; + /* + * Check for the existence of HEAD_OF_QUEUE, and if true return 1 + * to allow the passed struct se_cmd list of tasks to the front of the list. + */ + if (cmd->sam_task_attr == MSG_HEAD_TAG) { + pr_debug("Added HEAD_OF_QUEUE for CDB:" + " 0x%02x, se_ordered_id: %u\n", + cmd->t_task_cdb[0], + cmd->se_ordered_id); + return 1; + } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { + atomic_inc(&cmd->se_dev->dev_ordered_sync); + smp_mb__after_atomic_inc(); + + pr_debug("Added ORDERED for CDB: 0x%02x to ordered" + " list, se_ordered_id: %u\n", + cmd->t_task_cdb[0], + cmd->se_ordered_id); + /* + * Add ORDERED command to tail of execution queue if + * no other older commands exist that need to be + * completed first. + */ + if (!atomic_read(&cmd->se_dev->simple_cmds)) + return 1; + } else { + /* + * For SIMPLE and UNTAGGED Task Attribute commands + */ + atomic_inc(&cmd->se_dev->simple_cmds); + smp_mb__after_atomic_inc(); + } + /* + * Otherwise if one or more outstanding ORDERED task attribute exist, + * add the dormant task(s) built for the passed struct se_cmd to the + * execution queue and become in Active state for this struct se_device. + */ + if (atomic_read(&cmd->se_dev->dev_ordered_sync) != 0) { + /* + * Otherwise, add cmd w/ tasks to delayed cmd queue that + * will be drained upon completion of HEAD_OF_QUEUE task. + */ + spin_lock(&cmd->se_dev->delayed_cmd_lock); + cmd->se_cmd_flags |= SCF_DELAYED_CMD_FROM_SAM_ATTR; + list_add_tail(&cmd->se_delayed_node, + &cmd->se_dev->delayed_cmd_list); + spin_unlock(&cmd->se_dev->delayed_cmd_lock); + + pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to" + " delayed CMD list, se_ordered_id: %u\n", + cmd->t_task_cdb[0], cmd->sam_task_attr, + cmd->se_ordered_id); + /* + * Return zero to let transport_execute_tasks() know + * not to add the delayed tasks to the execution list. + */ + return 0; + } + /* + * Otherwise, no ORDERED task attributes exist.. + */ + return 1; +} + +/* + * Called from fabric module context in transport_generic_new_cmd() and + * transport_generic_process_write() + */ +static void transport_execute_tasks(struct se_cmd *cmd) +{ + int add_tasks; + struct se_device *se_dev = cmd->se_dev; + /* + * Call transport_cmd_check_stop() to see if a fabric exception + * has occurred that prevents execution. + */ + if (!transport_cmd_check_stop(cmd, 0, TRANSPORT_PROCESSING)) { + /* + * Check for SAM Task Attribute emulation and HEAD_OF_QUEUE + * attribute for the tasks of the received struct se_cmd CDB + */ + add_tasks = transport_execute_task_attr(cmd); + if (add_tasks) { + __transport_execute_tasks(se_dev, cmd); + return; + } + } + __transport_execute_tasks(se_dev, NULL); +} + +static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *new_cmd) +{ + int error; + struct se_cmd *cmd = NULL; + unsigned long flags; + +check_depth: + spin_lock_irq(&dev->execute_task_lock); + if (new_cmd != NULL) + __target_add_to_execute_list(new_cmd); + + if (list_empty(&dev->execute_list)) { + spin_unlock_irq(&dev->execute_task_lock); + return 0; + } + cmd = list_first_entry(&dev->execute_list, struct se_cmd, execute_list); + __target_remove_from_execute_list(cmd); + spin_unlock_irq(&dev->execute_task_lock); + + spin_lock_irqsave(&cmd->t_state_lock, flags); + cmd->transport_state |= CMD_T_BUSY; + cmd->transport_state |= CMD_T_SENT; + + spin_unlock_irqrestore(&cmd->t_state_lock, flags); if (cmd->execute_cmd) error = cmd->execute_cmd(cmd); + else { + error = dev->transport->execute_cmd(cmd, cmd->t_data_sg, + cmd->t_data_nents, cmd->data_direction); + } - if (error) { - spin_lock_irq(&cmd->t_state_lock); - cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); - spin_unlock_irq(&cmd->t_state_lock); + if (error != 0) { + spin_lock_irqsave(&cmd->t_state_lock, flags); + cmd->transport_state &= ~CMD_T_BUSY; + cmd->transport_state &= ~CMD_T_SENT; + spin_unlock_irqrestore(&cmd->t_state_lock, flags); transport_generic_request_failure(cmd); } + + new_cmd = NULL; + goto check_depth; + + return 0; } -void target_execute_cmd(struct se_cmd *cmd) +static inline u32 transport_get_sectors_6( + unsigned char *cdb, + struct se_cmd *cmd, + int *ret) { struct se_device *dev = cmd->se_dev; /* - * If the received CDB has aleady been aborted stop processing it here. + * Assume TYPE_DISK for non struct se_device objects. + * Use 8-bit sector value. */ - if (transport_check_aborted_status(cmd, 1)) - return; + if (!dev) + goto type_disk; /* - * Determine if IOCTL context caller in requesting the stopping of this - * command for LUN shutdown purposes. + * Use 24-bit allocation length for TYPE_TAPE. */ - spin_lock_irq(&cmd->t_state_lock); - if (cmd->transport_state & CMD_T_LUN_STOP) { - pr_debug("%s:%d CMD_T_LUN_STOP for ITT: 0x%08x\n", - __func__, __LINE__, cmd->se_tfo->get_task_tag(cmd)); + if (dev->transport->get_device_type(dev) == TYPE_TAPE) + return (u32)(cdb[2] << 16) + (cdb[3] << 8) + cdb[4]; - cmd->transport_state &= ~CMD_T_ACTIVE; - spin_unlock_irq(&cmd->t_state_lock); - complete(&cmd->transport_lun_stop_comp); - return; + /* + * Everything else assume TYPE_DISK Sector CDB location. + * Use 8-bit sector value. SBC-3 says: + * + * A TRANSFER LENGTH field set to zero specifies that 256 + * logical blocks shall be written. Any other value + * specifies the number of logical blocks that shall be + * written. + */ +type_disk: + return cdb[4] ? : 256; +} + +static inline u32 transport_get_sectors_10( + unsigned char *cdb, + struct se_cmd *cmd, + int *ret) +{ + struct se_device *dev = cmd->se_dev; + + /* + * Assume TYPE_DISK for non struct se_device objects. + * Use 16-bit sector value. + */ + if (!dev) + goto type_disk; + + /* + * XXX_10 is not defined in SSC, throw an exception + */ + if (dev->transport->get_device_type(dev) == TYPE_TAPE) { + *ret = -EINVAL; + return 0; } + /* - * Determine if frontend context caller is requesting the stopping of - * this command for frontend exceptions. + * Everything else assume TYPE_DISK Sector CDB location. + * Use 16-bit sector value. */ - if (cmd->transport_state & CMD_T_STOP) { - pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08x\n", - __func__, __LINE__, - cmd->se_tfo->get_task_tag(cmd)); +type_disk: + return (u32)(cdb[7] << 8) + cdb[8]; +} - spin_unlock_irq(&cmd->t_state_lock); - complete(&cmd->t_transport_stop_comp); - return; +static inline u32 transport_get_sectors_12( + unsigned char *cdb, + struct se_cmd *cmd, + int *ret) +{ + struct se_device *dev = cmd->se_dev; + + /* + * Assume TYPE_DISK for non struct se_device objects. + * Use 32-bit sector value. + */ + if (!dev) + goto type_disk; + + /* + * XXX_12 is not defined in SSC, throw an exception + */ + if (dev->transport->get_device_type(dev) == TYPE_TAPE) { + *ret = -EINVAL; + return 0; } - cmd->t_state = TRANSPORT_PROCESSING; - spin_unlock_irq(&cmd->t_state_lock); + /* + * Everything else assume TYPE_DISK Sector CDB location. + * Use 32-bit sector value. + */ +type_disk: + return (u32)(cdb[6] << 24) + (cdb[7] << 16) + (cdb[8] << 8) + cdb[9]; +} + +static inline u32 transport_get_sectors_16( + unsigned char *cdb, + struct se_cmd *cmd, + int *ret) +{ + struct se_device *dev = cmd->se_dev; - if (dev->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) - goto execute; + /* + * Assume TYPE_DISK for non struct se_device objects. + * Use 32-bit sector value. + */ + if (!dev) + goto type_disk; /* - * Check for the existence of HEAD_OF_QUEUE, and if true return 1 - * to allow the passed struct se_cmd list of tasks to the front of the list. + * Use 24-bit allocation length for TYPE_TAPE. */ - switch (cmd->sam_task_attr) { - case MSG_HEAD_TAG: - pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x, " - "se_ordered_id: %u\n", - cmd->t_task_cdb[0], cmd->se_ordered_id); - goto execute; - case MSG_ORDERED_TAG: - atomic_inc(&dev->dev_ordered_sync); - smp_mb__after_atomic_inc(); + if (dev->transport->get_device_type(dev) == TYPE_TAPE) + return (u32)(cdb[12] << 16) + (cdb[13] << 8) + cdb[14]; - pr_debug("Added ORDERED for CDB: 0x%02x to ordered list, " - " se_ordered_id: %u\n", - cmd->t_task_cdb[0], cmd->se_ordered_id); +type_disk: + return (u32)(cdb[10] << 24) + (cdb[11] << 16) + + (cdb[12] << 8) + cdb[13]; +} - /* - * Execute an ORDERED command if no other older commands - * exist that need to be completed first. - */ - if (!atomic_read(&dev->simple_cmds)) - goto execute; - break; - default: - /* - * For SIMPLE and UNTAGGED Task Attribute commands - */ - atomic_inc(&dev->simple_cmds); - smp_mb__after_atomic_inc(); - break; +/* + * Used for VARIABLE_LENGTH_CDB WRITE_32 and READ_32 variants + */ +static inline u32 transport_get_sectors_32( + unsigned char *cdb, + struct se_cmd *cmd, + int *ret) +{ + /* + * Assume TYPE_DISK for non struct se_device objects. + * Use 32-bit sector value. + */ + return (u32)(cdb[28] << 24) + (cdb[29] << 16) + + (cdb[30] << 8) + cdb[31]; + +} + +static inline u32 transport_get_size( + u32 sectors, + unsigned char *cdb, + struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + + if (dev->transport->get_device_type(dev) == TYPE_TAPE) { + if (cdb[1] & 1) { /* sectors */ + return dev->se_sub_dev->se_dev_attrib.block_size * sectors; + } else /* bytes */ + return sectors; } - if (atomic_read(&dev->dev_ordered_sync) != 0) { - spin_lock(&dev->delayed_cmd_lock); - list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); - spin_unlock(&dev->delayed_cmd_lock); + pr_debug("Returning block_size: %u, sectors: %u == %u for" + " %s object\n", dev->se_sub_dev->se_dev_attrib.block_size, + sectors, dev->se_sub_dev->se_dev_attrib.block_size * sectors, + dev->transport->name); - pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to" - " delayed CMD list, se_ordered_id: %u\n", - cmd->t_task_cdb[0], cmd->sam_task_attr, - cmd->se_ordered_id); + return dev->se_sub_dev->se_dev_attrib.block_size * sectors; +} + +static void transport_xor_callback(struct se_cmd *cmd) +{ + unsigned char *buf, *addr; + struct scatterlist *sg; + unsigned int offset; + int i; + int count; + /* + * From sbc3r22.pdf section 5.48 XDWRITEREAD (10) command + * + * 1) read the specified logical block(s); + * 2) transfer logical blocks from the data-out buffer; + * 3) XOR the logical blocks transferred from the data-out buffer with + * the logical blocks read, storing the resulting XOR data in a buffer; + * 4) if the DISABLE WRITE bit is set to zero, then write the logical + * blocks transferred from the data-out buffer; and + * 5) transfer the resulting XOR data to the data-in buffer. + */ + buf = kmalloc(cmd->data_length, GFP_KERNEL); + if (!buf) { + pr_err("Unable to allocate xor_callback buf\n"); return; } + /* + * Copy the scatterlist WRITE buffer located at cmd->t_data_sg + * into the locally allocated *buf + */ + sg_copy_to_buffer(cmd->t_data_sg, + cmd->t_data_nents, + buf, + cmd->data_length); -execute: /* - * Otherwise, no ORDERED task attributes exist.. + * Now perform the XOR against the BIDI read memory located at + * cmd->t_mem_bidi_list */ - __target_execute_cmd(cmd); + + offset = 0; + for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) { + addr = kmap_atomic(sg_page(sg)); + if (!addr) + goto out; + + for (i = 0; i < sg->length; i++) + *(addr + sg->offset + i) ^= *(buf + offset + i); + + offset += sg->length; + kunmap_atomic(addr); + } + +out: + kfree(buf); } -EXPORT_SYMBOL(target_execute_cmd); /* * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd @@ -1829,74 +2263,780 @@ static int transport_get_sense_data(struct se_cmd *cmd) WARN_ON(!cmd->se_lun); - if (!dev) - return 0; + if (!dev) + return 0; + + spin_lock_irqsave(&cmd->t_state_lock, flags); + if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return 0; + } + + if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) + goto out; + + if (!dev->transport->get_sense_buffer) { + pr_err("dev->transport->get_sense_buffer is NULL\n"); + goto out; + } + + sense_buffer = dev->transport->get_sense_buffer(cmd); + if (!sense_buffer) { + pr_err("ITT 0x%08x cmd %p: Unable to locate" + " sense buffer for task with sense\n", + cmd->se_tfo->get_task_tag(cmd), cmd); + goto out; + } + + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); + + memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); + + /* Automatically padded */ + cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + + pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", + dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); + return 0; + +out: + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return -1; +} + +static inline long long transport_dev_end_lba(struct se_device *dev) +{ + return dev->transport->get_blocks(dev) + 1; +} + +static int transport_cmd_get_valid_sectors(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + u32 sectors; + + if (dev->transport->get_device_type(dev) != TYPE_DISK) + return 0; + + sectors = (cmd->data_length / dev->se_sub_dev->se_dev_attrib.block_size); + + if ((cmd->t_task_lba + sectors) > transport_dev_end_lba(dev)) { + pr_err("LBA: %llu Sectors: %u exceeds" + " transport_dev_end_lba(): %llu\n", + cmd->t_task_lba, sectors, + transport_dev_end_lba(dev)); + return -EINVAL; + } + + return 0; +} + +static int target_check_write_same_discard(unsigned char *flags, struct se_device *dev) +{ + /* + * Determine if the received WRITE_SAME is used to for direct + * passthrough into Linux/SCSI with struct request via TCM/pSCSI + * or we are signaling the use of internal WRITE_SAME + UNMAP=1 + * emulation for -> Linux/BLOCK disbard with TCM/IBLOCK code. + */ + int passthrough = (dev->transport->transport_type == + TRANSPORT_PLUGIN_PHBA_PDEV); + + if (!passthrough) { + if ((flags[0] & 0x04) || (flags[0] & 0x02)) { + pr_err("WRITE_SAME PBDATA and LBDATA" + " bits not supported for Block Discard" + " Emulation\n"); + return -ENOSYS; + } + /* + * Currently for the emulated case we only accept + * tpws with the UNMAP=1 bit set. + */ + if (!(flags[0] & 0x08)) { + pr_err("WRITE_SAME w/o UNMAP bit not" + " supported for Block Discard Emulation\n"); + return -ENOSYS; + } + } + + return 0; +} + +/* transport_generic_cmd_sequencer(): + * + * Generic Command Sequencer that should work for most DAS transport + * drivers. + * + * Called from target_setup_cmd_from_cdb() in the $FABRIC_MOD + * RX Thread. + * + * FIXME: Need to support other SCSI OPCODES where as well. + */ +static int transport_generic_cmd_sequencer( + struct se_cmd *cmd, + unsigned char *cdb) +{ + struct se_device *dev = cmd->se_dev; + struct se_subsystem_dev *su_dev = dev->se_sub_dev; + int ret = 0, sector_ret = 0, passthrough; + u32 sectors = 0, size = 0, pr_reg_type = 0; + u16 service_action; + u8 alua_ascq = 0; + /* + * Check for an existing UNIT ATTENTION condition + */ + if (core_scsi3_ua_check(cmd, cdb) < 0) { + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; + return -EINVAL; + } + /* + * Check status of Asymmetric Logical Unit Assignment port + */ + ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq); + if (ret != 0) { + /* + * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; + * The ALUA additional sense code qualifier (ASCQ) is determined + * by the ALUA primary or secondary access state.. + */ + if (ret > 0) { + pr_debug("[%s]: ALUA TG Port not available," + " SenseKey: NOT_READY, ASC/ASCQ: 0x04/0x%02x\n", + cmd->se_tfo->get_fabric_name(), alua_ascq); + + transport_set_sense_codes(cmd, 0x04, alua_ascq); + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; + return -EINVAL; + } + goto out_invalid_cdb_field; + } + /* + * Check status for SPC-3 Persistent Reservations + */ + if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { + if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( + cmd, cdb, pr_reg_type) != 0) { + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; + cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; + return -EBUSY; + } + /* + * This means the CDB is allowed for the SCSI Initiator port + * when said port is *NOT* holding the legacy SPC-2 or + * SPC-3 Persistent Reservation. + */ + } + + /* + * If we operate in passthrough mode we skip most CDB emulation and + * instead hand the commands down to the physical SCSI device. + */ + passthrough = + (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV); + + switch (cdb[0]) { + case READ_6: + sectors = transport_get_sectors_6(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_21(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case READ_10: + sectors = transport_get_sectors_10(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_32(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case READ_12: + sectors = transport_get_sectors_12(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_32(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case READ_16: + sectors = transport_get_sectors_16(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_64(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case WRITE_6: + sectors = transport_get_sectors_6(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_21(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case WRITE_10: + case WRITE_VERIFY: + sectors = transport_get_sectors_10(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_32(cdb); + if (cdb[1] & 0x8) + cmd->se_cmd_flags |= SCF_FUA; + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case WRITE_12: + sectors = transport_get_sectors_12(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_32(cdb); + if (cdb[1] & 0x8) + cmd->se_cmd_flags |= SCF_FUA; + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case WRITE_16: + sectors = transport_get_sectors_16(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_64(cdb); + if (cdb[1] & 0x8) + cmd->se_cmd_flags |= SCF_FUA; + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + break; + case XDWRITEREAD_10: + if ((cmd->data_direction != DMA_TO_DEVICE) || + !(cmd->se_cmd_flags & SCF_BIDI)) + goto out_invalid_cdb_field; + sectors = transport_get_sectors_10(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + cmd->t_task_lba = transport_lba_32(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + + /* + * Do now allow BIDI commands for passthrough mode. + */ + if (passthrough) + goto out_unsupported_cdb; + + /* + * Setup BIDI XOR callback to be run after I/O completion. + */ + cmd->transport_complete_callback = &transport_xor_callback; + if (cdb[1] & 0x8) + cmd->se_cmd_flags |= SCF_FUA; + break; + case VARIABLE_LENGTH_CMD: + service_action = get_unaligned_be16(&cdb[8]); + switch (service_action) { + case XDWRITEREAD_32: + sectors = transport_get_sectors_32(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + size = transport_get_size(sectors, cdb, cmd); + /* + * Use WRITE_32 and READ_32 opcodes for the emulated + * XDWRITE_READ_32 logic. + */ + cmd->t_task_lba = transport_lba_64_ext(cdb); + cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; + + /* + * Do now allow BIDI commands for passthrough mode. + */ + if (passthrough) + goto out_unsupported_cdb; + + /* + * Setup BIDI XOR callback to be run during after I/O + * completion. + */ + cmd->transport_complete_callback = &transport_xor_callback; + if (cdb[1] & 0x8) + cmd->se_cmd_flags |= SCF_FUA; + break; + case WRITE_SAME_32: + sectors = transport_get_sectors_32(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + + if (sectors) + size = transport_get_size(1, cdb, cmd); + else { + pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" + " supported\n"); + goto out_invalid_cdb_field; + } + + cmd->t_task_lba = get_unaligned_be64(&cdb[12]); + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + + if (target_check_write_same_discard(&cdb[10], dev) < 0) + goto out_unsupported_cdb; + if (!passthrough) + cmd->execute_cmd = target_emulate_write_same; + break; + default: + pr_err("VARIABLE_LENGTH_CMD service action" + " 0x%04x not supported\n", service_action); + goto out_unsupported_cdb; + } + break; + case MAINTENANCE_IN: + if (dev->transport->get_device_type(dev) != TYPE_ROM) { + /* MAINTENANCE_IN from SCC-2 */ + /* + * Check for emulated MI_REPORT_TARGET_PGS. + */ + if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS && + su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { + cmd->execute_cmd = + target_emulate_report_target_port_groups; + } + size = (cdb[6] << 24) | (cdb[7] << 16) | + (cdb[8] << 8) | cdb[9]; + } else { + /* GPCMD_SEND_KEY from multi media commands */ + size = (cdb[8] << 8) + cdb[9]; + } + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case MODE_SELECT: + size = cdb[4]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case MODE_SELECT_10: + size = (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case MODE_SENSE: + size = cdb[4]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_modesense; + break; + case MODE_SENSE_10: + size = (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_modesense; + break; + case GPCMD_READ_BUFFER_CAPACITY: + case GPCMD_SEND_OPC: + case LOG_SELECT: + case LOG_SENSE: + size = (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case READ_BLOCK_LIMITS: + size = READ_BLOCK_LEN; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case GPCMD_GET_CONFIGURATION: + case GPCMD_READ_FORMAT_CAPACITIES: + case GPCMD_READ_DISC_INFO: + case GPCMD_READ_TRACK_RZONE_INFO: + size = (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case PERSISTENT_RESERVE_IN: + if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) + cmd->execute_cmd = target_scsi3_emulate_pr_in; + size = (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case PERSISTENT_RESERVE_OUT: + if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) + cmd->execute_cmd = target_scsi3_emulate_pr_out; + size = (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case GPCMD_MECHANISM_STATUS: + case GPCMD_READ_DVD_STRUCTURE: + size = (cdb[8] << 8) + cdb[9]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case READ_POSITION: + size = READ_POSITION_LEN; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case MAINTENANCE_OUT: + if (dev->transport->get_device_type(dev) != TYPE_ROM) { + /* MAINTENANCE_OUT from SCC-2 + * + * Check for emulated MO_SET_TARGET_PGS. + */ + if (cdb[1] == MO_SET_TARGET_PGS && + su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { + cmd->execute_cmd = + target_emulate_set_target_port_groups; + } + + size = (cdb[6] << 24) | (cdb[7] << 16) | + (cdb[8] << 8) | cdb[9]; + } else { + /* GPCMD_REPORT_KEY from multi media commands */ + size = (cdb[8] << 8) + cdb[9]; + } + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case INQUIRY: + size = (cdb[3] << 8) + cdb[4]; + /* + * Do implict HEAD_OF_QUEUE processing for INQUIRY. + * See spc4r17 section 5.3 + */ + if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) + cmd->sam_task_attr = MSG_HEAD_TAG; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_inquiry; + break; + case READ_BUFFER: + size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case READ_CAPACITY: + size = READ_CAP_LEN; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_readcapacity; + break; + case READ_MEDIA_SERIAL_NUMBER: + case SECURITY_PROTOCOL_IN: + case SECURITY_PROTOCOL_OUT: + size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case SERVICE_ACTION_IN: + switch (cmd->t_task_cdb[1] & 0x1f) { + case SAI_READ_CAPACITY_16: + if (!passthrough) + cmd->execute_cmd = + target_emulate_readcapacity_16; + break; + default: + if (passthrough) + break; + + pr_err("Unsupported SA: 0x%02x\n", + cmd->t_task_cdb[1] & 0x1f); + goto out_invalid_cdb_field; + } + /*FALLTHROUGH*/ + case ACCESS_CONTROL_IN: + case ACCESS_CONTROL_OUT: + case EXTENDED_COPY: + case READ_ATTRIBUTE: + case RECEIVE_COPY_RESULTS: + case WRITE_ATTRIBUTE: + size = (cdb[10] << 24) | (cdb[11] << 16) | + (cdb[12] << 8) | cdb[13]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case RECEIVE_DIAGNOSTIC: + case SEND_DIAGNOSTIC: + size = (cdb[3] << 8) | cdb[4]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; +/* #warning FIXME: Figure out correct GPCMD_READ_CD blocksize. */ +#if 0 + case GPCMD_READ_CD: + sectors = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; + size = (2336 * sectors); + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; +#endif + case READ_TOC: + size = cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case REQUEST_SENSE: + size = cdb[4]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_request_sense; + break; + case READ_ELEMENT_STATUS: + size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case WRITE_BUFFER: + size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case RESERVE: + case RESERVE_10: + /* + * The SPC-2 RESERVE does not contain a size in the SCSI CDB. + * Assume the passthrough or $FABRIC_MOD will tell us about it. + */ + if (cdb[0] == RESERVE_10) + size = (cdb[7] << 8) | cdb[8]; + else + size = cmd->data_length; + + /* + * Setup the legacy emulated handler for SPC-2 and + * >= SPC-3 compatible reservation handling (CRH=1) + * Otherwise, we assume the underlying SCSI logic is + * is running in SPC_PASSTHROUGH, and wants reservations + * emulation disabled. + */ + if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) + cmd->execute_cmd = target_scsi2_reservation_reserve; + cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; + break; + case RELEASE: + case RELEASE_10: + /* + * The SPC-2 RELEASE does not contain a size in the SCSI CDB. + * Assume the passthrough or $FABRIC_MOD will tell us about it. + */ + if (cdb[0] == RELEASE_10) + size = (cdb[7] << 8) | cdb[8]; + else + size = cmd->data_length; + + if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) + cmd->execute_cmd = target_scsi2_reservation_release; + cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; + break; + case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: + /* + * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE + */ + if (cdb[0] == SYNCHRONIZE_CACHE) { + sectors = transport_get_sectors_10(cdb, cmd, §or_ret); + cmd->t_task_lba = transport_lba_32(cdb); + } else { + sectors = transport_get_sectors_16(cdb, cmd, §or_ret); + cmd->t_task_lba = transport_lba_64(cdb); + } + if (sector_ret) + goto out_unsupported_cdb; + + size = transport_get_size(sectors, cdb, cmd); + cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; + + if (passthrough) + break; + + /* + * Check to ensure that LBA + Range does not exceed past end of + * device for IBLOCK and FILEIO ->do_sync_cache() backend calls + */ + if ((cmd->t_task_lba != 0) || (sectors != 0)) { + if (transport_cmd_get_valid_sectors(cmd) < 0) + goto out_invalid_cdb_field; + } + cmd->execute_cmd = target_emulate_synchronize_cache; + break; + case UNMAP: + size = get_unaligned_be16(&cdb[7]); + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_unmap; + break; + case WRITE_SAME_16: + sectors = transport_get_sectors_16(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; - spin_lock_irqsave(&cmd->t_state_lock, flags); - if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - return 0; - } + if (sectors) + size = transport_get_size(1, cdb, cmd); + else { + pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); + goto out_invalid_cdb_field; + } - if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) - goto out; + cmd->t_task_lba = get_unaligned_be64(&cdb[2]); + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; - if (!dev->transport->get_sense_buffer) { - pr_err("dev->transport->get_sense_buffer is NULL\n"); - goto out; - } + if (target_check_write_same_discard(&cdb[1], dev) < 0) + goto out_unsupported_cdb; + if (!passthrough) + cmd->execute_cmd = target_emulate_write_same; + break; + case WRITE_SAME: + sectors = transport_get_sectors_10(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; - sense_buffer = dev->transport->get_sense_buffer(cmd); - if (!sense_buffer) { - pr_err("ITT 0x%08x cmd %p: Unable to locate" - " sense buffer for task with sense\n", - cmd->se_tfo->get_task_tag(cmd), cmd); - goto out; - } + if (sectors) + size = transport_get_size(1, cdb, cmd); + else { + pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); + goto out_invalid_cdb_field; + } - spin_unlock_irqrestore(&cmd->t_state_lock, flags); + cmd->t_task_lba = get_unaligned_be32(&cdb[2]); + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + /* + * Follow sbcr26 with WRITE_SAME (10) and check for the existence + * of byte 1 bit 3 UNMAP instead of original reserved field + */ + if (target_check_write_same_discard(&cdb[1], dev) < 0) + goto out_unsupported_cdb; + if (!passthrough) + cmd->execute_cmd = target_emulate_write_same; + break; + case ALLOW_MEDIUM_REMOVAL: + case ERASE: + case REZERO_UNIT: + case SEEK_10: + case SPACE: + case START_STOP: + case TEST_UNIT_READY: + case VERIFY: + case WRITE_FILEMARKS: + cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; + if (!passthrough) + cmd->execute_cmd = target_emulate_noop; + break; + case GPCMD_CLOSE_TRACK: + case INITIALIZE_ELEMENT_STATUS: + case GPCMD_LOAD_UNLOAD: + case GPCMD_SET_SPEED: + case MOVE_MEDIUM: + cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; + break; + case REPORT_LUNS: + cmd->execute_cmd = target_report_luns; + size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + /* + * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS + * See spc4r17 section 5.3 + */ + if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) + cmd->sam_task_attr = MSG_HEAD_TAG; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case GET_EVENT_STATUS_NOTIFICATION: + size = (cdb[7] << 8) | cdb[8]; + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + case ATA_16: + /* Only support ATA passthrough to pSCSI backends.. */ + if (!passthrough) + goto out_unsupported_cdb; + + /* T_LENGTH */ + switch (cdb[2] & 0x3) { + case 0x0: + sectors = 0; + break; + case 0x1: + sectors = (((cdb[1] & 0x1) ? cdb[3] : 0) << 8) | cdb[4]; + break; + case 0x2: + sectors = (((cdb[1] & 0x1) ? cdb[5] : 0) << 8) | cdb[6]; + break; + case 0x3: + pr_err("T_LENGTH=0x3 not supported for ATA_16\n"); + goto out_invalid_cdb_field; + } - offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); + /* BYTE_BLOCK */ + if (cdb[2] & 0x4) { + /* BLOCK T_TYPE: 512 or sector */ + size = sectors * ((cdb[2] & 0x10) ? + dev->se_sub_dev->se_dev_attrib.block_size : 512); + } else { + /* BYTE */ + size = sectors; + } + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + break; + default: + pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" + " 0x%02x, sending CHECK_CONDITION.\n", + cmd->se_tfo->get_fabric_name(), cdb[0]); + goto out_unsupported_cdb; + } - memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); + if (cmd->unknown_data_length) + cmd->data_length = size; - /* Automatically padded */ - cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + if (size != cmd->data_length) { + pr_warn("TARGET_CORE[%s]: Expected Transfer Length:" + " %u does not match SCSI CDB Length: %u for SAM Opcode:" + " 0x%02x\n", cmd->se_tfo->get_fabric_name(), + cmd->data_length, size, cdb[0]); - pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", - dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); - return 0; + cmd->cmd_spdtl = size; -out: - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - return -1; -} + if (cmd->data_direction == DMA_TO_DEVICE) { + pr_err("Rejecting underflow/overflow" + " WRITE data\n"); + goto out_invalid_cdb_field; + } + /* + * Reject READ_* or WRITE_* with overflow/underflow for + * type SCF_SCSI_DATA_SG_IO_CDB. + */ + if (!ret && (dev->se_sub_dev->se_dev_attrib.block_size != 512)) { + pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" + " CDB on non 512-byte sector setup subsystem" + " plugin: %s\n", dev->transport->name); + /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ + goto out_invalid_cdb_field; + } -/* - * Process all commands up to the last received ORDERED task attribute which - * requires another blocking boundary - */ -static void target_restart_delayed_cmds(struct se_device *dev) -{ - for (;;) { - struct se_cmd *cmd; + if (size > cmd->data_length) { + cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; + cmd->residual_count = (size - cmd->data_length); + } else { + cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; + cmd->residual_count = (cmd->data_length - size); + } + cmd->data_length = size; + } - spin_lock(&dev->delayed_cmd_lock); - if (list_empty(&dev->delayed_cmd_list)) { - spin_unlock(&dev->delayed_cmd_lock); - break; + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + if (sectors > su_dev->se_dev_attrib.fabric_max_sectors) { + printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" + " big sectors %u exceeds fabric_max_sectors:" + " %u\n", cdb[0], sectors, + su_dev->se_dev_attrib.fabric_max_sectors); + goto out_invalid_cdb_field; + } + if (sectors > su_dev->se_dev_attrib.hw_max_sectors) { + printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" + " big sectors %u exceeds backend hw_max_sectors:" + " %u\n", cdb[0], sectors, + su_dev->se_dev_attrib.hw_max_sectors); + goto out_invalid_cdb_field; } + } - cmd = list_entry(dev->delayed_cmd_list.next, - struct se_cmd, se_delayed_node); - list_del(&cmd->se_delayed_node); - spin_unlock(&dev->delayed_cmd_lock); + /* reject any command that we don't have a handler for */ + if (!(passthrough || cmd->execute_cmd || + (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) + goto out_unsupported_cdb; - __target_execute_cmd(cmd); + transport_set_supported_SAM_opcode(cmd); + return ret; - if (cmd->sam_task_attr == MSG_ORDERED_TAG) - break; - } +out_unsupported_cdb: + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; + return -EINVAL; +out_invalid_cdb_field: + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; + return -EINVAL; } /* @@ -1906,6 +3046,8 @@ static void target_restart_delayed_cmds(struct se_device *dev) static void transport_complete_task_attr(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; + struct se_cmd *cmd_p, *cmd_tmp; + int new_active_tasks = 0; if (cmd->sam_task_attr == MSG_SIMPLE_TAG) { atomic_dec(&dev->simple_cmds); @@ -1927,8 +3069,38 @@ static void transport_complete_task_attr(struct se_cmd *cmd) pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" " %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); } + /* + * Process all commands up to the last received + * ORDERED task attribute which requires another blocking + * boundary + */ + spin_lock(&dev->delayed_cmd_lock); + list_for_each_entry_safe(cmd_p, cmd_tmp, + &dev->delayed_cmd_list, se_delayed_node) { - target_restart_delayed_cmds(dev); + list_del(&cmd_p->se_delayed_node); + spin_unlock(&dev->delayed_cmd_lock); + + pr_debug("Calling add_tasks() for" + " cmd_p: 0x%02x Task Attr: 0x%02x" + " Dormant -> Active, se_ordered_id: %u\n", + cmd_p->t_task_cdb[0], + cmd_p->sam_task_attr, cmd_p->se_ordered_id); + + target_add_to_execute_list(cmd_p); + new_active_tasks++; + + spin_lock(&dev->delayed_cmd_lock); + if (cmd_p->sam_task_attr == MSG_ORDERED_TAG) + break; + } + spin_unlock(&dev->delayed_cmd_lock); + /* + * If new tasks have become active, wake up the transport thread + * to do the processing of the Active tasks. + */ + if (new_active_tasks != 0) + wake_up_interruptible(&dev->dev_queue_obj.thread_wq); } static void transport_complete_qf(struct se_cmd *cmd) @@ -2187,27 +3359,31 @@ int transport_generic_map_mem_to_cmd( if (!sgl || !sgl_count) return 0; - /* - * Reject SCSI data overflow with map_mem_to_cmd() as incoming - * scatterlists already have been set to follow what the fabric - * passes for the original expected data transfer length. - */ - if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { - pr_warn("Rejecting SCSI DATA overflow for fabric using" - " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; - } + if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || + (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { + /* + * Reject SCSI data overflow with map_mem_to_cmd() as incoming + * scatterlists already have been set to follow what the fabric + * passes for the original expected data transfer length. + */ + if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { + pr_warn("Rejecting SCSI DATA overflow for fabric using" + " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; + return -EINVAL; + } - cmd->t_data_sg = sgl; - cmd->t_data_nents = sgl_count; + cmd->t_data_sg = sgl; + cmd->t_data_nents = sgl_count; - if (sgl_bidi && sgl_bidi_count) { - cmd->t_bidi_data_sg = sgl_bidi; - cmd->t_bidi_data_nents = sgl_bidi_count; + if (sgl_bidi && sgl_bidi_count) { + cmd->t_bidi_data_sg = sgl_bidi; + cmd->t_bidi_data_nents = sgl_bidi_count; + } + cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; } - cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; + return 0; } EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); @@ -2279,7 +3455,7 @@ transport_generic_get_mem(struct se_cmd *cmd) cmd->t_data_nents = nents; sg_init_table(cmd->t_data_sg, nents); - zero_flag = cmd->se_cmd_flags & SCF_SCSI_DATA_CDB ? 0 : __GFP_ZERO; + zero_flag = cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB ? 0 : __GFP_ZERO; while (length) { u32 page_len = min_t(u32, length, PAGE_SIZE); @@ -2310,6 +3486,7 @@ transport_generic_get_mem(struct se_cmd *cmd) */ int transport_generic_new_cmd(struct se_cmd *cmd) { + struct se_device *dev = cmd->se_dev; int ret = 0; /* @@ -2325,7 +3502,8 @@ int transport_generic_new_cmd(struct se_cmd *cmd) } /* Workaround for handling zero-length control CDBs */ - if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->data_length) { + if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && + !cmd->data_length) { spin_lock_irq(&cmd->t_state_lock); cmd->t_state = TRANSPORT_COMPLETE; cmd->transport_state |= CMD_T_ACTIVE; @@ -2343,45 +3521,52 @@ int transport_generic_new_cmd(struct se_cmd *cmd) return 0; } + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + struct se_dev_attrib *attr = &dev->se_sub_dev->se_dev_attrib; + + if (transport_cmd_get_valid_sectors(cmd) < 0) + return -EINVAL; + + BUG_ON(cmd->data_length % attr->block_size); + BUG_ON(DIV_ROUND_UP(cmd->data_length, attr->block_size) > + attr->hw_max_sectors); + } + atomic_inc(&cmd->t_fe_count); /* - * If this command is not a write we can execute it right here, - * for write buffers we need to notify the fabric driver first - * and let it call back once the write buffers are ready. + * For WRITEs, let the fabric know its buffer is ready. + * + * The command will be added to the execution queue after its write + * data has arrived. */ - target_add_to_state_list(cmd); - if (cmd->data_direction != DMA_TO_DEVICE) { - target_execute_cmd(cmd); - return 0; + if (cmd->data_direction == DMA_TO_DEVICE) { + target_add_to_state_list(cmd); + return transport_generic_write_pending(cmd); } - - spin_lock_irq(&cmd->t_state_lock); - cmd->t_state = TRANSPORT_WRITE_PENDING; - spin_unlock_irq(&cmd->t_state_lock); - - transport_cmd_check_stop(cmd, false); - - ret = cmd->se_tfo->write_pending(cmd); - if (ret == -EAGAIN || ret == -ENOMEM) - goto queue_full; - - if (ret < 0) - return ret; - return 1; + /* + * Everything else but a WRITE, add the command to the execution queue. + */ + transport_execute_tasks(cmd); + return 0; out_fail: cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; return -EINVAL; -queue_full: - pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); - cmd->t_state = TRANSPORT_COMPLETE_QF_WP; - transport_handle_queue_full(cmd, cmd->se_dev); - return 0; } EXPORT_SYMBOL(transport_generic_new_cmd); +/* transport_generic_process_write(): + * + * + */ +void transport_generic_process_write(struct se_cmd *cmd) +{ + transport_execute_tasks(cmd); +} +EXPORT_SYMBOL(transport_generic_process_write); + static void transport_write_pending_qf(struct se_cmd *cmd) { int ret; @@ -2394,6 +3579,43 @@ static void transport_write_pending_qf(struct se_cmd *cmd) } } +static int transport_generic_write_pending(struct se_cmd *cmd) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&cmd->t_state_lock, flags); + cmd->t_state = TRANSPORT_WRITE_PENDING; + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + /* + * Clear the se_cmd for WRITE_PENDING status in order to set + * CMD_T_ACTIVE so that transport_generic_handle_data can be called + * from HW target mode interrupt code. This is safe to be called + * with transport_off=1 before the cmd->se_tfo->write_pending + * because the se_cmd->se_lun pointer is not being cleared. + */ + transport_cmd_check_stop(cmd, 1, 0); + + /* + * Call the fabric write_pending function here to let the + * frontend know that WRITE buffers are ready. + */ + ret = cmd->se_tfo->write_pending(cmd); + if (ret == -EAGAIN || ret == -ENOMEM) + goto queue_full; + else if (ret < 0) + return ret; + + return 1; + +queue_full: + pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); + cmd->t_state = TRANSPORT_COMPLETE_QF_WP; + transport_handle_queue_full(cmd, cmd->se_dev); + return 0; +} + void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) { if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { @@ -2420,11 +3642,10 @@ EXPORT_SYMBOL(transport_generic_free_cmd); * @se_cmd: command descriptor to add * @ack_kref: Signal that fabric will perform an ack target_put_sess_cmd() */ -static int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd, - bool ack_kref) +void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd, + bool ack_kref) { unsigned long flags; - int ret = 0; kref_init(&se_cmd->cmd_kref); /* @@ -2438,17 +3659,11 @@ static int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd } spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); - if (se_sess->sess_tearing_down) { - ret = -ESHUTDOWN; - goto out; - } list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); se_cmd->check_release = 1; - -out: spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); - return ret; } +EXPORT_SYMBOL(target_get_sess_cmd); static void target_release_cmd_kref(struct kref *kref) { @@ -2483,27 +3698,28 @@ int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd) } EXPORT_SYMBOL(target_put_sess_cmd); -/* target_sess_cmd_list_set_waiting - Flag all commands in - * sess_cmd_list to complete cmd_wait_comp. Set - * sess_tearing_down so no more commands are queued. - * @se_sess: session to flag +/* target_splice_sess_cmd_list - Split active cmds into sess_wait_list + * @se_sess: session to split */ -void target_sess_cmd_list_set_waiting(struct se_session *se_sess) +void target_splice_sess_cmd_list(struct se_session *se_sess) { struct se_cmd *se_cmd; unsigned long flags; - spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); + WARN_ON(!list_empty(&se_sess->sess_wait_list)); + INIT_LIST_HEAD(&se_sess->sess_wait_list); - WARN_ON(se_sess->sess_tearing_down); + spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); se_sess->sess_tearing_down = 1; - list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) + list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list); + + list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) se_cmd->cmd_wait_set = 1; spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); } -EXPORT_SYMBOL(target_sess_cmd_list_set_waiting); +EXPORT_SYMBOL(target_splice_sess_cmd_list); /* target_wait_for_sess_cmds - Wait for outstanding descriptors * @se_sess: session to wait for active I/O @@ -2517,7 +3733,7 @@ void target_wait_for_sess_cmds( bool rc = false; list_for_each_entry_safe(se_cmd, tmp_cmd, - &se_sess->sess_cmd_list, se_cmd_list) { + &se_sess->sess_wait_list, se_cmd_list) { list_del(&se_cmd->se_cmd_list); pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:" @@ -2569,20 +3785,26 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) pr_debug("ConfigFS ITT[0x%08x] - CMD_T_STOP, skipping\n", cmd->se_tfo->get_task_tag(cmd)); spin_unlock_irqrestore(&cmd->t_state_lock, flags); - transport_cmd_check_stop(cmd, false); + transport_cmd_check_stop(cmd, 1, 0); return -EPERM; } cmd->transport_state |= CMD_T_LUN_FE_STOP; spin_unlock_irqrestore(&cmd->t_state_lock, flags); + wake_up_interruptible(&cmd->se_dev->dev_queue_obj.thread_wq); + // XXX: audit task_flags checks. spin_lock_irqsave(&cmd->t_state_lock, flags); if ((cmd->transport_state & CMD_T_BUSY) && (cmd->transport_state & CMD_T_SENT)) { if (!target_stop_cmd(cmd, &flags)) ret++; + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + } else { + spin_unlock_irqrestore(&cmd->t_state_lock, + flags); + target_remove_from_execute_list(cmd); } - spin_unlock_irqrestore(&cmd->t_state_lock, flags); pr_debug("ConfigFS: cmd: %p stop tasks ret:" " %d\n", cmd, ret); @@ -2593,6 +3815,7 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) pr_debug("ConfigFS: ITT[0x%08x] - stopped cmd....\n", cmd->se_tfo->get_task_tag(cmd)); } + transport_remove_cmd_from_queue(cmd); return 0; } @@ -2611,6 +3834,11 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun) struct se_cmd, se_lun_node); list_del_init(&cmd->se_lun_node); + /* + * This will notify iscsi_target_transport.c: + * transport_cmd_check_stop() that a LUN shutdown is in + * progress for the iscsi_cmd_t. + */ spin_lock(&cmd->t_state_lock); pr_debug("SE_LUN[%d] - Setting cmd->transport" "_lun_stop for ITT: 0x%08x\n", @@ -2677,7 +3905,7 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun) spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags); - transport_cmd_check_stop(cmd, false); + transport_cmd_check_stop(cmd, 1, 0); complete(&cmd->transport_lun_fe_stop_comp); spin_lock_irqsave(&lun->lun_cmd_lock, lun_flags); continue; @@ -2733,7 +3961,10 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) spin_unlock_irqrestore(&cmd->t_state_lock, flags); return false; } - + /* + * Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE + * has been set in transport_set_supported_SAM_opcode(). + */ if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); @@ -2791,6 +4022,8 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) spin_unlock_irqrestore(&cmd->t_state_lock, flags); + wake_up_interruptible(&cmd->se_dev->dev_queue_obj.thread_wq); + wait_for_completion(&cmd->t_transport_stop_comp); spin_lock_irqsave(&cmd->t_state_lock, flags); @@ -2973,15 +4206,6 @@ int transport_send_check_condition_and_sense( /* WRITE PROTECTED */ buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27; break; - case TCM_ADDRESS_OUT_OF_RANGE: - /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; - /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; - /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21; - break; case TCM_CHECK_CONDITION_UNIT_ATTENTION: /* CURRENT ERROR */ buffer[offset] = 0x70; @@ -3082,9 +4306,8 @@ void transport_send_task_abort(struct se_cmd *cmd) cmd->se_tfo->queue_status(cmd); } -static void target_tmr_work(struct work_struct *work) +static int transport_generic_do_tmr(struct se_cmd *cmd) { - struct se_cmd *cmd = container_of(work, struct se_cmd, work); struct se_device *dev = cmd->se_dev; struct se_tmr_req *tmr = cmd->se_tmr_req; int ret; @@ -3120,13 +4343,80 @@ static void target_tmr_work(struct work_struct *work) cmd->se_tfo->queue_tm_rsp(cmd); transport_cmd_check_stop_to_fabric(cmd); + return 0; } -int transport_generic_handle_tmr( - struct se_cmd *cmd) +/* transport_processing_thread(): + * + * + */ +static int transport_processing_thread(void *param) { - INIT_WORK(&cmd->work, target_tmr_work); - queue_work(cmd->se_dev->tmr_wq, &cmd->work); + int ret; + struct se_cmd *cmd; + struct se_device *dev = param; + + while (!kthread_should_stop()) { + ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq, + atomic_read(&dev->dev_queue_obj.queue_cnt) || + kthread_should_stop()); + if (ret < 0) + goto out; + +get_cmd: + cmd = transport_get_cmd_from_queue(&dev->dev_queue_obj); + if (!cmd) + continue; + + switch (cmd->t_state) { + case TRANSPORT_NEW_CMD: + BUG(); + break; + case TRANSPORT_NEW_CMD_MAP: + if (!cmd->se_tfo->new_cmd_map) { + pr_err("cmd->se_tfo->new_cmd_map is" + " NULL for TRANSPORT_NEW_CMD_MAP\n"); + BUG(); + } + ret = cmd->se_tfo->new_cmd_map(cmd); + if (ret < 0) { + transport_generic_request_failure(cmd); + break; + } + ret = transport_generic_new_cmd(cmd); + if (ret < 0) { + transport_generic_request_failure(cmd); + break; + } + break; + case TRANSPORT_PROCESS_WRITE: + transport_generic_process_write(cmd); + break; + case TRANSPORT_PROCESS_TMR: + transport_generic_do_tmr(cmd); + break; + case TRANSPORT_COMPLETE_QF_WP: + transport_write_pending_qf(cmd); + break; + case TRANSPORT_COMPLETE_QF_OK: + transport_complete_qf(cmd); + break; + default: + pr_err("Unknown t_state: %d for ITT: 0x%08x " + "i_state: %d on SE LUN: %u\n", + cmd->t_state, + cmd->se_tfo->get_task_tag(cmd), + cmd->se_tfo->get_cmd_state(cmd), + cmd->se_lun->unpacked_lun); + BUG(); + } + + goto get_cmd; + } + +out: + WARN_ON(!list_empty(&dev->state_list)); + WARN_ON(!list_empty(&dev->dev_queue_obj.qobj_list)); + dev->process_thread = NULL; return 0; } -EXPORT_SYMBOL(transport_generic_handle_tmr); diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index b9cb5006177e..f03fb9730f5b 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -215,7 +215,7 @@ int ft_write_pending(struct se_cmd *se_cmd) */ if ((ep->xid <= lport->lro_xid) && (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) { - if ((se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && + if ((se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) && lport->tt.ddp_target(lport, ep->xid, se_cmd->t_data_sg, se_cmd->t_data_nents)) @@ -230,8 +230,6 @@ u32 ft_get_task_tag(struct se_cmd *se_cmd) { struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); - if (cmd->aborted) - return ~0; return fc_seq_exch(cmd->seq)->rxid; } @@ -543,11 +541,9 @@ static void ft_send_work(struct work_struct *work) * Use a single se_cmd->cmd_kref as we expect to release se_cmd * directly from ft_check_stop_free callback in response path. */ - if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb, - &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun), - ntohl(fcp->fc_dl), task_attr, data_dir, 0)) - goto err; - + target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb, + &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun), + ntohl(fcp->fc_dl), task_attr, data_dir, 0); pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl); return; diff --git a/trunk/drivers/target/tcm_fc/tfc_io.c b/trunk/drivers/target/tcm_fc/tfc_io.c index ad36ede1a1ea..071a505f98fc 100644 --- a/trunk/drivers/target/tcm_fc/tfc_io.c +++ b/trunk/drivers/target/tcm_fc/tfc_io.c @@ -183,13 +183,6 @@ int ft_queue_data_in(struct se_cmd *se_cmd) return ft_queue_status(se_cmd); } -static void ft_execute_work(struct work_struct *work) -{ - struct ft_cmd *cmd = container_of(work, struct ft_cmd, work); - - target_execute_cmd(&cmd->se_cmd); -} - /* * Receive write data frame. */ @@ -314,10 +307,8 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp) cmd->write_data_len += tlen; } last_frame: - if (cmd->write_data_len == se_cmd->data_length) { - INIT_WORK(&cmd->work, ft_execute_work); - queue_work(cmd->sess->tport->tpg->workqueue, &cmd->work); - } + if (cmd->write_data_len == se_cmd->data_length) + transport_generic_handle_data(se_cmd); drop: fc_frame_free(fp); } diff --git a/trunk/drivers/target/tcm_fc/tfc_sess.c b/trunk/drivers/target/tcm_fc/tfc_sess.c index 87901fa74dd7..cb99da920068 100644 --- a/trunk/drivers/target/tcm_fc/tfc_sess.c +++ b/trunk/drivers/target/tcm_fc/tfc_sess.c @@ -58,8 +58,7 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport) struct ft_tport *tport; int i; - tport = rcu_dereference_protected(lport->prov[FC_TYPE_FCP], - lockdep_is_held(&ft_lport_lock)); + tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); if (tport && tport->tpg) return tport; diff --git a/trunk/drivers/tty/hvc/hvc_opal.c b/trunk/drivers/tty/hvc/hvc_opal.c index 0d2ea0c224c3..ced26c8ccd57 100644 --- a/trunk/drivers/tty/hvc/hvc_opal.c +++ b/trunk/drivers/tty/hvc/hvc_opal.c @@ -401,7 +401,7 @@ void __init hvc_opal_init_early(void) } #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW -void __init udbg_init_debug_opal_raw(void) +void __init udbg_init_debug_opal(void) { u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO; hvc_opal_privs[index] = &hvc_opal_boot_priv; diff --git a/trunk/drivers/tty/hvc/hvc_xen.c b/trunk/drivers/tty/hvc/hvc_xen.c index 944eaeb8e0cf..d3d91dae065c 100644 --- a/trunk/drivers/tty/hvc/hvc_xen.c +++ b/trunk/drivers/tty/hvc/hvc_xen.c @@ -214,24 +214,24 @@ static int xen_hvm_console_init(void) /* already configured */ if (info->intf != NULL) return 0; - /* - * If the toolstack (or the hypervisor) hasn't set these values, the - * default value is 0. Even though mfn = 0 and evtchn = 0 are - * theoretically correct values, in practice they never are and they - * mean that a legacy toolstack hasn't initialized the pv console correctly. - */ + r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); - if (r < 0 || v == 0) - goto err; + if (r < 0) { + kfree(info); + return -ENODEV; + } info->evtchn = v; - v = 0; - r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); - if (r < 0 || v == 0) - goto err; + hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); + if (r < 0) { + kfree(info); + return -ENODEV; + } mfn = v; info->intf = ioremap(mfn << PAGE_SHIFT, PAGE_SIZE); - if (info->intf == NULL) - goto err; + if (info->intf == NULL) { + kfree(info); + return -ENODEV; + } info->vtermno = HVC_COOKIE; spin_lock(&xencons_lock); @@ -239,9 +239,6 @@ static int xen_hvm_console_init(void) spin_unlock(&xencons_lock); return 0; -err: - kfree(info); - return -ENODEV; } static int xen_pv_console_init(void) diff --git a/trunk/drivers/tty/serial/8250/8250.c b/trunk/drivers/tty/serial/8250/8250.c index 6e1958a325bd..47d061b9ad4d 100644 --- a/trunk/drivers/tty/serial/8250/8250.c +++ b/trunk/drivers/tty/serial/8250/8250.c @@ -3113,7 +3113,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /** * serial8250_register_8250_port - register a serial port - * @up: serial port template + * @port: serial port template * * Configure the serial port specified by the request. If the * port exists and is in use, it is hung up and unregistered diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index c17923ec6e95..4ad721fb8405 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -133,10 +133,6 @@ struct pl011_dmatx_data { struct uart_amba_port { struct uart_port port; struct clk *clk; - /* Two optional pin states - default & sleep */ - struct pinctrl *pinctrl; - struct pinctrl_state *pins_default; - struct pinctrl_state *pins_sleep; const struct vendor_data *vendor; unsigned int dmacr; /* dma control reg */ unsigned int im; /* interrupt mask */ @@ -1316,14 +1312,6 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; - /* Optionaly enable pins to be muxed in and configured */ - if (!IS_ERR(uap->pins_default)) { - retval = pinctrl_select_state(uap->pinctrl, uap->pins_default); - if (retval) - dev_err(port->dev, - "could not set default pins\n"); - } - retval = clk_prepare(uap->clk); if (retval) goto out; @@ -1432,7 +1420,6 @@ static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; - int retval; /* * disable all interrupts @@ -1475,14 +1462,6 @@ static void pl011_shutdown(struct uart_port *port) */ clk_disable(uap->clk); clk_unprepare(uap->clk); - /* Optionally let pins go into sleep states */ - if (!IS_ERR(uap->pins_sleep)) { - retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); - if (retval) - dev_err(port->dev, - "could not set pins to sleep state\n"); - } - if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1813,14 +1792,6 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; - /* Allow pins to be muxed in and configured */ - if (!IS_ERR(uap->pins_default)) { - ret = pinctrl_select_state(uap->pinctrl, uap->pins_default); - if (ret) - dev_err(uap->port.dev, - "could not set default pins\n"); - } - ret = clk_prepare(uap->clk); if (ret) return ret; @@ -1873,6 +1844,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) { struct uart_amba_port *uap; struct vendor_data *vendor = id->data; + struct pinctrl *pinctrl; void __iomem *base; int i, ret; @@ -1897,20 +1869,11 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto free; } - uap->pinctrl = devm_pinctrl_get(&dev->dev); - if (IS_ERR(uap->pinctrl)) { - ret = PTR_ERR(uap->pinctrl); + pinctrl = devm_pinctrl_get_select_default(&dev->dev); + if (IS_ERR(pinctrl)) { + ret = PTR_ERR(pinctrl); goto unmap; } - uap->pins_default = pinctrl_lookup_state(uap->pinctrl, - PINCTRL_STATE_DEFAULT); - if (IS_ERR(uap->pins_default)) - dev_err(&dev->dev, "could not get default pinstate\n"); - - uap->pins_sleep = pinctrl_lookup_state(uap->pinctrl, - PINCTRL_STATE_SLEEP); - if (IS_ERR(uap->pins_sleep)) - dev_dbg(&dev->dev, "could not get sleep pinstate\n"); uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { diff --git a/trunk/drivers/tty/serial/serial_txx9.c b/trunk/drivers/tty/serial/serial_txx9.c index 6ae2a58d62f2..34bd345da775 100644 --- a/trunk/drivers/tty/serial/serial_txx9.c +++ b/trunk/drivers/tty/serial/serial_txx9.c @@ -466,7 +466,7 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) /* * Wait for transmitter & holding register to empty */ diff --git a/trunk/drivers/tty/serial/sh-sci.c b/trunk/drivers/tty/serial/sh-sci.c index 1bd9163bc118..4604153b7954 100644 --- a/trunk/drivers/tty/serial/sh-sci.c +++ b/trunk/drivers/tty/serial/sh-sci.c @@ -2179,16 +2179,6 @@ static int __devinit sci_init_single(struct platform_device *dev, return 0; } -static void sci_cleanup_single(struct sci_port *port) -{ - sci_free_gpios(port); - - clk_put(port->iclk); - clk_put(port->fclk); - - pm_runtime_disable(port->port.dev); -} - #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE static void serial_console_putchar(struct uart_port *port, int ch) { @@ -2370,10 +2360,14 @@ static int sci_remove(struct platform_device *dev) cpufreq_unregister_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); + sci_free_gpios(port); + uart_remove_one_port(&sci_uart_driver, &port->port); - sci_cleanup_single(port); + clk_put(port->iclk); + clk_put(port->fclk); + pm_runtime_disable(&dev->dev); return 0; } @@ -2391,20 +2385,14 @@ static int __devinit sci_probe_single(struct platform_device *dev, index+1, SCI_NPORTS); dev_notice(&dev->dev, "Consider bumping " "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); - return -EINVAL; + return 0; } ret = sci_init_single(dev, sciport, index, p); if (ret) return ret; - ret = uart_add_one_port(&sci_uart_driver, &sciport->port); - if (ret) { - sci_cleanup_single(sciport); - return ret; - } - - return 0; + return uart_add_one_port(&sci_uart_driver, &sciport->port); } static int __devinit sci_probe(struct platform_device *dev) @@ -2425,22 +2413,24 @@ static int __devinit sci_probe(struct platform_device *dev) ret = sci_probe_single(dev, dev->id, p, sp); if (ret) - return ret; + goto err_unreg; sp->freq_transition.notifier_call = sci_notifier; ret = cpufreq_register_notifier(&sp->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); - if (unlikely(ret < 0)) { - sci_cleanup_single(sp); - return ret; - } + if (unlikely(ret < 0)) + goto err_unreg; #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_gdb_detach(); #endif return 0; + +err_unreg: + sci_remove(dev); + return ret; } static int sci_suspend(struct device *dev) diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index f5ed3d75fa5a..c691eea51537 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB_COMMON) += phy/ +obj-$(CONFIG_USB) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 36a2a0b7b82c..f2a120eea9d4 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -567,14 +567,6 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) usb_autopm_put_interface(acm->control); - /* - * Unthrottle device in case the TTY was closed while throttled. - */ - spin_lock_irq(&acm->read_lock); - acm->throttled = 0; - acm->throttle_req = 0; - spin_unlock_irq(&acm->read_lock); - if (acm_submit_read_urbs(acm, GFP_KERNEL)) goto error_submit_read_urbs; diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index ee469274a3fe..ea8b304f0e85 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -55,15 +55,6 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ }, - { - /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | - USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = HUAWEI_VENDOR_ID, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 57, /* NOTE: CDC ECM control interface! */ - }, { } }; @@ -500,8 +491,6 @@ static ssize_t wdm_read goto retry; } if (!desc->reslength) { /* zero length read */ - dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); - clear_bit(WDM_READ, &desc->flags); spin_unlock_irq(&desc->iuspin); goto retry; } diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index 622b4a48e732..57ed9e400c06 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -493,6 +493,15 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); + /* + * Some systems crash if an EHCI controller is in D3 during + * a sleep transition. We have to leave such controllers in D0. + */ + if (hcd->broken_pci_sleep) { + dev_dbg(dev, "Staying in PCI D0\n"); + return retval; + } + /* If the root hub is dead rather than suspended, disallow remote * wakeup. usb_hc_died() should ensure that both hosts are marked as * dying, so we only need to check the primary roothub. diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 8fb484984c86..04fb834c3fa1 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -2324,16 +2324,12 @@ static unsigned hub_is_wusb(struct usb_hub *hub) static int hub_port_reset(struct usb_hub *hub, int port1, struct usb_device *udev, unsigned int delay, bool warm); -/* Is a USB 3.0 port in the Inactive or Complinance Mode state? - * Port worm reset is required to recover - */ -static bool hub_port_warm_reset_required(struct usb_hub *hub, u16 portstatus) +/* Is a USB 3.0 port in the Inactive state? */ +static bool hub_port_inactive(struct usb_hub *hub, u16 portstatus) { return hub_is_superspeed(hub->hdev) && - (((portstatus & USB_PORT_STAT_LINK_STATE) == - USB_SS_PORT_LS_SS_INACTIVE) || - ((portstatus & USB_PORT_STAT_LINK_STATE) == - USB_SS_PORT_LS_COMP_MOD)) ; + (portstatus & USB_PORT_STAT_LINK_STATE) == + USB_SS_PORT_LS_SS_INACTIVE; } static int hub_port_wait_reset(struct usb_hub *hub, int port1, @@ -2369,7 +2365,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, * * See https://bugzilla.kernel.org/show_bug.cgi?id=41752 */ - if (hub_port_warm_reset_required(hub, portstatus)) { + if (hub_port_inactive(hub, portstatus)) { int ret; if ((portchange & USB_PORT_STAT_C_CONNECTION)) @@ -3383,7 +3379,7 @@ int usb_disable_lpm(struct usb_device *udev) return 0; udev->lpm_disable_count++; - if ((udev->u1_params.timeout == 0 && udev->u2_params.timeout == 0)) + if ((udev->u1_params.timeout == 0 && udev->u1_params.timeout == 0)) return 0; /* If LPM is enabled, attempt to disable it. */ @@ -4412,7 +4408,9 @@ static void hub_events(void) /* Warm reset a USB3 protocol port if it's in * SS.Inactive state. */ - if (hub_port_warm_reset_required(hub, portstatus)) { + if (hub_is_superspeed(hub->hdev) && + (portstatus & USB_PORT_STAT_LINK_STATE) + == USB_SS_PORT_LS_SS_INACTIVE) { dev_dbg(hub_dev, "warm reset port %d\n", i); hub_port_reset(hub, i, NULL, HUB_BH_RESET_TIME, true); diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index bdd1c6749d88..b548cf1dbc62 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -1838,6 +1838,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) intfc = cp->intf_cache[i]; intf->altsetting = intfc->altsetting; intf->num_altsetting = intfc->num_altsetting; + intf->intf_assoc = find_iad(dev, cp, i); kref_get(&intfc->ref); alt = usb_altnum_to_altsetting(intf, 0); @@ -1850,8 +1851,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) if (!alt) alt = &intf->altsetting[0]; - intf->intf_assoc = - find_iad(dev, cp, alt->desc.bInterfaceNumber); intf->cur_altsetting = alt; usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; diff --git a/trunk/drivers/usb/dwc3/gadget.c b/trunk/drivers/usb/dwc3/gadget.c index ec70df7aba17..3df1a1973b05 100644 --- a/trunk/drivers/usb/dwc3/gadget.c +++ b/trunk/drivers/usb/dwc3/gadget.c @@ -1091,7 +1091,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { /* wait until it is processed */ dwc3_stop_active_transfer(dwc, dep->number); - goto out1; + goto out0; } dev_err(dwc->dev, "request %p was not queued to %s\n", request, ep->name); @@ -1099,7 +1099,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; } -out1: /* giveback the request */ dwc3_gadget_giveback(dep, req, -ECONNRESET); diff --git a/trunk/drivers/usb/gadget/atmel_usba_udc.c b/trunk/drivers/usb/gadget/atmel_usba_udc.c index 9a9bced813ed..e23bf7984aaf 100644 --- a/trunk/drivers/usb/gadget/atmel_usba_udc.c +++ b/trunk/drivers/usb/gadget/atmel_usba_udc.c @@ -599,6 +599,12 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) spin_lock_irqsave(&ep->udc->lock, flags); + if (ep->ep.desc) { + spin_unlock_irqrestore(&ep->udc->lock, flags); + DBG(DBG_ERR, "ep%d already enabled\n", ep->index); + return -EBUSY; + } + ep->ep.desc = desc; ep->ep.maxpacket = maxpacket; diff --git a/trunk/drivers/usb/gadget/fsl_qe_udc.c b/trunk/drivers/usb/gadget/fsl_qe_udc.c index b09452d6f33a..51881f3bd07a 100644 --- a/trunk/drivers/usb/gadget/fsl_qe_udc.c +++ b/trunk/drivers/usb/gadget/fsl_qe_udc.c @@ -1596,7 +1596,7 @@ static int qe_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct qe_ep, ep); /* catch various bogus parameters */ - if (!_ep || !desc || _ep->name == ep_name[0] || + if (!_ep || !desc || ep->ep.desc || _ep->name == ep_name[0] || (desc->bDescriptorType != USB_DT_ENDPOINT)) return -EINVAL; diff --git a/trunk/drivers/usb/gadget/fsl_qe_udc.h b/trunk/drivers/usb/gadget/fsl_qe_udc.h index 7026919fc901..4c07ca9cebf3 100644 --- a/trunk/drivers/usb/gadget/fsl_qe_udc.h +++ b/trunk/drivers/usb/gadget/fsl_qe_udc.h @@ -153,10 +153,10 @@ struct usb_ep_para{ #define USB_BUSMODE_DTB 0x02 /* Endpoint basic handle */ -#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress & 0xF) +#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ + USB_DIR_IN) : ((EP)->desc->bEndpointAddress \ & USB_DIR_IN) == USB_DIR_IN) /* ep0 transfer state */ diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index bc6f9bb9994a..28316858208b 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -567,7 +567,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct fsl_ep, ep); /* catch various bogus parameters */ - if (!_ep || !desc + if (!_ep || !desc || ep->ep.desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) return -EINVAL; @@ -2575,7 +2575,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) /* for ep0: the desc defined here; * for other eps, gadget layer called ep_enable with defined desc */ - udc_controller->eps[0].ep.desc = &fsl_ep0_desc; + udc_controller->eps[0].desc = &fsl_ep0_desc; udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; /* setup the udc->eps[] for non-control endpoints and link diff --git a/trunk/drivers/usb/gadget/fsl_usb2_udc.h b/trunk/drivers/usb/gadget/fsl_usb2_udc.h index f61a967f7082..5cd7b7e7ddb4 100644 --- a/trunk/drivers/usb/gadget/fsl_usb2_udc.h +++ b/trunk/drivers/usb/gadget/fsl_usb2_udc.h @@ -568,10 +568,10 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) /* * ### internal used help routines. */ -#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress&0xF) +#define ep_index(EP) ((EP)->desc->bEndpointAddress&0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ( (ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ + USB_DIR_IN ):((EP)->desc->bEndpointAddress \ & USB_DIR_IN)==USB_DIR_IN) #define get_ep_by_pipe(udc, pipe) ((pipe == 1)? &udc->eps[0]: \ &udc->eps[pipe]) diff --git a/trunk/drivers/usb/gadget/goku_udc.c b/trunk/drivers/usb/gadget/goku_udc.c index 3d28fb976c78..b241e6c6a7f2 100644 --- a/trunk/drivers/usb/gadget/goku_udc.c +++ b/trunk/drivers/usb/gadget/goku_udc.c @@ -102,7 +102,7 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) unsigned long flags; ep = container_of(_ep, struct goku_ep, ep); - if (!_ep || !desc + if (!_ep || !desc || ep->ep.desc || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; dev = ep->dev; diff --git a/trunk/drivers/usb/gadget/lpc32xx_udc.c b/trunk/drivers/usb/gadget/lpc32xx_udc.c index 2ab0388d93eb..262acfd53e32 100644 --- a/trunk/drivers/usb/gadget/lpc32xx_udc.c +++ b/trunk/drivers/usb/gadget/lpc32xx_udc.c @@ -61,7 +61,6 @@ #include #include #ifdef CONFIG_USB_GADGET_DEBUG_FILES -#include #include #endif diff --git a/trunk/drivers/usb/gadget/mv_udc_core.c b/trunk/drivers/usb/gadget/mv_udc_core.c index 117a4bba1b8c..dbcd1329495e 100644 --- a/trunk/drivers/usb/gadget/mv_udc_core.c +++ b/trunk/drivers/usb/gadget/mv_udc_core.c @@ -464,7 +464,7 @@ static int mv_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct mv_ep, ep); udc = ep->udc; - if (!_ep || !desc + if (!_ep || !desc || ep->ep.desc || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; diff --git a/trunk/drivers/usb/gadget/omap_udc.c b/trunk/drivers/usb/gadget/omap_udc.c index a460e8c204f4..7ba32469c5bd 100644 --- a/trunk/drivers/usb/gadget/omap_udc.c +++ b/trunk/drivers/usb/gadget/omap_udc.c @@ -153,7 +153,7 @@ static int omap_ep_enable(struct usb_ep *_ep, u16 maxp; /* catch various bogus parameters */ - if (!_ep || !desc + if (!_ep || !desc || ep->ep.desc || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep->maxpacket < usb_endpoint_maxp(desc)) { diff --git a/trunk/drivers/usb/gadget/pxa25x_udc.c b/trunk/drivers/usb/gadget/pxa25x_udc.c index f7ff9e8e746a..d7c8cb3bf759 100644 --- a/trunk/drivers/usb/gadget/pxa25x_udc.c +++ b/trunk/drivers/usb/gadget/pxa25x_udc.c @@ -218,7 +218,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep, struct pxa25x_udc *dev; ep = container_of (_ep, struct pxa25x_ep, ep); - if (!_ep || !desc || _ep->name == ep0name + if (!_ep || !desc || ep->ep.desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep->fifo_size < usb_endpoint_maxp (desc)) { diff --git a/trunk/drivers/usb/gadget/s3c-hsudc.c b/trunk/drivers/usb/gadget/s3c-hsudc.c index 236b271871a0..36c6836eeb0f 100644 --- a/trunk/drivers/usb/gadget/s3c-hsudc.c +++ b/trunk/drivers/usb/gadget/s3c-hsudc.c @@ -760,7 +760,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, u32 ecr = 0; hsep = our_ep(_ep); - if (!_ep || !desc || _ep->name == ep0name + if (!_ep || !desc || hsep->ep.desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || hsep->bEndpointAddress != desc->bEndpointAddress || ep_maxpacket(hsep) < usb_endpoint_maxp(desc)) diff --git a/trunk/drivers/usb/gadget/s3c2410_udc.c b/trunk/drivers/usb/gadget/s3c2410_udc.c index f2e51f50e528..3de71d37d75e 100644 --- a/trunk/drivers/usb/gadget/s3c2410_udc.c +++ b/trunk/drivers/usb/gadget/s3c2410_udc.c @@ -1062,7 +1062,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, ep = to_s3c2410_ep(_ep); - if (!_ep || !desc + if (!_ep || !desc || ep->ep.desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; diff --git a/trunk/drivers/usb/gadget/tcm_usb_gadget.c b/trunk/drivers/usb/gadget/tcm_usb_gadget.c index 5444866e13ef..c46439c8dd74 100644 --- a/trunk/drivers/usb/gadget/tcm_usb_gadget.c +++ b/trunk/drivers/usb/gadget/tcm_usb_gadget.c @@ -294,7 +294,7 @@ static int bot_send_write_request(struct usbg_cmd *cmd) pr_err("%s(%d)\n", __func__, __LINE__); wait_for_completion(&cmd->write_complete); - target_execute_cmd(se_cmd); + transport_generic_process_write(se_cmd); cleanup: return ret; } @@ -725,7 +725,7 @@ static int uasp_send_write_request(struct usbg_cmd *cmd) } wait_for_completion(&cmd->write_complete); - target_execute_cmd(se_cmd); + transport_generic_process_write(se_cmd); cleanup: return ret; } @@ -1065,20 +1065,16 @@ static void usbg_cmd_work(struct work_struct *work) tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, cmd->prio_attr, cmd->sense_iu.sense); - goto out; + + transport_send_check_condition_and_sense(se_cmd, + TCM_UNSUPPORTED_SCSI_OPCODE, 1); + usbg_cleanup_cmd(cmd); + return; } - if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, + target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, - 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE) < 0) - goto out; - - return; - -out: - transport_send_check_condition_and_sense(se_cmd, - TCM_UNSUPPORTED_SCSI_OPCODE, 1); - usbg_cleanup_cmd(cmd); + 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE); } static int usbg_submit_command(struct f_uas *fu, @@ -1181,20 +1177,16 @@ static void bot_cmd_work(struct work_struct *work) tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, cmd->prio_attr, cmd->sense_iu.sense); - goto out; + + transport_send_check_condition_and_sense(se_cmd, + TCM_UNSUPPORTED_SCSI_OPCODE, 1); + usbg_cleanup_cmd(cmd); + return; } - if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, + target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, - cmd->data_len, cmd->prio_attr, dir, 0) < 0) - goto out; - - return; - -out: - transport_send_check_condition_and_sense(se_cmd, - TCM_UNSUPPORTED_SCSI_OPCODE, 1); - usbg_cleanup_cmd(cmd); + cmd->data_len, cmd->prio_attr, dir, 0); } static int bot_submit_command(struct f_uas *fu, @@ -1408,6 +1400,19 @@ static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg) return 1; } +static int usbg_new_cmd(struct se_cmd *se_cmd) +{ + struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, + se_cmd); + int ret; + + ret = target_setup_cmd_from_cdb(se_cmd, cmd->cmd_buf); + if (ret) + return ret; + + return transport_generic_map_mem_to_cmd(se_cmd, NULL, 0, NULL, 0); +} + static void usbg_cmd_release(struct kref *ref) { struct usbg_cmd *cmd = container_of(ref, struct usbg_cmd, @@ -1897,6 +1902,7 @@ static struct target_core_fabric_ops usbg_ops = { .tpg_alloc_fabric_acl = usbg_alloc_fabric_acl, .tpg_release_fabric_acl = usbg_release_fabric_acl, .tpg_get_inst_index = usbg_tpg_get_inst_index, + .new_cmd_map = usbg_new_cmd, .release_cmd = usbg_release_cmd, .shutdown_session = usbg_shutdown_session, .close_session = usbg_close_session, diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 800be38c78b4..b100f5f9f4b6 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -671,9 +671,7 @@ static int ehci_init(struct usb_hcd *hcd) hw = ehci->async->hw; hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); -#if defined(CONFIG_PPC_PS3) hw->hw_info1 |= cpu_to_hc32(ehci, (1 << 7)); /* I = 1 */ -#endif hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); hw->hw_qtd_next = EHCI_LIST_END(ehci); ehci->async->qh_state = QH_STATE_LINKED; diff --git a/trunk/drivers/usb/host/ehci-omap.c b/trunk/drivers/usb/host/ehci-omap.c index c30435499a02..a44294d13494 100644 --- a/trunk/drivers/usb/host/ehci-omap.c +++ b/trunk/drivers/usb/host/ehci-omap.c @@ -43,7 +43,6 @@ #include #include #include -#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -56,15 +55,6 @@ #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 -/* Errata i693 */ -static struct clk *utmi_p1_fck; -static struct clk *utmi_p2_fck; -static struct clk *xclk60mhsp1_ck; -static struct clk *xclk60mhsp2_ck; -static struct clk *usbhost_p1_fck; -static struct clk *usbhost_p2_fck; -static struct clk *init_60m_fclk; - /*-------------------------------------------------------------------------*/ static const struct hc_driver ehci_omap_hc_driver; @@ -80,41 +70,6 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) return __raw_readl(base + reg); } -/* Erratum i693 workaround sequence */ -static void omap_ehci_erratum_i693(struct ehci_hcd *ehci) -{ - int ret = 0; - - /* Switch to the internal 60 MHz clock */ - ret = clk_set_parent(utmi_p1_fck, init_60m_fclk); - if (ret != 0) - ehci_err(ehci, "init_60m_fclk set parent" - "failed error:%d\n", ret); - - ret = clk_set_parent(utmi_p2_fck, init_60m_fclk); - if (ret != 0) - ehci_err(ehci, "init_60m_fclk set parent" - "failed error:%d\n", ret); - - clk_enable(usbhost_p1_fck); - clk_enable(usbhost_p2_fck); - - /* Wait 1ms and switch back to the external clock */ - mdelay(1); - ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck); - if (ret != 0) - ehci_err(ehci, "xclk60mhsp1_ck set parent" - "failed error:%d\n", ret); - - ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck); - if (ret != 0) - ehci_err(ehci, "xclk60mhsp2_ck set parent" - "failed error:%d\n", ret); - - clk_disable(usbhost_p1_fck); - clk_disable(usbhost_p2_fck); -} - static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) { struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev); @@ -145,50 +100,6 @@ static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) } } -static int omap_ehci_hub_control( - struct usb_hcd *hcd, - u16 typeReq, - u16 wValue, - u16 wIndex, - char *buf, - u16 wLength -) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - u32 __iomem *status_reg = &ehci->regs->port_status[ - (wIndex & 0xff) - 1]; - u32 temp; - unsigned long flags; - int retval = 0; - - spin_lock_irqsave(&ehci->lock, flags); - - if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { - temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { - retval = -EPIPE; - goto done; - } - - temp &= ~PORT_WKCONN_E; - temp |= PORT_WKDISC_E | PORT_WKOC_E; - ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); - - omap_ehci_erratum_i693(ehci); - - set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); - goto done; - } - - spin_unlock_irqrestore(&ehci->lock, flags); - - /* Handle the hub control events here */ - return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); -done: - spin_unlock_irqrestore(&ehci->lock, flags); - return retval; -} - static void disable_put_regulator( struct ehci_hcd_omap_platform_data *pdata) { @@ -281,13 +192,14 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } } - /* Hold PHYs in reset while initializing EHCI controller */ if (pdata->phy_reset) { if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0); + gpio_request_one(pdata->reset_gpio_port[0], + GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0); + gpio_request_one(pdata->reset_gpio_port[1], + GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); @@ -329,11 +241,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); ehci_reset(omap_ehci); - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) { - dev_err(dev, "failed to add hcd with err %d\n", ret); - goto err_add_hcd; - } if (pdata->phy_reset) { /* Hold the PHY in RESET for enough time till @@ -348,79 +255,17 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1); } - /* root ports should always stay powered */ - ehci_port_power(omap_ehci, 1); - - /* get clocks */ - utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); - if (IS_ERR(utmi_p1_fck)) { - ret = PTR_ERR(utmi_p1_fck); - dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (ret) { + dev_err(dev, "failed to add hcd with err %d\n", ret); goto err_add_hcd; } - xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); - if (IS_ERR(xclk60mhsp1_ck)) { - ret = PTR_ERR(xclk60mhsp1_ck); - dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); - goto err_utmi_p1_fck; - } - - utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); - if (IS_ERR(utmi_p2_fck)) { - ret = PTR_ERR(utmi_p2_fck); - dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); - goto err_xclk60mhsp1_ck; - } - - xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); - if (IS_ERR(xclk60mhsp2_ck)) { - ret = PTR_ERR(xclk60mhsp2_ck); - dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); - goto err_utmi_p2_fck; - } - - usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); - if (IS_ERR(usbhost_p1_fck)) { - ret = PTR_ERR(usbhost_p1_fck); - dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); - goto err_xclk60mhsp2_ck; - } - - usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); - if (IS_ERR(usbhost_p2_fck)) { - ret = PTR_ERR(usbhost_p2_fck); - dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); - goto err_usbhost_p1_fck; - } - - init_60m_fclk = clk_get(dev, "init_60m_fclk"); - if (IS_ERR(init_60m_fclk)) { - ret = PTR_ERR(init_60m_fclk); - dev_err(dev, "init_60m_fclk failed error:%d\n", ret); - goto err_usbhost_p2_fck; - } + /* root ports should always stay powered */ + ehci_port_power(omap_ehci, 1); return 0; -err_usbhost_p2_fck: - clk_put(usbhost_p2_fck); - -err_usbhost_p1_fck: - clk_put(usbhost_p1_fck); - -err_xclk60mhsp2_ck: - clk_put(xclk60mhsp2_ck); - -err_utmi_p2_fck: - clk_put(utmi_p2_fck); - -err_xclk60mhsp1_ck: - clk_put(xclk60mhsp1_ck); - -err_utmi_p1_fck: - clk_put(utmi_p1_fck); - err_add_hcd: disable_put_regulator(pdata); pm_runtime_put_sync(dev); @@ -449,15 +294,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) disable_put_regulator(dev->platform_data); iounmap(hcd->regs); usb_put_hcd(hcd); - - clk_put(utmi_p1_fck); - clk_put(utmi_p2_fck); - clk_put(xclk60mhsp1_ck); - clk_put(xclk60mhsp2_ck); - clk_put(usbhost_p1_fck); - clk_put(usbhost_p2_fck); - clk_put(init_60m_fclk); - pm_runtime_put_sync(dev); pm_runtime_disable(dev); @@ -528,7 +364,7 @@ static const struct hc_driver ehci_omap_hc_driver = { * root hub support */ .hub_status_data = ehci_hub_status_data, - .hub_control = omap_ehci_hub_control, + .hub_control = ehci_hub_control, .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index 123481793a47..bc94d7bf072d 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd *hcd) hcd->has_tt = 1; tdi_reset(ehci); } + if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { + /* EHCI #1 or #2 on 6 Series/C200 Series chipset */ + if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { + ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); + hcd->broken_pci_sleep = 1; + device_set_wakeup_capable(&pdev->dev, false); + } + } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/trunk/drivers/usb/host/ehci-sh.c b/trunk/drivers/usb/host/ehci-sh.c index e7cb3925abf8..ca819cdd0c5e 100644 --- a/trunk/drivers/usb/host/ehci-sh.c +++ b/trunk/drivers/usb/host/ehci-sh.c @@ -126,7 +126,8 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) goto fail_create_hcd; } - pdata = pdev->dev.platform_data; + if (pdev->dev.platform_data != NULL) + pdata = pdev->dev.platform_data; /* initialize hcd */ hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev, diff --git a/trunk/drivers/usb/host/ehci-xilinx-of.c b/trunk/drivers/usb/host/ehci-xilinx-of.c index e9713d589e30..9c2cc4633894 100644 --- a/trunk/drivers/usb/host/ehci-xilinx-of.c +++ b/trunk/drivers/usb/host/ehci-xilinx-of.c @@ -270,12 +270,14 @@ static int ehci_hcd_xilinx_of_remove(struct platform_device *op) * * Properly shutdown the hcd, call driver's shutdown routine. */ -static void ehci_hcd_xilinx_of_shutdown(struct platform_device *op) +static int ehci_hcd_xilinx_of_shutdown(struct platform_device *op) { struct usb_hcd *hcd = dev_get_drvdata(&op->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); + + return 0; } diff --git a/trunk/drivers/usb/host/ohci-hub.c b/trunk/drivers/usb/host/ohci-hub.c index 2f3619eefefa..836772dfabd3 100644 --- a/trunk/drivers/usb/host/ohci-hub.c +++ b/trunk/drivers/usb/host/ohci-hub.c @@ -317,7 +317,7 @@ static int ohci_bus_resume (struct usb_hcd *hcd) } /* Carry out the final steps of resuming the controller device */ -static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd) +static void ohci_finish_controller_resume(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int port; diff --git a/trunk/drivers/usb/host/xhci-hub.c b/trunk/drivers/usb/host/xhci-hub.c index 7b01094d7993..2732ef660c5c 100644 --- a/trunk/drivers/usb/host/xhci-hub.c +++ b/trunk/drivers/usb/host/xhci-hub.c @@ -462,42 +462,6 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, } } -/* Updates Link Status for super Speed port */ -static void xhci_hub_report_link_state(u32 *status, u32 status_reg) -{ - u32 pls = status_reg & PORT_PLS_MASK; - - /* resume state is a xHCI internal state. - * Do not report it to usb core. - */ - if (pls == XDEV_RESUME) - return; - - /* When the CAS bit is set then warm reset - * should be performed on port - */ - if (status_reg & PORT_CAS) { - /* The CAS bit can be set while the port is - * in any link state. - * Only roothubs have CAS bit, so we - * pretend to be in compliance mode - * unless we're already in compliance - * or the inactive state. - */ - if (pls != USB_SS_PORT_LS_COMP_MOD && - pls != USB_SS_PORT_LS_SS_INACTIVE) { - pls = USB_SS_PORT_LS_COMP_MOD; - } - /* Return also connection bit - - * hub state machine resets port - * when this bit is set. - */ - pls |= USB_PORT_STAT_CONNECTION; - } - /* update status field */ - *status |= pls; -} - int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { @@ -642,9 +606,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, else status |= USB_PORT_STAT_POWER; } - /* Update Port Link State for super speed ports*/ + /* Port Link State */ if (hcd->speed == HCD_USB3) { - xhci_hub_report_link_state(&status, temp); + /* resume state is a xHCI internal state. + * Do not report it to usb core. + */ + if ((temp & PORT_PLS_MASK) != XDEV_RESUME) + status |= (temp & PORT_PLS_MASK); } if (bus_state->port_c_suspend & (1 << wIndex)) status |= 1 << USB_PORT_FEAT_C_SUSPEND; diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 77689bd64cac..ec4338eec826 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -793,9 +793,10 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, int slot_id) { + struct list_head *tt; struct list_head *tt_list_head; - struct xhci_tt_bw_info *tt_info, *next; - bool slot_found = false; + struct list_head *tt_next; + struct xhci_tt_bw_info *tt_info; /* If the device never made it past the Set Address stage, * it may not have the real_port set correctly. @@ -807,16 +808,34 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, } tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts); - list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { - /* Multi-TT hubs will have more than one entry */ - if (tt_info->slot_id == slot_id) { - slot_found = true; - list_del(&tt_info->tt_list); - kfree(tt_info); - } else if (slot_found) { + if (list_empty(tt_list_head)) + return; + + list_for_each(tt, tt_list_head) { + tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); + if (tt_info->slot_id == slot_id) break; - } } + /* Cautionary measure in case the hub was disconnected before we + * stored the TT information. + */ + if (tt_info->slot_id != slot_id) + return; + + tt_next = tt->next; + tt_info = list_entry(tt, struct xhci_tt_bw_info, + tt_list); + /* Multi-TT hubs will have more than one entry */ + do { + list_del(tt); + kfree(tt_info); + tt = tt_next; + if (list_empty(tt_list_head)) + break; + tt_next = tt->next; + tt_info = list_entry(tt, struct xhci_tt_bw_info, + tt_list); + } while (tt_info->slot_id == slot_id); } int xhci_alloc_tt_info(struct xhci_hcd *xhci, @@ -1772,9 +1791,17 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) { struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); struct dev_info *dev_info, *next; + struct list_head *tt_list_head; + struct list_head *tt; + struct list_head *endpoints; + struct list_head *ep, *q; + struct xhci_tt_bw_info *tt_info; + struct xhci_interval_bw_table *bwt; + struct xhci_virt_ep *virt_ep; + unsigned long flags; int size; - int i, j, num_ports; + int i; /* Free the Event Ring Segment Table and the actual Event Ring */ size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); @@ -1833,22 +1860,21 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } spin_unlock_irqrestore(&xhci->lock, flags); - num_ports = HCS_MAX_PORTS(xhci->hcs_params1); - for (i = 0; i < num_ports; i++) { - struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; - for (j = 0; j < XHCI_MAX_INTERVAL; j++) { - struct list_head *ep = &bwt->interval_bw[j].endpoints; - while (!list_empty(ep)) - list_del_init(ep->next); + bwt = &xhci->rh_bw->bw_table; + for (i = 0; i < XHCI_MAX_INTERVAL; i++) { + endpoints = &bwt->interval_bw[i].endpoints; + list_for_each_safe(ep, q, endpoints) { + virt_ep = list_entry(ep, struct xhci_virt_ep, bw_endpoint_list); + list_del(&virt_ep->bw_endpoint_list); + kfree(virt_ep); } } - for (i = 0; i < num_ports; i++) { - struct xhci_tt_bw_info *tt, *n; - list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) { - list_del(&tt->tt_list); - kfree(tt); - } + tt_list_head = &xhci->rh_bw->tts; + list_for_each_safe(tt, q, tt_list_head) { + tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); + list_del(tt); + kfree(tt_info); } xhci->num_usb2_ports = 0; diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 8275645889da..23b4aefd1036 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -885,17 +885,6 @@ static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci, num_trbs_free_temp = ep_ring->num_trbs_free; dequeue_temp = ep_ring->dequeue; - /* If we get two back-to-back stalls, and the first stalled transfer - * ends just before a link TRB, the dequeue pointer will be left on - * the link TRB by the code in the while loop. So we have to update - * the dequeue pointer one segment further, or we'll jump off - * the segment into la-la-land. - */ - if (last_trb(xhci, ep_ring, ep_ring->deq_seg, ep_ring->dequeue)) { - ep_ring->deq_seg = ep_ring->deq_seg->next; - ep_ring->dequeue = ep_ring->deq_seg->trbs; - } - while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) { /* We have more usable TRBs */ ep_ring->num_trbs_free++; diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index a979cd0dbe0f..afdc73ee84a6 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -795,8 +795,8 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CSS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { - xhci_warn(xhci, "WARN: xHC save state timeout\n"); + if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) { + xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } @@ -848,8 +848,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command |= CMD_CRS; xhci_writel(xhci, command, &xhci->op_regs->command); if (handshake(xhci, &xhci->op_regs->status, - STS_RESTORE, 0, 10 * 1000)) { - xhci_warn(xhci, "WARN: xHC restore state timeout\n"); + STS_RESTORE, 0, 10*100)) { + xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } @@ -3906,7 +3906,7 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, default: dev_warn(&udev->dev, "%s: Can't get timeout for non-U1 or U2 state.\n", __func__); - return USB3_LPM_DISABLED; + return -EINVAL; } if (sel <= max_sel_pel && pel <= max_sel_pel) diff --git a/trunk/drivers/usb/host/xhci.h b/trunk/drivers/usb/host/xhci.h index 55c0785810c9..de3d6e3e57be 100644 --- a/trunk/drivers/usb/host/xhci.h +++ b/trunk/drivers/usb/host/xhci.h @@ -341,11 +341,7 @@ struct xhci_op_regs { #define PORT_PLC (1 << 22) /* port configure error change - port failed to configure its link partner */ #define PORT_CEC (1 << 23) -/* Cold Attach Status - xHC can set this bit to report device attached during - * Sx state. Warm port reset should be perfomed to clear this bit and move port - * to connected state. - */ -#define PORT_CAS (1 << 24) +/* bit 24 reserved */ /* wake on connect (enable) */ #define PORT_WKCONN_E (1 << 25) /* wake on disconnect (enable) */ diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index 9d63ba4d10d6..768b4b55c816 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -34,7 +34,6 @@ #include #include -#include #include diff --git a/trunk/drivers/usb/musb/davinci.h b/trunk/drivers/usb/musb/davinci.h index 371baa0ee509..046c84433cad 100644 --- a/trunk/drivers/usb/musb/davinci.h +++ b/trunk/drivers/usb/musb/davinci.h @@ -15,7 +15,7 @@ */ /* Integrated highspeed/otg PHY */ -#define USBPHY_CTL_PADDR 0x01c40034 +#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) #define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ #define USBPHY_PHYCLKGD BIT(8) #define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ @@ -27,7 +27,7 @@ #define USBPHY_OTGPDWN BIT(1) #define USBPHY_PHYPDWN BIT(0) -#define DM355_DEEPSLEEP_PADDR 0x01c40048 +#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) #define DRVVBUS_FORCE BIT(2) #define DRVVBUS_OVERRIDE BIT(1) diff --git a/trunk/drivers/usb/musb/musb_gadget.c b/trunk/drivers/usb/musb/musb_gadget.c index 95918dacc99a..f42c29b11f71 100644 --- a/trunk/drivers/usb/musb/musb_gadget.c +++ b/trunk/drivers/usb/musb/musb_gadget.c @@ -1232,7 +1232,6 @@ static int musb_gadget_disable(struct usb_ep *ep) } musb_ep->desc = NULL; - musb_ep->end_point.desc = NULL; /* abort all pending DMA and requests */ nuke(musb_ep, -ESHUTDOWN); diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index e090c799d87b..ef8d744800ac 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -375,21 +375,11 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, */ if (list_empty(&qh->hep->urb_list)) { struct list_head *head; - struct dma_controller *dma = musb->dma_controller; - if (is_in) { + if (is_in) ep->rx_reinit = 1; - if (ep->rx_channel) { - dma->channel_release(ep->rx_channel); - ep->rx_channel = NULL; - } - } else { + else ep->tx_reinit = 1; - if (ep->tx_channel) { - dma->channel_release(ep->tx_channel); - ep->tx_channel = NULL; - } - } /* Clobber old pointers to this qh */ musb_ep_set_qh(ep, is_in, NULL); diff --git a/trunk/drivers/usb/otg/twl6030-usb.c b/trunk/drivers/usb/otg/twl6030-usb.c index 0eabb049b6a9..d2a9a8e691b9 100644 --- a/trunk/drivers/usb/otg/twl6030-usb.c +++ b/trunk/drivers/usb/otg/twl6030-usb.c @@ -305,8 +305,9 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) regulator_enable(twl->usb3v3); twl->asleep = 1; - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); - twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); + twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, + 0x10); status = USB_EVENT_ID; otg->default_a = true; twl->phy.state = OTG_STATE_A_IDLE; @@ -315,10 +316,12 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) atomic_notifier_call_chain(&twl->phy.notifier, status, otg->gadget); } else { - twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); + twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, + 0x10); + twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, + 0x1); } - twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); return IRQ_HANDLED; } @@ -340,7 +343,7 @@ static int twl6030_enable_irq(struct usb_phy *x) { struct twl6030_usb *twl = phy_to_twl(x); - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); + twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x1); twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); diff --git a/trunk/drivers/usb/phy/Kconfig b/trunk/drivers/usb/phy/Kconfig index e7cf84f0751a..3cfabcba7447 100644 --- a/trunk/drivers/usb/phy/Kconfig +++ b/trunk/drivers/usb/phy/Kconfig @@ -2,11 +2,11 @@ # Physical Layer USB driver configuration # comment "USB Physical Layer drivers" - depends on USB || USB_GADGET + depends on USB config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" - depends on USB || USB_GADGET + depends on USB depends on I2C help Say Y here to add support for the NXP ISP1301 USB transceiver driver. diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index 1e71079ce33b..1b1926200ba7 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -82,7 +82,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ - { USB_DEVICE(0x10C4, 0x80C4) }, /* Cygnal Integrated Products, Inc., Optris infrared thermometer */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ @@ -93,7 +92,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ - { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ @@ -135,13 +133,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ - { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ - { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ - { USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */ - { USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */ - { USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */ - { USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ @@ -153,11 +145,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ - { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ - { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ - { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ - { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index bc912e5a3beb..8c084ea34e26 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -737,7 +737,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index 5661c7e2d415..f3c7c78ede33 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -784,7 +784,6 @@ #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ #define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ #define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ -#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ /* diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index 9b026bf7afef..105a6d898ca4 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -39,6 +39,13 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ +/* we want to look at all devices, as the vendor/product id can change + * depending on the command line argument */ +static const struct usb_device_id generic_serial_ids[] = { + {.driver_info = 42}, + {} +}; + /* All of the device info needed for the Generic Serial Converter */ struct usb_serial_driver usb_serial_generic_device = { .driver = { @@ -72,8 +79,7 @@ int usb_serial_generic_register(int _debug) USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; /* register our generic driver with ourselves */ - retval = usb_serial_register_drivers(serial_drivers, - "usbserial_generic", generic_device_ids); + retval = usb_serial_register_drivers(serial_drivers, "usbserial_generic", generic_serial_ids); #endif return retval; } diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index a71fa0aa0406..d0ec1aa52719 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/drivers/usb/serial/mct_u232.c @@ -309,16 +309,13 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, MCT_U232_SET_REQUEST_TYPE, 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, WDR_TIMEOUT); - kfree(buf); - - dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); - - if (rc < 0) { + if (rc < 0) dev_err(&serial->dev->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); - return rc; - } - return 0; + dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); + + kfree(buf); + return rc; } /* mct_u232_set_modem_ctrl */ static int mct_u232_get_modem_stat(struct usb_serial *serial, diff --git a/trunk/drivers/usb/serial/metro-usb.c b/trunk/drivers/usb/serial/metro-usb.c index d47eb06fe463..81423f7361db 100644 --- a/trunk/drivers/usb/serial/metro-usb.c +++ b/trunk/drivers/usb/serial/metro-usb.c @@ -222,6 +222,14 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) metro_priv->throttled = 0; spin_unlock_irqrestore(&metro_priv->lock, flags); + /* + * Force low_latency on so that our tty_push actually forces the data + * through, otherwise it is scheduled, and with high data rates (like + * with OHCI) data can get lost. + */ + if (tty) + tty->low_latency = 1; + /* Clear the urb pipe. */ usb_clear_halt(serial->dev, port->interrupt_in_urb->pipe); diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 57eca2448424..29160f8b5101 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -190,7 +190,7 @@ static int device_type; -static const struct usb_device_id id_table[] = { +static const struct usb_device_id id_table[] __devinitconst = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)}, diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 417ab1b0aa30..1aae9028cd0b 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -47,7 +47,6 @@ /* Function prototypes */ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id); -static void option_release(struct usb_serial *serial); static int option_send_setup(struct usb_serial_port *port); static void option_instat_callback(struct urb *urb); @@ -151,7 +150,6 @@ static void option_instat_callback(struct urb *urb); #define HUAWEI_PRODUCT_E14AC 0x14AC #define HUAWEI_PRODUCT_K3806 0x14AE #define HUAWEI_PRODUCT_K4605 0x14C6 -#define HUAWEI_PRODUCT_K5005 0x14C8 #define HUAWEI_PRODUCT_K3770 0x14C9 #define HUAWEI_PRODUCT_K3771 0x14CA #define HUAWEI_PRODUCT_K4510 0x14CB @@ -236,7 +234,6 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 -#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 @@ -428,7 +425,7 @@ static void option_instat_callback(struct urb *urb); #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_GT_B3730 0x6889 -/* YUGA products www.yuga-info.com gavin.kx@qq.com */ +/* YUGA products www.yuga-info.com*/ #define YUGA_VENDOR_ID 0x257A #define YUGA_PRODUCT_CEM600 0x1601 #define YUGA_PRODUCT_CEM610 0x1602 @@ -445,8 +442,6 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CEU516 0x160C #define YUGA_PRODUCT_CEU528 0x160D #define YUGA_PRODUCT_CEU526 0x160F -#define YUGA_PRODUCT_CEU881 0x161F -#define YUGA_PRODUCT_CEU882 0x162F #define YUGA_PRODUCT_CWM600 0x2601 #define YUGA_PRODUCT_CWM610 0x2602 @@ -462,26 +457,23 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CWU518 0x260B #define YUGA_PRODUCT_CWU516 0x260C #define YUGA_PRODUCT_CWU528 0x260D -#define YUGA_PRODUCT_CWU581 0x260E #define YUGA_PRODUCT_CWU526 0x260F -#define YUGA_PRODUCT_CWU582 0x261F -#define YUGA_PRODUCT_CWU583 0x262F - -#define YUGA_PRODUCT_CLM600 0x3601 -#define YUGA_PRODUCT_CLM610 0x3602 -#define YUGA_PRODUCT_CLM500 0x3603 -#define YUGA_PRODUCT_CLM510 0x3604 -#define YUGA_PRODUCT_CLM800 0x3605 -#define YUGA_PRODUCT_CLM900 0x3606 - -#define YUGA_PRODUCT_CLU718 0x3607 -#define YUGA_PRODUCT_CLU716 0x3608 -#define YUGA_PRODUCT_CLU728 0x3609 -#define YUGA_PRODUCT_CLU726 0x360A -#define YUGA_PRODUCT_CLU518 0x360B -#define YUGA_PRODUCT_CLU516 0x360C -#define YUGA_PRODUCT_CLU528 0x360D -#define YUGA_PRODUCT_CLU526 0x360F + +#define YUGA_PRODUCT_CLM600 0x2601 +#define YUGA_PRODUCT_CLM610 0x2602 +#define YUGA_PRODUCT_CLM500 0x2603 +#define YUGA_PRODUCT_CLM510 0x2604 +#define YUGA_PRODUCT_CLM800 0x2605 +#define YUGA_PRODUCT_CLM900 0x2606 + +#define YUGA_PRODUCT_CLU718 0x2607 +#define YUGA_PRODUCT_CLU716 0x2608 +#define YUGA_PRODUCT_CLU728 0x2609 +#define YUGA_PRODUCT_CLU726 0x260A +#define YUGA_PRODUCT_CLU518 0x260B +#define YUGA_PRODUCT_CLU516 0x260C +#define YUGA_PRODUCT_CLU528 0x260D +#define YUGA_PRODUCT_CLU526 0x260F /* Viettel products */ #define VIETTEL_VENDOR_ID 0x2262 @@ -497,19 +489,6 @@ static void option_instat_callback(struct urb *urb); /* MediaTek products */ #define MEDIATEK_VENDOR_ID 0x0e8d -#define MEDIATEK_PRODUCT_DC_1COM 0x00a0 -#define MEDIATEK_PRODUCT_DC_4COM 0x00a5 -#define MEDIATEK_PRODUCT_DC_5COM 0x00a4 -#define MEDIATEK_PRODUCT_7208_1COM 0x7101 -#define MEDIATEK_PRODUCT_7208_2COM 0x7102 -#define MEDIATEK_PRODUCT_FP_1COM 0x0003 -#define MEDIATEK_PRODUCT_FP_2COM 0x0023 -#define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 -#define MEDIATEK_PRODUCT_FPDC_2COM 0x0033 - -/* Cellient products */ -#define CELLIENT_VENDOR_ID 0x2692 -#define CELLIENT_PRODUCT_MEN200 0x9005 /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { @@ -563,10 +542,6 @@ static const struct option_blacklist_info net_intf1_blacklist = { .reserved = BIT(1), }; -static const struct option_blacklist_info net_intf2_blacklist = { - .reserved = BIT(2), -}; - static const struct option_blacklist_info net_intf3_blacklist = { .reserved = BIT(3), }; @@ -691,11 +666,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, @@ -752,8 +722,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, - /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ - { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, @@ -1112,8 +1080,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, @@ -1243,11 +1209,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) }, { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ @@ -1255,18 +1216,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_1COM, 0x02, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_2COM, 0x02, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -1296,7 +1245,7 @@ static struct usb_serial_driver option_1port_device = { .ioctl = usb_wwan_ioctl, .attach = usb_wwan_startup, .disconnect = usb_wwan_disconnect, - .release = option_release, + .release = usb_wwan_release, .read_int_callback = option_instat_callback, #ifdef CONFIG_PM .suspend = usb_wwan_suspend, @@ -1310,6 +1259,35 @@ static struct usb_serial_driver * const serial_drivers[] = { static bool debug; +/* per port private data */ + +#define N_IN_URB 4 +#define N_OUT_URB 4 +#define IN_BUFLEN 4096 +#define OUT_BUFLEN 4096 + +struct option_port_private { + /* Input endpoints and buffer for this port */ + struct urb *in_urbs[N_IN_URB]; + u8 *in_buffer[N_IN_URB]; + /* Output endpoints and buffer for this port */ + struct urb *out_urbs[N_OUT_URB]; + u8 *out_buffer[N_OUT_URB]; + unsigned long out_busy; /* Bit vector of URBs in use */ + int opened; + struct usb_anchor delayed; + + /* Settings for the port */ + int rts_state; /* Handshaking pins (outputs) */ + int dtr_state; + int cts_state; /* Handshaking pins (inputs) */ + int dsr_state; + int dcd_state; + int ri_state; + + unsigned long tx_start_time[N_OUT_URB]; +}; + module_usb_serial_driver(serial_drivers, option_ids); static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, @@ -1378,22 +1356,12 @@ static int option_probe(struct usb_serial *serial, return 0; } -static void option_release(struct usb_serial *serial) -{ - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); - - usb_wwan_release(serial); - - kfree(priv); -} - static void option_instat_callback(struct urb *urb) { int err; int status = urb->status; struct usb_serial_port *port = urb->context; - struct usb_wwan_port_private *portdata = - usb_get_serial_port_data(port); + struct option_port_private *portdata = usb_get_serial_port_data(port); dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); @@ -1453,7 +1421,7 @@ static int option_send_setup(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct usb_wwan_intf_private *intfdata = (struct usb_wwan_intf_private *) serial->private; - struct usb_wwan_port_private *portdata; + struct option_port_private *portdata; int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; int val = 0; diff --git a/trunk/drivers/usb/serial/qcserial.c b/trunk/drivers/usb/serial/qcserial.c index 996015c5f1ac..0d5fe59ebb9e 100644 --- a/trunk/drivers/usb/serial/qcserial.c +++ b/trunk/drivers/usb/serial/qcserial.c @@ -105,13 +105,7 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */ {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */ {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ - {USB_DEVICE(0x1199, 0x9010)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9012)}, /* Sierra Wireless Gobi 3000 QDL */ {USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ - {USB_DEVICE(0x1199, 0x9014)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ - {USB_DEVICE(0x1199, 0x9018)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */ {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */ { } /* Terminating entry */ diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index d423d36acc04..ba54a0a8235c 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -294,10 +294,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, - /* AT&T Direct IP LTE modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 27483f91a4a3..6a1b609a0d94 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -659,14 +659,12 @@ static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, static struct usb_serial_driver *search_serial_device( struct usb_interface *iface) { - const struct usb_device_id *id = NULL; + const struct usb_device_id *id; struct usb_serial_driver *drv; - struct usb_driver *driver = to_usb_driver(iface->dev.driver); /* Check if the usb id matches a known device */ list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { - if (drv->usb_driver == driver) - id = get_iface_id(drv, iface); + id = get_iface_id(drv, iface); if (id) return drv; } @@ -757,7 +755,7 @@ static int usb_serial_probe(struct usb_interface *interface, if (retval) { dbg("sub driver rejected device"); - usb_serial_put(serial); + kfree(serial); module_put(type->driver.owner); return retval; } @@ -829,7 +827,7 @@ static int usb_serial_probe(struct usb_interface *interface, */ if (num_bulk_in == 0 || num_bulk_out == 0) { dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); - usb_serial_put(serial); + kfree(serial); module_put(type->driver.owner); return -ENODEV; } @@ -843,7 +841,7 @@ static int usb_serial_probe(struct usb_interface *interface, if (num_ports == 0) { dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); - usb_serial_put(serial); + kfree(serial); module_put(type->driver.owner); return -EIO; } diff --git a/trunk/drivers/usb/storage/scsiglue.c b/trunk/drivers/usb/storage/scsiglue.c index 11418da9bc09..a324a5d21e99 100644 --- a/trunk/drivers/usb/storage/scsiglue.c +++ b/trunk/drivers/usb/storage/scsiglue.c @@ -202,12 +202,6 @@ static int slave_configure(struct scsi_device *sdev) if (us->fflags & US_FL_NO_READ_CAPACITY_16) sdev->no_read_capacity_16 = 1; - /* - * Many devices do not respond properly to READ_CAPACITY_16. - * Tell the SCSI layer to try READ_CAPACITY_10 first. - */ - sdev->try_rc_10_first = 1; - /* assume SPC3 or latter devices support sense size > 18 */ if (sdev->scsi_level > SCSI_SPC_2) us->fflags |= US_FL_SANE_SENSE; diff --git a/trunk/drivers/vhost/vhost.c b/trunk/drivers/vhost/vhost.c index 112156f68afb..94dbd25caa30 100644 --- a/trunk/drivers/vhost/vhost.c +++ b/trunk/drivers/vhost/vhost.c @@ -191,9 +191,7 @@ static int vhost_worker(void *data) struct vhost_dev *dev = data; struct vhost_work *work = NULL; unsigned uninitialized_var(seq); - mm_segment_t oldfs = get_fs(); - set_fs(USER_DS); use_mm(dev->mm); for (;;) { @@ -231,7 +229,6 @@ static int vhost_worker(void *data) } unuse_mm(dev->mm); - set_fs(oldfs); return 0; } diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index 2979292650d6..fa2b03750316 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -88,7 +88,7 @@ config LCD_PLATFORM config LCD_TOSA tristate "Sharp SL-6000 LCD Driver" - depends on I2C && SPI && MACH_TOSA + depends on SPI && MACH_TOSA help If you have an Sharp SL-6000 Zaurus say Y to enable a driver for its LCD. diff --git a/trunk/drivers/video/backlight/ili9320.c b/trunk/drivers/video/backlight/ili9320.c index 9327cd1b3143..6c9399341bcf 100644 --- a/trunk/drivers/video/backlight/ili9320.c +++ b/trunk/drivers/video/backlight/ili9320.c @@ -263,7 +263,7 @@ int __devinit ili9320_probe_spi(struct spi_device *spi, EXPORT_SYMBOL_GPL(ili9320_probe_spi); -int ili9320_remove(struct ili9320 *ili) +int __devexit ili9320_remove(struct ili9320 *ili) { ili9320_power(ili, FB_BLANK_POWERDOWN); diff --git a/trunk/drivers/video/bfin_adv7393fb.c b/trunk/drivers/video/bfin_adv7393fb.c index 9bdd4b0c18c8..33ea874c87d2 100644 --- a/trunk/drivers/video/bfin_adv7393fb.c +++ b/trunk/drivers/video/bfin_adv7393fb.c @@ -353,16 +353,18 @@ adv7393_read_proc(char *page, char **start, off_t off, static int adv7393_write_proc(struct file *file, const char __user * buffer, - size_t count, void *data) + unsigned long count, void *data) { struct adv7393fb_device *fbdev = data; + char line[8]; unsigned int val; int ret; - ret = kstrtouint_from_user(buffer, count, 0, &val); + ret = copy_from_user(line, buffer, count); if (ret) return -EFAULT; + val = simple_strtoul(line, NULL, 0); adv7393_write(fbdev->client, val >> 8, val & 0xff); return count; diff --git a/trunk/drivers/video/broadsheetfb.c b/trunk/drivers/video/broadsheetfb.c index c95b417d0d41..377dde3d5bfc 100644 --- a/trunk/drivers/video/broadsheetfb.c +++ b/trunk/drivers/video/broadsheetfb.c @@ -1211,7 +1211,7 @@ static int __devexit broadsheetfb_remove(struct platform_device *dev) static struct platform_driver broadsheetfb_driver = { .probe = broadsheetfb_probe, - .remove = __devexit_p(broadsheetfb_remove), + .remove = broadsheetfb_remove, .driver = { .owner = THIS_MODULE, .name = "broadsheetfb", diff --git a/trunk/drivers/video/console/Kconfig b/trunk/drivers/video/console/Kconfig index e2c96d01d8f5..c2d11fef114b 100644 --- a/trunk/drivers/video/console/Kconfig +++ b/trunk/drivers/video/console/Kconfig @@ -224,19 +224,5 @@ config FONT_10x18 big letters. It fits between the sun 12x22 and the normal 8x16 font. If other fonts are too big or too small for you, say Y, otherwise say N. -config FONT_AUTOSELECT - def_bool y - depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE || STI_CONSOLE || USB_SISUSBVGA_CON - depends on !FONT_8x8 - depends on !FONT_6x11 - depends on !FONT_7x14 - depends on !FONT_PEARL_8x8 - depends on !FONT_ACORN_8x8 - depends on !FONT_MINI_4x6 - depends on !FONT_SUN8x16 - depends on !FONT_SUN12x22 - depends on !FONT_10x18 - select FONT_8x16 - endmenu diff --git a/trunk/drivers/video/mbx/mbxfb.c b/trunk/drivers/video/mbx/mbxfb.c index 85e4f44bfa61..ab0a8e527333 100644 --- a/trunk/drivers/video/mbx/mbxfb.c +++ b/trunk/drivers/video/mbx/mbxfb.c @@ -1045,7 +1045,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev) static struct platform_driver mbxfb_driver = { .probe = mbxfb_probe, - .remove = __devexit_p(mbxfb_remove), + .remove = mbxfb_remove, .suspend = mbxfb_suspend, .resume = mbxfb_resume, .driver = { diff --git a/trunk/drivers/video/omap2/displays/panel-taal.c b/trunk/drivers/video/omap2/displays/panel-taal.c index 901576eb5a84..2ce9992f403b 100644 --- a/trunk/drivers/video/omap2/displays/panel-taal.c +++ b/trunk/drivers/video/omap2/displays/panel-taal.c @@ -526,7 +526,7 @@ static ssize_t taal_num_errors_show(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); struct taal_data *td = dev_get_drvdata(&dssdev->dev); - u8 errors = 0; + u8 errors; int r; mutex_lock(&td->lock); diff --git a/trunk/drivers/video/omap2/dss/core.c b/trunk/drivers/video/omap2/dss/core.c index 58bd9c27369d..72ded9cd2cb0 100644 --- a/trunk/drivers/video/omap2/dss/core.c +++ b/trunk/drivers/video/omap2/dss/core.c @@ -32,7 +32,6 @@ #include #include #include -#include #include