diff options
270 files changed, 6505 insertions, 3950 deletions
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX index d111e3b23db0..d18ecd827c40 100644 --- a/Documentation/block/00-INDEX +++ b/Documentation/block/00-INDEX | |||
| @@ -3,15 +3,21 @@ | |||
| 3 | biodoc.txt | 3 | biodoc.txt |
| 4 | - Notes on the Generic Block Layer Rewrite in Linux 2.5 | 4 | - Notes on the Generic Block Layer Rewrite in Linux 2.5 |
| 5 | capability.txt | 5 | capability.txt |
| 6 | - Generic Block Device Capability (/sys/block/<disk>/capability) | 6 | - Generic Block Device Capability (/sys/block/<device>/capability) |
| 7 | cfq-iosched.txt | ||
| 8 | - CFQ IO scheduler tunables | ||
| 9 | data-integrity.txt | ||
| 10 | - Block data integrity | ||
| 7 | deadline-iosched.txt | 11 | deadline-iosched.txt |
| 8 | - Deadline IO scheduler tunables | 12 | - Deadline IO scheduler tunables |
| 9 | ioprio.txt | 13 | ioprio.txt |
| 10 | - Block io priorities (in CFQ scheduler) | 14 | - Block io priorities (in CFQ scheduler) |
| 15 | queue-sysfs.txt | ||
| 16 | - Queue's sysfs entries | ||
| 11 | request.txt | 17 | request.txt |
| 12 | - The members of struct request (in include/linux/blkdev.h) | 18 | - The members of struct request (in include/linux/blkdev.h) |
| 13 | stat.txt | 19 | stat.txt |
| 14 | - Block layer statistics in /sys/block/<dev>/stat | 20 | - Block layer statistics in /sys/block/<device>/stat |
| 15 | switching-sched.txt | 21 | switching-sched.txt |
| 16 | - Switching I/O schedulers at runtime | 22 | - Switching I/O schedulers at runtime |
| 17 | writeback_cache_control.txt | 23 | writeback_cache_control.txt |
diff --git a/Documentation/block/cfq-iosched.txt b/Documentation/block/cfq-iosched.txt index 6d670f570451..d89b4fe724d7 100644 --- a/Documentation/block/cfq-iosched.txt +++ b/Documentation/block/cfq-iosched.txt | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | CFQ (Complete Fairness Queueing) | ||
| 2 | =============================== | ||
| 3 | |||
| 4 | The main aim of CFQ scheduler is to provide a fair allocation of the disk | ||
| 5 | I/O bandwidth for all the processes which requests an I/O operation. | ||
| 6 | |||
| 7 | CFQ maintains the per process queue for the processes which request I/O | ||
| 8 | operation(syncronous requests). In case of asynchronous requests, all the | ||
| 9 | requests from all the processes are batched together according to their | ||
| 10 | process's I/O priority. | ||
| 11 | |||
| 1 | CFQ ioscheduler tunables | 12 | CFQ ioscheduler tunables |
| 2 | ======================== | 13 | ======================== |
| 3 | 14 | ||
| @@ -25,6 +36,72 @@ there are multiple spindles behind single LUN (Host based hardware RAID | |||
| 25 | controller or for storage arrays), setting slice_idle=0 might end up in better | 36 | controller or for storage arrays), setting slice_idle=0 might end up in better |
| 26 | throughput and acceptable latencies. | 37 | throughput and acceptable latencies. |
| 27 | 38 | ||
| 39 | back_seek_max | ||
| 40 | ------------- | ||
| 41 | This specifies, given in Kbytes, the maximum "distance" for backward seeking. | ||
| 42 | The distance is the amount of space from the current head location to the | ||
| 43 | sectors that are backward in terms of distance. | ||
| 44 | |||
| 45 | This parameter allows the scheduler to anticipate requests in the "backward" | ||
| 46 | direction and consider them as being the "next" if they are within this | ||
| 47 | distance from the current head location. | ||
| 48 | |||
| 49 | back_seek_penalty | ||
| 50 | ----------------- | ||
| 51 | This parameter is used to compute the cost of backward seeking. If the | ||
| 52 | backward distance of request is just 1/back_seek_penalty from a "front" | ||
| 53 | request, then the seeking cost of two requests is considered equivalent. | ||
| 54 | |||
| 55 | So scheduler will not bias toward one or the other request (otherwise scheduler | ||
| 56 | will bias toward front request). Default value of back_seek_penalty is 2. | ||
| 57 | |||
| 58 | fifo_expire_async | ||
| 59 | ----------------- | ||
| 60 | This parameter is used to set the timeout of asynchronous requests. Default | ||
| 61 | value of this is 248ms. | ||
| 62 | |||
| 63 | fifo_expire_sync | ||
| 64 | ---------------- | ||
| 65 | This parameter is used to set the timeout of synchronous requests. Default | ||
| 66 | value of this is 124ms. In case to favor synchronous requests over asynchronous | ||
| 67 | one, this value should be decreased relative to fifo_expire_async. | ||
| 68 | |||
| 69 | slice_async | ||
| 70 | ----------- | ||
| 71 | This parameter is same as of slice_sync but for asynchronous queue. The | ||
| 72 | default value is 40ms. | ||
| 73 | |||
| 74 | slice_async_rq | ||
| 75 | -------------- | ||
| 76 | This parameter is used to limit the dispatching of asynchronous request to | ||
| 77 | device request queue in queue's slice time. The maximum number of request that | ||
| 78 | are allowed to be dispatched also depends upon the io priority. Default value | ||
| 79 | for this is 2. | ||
| 80 | |||
| 81 | slice_sync | ||
| 82 | ---------- | ||
| 83 | When a queue is selected for execution, the queues IO requests are only | ||
| 84 | executed for a certain amount of time(time_slice) before switching to another | ||
| 85 | queue. This parameter is used to calculate the time slice of synchronous | ||
| 86 | queue. | ||
| 87 | |||
| 88 | time_slice is computed using the below equation:- | ||
| 89 | time_slice = slice_sync + (slice_sync/5 * (4 - prio)). To increase the | ||
| 90 | time_slice of synchronous queue, increase the value of slice_sync. Default | ||
| 91 | value is 100ms. | ||
| 92 | |||
| 93 | quantum | ||
| 94 | ------- | ||
| 95 | This specifies the number of request dispatched to the device queue. In a | ||
| 96 | queue's time slice, a request will not be dispatched if the number of request | ||
| 97 | in the device exceeds this parameter. This parameter is used for synchronous | ||
| 98 | request. | ||
| 99 | |||
| 100 | In case of storage with several disk, this setting can limit the parallel | ||
| 101 | processing of request. Therefore, increasing the value can imporve the | ||
| 102 | performace although this can cause the latency of some I/O to increase due | ||
| 103 | to more number of requests. | ||
| 104 | |||
| 28 | CFQ IOPS Mode for group scheduling | 105 | CFQ IOPS Mode for group scheduling |
| 29 | =================================== | 106 | =================================== |
| 30 | Basic CFQ design is to provide priority based time slices. Higher priority | 107 | Basic CFQ design is to provide priority based time slices. Higher priority |
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index 6518a55273e7..e54ac1d53403 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt | |||
| @@ -9,20 +9,71 @@ These files are the ones found in the /sys/block/xxx/queue/ directory. | |||
| 9 | Files denoted with a RO postfix are readonly and the RW postfix means | 9 | Files denoted with a RO postfix are readonly and the RW postfix means |
| 10 | read-write. | 10 | read-write. |
| 11 | 11 | ||
| 12 | add_random (RW) | ||
| 13 | ---------------- | ||
| 14 | This file allows to trun off the disk entropy contribution. Default | ||
| 15 | value of this file is '1'(on). | ||
| 16 | |||
| 17 | discard_granularity (RO) | ||
| 18 | ----------------------- | ||
| 19 | This shows the size of internal allocation of the device in bytes, if | ||
| 20 | reported by the device. A value of '0' means device does not support | ||
| 21 | the discard functionality. | ||
| 22 | |||
| 23 | discard_max_bytes (RO) | ||
| 24 | ---------------------- | ||
| 25 | Devices that support discard functionality may have internal limits on | ||
| 26 | the number of bytes that can be trimmed or unmapped in a single operation. | ||
| 27 | The discard_max_bytes parameter is set by the device driver to the maximum | ||
| 28 | number of bytes that can be discarded in a single operation. Discard | ||
| 29 | requests issued to the device must not exceed this limit. A discard_max_bytes | ||
| 30 | value of 0 means that the device does not support discard functionality. | ||
| 31 | |||
| 32 | discard_zeroes_data (RO) | ||
| 33 | ------------------------ | ||
| 34 | When read, this file will show if the discarded block are zeroed by the | ||
| 35 | device or not. If its value is '1' the blocks are zeroed otherwise not. | ||
| 36 | |||
| 12 | hw_sector_size (RO) | 37 | hw_sector_size (RO) |
| 13 | ------------------- | 38 | ------------------- |
| 14 | This is the hardware sector size of the device, in bytes. | 39 | This is the hardware sector size of the device, in bytes. |
| 15 | 40 | ||
| 41 | iostats (RW) | ||
| 42 | ------------- | ||
| 43 | This file is used to control (on/off) the iostats accounting of the | ||
| 44 | disk. | ||
| 45 | |||
| 46 | logical_block_size (RO) | ||
| 47 | ----------------------- | ||
| 48 | This is the logcal block size of the device, in bytes. | ||
| 49 | |||
| 16 | max_hw_sectors_kb (RO) | 50 | max_hw_sectors_kb (RO) |
| 17 | ---------------------- | 51 | ---------------------- |
| 18 | This is the maximum number of kilobytes supported in a single data transfer. | 52 | This is the maximum number of kilobytes supported in a single data transfer. |
| 19 | 53 | ||
| 54 | max_integrity_segments (RO) | ||
| 55 | --------------------------- | ||
| 56 | When read, this file shows the max limit of integrity segments as | ||
| 57 | set by block layer which a hardware controller can handle. | ||
| 58 | |||
| 20 | max_sectors_kb (RW) | 59 | max_sectors_kb (RW) |
| 21 | ------------------- | 60 | ------------------- |
| 22 | This is the maximum number of kilobytes that the block layer will allow | 61 | This is the maximum number of kilobytes that the block layer will allow |
| 23 | for a filesystem request. Must be smaller than or equal to the maximum | 62 | for a filesystem request. Must be smaller than or equal to the maximum |
| 24 | size allowed by the hardware. | 63 | size allowed by the hardware. |
| 25 | 64 | ||
| 65 | max_segments (RO) | ||
| 66 | ----------------- | ||
| 67 | Maximum number of segments of the device. | ||
| 68 | |||
| 69 | max_segment_size (RO) | ||
| 70 | --------------------- | ||
| 71 | Maximum segment size of the device. | ||
| 72 | |||
| 73 | minimum_io_size (RO) | ||
| 74 | -------------------- | ||
| 75 | This is the smallest preferred io size reported by the device. | ||
| 76 | |||
| 26 | nomerges (RW) | 77 | nomerges (RW) |
| 27 | ------------- | 78 | ------------- |
| 28 | This enables the user to disable the lookup logic involved with IO | 79 | This enables the user to disable the lookup logic involved with IO |
| @@ -45,11 +96,24 @@ per-block-cgroup request pool. IOW, if there are N block cgroups, | |||
| 45 | each request queue may have upto N request pools, each independently | 96 | each request queue may have upto N request pools, each independently |
| 46 | regulated by nr_requests. | 97 | regulated by nr_requests. |
| 47 | 98 | ||
| 99 | optimal_io_size (RO) | ||
| 100 | -------------------- | ||
| 101 | This is the optimal io size reported by the device. | ||
| 102 | |||
| 103 | physical_block_size (RO) | ||
| 104 | ------------------------ | ||
| 105 | This is the physical block size of device, in bytes. | ||
| 106 | |||
| 48 | read_ahead_kb (RW) | 107 | read_ahead_kb (RW) |
| 49 | ------------------ | 108 | ------------------ |
| 50 | Maximum number of kilobytes to read-ahead for filesystems on this block | 109 | Maximum number of kilobytes to read-ahead for filesystems on this block |
| 51 | device. | 110 | device. |
| 52 | 111 | ||
| 112 | rotational (RW) | ||
| 113 | --------------- | ||
| 114 | This file is used to stat if the device is of rotational type or | ||
| 115 | non-rotational type. | ||
| 116 | |||
| 53 | rq_affinity (RW) | 117 | rq_affinity (RW) |
| 54 | ---------------- | 118 | ---------------- |
| 55 | If this option is '1', the block layer will migrate request completions to the | 119 | If this option is '1', the block layer will migrate request completions to the |
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 70cd49b1caa8..1dd622546d06 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | |||
| @@ -10,8 +10,8 @@ Required properties: | |||
| 10 | - compatible : Should be "fsl,<chip>-esdhc" | 10 | - compatible : Should be "fsl,<chip>-esdhc" |
| 11 | 11 | ||
| 12 | Optional properties: | 12 | Optional properties: |
| 13 | - fsl,cd-internal : Indicate to use controller internal card detection | 13 | - fsl,cd-controller : Indicate to use controller internal card detection |
| 14 | - fsl,wp-internal : Indicate to use controller internal write protection | 14 | - fsl,wp-controller : Indicate to use controller internal write protection |
| 15 | 15 | ||
| 16 | Examples: | 16 | Examples: |
| 17 | 17 | ||
| @@ -19,8 +19,8 @@ esdhc@70004000 { | |||
| 19 | compatible = "fsl,imx51-esdhc"; | 19 | compatible = "fsl,imx51-esdhc"; |
| 20 | reg = <0x70004000 0x4000>; | 20 | reg = <0x70004000 0x4000>; |
| 21 | interrupts = <1>; | 21 | interrupts = <1>; |
| 22 | fsl,cd-internal; | 22 | fsl,cd-controller; |
| 23 | fsl,wp-internal; | 23 | fsl,wp-controller; |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | esdhc@70008000 { | 26 | esdhc@70008000 { |
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c index 73ff5cc93e05..3da822967ee0 100644 --- a/Documentation/watchdog/src/watchdog-test.c +++ b/Documentation/watchdog/src/watchdog-test.c | |||
| @@ -31,7 +31,7 @@ static void keep_alive(void) | |||
| 31 | * or "-e" to enable the card. | 31 | * or "-e" to enable the card. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | void term(int sig) | 34 | static void term(int sig) |
| 35 | { | 35 | { |
| 36 | close(fd); | 36 | close(fd); |
| 37 | fprintf(stderr, "Stopping watchdog ticks...\n"); | 37 | fprintf(stderr, "Stopping watchdog ticks...\n"); |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 3 | 1 | VERSION = 3 |
| 2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
| 3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
| 4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc4 |
| 5 | NAME = Saber-toothed Squirrel | 5 | NAME = Saber-toothed Squirrel |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6d6e18fee9fe..c5f9ae5dbd1a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -2144,6 +2144,7 @@ source "drivers/cpufreq/Kconfig" | |||
| 2144 | config CPU_FREQ_IMX | 2144 | config CPU_FREQ_IMX |
| 2145 | tristate "CPUfreq driver for i.MX CPUs" | 2145 | tristate "CPUfreq driver for i.MX CPUs" |
| 2146 | depends on ARCH_MXC && CPU_FREQ | 2146 | depends on ARCH_MXC && CPU_FREQ |
| 2147 | select CPU_FREQ_TABLE | ||
| 2147 | help | 2148 | help |
| 2148 | This enables the CPUfreq driver for i.MX CPUs. | 2149 | This enables the CPUfreq driver for i.MX CPUs. |
| 2149 | 2150 | ||
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 59509c48d7e5..bd0cff3f808c 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi | |||
| @@ -154,5 +154,10 @@ | |||
| 154 | #size-cells = <0>; | 154 | #size-cells = <0>; |
| 155 | ti,hwmods = "i2c3"; | 155 | ti,hwmods = "i2c3"; |
| 156 | }; | 156 | }; |
| 157 | |||
| 158 | wdt2: wdt@44e35000 { | ||
| 159 | compatible = "ti,omap3-wdt"; | ||
| 160 | ti,hwmods = "wd_timer2"; | ||
| 161 | }; | ||
| 157 | }; | 162 | }; |
| 158 | }; | 163 | }; |
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index cd86177a3ea2..59d9789e5508 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | aips@70000000 { /* aips-1 */ | 25 | aips@70000000 { /* aips-1 */ |
| 26 | spba@70000000 { | 26 | spba@70000000 { |
| 27 | esdhc@70004000 { /* ESDHC1 */ | 27 | esdhc@70004000 { /* ESDHC1 */ |
| 28 | fsl,cd-internal; | 28 | fsl,cd-controller; |
| 29 | fsl,wp-internal; | 29 | fsl,wp-controller; |
| 30 | status = "okay"; | 30 | status = "okay"; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 52d947045106..f8ca6fa88192 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts | |||
| @@ -41,9 +41,13 @@ | |||
| 41 | }; | 41 | }; |
| 42 | power-blue { | 42 | power-blue { |
| 43 | label = "power:blue"; | 43 | label = "power:blue"; |
| 44 | gpios = <&gpio1 11 0>; | 44 | gpios = <&gpio1 10 0>; |
| 45 | linux,default-trigger = "timer"; | 45 | linux,default-trigger = "timer"; |
| 46 | }; | 46 | }; |
| 47 | power-red { | ||
| 48 | label = "power:red"; | ||
| 49 | gpios = <&gpio1 11 0>; | ||
| 50 | }; | ||
| 47 | usb1 { | 51 | usb1 { |
| 48 | label = "usb1:blue"; | 52 | label = "usb1:blue"; |
| 49 | gpios = <&gpio1 12 0>; | 53 | gpios = <&gpio1 12 0>; |
diff --git a/arch/arm/boot/dts/twl6030.dtsi b/arch/arm/boot/dts/twl6030.dtsi index 3b2f3510d7eb..d351b27d7213 100644 --- a/arch/arm/boot/dts/twl6030.dtsi +++ b/arch/arm/boot/dts/twl6030.dtsi | |||
| @@ -66,6 +66,7 @@ | |||
| 66 | 66 | ||
| 67 | vcxio: regulator@8 { | 67 | vcxio: regulator@8 { |
| 68 | compatible = "ti,twl6030-vcxio"; | 68 | compatible = "ti,twl6030-vcxio"; |
| 69 | regulator-always-on; | ||
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 71 | vusb: regulator@9 { | 72 | vusb: regulator@9 { |
| @@ -74,10 +75,12 @@ | |||
| 74 | 75 | ||
| 75 | v1v8: regulator@10 { | 76 | v1v8: regulator@10 { |
| 76 | compatible = "ti,twl6030-v1v8"; | 77 | compatible = "ti,twl6030-v1v8"; |
| 78 | regulator-always-on; | ||
| 77 | }; | 79 | }; |
| 78 | 80 | ||
| 79 | v2v1: regulator@11 { | 81 | v2v1: regulator@11 { |
| 80 | compatible = "ti,twl6030-v2v1"; | 82 | compatible = "ti,twl6030-v2v1"; |
| 83 | regulator-always-on; | ||
| 81 | }; | 84 | }; |
| 82 | 85 | ||
| 83 | clk32kg: regulator@12 { | 86 | clk32kg: regulator@12 { |
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 2d4f661d1cf6..da6845493caa 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig | |||
| @@ -86,6 +86,7 @@ CONFIG_NEW_LEDS=y | |||
| 86 | CONFIG_LEDS_CLASS=y | 86 | CONFIG_LEDS_CLASS=y |
| 87 | CONFIG_LEDS_LM3530=y | 87 | CONFIG_LEDS_LM3530=y |
| 88 | CONFIG_LEDS_LP5521=y | 88 | CONFIG_LEDS_LP5521=y |
| 89 | CONFIG_LEDS_GPIO=y | ||
| 89 | CONFIG_RTC_CLASS=y | 90 | CONFIG_RTC_CLASS=y |
| 90 | CONFIG_RTC_DRV_AB8500=y | 91 | CONFIG_RTC_DRV_AB8500=y |
| 91 | CONFIG_RTC_DRV_PL031=y | 92 | CONFIG_RTC_DRV_PL031=y |
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 4db5de54b6a7..6321567d8eaa 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c | |||
| @@ -102,7 +102,8 @@ void __init dove_ehci1_init(void) | |||
| 102 | void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) | 102 | void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) |
| 103 | { | 103 | { |
| 104 | orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE, | 104 | orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE, |
| 105 | IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR); | 105 | IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR, |
| 106 | 1600); | ||
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | /***************************************************************************** | 109 | /***************************************************************************** |
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 4e245f1b29a2..5ec563be6c65 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <plat/backlight.h> | 42 | #include <plat/backlight.h> |
| 43 | #include <plat/fb.h> | 43 | #include <plat/fb.h> |
| 44 | #include <plat/mfc.h> | 44 | #include <plat/mfc.h> |
| 45 | #include <plat/hdmi.h> | ||
| 45 | 46 | ||
| 46 | #include <mach/ohci.h> | 47 | #include <mach/ohci.h> |
| 47 | #include <mach/map.h> | 48 | #include <mach/map.h> |
| @@ -734,6 +735,11 @@ static void __init origen_bt_setup(void) | |||
| 734 | s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE); | 735 | s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE); |
| 735 | } | 736 | } |
| 736 | 737 | ||
| 738 | /* I2C module and id for HDMIPHY */ | ||
| 739 | static struct i2c_board_info hdmiphy_info = { | ||
| 740 | I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38), | ||
| 741 | }; | ||
| 742 | |||
| 737 | static void s5p_tv_setup(void) | 743 | static void s5p_tv_setup(void) |
| 738 | { | 744 | { |
| 739 | /* Direct HPD to HDMI chip */ | 745 | /* Direct HPD to HDMI chip */ |
| @@ -781,6 +787,7 @@ static void __init origen_machine_init(void) | |||
| 781 | 787 | ||
| 782 | s5p_tv_setup(); | 788 | s5p_tv_setup(); |
| 783 | s5p_i2c_hdmiphy_set_platdata(NULL); | 789 | s5p_i2c_hdmiphy_set_platdata(NULL); |
| 790 | s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0); | ||
| 784 | 791 | ||
| 785 | #ifdef CONFIG_DRM_EXYNOS | 792 | #ifdef CONFIG_DRM_EXYNOS |
| 786 | s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata; | 793 | s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata; |
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index b1c50dabd862..208aa6236af3 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <plat/mfc.h> | 40 | #include <plat/mfc.h> |
| 41 | #include <plat/ehci.h> | 41 | #include <plat/ehci.h> |
| 42 | #include <plat/clock.h> | 42 | #include <plat/clock.h> |
| 43 | #include <plat/hdmi.h> | ||
| 43 | 44 | ||
| 44 | #include <mach/map.h> | 45 | #include <mach/map.h> |
| 45 | #include <mach/ohci.h> | 46 | #include <mach/ohci.h> |
| @@ -354,6 +355,11 @@ static struct platform_pwm_backlight_data smdkv310_bl_data = { | |||
| 354 | .pwm_period_ns = 1000, | 355 | .pwm_period_ns = 1000, |
| 355 | }; | 356 | }; |
| 356 | 357 | ||
| 358 | /* I2C module and id for HDMIPHY */ | ||
| 359 | static struct i2c_board_info hdmiphy_info = { | ||
| 360 | I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38), | ||
| 361 | }; | ||
| 362 | |||
| 357 | static void s5p_tv_setup(void) | 363 | static void s5p_tv_setup(void) |
| 358 | { | 364 | { |
| 359 | /* direct HPD to HDMI chip */ | 365 | /* direct HPD to HDMI chip */ |
| @@ -388,6 +394,7 @@ static void __init smdkv310_machine_init(void) | |||
| 388 | 394 | ||
| 389 | s5p_tv_setup(); | 395 | s5p_tv_setup(); |
| 390 | s5p_i2c_hdmiphy_set_platdata(NULL); | 396 | s5p_i2c_hdmiphy_set_platdata(NULL); |
| 397 | s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0); | ||
| 391 | 398 | ||
| 392 | samsung_keypad_set_platdata(&smdkv310_keypad_data); | 399 | samsung_keypad_set_platdata(&smdkv310_keypad_data); |
| 393 | 400 | ||
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 07f7c226e4cf..d004d37ad9d8 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
| @@ -9,7 +9,8 @@ obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o | |||
| 9 | obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o | 9 | obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o |
| 10 | obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o | 10 | obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o |
| 11 | 11 | ||
| 12 | obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o | 12 | imx5-pm-$(CONFIG_PM) += pm-imx5.o |
| 13 | obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o | ||
| 13 | 14 | ||
| 14 | obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ | 15 | obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ |
| 15 | clk-pfd.o clk-busy.o | 16 | clk-pfd.o clk-busy.o |
| @@ -70,14 +71,13 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o | |||
| 70 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o | 71 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o |
| 71 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o | 72 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o |
| 72 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o | 73 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o |
| 73 | obj-$(CONFIG_CPU_V7) += head-v7.o | 74 | AFLAGS_headsmp.o :=-Wa,-march=armv7-a |
| 74 | AFLAGS_head-v7.o :=-Wa,-march=armv7-a | 75 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o |
| 75 | obj-$(CONFIG_SMP) += platsmp.o | ||
| 76 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 76 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
| 77 | obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o | 77 | obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o |
| 78 | 78 | ||
| 79 | ifeq ($(CONFIG_PM),y) | 79 | ifeq ($(CONFIG_PM),y) |
| 80 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o | 80 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o |
| 81 | endif | 81 | endif |
| 82 | 82 | ||
| 83 | # i.MX5 based machines | 83 | # i.MX5 based machines |
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index ea89520b6e22..4233d9e3531d 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
| @@ -152,7 +152,7 @@ enum mx6q_clks { | |||
| 152 | ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3, | 152 | ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3, |
| 153 | usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, | 153 | usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, |
| 154 | pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, | 154 | pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, |
| 155 | ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, | 155 | ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, |
| 156 | clk_max | 156 | clk_max |
| 157 | }; | 157 | }; |
| 158 | 158 | ||
| @@ -288,8 +288,10 @@ int __init mx6q_clocks_init(void) | |||
| 288 | clk[gpu3d_shader] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); | 288 | clk[gpu3d_shader] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); |
| 289 | clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); | 289 | clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); |
| 290 | clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); | 290 | clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); |
| 291 | clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_sel", base + 0x20, 10, 1); | 291 | clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
| 292 | clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_sel", base + 0x20, 11, 1); | 292 | clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1); |
| 293 | clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); | ||
| 294 | clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1); | ||
| 293 | clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); | 295 | clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); |
| 294 | clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); | 296 | clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); |
| 295 | clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); | 297 | clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); |
diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/headsmp.S index 7e49deb128a4..7e49deb128a4 100644 --- a/arch/arm/mach-imx/head-v7.S +++ b/arch/arm/mach-imx/headsmp.S | |||
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 20ed2d56c1af..f8f7437c83b8 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c | |||
| @@ -42,22 +42,6 @@ static inline void cpu_enter_lowpower(void) | |||
| 42 | : "cc"); | 42 | : "cc"); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static inline void cpu_leave_lowpower(void) | ||
| 46 | { | ||
| 47 | unsigned int v; | ||
| 48 | |||
| 49 | asm volatile( | ||
| 50 | "mrc p15, 0, %0, c1, c0, 0\n" | ||
| 51 | " orr %0, %0, %1\n" | ||
| 52 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 53 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 54 | " orr %0, %0, %2\n" | ||
| 55 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 56 | : "=&r" (v) | ||
| 57 | : "Ir" (CR_C), "Ir" (0x40) | ||
| 58 | : "cc"); | ||
| 59 | } | ||
| 60 | |||
| 61 | /* | 45 | /* |
| 62 | * platform-specific code to shutdown a CPU | 46 | * platform-specific code to shutdown a CPU |
| 63 | * | 47 | * |
| @@ -67,11 +51,10 @@ void platform_cpu_die(unsigned int cpu) | |||
| 67 | { | 51 | { |
| 68 | cpu_enter_lowpower(); | 52 | cpu_enter_lowpower(); |
| 69 | imx_enable_cpu(cpu, false); | 53 | imx_enable_cpu(cpu, false); |
| 70 | cpu_do_idle(); | ||
| 71 | cpu_leave_lowpower(); | ||
| 72 | 54 | ||
| 73 | /* We should never return from idle */ | 55 | /* spin here until hardware takes it down */ |
| 74 | panic("cpu %d unexpectedly exit from shutdown\n", cpu); | 56 | while (1) |
| 57 | ; | ||
| 75 | } | 58 | } |
| 76 | 59 | ||
| 77 | int platform_cpu_disable(unsigned int cpu) | 60 | int platform_cpu_disable(unsigned int cpu) |
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 5ec0608f2a76..045b3f6a387d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
| @@ -71,7 +71,7 @@ soft: | |||
| 71 | /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ | 71 | /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ |
| 72 | static int ksz9021rn_phy_fixup(struct phy_device *phydev) | 72 | static int ksz9021rn_phy_fixup(struct phy_device *phydev) |
| 73 | { | 73 | { |
| 74 | if (IS_ENABLED(CONFIG_PHYLIB)) { | 74 | if (IS_BUILTIN(CONFIG_PHYLIB)) { |
| 75 | /* min rx data delay */ | 75 | /* min rx data delay */ |
| 76 | phy_write(phydev, 0x0b, 0x8105); | 76 | phy_write(phydev, 0x0b, 0x8105); |
| 77 | phy_write(phydev, 0x0c, 0x0000); | 77 | phy_write(phydev, 0x0c, 0x0000); |
| @@ -112,7 +112,7 @@ put_clk: | |||
| 112 | 112 | ||
| 113 | static void __init imx6q_sabrelite_init(void) | 113 | static void __init imx6q_sabrelite_init(void) |
| 114 | { | 114 | { |
| 115 | if (IS_ENABLED(CONFIG_PHYLIB)) | 115 | if (IS_BUILTIN(CONFIG_PHYLIB)) |
| 116 | phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, | 116 | phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, |
| 117 | ksz9021rn_phy_fixup); | 117 | ksz9021rn_phy_fixup); |
| 118 | imx6q_sabrelite_cko1_setup(); | 118 | imx6q_sabrelite_cko1_setup(); |
diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot index a5717558ee89..a13299d758e1 100644 --- a/arch/arm/mach-kirkwood/Makefile.boot +++ b/arch/arm/mach-kirkwood/Makefile.boot | |||
| @@ -7,7 +7,8 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb | |||
| 7 | dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb | 7 | dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb |
| 8 | dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb | 8 | dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb |
| 9 | dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb | 9 | dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb |
| 10 | dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-qnap-ts219.dtb | 10 | dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-ts219-6281.dtb |
| 11 | dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-ts219-6282.dtb | ||
| 11 | dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb | 12 | dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb |
| 12 | dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb | 13 | dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb |
| 13 | dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb | 14 | dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb |
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c4b64adcbfce..3226077735b1 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
| @@ -301,7 +301,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) | |||
| 301 | { | 301 | { |
| 302 | orion_ge00_init(eth_data, | 302 | orion_ge00_init(eth_data, |
| 303 | GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, | 303 | GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, |
| 304 | IRQ_KIRKWOOD_GE00_ERR); | 304 | IRQ_KIRKWOOD_GE00_ERR, 1600); |
| 305 | /* The interface forgets the MAC address assigned by u-boot if | 305 | /* The interface forgets the MAC address assigned by u-boot if |
| 306 | the clock is turned off, so claim the clk now. */ | 306 | the clock is turned off, so claim the clk now. */ |
| 307 | clk_prepare_enable(ge0); | 307 | clk_prepare_enable(ge0); |
| @@ -315,7 +315,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) | |||
| 315 | { | 315 | { |
| 316 | orion_ge01_init(eth_data, | 316 | orion_ge01_init(eth_data, |
| 317 | GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, | 317 | GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, |
| 318 | IRQ_KIRKWOOD_GE01_ERR); | 318 | IRQ_KIRKWOOD_GE01_ERR, 1600); |
| 319 | clk_prepare_enable(ge1); | 319 | clk_prepare_enable(ge1); |
| 320 | } | 320 | } |
| 321 | 321 | ||
diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c index 4304f9519372..7e8a5a2e1ec7 100644 --- a/arch/arm/mach-mmp/sram.c +++ b/arch/arm/mach-mmp/sram.c | |||
| @@ -68,7 +68,7 @@ static int __devinit sram_probe(struct platform_device *pdev) | |||
| 68 | struct resource *res; | 68 | struct resource *res; |
| 69 | int ret = 0; | 69 | int ret = 0; |
| 70 | 70 | ||
| 71 | if (!pdata && !pdata->pool_name) | 71 | if (!pdata || !pdata->pool_name) |
| 72 | return -ENODEV; | 72 | return -ENODEV; |
| 73 | 73 | ||
| 74 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 74 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c index 62b53d710efd..a9bc84180d21 100644 --- a/arch/arm/mach-mv78xx0/addr-map.c +++ b/arch/arm/mach-mv78xx0/addr-map.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) | 37 | #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) |
| 38 | #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) | 38 | #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) |
| 39 | 39 | ||
| 40 | static void __init __iomem *win_cfg_base(int win) | 40 | static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win) |
| 41 | { | 41 | { |
| 42 | /* | 42 | /* |
| 43 | * Find the control register base address for this window. | 43 | * Find the control register base address for this window. |
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index b4c53b846c9c..3057f7d4329a 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c | |||
| @@ -213,7 +213,8 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) | |||
| 213 | { | 213 | { |
| 214 | orion_ge00_init(eth_data, | 214 | orion_ge00_init(eth_data, |
| 215 | GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, | 215 | GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, |
| 216 | IRQ_MV78XX0_GE_ERR); | 216 | IRQ_MV78XX0_GE_ERR, |
| 217 | MV643XX_TX_CSUM_DEFAULT_LIMIT); | ||
| 217 | } | 218 | } |
| 218 | 219 | ||
| 219 | 220 | ||
| @@ -224,7 +225,8 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data) | |||
| 224 | { | 225 | { |
| 225 | orion_ge01_init(eth_data, | 226 | orion_ge01_init(eth_data, |
| 226 | GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, | 227 | GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, |
| 227 | NO_IRQ); | 228 | NO_IRQ, |
| 229 | MV643XX_TX_CSUM_DEFAULT_LIMIT); | ||
| 228 | } | 230 | } |
| 229 | 231 | ||
| 230 | 232 | ||
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index dd2db025f778..fcd4e85c4ddc 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
| @@ -62,13 +62,14 @@ config ARCH_OMAP4 | |||
| 62 | select PM_OPP if PM | 62 | select PM_OPP if PM |
| 63 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | 63 | select USB_ARCH_HAS_EHCI if USB_SUPPORT |
| 64 | select ARM_CPU_SUSPEND if PM | 64 | select ARM_CPU_SUSPEND if PM |
| 65 | select ARCH_NEEDS_CPU_IDLE_COUPLED | 65 | select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP |
| 66 | 66 | ||
| 67 | config SOC_OMAP5 | 67 | config SOC_OMAP5 |
| 68 | bool "TI OMAP5" | 68 | bool "TI OMAP5" |
| 69 | select CPU_V7 | 69 | select CPU_V7 |
| 70 | select ARM_GIC | 70 | select ARM_GIC |
| 71 | select HAVE_SMP | 71 | select HAVE_SMP |
| 72 | select ARM_CPU_SUSPEND if PM | ||
| 72 | 73 | ||
| 73 | comment "OMAP Core Type" | 74 | comment "OMAP Core Type" |
| 74 | depends on ARCH_OMAP2 | 75 | depends on ARCH_OMAP2 |
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index ad8a7d94afcd..c165e20506c9 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
| @@ -601,29 +601,6 @@ static void __init omap_sfh7741prox_init(void) | |||
| 601 | __func__, OMAP4_SFH7741_ENABLE_GPIO, error); | 601 | __func__, OMAP4_SFH7741_ENABLE_GPIO, error); |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | static struct gpio sdp4430_hdmi_gpios[] = { | ||
| 605 | { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, | ||
| 606 | { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, | ||
| 607 | { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, | ||
| 608 | }; | ||
| 609 | |||
| 610 | static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) | ||
| 611 | { | ||
| 612 | int status; | ||
| 613 | |||
| 614 | status = gpio_request_array(sdp4430_hdmi_gpios, | ||
| 615 | ARRAY_SIZE(sdp4430_hdmi_gpios)); | ||
| 616 | if (status) | ||
| 617 | pr_err("%s: Cannot request HDMI GPIOs\n", __func__); | ||
| 618 | |||
| 619 | return status; | ||
| 620 | } | ||
| 621 | |||
| 622 | static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) | ||
| 623 | { | ||
| 624 | gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios)); | ||
| 625 | } | ||
| 626 | |||
| 627 | static struct nokia_dsi_panel_data dsi1_panel = { | 604 | static struct nokia_dsi_panel_data dsi1_panel = { |
| 628 | .name = "taal", | 605 | .name = "taal", |
| 629 | .reset_gpio = 102, | 606 | .reset_gpio = 102, |
| @@ -644,29 +621,6 @@ static struct omap_dss_device sdp4430_lcd_device = { | |||
| 644 | .phy.dsi = { | 621 | .phy.dsi = { |
| 645 | .module = 0, | 622 | .module = 0, |
| 646 | }, | 623 | }, |
| 647 | |||
| 648 | .clocks = { | ||
| 649 | .dispc = { | ||
| 650 | .channel = { | ||
| 651 | /* Logic Clock = 172.8 MHz */ | ||
| 652 | .lck_div = 1, | ||
| 653 | /* Pixel Clock = 34.56 MHz */ | ||
| 654 | .pck_div = 5, | ||
| 655 | .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, | ||
| 656 | }, | ||
| 657 | .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK, | ||
| 658 | }, | ||
| 659 | |||
| 660 | .dsi = { | ||
| 661 | .regn = 16, /* Fint = 2.4 MHz */ | ||
| 662 | .regm = 180, /* DDR Clock = 216 MHz */ | ||
| 663 | .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */ | ||
| 664 | .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */ | ||
| 665 | |||
| 666 | .lp_clk_div = 10, /* LP Clock = 8.64 MHz */ | ||
| 667 | .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, | ||
| 668 | }, | ||
| 669 | }, | ||
| 670 | .channel = OMAP_DSS_CHANNEL_LCD, | 624 | .channel = OMAP_DSS_CHANNEL_LCD, |
| 671 | }; | 625 | }; |
| 672 | 626 | ||
| @@ -691,33 +645,12 @@ static struct omap_dss_device sdp4430_lcd2_device = { | |||
| 691 | 645 | ||
| 692 | .module = 1, | 646 | .module = 1, |
| 693 | }, | 647 | }, |
| 694 | |||
| 695 | .clocks = { | ||
| 696 | .dispc = { | ||
| 697 | .channel = { | ||
| 698 | /* Logic Clock = 172.8 MHz */ | ||
| 699 | .lck_div = 1, | ||
| 700 | /* Pixel Clock = 34.56 MHz */ | ||
| 701 | .pck_div = 5, | ||
| 702 | .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC, | ||
| 703 | }, | ||
| 704 | .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK, | ||
| 705 | }, | ||
| 706 | |||
| 707 | .dsi = { | ||
| 708 | .regn = 16, /* Fint = 2.4 MHz */ | ||
| 709 | .regm = 180, /* DDR Clock = 216 MHz */ | ||
| 710 | .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */ | ||
| 711 | .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */ | ||
| 712 | |||
| 713 | .lp_clk_div = 10, /* LP Clock = 8.64 MHz */ | ||
| 714 | .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, | ||
| 715 | }, | ||
| 716 | }, | ||
| 717 | .channel = OMAP_DSS_CHANNEL_LCD2, | 648 | .channel = OMAP_DSS_CHANNEL_LCD2, |
| 718 | }; | 649 | }; |
| 719 | 650 | ||
| 720 | static struct omap_dss_hdmi_data sdp4430_hdmi_data = { | 651 | static struct omap_dss_hdmi_data sdp4430_hdmi_data = { |
| 652 | .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, | ||
| 653 | .ls_oe_gpio = HDMI_GPIO_LS_OE, | ||
| 721 | .hpd_gpio = HDMI_GPIO_HPD, | 654 | .hpd_gpio = HDMI_GPIO_HPD, |
| 722 | }; | 655 | }; |
| 723 | 656 | ||
| @@ -725,8 +658,6 @@ static struct omap_dss_device sdp4430_hdmi_device = { | |||
| 725 | .name = "hdmi", | 658 | .name = "hdmi", |
| 726 | .driver_name = "hdmi_panel", | 659 | .driver_name = "hdmi_panel", |
| 727 | .type = OMAP_DISPLAY_TYPE_HDMI, | 660 | .type = OMAP_DISPLAY_TYPE_HDMI, |
| 728 | .platform_enable = sdp4430_panel_enable_hdmi, | ||
| 729 | .platform_disable = sdp4430_panel_disable_hdmi, | ||
| 730 | .channel = OMAP_DSS_CHANNEL_DIGIT, | 661 | .channel = OMAP_DSS_CHANNEL_DIGIT, |
| 731 | .data = &sdp4430_hdmi_data, | 662 | .data = &sdp4430_hdmi_data, |
| 732 | }; | 663 | }; |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 74915295482e..28214483aaba 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
| @@ -554,6 +554,8 @@ static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = { | |||
| 554 | 554 | ||
| 555 | #ifdef CONFIG_OMAP_MUX | 555 | #ifdef CONFIG_OMAP_MUX |
| 556 | static struct omap_board_mux board_mux[] __initdata = { | 556 | static struct omap_board_mux board_mux[] __initdata = { |
| 557 | /* SMSC9221 LAN Controller ETH IRQ (GPIO_176) */ | ||
| 558 | OMAP3_MUX(MCSPI1_CS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), | ||
| 557 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 559 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
| 558 | }; | 560 | }; |
| 559 | #endif | 561 | #endif |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index ef230a0eb5eb..0d362e9f9cb9 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #include "hsmmc.h" | 58 | #include "hsmmc.h" |
| 59 | #include "common-board-devices.h" | 59 | #include "common-board-devices.h" |
| 60 | 60 | ||
| 61 | #define OMAP3_EVM_TS_GPIO 175 | ||
| 61 | #define OMAP3_EVM_EHCI_VBUS 22 | 62 | #define OMAP3_EVM_EHCI_VBUS 22 |
| 62 | #define OMAP3_EVM_EHCI_SELECT 61 | 63 | #define OMAP3_EVM_EHCI_SELECT 61 |
| 63 | 64 | ||
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 70f6d1d25463..cd4852e5ca57 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
| @@ -408,30 +408,9 @@ static struct omap_dss_device omap4_panda_dvi_device = { | |||
| 408 | .channel = OMAP_DSS_CHANNEL_LCD2, | 408 | .channel = OMAP_DSS_CHANNEL_LCD2, |
| 409 | }; | 409 | }; |
| 410 | 410 | ||
| 411 | static struct gpio panda_hdmi_gpios[] = { | ||
| 412 | { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, | ||
| 413 | { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, | ||
| 414 | { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, | ||
| 415 | }; | ||
| 416 | |||
| 417 | static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) | ||
| 418 | { | ||
| 419 | int status; | ||
| 420 | |||
| 421 | status = gpio_request_array(panda_hdmi_gpios, | ||
| 422 | ARRAY_SIZE(panda_hdmi_gpios)); | ||
| 423 | if (status) | ||
| 424 | pr_err("Cannot request HDMI GPIOs\n"); | ||
| 425 | |||
| 426 | return status; | ||
| 427 | } | ||
| 428 | |||
| 429 | static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev) | ||
| 430 | { | ||
| 431 | gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios)); | ||
| 432 | } | ||
| 433 | |||
| 434 | static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { | 411 | static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { |
| 412 | .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, | ||
| 413 | .ls_oe_gpio = HDMI_GPIO_LS_OE, | ||
| 435 | .hpd_gpio = HDMI_GPIO_HPD, | 414 | .hpd_gpio = HDMI_GPIO_HPD, |
| 436 | }; | 415 | }; |
| 437 | 416 | ||
| @@ -439,8 +418,6 @@ static struct omap_dss_device omap4_panda_hdmi_device = { | |||
| 439 | .name = "hdmi", | 418 | .name = "hdmi", |
| 440 | .driver_name = "hdmi_panel", | 419 | .driver_name = "hdmi_panel", |
| 441 | .type = OMAP_DISPLAY_TYPE_HDMI, | 420 | .type = OMAP_DISPLAY_TYPE_HDMI, |
| 442 | .platform_enable = omap4_panda_panel_enable_hdmi, | ||
| 443 | .platform_disable = omap4_panda_panel_disable_hdmi, | ||
| 444 | .channel = OMAP_DSS_CHANNEL_DIGIT, | 421 | .channel = OMAP_DSS_CHANNEL_DIGIT, |
| 445 | .data = &omap4_panda_hdmi_data, | 422 | .data = &omap4_panda_hdmi_data, |
| 446 | }; | 423 | }; |
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 14734746457c..c1875862679f 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c | |||
| @@ -35,16 +35,6 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = { | |||
| 35 | .turbo_mode = 0, | 35 | .turbo_mode = 0, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | /* | ||
| 39 | * ADS7846 driver maybe request a gpio according to the value | ||
| 40 | * of pdata->get_pendown_state, but we have done this. So set | ||
| 41 | * get_pendown_state to avoid twice gpio requesting. | ||
| 42 | */ | ||
| 43 | static int omap3_get_pendown_state(void) | ||
| 44 | { | ||
| 45 | return !gpio_get_value(OMAP3_EVM_TS_GPIO); | ||
| 46 | } | ||
| 47 | |||
| 48 | static struct ads7846_platform_data ads7846_config = { | 38 | static struct ads7846_platform_data ads7846_config = { |
| 49 | .x_max = 0x0fff, | 39 | .x_max = 0x0fff, |
| 50 | .y_max = 0x0fff, | 40 | .y_max = 0x0fff, |
| @@ -55,7 +45,6 @@ static struct ads7846_platform_data ads7846_config = { | |||
| 55 | .debounce_rep = 1, | 45 | .debounce_rep = 1, |
| 56 | .gpio_pendown = -EINVAL, | 46 | .gpio_pendown = -EINVAL, |
| 57 | .keep_vref_on = 1, | 47 | .keep_vref_on = 1, |
| 58 | .get_pendown_state = &omap3_get_pendown_state, | ||
| 59 | }; | 48 | }; |
| 60 | 49 | ||
| 61 | static struct spi_board_info ads7846_spi_board_info __initdata = { | 50 | static struct spi_board_info ads7846_spi_board_info __initdata = { |
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h index 4c4ef6a6166b..a0b4a42836ab 100644 --- a/arch/arm/mach-omap2/common-board-devices.h +++ b/arch/arm/mach-omap2/common-board-devices.h | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | #include "twl-common.h" | 4 | #include "twl-common.h" |
| 5 | 5 | ||
| 6 | #define NAND_BLOCK_SIZE SZ_128K | 6 | #define NAND_BLOCK_SIZE SZ_128K |
| 7 | #define OMAP3_EVM_TS_GPIO 175 | ||
| 8 | 7 | ||
| 9 | struct mtd_partition; | 8 | struct mtd_partition; |
| 10 | struct ads7846_platform_data; | 9 | struct ads7846_platform_data; |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index ee05e193fc61..288bee6cbb76 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
| @@ -238,8 +238,9 @@ int __init omap4_idle_init(void) | |||
| 238 | for_each_cpu(cpu_id, cpu_online_mask) { | 238 | for_each_cpu(cpu_id, cpu_online_mask) { |
| 239 | dev = &per_cpu(omap4_idle_dev, cpu_id); | 239 | dev = &per_cpu(omap4_idle_dev, cpu_id); |
| 240 | dev->cpu = cpu_id; | 240 | dev->cpu = cpu_id; |
| 241 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED | ||
| 241 | dev->coupled_cpus = *cpu_online_mask; | 242 | dev->coupled_cpus = *cpu_online_mask; |
| 242 | 243 | #endif | |
| 243 | cpuidle_register_driver(&omap4_idle_driver); | 244 | cpuidle_register_driver(&omap4_idle_driver); |
| 244 | 245 | ||
| 245 | if (cpuidle_register_device(dev)) { | 246 | if (cpuidle_register_device(dev)) { |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index af1ed7d24a1f..ee40739b55c0 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
| @@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = { | |||
| 95 | { "dss_core", "omapdss_dss", -1 }, | 95 | { "dss_core", "omapdss_dss", -1 }, |
| 96 | { "dss_dispc", "omapdss_dispc", -1 }, | 96 | { "dss_dispc", "omapdss_dispc", -1 }, |
| 97 | { "dss_rfbi", "omapdss_rfbi", -1 }, | 97 | { "dss_rfbi", "omapdss_rfbi", -1 }, |
| 98 | { "dss_venc", "omapdss_venc", -1 }, | ||
| 99 | { "dss_dsi1", "omapdss_dsi", 0 }, | 98 | { "dss_dsi1", "omapdss_dsi", 0 }, |
| 100 | { "dss_dsi2", "omapdss_dsi", 1 }, | 99 | { "dss_dsi2", "omapdss_dsi", 1 }, |
| 101 | { "dss_hdmi", "omapdss_hdmi", -1 }, | 100 | { "dss_hdmi", "omapdss_hdmi", -1 }, |
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 471e62a74a16..76f9b3c2f586 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h | |||
| @@ -127,7 +127,6 @@ struct omap_mux_partition { | |||
| 127 | * @gpio: GPIO number | 127 | * @gpio: GPIO number |
| 128 | * @muxnames: available signal modes for a ball | 128 | * @muxnames: available signal modes for a ball |
| 129 | * @balls: available balls on the package | 129 | * @balls: available balls on the package |
| 130 | * @partition: mux partition | ||
| 131 | */ | 130 | */ |
| 132 | struct omap_mux { | 131 | struct omap_mux { |
| 133 | u16 reg_offset; | 132 | u16 reg_offset; |
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index 2293ba27101b..c95415da23c2 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c | |||
| @@ -94,7 +94,7 @@ int __init omap4_opp_init(void) | |||
| 94 | { | 94 | { |
| 95 | int r = -ENODEV; | 95 | int r = -ENODEV; |
| 96 | 96 | ||
| 97 | if (!cpu_is_omap44xx()) | 97 | if (!cpu_is_omap443x()) |
| 98 | return r; | 98 | return r; |
| 99 | 99 | ||
| 100 | r = omap_init_opp_table(omap44xx_opp_def_list, | 100 | r = omap_init_opp_table(omap44xx_opp_def_list, |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e4fc88c65dbd..05bd8f02723f 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
| @@ -272,21 +272,16 @@ void omap_sram_idle(void) | |||
| 272 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); | 272 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); |
| 273 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); | 273 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); |
| 274 | 274 | ||
| 275 | if (mpu_next_state < PWRDM_POWER_ON) { | 275 | pwrdm_pre_transition(NULL); |
| 276 | pwrdm_pre_transition(mpu_pwrdm); | ||
| 277 | pwrdm_pre_transition(neon_pwrdm); | ||
| 278 | } | ||
| 279 | 276 | ||
| 280 | /* PER */ | 277 | /* PER */ |
| 281 | if (per_next_state < PWRDM_POWER_ON) { | 278 | if (per_next_state < PWRDM_POWER_ON) { |
| 282 | pwrdm_pre_transition(per_pwrdm); | ||
| 283 | per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; | 279 | per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; |
| 284 | omap2_gpio_prepare_for_idle(per_going_off); | 280 | omap2_gpio_prepare_for_idle(per_going_off); |
| 285 | } | 281 | } |
| 286 | 282 | ||
| 287 | /* CORE */ | 283 | /* CORE */ |
| 288 | if (core_next_state < PWRDM_POWER_ON) { | 284 | if (core_next_state < PWRDM_POWER_ON) { |
| 289 | pwrdm_pre_transition(core_pwrdm); | ||
| 290 | if (core_next_state == PWRDM_POWER_OFF) { | 285 | if (core_next_state == PWRDM_POWER_OFF) { |
| 291 | omap3_core_save_context(); | 286 | omap3_core_save_context(); |
| 292 | omap3_cm_save_context(); | 287 | omap3_cm_save_context(); |
| @@ -339,20 +334,14 @@ void omap_sram_idle(void) | |||
| 339 | omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, | 334 | omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, |
| 340 | OMAP3430_GR_MOD, | 335 | OMAP3430_GR_MOD, |
| 341 | OMAP3_PRM_VOLTCTRL_OFFSET); | 336 | OMAP3_PRM_VOLTCTRL_OFFSET); |
| 342 | pwrdm_post_transition(core_pwrdm); | ||
| 343 | } | 337 | } |
| 344 | omap3_intc_resume_idle(); | 338 | omap3_intc_resume_idle(); |
| 345 | 339 | ||
| 340 | pwrdm_post_transition(NULL); | ||
| 341 | |||
| 346 | /* PER */ | 342 | /* PER */ |
| 347 | if (per_next_state < PWRDM_POWER_ON) { | 343 | if (per_next_state < PWRDM_POWER_ON) |
| 348 | omap2_gpio_resume_after_idle(); | 344 | omap2_gpio_resume_after_idle(); |
| 349 | pwrdm_post_transition(per_pwrdm); | ||
| 350 | } | ||
| 351 | |||
| 352 | if (mpu_next_state < PWRDM_POWER_ON) { | ||
| 353 | pwrdm_post_transition(mpu_pwrdm); | ||
| 354 | pwrdm_post_transition(neon_pwrdm); | ||
| 355 | } | ||
| 356 | } | 345 | } |
| 357 | 346 | ||
| 358 | static void omap3_pm_idle(void) | 347 | static void omap3_pm_idle(void) |
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 9f6b83d1b193..91e71d8f46f0 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S | |||
| @@ -56,9 +56,13 @@ ppa_por_params: | |||
| 56 | * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. | 56 | * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. |
| 57 | * It returns to the caller for CPU INACTIVE and ON power states or in case | 57 | * It returns to the caller for CPU INACTIVE and ON power states or in case |
| 58 | * CPU failed to transition to targeted OFF/DORMANT state. | 58 | * CPU failed to transition to targeted OFF/DORMANT state. |
| 59 | * | ||
| 60 | * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save | ||
| 61 | * stack frame and it expects the caller to take care of it. Hence the entire | ||
| 62 | * stack frame is saved to avoid possible stack corruption. | ||
| 59 | */ | 63 | */ |
| 60 | ENTRY(omap4_finish_suspend) | 64 | ENTRY(omap4_finish_suspend) |
| 61 | stmfd sp!, {lr} | 65 | stmfd sp!, {r4-r12, lr} |
| 62 | cmp r0, #0x0 | 66 | cmp r0, #0x0 |
| 63 | beq do_WFI @ No lowpower state, jump to WFI | 67 | beq do_WFI @ No lowpower state, jump to WFI |
| 64 | 68 | ||
| @@ -226,7 +230,7 @@ scu_gp_clear: | |||
| 226 | skip_scu_gp_clear: | 230 | skip_scu_gp_clear: |
| 227 | isb | 231 | isb |
| 228 | dsb | 232 | dsb |
| 229 | ldmfd sp!, {pc} | 233 | ldmfd sp!, {r4-r12, pc} |
| 230 | ENDPROC(omap4_finish_suspend) | 234 | ENDPROC(omap4_finish_suspend) |
| 231 | 235 | ||
| 232 | /* | 236 | /* |
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index de47f170ba50..9bf8a89e78c6 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c | |||
| @@ -67,6 +67,7 @@ void __init omap_pmic_init(int bus, u32 clkrate, | |||
| 67 | const char *pmic_type, int pmic_irq, | 67 | const char *pmic_type, int pmic_irq, |
| 68 | struct twl4030_platform_data *pmic_data) | 68 | struct twl4030_platform_data *pmic_data) |
| 69 | { | 69 | { |
| 70 | omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); | ||
| 70 | strncpy(pmic_i2c_board_info.type, pmic_type, | 71 | strncpy(pmic_i2c_board_info.type, pmic_type, |
| 71 | sizeof(pmic_i2c_board_info.type)); | 72 | sizeof(pmic_i2c_board_info.type)); |
| 72 | pmic_i2c_board_info.irq = pmic_irq; | 73 | pmic_i2c_board_info.irq = pmic_irq; |
| @@ -257,6 +258,10 @@ static struct twl4030_usb_data omap4_usb_pdata = { | |||
| 257 | .phy_suspend = omap4430_phy_suspend, | 258 | .phy_suspend = omap4430_phy_suspend, |
| 258 | }; | 259 | }; |
| 259 | 260 | ||
| 261 | static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = { | ||
| 262 | REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"), | ||
| 263 | }; | ||
| 264 | |||
| 260 | static struct regulator_init_data omap4_vdac_idata = { | 265 | static struct regulator_init_data omap4_vdac_idata = { |
| 261 | .constraints = { | 266 | .constraints = { |
| 262 | .min_uV = 1800000, | 267 | .min_uV = 1800000, |
| @@ -266,6 +271,8 @@ static struct regulator_init_data omap4_vdac_idata = { | |||
| 266 | .valid_ops_mask = REGULATOR_CHANGE_MODE | 271 | .valid_ops_mask = REGULATOR_CHANGE_MODE |
| 267 | | REGULATOR_CHANGE_STATUS, | 272 | | REGULATOR_CHANGE_STATUS, |
| 268 | }, | 273 | }, |
| 274 | .num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies), | ||
| 275 | .consumer_supplies = omap4_vdda_hdmi_dac_supplies, | ||
| 269 | .supply_regulator = "V2V1", | 276 | .supply_regulator = "V2V1", |
| 270 | }; | 277 | }; |
| 271 | 278 | ||
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 9148b229d0de..410291c67666 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c | |||
| @@ -109,7 +109,8 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) | |||
| 109 | { | 109 | { |
| 110 | orion_ge00_init(eth_data, | 110 | orion_ge00_init(eth_data, |
| 111 | ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, | 111 | ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, |
| 112 | IRQ_ORION5X_ETH_ERR); | 112 | IRQ_ORION5X_ETH_ERR, |
| 113 | MV643XX_TX_CSUM_DEFAULT_LIMIT); | ||
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | 116 | ||
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h index 454831b66037..ee99fd56c043 100644 --- a/arch/arm/mach-s3c24xx/include/mach/dma.h +++ b/arch/arm/mach-s3c24xx/include/mach/dma.h | |||
| @@ -24,7 +24,8 @@ | |||
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | enum dma_ch { | 26 | enum dma_ch { |
| 27 | DMACH_XD0, | 27 | DMACH_DT_PROP = -1, /* not yet supported, do not use */ |
| 28 | DMACH_XD0 = 0, | ||
| 28 | DMACH_XD1, | 29 | DMACH_XD1, |
| 29 | DMACH_SDI, | 30 | DMACH_SDI, |
| 30 | DMACH_SPI0, | 31 | DMACH_SPI0, |
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index c013bbf79cac..53d3d46dec12 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig | |||
| @@ -41,7 +41,6 @@ config MACH_HREFV60 | |||
| 41 | config MACH_SNOWBALL | 41 | config MACH_SNOWBALL |
| 42 | bool "U8500 Snowball platform" | 42 | bool "U8500 Snowball platform" |
| 43 | select MACH_MOP500 | 43 | select MACH_MOP500 |
| 44 | select LEDS_GPIO | ||
| 45 | help | 44 | help |
| 46 | Include support for the snowball development platform. | 45 | Include support for the snowball development platform. |
| 47 | 46 | ||
diff --git a/arch/arm/mach-ux500/board-mop500-msp.c b/arch/arm/mach-ux500/board-mop500-msp.c index 996048038743..df15646036aa 100644 --- a/arch/arm/mach-ux500/board-mop500-msp.c +++ b/arch/arm/mach-ux500/board-mop500-msp.c | |||
| @@ -191,9 +191,9 @@ static struct platform_device *db8500_add_msp_i2s(struct device *parent, | |||
| 191 | return pdev; | 191 | return pdev; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | /* Platform device for ASoC U8500 machine */ | 194 | /* Platform device for ASoC MOP500 machine */ |
| 195 | static struct platform_device snd_soc_u8500 = { | 195 | static struct platform_device snd_soc_mop500 = { |
| 196 | .name = "snd-soc-u8500", | 196 | .name = "snd-soc-mop500", |
| 197 | .id = 0, | 197 | .id = 0, |
| 198 | .dev = { | 198 | .dev = { |
| 199 | .platform_data = NULL, | 199 | .platform_data = NULL, |
| @@ -227,8 +227,8 @@ int mop500_msp_init(struct device *parent) | |||
| 227 | { | 227 | { |
| 228 | struct platform_device *msp1; | 228 | struct platform_device *msp1; |
| 229 | 229 | ||
| 230 | pr_info("%s: Register platform-device 'snd-soc-u8500'.\n", __func__); | 230 | pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__); |
| 231 | platform_device_register(&snd_soc_u8500); | 231 | platform_device_register(&snd_soc_mop500); |
| 232 | 232 | ||
| 233 | pr_info("Initialize MSP I2S-devices.\n"); | 233 | pr_info("Initialize MSP I2S-devices.\n"); |
| 234 | db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, | 234 | db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 8674a890fd1c..a534d8880de1 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
| @@ -797,6 +797,7 @@ static void __init u8500_init_machine(void) | |||
| 797 | ARRAY_SIZE(mop500_platform_devs)); | 797 | ARRAY_SIZE(mop500_platform_devs)); |
| 798 | 798 | ||
| 799 | mop500_sdi_init(parent); | 799 | mop500_sdi_init(parent); |
| 800 | mop500_msp_init(parent); | ||
| 800 | i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); | 801 | i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); |
| 801 | i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); | 802 | i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); |
| 802 | i2c_register_board_info(2, mop500_i2c2_devices, | 803 | i2c_register_board_info(2, mop500_i2c2_devices, |
| @@ -804,6 +805,8 @@ static void __init u8500_init_machine(void) | |||
| 804 | 805 | ||
| 805 | mop500_uib_init(); | 806 | mop500_uib_init(); |
| 806 | 807 | ||
| 808 | } else if (of_machine_is_compatible("calaosystems,snowball-a9500")) { | ||
| 809 | mop500_msp_init(parent); | ||
| 807 | } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) { | 810 | } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) { |
| 808 | /* | 811 | /* |
| 809 | * The HREFv60 board removed a GPIO expander and routed | 812 | * The HREFv60 board removed a GPIO expander and routed |
| @@ -815,6 +818,7 @@ static void __init u8500_init_machine(void) | |||
| 815 | ARRAY_SIZE(mop500_platform_devs)); | 818 | ARRAY_SIZE(mop500_platform_devs)); |
| 816 | 819 | ||
| 817 | hrefv60_sdi_init(parent); | 820 | hrefv60_sdi_init(parent); |
| 821 | mop500_msp_init(parent); | ||
| 818 | 822 | ||
| 819 | i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); | 823 | i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); |
| 820 | i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; | 824 | i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; |
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 626ad8cad7a9..938b50a33439 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
| @@ -189,6 +189,7 @@ struct omap_dm_timer *omap_dm_timer_request(void) | |||
| 189 | timer->reserved = 1; | 189 | timer->reserved = 1; |
| 190 | break; | 190 | break; |
| 191 | } | 191 | } |
| 192 | spin_unlock_irqrestore(&dm_timer_lock, flags); | ||
| 192 | 193 | ||
| 193 | if (timer) { | 194 | if (timer) { |
| 194 | ret = omap_dm_timer_prepare(timer); | 195 | ret = omap_dm_timer_prepare(timer); |
| @@ -197,7 +198,6 @@ struct omap_dm_timer *omap_dm_timer_request(void) | |||
| 197 | timer = NULL; | 198 | timer = NULL; |
| 198 | } | 199 | } |
| 199 | } | 200 | } |
| 200 | spin_unlock_irqrestore(&dm_timer_lock, flags); | ||
| 201 | 201 | ||
| 202 | if (!timer) | 202 | if (!timer) |
| 203 | pr_debug("%s: timer request failed!\n", __func__); | 203 | pr_debug("%s: timer request failed!\n", __func__); |
| @@ -220,6 +220,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id) | |||
| 220 | break; | 220 | break; |
| 221 | } | 221 | } |
| 222 | } | 222 | } |
| 223 | spin_unlock_irqrestore(&dm_timer_lock, flags); | ||
| 223 | 224 | ||
| 224 | if (timer) { | 225 | if (timer) { |
| 225 | ret = omap_dm_timer_prepare(timer); | 226 | ret = omap_dm_timer_prepare(timer); |
| @@ -228,7 +229,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id) | |||
| 228 | timer = NULL; | 229 | timer = NULL; |
| 229 | } | 230 | } |
| 230 | } | 231 | } |
| 231 | spin_unlock_irqrestore(&dm_timer_lock, flags); | ||
| 232 | 232 | ||
| 233 | if (!timer) | 233 | if (!timer) |
| 234 | pr_debug("%s: timer%d request failed!\n", __func__, id); | 234 | pr_debug("%s: timer%d request failed!\n", __func__, id); |
| @@ -258,7 +258,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_enable); | |||
| 258 | 258 | ||
| 259 | void omap_dm_timer_disable(struct omap_dm_timer *timer) | 259 | void omap_dm_timer_disable(struct omap_dm_timer *timer) |
| 260 | { | 260 | { |
| 261 | pm_runtime_put(&timer->pdev->dev); | 261 | pm_runtime_put_sync(&timer->pdev->dev); |
| 262 | } | 262 | } |
| 263 | EXPORT_SYMBOL_GPL(omap_dm_timer_disable); | 263 | EXPORT_SYMBOL_GPL(omap_dm_timer_disable); |
| 264 | 264 | ||
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 68b180edcfff..bb5d08a70dbc 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h | |||
| @@ -372,7 +372,8 @@ IS_OMAP_TYPE(3430, 0x3430) | |||
| 372 | #define cpu_class_is_omap1() (cpu_is_omap7xx() || cpu_is_omap15xx() || \ | 372 | #define cpu_class_is_omap1() (cpu_is_omap7xx() || cpu_is_omap15xx() || \ |
| 373 | cpu_is_omap16xx()) | 373 | cpu_is_omap16xx()) |
| 374 | #define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx() || \ | 374 | #define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx() || \ |
| 375 | cpu_is_omap44xx() || soc_is_omap54xx()) | 375 | cpu_is_omap44xx() || soc_is_omap54xx() || \ |
| 376 | soc_is_am33xx()) | ||
| 376 | 377 | ||
| 377 | /* Various silicon revisions for omap2 */ | 378 | /* Various silicon revisions for omap2 */ |
| 378 | #define OMAP242X_CLASS 0x24200024 | 379 | #define OMAP242X_CLASS 0x24200024 |
diff --git a/arch/arm/plat-omap/include/plat/multi.h b/arch/arm/plat-omap/include/plat/multi.h index 045e320f1067..324d31b14852 100644 --- a/arch/arm/plat-omap/include/plat/multi.h +++ b/arch/arm/plat-omap/include/plat/multi.h | |||
| @@ -108,4 +108,13 @@ | |||
| 108 | # endif | 108 | # endif |
| 109 | #endif | 109 | #endif |
| 110 | 110 | ||
| 111 | #ifdef CONFIG_SOC_AM33XX | ||
| 112 | # ifdef OMAP_NAME | ||
| 113 | # undef MULTI_OMAP2 | ||
| 114 | # define MULTI_OMAP2 | ||
| 115 | # else | ||
| 116 | # define OMAP_NAME am33xx | ||
| 117 | # endif | ||
| 118 | #endif | ||
| 119 | |||
| 111 | #endif /* __PLAT_OMAP_MULTI_H */ | 120 | #endif /* __PLAT_OMAP_MULTI_H */ |
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index b8d19a136781..7f7b112acccb 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h | |||
| @@ -110,7 +110,7 @@ static inline void flush(void) | |||
| 110 | _DEBUG_LL_ENTRY(mach, AM33XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ | 110 | _DEBUG_LL_ENTRY(mach, AM33XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ |
| 111 | AM33XXUART##p) | 111 | AM33XXUART##p) |
| 112 | 112 | ||
| 113 | static inline void __arch_decomp_setup(unsigned long arch_id) | 113 | static inline void arch_decomp_setup(void) |
| 114 | { | 114 | { |
| 115 | int port = 0; | 115 | int port = 0; |
| 116 | 116 | ||
| @@ -198,8 +198,6 @@ static inline void __arch_decomp_setup(unsigned long arch_id) | |||
| 198 | } while (0); | 198 | } while (0); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | #define arch_decomp_setup() __arch_decomp_setup(arch_id) | ||
| 202 | |||
| 203 | /* | 201 | /* |
| 204 | * nothing to do | 202 | * nothing to do |
| 205 | */ | 203 | */ |
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index d245a87dc014..b8b747a9d360 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c | |||
| @@ -291,10 +291,12 @@ static struct platform_device orion_ge00 = { | |||
| 291 | void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, | 291 | void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, |
| 292 | unsigned long mapbase, | 292 | unsigned long mapbase, |
| 293 | unsigned long irq, | 293 | unsigned long irq, |
| 294 | unsigned long irq_err) | 294 | unsigned long irq_err, |
| 295 | unsigned int tx_csum_limit) | ||
| 295 | { | 296 | { |
| 296 | fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, | 297 | fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, |
| 297 | mapbase + 0x2000, SZ_16K - 1, irq_err); | 298 | mapbase + 0x2000, SZ_16K - 1, irq_err); |
| 299 | orion_ge00_shared_data.tx_csum_limit = tx_csum_limit; | ||
| 298 | ge_complete(&orion_ge00_shared_data, | 300 | ge_complete(&orion_ge00_shared_data, |
| 299 | orion_ge00_resources, irq, &orion_ge00_shared, | 301 | orion_ge00_resources, irq, &orion_ge00_shared, |
| 300 | eth_data, &orion_ge00); | 302 | eth_data, &orion_ge00); |
| @@ -343,10 +345,12 @@ static struct platform_device orion_ge01 = { | |||
| 343 | void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, | 345 | void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, |
| 344 | unsigned long mapbase, | 346 | unsigned long mapbase, |
| 345 | unsigned long irq, | 347 | unsigned long irq, |
| 346 | unsigned long irq_err) | 348 | unsigned long irq_err, |
| 349 | unsigned int tx_csum_limit) | ||
| 347 | { | 350 | { |
| 348 | fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, | 351 | fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, |
| 349 | mapbase + 0x2000, SZ_16K - 1, irq_err); | 352 | mapbase + 0x2000, SZ_16K - 1, irq_err); |
| 353 | orion_ge01_shared_data.tx_csum_limit = tx_csum_limit; | ||
| 350 | ge_complete(&orion_ge01_shared_data, | 354 | ge_complete(&orion_ge01_shared_data, |
| 351 | orion_ge01_resources, irq, &orion_ge01_shared, | 355 | orion_ge01_resources, irq, &orion_ge01_shared, |
| 352 | eth_data, &orion_ge01); | 356 | eth_data, &orion_ge01); |
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index e00fdb213609..ae2377ef63e5 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h | |||
| @@ -39,12 +39,14 @@ void __init orion_rtc_init(unsigned long mapbase, | |||
| 39 | void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, | 39 | void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, |
| 40 | unsigned long mapbase, | 40 | unsigned long mapbase, |
| 41 | unsigned long irq, | 41 | unsigned long irq, |
| 42 | unsigned long irq_err); | 42 | unsigned long irq_err, |
| 43 | unsigned int tx_csum_limit); | ||
| 43 | 44 | ||
| 44 | void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, | 45 | void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, |
| 45 | unsigned long mapbase, | 46 | unsigned long mapbase, |
| 46 | unsigned long irq, | 47 | unsigned long irq, |
| 47 | unsigned long irq_err); | 48 | unsigned long irq_err, |
| 49 | unsigned int tx_csum_limit); | ||
| 48 | 50 | ||
| 49 | void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, | 51 | void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, |
| 50 | unsigned long mapbase, | 52 | unsigned long mapbase, |
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 28f898f75380..db98e7021f0d 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
| @@ -430,7 +430,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) | |||
| 430 | * when necessary. | 430 | * when necessary. |
| 431 | */ | 431 | */ |
| 432 | 432 | ||
| 433 | int s3c2410_dma_enqueue(unsigned int channel, void *id, | 433 | int s3c2410_dma_enqueue(enum dma_ch channel, void *id, |
| 434 | dma_addr_t data, int size) | 434 | dma_addr_t data, int size) |
| 435 | { | 435 | { |
| 436 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 436 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 74e31ce35538..fc49f3dabd76 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include <linux/platform_data/s3c-hsudc.h> | 32 | #include <linux/platform_data/s3c-hsudc.h> |
| 33 | #include <linux/platform_data/s3c-hsotg.h> | 33 | #include <linux/platform_data/s3c-hsotg.h> |
| 34 | 34 | ||
| 35 | #include <media/s5p_hdmi.h> | ||
| 36 | |||
| 35 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
| 36 | #include <asm/pmu.h> | 38 | #include <asm/pmu.h> |
| 37 | #include <asm/mach/arch.h> | 39 | #include <asm/mach/arch.h> |
| @@ -748,7 +750,8 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd) | |||
| 748 | if (!pd) { | 750 | if (!pd) { |
| 749 | pd = &default_i2c_data; | 751 | pd = &default_i2c_data; |
| 750 | 752 | ||
| 751 | if (soc_is_exynos4210()) | 753 | if (soc_is_exynos4210() || |
| 754 | soc_is_exynos4212() || soc_is_exynos4412()) | ||
| 752 | pd->bus_num = 8; | 755 | pd->bus_num = 8; |
| 753 | else if (soc_is_s5pv210()) | 756 | else if (soc_is_s5pv210()) |
| 754 | pd->bus_num = 3; | 757 | pd->bus_num = 3; |
| @@ -759,6 +762,30 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd) | |||
| 759 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | 762 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), |
| 760 | &s5p_device_i2c_hdmiphy); | 763 | &s5p_device_i2c_hdmiphy); |
| 761 | } | 764 | } |
| 765 | |||
| 766 | struct s5p_hdmi_platform_data s5p_hdmi_def_platdata; | ||
| 767 | |||
| 768 | void __init s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info, | ||
| 769 | struct i2c_board_info *mhl_info, int mhl_bus) | ||
| 770 | { | ||
| 771 | struct s5p_hdmi_platform_data *pd = &s5p_hdmi_def_platdata; | ||
| 772 | |||
| 773 | if (soc_is_exynos4210() || | ||
| 774 | soc_is_exynos4212() || soc_is_exynos4412()) | ||
| 775 | pd->hdmiphy_bus = 8; | ||
| 776 | else if (soc_is_s5pv210()) | ||
| 777 | pd->hdmiphy_bus = 3; | ||
| 778 | else | ||
| 779 | pd->hdmiphy_bus = 0; | ||
| 780 | |||
| 781 | pd->hdmiphy_info = hdmiphy_info; | ||
| 782 | pd->mhl_info = mhl_info; | ||
| 783 | pd->mhl_bus = mhl_bus; | ||
| 784 | |||
| 785 | s3c_set_platdata(pd, sizeof(struct s5p_hdmi_platform_data), | ||
| 786 | &s5p_device_hdmi); | ||
| 787 | } | ||
| 788 | |||
| 762 | #endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */ | 789 | #endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */ |
| 763 | 790 | ||
| 764 | /* I2S */ | 791 | /* I2S */ |
diff --git a/arch/arm/plat-samsung/include/plat/hdmi.h b/arch/arm/plat-samsung/include/plat/hdmi.h new file mode 100644 index 000000000000..331d046ac2c5 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/hdmi.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __PLAT_SAMSUNG_HDMI_H | ||
| 11 | #define __PLAT_SAMSUNG_HDMI_H __FILE__ | ||
| 12 | |||
| 13 | extern void s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info, | ||
| 14 | struct i2c_board_info *mhl_info, int mhl_bus); | ||
| 15 | |||
| 16 | #endif /* __PLAT_SAMSUNG_HDMI_H */ | ||
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 64ab65f0fdbc..15070284343e 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c | |||
| @@ -74,7 +74,7 @@ unsigned char pm_uart_udivslot; | |||
| 74 | 74 | ||
| 75 | #ifdef CONFIG_SAMSUNG_PM_DEBUG | 75 | #ifdef CONFIG_SAMSUNG_PM_DEBUG |
| 76 | 76 | ||
| 77 | struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; | 77 | static struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; |
| 78 | 78 | ||
| 79 | static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save) | 79 | static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save) |
| 80 | { | 80 | { |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 331d574df99c..faf65286574e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -89,6 +89,7 @@ config ATH79 | |||
| 89 | select CEVT_R4K | 89 | select CEVT_R4K |
| 90 | select CSRC_R4K | 90 | select CSRC_R4K |
| 91 | select DMA_NONCOHERENT | 91 | select DMA_NONCOHERENT |
| 92 | select HAVE_CLK | ||
| 92 | select IRQ_CPU | 93 | select IRQ_CPU |
| 93 | select MIPS_MACHINE | 94 | select MIPS_MACHINE |
| 94 | select SYS_HAS_CPU_MIPS32_R2 | 95 | select SYS_HAS_CPU_MIPS32_R2 |
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 99969484c475..a124c251c0c9 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c | |||
| @@ -228,6 +228,8 @@ static int mtx1_pci_idsel(unsigned int devsel, int assert) | |||
| 228 | * adapter on the mtx-1 "singleboard" variant. It triggers a custom | 228 | * adapter on the mtx-1 "singleboard" variant. It triggers a custom |
| 229 | * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals. | 229 | * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals. |
| 230 | */ | 230 | */ |
| 231 | udelay(1); | ||
| 232 | |||
| 231 | if (assert && devsel != 0) | 233 | if (assert && devsel != 0) |
| 232 | /* Suppress signal to Cardbus */ | 234 | /* Suppress signal to Cardbus */ |
| 233 | alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */ | 235 | alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */ |
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index 36e9570e7bc4..b2a2311ec85b 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c | |||
| @@ -145,6 +145,8 @@ static void __init ar7240_usb_setup(void) | |||
| 145 | 145 | ||
| 146 | ath79_ohci_resources[0].start = AR7240_OHCI_BASE; | 146 | ath79_ohci_resources[0].start = AR7240_OHCI_BASE; |
| 147 | ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; | 147 | ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; |
| 148 | ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB; | ||
| 149 | ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB; | ||
| 148 | platform_device_register(&ath79_ohci_device); | 150 | platform_device_register(&ath79_ohci_device); |
| 149 | } | 151 | } |
| 150 | 152 | ||
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index 29054f211832..48fe762d2526 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c | |||
| @@ -188,8 +188,10 @@ void __init ath79_gpio_init(void) | |||
| 188 | 188 | ||
| 189 | if (soc_is_ar71xx()) | 189 | if (soc_is_ar71xx()) |
| 190 | ath79_gpio_count = AR71XX_GPIO_COUNT; | 190 | ath79_gpio_count = AR71XX_GPIO_COUNT; |
| 191 | else if (soc_is_ar724x()) | 191 | else if (soc_is_ar7240()) |
| 192 | ath79_gpio_count = AR724X_GPIO_COUNT; | 192 | ath79_gpio_count = AR7240_GPIO_COUNT; |
| 193 | else if (soc_is_ar7241() || soc_is_ar7242()) | ||
| 194 | ath79_gpio_count = AR7241_GPIO_COUNT; | ||
| 193 | else if (soc_is_ar913x()) | 195 | else if (soc_is_ar913x()) |
| 194 | ath79_gpio_count = AR913X_GPIO_COUNT; | 196 | ath79_gpio_count = AR913X_GPIO_COUNT; |
| 195 | else if (soc_is_ar933x()) | 197 | else if (soc_is_ar933x()) |
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index e39f73048d4f..f1c9c3e2f678 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c | |||
| @@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void) | |||
| 106 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { | 106 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { |
| 107 | spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1; | 107 | spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1; |
| 108 | spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE; | 108 | spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE; |
| 109 | spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT; | ||
| 110 | spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH; | ||
| 109 | } | 111 | } |
| 110 | 112 | ||
| 111 | if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { | 113 | if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { |
| 112 | spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; | 114 | spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; |
| 113 | spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; | 115 | spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; |
| 116 | spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; | ||
| 117 | spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH; | ||
| 114 | } | 118 | } |
| 115 | 119 | ||
| 116 | bcm63xx_spi_regs_init(); | 120 | bcm63xx_spi_regs_init(); |
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 7fb1f222b8a5..274cd4fad30c 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c | |||
| @@ -61,6 +61,12 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit, | |||
| 61 | octeon_irq_ciu_to_irq[line][bit] = irq; | 61 | octeon_irq_ciu_to_irq[line][bit] = irq; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static void octeon_irq_force_ciu_mapping(struct irq_domain *domain, | ||
| 65 | int irq, int line, int bit) | ||
| 66 | { | ||
| 67 | irq_domain_associate(domain, irq, line << 6 | bit); | ||
| 68 | } | ||
| 69 | |||
| 64 | static int octeon_coreid_for_cpu(int cpu) | 70 | static int octeon_coreid_for_cpu(int cpu) |
| 65 | { | 71 | { |
| 66 | #ifdef CONFIG_SMP | 72 | #ifdef CONFIG_SMP |
| @@ -183,19 +189,9 @@ static void __init octeon_irq_init_core(void) | |||
| 183 | mutex_init(&cd->core_irq_mutex); | 189 | mutex_init(&cd->core_irq_mutex); |
| 184 | 190 | ||
| 185 | irq = OCTEON_IRQ_SW0 + i; | 191 | irq = OCTEON_IRQ_SW0 + i; |
| 186 | switch (irq) { | 192 | irq_set_chip_data(irq, cd); |
| 187 | case OCTEON_IRQ_TIMER: | 193 | irq_set_chip_and_handler(irq, &octeon_irq_chip_core, |
| 188 | case OCTEON_IRQ_SW0: | 194 | handle_percpu_irq); |
| 189 | case OCTEON_IRQ_SW1: | ||
| 190 | case OCTEON_IRQ_5: | ||
| 191 | case OCTEON_IRQ_PERF: | ||
| 192 | irq_set_chip_data(irq, cd); | ||
| 193 | irq_set_chip_and_handler(irq, &octeon_irq_chip_core, | ||
| 194 | handle_percpu_irq); | ||
| 195 | break; | ||
| 196 | default: | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | } | 195 | } |
| 200 | } | 196 | } |
| 201 | 197 | ||
| @@ -890,7 +886,6 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d, | |||
| 890 | unsigned int type; | 886 | unsigned int type; |
| 891 | unsigned int pin; | 887 | unsigned int pin; |
| 892 | unsigned int trigger; | 888 | unsigned int trigger; |
| 893 | struct octeon_irq_gpio_domain_data *gpiod; | ||
| 894 | 889 | ||
| 895 | if (d->of_node != node) | 890 | if (d->of_node != node) |
| 896 | return -EINVAL; | 891 | return -EINVAL; |
| @@ -925,8 +920,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d, | |||
| 925 | break; | 920 | break; |
| 926 | } | 921 | } |
| 927 | *out_type = type; | 922 | *out_type = type; |
| 928 | gpiod = d->host_data; | 923 | *out_hwirq = pin; |
| 929 | *out_hwirq = gpiod->base_hwirq + pin; | ||
| 930 | 924 | ||
| 931 | return 0; | 925 | return 0; |
| 932 | } | 926 | } |
| @@ -996,19 +990,21 @@ static int octeon_irq_ciu_map(struct irq_domain *d, | |||
| 996 | static int octeon_irq_gpio_map(struct irq_domain *d, | 990 | static int octeon_irq_gpio_map(struct irq_domain *d, |
| 997 | unsigned int virq, irq_hw_number_t hw) | 991 | unsigned int virq, irq_hw_number_t hw) |
| 998 | { | 992 | { |
| 999 | unsigned int line = hw >> 6; | 993 | struct octeon_irq_gpio_domain_data *gpiod = d->host_data; |
| 1000 | unsigned int bit = hw & 63; | 994 | unsigned int line, bit; |
| 1001 | 995 | ||
| 1002 | if (!octeon_irq_virq_in_range(virq)) | 996 | if (!octeon_irq_virq_in_range(virq)) |
| 1003 | return -EINVAL; | 997 | return -EINVAL; |
| 1004 | 998 | ||
| 999 | hw += gpiod->base_hwirq; | ||
| 1000 | line = hw >> 6; | ||
| 1001 | bit = hw & 63; | ||
| 1005 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) | 1002 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) |
| 1006 | return -EINVAL; | 1003 | return -EINVAL; |
| 1007 | 1004 | ||
| 1008 | octeon_irq_set_ciu_mapping(virq, line, bit, | 1005 | octeon_irq_set_ciu_mapping(virq, line, bit, |
| 1009 | octeon_irq_gpio_chip, | 1006 | octeon_irq_gpio_chip, |
| 1010 | octeon_irq_handle_gpio); | 1007 | octeon_irq_handle_gpio); |
| 1011 | |||
| 1012 | return 0; | 1008 | return 0; |
| 1013 | } | 1009 | } |
| 1014 | 1010 | ||
| @@ -1149,6 +1145,7 @@ static void __init octeon_irq_init_ciu(void) | |||
| 1149 | struct irq_chip *chip_wd; | 1145 | struct irq_chip *chip_wd; |
| 1150 | struct device_node *gpio_node; | 1146 | struct device_node *gpio_node; |
| 1151 | struct device_node *ciu_node; | 1147 | struct device_node *ciu_node; |
| 1148 | struct irq_domain *ciu_domain = NULL; | ||
| 1152 | 1149 | ||
| 1153 | octeon_irq_init_ciu_percpu(); | 1150 | octeon_irq_init_ciu_percpu(); |
| 1154 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; | 1151 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; |
| @@ -1177,31 +1174,6 @@ static void __init octeon_irq_init_ciu(void) | |||
| 1177 | /* Mips internal */ | 1174 | /* Mips internal */ |
| 1178 | octeon_irq_init_core(); | 1175 | octeon_irq_init_core(); |
| 1179 | 1176 | ||
| 1180 | /* CIU_0 */ | ||
| 1181 | for (i = 0; i < 16; i++) | ||
| 1182 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); | ||
| 1183 | |||
| 1184 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); | ||
| 1185 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); | ||
| 1186 | |||
| 1187 | for (i = 0; i < 4; i++) | ||
| 1188 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); | ||
| 1189 | for (i = 0; i < 4; i++) | ||
| 1190 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); | ||
| 1191 | |||
| 1192 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); | ||
| 1193 | for (i = 0; i < 4; i++) | ||
| 1194 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq); | ||
| 1195 | |||
| 1196 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); | ||
| 1197 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); | ||
| 1198 | |||
| 1199 | /* CIU_1 */ | ||
| 1200 | for (i = 0; i < 16; i++) | ||
| 1201 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); | ||
| 1202 | |||
| 1203 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); | ||
| 1204 | |||
| 1205 | gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio"); | 1177 | gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio"); |
| 1206 | if (gpio_node) { | 1178 | if (gpio_node) { |
| 1207 | struct octeon_irq_gpio_domain_data *gpiod; | 1179 | struct octeon_irq_gpio_domain_data *gpiod; |
| @@ -1219,10 +1191,35 @@ static void __init octeon_irq_init_ciu(void) | |||
| 1219 | 1191 | ||
| 1220 | ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu"); | 1192 | ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu"); |
| 1221 | if (ciu_node) { | 1193 | if (ciu_node) { |
| 1222 | irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); | 1194 | ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); |
| 1223 | of_node_put(ciu_node); | 1195 | of_node_put(ciu_node); |
| 1224 | } else | 1196 | } else |
| 1225 | pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n"); | 1197 | panic("Cannot find device node for cavium,octeon-3860-ciu."); |
| 1198 | |||
| 1199 | /* CIU_0 */ | ||
| 1200 | for (i = 0; i < 16; i++) | ||
| 1201 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0); | ||
| 1202 | |||
| 1203 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); | ||
| 1204 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); | ||
| 1205 | |||
| 1206 | for (i = 0; i < 4; i++) | ||
| 1207 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36); | ||
| 1208 | for (i = 0; i < 4; i++) | ||
| 1209 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40); | ||
| 1210 | |||
| 1211 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46); | ||
| 1212 | for (i = 0; i < 4; i++) | ||
| 1213 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52); | ||
| 1214 | |||
| 1215 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56); | ||
| 1216 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63); | ||
| 1217 | |||
| 1218 | /* CIU_1 */ | ||
| 1219 | for (i = 0; i < 16; i++) | ||
| 1220 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); | ||
| 1221 | |||
| 1222 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17); | ||
| 1226 | 1223 | ||
| 1227 | /* Enable the CIU lines */ | 1224 | /* Enable the CIU lines */ |
| 1228 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); | 1225 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); |
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index 1caa78ad06d5..dde504477fac 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h | |||
| @@ -393,7 +393,8 @@ | |||
| 393 | #define AR71XX_GPIO_REG_FUNC 0x28 | 393 | #define AR71XX_GPIO_REG_FUNC 0x28 |
| 394 | 394 | ||
| 395 | #define AR71XX_GPIO_COUNT 16 | 395 | #define AR71XX_GPIO_COUNT 16 |
| 396 | #define AR724X_GPIO_COUNT 18 | 396 | #define AR7240_GPIO_COUNT 18 |
| 397 | #define AR7241_GPIO_COUNT 20 | ||
| 397 | #define AR913X_GPIO_COUNT 22 | 398 | #define AR913X_GPIO_COUNT 22 |
| 398 | #define AR933X_GPIO_COUNT 30 | 399 | #define AR933X_GPIO_COUNT 30 |
| 399 | #define AR934X_GPIO_COUNT 23 | 400 | #define AR934X_GPIO_COUNT 23 |
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h index 4476fa03bf36..6ddae926bf79 100644 --- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h | |||
| @@ -42,7 +42,6 @@ | |||
| 42 | #define cpu_has_mips64r1 0 | 42 | #define cpu_has_mips64r1 0 |
| 43 | #define cpu_has_mips64r2 0 | 43 | #define cpu_has_mips64r2 0 |
| 44 | 44 | ||
| 45 | #define cpu_has_dsp 0 | ||
| 46 | #define cpu_has_mipsmt 0 | 45 | #define cpu_has_mipsmt 0 |
| 47 | 46 | ||
| 48 | #define cpu_has_64bits 0 | 47 | #define cpu_has_64bits 0 |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index 7d98dbe5d4b5..c9bae1362606 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | |||
| @@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void); | |||
| 9 | 9 | ||
| 10 | struct bcm63xx_spi_pdata { | 10 | struct bcm63xx_spi_pdata { |
| 11 | unsigned int fifo_size; | 11 | unsigned int fifo_size; |
| 12 | unsigned int msg_type_shift; | ||
| 13 | unsigned int msg_ctl_width; | ||
| 12 | int bus_num; | 14 | int bus_num; |
| 13 | int num_chipselect; | 15 | int num_chipselect; |
| 14 | u32 speed_hz; | 16 | u32 speed_hz; |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 4ccc2a748aff..61f2a2a5099d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | |||
| @@ -1054,7 +1054,8 @@ | |||
| 1054 | #define SPI_6338_FILL_BYTE 0x07 | 1054 | #define SPI_6338_FILL_BYTE 0x07 |
| 1055 | #define SPI_6338_MSG_TAIL 0x09 | 1055 | #define SPI_6338_MSG_TAIL 0x09 |
| 1056 | #define SPI_6338_RX_TAIL 0x0b | 1056 | #define SPI_6338_RX_TAIL 0x0b |
| 1057 | #define SPI_6338_MSG_CTL 0x40 | 1057 | #define SPI_6338_MSG_CTL 0x40 /* 8-bits register */ |
| 1058 | #define SPI_6338_MSG_CTL_WIDTH 8 | ||
| 1058 | #define SPI_6338_MSG_DATA 0x41 | 1059 | #define SPI_6338_MSG_DATA 0x41 |
| 1059 | #define SPI_6338_MSG_DATA_SIZE 0x3f | 1060 | #define SPI_6338_MSG_DATA_SIZE 0x3f |
| 1060 | #define SPI_6338_RX_DATA 0x80 | 1061 | #define SPI_6338_RX_DATA 0x80 |
| @@ -1070,7 +1071,8 @@ | |||
| 1070 | #define SPI_6348_FILL_BYTE 0x07 | 1071 | #define SPI_6348_FILL_BYTE 0x07 |
| 1071 | #define SPI_6348_MSG_TAIL 0x09 | 1072 | #define SPI_6348_MSG_TAIL 0x09 |
| 1072 | #define SPI_6348_RX_TAIL 0x0b | 1073 | #define SPI_6348_RX_TAIL 0x0b |
| 1073 | #define SPI_6348_MSG_CTL 0x40 | 1074 | #define SPI_6348_MSG_CTL 0x40 /* 8-bits register */ |
| 1075 | #define SPI_6348_MSG_CTL_WIDTH 8 | ||
| 1074 | #define SPI_6348_MSG_DATA 0x41 | 1076 | #define SPI_6348_MSG_DATA 0x41 |
| 1075 | #define SPI_6348_MSG_DATA_SIZE 0x3f | 1077 | #define SPI_6348_MSG_DATA_SIZE 0x3f |
| 1076 | #define SPI_6348_RX_DATA 0x80 | 1078 | #define SPI_6348_RX_DATA 0x80 |
| @@ -1078,6 +1080,7 @@ | |||
| 1078 | 1080 | ||
| 1079 | /* BCM 6358 SPI core */ | 1081 | /* BCM 6358 SPI core */ |
| 1080 | #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ | 1082 | #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ |
| 1083 | #define SPI_6358_MSG_CTL_WIDTH 16 | ||
| 1081 | #define SPI_6358_MSG_DATA 0x02 | 1084 | #define SPI_6358_MSG_DATA 0x02 |
| 1082 | #define SPI_6358_MSG_DATA_SIZE 0x21e | 1085 | #define SPI_6358_MSG_DATA_SIZE 0x21e |
| 1083 | #define SPI_6358_RX_DATA 0x400 | 1086 | #define SPI_6358_RX_DATA 0x400 |
| @@ -1094,6 +1097,7 @@ | |||
| 1094 | 1097 | ||
| 1095 | /* BCM 6358 SPI core */ | 1098 | /* BCM 6358 SPI core */ |
| 1096 | #define SPI_6368_MSG_CTL 0x00 /* 16-bits register */ | 1099 | #define SPI_6368_MSG_CTL 0x00 /* 16-bits register */ |
| 1100 | #define SPI_6368_MSG_CTL_WIDTH 16 | ||
| 1097 | #define SPI_6368_MSG_DATA 0x02 | 1101 | #define SPI_6368_MSG_DATA 0x02 |
| 1098 | #define SPI_6368_MSG_DATA_SIZE 0x21e | 1102 | #define SPI_6368_MSG_DATA_SIZE 0x21e |
| 1099 | #define SPI_6368_RX_DATA 0x400 | 1103 | #define SPI_6368_RX_DATA 0x400 |
| @@ -1115,7 +1119,10 @@ | |||
| 1115 | #define SPI_HD_W 0x01 | 1119 | #define SPI_HD_W 0x01 |
| 1116 | #define SPI_HD_R 0x02 | 1120 | #define SPI_HD_R 0x02 |
| 1117 | #define SPI_BYTE_CNT_SHIFT 0 | 1121 | #define SPI_BYTE_CNT_SHIFT 0 |
| 1118 | #define SPI_MSG_TYPE_SHIFT 14 | 1122 | #define SPI_6338_MSG_TYPE_SHIFT 6 |
| 1123 | #define SPI_6348_MSG_TYPE_SHIFT 6 | ||
| 1124 | #define SPI_6358_MSG_TYPE_SHIFT 14 | ||
| 1125 | #define SPI_6368_MSG_TYPE_SHIFT 14 | ||
| 1119 | 1126 | ||
| 1120 | /* Command */ | 1127 | /* Command */ |
| 1121 | #define SPI_CMD_NOOP 0x00 | 1128 | #define SPI_CMD_NOOP 0x00 |
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h index 418992042f6f..c22a3078bf11 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/irq.h +++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h | |||
| @@ -21,14 +21,10 @@ enum octeon_irq { | |||
| 21 | OCTEON_IRQ_TIMER, | 21 | OCTEON_IRQ_TIMER, |
| 22 | /* sources in CIU_INTX_EN0 */ | 22 | /* sources in CIU_INTX_EN0 */ |
| 23 | OCTEON_IRQ_WORKQ0, | 23 | OCTEON_IRQ_WORKQ0, |
| 24 | OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16, | 24 | OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 16, |
| 25 | OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16, | ||
| 26 | OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15, | 25 | OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15, |
| 27 | OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16, | 26 | OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16, |
| 28 | OCTEON_IRQ_MBOX1, | 27 | OCTEON_IRQ_MBOX1, |
| 29 | OCTEON_IRQ_UART0, | ||
| 30 | OCTEON_IRQ_UART1, | ||
| 31 | OCTEON_IRQ_UART2, | ||
| 32 | OCTEON_IRQ_PCI_INT0, | 28 | OCTEON_IRQ_PCI_INT0, |
| 33 | OCTEON_IRQ_PCI_INT1, | 29 | OCTEON_IRQ_PCI_INT1, |
| 34 | OCTEON_IRQ_PCI_INT2, | 30 | OCTEON_IRQ_PCI_INT2, |
| @@ -38,8 +34,6 @@ enum octeon_irq { | |||
| 38 | OCTEON_IRQ_PCI_MSI2, | 34 | OCTEON_IRQ_PCI_MSI2, |
| 39 | OCTEON_IRQ_PCI_MSI3, | 35 | OCTEON_IRQ_PCI_MSI3, |
| 40 | 36 | ||
| 41 | OCTEON_IRQ_TWSI, | ||
| 42 | OCTEON_IRQ_TWSI2, | ||
| 43 | OCTEON_IRQ_RML, | 37 | OCTEON_IRQ_RML, |
| 44 | OCTEON_IRQ_TIMER0, | 38 | OCTEON_IRQ_TIMER0, |
| 45 | OCTEON_IRQ_TIMER1, | 39 | OCTEON_IRQ_TIMER1, |
| @@ -47,8 +41,6 @@ enum octeon_irq { | |||
| 47 | OCTEON_IRQ_TIMER3, | 41 | OCTEON_IRQ_TIMER3, |
| 48 | OCTEON_IRQ_USB0, | 42 | OCTEON_IRQ_USB0, |
| 49 | OCTEON_IRQ_USB1, | 43 | OCTEON_IRQ_USB1, |
| 50 | OCTEON_IRQ_MII0, | ||
| 51 | OCTEON_IRQ_MII1, | ||
| 52 | OCTEON_IRQ_BOOTDMA, | 44 | OCTEON_IRQ_BOOTDMA, |
| 53 | #ifndef CONFIG_PCI_MSI | 45 | #ifndef CONFIG_PCI_MSI |
| 54 | OCTEON_IRQ_LAST = 127 | 46 | OCTEON_IRQ_LAST = 127 |
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 7531ecd654d6..dca8bce8c7ab 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h | |||
| @@ -10,6 +10,7 @@ struct mod_arch_specific { | |||
| 10 | struct list_head dbe_list; | 10 | struct list_head dbe_list; |
| 11 | const struct exception_table_entry *dbe_start; | 11 | const struct exception_table_entry *dbe_start; |
| 12 | const struct exception_table_entry *dbe_end; | 12 | const struct exception_table_entry *dbe_end; |
| 13 | struct mips_hi16 *r_mips_hi16_list; | ||
| 13 | }; | 14 | }; |
| 14 | 15 | ||
| 15 | typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ | 16 | typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ |
diff --git a/arch/mips/include/asm/r4k-timer.h b/arch/mips/include/asm/r4k-timer.h index a37d12b3b61c..afe9e0e03fe9 100644 --- a/arch/mips/include/asm/r4k-timer.h +++ b/arch/mips/include/asm/r4k-timer.h | |||
| @@ -12,16 +12,16 @@ | |||
| 12 | 12 | ||
| 13 | #ifdef CONFIG_SYNC_R4K | 13 | #ifdef CONFIG_SYNC_R4K |
| 14 | 14 | ||
| 15 | extern void synchronise_count_master(void); | 15 | extern void synchronise_count_master(int cpu); |
| 16 | extern void synchronise_count_slave(void); | 16 | extern void synchronise_count_slave(int cpu); |
| 17 | 17 | ||
| 18 | #else | 18 | #else |
| 19 | 19 | ||
| 20 | static inline void synchronise_count_master(void) | 20 | static inline void synchronise_count_master(int cpu) |
| 21 | { | 21 | { |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static inline void synchronise_count_slave(void) | 24 | static inline void synchronise_count_slave(int cpu) |
| 25 | { | 25 | { |
| 26 | } | 26 | } |
| 27 | 27 | ||
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index a5066b1c3de3..4f8c3cba8c0c 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c | |||
| @@ -39,8 +39,6 @@ struct mips_hi16 { | |||
| 39 | Elf_Addr value; | 39 | Elf_Addr value; |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | static struct mips_hi16 *mips_hi16_list; | ||
| 43 | |||
| 44 | static LIST_HEAD(dbe_list); | 42 | static LIST_HEAD(dbe_list); |
| 45 | static DEFINE_SPINLOCK(dbe_lock); | 43 | static DEFINE_SPINLOCK(dbe_lock); |
| 46 | 44 | ||
| @@ -128,8 +126,8 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) | |||
| 128 | 126 | ||
| 129 | n->addr = (Elf_Addr *)location; | 127 | n->addr = (Elf_Addr *)location; |
| 130 | n->value = v; | 128 | n->value = v; |
| 131 | n->next = mips_hi16_list; | 129 | n->next = me->arch.r_mips_hi16_list; |
| 132 | mips_hi16_list = n; | 130 | me->arch.r_mips_hi16_list = n; |
| 133 | 131 | ||
| 134 | return 0; | 132 | return 0; |
| 135 | } | 133 | } |
| @@ -142,18 +140,28 @@ static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v) | |||
| 142 | return 0; | 140 | return 0; |
| 143 | } | 141 | } |
| 144 | 142 | ||
| 143 | static void free_relocation_chain(struct mips_hi16 *l) | ||
| 144 | { | ||
| 145 | struct mips_hi16 *next; | ||
| 146 | |||
| 147 | while (l) { | ||
| 148 | next = l->next; | ||
| 149 | kfree(l); | ||
| 150 | l = next; | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 145 | static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) | 154 | static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) |
| 146 | { | 155 | { |
| 147 | unsigned long insnlo = *location; | 156 | unsigned long insnlo = *location; |
| 157 | struct mips_hi16 *l; | ||
| 148 | Elf_Addr val, vallo; | 158 | Elf_Addr val, vallo; |
| 149 | 159 | ||
| 150 | /* Sign extend the addend we extract from the lo insn. */ | 160 | /* Sign extend the addend we extract from the lo insn. */ |
| 151 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; | 161 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; |
| 152 | 162 | ||
| 153 | if (mips_hi16_list != NULL) { | 163 | if (me->arch.r_mips_hi16_list != NULL) { |
| 154 | struct mips_hi16 *l; | 164 | l = me->arch.r_mips_hi16_list; |
| 155 | |||
| 156 | l = mips_hi16_list; | ||
| 157 | while (l != NULL) { | 165 | while (l != NULL) { |
| 158 | struct mips_hi16 *next; | 166 | struct mips_hi16 *next; |
| 159 | unsigned long insn; | 167 | unsigned long insn; |
| @@ -188,7 +196,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) | |||
| 188 | l = next; | 196 | l = next; |
| 189 | } | 197 | } |
| 190 | 198 | ||
| 191 | mips_hi16_list = NULL; | 199 | me->arch.r_mips_hi16_list = NULL; |
| 192 | } | 200 | } |
| 193 | 201 | ||
| 194 | /* | 202 | /* |
| @@ -201,6 +209,9 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) | |||
| 201 | return 0; | 209 | return 0; |
| 202 | 210 | ||
| 203 | out_danger: | 211 | out_danger: |
| 212 | free_relocation_chain(l); | ||
| 213 | me->arch.r_mips_hi16_list = NULL; | ||
| 214 | |||
| 204 | pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name); | 215 | pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name); |
| 205 | 216 | ||
| 206 | return -ENOEXEC; | 217 | return -ENOEXEC; |
| @@ -273,6 +284,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | |||
| 273 | pr_debug("Applying relocate section %u to %u\n", relsec, | 284 | pr_debug("Applying relocate section %u to %u\n", relsec, |
| 274 | sechdrs[relsec].sh_info); | 285 | sechdrs[relsec].sh_info); |
| 275 | 286 | ||
| 287 | me->arch.r_mips_hi16_list = NULL; | ||
| 276 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | 288 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { |
| 277 | /* This is where to make the change */ | 289 | /* This is where to make the change */ |
| 278 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | 290 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
| @@ -296,6 +308,19 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | |||
| 296 | return res; | 308 | return res; |
| 297 | } | 309 | } |
| 298 | 310 | ||
| 311 | /* | ||
| 312 | * Normally the hi16 list should be deallocated at this point. A | ||
| 313 | * malformed binary however could contain a series of R_MIPS_HI16 | ||
| 314 | * relocations not followed by a R_MIPS_LO16 relocation. In that | ||
| 315 | * case, free up the list and return an error. | ||
| 316 | */ | ||
| 317 | if (me->arch.r_mips_hi16_list) { | ||
| 318 | free_relocation_chain(me->arch.r_mips_hi16_list); | ||
| 319 | me->arch.r_mips_hi16_list = NULL; | ||
| 320 | |||
| 321 | return -ENOEXEC; | ||
| 322 | } | ||
| 323 | |||
| 299 | return 0; | 324 | return 0; |
| 300 | } | 325 | } |
| 301 | 326 | ||
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 31637d8c8738..9005bf9fb859 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
| @@ -130,7 +130,7 @@ asmlinkage __cpuinit void start_secondary(void) | |||
| 130 | 130 | ||
| 131 | cpu_set(cpu, cpu_callin_map); | 131 | cpu_set(cpu, cpu_callin_map); |
| 132 | 132 | ||
| 133 | synchronise_count_slave(); | 133 | synchronise_count_slave(cpu); |
| 134 | 134 | ||
| 135 | /* | 135 | /* |
| 136 | * irq will be enabled in ->smp_finish(), enabling it too early | 136 | * irq will be enabled in ->smp_finish(), enabling it too early |
| @@ -173,7 +173,6 @@ void smp_send_stop(void) | |||
| 173 | void __init smp_cpus_done(unsigned int max_cpus) | 173 | void __init smp_cpus_done(unsigned int max_cpus) |
| 174 | { | 174 | { |
| 175 | mp_ops->cpus_done(); | 175 | mp_ops->cpus_done(); |
| 176 | synchronise_count_master(); | ||
| 177 | } | 176 | } |
| 178 | 177 | ||
| 179 | /* called from main before smp_init() */ | 178 | /* called from main before smp_init() */ |
| @@ -206,6 +205,7 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
| 206 | while (!cpu_isset(cpu, cpu_callin_map)) | 205 | while (!cpu_isset(cpu, cpu_callin_map)) |
| 207 | udelay(100); | 206 | udelay(100); |
| 208 | 207 | ||
| 208 | synchronise_count_master(cpu); | ||
| 209 | return 0; | 209 | return 0; |
| 210 | } | 210 | } |
| 211 | 211 | ||
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 842d55e411fd..7f1eca3858de 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c | |||
| @@ -28,12 +28,11 @@ static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0); | |||
| 28 | #define COUNTON 100 | 28 | #define COUNTON 100 |
| 29 | #define NR_LOOPS 5 | 29 | #define NR_LOOPS 5 |
| 30 | 30 | ||
| 31 | void __cpuinit synchronise_count_master(void) | 31 | void __cpuinit synchronise_count_master(int cpu) |
| 32 | { | 32 | { |
| 33 | int i; | 33 | int i; |
| 34 | unsigned long flags; | 34 | unsigned long flags; |
| 35 | unsigned int initcount; | 35 | unsigned int initcount; |
| 36 | int nslaves; | ||
| 37 | 36 | ||
| 38 | #ifdef CONFIG_MIPS_MT_SMTC | 37 | #ifdef CONFIG_MIPS_MT_SMTC |
| 39 | /* | 38 | /* |
| @@ -43,8 +42,7 @@ void __cpuinit synchronise_count_master(void) | |||
| 43 | return; | 42 | return; |
| 44 | #endif | 43 | #endif |
| 45 | 44 | ||
| 46 | printk(KERN_INFO "Synchronize counters across %u CPUs: ", | 45 | printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu); |
| 47 | num_online_cpus()); | ||
| 48 | 46 | ||
| 49 | local_irq_save(flags); | 47 | local_irq_save(flags); |
| 50 | 48 | ||
| @@ -52,7 +50,7 @@ void __cpuinit synchronise_count_master(void) | |||
| 52 | * Notify the slaves that it's time to start | 50 | * Notify the slaves that it's time to start |
| 53 | */ | 51 | */ |
| 54 | atomic_set(&count_reference, read_c0_count()); | 52 | atomic_set(&count_reference, read_c0_count()); |
| 55 | atomic_set(&count_start_flag, 1); | 53 | atomic_set(&count_start_flag, cpu); |
| 56 | smp_wmb(); | 54 | smp_wmb(); |
| 57 | 55 | ||
| 58 | /* Count will be initialised to current timer for all CPU's */ | 56 | /* Count will be initialised to current timer for all CPU's */ |
| @@ -69,10 +67,9 @@ void __cpuinit synchronise_count_master(void) | |||
| 69 | * two CPUs. | 67 | * two CPUs. |
| 70 | */ | 68 | */ |
| 71 | 69 | ||
| 72 | nslaves = num_online_cpus()-1; | ||
| 73 | for (i = 0; i < NR_LOOPS; i++) { | 70 | for (i = 0; i < NR_LOOPS; i++) { |
| 74 | /* slaves loop on '!= ncpus' */ | 71 | /* slaves loop on '!= 2' */ |
| 75 | while (atomic_read(&count_count_start) != nslaves) | 72 | while (atomic_read(&count_count_start) != 1) |
| 76 | mb(); | 73 | mb(); |
| 77 | atomic_set(&count_count_stop, 0); | 74 | atomic_set(&count_count_stop, 0); |
| 78 | smp_wmb(); | 75 | smp_wmb(); |
| @@ -89,7 +86,7 @@ void __cpuinit synchronise_count_master(void) | |||
| 89 | /* | 86 | /* |
| 90 | * Wait for all slaves to leave the synchronization point: | 87 | * Wait for all slaves to leave the synchronization point: |
| 91 | */ | 88 | */ |
| 92 | while (atomic_read(&count_count_stop) != nslaves) | 89 | while (atomic_read(&count_count_stop) != 1) |
| 93 | mb(); | 90 | mb(); |
| 94 | atomic_set(&count_count_start, 0); | 91 | atomic_set(&count_count_start, 0); |
| 95 | smp_wmb(); | 92 | smp_wmb(); |
| @@ -97,6 +94,7 @@ void __cpuinit synchronise_count_master(void) | |||
| 97 | } | 94 | } |
| 98 | /* Arrange for an interrupt in a short while */ | 95 | /* Arrange for an interrupt in a short while */ |
| 99 | write_c0_compare(read_c0_count() + COUNTON); | 96 | write_c0_compare(read_c0_count() + COUNTON); |
| 97 | atomic_set(&count_start_flag, 0); | ||
| 100 | 98 | ||
| 101 | local_irq_restore(flags); | 99 | local_irq_restore(flags); |
| 102 | 100 | ||
| @@ -108,11 +106,10 @@ void __cpuinit synchronise_count_master(void) | |||
| 108 | printk("done.\n"); | 106 | printk("done.\n"); |
| 109 | } | 107 | } |
| 110 | 108 | ||
| 111 | void __cpuinit synchronise_count_slave(void) | 109 | void __cpuinit synchronise_count_slave(int cpu) |
| 112 | { | 110 | { |
| 113 | int i; | 111 | int i; |
| 114 | unsigned int initcount; | 112 | unsigned int initcount; |
| 115 | int ncpus; | ||
| 116 | 113 | ||
| 117 | #ifdef CONFIG_MIPS_MT_SMTC | 114 | #ifdef CONFIG_MIPS_MT_SMTC |
| 118 | /* | 115 | /* |
| @@ -127,16 +124,15 @@ void __cpuinit synchronise_count_slave(void) | |||
| 127 | * so we first wait for the master to say everyone is ready | 124 | * so we first wait for the master to say everyone is ready |
| 128 | */ | 125 | */ |
| 129 | 126 | ||
| 130 | while (!atomic_read(&count_start_flag)) | 127 | while (atomic_read(&count_start_flag) != cpu) |
| 131 | mb(); | 128 | mb(); |
| 132 | 129 | ||
| 133 | /* Count will be initialised to next expire for all CPU's */ | 130 | /* Count will be initialised to next expire for all CPU's */ |
| 134 | initcount = atomic_read(&count_reference); | 131 | initcount = atomic_read(&count_reference); |
| 135 | 132 | ||
| 136 | ncpus = num_online_cpus(); | ||
| 137 | for (i = 0; i < NR_LOOPS; i++) { | 133 | for (i = 0; i < NR_LOOPS; i++) { |
| 138 | atomic_inc(&count_count_start); | 134 | atomic_inc(&count_count_start); |
| 139 | while (atomic_read(&count_count_start) != ncpus) | 135 | while (atomic_read(&count_count_start) != 2) |
| 140 | mb(); | 136 | mb(); |
| 141 | 137 | ||
| 142 | /* | 138 | /* |
| @@ -146,7 +142,7 @@ void __cpuinit synchronise_count_slave(void) | |||
| 146 | write_c0_count(initcount); | 142 | write_c0_count(initcount); |
| 147 | 143 | ||
| 148 | atomic_inc(&count_count_stop); | 144 | atomic_inc(&count_count_stop); |
| 149 | while (atomic_read(&count_count_stop) != ncpus) | 145 | while (atomic_read(&count_count_stop) != 2) |
| 150 | mb(); | 146 | mb(); |
| 151 | } | 147 | } |
| 152 | /* Arrange for an interrupt in a short while */ | 148 | /* Arrange for an interrupt in a short while */ |
diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c index 284dea54faf5..2147cb34e705 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/mti-malta/malta-pci.c | |||
| @@ -252,16 +252,3 @@ void __init mips_pcibios_init(void) | |||
| 252 | 252 | ||
| 253 | register_pci_controller(controller); | 253 | register_pci_controller(controller); |
| 254 | } | 254 | } |
| 255 | |||
| 256 | /* Enable PCI 2.1 compatibility in PIIX4 */ | ||
| 257 | static void __devinit quirk_dlcsetup(struct pci_dev *dev) | ||
| 258 | { | ||
| 259 | u8 odlc, ndlc; | ||
| 260 | (void) pci_read_config_byte(dev, 0x82, &odlc); | ||
| 261 | /* Enable passive releases and delayed transaction */ | ||
| 262 | ndlc = odlc | 7; | ||
| 263 | (void) pci_write_config_byte(dev, 0x82, ndlc); | ||
| 264 | } | ||
| 265 | |||
| 266 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, | ||
| 267 | quirk_dlcsetup); | ||
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 414a7459858d..86d77a666458 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c | |||
| @@ -23,9 +23,12 @@ | |||
| 23 | #define AR724X_PCI_MEM_BASE 0x10000000 | 23 | #define AR724X_PCI_MEM_BASE 0x10000000 |
| 24 | #define AR724X_PCI_MEM_SIZE 0x08000000 | 24 | #define AR724X_PCI_MEM_SIZE 0x08000000 |
| 25 | 25 | ||
| 26 | #define AR724X_PCI_REG_RESET 0x18 | ||
| 26 | #define AR724X_PCI_REG_INT_STATUS 0x4c | 27 | #define AR724X_PCI_REG_INT_STATUS 0x4c |
| 27 | #define AR724X_PCI_REG_INT_MASK 0x50 | 28 | #define AR724X_PCI_REG_INT_MASK 0x50 |
| 28 | 29 | ||
| 30 | #define AR724X_PCI_RESET_LINK_UP BIT(0) | ||
| 31 | |||
| 29 | #define AR724X_PCI_INT_DEV0 BIT(14) | 32 | #define AR724X_PCI_INT_DEV0 BIT(14) |
| 30 | 33 | ||
| 31 | #define AR724X_PCI_IRQ_COUNT 1 | 34 | #define AR724X_PCI_IRQ_COUNT 1 |
| @@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_base; | |||
| 38 | 41 | ||
| 39 | static u32 ar724x_pci_bar0_value; | 42 | static u32 ar724x_pci_bar0_value; |
| 40 | static bool ar724x_pci_bar0_is_cached; | 43 | static bool ar724x_pci_bar0_is_cached; |
| 44 | static bool ar724x_pci_link_up; | ||
| 45 | |||
| 46 | static inline bool ar724x_pci_check_link(void) | ||
| 47 | { | ||
| 48 | u32 reset; | ||
| 49 | |||
| 50 | reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); | ||
| 51 | return reset & AR724X_PCI_RESET_LINK_UP; | ||
| 52 | } | ||
| 41 | 53 | ||
| 42 | static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | 54 | static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
| 43 | int size, uint32_t *value) | 55 | int size, uint32_t *value) |
| @@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 46 | void __iomem *base; | 58 | void __iomem *base; |
| 47 | u32 data; | 59 | u32 data; |
| 48 | 60 | ||
| 61 | if (!ar724x_pci_link_up) | ||
| 62 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 63 | |||
| 49 | if (devfn) | 64 | if (devfn) |
| 50 | return PCIBIOS_DEVICE_NOT_FOUND; | 65 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 51 | 66 | ||
| @@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 96 | u32 data; | 111 | u32 data; |
| 97 | int s; | 112 | int s; |
| 98 | 113 | ||
| 114 | if (!ar724x_pci_link_up) | ||
| 115 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 116 | |||
| 99 | if (devfn) | 117 | if (devfn) |
| 100 | return PCIBIOS_DEVICE_NOT_FOUND; | 118 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 101 | 119 | ||
| @@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq) | |||
| 280 | if (ar724x_pci_ctrl_base == NULL) | 298 | if (ar724x_pci_ctrl_base == NULL) |
| 281 | goto err_unmap_devcfg; | 299 | goto err_unmap_devcfg; |
| 282 | 300 | ||
| 301 | ar724x_pci_link_up = ar724x_pci_check_link(); | ||
| 302 | if (!ar724x_pci_link_up) | ||
| 303 | pr_warn("ar724x: PCIe link is down\n"); | ||
| 304 | |||
| 283 | ar724x_pci_irq_init(irq); | 305 | ar724x_pci_irq_init(irq); |
| 284 | register_pci_controller(&ar724x_pci_controller); | 306 | register_pci_controller(&ar724x_pci_controller); |
| 285 | 307 | ||
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 6c6defc24619..af9cf30ed474 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h | |||
| @@ -141,7 +141,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
| 141 | 141 | ||
| 142 | #define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) | 142 | #define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) |
| 143 | 143 | ||
| 144 | #define ATOMIC_INIT(i) ((atomic_t) { (i) }) | 144 | #define ATOMIC_INIT(i) { (i) } |
| 145 | 145 | ||
| 146 | #define smp_mb__before_atomic_dec() smp_mb() | 146 | #define smp_mb__before_atomic_dec() smp_mb() |
| 147 | #define smp_mb__after_atomic_dec() smp_mb() | 147 | #define smp_mb__after_atomic_dec() smp_mb() |
| @@ -150,7 +150,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
| 150 | 150 | ||
| 151 | #ifdef CONFIG_64BIT | 151 | #ifdef CONFIG_64BIT |
| 152 | 152 | ||
| 153 | #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) | 153 | #define ATOMIC64_INIT(i) { (i) } |
| 154 | 154 | ||
| 155 | static __inline__ s64 | 155 | static __inline__ s64 |
| 156 | __atomic64_add_return(s64 i, atomic64_t *v) | 156 | __atomic64_add_return(s64 i, atomic64_t *v) |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index d4b94b395c16..2c05a9292a81 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
| @@ -309,7 +309,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
| 309 | cregs->ksp = (unsigned long)stack | 309 | cregs->ksp = (unsigned long)stack |
| 310 | + (pregs->gr[21] & (THREAD_SIZE - 1)); | 310 | + (pregs->gr[21] & (THREAD_SIZE - 1)); |
| 311 | cregs->gr[30] = usp; | 311 | cregs->gr[30] = usp; |
| 312 | if (p->personality == PER_HPUX) { | 312 | if (personality(p->personality) == PER_HPUX) { |
| 313 | #ifdef CONFIG_HPUX | 313 | #ifdef CONFIG_HPUX |
| 314 | cregs->kpc = (unsigned long) &hpux_child_return; | 314 | cregs->kpc = (unsigned long) &hpux_child_return; |
| 315 | #else | 315 | #else |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index c9b932260f47..7426e40699bd 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
| @@ -225,12 +225,12 @@ long parisc_personality(unsigned long personality) | |||
| 225 | long err; | 225 | long err; |
| 226 | 226 | ||
| 227 | if (personality(current->personality) == PER_LINUX32 | 227 | if (personality(current->personality) == PER_LINUX32 |
| 228 | && personality == PER_LINUX) | 228 | && personality(personality) == PER_LINUX) |
| 229 | personality = PER_LINUX32; | 229 | personality = (personality & ~PER_MASK) | PER_LINUX32; |
| 230 | 230 | ||
| 231 | err = sys_personality(personality); | 231 | err = sys_personality(personality); |
| 232 | if (err == PER_LINUX32) | 232 | if (personality(err) == PER_LINUX32) |
| 233 | err = PER_LINUX; | 233 | err = (err & ~PER_MASK) | PER_LINUX; |
| 234 | 234 | ||
| 235 | return err; | 235 | return err; |
| 236 | } | 236 | } |
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi index 8d35d2c1f694..4f9c9f682ecf 100644 --- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | |||
| @@ -345,6 +345,13 @@ | |||
| 345 | /include/ "qoriq-duart-1.dtsi" | 345 | /include/ "qoriq-duart-1.dtsi" |
| 346 | /include/ "qoriq-gpio-0.dtsi" | 346 | /include/ "qoriq-gpio-0.dtsi" |
| 347 | /include/ "qoriq-usb2-mph-0.dtsi" | 347 | /include/ "qoriq-usb2-mph-0.dtsi" |
| 348 | usb@210000 { | ||
| 349 | compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; | ||
| 350 | port0; | ||
| 351 | }; | ||
| 348 | /include/ "qoriq-usb2-dr-0.dtsi" | 352 | /include/ "qoriq-usb2-dr-0.dtsi" |
| 353 | usb@211000 { | ||
| 354 | compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; | ||
| 355 | }; | ||
| 349 | /include/ "qoriq-sec4.0-0.dtsi" | 356 | /include/ "qoriq-sec4.0-0.dtsi" |
| 350 | }; | 357 | }; |
diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig index f4337bacd0e7..26e541c4662b 100644 --- a/arch/powerpc/configs/85xx/p1023rds_defconfig +++ b/arch/powerpc/configs/85xx/p1023rds_defconfig | |||
| @@ -6,28 +6,27 @@ CONFIG_SYSVIPC=y | |||
| 6 | CONFIG_POSIX_MQUEUE=y | 6 | CONFIG_POSIX_MQUEUE=y |
| 7 | CONFIG_BSD_PROCESS_ACCT=y | 7 | CONFIG_BSD_PROCESS_ACCT=y |
| 8 | CONFIG_AUDIT=y | 8 | CONFIG_AUDIT=y |
| 9 | CONFIG_SPARSE_IRQ=y | 9 | CONFIG_IRQ_DOMAIN_DEBUG=y |
| 10 | CONFIG_NO_HZ=y | ||
| 11 | CONFIG_HIGH_RES_TIMERS=y | ||
| 10 | CONFIG_IKCONFIG=y | 12 | CONFIG_IKCONFIG=y |
| 11 | CONFIG_IKCONFIG_PROC=y | 13 | CONFIG_IKCONFIG_PROC=y |
| 12 | CONFIG_LOG_BUF_SHIFT=14 | 14 | CONFIG_LOG_BUF_SHIFT=14 |
| 13 | CONFIG_BLK_DEV_INITRD=y | 15 | CONFIG_BLK_DEV_INITRD=y |
| 14 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 15 | CONFIG_KALLSYMS_ALL=y | 16 | CONFIG_KALLSYMS_ALL=y |
| 16 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
| 17 | CONFIG_EMBEDDED=y | 17 | CONFIG_EMBEDDED=y |
| 18 | CONFIG_MODULES=y | 18 | CONFIG_MODULES=y |
| 19 | CONFIG_MODULE_UNLOAD=y | 19 | CONFIG_MODULE_UNLOAD=y |
| 20 | CONFIG_MODULE_FORCE_UNLOAD=y | 20 | CONFIG_MODULE_FORCE_UNLOAD=y |
| 21 | CONFIG_MODVERSIONS=y | 21 | CONFIG_MODVERSIONS=y |
| 22 | # CONFIG_BLK_DEV_BSG is not set | 22 | # CONFIG_BLK_DEV_BSG is not set |
| 23 | CONFIG_PARTITION_ADVANCED=y | ||
| 24 | CONFIG_MAC_PARTITION=y | ||
| 23 | CONFIG_P1023_RDS=y | 25 | CONFIG_P1023_RDS=y |
| 24 | CONFIG_QUICC_ENGINE=y | 26 | CONFIG_QUICC_ENGINE=y |
| 25 | CONFIG_QE_GPIO=y | 27 | CONFIG_QE_GPIO=y |
| 26 | CONFIG_CPM2=y | 28 | CONFIG_CPM2=y |
| 27 | CONFIG_GPIO_MPC8XXX=y | ||
| 28 | CONFIG_HIGHMEM=y | 29 | CONFIG_HIGHMEM=y |
| 29 | CONFIG_NO_HZ=y | ||
| 30 | CONFIG_HIGH_RES_TIMERS=y | ||
| 31 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 30 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 32 | CONFIG_BINFMT_MISC=m | 31 | CONFIG_BINFMT_MISC=m |
| 33 | CONFIG_MATH_EMULATION=y | 32 | CONFIG_MATH_EMULATION=y |
| @@ -63,11 +62,11 @@ CONFIG_INET_ESP=y | |||
| 63 | CONFIG_IPV6=y | 62 | CONFIG_IPV6=y |
| 64 | CONFIG_IP_SCTP=m | 63 | CONFIG_IP_SCTP=m |
| 65 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 64 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 65 | CONFIG_DEVTMPFS=y | ||
| 66 | CONFIG_PROC_DEVICETREE=y | 66 | CONFIG_PROC_DEVICETREE=y |
| 67 | CONFIG_BLK_DEV_LOOP=y | 67 | CONFIG_BLK_DEV_LOOP=y |
| 68 | CONFIG_BLK_DEV_RAM=y | 68 | CONFIG_BLK_DEV_RAM=y |
| 69 | CONFIG_BLK_DEV_RAM_SIZE=131072 | 69 | CONFIG_BLK_DEV_RAM_SIZE=131072 |
| 70 | CONFIG_MISC_DEVICES=y | ||
| 71 | CONFIG_EEPROM_LEGACY=y | 70 | CONFIG_EEPROM_LEGACY=y |
| 72 | CONFIG_BLK_DEV_SD=y | 71 | CONFIG_BLK_DEV_SD=y |
| 73 | CONFIG_CHR_DEV_ST=y | 72 | CONFIG_CHR_DEV_ST=y |
| @@ -80,15 +79,14 @@ CONFIG_SATA_FSL=y | |||
| 80 | CONFIG_SATA_SIL24=y | 79 | CONFIG_SATA_SIL24=y |
| 81 | CONFIG_NETDEVICES=y | 80 | CONFIG_NETDEVICES=y |
| 82 | CONFIG_DUMMY=y | 81 | CONFIG_DUMMY=y |
| 82 | CONFIG_FS_ENET=y | ||
| 83 | CONFIG_FSL_PQ_MDIO=y | ||
| 84 | CONFIG_E1000E=y | ||
| 83 | CONFIG_MARVELL_PHY=y | 85 | CONFIG_MARVELL_PHY=y |
| 84 | CONFIG_DAVICOM_PHY=y | 86 | CONFIG_DAVICOM_PHY=y |
| 85 | CONFIG_CICADA_PHY=y | 87 | CONFIG_CICADA_PHY=y |
| 86 | CONFIG_VITESSE_PHY=y | 88 | CONFIG_VITESSE_PHY=y |
| 87 | CONFIG_FIXED_PHY=y | 89 | CONFIG_FIXED_PHY=y |
| 88 | CONFIG_NET_ETHERNET=y | ||
| 89 | CONFIG_FS_ENET=y | ||
| 90 | CONFIG_E1000E=y | ||
| 91 | CONFIG_FSL_PQ_MDIO=y | ||
| 92 | CONFIG_INPUT_FF_MEMLESS=m | 90 | CONFIG_INPUT_FF_MEMLESS=m |
| 93 | # CONFIG_INPUT_MOUSEDEV is not set | 91 | # CONFIG_INPUT_MOUSEDEV is not set |
| 94 | # CONFIG_INPUT_KEYBOARD is not set | 92 | # CONFIG_INPUT_KEYBOARD is not set |
| @@ -98,16 +96,15 @@ CONFIG_SERIAL_8250=y | |||
| 98 | CONFIG_SERIAL_8250_CONSOLE=y | 96 | CONFIG_SERIAL_8250_CONSOLE=y |
| 99 | CONFIG_SERIAL_8250_NR_UARTS=2 | 97 | CONFIG_SERIAL_8250_NR_UARTS=2 |
| 100 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | 98 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 |
| 101 | CONFIG_SERIAL_8250_EXTENDED=y | ||
| 102 | CONFIG_SERIAL_8250_MANY_PORTS=y | 99 | CONFIG_SERIAL_8250_MANY_PORTS=y |
| 103 | CONFIG_SERIAL_8250_DETECT_IRQ=y | 100 | CONFIG_SERIAL_8250_DETECT_IRQ=y |
| 104 | CONFIG_SERIAL_8250_RSA=y | 101 | CONFIG_SERIAL_8250_RSA=y |
| 105 | CONFIG_SERIAL_QE=m | 102 | CONFIG_SERIAL_QE=m |
| 106 | CONFIG_HW_RANDOM=y | ||
| 107 | CONFIG_NVRAM=y | 103 | CONFIG_NVRAM=y |
| 108 | CONFIG_I2C=y | 104 | CONFIG_I2C=y |
| 109 | CONFIG_I2C_CPM=m | 105 | CONFIG_I2C_CPM=m |
| 110 | CONFIG_I2C_MPC=y | 106 | CONFIG_I2C_MPC=y |
| 107 | CONFIG_GPIO_MPC8XXX=y | ||
| 111 | # CONFIG_HWMON is not set | 108 | # CONFIG_HWMON is not set |
| 112 | CONFIG_VIDEO_OUTPUT_CONTROL=y | 109 | CONFIG_VIDEO_OUTPUT_CONTROL=y |
| 113 | CONFIG_SOUND=y | 110 | CONFIG_SOUND=y |
| @@ -123,7 +120,6 @@ CONFIG_DMADEVICES=y | |||
| 123 | CONFIG_FSL_DMA=y | 120 | CONFIG_FSL_DMA=y |
| 124 | # CONFIG_NET_DMA is not set | 121 | # CONFIG_NET_DMA is not set |
| 125 | CONFIG_STAGING=y | 122 | CONFIG_STAGING=y |
| 126 | # CONFIG_STAGING_EXCLUDE_BUILD is not set | ||
| 127 | CONFIG_EXT2_FS=y | 123 | CONFIG_EXT2_FS=y |
| 128 | CONFIG_EXT3_FS=y | 124 | CONFIG_EXT3_FS=y |
| 129 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 125 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| @@ -150,22 +146,15 @@ CONFIG_QNX4FS_FS=m | |||
| 150 | CONFIG_SYSV_FS=m | 146 | CONFIG_SYSV_FS=m |
| 151 | CONFIG_UFS_FS=m | 147 | CONFIG_UFS_FS=m |
| 152 | CONFIG_NFS_FS=y | 148 | CONFIG_NFS_FS=y |
| 153 | CONFIG_NFS_V3=y | ||
| 154 | CONFIG_NFS_V4=y | 149 | CONFIG_NFS_V4=y |
| 155 | CONFIG_ROOT_NFS=y | 150 | CONFIG_ROOT_NFS=y |
| 156 | CONFIG_NFSD=y | 151 | CONFIG_NFSD=y |
| 157 | CONFIG_PARTITION_ADVANCED=y | ||
| 158 | CONFIG_MAC_PARTITION=y | ||
| 159 | CONFIG_CRC_T10DIF=y | 152 | CONFIG_CRC_T10DIF=y |
| 160 | CONFIG_FRAME_WARN=8092 | 153 | CONFIG_FRAME_WARN=8092 |
| 161 | CONFIG_DEBUG_FS=y | 154 | CONFIG_DEBUG_FS=y |
| 162 | CONFIG_DEBUG_KERNEL=y | ||
| 163 | CONFIG_DETECT_HUNG_TASK=y | 155 | CONFIG_DETECT_HUNG_TASK=y |
| 164 | # CONFIG_DEBUG_BUGVERBOSE is not set | 156 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 165 | CONFIG_DEBUG_INFO=y | 157 | CONFIG_DEBUG_INFO=y |
| 166 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 167 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
| 168 | CONFIG_IRQ_DOMAIN_DEBUG=y | ||
| 169 | CONFIG_CRYPTO_PCBC=m | 158 | CONFIG_CRYPTO_PCBC=m |
| 170 | CONFIG_CRYPTO_SHA256=y | 159 | CONFIG_CRYPTO_SHA256=y |
| 171 | CONFIG_CRYPTO_SHA512=y | 160 | CONFIG_CRYPTO_SHA512=y |
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index cbb98c1234fd..8b3d57c1ebe8 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig | |||
| @@ -6,8 +6,8 @@ CONFIG_SYSVIPC=y | |||
| 6 | CONFIG_POSIX_MQUEUE=y | 6 | CONFIG_POSIX_MQUEUE=y |
| 7 | CONFIG_BSD_PROCESS_ACCT=y | 7 | CONFIG_BSD_PROCESS_ACCT=y |
| 8 | CONFIG_AUDIT=y | 8 | CONFIG_AUDIT=y |
| 9 | CONFIG_SPARSE_IRQ=y | 9 | CONFIG_NO_HZ=y |
| 10 | CONFIG_RCU_TRACE=y | 10 | CONFIG_HIGH_RES_TIMERS=y |
| 11 | CONFIG_IKCONFIG=y | 11 | CONFIG_IKCONFIG=y |
| 12 | CONFIG_IKCONFIG_PROC=y | 12 | CONFIG_IKCONFIG_PROC=y |
| 13 | CONFIG_LOG_BUF_SHIFT=14 | 13 | CONFIG_LOG_BUF_SHIFT=14 |
| @@ -21,23 +21,22 @@ CONFIG_MODULE_UNLOAD=y | |||
| 21 | CONFIG_MODULE_FORCE_UNLOAD=y | 21 | CONFIG_MODULE_FORCE_UNLOAD=y |
| 22 | CONFIG_MODVERSIONS=y | 22 | CONFIG_MODVERSIONS=y |
| 23 | # CONFIG_BLK_DEV_BSG is not set | 23 | # CONFIG_BLK_DEV_BSG is not set |
| 24 | CONFIG_PARTITION_ADVANCED=y | ||
| 25 | CONFIG_MAC_PARTITION=y | ||
| 24 | CONFIG_P2041_RDB=y | 26 | CONFIG_P2041_RDB=y |
| 25 | CONFIG_P3041_DS=y | 27 | CONFIG_P3041_DS=y |
| 26 | CONFIG_P4080_DS=y | 28 | CONFIG_P4080_DS=y |
| 27 | CONFIG_P5020_DS=y | 29 | CONFIG_P5020_DS=y |
| 28 | CONFIG_HIGHMEM=y | 30 | CONFIG_HIGHMEM=y |
| 29 | CONFIG_NO_HZ=y | ||
| 30 | CONFIG_HIGH_RES_TIMERS=y | ||
| 31 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 31 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 32 | CONFIG_BINFMT_MISC=m | 32 | CONFIG_BINFMT_MISC=m |
| 33 | CONFIG_KEXEC=y | 33 | CONFIG_KEXEC=y |
| 34 | CONFIG_IRQ_ALL_CPUS=y | 34 | CONFIG_IRQ_ALL_CPUS=y |
| 35 | CONFIG_FORCE_MAX_ZONEORDER=13 | 35 | CONFIG_FORCE_MAX_ZONEORDER=13 |
| 36 | CONFIG_FSL_LBC=y | ||
| 37 | CONFIG_PCI=y | 36 | CONFIG_PCI=y |
| 38 | CONFIG_PCIEPORTBUS=y | 37 | CONFIG_PCIEPORTBUS=y |
| 39 | CONFIG_PCI_MSI=y | ||
| 40 | # CONFIG_PCIEASPM is not set | 38 | # CONFIG_PCIEASPM is not set |
| 39 | CONFIG_PCI_MSI=y | ||
| 41 | CONFIG_RAPIDIO=y | 40 | CONFIG_RAPIDIO=y |
| 42 | CONFIG_FSL_RIO=y | 41 | CONFIG_FSL_RIO=y |
| 43 | CONFIG_NET=y | 42 | CONFIG_NET=y |
| @@ -70,6 +69,7 @@ CONFIG_INET_IPCOMP=y | |||
| 70 | CONFIG_IPV6=y | 69 | CONFIG_IPV6=y |
| 71 | CONFIG_IP_SCTP=m | 70 | CONFIG_IP_SCTP=m |
| 72 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 71 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 72 | CONFIG_DEVTMPFS=y | ||
| 73 | CONFIG_MTD=y | 73 | CONFIG_MTD=y |
| 74 | CONFIG_MTD_CMDLINE_PARTS=y | 74 | CONFIG_MTD_CMDLINE_PARTS=y |
| 75 | CONFIG_MTD_CHAR=y | 75 | CONFIG_MTD_CHAR=y |
| @@ -77,17 +77,14 @@ CONFIG_MTD_BLOCK=y | |||
| 77 | CONFIG_MTD_CFI=y | 77 | CONFIG_MTD_CFI=y |
| 78 | CONFIG_MTD_CFI_AMDSTD=y | 78 | CONFIG_MTD_CFI_AMDSTD=y |
| 79 | CONFIG_MTD_PHYSMAP_OF=y | 79 | CONFIG_MTD_PHYSMAP_OF=y |
| 80 | CONFIG_MTD_M25P80=y | ||
| 80 | CONFIG_MTD_NAND=y | 81 | CONFIG_MTD_NAND=y |
| 81 | CONFIG_MTD_NAND_ECC=y | ||
| 82 | CONFIG_MTD_NAND_IDS=y | ||
| 83 | CONFIG_MTD_NAND_FSL_IFC=y | ||
| 84 | CONFIG_MTD_NAND_FSL_ELBC=y | 82 | CONFIG_MTD_NAND_FSL_ELBC=y |
| 85 | CONFIG_MTD_M25P80=y | 83 | CONFIG_MTD_NAND_FSL_IFC=y |
| 86 | CONFIG_PROC_DEVICETREE=y | 84 | CONFIG_PROC_DEVICETREE=y |
| 87 | CONFIG_BLK_DEV_LOOP=y | 85 | CONFIG_BLK_DEV_LOOP=y |
| 88 | CONFIG_BLK_DEV_RAM=y | 86 | CONFIG_BLK_DEV_RAM=y |
| 89 | CONFIG_BLK_DEV_RAM_SIZE=131072 | 87 | CONFIG_BLK_DEV_RAM_SIZE=131072 |
| 90 | CONFIG_MISC_DEVICES=y | ||
| 91 | CONFIG_BLK_DEV_SD=y | 88 | CONFIG_BLK_DEV_SD=y |
| 92 | CONFIG_CHR_DEV_ST=y | 89 | CONFIG_CHR_DEV_ST=y |
| 93 | CONFIG_BLK_DEV_SR=y | 90 | CONFIG_BLK_DEV_SR=y |
| @@ -115,11 +112,9 @@ CONFIG_SERIO_LIBPS2=y | |||
| 115 | CONFIG_PPC_EPAPR_HV_BYTECHAN=y | 112 | CONFIG_PPC_EPAPR_HV_BYTECHAN=y |
| 116 | CONFIG_SERIAL_8250=y | 113 | CONFIG_SERIAL_8250=y |
| 117 | CONFIG_SERIAL_8250_CONSOLE=y | 114 | CONFIG_SERIAL_8250_CONSOLE=y |
| 118 | CONFIG_SERIAL_8250_EXTENDED=y | ||
| 119 | CONFIG_SERIAL_8250_MANY_PORTS=y | 115 | CONFIG_SERIAL_8250_MANY_PORTS=y |
| 120 | CONFIG_SERIAL_8250_DETECT_IRQ=y | 116 | CONFIG_SERIAL_8250_DETECT_IRQ=y |
| 121 | CONFIG_SERIAL_8250_RSA=y | 117 | CONFIG_SERIAL_8250_RSA=y |
| 122 | CONFIG_HW_RANDOM=y | ||
| 123 | CONFIG_NVRAM=y | 118 | CONFIG_NVRAM=y |
| 124 | CONFIG_I2C=y | 119 | CONFIG_I2C=y |
| 125 | CONFIG_I2C_CHARDEV=y | 120 | CONFIG_I2C_CHARDEV=y |
| @@ -132,7 +127,6 @@ CONFIG_SPI_FSL_ESPI=y | |||
| 132 | CONFIG_VIDEO_OUTPUT_CONTROL=y | 127 | CONFIG_VIDEO_OUTPUT_CONTROL=y |
| 133 | CONFIG_USB_HID=m | 128 | CONFIG_USB_HID=m |
| 134 | CONFIG_USB=y | 129 | CONFIG_USB=y |
| 135 | CONFIG_USB_DEVICEFS=y | ||
| 136 | CONFIG_USB_MON=y | 130 | CONFIG_USB_MON=y |
| 137 | CONFIG_USB_EHCI_HCD=y | 131 | CONFIG_USB_EHCI_HCD=y |
| 138 | CONFIG_USB_EHCI_FSL=y | 132 | CONFIG_USB_EHCI_FSL=y |
| @@ -142,8 +136,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y | |||
| 142 | CONFIG_USB_STORAGE=y | 136 | CONFIG_USB_STORAGE=y |
| 143 | CONFIG_MMC=y | 137 | CONFIG_MMC=y |
| 144 | CONFIG_MMC_SDHCI=y | 138 | CONFIG_MMC_SDHCI=y |
| 145 | CONFIG_MMC_SDHCI_OF=y | ||
| 146 | CONFIG_MMC_SDHCI_OF_ESDHC=y | ||
| 147 | CONFIG_EDAC=y | 139 | CONFIG_EDAC=y |
| 148 | CONFIG_EDAC_MM_EDAC=y | 140 | CONFIG_EDAC_MM_EDAC=y |
| 149 | CONFIG_EDAC_MPC85XX=y | 141 | CONFIG_EDAC_MPC85XX=y |
| @@ -170,19 +162,16 @@ CONFIG_HUGETLBFS=y | |||
| 170 | CONFIG_JFFS2_FS=y | 162 | CONFIG_JFFS2_FS=y |
| 171 | CONFIG_CRAMFS=y | 163 | CONFIG_CRAMFS=y |
| 172 | CONFIG_NFS_FS=y | 164 | CONFIG_NFS_FS=y |
| 173 | CONFIG_NFS_V3=y | ||
| 174 | CONFIG_NFS_V4=y | 165 | CONFIG_NFS_V4=y |
| 175 | CONFIG_ROOT_NFS=y | 166 | CONFIG_ROOT_NFS=y |
| 176 | CONFIG_NFSD=m | 167 | CONFIG_NFSD=m |
| 177 | CONFIG_PARTITION_ADVANCED=y | ||
| 178 | CONFIG_MAC_PARTITION=y | ||
| 179 | CONFIG_NLS_ISO8859_1=y | 168 | CONFIG_NLS_ISO8859_1=y |
| 180 | CONFIG_NLS_UTF8=m | 169 | CONFIG_NLS_UTF8=m |
| 181 | CONFIG_MAGIC_SYSRQ=y | 170 | CONFIG_MAGIC_SYSRQ=y |
| 182 | CONFIG_DEBUG_SHIRQ=y | 171 | CONFIG_DEBUG_SHIRQ=y |
| 183 | CONFIG_DETECT_HUNG_TASK=y | 172 | CONFIG_DETECT_HUNG_TASK=y |
| 184 | CONFIG_DEBUG_INFO=y | 173 | CONFIG_DEBUG_INFO=y |
| 185 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 174 | CONFIG_RCU_TRACE=y |
| 186 | CONFIG_CRYPTO_NULL=y | 175 | CONFIG_CRYPTO_NULL=y |
| 187 | CONFIG_CRYPTO_PCBC=m | 176 | CONFIG_CRYPTO_PCBC=m |
| 188 | CONFIG_CRYPTO_MD4=y | 177 | CONFIG_CRYPTO_MD4=y |
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index dd89de8b0b7f..0516e22ca3de 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig | |||
| @@ -56,6 +56,7 @@ CONFIG_INET_ESP=y | |||
| 56 | CONFIG_IPV6=y | 56 | CONFIG_IPV6=y |
| 57 | CONFIG_IP_SCTP=m | 57 | CONFIG_IP_SCTP=m |
| 58 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 58 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 59 | CONFIG_DEVTMPFS=y | ||
| 59 | CONFIG_MTD=y | 60 | CONFIG_MTD=y |
| 60 | CONFIG_MTD_CMDLINE_PARTS=y | 61 | CONFIG_MTD_CMDLINE_PARTS=y |
| 61 | CONFIG_MTD_CHAR=y | 62 | CONFIG_MTD_CHAR=y |
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 15130066e5e2..07b7f2af2dca 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | CONFIG_PPC64=y | ||
| 2 | CONFIG_ALTIVEC=y | ||
| 3 | CONFIG_SMP=y | ||
| 4 | CONFIG_NR_CPUS=4 | ||
| 1 | CONFIG_EXPERIMENTAL=y | 5 | CONFIG_EXPERIMENTAL=y |
| 2 | CONFIG_SYSVIPC=y | 6 | CONFIG_SYSVIPC=y |
| 3 | CONFIG_POSIX_MQUEUE=y | 7 | CONFIG_POSIX_MQUEUE=y |
| 4 | CONFIG_NO_HZ=y | ||
| 5 | CONFIG_HIGH_RES_TIMERS=y | ||
| 6 | CONFIG_IKCONFIG=y | 8 | CONFIG_IKCONFIG=y |
| 7 | CONFIG_IKCONFIG_PROC=y | 9 | CONFIG_IKCONFIG_PROC=y |
| 8 | CONFIG_BLK_DEV_INITRD=y | 10 | CONFIG_BLK_DEV_INITRD=y |
| @@ -13,15 +15,16 @@ CONFIG_MODULES=y | |||
| 13 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
| 14 | CONFIG_MODVERSIONS=y | 16 | CONFIG_MODVERSIONS=y |
| 15 | CONFIG_MODULE_SRCVERSION_ALL=y | 17 | CONFIG_MODULE_SRCVERSION_ALL=y |
| 16 | CONFIG_PARTITION_ADVANCED=y | 18 | # CONFIG_PPC_PSERIES is not set |
| 17 | CONFIG_MAC_PARTITION=y | ||
| 18 | CONFIG_SMP=y | ||
| 19 | CONFIG_NR_CPUS=4 | ||
| 20 | CONFIG_KEXEC=y | ||
| 21 | # CONFIG_RELOCATABLE is not set | ||
| 22 | CONFIG_CPU_FREQ=y | 19 | CONFIG_CPU_FREQ=y |
| 23 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y | 20 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y |
| 24 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 21 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
| 22 | CONFIG_CPU_FREQ_PMAC64=y | ||
| 23 | CONFIG_NO_HZ=y | ||
| 24 | CONFIG_HIGH_RES_TIMERS=y | ||
| 25 | CONFIG_KEXEC=y | ||
| 26 | CONFIG_IRQ_ALL_CPUS=y | ||
| 27 | # CONFIG_MIGRATION is not set | ||
| 25 | CONFIG_PCI_MSI=y | 28 | CONFIG_PCI_MSI=y |
| 26 | CONFIG_NET=y | 29 | CONFIG_NET=y |
| 27 | CONFIG_PACKET=y | 30 | CONFIG_PACKET=y |
| @@ -49,6 +52,7 @@ CONFIG_NF_CT_NETLINK=m | |||
| 49 | CONFIG_NF_CONNTRACK_IPV4=m | 52 | CONFIG_NF_CONNTRACK_IPV4=m |
| 50 | CONFIG_IP_NF_QUEUE=m | 53 | CONFIG_IP_NF_QUEUE=m |
| 51 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 54 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 55 | CONFIG_PROC_DEVICETREE=y | ||
| 52 | CONFIG_BLK_DEV_LOOP=y | 56 | CONFIG_BLK_DEV_LOOP=y |
| 53 | CONFIG_BLK_DEV_NBD=m | 57 | CONFIG_BLK_DEV_NBD=m |
| 54 | CONFIG_BLK_DEV_RAM=y | 58 | CONFIG_BLK_DEV_RAM=y |
| @@ -56,6 +60,8 @@ CONFIG_BLK_DEV_RAM_SIZE=65536 | |||
| 56 | CONFIG_CDROM_PKTCDVD=m | 60 | CONFIG_CDROM_PKTCDVD=m |
| 57 | CONFIG_IDE=y | 61 | CONFIG_IDE=y |
| 58 | CONFIG_BLK_DEV_IDECD=y | 62 | CONFIG_BLK_DEV_IDECD=y |
| 63 | CONFIG_BLK_DEV_IDE_PMAC=y | ||
| 64 | CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y | ||
| 59 | CONFIG_BLK_DEV_SD=y | 65 | CONFIG_BLK_DEV_SD=y |
| 60 | CONFIG_CHR_DEV_ST=y | 66 | CONFIG_CHR_DEV_ST=y |
| 61 | CONFIG_BLK_DEV_SR=y | 67 | CONFIG_BLK_DEV_SR=y |
| @@ -79,24 +85,33 @@ CONFIG_DM_CRYPT=m | |||
| 79 | CONFIG_DM_SNAPSHOT=m | 85 | CONFIG_DM_SNAPSHOT=m |
| 80 | CONFIG_DM_MIRROR=m | 86 | CONFIG_DM_MIRROR=m |
| 81 | CONFIG_DM_ZERO=m | 87 | CONFIG_DM_ZERO=m |
| 82 | CONFIG_MACINTOSH_DRIVERS=y | 88 | CONFIG_IEEE1394=y |
| 89 | CONFIG_IEEE1394_OHCI1394=y | ||
| 90 | CONFIG_IEEE1394_SBP2=m | ||
| 91 | CONFIG_IEEE1394_ETH1394=m | ||
| 92 | CONFIG_IEEE1394_RAWIO=y | ||
| 93 | CONFIG_IEEE1394_VIDEO1394=m | ||
| 94 | CONFIG_IEEE1394_DV1394=m | ||
| 95 | CONFIG_ADB_PMU=y | ||
| 96 | CONFIG_PMAC_SMU=y | ||
| 83 | CONFIG_MAC_EMUMOUSEBTN=y | 97 | CONFIG_MAC_EMUMOUSEBTN=y |
| 98 | CONFIG_THERM_PM72=y | ||
| 99 | CONFIG_WINDFARM=y | ||
| 100 | CONFIG_WINDFARM_PM81=y | ||
| 101 | CONFIG_WINDFARM_PM91=y | ||
| 102 | CONFIG_WINDFARM_PM112=y | ||
| 103 | CONFIG_WINDFARM_PM121=y | ||
| 84 | CONFIG_NETDEVICES=y | 104 | CONFIG_NETDEVICES=y |
| 85 | CONFIG_BONDING=m | ||
| 86 | CONFIG_DUMMY=m | 105 | CONFIG_DUMMY=m |
| 87 | CONFIG_MII=y | 106 | CONFIG_BONDING=m |
| 88 | CONFIG_TUN=m | 107 | CONFIG_TUN=m |
| 108 | CONFIG_NET_ETHERNET=y | ||
| 109 | CONFIG_MII=y | ||
| 110 | CONFIG_SUNGEM=y | ||
| 89 | CONFIG_ACENIC=m | 111 | CONFIG_ACENIC=m |
| 90 | CONFIG_ACENIC_OMIT_TIGON_I=y | 112 | CONFIG_ACENIC_OMIT_TIGON_I=y |
| 91 | CONFIG_TIGON3=y | ||
| 92 | CONFIG_E1000=y | 113 | CONFIG_E1000=y |
| 93 | CONFIG_SUNGEM=y | 114 | CONFIG_TIGON3=y |
| 94 | CONFIG_PPP=m | ||
| 95 | CONFIG_PPP_BSDCOMP=m | ||
| 96 | CONFIG_PPP_DEFLATE=m | ||
| 97 | CONFIG_PPPOE=m | ||
| 98 | CONFIG_PPP_ASYNC=m | ||
| 99 | CONFIG_PPP_SYNC_TTY=m | ||
| 100 | CONFIG_USB_CATC=m | 115 | CONFIG_USB_CATC=m |
| 101 | CONFIG_USB_KAWETH=m | 116 | CONFIG_USB_KAWETH=m |
| 102 | CONFIG_USB_PEGASUS=m | 117 | CONFIG_USB_PEGASUS=m |
| @@ -106,24 +121,36 @@ CONFIG_USB_USBNET=m | |||
| 106 | # CONFIG_USB_NET_NET1080 is not set | 121 | # CONFIG_USB_NET_NET1080 is not set |
| 107 | # CONFIG_USB_NET_CDC_SUBSET is not set | 122 | # CONFIG_USB_NET_CDC_SUBSET is not set |
| 108 | # CONFIG_USB_NET_ZAURUS is not set | 123 | # CONFIG_USB_NET_ZAURUS is not set |
| 124 | CONFIG_PPP=m | ||
| 125 | CONFIG_PPP_ASYNC=m | ||
| 126 | CONFIG_PPP_SYNC_TTY=m | ||
| 127 | CONFIG_PPP_DEFLATE=m | ||
| 128 | CONFIG_PPP_BSDCOMP=m | ||
| 129 | CONFIG_PPPOE=m | ||
| 109 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 130 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
| 110 | CONFIG_INPUT_JOYDEV=m | 131 | CONFIG_INPUT_JOYDEV=m |
| 111 | CONFIG_INPUT_EVDEV=y | 132 | CONFIG_INPUT_EVDEV=y |
| 133 | # CONFIG_KEYBOARD_ATKBD is not set | ||
| 112 | # CONFIG_MOUSE_PS2 is not set | 134 | # CONFIG_MOUSE_PS2 is not set |
| 135 | # CONFIG_SERIO_I8042 is not set | ||
| 113 | # CONFIG_SERIO_SERPORT is not set | 136 | # CONFIG_SERIO_SERPORT is not set |
| 114 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
| 115 | # CONFIG_HW_RANDOM is not set | 137 | # CONFIG_HW_RANDOM is not set |
| 116 | CONFIG_GEN_RTC=y | 138 | CONFIG_GEN_RTC=y |
| 117 | CONFIG_RAW_DRIVER=y | 139 | CONFIG_RAW_DRIVER=y |
| 118 | CONFIG_I2C_CHARDEV=y | 140 | CONFIG_I2C_CHARDEV=y |
| 119 | # CONFIG_HWMON is not set | 141 | # CONFIG_HWMON is not set |
| 120 | CONFIG_AGP=y | 142 | CONFIG_AGP=m |
| 121 | CONFIG_DRM=y | 143 | CONFIG_AGP_UNINORTH=m |
| 122 | CONFIG_DRM_NOUVEAU=y | ||
| 123 | CONFIG_VIDEO_OUTPUT_CONTROL=m | 144 | CONFIG_VIDEO_OUTPUT_CONTROL=m |
| 145 | CONFIG_FB=y | ||
| 124 | CONFIG_FIRMWARE_EDID=y | 146 | CONFIG_FIRMWARE_EDID=y |
| 125 | CONFIG_FB_TILEBLITTING=y | 147 | CONFIG_FB_TILEBLITTING=y |
| 148 | CONFIG_FB_OF=y | ||
| 149 | CONFIG_FB_NVIDIA=y | ||
| 150 | CONFIG_FB_NVIDIA_I2C=y | ||
| 126 | CONFIG_FB_RADEON=y | 151 | CONFIG_FB_RADEON=y |
| 152 | # CONFIG_VGA_CONSOLE is not set | ||
| 153 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
| 127 | CONFIG_LOGO=y | 154 | CONFIG_LOGO=y |
| 128 | CONFIG_SOUND=m | 155 | CONFIG_SOUND=m |
| 129 | CONFIG_SND=m | 156 | CONFIG_SND=m |
| @@ -131,7 +158,15 @@ CONFIG_SND_SEQUENCER=m | |||
| 131 | CONFIG_SND_MIXER_OSS=m | 158 | CONFIG_SND_MIXER_OSS=m |
| 132 | CONFIG_SND_PCM_OSS=m | 159 | CONFIG_SND_PCM_OSS=m |
| 133 | CONFIG_SND_SEQUENCER_OSS=y | 160 | CONFIG_SND_SEQUENCER_OSS=y |
| 161 | CONFIG_SND_POWERMAC=m | ||
| 162 | CONFIG_SND_AOA=m | ||
| 163 | CONFIG_SND_AOA_FABRIC_LAYOUT=m | ||
| 164 | CONFIG_SND_AOA_ONYX=m | ||
| 165 | CONFIG_SND_AOA_TAS=m | ||
| 166 | CONFIG_SND_AOA_TOONIE=m | ||
| 134 | CONFIG_SND_USB_AUDIO=m | 167 | CONFIG_SND_USB_AUDIO=m |
| 168 | CONFIG_HID_PID=y | ||
| 169 | CONFIG_USB_HIDDEV=y | ||
| 135 | CONFIG_HID_GYRATION=y | 170 | CONFIG_HID_GYRATION=y |
| 136 | CONFIG_LOGITECH_FF=y | 171 | CONFIG_LOGITECH_FF=y |
| 137 | CONFIG_HID_PANTHERLORD=y | 172 | CONFIG_HID_PANTHERLORD=y |
| @@ -139,12 +174,13 @@ CONFIG_HID_PETALYNX=y | |||
| 139 | CONFIG_HID_SAMSUNG=y | 174 | CONFIG_HID_SAMSUNG=y |
| 140 | CONFIG_HID_SONY=y | 175 | CONFIG_HID_SONY=y |
| 141 | CONFIG_HID_SUNPLUS=y | 176 | CONFIG_HID_SUNPLUS=y |
| 142 | CONFIG_HID_PID=y | ||
| 143 | CONFIG_USB_HIDDEV=y | ||
| 144 | CONFIG_USB=y | 177 | CONFIG_USB=y |
| 178 | CONFIG_USB_DEVICEFS=y | ||
| 145 | CONFIG_USB_MON=y | 179 | CONFIG_USB_MON=y |
| 146 | CONFIG_USB_EHCI_HCD=y | 180 | CONFIG_USB_EHCI_HCD=y |
| 181 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | ||
| 147 | CONFIG_USB_OHCI_HCD=y | 182 | CONFIG_USB_OHCI_HCD=y |
| 183 | CONFIG_USB_OHCI_HCD_PPC_OF_BE=y | ||
| 148 | CONFIG_USB_ACM=m | 184 | CONFIG_USB_ACM=m |
| 149 | CONFIG_USB_PRINTER=y | 185 | CONFIG_USB_PRINTER=y |
| 150 | CONFIG_USB_STORAGE=y | 186 | CONFIG_USB_STORAGE=y |
| @@ -208,6 +244,8 @@ CONFIG_REISERFS_FS_POSIX_ACL=y | |||
| 208 | CONFIG_REISERFS_FS_SECURITY=y | 244 | CONFIG_REISERFS_FS_SECURITY=y |
| 209 | CONFIG_XFS_FS=m | 245 | CONFIG_XFS_FS=m |
| 210 | CONFIG_XFS_POSIX_ACL=y | 246 | CONFIG_XFS_POSIX_ACL=y |
| 247 | CONFIG_INOTIFY=y | ||
| 248 | CONFIG_AUTOFS_FS=m | ||
| 211 | CONFIG_ISO9660_FS=y | 249 | CONFIG_ISO9660_FS=y |
| 212 | CONFIG_JOLIET=y | 250 | CONFIG_JOLIET=y |
| 213 | CONFIG_ZISOFS=y | 251 | CONFIG_ZISOFS=y |
| @@ -221,12 +259,14 @@ CONFIG_HFS_FS=m | |||
| 221 | CONFIG_HFSPLUS_FS=m | 259 | CONFIG_HFSPLUS_FS=m |
| 222 | CONFIG_CRAMFS=y | 260 | CONFIG_CRAMFS=y |
| 223 | CONFIG_NFS_FS=y | 261 | CONFIG_NFS_FS=y |
| 262 | CONFIG_NFS_V3=y | ||
| 224 | CONFIG_NFS_V3_ACL=y | 263 | CONFIG_NFS_V3_ACL=y |
| 225 | CONFIG_NFS_V4=y | 264 | CONFIG_NFS_V4=y |
| 226 | CONFIG_NFSD=y | 265 | CONFIG_NFSD=y |
| 227 | CONFIG_NFSD_V3_ACL=y | 266 | CONFIG_NFSD_V3_ACL=y |
| 228 | CONFIG_NFSD_V4=y | 267 | CONFIG_NFSD_V4=y |
| 229 | CONFIG_CIFS=m | 268 | CONFIG_CIFS=m |
| 269 | CONFIG_PARTITION_ADVANCED=y | ||
| 230 | CONFIG_NLS_CODEPAGE_437=y | 270 | CONFIG_NLS_CODEPAGE_437=y |
| 231 | CONFIG_NLS_CODEPAGE_1250=y | 271 | CONFIG_NLS_CODEPAGE_1250=y |
| 232 | CONFIG_NLS_CODEPAGE_1251=y | 272 | CONFIG_NLS_CODEPAGE_1251=y |
| @@ -234,23 +274,29 @@ CONFIG_NLS_ASCII=y | |||
| 234 | CONFIG_NLS_ISO8859_1=y | 274 | CONFIG_NLS_ISO8859_1=y |
| 235 | CONFIG_NLS_ISO8859_15=y | 275 | CONFIG_NLS_ISO8859_15=y |
| 236 | CONFIG_NLS_UTF8=y | 276 | CONFIG_NLS_UTF8=y |
| 277 | CONFIG_CRC_T10DIF=y | ||
| 278 | CONFIG_LIBCRC32C=m | ||
| 237 | CONFIG_MAGIC_SYSRQ=y | 279 | CONFIG_MAGIC_SYSRQ=y |
| 238 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 239 | CONFIG_DEBUG_FS=y | 280 | CONFIG_DEBUG_FS=y |
| 240 | CONFIG_DEBUG_KERNEL=y | 281 | CONFIG_DEBUG_KERNEL=y |
| 241 | CONFIG_DEBUG_MUTEXES=y | 282 | CONFIG_DEBUG_MUTEXES=y |
| 283 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 242 | CONFIG_LATENCYTOP=y | 284 | CONFIG_LATENCYTOP=y |
| 243 | CONFIG_STRICT_DEVMEM=y | 285 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
| 286 | CONFIG_BOOTX_TEXT=y | ||
| 244 | CONFIG_CRYPTO_NULL=m | 287 | CONFIG_CRYPTO_NULL=m |
| 245 | CONFIG_CRYPTO_TEST=m | 288 | CONFIG_CRYPTO_TEST=m |
| 289 | CONFIG_CRYPTO_ECB=m | ||
| 246 | CONFIG_CRYPTO_PCBC=m | 290 | CONFIG_CRYPTO_PCBC=m |
| 247 | CONFIG_CRYPTO_HMAC=y | 291 | CONFIG_CRYPTO_HMAC=y |
| 292 | CONFIG_CRYPTO_MD4=m | ||
| 248 | CONFIG_CRYPTO_MICHAEL_MIC=m | 293 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 249 | CONFIG_CRYPTO_SHA256=m | 294 | CONFIG_CRYPTO_SHA256=m |
| 250 | CONFIG_CRYPTO_SHA512=m | 295 | CONFIG_CRYPTO_SHA512=m |
| 251 | CONFIG_CRYPTO_WP512=m | 296 | CONFIG_CRYPTO_WP512=m |
| 252 | CONFIG_CRYPTO_AES=m | 297 | CONFIG_CRYPTO_AES=m |
| 253 | CONFIG_CRYPTO_ANUBIS=m | 298 | CONFIG_CRYPTO_ANUBIS=m |
| 299 | CONFIG_CRYPTO_ARC4=m | ||
| 254 | CONFIG_CRYPTO_BLOWFISH=m | 300 | CONFIG_CRYPTO_BLOWFISH=m |
| 255 | CONFIG_CRYPTO_CAST5=m | 301 | CONFIG_CRYPTO_CAST5=m |
| 256 | CONFIG_CRYPTO_CAST6=m | 302 | CONFIG_CRYPTO_CAST6=m |
| @@ -260,6 +306,3 @@ CONFIG_CRYPTO_TEA=m | |||
| 260 | CONFIG_CRYPTO_TWOFISH=m | 306 | CONFIG_CRYPTO_TWOFISH=m |
| 261 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 307 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 262 | # CONFIG_CRYPTO_HW is not set | 308 | # CONFIG_CRYPTO_HW is not set |
| 263 | # CONFIG_VIRTUALIZATION is not set | ||
| 264 | CONFIG_CRC_T10DIF=y | ||
| 265 | CONFIG_LIBCRC32C=m | ||
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig index 5aac9a8bc53b..9352e4430c3b 100644 --- a/arch/powerpc/configs/mpc83xx_defconfig +++ b/arch/powerpc/configs/mpc83xx_defconfig | |||
| @@ -2,12 +2,12 @@ CONFIG_EXPERIMENTAL=y | |||
| 2 | CONFIG_SYSVIPC=y | 2 | CONFIG_SYSVIPC=y |
| 3 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
| 4 | CONFIG_BLK_DEV_INITRD=y | 4 | CONFIG_BLK_DEV_INITRD=y |
| 5 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 6 | CONFIG_EXPERT=y | 5 | CONFIG_EXPERT=y |
| 7 | CONFIG_SLAB=y | 6 | CONFIG_SLAB=y |
| 8 | CONFIG_MODULES=y | 7 | CONFIG_MODULES=y |
| 9 | CONFIG_MODULE_UNLOAD=y | 8 | CONFIG_MODULE_UNLOAD=y |
| 10 | # CONFIG_BLK_DEV_BSG is not set | 9 | # CONFIG_BLK_DEV_BSG is not set |
| 10 | CONFIG_PARTITION_ADVANCED=y | ||
| 11 | # CONFIG_PPC_CHRP is not set | 11 | # CONFIG_PPC_CHRP is not set |
| 12 | # CONFIG_PPC_PMAC is not set | 12 | # CONFIG_PPC_PMAC is not set |
| 13 | CONFIG_PPC_83xx=y | 13 | CONFIG_PPC_83xx=y |
| @@ -25,7 +25,6 @@ CONFIG_ASP834x=y | |||
| 25 | CONFIG_QUICC_ENGINE=y | 25 | CONFIG_QUICC_ENGINE=y |
| 26 | CONFIG_QE_GPIO=y | 26 | CONFIG_QE_GPIO=y |
| 27 | CONFIG_MATH_EMULATION=y | 27 | CONFIG_MATH_EMULATION=y |
| 28 | CONFIG_SPARSE_IRQ=y | ||
| 29 | CONFIG_PCI=y | 28 | CONFIG_PCI=y |
| 30 | CONFIG_NET=y | 29 | CONFIG_NET=y |
| 31 | CONFIG_PACKET=y | 30 | CONFIG_PACKET=y |
| @@ -42,10 +41,9 @@ CONFIG_INET_ESP=y | |||
| 42 | # CONFIG_INET_LRO is not set | 41 | # CONFIG_INET_LRO is not set |
| 43 | # CONFIG_IPV6 is not set | 42 | # CONFIG_IPV6 is not set |
| 44 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 44 | CONFIG_DEVTMPFS=y | ||
| 45 | # CONFIG_FW_LOADER is not set | 45 | # CONFIG_FW_LOADER is not set |
| 46 | CONFIG_MTD=y | 46 | CONFIG_MTD=y |
| 47 | CONFIG_MTD_PARTITIONS=y | ||
| 48 | CONFIG_MTD_OF_PARTS=y | ||
| 49 | CONFIG_MTD_CHAR=y | 47 | CONFIG_MTD_CHAR=y |
| 50 | CONFIG_MTD_BLOCK=y | 48 | CONFIG_MTD_BLOCK=y |
| 51 | CONFIG_MTD_CFI=y | 49 | CONFIG_MTD_CFI=y |
| @@ -64,15 +62,14 @@ CONFIG_ATA=y | |||
| 64 | CONFIG_SATA_FSL=y | 62 | CONFIG_SATA_FSL=y |
| 65 | CONFIG_SATA_SIL=y | 63 | CONFIG_SATA_SIL=y |
| 66 | CONFIG_NETDEVICES=y | 64 | CONFIG_NETDEVICES=y |
| 65 | CONFIG_MII=y | ||
| 66 | CONFIG_UCC_GETH=y | ||
| 67 | CONFIG_GIANFAR=y | ||
| 67 | CONFIG_MARVELL_PHY=y | 68 | CONFIG_MARVELL_PHY=y |
| 68 | CONFIG_DAVICOM_PHY=y | 69 | CONFIG_DAVICOM_PHY=y |
| 69 | CONFIG_VITESSE_PHY=y | 70 | CONFIG_VITESSE_PHY=y |
| 70 | CONFIG_ICPLUS_PHY=y | 71 | CONFIG_ICPLUS_PHY=y |
| 71 | CONFIG_FIXED_PHY=y | 72 | CONFIG_FIXED_PHY=y |
| 72 | CONFIG_NET_ETHERNET=y | ||
| 73 | CONFIG_MII=y | ||
| 74 | CONFIG_GIANFAR=y | ||
| 75 | CONFIG_UCC_GETH=y | ||
| 76 | CONFIG_INPUT_FF_MEMLESS=m | 73 | CONFIG_INPUT_FF_MEMLESS=m |
| 77 | # CONFIG_INPUT_MOUSEDEV is not set | 74 | # CONFIG_INPUT_MOUSEDEV is not set |
| 78 | # CONFIG_INPUT_KEYBOARD is not set | 75 | # CONFIG_INPUT_KEYBOARD is not set |
| @@ -112,17 +109,12 @@ CONFIG_RTC_DRV_DS1374=y | |||
| 112 | CONFIG_EXT2_FS=y | 109 | CONFIG_EXT2_FS=y |
| 113 | CONFIG_EXT3_FS=y | 110 | CONFIG_EXT3_FS=y |
| 114 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 111 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 115 | CONFIG_INOTIFY=y | ||
| 116 | CONFIG_PROC_KCORE=y | 112 | CONFIG_PROC_KCORE=y |
| 117 | CONFIG_TMPFS=y | 113 | CONFIG_TMPFS=y |
| 118 | CONFIG_NFS_FS=y | 114 | CONFIG_NFS_FS=y |
| 119 | CONFIG_NFS_V3=y | ||
| 120 | CONFIG_NFS_V4=y | 115 | CONFIG_NFS_V4=y |
| 121 | CONFIG_ROOT_NFS=y | 116 | CONFIG_ROOT_NFS=y |
| 122 | CONFIG_PARTITION_ADVANCED=y | ||
| 123 | CONFIG_CRC_T10DIF=y | 117 | CONFIG_CRC_T10DIF=y |
| 124 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 125 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
| 126 | CONFIG_CRYPTO_ECB=m | 118 | CONFIG_CRYPTO_ECB=m |
| 127 | CONFIG_CRYPTO_PCBC=m | 119 | CONFIG_CRYPTO_PCBC=m |
| 128 | CONFIG_CRYPTO_SHA256=y | 120 | CONFIG_CRYPTO_SHA256=y |
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 03ee911c4577..8b5bda27d248 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig | |||
| @@ -5,7 +5,9 @@ CONFIG_SYSVIPC=y | |||
| 5 | CONFIG_POSIX_MQUEUE=y | 5 | CONFIG_POSIX_MQUEUE=y |
| 6 | CONFIG_BSD_PROCESS_ACCT=y | 6 | CONFIG_BSD_PROCESS_ACCT=y |
| 7 | CONFIG_AUDIT=y | 7 | CONFIG_AUDIT=y |
| 8 | CONFIG_SPARSE_IRQ=y | 8 | CONFIG_IRQ_DOMAIN_DEBUG=y |
| 9 | CONFIG_NO_HZ=y | ||
| 10 | CONFIG_HIGH_RES_TIMERS=y | ||
| 9 | CONFIG_IKCONFIG=y | 11 | CONFIG_IKCONFIG=y |
| 10 | CONFIG_IKCONFIG_PROC=y | 12 | CONFIG_IKCONFIG_PROC=y |
| 11 | CONFIG_LOG_BUF_SHIFT=14 | 13 | CONFIG_LOG_BUF_SHIFT=14 |
| @@ -17,6 +19,8 @@ CONFIG_MODULE_UNLOAD=y | |||
| 17 | CONFIG_MODULE_FORCE_UNLOAD=y | 19 | CONFIG_MODULE_FORCE_UNLOAD=y |
| 18 | CONFIG_MODVERSIONS=y | 20 | CONFIG_MODVERSIONS=y |
| 19 | # CONFIG_BLK_DEV_BSG is not set | 21 | # CONFIG_BLK_DEV_BSG is not set |
| 22 | CONFIG_PARTITION_ADVANCED=y | ||
| 23 | CONFIG_MAC_PARTITION=y | ||
| 20 | CONFIG_MPC8540_ADS=y | 24 | CONFIG_MPC8540_ADS=y |
| 21 | CONFIG_MPC8560_ADS=y | 25 | CONFIG_MPC8560_ADS=y |
| 22 | CONFIG_MPC85xx_CDS=y | 26 | CONFIG_MPC85xx_CDS=y |
| @@ -40,8 +44,6 @@ CONFIG_SBC8548=y | |||
| 40 | CONFIG_QUICC_ENGINE=y | 44 | CONFIG_QUICC_ENGINE=y |
| 41 | CONFIG_QE_GPIO=y | 45 | CONFIG_QE_GPIO=y |
| 42 | CONFIG_HIGHMEM=y | 46 | CONFIG_HIGHMEM=y |
| 43 | CONFIG_NO_HZ=y | ||
| 44 | CONFIG_HIGH_RES_TIMERS=y | ||
| 45 | CONFIG_BINFMT_MISC=m | 47 | CONFIG_BINFMT_MISC=m |
| 46 | CONFIG_MATH_EMULATION=y | 48 | CONFIG_MATH_EMULATION=y |
| 47 | CONFIG_FORCE_MAX_ZONEORDER=12 | 49 | CONFIG_FORCE_MAX_ZONEORDER=12 |
| @@ -74,36 +76,25 @@ CONFIG_INET_ESP=y | |||
| 74 | CONFIG_IPV6=y | 76 | CONFIG_IPV6=y |
| 75 | CONFIG_IP_SCTP=m | 77 | CONFIG_IP_SCTP=m |
| 76 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 78 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 79 | CONFIG_DEVTMPFS=y | ||
| 77 | CONFIG_MTD=y | 80 | CONFIG_MTD=y |
| 78 | CONFIG_MTD_CMDLINE_PARTS=y | 81 | CONFIG_MTD_CMDLINE_PARTS=y |
| 79 | CONFIG_MTD_CHAR=y | 82 | CONFIG_MTD_CHAR=y |
| 80 | CONFIG_MTD_BLOCK=y | 83 | CONFIG_MTD_BLOCK=y |
| 81 | CONFIG_MTD_CFI=y | ||
| 82 | CONFIG_FTL=y | 84 | CONFIG_FTL=y |
| 83 | CONFIG_MTD_GEN_PROBE=y | 85 | CONFIG_MTD_CFI=y |
| 84 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 85 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 86 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 87 | CONFIG_MTD_CFI_I1=y | ||
| 88 | CONFIG_MTD_CFI_I2=y | ||
| 89 | CONFIG_MTD_CFI_INTELEXT=y | 86 | CONFIG_MTD_CFI_INTELEXT=y |
| 90 | CONFIG_MTD_CFI_AMDSTD=y | 87 | CONFIG_MTD_CFI_AMDSTD=y |
| 91 | CONFIG_MTD_CFI_UTIL=y | ||
| 92 | CONFIG_MTD_PHYSMAP_OF=y | 88 | CONFIG_MTD_PHYSMAP_OF=y |
| 93 | CONFIG_MTD_PARTITIONS=y | 89 | CONFIG_MTD_M25P80=y |
| 94 | CONFIG_MTD_OF_PARTS=y | ||
| 95 | CONFIG_MTD_NAND=y | 90 | CONFIG_MTD_NAND=y |
| 96 | CONFIG_MTD_NAND_FSL_ELBC=y | 91 | CONFIG_MTD_NAND_FSL_ELBC=y |
| 97 | CONFIG_MTD_NAND_FSL_IFC=y | 92 | CONFIG_MTD_NAND_FSL_IFC=y |
| 98 | CONFIG_MTD_NAND_IDS=y | ||
| 99 | CONFIG_MTD_NAND_ECC=y | ||
| 100 | CONFIG_MTD_M25P80=y | ||
| 101 | CONFIG_PROC_DEVICETREE=y | 93 | CONFIG_PROC_DEVICETREE=y |
| 102 | CONFIG_BLK_DEV_LOOP=y | 94 | CONFIG_BLK_DEV_LOOP=y |
| 103 | CONFIG_BLK_DEV_NBD=y | 95 | CONFIG_BLK_DEV_NBD=y |
| 104 | CONFIG_BLK_DEV_RAM=y | 96 | CONFIG_BLK_DEV_RAM=y |
| 105 | CONFIG_BLK_DEV_RAM_SIZE=131072 | 97 | CONFIG_BLK_DEV_RAM_SIZE=131072 |
| 106 | CONFIG_MISC_DEVICES=y | ||
| 107 | CONFIG_EEPROM_LEGACY=y | 98 | CONFIG_EEPROM_LEGACY=y |
| 108 | CONFIG_BLK_DEV_SD=y | 99 | CONFIG_BLK_DEV_SD=y |
| 109 | CONFIG_CHR_DEV_ST=y | 100 | CONFIG_CHR_DEV_ST=y |
| @@ -115,6 +106,7 @@ CONFIG_ATA=y | |||
| 115 | CONFIG_SATA_AHCI=y | 106 | CONFIG_SATA_AHCI=y |
| 116 | CONFIG_SATA_FSL=y | 107 | CONFIG_SATA_FSL=y |
| 117 | CONFIG_PATA_ALI=y | 108 | CONFIG_PATA_ALI=y |
| 109 | CONFIG_PATA_VIA=y | ||
| 118 | CONFIG_NETDEVICES=y | 110 | CONFIG_NETDEVICES=y |
| 119 | CONFIG_DUMMY=y | 111 | CONFIG_DUMMY=y |
| 120 | CONFIG_FS_ENET=y | 112 | CONFIG_FS_ENET=y |
| @@ -134,7 +126,6 @@ CONFIG_SERIAL_8250=y | |||
| 134 | CONFIG_SERIAL_8250_CONSOLE=y | 126 | CONFIG_SERIAL_8250_CONSOLE=y |
| 135 | CONFIG_SERIAL_8250_NR_UARTS=2 | 127 | CONFIG_SERIAL_8250_NR_UARTS=2 |
| 136 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | 128 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 |
| 137 | CONFIG_SERIAL_8250_EXTENDED=y | ||
| 138 | CONFIG_SERIAL_8250_MANY_PORTS=y | 129 | CONFIG_SERIAL_8250_MANY_PORTS=y |
| 139 | CONFIG_SERIAL_8250_DETECT_IRQ=y | 130 | CONFIG_SERIAL_8250_DETECT_IRQ=y |
| 140 | CONFIG_SERIAL_8250_RSA=y | 131 | CONFIG_SERIAL_8250_RSA=y |
| @@ -183,7 +174,6 @@ CONFIG_HID_SAMSUNG=y | |||
| 183 | CONFIG_HID_SONY=y | 174 | CONFIG_HID_SONY=y |
| 184 | CONFIG_HID_SUNPLUS=y | 175 | CONFIG_HID_SUNPLUS=y |
| 185 | CONFIG_USB=y | 176 | CONFIG_USB=y |
| 186 | CONFIG_USB_DEVICEFS=y | ||
| 187 | CONFIG_USB_MON=y | 177 | CONFIG_USB_MON=y |
| 188 | CONFIG_USB_EHCI_HCD=y | 178 | CONFIG_USB_EHCI_HCD=y |
| 189 | CONFIG_USB_EHCI_FSL=y | 179 | CONFIG_USB_EHCI_FSL=y |
| @@ -229,18 +219,13 @@ CONFIG_QNX4FS_FS=m | |||
| 229 | CONFIG_SYSV_FS=m | 219 | CONFIG_SYSV_FS=m |
| 230 | CONFIG_UFS_FS=m | 220 | CONFIG_UFS_FS=m |
| 231 | CONFIG_NFS_FS=y | 221 | CONFIG_NFS_FS=y |
| 232 | CONFIG_NFS_V3=y | ||
| 233 | CONFIG_NFS_V4=y | 222 | CONFIG_NFS_V4=y |
| 234 | CONFIG_ROOT_NFS=y | 223 | CONFIG_ROOT_NFS=y |
| 235 | CONFIG_NFSD=y | 224 | CONFIG_NFSD=y |
| 236 | CONFIG_PARTITION_ADVANCED=y | ||
| 237 | CONFIG_MAC_PARTITION=y | ||
| 238 | CONFIG_CRC_T10DIF=y | 225 | CONFIG_CRC_T10DIF=y |
| 239 | CONFIG_DEBUG_FS=y | 226 | CONFIG_DEBUG_FS=y |
| 240 | CONFIG_DETECT_HUNG_TASK=y | 227 | CONFIG_DETECT_HUNG_TASK=y |
| 241 | CONFIG_DEBUG_INFO=y | 228 | CONFIG_DEBUG_INFO=y |
| 242 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
| 243 | CONFIG_IRQ_DOMAIN_DEBUG=y | ||
| 244 | CONFIG_CRYPTO_PCBC=m | 229 | CONFIG_CRYPTO_PCBC=m |
| 245 | CONFIG_CRYPTO_SHA256=y | 230 | CONFIG_CRYPTO_SHA256=y |
| 246 | CONFIG_CRYPTO_SHA512=y | 231 | CONFIG_CRYPTO_SHA512=y |
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index fdfa84dc908f..b0974e7e98ae 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig | |||
| @@ -7,7 +7,9 @@ CONFIG_SYSVIPC=y | |||
| 7 | CONFIG_POSIX_MQUEUE=y | 7 | CONFIG_POSIX_MQUEUE=y |
| 8 | CONFIG_BSD_PROCESS_ACCT=y | 8 | CONFIG_BSD_PROCESS_ACCT=y |
| 9 | CONFIG_AUDIT=y | 9 | CONFIG_AUDIT=y |
| 10 | CONFIG_SPARSE_IRQ=y | 10 | CONFIG_IRQ_DOMAIN_DEBUG=y |
| 11 | CONFIG_NO_HZ=y | ||
| 12 | CONFIG_HIGH_RES_TIMERS=y | ||
| 11 | CONFIG_IKCONFIG=y | 13 | CONFIG_IKCONFIG=y |
| 12 | CONFIG_IKCONFIG_PROC=y | 14 | CONFIG_IKCONFIG_PROC=y |
| 13 | CONFIG_LOG_BUF_SHIFT=14 | 15 | CONFIG_LOG_BUF_SHIFT=14 |
| @@ -19,6 +21,8 @@ CONFIG_MODULE_UNLOAD=y | |||
| 19 | CONFIG_MODULE_FORCE_UNLOAD=y | 21 | CONFIG_MODULE_FORCE_UNLOAD=y |
| 20 | CONFIG_MODVERSIONS=y | 22 | CONFIG_MODVERSIONS=y |
| 21 | # CONFIG_BLK_DEV_BSG is not set | 23 | # CONFIG_BLK_DEV_BSG is not set |
| 24 | CONFIG_PARTITION_ADVANCED=y | ||
| 25 | CONFIG_MAC_PARTITION=y | ||
| 22 | CONFIG_MPC8540_ADS=y | 26 | CONFIG_MPC8540_ADS=y |
| 23 | CONFIG_MPC8560_ADS=y | 27 | CONFIG_MPC8560_ADS=y |
| 24 | CONFIG_MPC85xx_CDS=y | 28 | CONFIG_MPC85xx_CDS=y |
| @@ -42,8 +46,6 @@ CONFIG_SBC8548=y | |||
| 42 | CONFIG_QUICC_ENGINE=y | 46 | CONFIG_QUICC_ENGINE=y |
| 43 | CONFIG_QE_GPIO=y | 47 | CONFIG_QE_GPIO=y |
| 44 | CONFIG_HIGHMEM=y | 48 | CONFIG_HIGHMEM=y |
| 45 | CONFIG_NO_HZ=y | ||
| 46 | CONFIG_HIGH_RES_TIMERS=y | ||
| 47 | CONFIG_BINFMT_MISC=m | 49 | CONFIG_BINFMT_MISC=m |
| 48 | CONFIG_MATH_EMULATION=y | 50 | CONFIG_MATH_EMULATION=y |
| 49 | CONFIG_IRQ_ALL_CPUS=y | 51 | CONFIG_IRQ_ALL_CPUS=y |
| @@ -77,36 +79,25 @@ CONFIG_INET_ESP=y | |||
| 77 | CONFIG_IPV6=y | 79 | CONFIG_IPV6=y |
| 78 | CONFIG_IP_SCTP=m | 80 | CONFIG_IP_SCTP=m |
| 79 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 81 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 82 | CONFIG_DEVTMPFS=y | ||
| 80 | CONFIG_MTD=y | 83 | CONFIG_MTD=y |
| 81 | CONFIG_MTD_CMDLINE_PARTS=y | 84 | CONFIG_MTD_CMDLINE_PARTS=y |
| 82 | CONFIG_MTD_CHAR=y | 85 | CONFIG_MTD_CHAR=y |
| 83 | CONFIG_MTD_BLOCK=y | 86 | CONFIG_MTD_BLOCK=y |
| 84 | CONFIG_MTD_CFI=y | ||
| 85 | CONFIG_FTL=y | 87 | CONFIG_FTL=y |
| 86 | CONFIG_MTD_GEN_PROBE=y | 88 | CONFIG_MTD_CFI=y |
| 87 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 88 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 89 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 90 | CONFIG_MTD_CFI_I1=y | ||
| 91 | CONFIG_MTD_CFI_I2=y | ||
| 92 | CONFIG_MTD_CFI_INTELEXT=y | 89 | CONFIG_MTD_CFI_INTELEXT=y |
| 93 | CONFIG_MTD_CFI_AMDSTD=y | 90 | CONFIG_MTD_CFI_AMDSTD=y |
| 94 | CONFIG_MTD_CFI_UTIL=y | ||
| 95 | CONFIG_MTD_PHYSMAP_OF=y | 91 | CONFIG_MTD_PHYSMAP_OF=y |
| 96 | CONFIG_MTD_PARTITIONS=y | 92 | CONFIG_MTD_M25P80=y |
| 97 | CONFIG_MTD_OF_PARTS=y | ||
| 98 | CONFIG_MTD_NAND=y | 93 | CONFIG_MTD_NAND=y |
| 99 | CONFIG_MTD_NAND_FSL_ELBC=y | 94 | CONFIG_MTD_NAND_FSL_ELBC=y |
| 100 | CONFIG_MTD_NAND_FSL_IFC=y | 95 | CONFIG_MTD_NAND_FSL_IFC=y |
| 101 | CONFIG_MTD_NAND_IDS=y | ||
| 102 | CONFIG_MTD_NAND_ECC=y | ||
| 103 | CONFIG_MTD_M25P80=y | ||
| 104 | CONFIG_PROC_DEVICETREE=y | 96 | CONFIG_PROC_DEVICETREE=y |
| 105 | CONFIG_BLK_DEV_LOOP=y | 97 | CONFIG_BLK_DEV_LOOP=y |
| 106 | CONFIG_BLK_DEV_NBD=y | 98 | CONFIG_BLK_DEV_NBD=y |
| 107 | CONFIG_BLK_DEV_RAM=y | 99 | CONFIG_BLK_DEV_RAM=y |
| 108 | CONFIG_BLK_DEV_RAM_SIZE=131072 | 100 | CONFIG_BLK_DEV_RAM_SIZE=131072 |
| 109 | CONFIG_MISC_DEVICES=y | ||
| 110 | CONFIG_EEPROM_LEGACY=y | 101 | CONFIG_EEPROM_LEGACY=y |
| 111 | CONFIG_BLK_DEV_SD=y | 102 | CONFIG_BLK_DEV_SD=y |
| 112 | CONFIG_CHR_DEV_ST=y | 103 | CONFIG_CHR_DEV_ST=y |
| @@ -137,7 +128,6 @@ CONFIG_SERIAL_8250=y | |||
| 137 | CONFIG_SERIAL_8250_CONSOLE=y | 128 | CONFIG_SERIAL_8250_CONSOLE=y |
| 138 | CONFIG_SERIAL_8250_NR_UARTS=2 | 129 | CONFIG_SERIAL_8250_NR_UARTS=2 |
| 139 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | 130 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 |
| 140 | CONFIG_SERIAL_8250_EXTENDED=y | ||
| 141 | CONFIG_SERIAL_8250_MANY_PORTS=y | 131 | CONFIG_SERIAL_8250_MANY_PORTS=y |
| 142 | CONFIG_SERIAL_8250_DETECT_IRQ=y | 132 | CONFIG_SERIAL_8250_DETECT_IRQ=y |
| 143 | CONFIG_SERIAL_8250_RSA=y | 133 | CONFIG_SERIAL_8250_RSA=y |
| @@ -186,7 +176,6 @@ CONFIG_HID_SAMSUNG=y | |||
| 186 | CONFIG_HID_SONY=y | 176 | CONFIG_HID_SONY=y |
| 187 | CONFIG_HID_SUNPLUS=y | 177 | CONFIG_HID_SUNPLUS=y |
| 188 | CONFIG_USB=y | 178 | CONFIG_USB=y |
| 189 | CONFIG_USB_DEVICEFS=y | ||
| 190 | CONFIG_USB_MON=y | 179 | CONFIG_USB_MON=y |
| 191 | CONFIG_USB_EHCI_HCD=y | 180 | CONFIG_USB_EHCI_HCD=y |
| 192 | CONFIG_USB_EHCI_FSL=y | 181 | CONFIG_USB_EHCI_FSL=y |
| @@ -232,18 +221,13 @@ CONFIG_QNX4FS_FS=m | |||
| 232 | CONFIG_SYSV_FS=m | 221 | CONFIG_SYSV_FS=m |
| 233 | CONFIG_UFS_FS=m | 222 | CONFIG_UFS_FS=m |
| 234 | CONFIG_NFS_FS=y | 223 | CONFIG_NFS_FS=y |
| 235 | CONFIG_NFS_V3=y | ||
| 236 | CONFIG_NFS_V4=y | 224 | CONFIG_NFS_V4=y |
| 237 | CONFIG_ROOT_NFS=y | 225 | CONFIG_ROOT_NFS=y |
| 238 | CONFIG_NFSD=y | 226 | CONFIG_NFSD=y |
| 239 | CONFIG_PARTITION_ADVANCED=y | ||
| 240 | CONFIG_MAC_PARTITION=y | ||
| 241 | CONFIG_CRC_T10DIF=y | 227 | CONFIG_CRC_T10DIF=y |
| 242 | CONFIG_DEBUG_FS=y | 228 | CONFIG_DEBUG_FS=y |
| 243 | CONFIG_DETECT_HUNG_TASK=y | 229 | CONFIG_DETECT_HUNG_TASK=y |
| 244 | CONFIG_DEBUG_INFO=y | 230 | CONFIG_DEBUG_INFO=y |
| 245 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
| 246 | CONFIG_IRQ_DOMAIN_DEBUG=y | ||
| 247 | CONFIG_CRYPTO_PCBC=m | 231 | CONFIG_CRYPTO_PCBC=m |
| 248 | CONFIG_CRYPTO_SHA256=y | 232 | CONFIG_CRYPTO_SHA256=y |
| 249 | CONFIG_CRYPTO_SHA512=y | 233 | CONFIG_CRYPTO_SHA512=y |
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 50d82c8a037f..b3c083de17ad 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
| @@ -553,9 +553,7 @@ static inline int cpu_has_feature(unsigned long feature) | |||
| 553 | & feature); | 553 | & feature); |
| 554 | } | 554 | } |
| 555 | 555 | ||
| 556 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 557 | #define HBP_NUM 1 | 556 | #define HBP_NUM 1 |
| 558 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 559 | 557 | ||
| 560 | #endif /* !__ASSEMBLY__ */ | 558 | #endif /* !__ASSEMBLY__ */ |
| 561 | 559 | ||
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 50ea12fd7bf5..a8bf5c673a3c 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/kvm_asm.h> | 33 | #include <asm/kvm_asm.h> |
| 34 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
| 35 | #include <asm/page.h> | 35 | #include <asm/page.h> |
| 36 | #include <asm/cacheflush.h> | ||
| 36 | 37 | ||
| 37 | #define KVM_MAX_VCPUS NR_CPUS | 38 | #define KVM_MAX_VCPUS NR_CPUS |
| 38 | #define KVM_MAX_VCORES NR_CPUS | 39 | #define KVM_MAX_VCORES NR_CPUS |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 0124937a23b9..e006f0bdea95 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
| @@ -219,4 +219,16 @@ void kvmppc_claim_lpid(long lpid); | |||
| 219 | void kvmppc_free_lpid(long lpid); | 219 | void kvmppc_free_lpid(long lpid); |
| 220 | void kvmppc_init_lpid(unsigned long nr_lpids); | 220 | void kvmppc_init_lpid(unsigned long nr_lpids); |
| 221 | 221 | ||
| 222 | static inline void kvmppc_mmu_flush_icache(pfn_t pfn) | ||
| 223 | { | ||
| 224 | /* Clear i-cache for new pages */ | ||
| 225 | struct page *page; | ||
| 226 | page = pfn_to_page(pfn); | ||
| 227 | if (!test_bit(PG_arch_1, &page->flags)) { | ||
| 228 | flush_dcache_icache_page(page); | ||
| 229 | set_bit(PG_arch_1, &page->flags); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 222 | #endif /* __POWERPC_KVM_PPC_H__ */ | 234 | #endif /* __POWERPC_KVM_PPC_H__ */ |
diff --git a/arch/powerpc/include/asm/mpic_msgr.h b/arch/powerpc/include/asm/mpic_msgr.h index 326d33ca55cd..d4f471fb1031 100644 --- a/arch/powerpc/include/asm/mpic_msgr.h +++ b/arch/powerpc/include/asm/mpic_msgr.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
| 16 | #include <asm/smp.h> | 16 | #include <asm/smp.h> |
| 17 | #include <asm/io.h> | ||
| 17 | 18 | ||
| 18 | struct mpic_msgr { | 19 | struct mpic_msgr { |
| 19 | u32 __iomem *base; | 20 | u32 __iomem *base; |
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 2d7bb8ced136..e4897523de41 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c | |||
| @@ -83,11 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask) | |||
| 83 | return 0; | 83 | return 0; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | if ((tbl->it_offset + tbl->it_size) > (mask >> IOMMU_PAGE_SHIFT)) { | 86 | if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) { |
| 87 | dev_info(dev, "Warning: IOMMU window too big for device mask\n"); | 87 | dev_info(dev, "Warning: IOMMU offset too big for device mask\n"); |
| 88 | dev_info(dev, "mask: 0x%08llx, table end: 0x%08lx\n", | 88 | dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n", |
| 89 | mask, (tbl->it_offset + tbl->it_size) << | 89 | mask, tbl->it_offset << IOMMU_PAGE_SHIFT); |
| 90 | IOMMU_PAGE_SHIFT); | ||
| 91 | return 0; | 90 | return 0; |
| 92 | } else | 91 | } else |
| 93 | return 1; | 92 | return 1; |
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index f3a82dde61db..956a4c496de9 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
| @@ -253,7 +253,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
| 253 | 253 | ||
| 254 | /* Do not emulate user-space instructions, instead single-step them */ | 254 | /* Do not emulate user-space instructions, instead single-step them */ |
| 255 | if (user_mode(regs)) { | 255 | if (user_mode(regs)) { |
| 256 | bp->ctx->task->thread.last_hit_ubp = bp; | 256 | current->thread.last_hit_ubp = bp; |
| 257 | regs->msr |= MSR_SE; | 257 | regs->msr |= MSR_SE; |
| 258 | goto out; | 258 | goto out; |
| 259 | } | 259 | } |
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 782bd0a3c2f0..c470a40b29f5 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <asm/processor.h> | 25 | #include <asm/processor.h> |
| 26 | #include <asm/machdep.h> | 26 | #include <asm/machdep.h> |
| 27 | #include <asm/debug.h> | 27 | #include <asm/debug.h> |
| 28 | #include <linux/slab.h> | ||
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * This table contains the mapping between PowerPC hardware trap types, and | 31 | * This table contains the mapping between PowerPC hardware trap types, and |
| @@ -101,6 +102,21 @@ static int computeSignal(unsigned int tt) | |||
| 101 | return SIGHUP; /* default for things we don't know about */ | 102 | return SIGHUP; /* default for things we don't know about */ |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 105 | /** | ||
| 106 | * | ||
| 107 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. | ||
| 108 | * @exception: Exception vector number | ||
| 109 | * @regs: Current &struct pt_regs. | ||
| 110 | * | ||
| 111 | * On some architectures we need to skip a breakpoint exception when | ||
| 112 | * it occurs after a breakpoint has been removed. | ||
| 113 | * | ||
| 114 | */ | ||
| 115 | int kgdb_skipexception(int exception, struct pt_regs *regs) | ||
| 116 | { | ||
| 117 | return kgdb_isremovedbreak(regs->nip); | ||
| 118 | } | ||
| 119 | |||
| 104 | static int kgdb_call_nmi_hook(struct pt_regs *regs) | 120 | static int kgdb_call_nmi_hook(struct pt_regs *regs) |
| 105 | { | 121 | { |
| 106 | kgdb_nmicallback(raw_smp_processor_id(), regs); | 122 | kgdb_nmicallback(raw_smp_processor_id(), regs); |
| @@ -138,6 +154,8 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) | |||
| 138 | static int kgdb_singlestep(struct pt_regs *regs) | 154 | static int kgdb_singlestep(struct pt_regs *regs) |
| 139 | { | 155 | { |
| 140 | struct thread_info *thread_info, *exception_thread_info; | 156 | struct thread_info *thread_info, *exception_thread_info; |
| 157 | struct thread_info *backup_current_thread_info = \ | ||
| 158 | (struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL); | ||
| 141 | 159 | ||
| 142 | if (user_mode(regs)) | 160 | if (user_mode(regs)) |
| 143 | return 0; | 161 | return 0; |
| @@ -155,13 +173,17 @@ static int kgdb_singlestep(struct pt_regs *regs) | |||
| 155 | thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1)); | 173 | thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1)); |
| 156 | exception_thread_info = current_thread_info(); | 174 | exception_thread_info = current_thread_info(); |
| 157 | 175 | ||
| 158 | if (thread_info != exception_thread_info) | 176 | if (thread_info != exception_thread_info) { |
| 177 | /* Save the original current_thread_info. */ | ||
| 178 | memcpy(backup_current_thread_info, exception_thread_info, sizeof *thread_info); | ||
| 159 | memcpy(exception_thread_info, thread_info, sizeof *thread_info); | 179 | memcpy(exception_thread_info, thread_info, sizeof *thread_info); |
| 180 | } | ||
| 160 | 181 | ||
| 161 | kgdb_handle_exception(0, SIGTRAP, 0, regs); | 182 | kgdb_handle_exception(0, SIGTRAP, 0, regs); |
| 162 | 183 | ||
| 163 | if (thread_info != exception_thread_info) | 184 | if (thread_info != exception_thread_info) |
| 164 | memcpy(thread_info, exception_thread_info, sizeof *thread_info); | 185 | /* Restore current_thread_info lastly. */ |
| 186 | memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info); | ||
| 165 | 187 | ||
| 166 | return 1; | 188 | return 1; |
| 167 | } | 189 | } |
| @@ -410,7 +432,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, | |||
| 410 | #else | 432 | #else |
| 411 | linux_regs->msr |= MSR_SE; | 433 | linux_regs->msr |= MSR_SE; |
| 412 | #endif | 434 | #endif |
| 413 | kgdb_single_step = 1; | ||
| 414 | atomic_set(&kgdb_cpu_doing_single_step, | 435 | atomic_set(&kgdb_cpu_doing_single_step, |
| 415 | raw_smp_processor_id()); | 436 | raw_smp_processor_id()); |
| 416 | } | 437 | } |
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index f2496f2faecc..4e3cc47f26b9 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c | |||
| @@ -107,11 +107,11 @@ long ppc64_personality(unsigned long personality) | |||
| 107 | long ret; | 107 | long ret; |
| 108 | 108 | ||
| 109 | if (personality(current->personality) == PER_LINUX32 | 109 | if (personality(current->personality) == PER_LINUX32 |
| 110 | && personality == PER_LINUX) | 110 | && personality(personality) == PER_LINUX) |
| 111 | personality = PER_LINUX32; | 111 | personality = (personality & ~PER_MASK) | PER_LINUX32; |
| 112 | ret = sys_personality(personality); | 112 | ret = sys_personality(personality); |
| 113 | if (ret == PER_LINUX32) | 113 | if (personality(ret) == PER_LINUX32) |
| 114 | ret = PER_LINUX; | 114 | ret = (ret & ~PER_MASK) | PER_LINUX; |
| 115 | return ret; | 115 | return ret; |
| 116 | } | 116 | } |
| 117 | #endif | 117 | #endif |
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index f922c29bb234..837f13e7b6bf 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c | |||
| @@ -211,6 +211,9 @@ next_pteg: | |||
| 211 | pteg1 |= PP_RWRX; | 211 | pteg1 |= PP_RWRX; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | if (orig_pte->may_execute) | ||
| 215 | kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); | ||
| 216 | |||
| 214 | local_irq_disable(); | 217 | local_irq_disable(); |
| 215 | 218 | ||
| 216 | if (pteg[rr]) { | 219 | if (pteg[rr]) { |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 10fc8ec9d2a8..0688b6b39585 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
| @@ -126,6 +126,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) | |||
| 126 | 126 | ||
| 127 | if (!orig_pte->may_execute) | 127 | if (!orig_pte->may_execute) |
| 128 | rflags |= HPTE_R_N; | 128 | rflags |= HPTE_R_N; |
| 129 | else | ||
| 130 | kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); | ||
| 129 | 131 | ||
| 130 | hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M); | 132 | hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M); |
| 131 | 133 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 5a84c8d3d040..44b72feaff7d 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
| @@ -1421,13 +1421,13 @@ _GLOBAL(kvmppc_h_cede) | |||
| 1421 | sync /* order setting ceded vs. testing prodded */ | 1421 | sync /* order setting ceded vs. testing prodded */ |
| 1422 | lbz r5,VCPU_PRODDED(r3) | 1422 | lbz r5,VCPU_PRODDED(r3) |
| 1423 | cmpwi r5,0 | 1423 | cmpwi r5,0 |
| 1424 | bne 1f | 1424 | bne kvm_cede_prodded |
| 1425 | li r0,0 /* set trap to 0 to say hcall is handled */ | 1425 | li r0,0 /* set trap to 0 to say hcall is handled */ |
| 1426 | stw r0,VCPU_TRAP(r3) | 1426 | stw r0,VCPU_TRAP(r3) |
| 1427 | li r0,H_SUCCESS | 1427 | li r0,H_SUCCESS |
| 1428 | std r0,VCPU_GPR(R3)(r3) | 1428 | std r0,VCPU_GPR(R3)(r3) |
| 1429 | BEGIN_FTR_SECTION | 1429 | BEGIN_FTR_SECTION |
| 1430 | b 2f /* just send it up to host on 970 */ | 1430 | b kvm_cede_exit /* just send it up to host on 970 */ |
| 1431 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | 1431 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) |
| 1432 | 1432 | ||
| 1433 | /* | 1433 | /* |
| @@ -1446,7 +1446,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | |||
| 1446 | or r4,r4,r0 | 1446 | or r4,r4,r0 |
| 1447 | PPC_POPCNTW(R7,R4) | 1447 | PPC_POPCNTW(R7,R4) |
| 1448 | cmpw r7,r8 | 1448 | cmpw r7,r8 |
| 1449 | bge 2f | 1449 | bge kvm_cede_exit |
| 1450 | stwcx. r4,0,r6 | 1450 | stwcx. r4,0,r6 |
| 1451 | bne 31b | 1451 | bne 31b |
| 1452 | li r0,1 | 1452 | li r0,1 |
| @@ -1555,7 +1555,8 @@ kvm_end_cede: | |||
| 1555 | b hcall_real_fallback | 1555 | b hcall_real_fallback |
| 1556 | 1556 | ||
| 1557 | /* cede when already previously prodded case */ | 1557 | /* cede when already previously prodded case */ |
| 1558 | 1: li r0,0 | 1558 | kvm_cede_prodded: |
| 1559 | li r0,0 | ||
| 1559 | stb r0,VCPU_PRODDED(r3) | 1560 | stb r0,VCPU_PRODDED(r3) |
| 1560 | sync /* order testing prodded vs. clearing ceded */ | 1561 | sync /* order testing prodded vs. clearing ceded */ |
| 1561 | stb r0,VCPU_CEDED(r3) | 1562 | stb r0,VCPU_CEDED(r3) |
| @@ -1563,7 +1564,8 @@ kvm_end_cede: | |||
| 1563 | blr | 1564 | blr |
| 1564 | 1565 | ||
| 1565 | /* we've ceded but we want to give control to the host */ | 1566 | /* we've ceded but we want to give control to the host */ |
| 1566 | 2: li r3,H_TOO_HARD | 1567 | kvm_cede_exit: |
| 1568 | li r3,H_TOO_HARD | ||
| 1567 | blr | 1569 | blr |
| 1568 | 1570 | ||
| 1569 | secondary_too_late: | 1571 | secondary_too_late: |
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index c510fc961302..a2b66717813d 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c | |||
| @@ -322,11 +322,11 @@ static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) | |||
| 322 | static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500) | 322 | static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500) |
| 323 | { | 323 | { |
| 324 | if (vcpu_e500->g2h_tlb1_map) | 324 | if (vcpu_e500->g2h_tlb1_map) |
| 325 | memset(vcpu_e500->g2h_tlb1_map, | 325 | memset(vcpu_e500->g2h_tlb1_map, 0, |
| 326 | sizeof(u64) * vcpu_e500->gtlb_params[1].entries, 0); | 326 | sizeof(u64) * vcpu_e500->gtlb_params[1].entries); |
| 327 | if (vcpu_e500->h2g_tlb1_rmap) | 327 | if (vcpu_e500->h2g_tlb1_rmap) |
| 328 | memset(vcpu_e500->h2g_tlb1_rmap, | 328 | memset(vcpu_e500->h2g_tlb1_rmap, 0, |
| 329 | sizeof(unsigned int) * host_tlb_params[1].entries, 0); | 329 | sizeof(unsigned int) * host_tlb_params[1].entries); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) | 332 | static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) |
| @@ -539,6 +539,9 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
| 539 | 539 | ||
| 540 | kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, | 540 | kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, |
| 541 | ref, gvaddr, stlbe); | 541 | ref, gvaddr, stlbe); |
| 542 | |||
| 543 | /* Clear i-cache for new pages */ | ||
| 544 | kvmppc_mmu_flush_icache(pfn); | ||
| 542 | } | 545 | } |
| 543 | 546 | ||
| 544 | /* XXX only map the one-one case, for now use TLB0 */ | 547 | /* XXX only map the one-one case, for now use TLB0 */ |
diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index f9ede7c6606e..0d24ff15f5f6 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S | |||
| @@ -288,7 +288,7 @@ err1; stb r0,0(r3) | |||
| 288 | std r0,16(r1) | 288 | std r0,16(r1) |
| 289 | stdu r1,-STACKFRAMESIZE(r1) | 289 | stdu r1,-STACKFRAMESIZE(r1) |
| 290 | bl .enter_vmx_usercopy | 290 | bl .enter_vmx_usercopy |
| 291 | cmpwi r3,0 | 291 | cmpwi cr1,r3,0 |
| 292 | ld r0,STACKFRAMESIZE+16(r1) | 292 | ld r0,STACKFRAMESIZE+16(r1) |
| 293 | ld r3,STACKFRAMESIZE+48(r1) | 293 | ld r3,STACKFRAMESIZE+48(r1) |
| 294 | ld r4,STACKFRAMESIZE+56(r1) | 294 | ld r4,STACKFRAMESIZE+56(r1) |
| @@ -326,38 +326,7 @@ err1; stb r0,0(r3) | |||
| 326 | dcbt r0,r8,0b01010 /* GO */ | 326 | dcbt r0,r8,0b01010 /* GO */ |
| 327 | .machine pop | 327 | .machine pop |
| 328 | 328 | ||
| 329 | /* | 329 | beq cr1,.Lunwind_stack_nonvmx_copy |
| 330 | * We prefetch both the source and destination using enhanced touch | ||
| 331 | * instructions. We use a stream ID of 0 for the load side and | ||
| 332 | * 1 for the store side. | ||
| 333 | */ | ||
| 334 | clrrdi r6,r4,7 | ||
| 335 | clrrdi r9,r3,7 | ||
| 336 | ori r9,r9,1 /* stream=1 */ | ||
| 337 | |||
| 338 | srdi r7,r5,7 /* length in cachelines, capped at 0x3FF */ | ||
| 339 | cmpldi cr1,r7,0x3FF | ||
| 340 | ble cr1,1f | ||
| 341 | li r7,0x3FF | ||
| 342 | 1: lis r0,0x0E00 /* depth=7 */ | ||
| 343 | sldi r7,r7,7 | ||
| 344 | or r7,r7,r0 | ||
| 345 | ori r10,r7,1 /* stream=1 */ | ||
| 346 | |||
| 347 | lis r8,0x8000 /* GO=1 */ | ||
| 348 | clrldi r8,r8,32 | ||
| 349 | |||
| 350 | .machine push | ||
| 351 | .machine "power4" | ||
| 352 | dcbt r0,r6,0b01000 | ||
| 353 | dcbt r0,r7,0b01010 | ||
| 354 | dcbtst r0,r9,0b01000 | ||
| 355 | dcbtst r0,r10,0b01010 | ||
| 356 | eieio | ||
| 357 | dcbt r0,r8,0b01010 /* GO */ | ||
| 358 | .machine pop | ||
| 359 | |||
| 360 | beq .Lunwind_stack_nonvmx_copy | ||
| 361 | 330 | ||
| 362 | /* | 331 | /* |
| 363 | * If source and destination are not relatively aligned we use a | 332 | * If source and destination are not relatively aligned we use a |
diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index 0efdc51bc716..7ba6c96de778 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S | |||
| @@ -222,7 +222,7 @@ _GLOBAL(memcpy_power7) | |||
| 222 | std r0,16(r1) | 222 | std r0,16(r1) |
| 223 | stdu r1,-STACKFRAMESIZE(r1) | 223 | stdu r1,-STACKFRAMESIZE(r1) |
| 224 | bl .enter_vmx_copy | 224 | bl .enter_vmx_copy |
| 225 | cmpwi r3,0 | 225 | cmpwi cr1,r3,0 |
| 226 | ld r0,STACKFRAMESIZE+16(r1) | 226 | ld r0,STACKFRAMESIZE+16(r1) |
| 227 | ld r3,STACKFRAMESIZE+48(r1) | 227 | ld r3,STACKFRAMESIZE+48(r1) |
| 228 | ld r4,STACKFRAMESIZE+56(r1) | 228 | ld r4,STACKFRAMESIZE+56(r1) |
| @@ -260,7 +260,7 @@ _GLOBAL(memcpy_power7) | |||
| 260 | dcbt r0,r8,0b01010 /* GO */ | 260 | dcbt r0,r8,0b01010 /* GO */ |
| 261 | .machine pop | 261 | .machine pop |
| 262 | 262 | ||
| 263 | beq .Lunwind_stack_nonvmx_copy | 263 | beq cr1,.Lunwind_stack_nonvmx_copy |
| 264 | 264 | ||
| 265 | /* | 265 | /* |
| 266 | * If source and destination are not relatively aligned we use a | 266 | * If source and destination are not relatively aligned we use a |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index baaafde7d135..fbdad0e3929a 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
| @@ -469,6 +469,7 @@ void flush_dcache_icache_page(struct page *page) | |||
| 469 | __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); | 469 | __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); |
| 470 | #endif | 470 | #endif |
| 471 | } | 471 | } |
| 472 | EXPORT_SYMBOL(flush_dcache_icache_page); | ||
| 472 | 473 | ||
| 473 | void clear_user_page(void *page, unsigned long vaddr, struct page *pg) | 474 | void clear_user_page(void *page, unsigned long vaddr, struct page *pg) |
| 474 | { | 475 | { |
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 77b49ddda9d3..7cd2dbd6e4c4 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
| @@ -1431,7 +1431,7 @@ static void perf_event_interrupt(struct pt_regs *regs) | |||
| 1431 | if (!event->hw.idx || is_limited_pmc(event->hw.idx)) | 1431 | if (!event->hw.idx || is_limited_pmc(event->hw.idx)) |
| 1432 | continue; | 1432 | continue; |
| 1433 | val = read_pmc(event->hw.idx); | 1433 | val = read_pmc(event->hw.idx); |
| 1434 | if ((int)val < 0) { | 1434 | if (pmc_overflow(val)) { |
| 1435 | /* event has overflowed */ | 1435 | /* event has overflowed */ |
| 1436 | found = 1; | 1436 | found = 1; |
| 1437 | record_and_restart(event, val, regs); | 1437 | record_and_restart(event, val, regs); |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index a7b2a600d0a4..c37f46136321 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -465,7 +465,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) | |||
| 465 | iounmap(hose->cfg_data); | 465 | iounmap(hose->cfg_data); |
| 466 | iounmap(hose->cfg_addr); | 466 | iounmap(hose->cfg_addr); |
| 467 | pcibios_free_controller(hose); | 467 | pcibios_free_controller(hose); |
| 468 | return 0; | 468 | return -ENODEV; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | setup_pci_cmd(hose); | 471 | setup_pci_cmd(hose); |
| @@ -827,6 +827,7 @@ struct device_node *fsl_pci_primary; | |||
| 827 | 827 | ||
| 828 | void __devinit fsl_pci_init(void) | 828 | void __devinit fsl_pci_init(void) |
| 829 | { | 829 | { |
| 830 | int ret; | ||
| 830 | struct device_node *node; | 831 | struct device_node *node; |
| 831 | struct pci_controller *hose; | 832 | struct pci_controller *hose; |
| 832 | dma_addr_t max = 0xffffffff; | 833 | dma_addr_t max = 0xffffffff; |
| @@ -855,10 +856,12 @@ void __devinit fsl_pci_init(void) | |||
| 855 | if (!fsl_pci_primary) | 856 | if (!fsl_pci_primary) |
| 856 | fsl_pci_primary = node; | 857 | fsl_pci_primary = node; |
| 857 | 858 | ||
| 858 | fsl_add_bridge(node, fsl_pci_primary == node); | 859 | ret = fsl_add_bridge(node, fsl_pci_primary == node); |
| 859 | hose = pci_find_hose_for_OF_device(node); | 860 | if (ret == 0) { |
| 860 | max = min(max, hose->dma_window_base_cur + | 861 | hose = pci_find_hose_for_OF_device(node); |
| 861 | hose->dma_window_size); | 862 | max = min(max, hose->dma_window_base_cur + |
| 863 | hose->dma_window_size); | ||
| 864 | } | ||
| 862 | } | 865 | } |
| 863 | } | 866 | } |
| 864 | 867 | ||
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 483d8fa72e8b..e961f8c4a8f0 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c | |||
| @@ -14,6 +14,9 @@ | |||
| 14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
| 15 | #include <linux/of_platform.h> | 15 | #include <linux/of_platform.h> |
| 16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
| 17 | #include <linux/err.h> | ||
| 18 | #include <linux/export.h> | ||
| 19 | #include <linux/slab.h> | ||
| 17 | #include <asm/prom.h> | 20 | #include <asm/prom.h> |
| 18 | #include <asm/hw_irq.h> | 21 | #include <asm/hw_irq.h> |
| 19 | #include <asm/ppc-pci.h> | 22 | #include <asm/ppc-pci.h> |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index eab3492a45c5..9b49c65ee7a4 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/reboot.h> | 17 | #include <linux/reboot.h> |
| 18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
| 19 | #include <linux/kallsyms.h> | 19 | #include <linux/kallsyms.h> |
| 20 | #include <linux/kmsg_dump.h> | ||
| 20 | #include <linux/cpumask.h> | 21 | #include <linux/cpumask.h> |
| 21 | #include <linux/export.h> | 22 | #include <linux/export.h> |
| 22 | #include <linux/sysrq.h> | 23 | #include <linux/sysrq.h> |
| @@ -894,13 +895,13 @@ cmds(struct pt_regs *excp) | |||
| 894 | #endif | 895 | #endif |
| 895 | default: | 896 | default: |
| 896 | printf("Unrecognized command: "); | 897 | printf("Unrecognized command: "); |
| 897 | do { | 898 | do { |
| 898 | if (' ' < cmd && cmd <= '~') | 899 | if (' ' < cmd && cmd <= '~') |
| 899 | putchar(cmd); | 900 | putchar(cmd); |
| 900 | else | 901 | else |
| 901 | printf("\\x%x", cmd); | 902 | printf("\\x%x", cmd); |
| 902 | cmd = inchar(); | 903 | cmd = inchar(); |
| 903 | } while (cmd != '\n'); | 904 | } while (cmd != '\n'); |
| 904 | printf(" (type ? for help)\n"); | 905 | printf(" (type ? for help)\n"); |
| 905 | break; | 906 | break; |
| 906 | } | 907 | } |
| @@ -1097,7 +1098,7 @@ static long check_bp_loc(unsigned long addr) | |||
| 1097 | return 1; | 1098 | return 1; |
| 1098 | } | 1099 | } |
| 1099 | 1100 | ||
| 1100 | static char *breakpoint_help_string = | 1101 | static char *breakpoint_help_string = |
| 1101 | "Breakpoint command usage:\n" | 1102 | "Breakpoint command usage:\n" |
| 1102 | "b show breakpoints\n" | 1103 | "b show breakpoints\n" |
| 1103 | "b <addr> [cnt] set breakpoint at given instr addr\n" | 1104 | "b <addr> [cnt] set breakpoint at given instr addr\n" |
| @@ -1193,7 +1194,7 @@ bpt_cmds(void) | |||
| 1193 | 1194 | ||
| 1194 | default: | 1195 | default: |
| 1195 | termch = cmd; | 1196 | termch = cmd; |
| 1196 | cmd = skipbl(); | 1197 | cmd = skipbl(); |
| 1197 | if (cmd == '?') { | 1198 | if (cmd == '?') { |
| 1198 | printf(breakpoint_help_string); | 1199 | printf(breakpoint_help_string); |
| 1199 | break; | 1200 | break; |
| @@ -1359,7 +1360,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, | |||
| 1359 | sp + REGS_OFFSET); | 1360 | sp + REGS_OFFSET); |
| 1360 | break; | 1361 | break; |
| 1361 | } | 1362 | } |
| 1362 | printf("--- Exception: %lx %s at ", regs.trap, | 1363 | printf("--- Exception: %lx %s at ", regs.trap, |
| 1363 | getvecname(TRAP(®s))); | 1364 | getvecname(TRAP(®s))); |
| 1364 | pc = regs.nip; | 1365 | pc = regs.nip; |
| 1365 | lr = regs.link; | 1366 | lr = regs.link; |
| @@ -1623,14 +1624,14 @@ static void super_regs(void) | |||
| 1623 | 1624 | ||
| 1624 | cmd = skipbl(); | 1625 | cmd = skipbl(); |
| 1625 | if (cmd == '\n') { | 1626 | if (cmd == '\n') { |
| 1626 | unsigned long sp, toc; | 1627 | unsigned long sp, toc; |
| 1627 | asm("mr %0,1" : "=r" (sp) :); | 1628 | asm("mr %0,1" : "=r" (sp) :); |
| 1628 | asm("mr %0,2" : "=r" (toc) :); | 1629 | asm("mr %0,2" : "=r" (toc) :); |
| 1629 | 1630 | ||
| 1630 | printf("msr = "REG" sprg0= "REG"\n", | 1631 | printf("msr = "REG" sprg0= "REG"\n", |
| 1631 | mfmsr(), mfspr(SPRN_SPRG0)); | 1632 | mfmsr(), mfspr(SPRN_SPRG0)); |
| 1632 | printf("pvr = "REG" sprg1= "REG"\n", | 1633 | printf("pvr = "REG" sprg1= "REG"\n", |
| 1633 | mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); | 1634 | mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); |
| 1634 | printf("dec = "REG" sprg2= "REG"\n", | 1635 | printf("dec = "REG" sprg2= "REG"\n", |
| 1635 | mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); | 1636 | mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); |
| 1636 | printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); | 1637 | printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); |
| @@ -1783,7 +1784,7 @@ byterev(unsigned char *val, int size) | |||
| 1783 | static int brev; | 1784 | static int brev; |
| 1784 | static int mnoread; | 1785 | static int mnoread; |
| 1785 | 1786 | ||
| 1786 | static char *memex_help_string = | 1787 | static char *memex_help_string = |
| 1787 | "Memory examine command usage:\n" | 1788 | "Memory examine command usage:\n" |
| 1788 | "m [addr] [flags] examine/change memory\n" | 1789 | "m [addr] [flags] examine/change memory\n" |
| 1789 | " addr is optional. will start where left off.\n" | 1790 | " addr is optional. will start where left off.\n" |
| @@ -1798,7 +1799,7 @@ static char *memex_help_string = | |||
| 1798 | "NOTE: flags are saved as defaults\n" | 1799 | "NOTE: flags are saved as defaults\n" |
| 1799 | ""; | 1800 | ""; |
| 1800 | 1801 | ||
| 1801 | static char *memex_subcmd_help_string = | 1802 | static char *memex_subcmd_help_string = |
| 1802 | "Memory examine subcommands:\n" | 1803 | "Memory examine subcommands:\n" |
| 1803 | " hexval write this val to current location\n" | 1804 | " hexval write this val to current location\n" |
| 1804 | " 'string' write chars from string to this location\n" | 1805 | " 'string' write chars from string to this location\n" |
| @@ -2064,7 +2065,7 @@ prdump(unsigned long adrs, long ndump) | |||
| 2064 | nr = mread(adrs, temp, r); | 2065 | nr = mread(adrs, temp, r); |
| 2065 | adrs += nr; | 2066 | adrs += nr; |
| 2066 | for (m = 0; m < r; ++m) { | 2067 | for (m = 0; m < r; ++m) { |
| 2067 | if ((m & (sizeof(long) - 1)) == 0 && m > 0) | 2068 | if ((m & (sizeof(long) - 1)) == 0 && m > 0) |
| 2068 | putchar(' '); | 2069 | putchar(' '); |
| 2069 | if (m < nr) | 2070 | if (m < nr) |
| 2070 | printf("%.2x", temp[m]); | 2071 | printf("%.2x", temp[m]); |
| @@ -2072,7 +2073,7 @@ prdump(unsigned long adrs, long ndump) | |||
| 2072 | printf("%s", fault_chars[fault_type]); | 2073 | printf("%s", fault_chars[fault_type]); |
| 2073 | } | 2074 | } |
| 2074 | for (; m < 16; ++m) { | 2075 | for (; m < 16; ++m) { |
| 2075 | if ((m & (sizeof(long) - 1)) == 0) | 2076 | if ((m & (sizeof(long) - 1)) == 0) |
| 2076 | putchar(' '); | 2077 | putchar(' '); |
| 2077 | printf(" "); | 2078 | printf(" "); |
| 2078 | } | 2079 | } |
| @@ -2148,45 +2149,28 @@ print_address(unsigned long addr) | |||
| 2148 | void | 2149 | void |
| 2149 | dump_log_buf(void) | 2150 | dump_log_buf(void) |
| 2150 | { | 2151 | { |
| 2151 | const unsigned long size = 128; | 2152 | struct kmsg_dumper dumper = { .active = 1 }; |
| 2152 | unsigned long end, addr; | 2153 | unsigned char buf[128]; |
| 2153 | unsigned char buf[size + 1]; | 2154 | size_t len; |
| 2154 | 2155 | ||
| 2155 | addr = 0; | 2156 | if (setjmp(bus_error_jmp) != 0) { |
| 2156 | buf[size] = '\0'; | 2157 | printf("Error dumping printk buffer!\n"); |
| 2157 | 2158 | return; | |
| 2158 | if (setjmp(bus_error_jmp) != 0) { | 2159 | } |
| 2159 | printf("Unable to lookup symbol __log_buf!\n"); | 2160 | |
| 2160 | return; | 2161 | catch_memory_errors = 1; |
| 2161 | } | 2162 | sync(); |
| 2162 | 2163 | ||
| 2163 | catch_memory_errors = 1; | 2164 | kmsg_dump_rewind_nolock(&dumper); |
| 2164 | sync(); | 2165 | while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) { |
| 2165 | addr = kallsyms_lookup_name("__log_buf"); | 2166 | buf[len] = '\0'; |
| 2166 | 2167 | printf("%s", buf); | |
| 2167 | if (! addr) | 2168 | } |
| 2168 | printf("Symbol __log_buf not found!\n"); | 2169 | |
| 2169 | else { | 2170 | sync(); |
| 2170 | end = addr + (1 << CONFIG_LOG_BUF_SHIFT); | 2171 | /* wait a little while to see if we get a machine check */ |
| 2171 | while (addr < end) { | 2172 | __delay(200); |
| 2172 | if (! mread(addr, buf, size)) { | 2173 | catch_memory_errors = 0; |
| 2173 | printf("Can't read memory at address 0x%lx\n", addr); | ||
| 2174 | break; | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | printf("%s", buf); | ||
| 2178 | |||
| 2179 | if (strlen(buf) < size) | ||
| 2180 | break; | ||
| 2181 | |||
| 2182 | addr += size; | ||
| 2183 | } | ||
| 2184 | } | ||
| 2185 | |||
| 2186 | sync(); | ||
| 2187 | /* wait a little while to see if we get a machine check */ | ||
| 2188 | __delay(200); | ||
| 2189 | catch_memory_errors = 0; | ||
| 2190 | } | 2174 | } |
| 2191 | 2175 | ||
| 2192 | /* | 2176 | /* |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 32e8449640fa..9b94a160fe7f 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
| @@ -180,7 +180,8 @@ extern char elf_platform[]; | |||
| 180 | #define ELF_PLATFORM (elf_platform) | 180 | #define ELF_PLATFORM (elf_platform) |
| 181 | 181 | ||
| 182 | #ifndef CONFIG_64BIT | 182 | #ifndef CONFIG_64BIT |
| 183 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 183 | #define SET_PERSONALITY(ex) \ |
| 184 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
| 184 | #else /* CONFIG_64BIT */ | 185 | #else /* CONFIG_64BIT */ |
| 185 | #define SET_PERSONALITY(ex) \ | 186 | #define SET_PERSONALITY(ex) \ |
| 186 | do { \ | 187 | do { \ |
diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/asm/posix_types.h index 7bcc14e395f0..bf2a2ad2f800 100644 --- a/arch/s390/include/asm/posix_types.h +++ b/arch/s390/include/asm/posix_types.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | typedef unsigned long __kernel_size_t; | 15 | typedef unsigned long __kernel_size_t; |
| 16 | typedef long __kernel_ssize_t; | ||
| 16 | #define __kernel_size_t __kernel_size_t | 17 | #define __kernel_size_t __kernel_size_t |
| 17 | 18 | ||
| 18 | typedef unsigned short __kernel_old_dev_t; | 19 | typedef unsigned short __kernel_old_dev_t; |
| @@ -25,7 +26,6 @@ typedef unsigned short __kernel_mode_t; | |||
| 25 | typedef unsigned short __kernel_ipc_pid_t; | 26 | typedef unsigned short __kernel_ipc_pid_t; |
| 26 | typedef unsigned short __kernel_uid_t; | 27 | typedef unsigned short __kernel_uid_t; |
| 27 | typedef unsigned short __kernel_gid_t; | 28 | typedef unsigned short __kernel_gid_t; |
| 28 | typedef int __kernel_ssize_t; | ||
| 29 | typedef int __kernel_ptrdiff_t; | 29 | typedef int __kernel_ptrdiff_t; |
| 30 | 30 | ||
| 31 | #else /* __s390x__ */ | 31 | #else /* __s390x__ */ |
| @@ -35,7 +35,6 @@ typedef unsigned int __kernel_mode_t; | |||
| 35 | typedef int __kernel_ipc_pid_t; | 35 | typedef int __kernel_ipc_pid_t; |
| 36 | typedef unsigned int __kernel_uid_t; | 36 | typedef unsigned int __kernel_uid_t; |
| 37 | typedef unsigned int __kernel_gid_t; | 37 | typedef unsigned int __kernel_gid_t; |
| 38 | typedef long __kernel_ssize_t; | ||
| 39 | typedef long __kernel_ptrdiff_t; | 38 | typedef long __kernel_ptrdiff_t; |
| 40 | typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ | 39 | typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ |
| 41 | 40 | ||
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index a0a8340daafa..ce26ac3cb162 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
| @@ -44,6 +44,7 @@ static inline void smp_call_online_cpu(void (*func)(void *), void *data) | |||
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | static inline int smp_find_processor_id(int address) { return 0; } | 46 | static inline int smp_find_processor_id(int address) { return 0; } |
| 47 | static inline int smp_store_status(int cpu) { return 0; } | ||
| 47 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } | 48 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } |
| 48 | static inline void smp_yield_cpu(int cpu) { } | 49 | static inline void smp_yield_cpu(int cpu) { } |
| 49 | static inline void smp_yield(void) { } | 50 | static inline void smp_yield(void) { } |
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index b315a33867f2..33692eaabab5 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h | |||
| @@ -12,8 +12,7 @@ | |||
| 12 | * Simple spin lock operations. There are two variants, one clears IRQ's | 12 | * Simple spin lock operations. There are two variants, one clears IRQ's |
| 13 | * on the local processor, one does not. | 13 | * on the local processor, one does not. |
| 14 | * | 14 | * |
| 15 | * These are fair FIFO ticket locks, which are currently limited to 256 | 15 | * These are fair FIFO ticket locks, which support up to 2^16 CPUs. |
| 16 | * CPUs. | ||
| 17 | * | 16 | * |
| 18 | * (the type definitions are in asm/spinlock_types.h) | 17 | * (the type definitions are in asm/spinlock_types.h) |
| 19 | */ | 18 | */ |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index afb7ff79a29f..ced4534baed5 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
| @@ -165,7 +165,7 @@ static const unsigned char * const k7_nops[ASM_NOP_MAX+2] = | |||
| 165 | #endif | 165 | #endif |
| 166 | 166 | ||
| 167 | #ifdef P6_NOP1 | 167 | #ifdef P6_NOP1 |
| 168 | static const unsigned char __initconst_or_module p6nops[] = | 168 | static const unsigned char p6nops[] = |
| 169 | { | 169 | { |
| 170 | P6_NOP1, | 170 | P6_NOP1, |
| 171 | P6_NOP2, | 171 | P6_NOP2, |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 7ad683d78645..d44f7829968e 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
| @@ -270,7 +270,7 @@ void fixup_irqs(void) | |||
| 270 | 270 | ||
| 271 | if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { | 271 | if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { |
| 272 | break_affinity = 1; | 272 | break_affinity = 1; |
| 273 | affinity = cpu_all_mask; | 273 | affinity = cpu_online_mask; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | chip = irq_data_get_irq_chip(data); | 276 | chip = irq_data_get_irq_chip(data); |
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 8a2ce8fd41c0..82746f942cd8 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
| @@ -143,11 +143,12 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr, | |||
| 143 | unsigned int *current_size) | 143 | unsigned int *current_size) |
| 144 | { | 144 | { |
| 145 | struct microcode_header_amd *mc_hdr; | 145 | struct microcode_header_amd *mc_hdr; |
| 146 | unsigned int actual_size; | 146 | unsigned int actual_size, patch_size; |
| 147 | u16 equiv_cpu_id; | 147 | u16 equiv_cpu_id; |
| 148 | 148 | ||
| 149 | /* size of the current patch we're staring at */ | 149 | /* size of the current patch we're staring at */ |
| 150 | *current_size = *(u32 *)(ucode_ptr + 4) + SECTION_HDR_SIZE; | 150 | patch_size = *(u32 *)(ucode_ptr + 4); |
| 151 | *current_size = patch_size + SECTION_HDR_SIZE; | ||
| 151 | 152 | ||
| 152 | equiv_cpu_id = find_equiv_id(); | 153 | equiv_cpu_id = find_equiv_id(); |
| 153 | if (!equiv_cpu_id) | 154 | if (!equiv_cpu_id) |
| @@ -174,7 +175,7 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr, | |||
| 174 | /* | 175 | /* |
| 175 | * now that the header looks sane, verify its size | 176 | * now that the header looks sane, verify its size |
| 176 | */ | 177 | */ |
| 177 | actual_size = verify_ucode_size(cpu, *current_size, leftover_size); | 178 | actual_size = verify_ucode_size(cpu, patch_size, leftover_size); |
| 178 | if (!actual_size) | 179 | if (!actual_size) |
| 179 | return 0; | 180 | return 0; |
| 180 | 181 | ||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 97d9a9914ba8..a3b57a27be88 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
| @@ -475,13 +475,26 @@ register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg) | |||
| 475 | return address_mask(ctxt, reg); | 475 | return address_mask(ctxt, reg); |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | static void masked_increment(ulong *reg, ulong mask, int inc) | ||
| 479 | { | ||
| 480 | assign_masked(reg, *reg + inc, mask); | ||
| 481 | } | ||
| 482 | |||
| 478 | static inline void | 483 | static inline void |
| 479 | register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc) | 484 | register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc) |
| 480 | { | 485 | { |
| 486 | ulong mask; | ||
| 487 | |||
| 481 | if (ctxt->ad_bytes == sizeof(unsigned long)) | 488 | if (ctxt->ad_bytes == sizeof(unsigned long)) |
| 482 | *reg += inc; | 489 | mask = ~0UL; |
| 483 | else | 490 | else |
| 484 | *reg = (*reg & ~ad_mask(ctxt)) | ((*reg + inc) & ad_mask(ctxt)); | 491 | mask = ad_mask(ctxt); |
| 492 | masked_increment(reg, mask, inc); | ||
| 493 | } | ||
| 494 | |||
| 495 | static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc) | ||
| 496 | { | ||
| 497 | masked_increment(&ctxt->regs[VCPU_REGS_RSP], stack_mask(ctxt), inc); | ||
| 485 | } | 498 | } |
| 486 | 499 | ||
| 487 | static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | 500 | static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) |
| @@ -1522,8 +1535,8 @@ static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes) | |||
| 1522 | { | 1535 | { |
| 1523 | struct segmented_address addr; | 1536 | struct segmented_address addr; |
| 1524 | 1537 | ||
| 1525 | register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], -bytes); | 1538 | rsp_increment(ctxt, -bytes); |
| 1526 | addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]); | 1539 | addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt); |
| 1527 | addr.seg = VCPU_SREG_SS; | 1540 | addr.seg = VCPU_SREG_SS; |
| 1528 | 1541 | ||
| 1529 | return segmented_write(ctxt, addr, data, bytes); | 1542 | return segmented_write(ctxt, addr, data, bytes); |
| @@ -1542,13 +1555,13 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt, | |||
| 1542 | int rc; | 1555 | int rc; |
| 1543 | struct segmented_address addr; | 1556 | struct segmented_address addr; |
| 1544 | 1557 | ||
| 1545 | addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]); | 1558 | addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt); |
| 1546 | addr.seg = VCPU_SREG_SS; | 1559 | addr.seg = VCPU_SREG_SS; |
| 1547 | rc = segmented_read(ctxt, addr, dest, len); | 1560 | rc = segmented_read(ctxt, addr, dest, len); |
| 1548 | if (rc != X86EMUL_CONTINUE) | 1561 | if (rc != X86EMUL_CONTINUE) |
| 1549 | return rc; | 1562 | return rc; |
| 1550 | 1563 | ||
| 1551 | register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], len); | 1564 | rsp_increment(ctxt, len); |
| 1552 | return rc; | 1565 | return rc; |
| 1553 | } | 1566 | } |
| 1554 | 1567 | ||
| @@ -1688,8 +1701,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt) | |||
| 1688 | 1701 | ||
| 1689 | while (reg >= VCPU_REGS_RAX) { | 1702 | while (reg >= VCPU_REGS_RAX) { |
| 1690 | if (reg == VCPU_REGS_RSP) { | 1703 | if (reg == VCPU_REGS_RSP) { |
| 1691 | register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], | 1704 | rsp_increment(ctxt, ctxt->op_bytes); |
| 1692 | ctxt->op_bytes); | ||
| 1693 | --reg; | 1705 | --reg; |
| 1694 | } | 1706 | } |
| 1695 | 1707 | ||
| @@ -2825,7 +2837,7 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt) | |||
| 2825 | rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes); | 2837 | rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes); |
| 2826 | if (rc != X86EMUL_CONTINUE) | 2838 | if (rc != X86EMUL_CONTINUE) |
| 2827 | return rc; | 2839 | return rc; |
| 2828 | register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], ctxt->src.val); | 2840 | rsp_increment(ctxt, ctxt->src.val); |
| 2829 | return X86EMUL_CONTINUE; | 2841 | return X86EMUL_CONTINUE; |
| 2830 | } | 2842 | } |
| 2831 | 2843 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 01ca00423938..7fbd0d273ea8 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
| @@ -4113,16 +4113,21 @@ static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) | |||
| 4113 | LIST_HEAD(invalid_list); | 4113 | LIST_HEAD(invalid_list); |
| 4114 | 4114 | ||
| 4115 | /* | 4115 | /* |
| 4116 | * Never scan more than sc->nr_to_scan VM instances. | ||
| 4117 | * Will not hit this condition practically since we do not try | ||
| 4118 | * to shrink more than one VM and it is very unlikely to see | ||
| 4119 | * !n_used_mmu_pages so many times. | ||
| 4120 | */ | ||
| 4121 | if (!nr_to_scan--) | ||
| 4122 | break; | ||
| 4123 | /* | ||
| 4116 | * n_used_mmu_pages is accessed without holding kvm->mmu_lock | 4124 | * n_used_mmu_pages is accessed without holding kvm->mmu_lock |
| 4117 | * here. We may skip a VM instance errorneosly, but we do not | 4125 | * here. We may skip a VM instance errorneosly, but we do not |
| 4118 | * want to shrink a VM that only started to populate its MMU | 4126 | * want to shrink a VM that only started to populate its MMU |
| 4119 | * anyway. | 4127 | * anyway. |
| 4120 | */ | 4128 | */ |
| 4121 | if (kvm->arch.n_used_mmu_pages > 0) { | 4129 | if (!kvm->arch.n_used_mmu_pages) |
| 4122 | if (!nr_to_scan--) | ||
| 4123 | break; | ||
| 4124 | continue; | 4130 | continue; |
| 4125 | } | ||
| 4126 | 4131 | ||
| 4127 | idx = srcu_read_lock(&kvm->srcu); | 4132 | idx = srcu_read_lock(&kvm->srcu); |
| 4128 | spin_lock(&kvm->mmu_lock); | 4133 | spin_lock(&kvm->mmu_lock); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 42bce48f6928..148ed666e311 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -806,7 +806,7 @@ EXPORT_SYMBOL_GPL(kvm_rdpmc); | |||
| 806 | * kvm-specific. Those are put in the beginning of the list. | 806 | * kvm-specific. Those are put in the beginning of the list. |
| 807 | */ | 807 | */ |
| 808 | 808 | ||
| 809 | #define KVM_SAVE_MSRS_BEGIN 9 | 809 | #define KVM_SAVE_MSRS_BEGIN 10 |
| 810 | static u32 msrs_to_save[] = { | 810 | static u32 msrs_to_save[] = { |
| 811 | MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, | 811 | MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, |
| 812 | MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, | 812 | MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, |
| @@ -2000,6 +2000,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
| 2000 | case MSR_KVM_STEAL_TIME: | 2000 | case MSR_KVM_STEAL_TIME: |
| 2001 | data = vcpu->arch.st.msr_val; | 2001 | data = vcpu->arch.st.msr_val; |
| 2002 | break; | 2002 | break; |
| 2003 | case MSR_KVM_PV_EOI_EN: | ||
| 2004 | data = vcpu->arch.pv_eoi.msr_val; | ||
| 2005 | break; | ||
| 2003 | case MSR_IA32_P5_MC_ADDR: | 2006 | case MSR_IA32_P5_MC_ADDR: |
| 2004 | case MSR_IA32_P5_MC_TYPE: | 2007 | case MSR_IA32_P5_MC_TYPE: |
| 2005 | case MSR_IA32_MCG_CAP: | 2008 | case MSR_IA32_MCG_CAP: |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bf4bda6d3e9a..9642d4a38602 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
| 33 | #include <linux/memblock.h> | 33 | #include <linux/memblock.h> |
| 34 | #include <linux/syscore_ops.h> | ||
| 35 | 34 | ||
| 36 | #include <xen/xen.h> | 35 | #include <xen/xen.h> |
| 37 | #include <xen/interface/xen.h> | 36 | #include <xen/interface/xen.h> |
| @@ -1470,130 +1469,38 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1470 | #endif | 1469 | #endif |
| 1471 | } | 1470 | } |
| 1472 | 1471 | ||
| 1473 | #ifdef CONFIG_XEN_PVHVM | 1472 | void __ref xen_hvm_init_shared_info(void) |
| 1474 | /* | ||
| 1475 | * The pfn containing the shared_info is located somewhere in RAM. This | ||
| 1476 | * will cause trouble if the current kernel is doing a kexec boot into a | ||
| 1477 | * new kernel. The new kernel (and its startup code) can not know where | ||
| 1478 | * the pfn is, so it can not reserve the page. The hypervisor will | ||
| 1479 | * continue to update the pfn, and as a result memory corruption occours | ||
| 1480 | * in the new kernel. | ||
| 1481 | * | ||
| 1482 | * One way to work around this issue is to allocate a page in the | ||
| 1483 | * xen-platform pci device's BAR memory range. But pci init is done very | ||
| 1484 | * late and the shared_info page is already in use very early to read | ||
| 1485 | * the pvclock. So moving the pfn from RAM to MMIO is racy because some | ||
| 1486 | * code paths on other vcpus could access the pfn during the small | ||
| 1487 | * window when the old pfn is moved to the new pfn. There is even a | ||
| 1488 | * small window were the old pfn is not backed by a mfn, and during that | ||
| 1489 | * time all reads return -1. | ||
| 1490 | * | ||
| 1491 | * Because it is not known upfront where the MMIO region is located it | ||
| 1492 | * can not be used right from the start in xen_hvm_init_shared_info. | ||
| 1493 | * | ||
| 1494 | * To minimise trouble the move of the pfn is done shortly before kexec. | ||
| 1495 | * This does not eliminate the race because all vcpus are still online | ||
| 1496 | * when the syscore_ops will be called. But hopefully there is no work | ||
| 1497 | * pending at this point in time. Also the syscore_op is run last which | ||
| 1498 | * reduces the risk further. | ||
| 1499 | */ | ||
| 1500 | |||
| 1501 | static struct shared_info *xen_hvm_shared_info; | ||
| 1502 | |||
| 1503 | static void xen_hvm_connect_shared_info(unsigned long pfn) | ||
| 1504 | { | 1473 | { |
| 1474 | int cpu; | ||
| 1505 | struct xen_add_to_physmap xatp; | 1475 | struct xen_add_to_physmap xatp; |
| 1476 | static struct shared_info *shared_info_page = 0; | ||
| 1506 | 1477 | ||
| 1478 | if (!shared_info_page) | ||
| 1479 | shared_info_page = (struct shared_info *) | ||
| 1480 | extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
| 1507 | xatp.domid = DOMID_SELF; | 1481 | xatp.domid = DOMID_SELF; |
| 1508 | xatp.idx = 0; | 1482 | xatp.idx = 0; |
| 1509 | xatp.space = XENMAPSPACE_shared_info; | 1483 | xatp.space = XENMAPSPACE_shared_info; |
| 1510 | xatp.gpfn = pfn; | 1484 | xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; |
| 1511 | if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) | 1485 | if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) |
| 1512 | BUG(); | 1486 | BUG(); |
| 1513 | 1487 | ||
| 1514 | } | 1488 | HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; |
| 1515 | static void xen_hvm_set_shared_info(struct shared_info *sip) | ||
| 1516 | { | ||
| 1517 | int cpu; | ||
| 1518 | |||
| 1519 | HYPERVISOR_shared_info = sip; | ||
| 1520 | 1489 | ||
| 1521 | /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info | 1490 | /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info |
| 1522 | * page, we use it in the event channel upcall and in some pvclock | 1491 | * page, we use it in the event channel upcall and in some pvclock |
| 1523 | * related functions. We don't need the vcpu_info placement | 1492 | * related functions. We don't need the vcpu_info placement |
| 1524 | * optimizations because we don't use any pv_mmu or pv_irq op on | 1493 | * optimizations because we don't use any pv_mmu or pv_irq op on |
| 1525 | * HVM. | 1494 | * HVM. |
| 1526 | * When xen_hvm_set_shared_info is run at boot time only vcpu 0 is | 1495 | * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is |
| 1527 | * online but xen_hvm_set_shared_info is run at resume time too and | 1496 | * online but xen_hvm_init_shared_info is run at resume time too and |
| 1528 | * in that case multiple vcpus might be online. */ | 1497 | * in that case multiple vcpus might be online. */ |
| 1529 | for_each_online_cpu(cpu) { | 1498 | for_each_online_cpu(cpu) { |
| 1530 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; | 1499 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; |
| 1531 | } | 1500 | } |
| 1532 | } | 1501 | } |
| 1533 | 1502 | ||
| 1534 | /* Reconnect the shared_info pfn to a mfn */ | 1503 | #ifdef CONFIG_XEN_PVHVM |
| 1535 | void xen_hvm_resume_shared_info(void) | ||
| 1536 | { | ||
| 1537 | xen_hvm_connect_shared_info(__pa(xen_hvm_shared_info) >> PAGE_SHIFT); | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | #ifdef CONFIG_KEXEC | ||
| 1541 | static struct shared_info *xen_hvm_shared_info_kexec; | ||
| 1542 | static unsigned long xen_hvm_shared_info_pfn_kexec; | ||
| 1543 | |||
| 1544 | /* Remember a pfn in MMIO space for kexec reboot */ | ||
| 1545 | void __devinit xen_hvm_prepare_kexec(struct shared_info *sip, unsigned long pfn) | ||
| 1546 | { | ||
| 1547 | xen_hvm_shared_info_kexec = sip; | ||
| 1548 | xen_hvm_shared_info_pfn_kexec = pfn; | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | static void xen_hvm_syscore_shutdown(void) | ||
| 1552 | { | ||
| 1553 | struct xen_memory_reservation reservation = { | ||
| 1554 | .domid = DOMID_SELF, | ||
| 1555 | .nr_extents = 1, | ||
| 1556 | }; | ||
| 1557 | unsigned long prev_pfn; | ||
| 1558 | int rc; | ||
| 1559 | |||
| 1560 | if (!xen_hvm_shared_info_kexec) | ||
| 1561 | return; | ||
| 1562 | |||
| 1563 | prev_pfn = __pa(xen_hvm_shared_info) >> PAGE_SHIFT; | ||
| 1564 | set_xen_guest_handle(reservation.extent_start, &prev_pfn); | ||
| 1565 | |||
| 1566 | /* Move pfn to MMIO, disconnects previous pfn from mfn */ | ||
| 1567 | xen_hvm_connect_shared_info(xen_hvm_shared_info_pfn_kexec); | ||
| 1568 | |||
| 1569 | /* Update pointers, following hypercall is also a memory barrier */ | ||
| 1570 | xen_hvm_set_shared_info(xen_hvm_shared_info_kexec); | ||
| 1571 | |||
| 1572 | /* Allocate new mfn for previous pfn */ | ||
| 1573 | do { | ||
| 1574 | rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); | ||
| 1575 | if (rc == 0) | ||
| 1576 | msleep(123); | ||
| 1577 | } while (rc == 0); | ||
| 1578 | |||
| 1579 | /* Make sure the previous pfn is really connected to a (new) mfn */ | ||
| 1580 | BUG_ON(rc != 1); | ||
| 1581 | } | ||
| 1582 | |||
| 1583 | static struct syscore_ops xen_hvm_syscore_ops = { | ||
| 1584 | .shutdown = xen_hvm_syscore_shutdown, | ||
| 1585 | }; | ||
| 1586 | #endif | ||
| 1587 | |||
| 1588 | /* Use a pfn in RAM, may move to MMIO before kexec. */ | ||
| 1589 | static void __init xen_hvm_init_shared_info(void) | ||
| 1590 | { | ||
| 1591 | /* Remember pointer for resume */ | ||
| 1592 | xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
| 1593 | xen_hvm_connect_shared_info(__pa(xen_hvm_shared_info) >> PAGE_SHIFT); | ||
| 1594 | xen_hvm_set_shared_info(xen_hvm_shared_info); | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | static void __init init_hvm_pv_info(void) | 1504 | static void __init init_hvm_pv_info(void) |
| 1598 | { | 1505 | { |
| 1599 | int major, minor; | 1506 | int major, minor; |
| @@ -1644,9 +1551,6 @@ static void __init xen_hvm_guest_init(void) | |||
| 1644 | init_hvm_pv_info(); | 1551 | init_hvm_pv_info(); |
| 1645 | 1552 | ||
| 1646 | xen_hvm_init_shared_info(); | 1553 | xen_hvm_init_shared_info(); |
| 1647 | #ifdef CONFIG_KEXEC | ||
| 1648 | register_syscore_ops(&xen_hvm_syscore_ops); | ||
| 1649 | #endif | ||
| 1650 | 1554 | ||
| 1651 | if (xen_feature(XENFEAT_hvm_callback_vector)) | 1555 | if (xen_feature(XENFEAT_hvm_callback_vector)) |
| 1652 | xen_have_vector_callback = 1; | 1556 | xen_have_vector_callback = 1; |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index b2e91d40a4cb..d4b255463253 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
| @@ -196,9 +196,11 @@ RESERVE_BRK(p2m_mid_identity, PAGE_SIZE * 2 * 3); | |||
| 196 | 196 | ||
| 197 | /* When we populate back during bootup, the amount of pages can vary. The | 197 | /* When we populate back during bootup, the amount of pages can vary. The |
| 198 | * max we have is seen is 395979, but that does not mean it can't be more. | 198 | * max we have is seen is 395979, but that does not mean it can't be more. |
| 199 | * But some machines can have 3GB I/O holes even. So lets reserve enough | 199 | * Some machines can have 3GB I/O holes even. With early_can_reuse_p2m_middle |
| 200 | * for 4GB of I/O and E820 holes. */ | 200 | * it can re-use Xen provided mfn_list array, so we only need to allocate at |
| 201 | RESERVE_BRK(p2m_populated, PMD_SIZE * 4); | 201 | * most three P2M top nodes. */ |
| 202 | RESERVE_BRK(p2m_populated, PAGE_SIZE * 3); | ||
| 203 | |||
| 202 | static inline unsigned p2m_top_index(unsigned long pfn) | 204 | static inline unsigned p2m_top_index(unsigned long pfn) |
| 203 | { | 205 | { |
| 204 | BUG_ON(pfn >= MAX_P2M_PFN); | 206 | BUG_ON(pfn >= MAX_P2M_PFN); |
| @@ -575,12 +577,99 @@ static bool __init early_alloc_p2m(unsigned long pfn) | |||
| 575 | } | 577 | } |
| 576 | return true; | 578 | return true; |
| 577 | } | 579 | } |
| 580 | |||
| 581 | /* | ||
| 582 | * Skim over the P2M tree looking at pages that are either filled with | ||
| 583 | * INVALID_P2M_ENTRY or with 1:1 PFNs. If found, re-use that page and | ||
| 584 | * replace the P2M leaf with a p2m_missing or p2m_identity. | ||
| 585 | * Stick the old page in the new P2M tree location. | ||
| 586 | */ | ||
| 587 | bool __init early_can_reuse_p2m_middle(unsigned long set_pfn, unsigned long set_mfn) | ||
| 588 | { | ||
| 589 | unsigned topidx; | ||
| 590 | unsigned mididx; | ||
| 591 | unsigned ident_pfns; | ||
| 592 | unsigned inv_pfns; | ||
| 593 | unsigned long *p2m; | ||
| 594 | unsigned long *mid_mfn_p; | ||
| 595 | unsigned idx; | ||
| 596 | unsigned long pfn; | ||
| 597 | |||
| 598 | /* We only look when this entails a P2M middle layer */ | ||
| 599 | if (p2m_index(set_pfn)) | ||
| 600 | return false; | ||
| 601 | |||
| 602 | for (pfn = 0; pfn <= MAX_DOMAIN_PAGES; pfn += P2M_PER_PAGE) { | ||
| 603 | topidx = p2m_top_index(pfn); | ||
| 604 | |||
| 605 | if (!p2m_top[topidx]) | ||
| 606 | continue; | ||
| 607 | |||
| 608 | if (p2m_top[topidx] == p2m_mid_missing) | ||
| 609 | continue; | ||
| 610 | |||
| 611 | mididx = p2m_mid_index(pfn); | ||
| 612 | p2m = p2m_top[topidx][mididx]; | ||
| 613 | if (!p2m) | ||
| 614 | continue; | ||
| 615 | |||
| 616 | if ((p2m == p2m_missing) || (p2m == p2m_identity)) | ||
| 617 | continue; | ||
| 618 | |||
| 619 | if ((unsigned long)p2m == INVALID_P2M_ENTRY) | ||
| 620 | continue; | ||
| 621 | |||
| 622 | ident_pfns = 0; | ||
| 623 | inv_pfns = 0; | ||
| 624 | for (idx = 0; idx < P2M_PER_PAGE; idx++) { | ||
| 625 | /* IDENTITY_PFNs are 1:1 */ | ||
| 626 | if (p2m[idx] == IDENTITY_FRAME(pfn + idx)) | ||
| 627 | ident_pfns++; | ||
| 628 | else if (p2m[idx] == INVALID_P2M_ENTRY) | ||
| 629 | inv_pfns++; | ||
| 630 | else | ||
| 631 | break; | ||
| 632 | } | ||
| 633 | if ((ident_pfns == P2M_PER_PAGE) || (inv_pfns == P2M_PER_PAGE)) | ||
| 634 | goto found; | ||
| 635 | } | ||
| 636 | return false; | ||
| 637 | found: | ||
| 638 | /* Found one, replace old with p2m_identity or p2m_missing */ | ||
| 639 | p2m_top[topidx][mididx] = (ident_pfns ? p2m_identity : p2m_missing); | ||
| 640 | /* And the other for save/restore.. */ | ||
| 641 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
| 642 | /* NOTE: Even if it is a p2m_identity it should still be point to | ||
| 643 | * a page filled with INVALID_P2M_ENTRY entries. */ | ||
| 644 | mid_mfn_p[mididx] = virt_to_mfn(p2m_missing); | ||
| 645 | |||
| 646 | /* Reset where we want to stick the old page in. */ | ||
| 647 | topidx = p2m_top_index(set_pfn); | ||
| 648 | mididx = p2m_mid_index(set_pfn); | ||
| 649 | |||
| 650 | /* This shouldn't happen */ | ||
| 651 | if (WARN_ON(p2m_top[topidx] == p2m_mid_missing)) | ||
| 652 | early_alloc_p2m(set_pfn); | ||
| 653 | |||
| 654 | if (WARN_ON(p2m_top[topidx][mididx] != p2m_missing)) | ||
| 655 | return false; | ||
| 656 | |||
| 657 | p2m_init(p2m); | ||
| 658 | p2m_top[topidx][mididx] = p2m; | ||
| 659 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
| 660 | mid_mfn_p[mididx] = virt_to_mfn(p2m); | ||
| 661 | |||
| 662 | return true; | ||
| 663 | } | ||
| 578 | bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn) | 664 | bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn) |
| 579 | { | 665 | { |
| 580 | if (unlikely(!__set_phys_to_machine(pfn, mfn))) { | 666 | if (unlikely(!__set_phys_to_machine(pfn, mfn))) { |
| 581 | if (!early_alloc_p2m(pfn)) | 667 | if (!early_alloc_p2m(pfn)) |
| 582 | return false; | 668 | return false; |
| 583 | 669 | ||
| 670 | if (early_can_reuse_p2m_middle(pfn, mfn)) | ||
| 671 | return __set_phys_to_machine(pfn, mfn); | ||
| 672 | |||
| 584 | if (!early_alloc_p2m_middle(pfn, false /* boundary crossover OK!*/)) | 673 | if (!early_alloc_p2m_middle(pfn, false /* boundary crossover OK!*/)) |
| 585 | return false; | 674 | return false; |
| 586 | 675 | ||
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index ead85576d54a..d11ca11d14fc 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
| @@ -78,9 +78,16 @@ static void __init xen_add_extra_mem(u64 start, u64 size) | |||
| 78 | memblock_reserve(start, size); | 78 | memblock_reserve(start, size); |
| 79 | 79 | ||
| 80 | xen_max_p2m_pfn = PFN_DOWN(start + size); | 80 | xen_max_p2m_pfn = PFN_DOWN(start + size); |
| 81 | for (pfn = PFN_DOWN(start); pfn < xen_max_p2m_pfn; pfn++) { | ||
| 82 | unsigned long mfn = pfn_to_mfn(pfn); | ||
| 83 | |||
| 84 | if (WARN(mfn == pfn, "Trying to over-write 1-1 mapping (pfn: %lx)\n", pfn)) | ||
| 85 | continue; | ||
| 86 | WARN(mfn != INVALID_P2M_ENTRY, "Trying to remove %lx which has %lx mfn!\n", | ||
| 87 | pfn, mfn); | ||
| 81 | 88 | ||
| 82 | for (pfn = PFN_DOWN(start); pfn <= xen_max_p2m_pfn; pfn++) | ||
| 83 | __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); | 89 | __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); |
| 90 | } | ||
| 84 | } | 91 | } |
| 85 | 92 | ||
| 86 | static unsigned long __init xen_do_chunk(unsigned long start, | 93 | static unsigned long __init xen_do_chunk(unsigned long start, |
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index ae8a00c39de4..45329c8c226e 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c | |||
| @@ -30,7 +30,7 @@ void xen_arch_hvm_post_suspend(int suspend_cancelled) | |||
| 30 | { | 30 | { |
| 31 | #ifdef CONFIG_XEN_PVHVM | 31 | #ifdef CONFIG_XEN_PVHVM |
| 32 | int cpu; | 32 | int cpu; |
| 33 | xen_hvm_resume_shared_info(); | 33 | xen_hvm_init_shared_info(); |
| 34 | xen_callback_vector(); | 34 | xen_callback_vector(); |
| 35 | xen_unplug_emulated_devices(); | 35 | xen_unplug_emulated_devices(); |
| 36 | if (xen_feature(XENFEAT_hvm_safe_pvclock)) { | 36 | if (xen_feature(XENFEAT_hvm_safe_pvclock)) { |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 1e4329e04e0f..202d4c150154 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
| @@ -41,7 +41,7 @@ void xen_enable_syscall(void); | |||
| 41 | void xen_vcpu_restore(void); | 41 | void xen_vcpu_restore(void); |
| 42 | 42 | ||
| 43 | void xen_callback_vector(void); | 43 | void xen_callback_vector(void); |
| 44 | void xen_hvm_resume_shared_info(void); | 44 | void xen_hvm_init_shared_info(void); |
| 45 | void xen_unplug_emulated_devices(void); | 45 | void xen_unplug_emulated_devices(void); |
| 46 | 46 | ||
| 47 | void __init xen_build_dynamic_phys_to_machine(void); | 47 | void __init xen_build_dynamic_phys_to_machine(void); |
diff --git a/block/blk-lib.c b/block/blk-lib.c index 2b461b496a78..19cc761cacb2 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c | |||
| @@ -44,6 +44,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 44 | struct request_queue *q = bdev_get_queue(bdev); | 44 | struct request_queue *q = bdev_get_queue(bdev); |
| 45 | int type = REQ_WRITE | REQ_DISCARD; | 45 | int type = REQ_WRITE | REQ_DISCARD; |
| 46 | unsigned int max_discard_sectors; | 46 | unsigned int max_discard_sectors; |
| 47 | unsigned int granularity, alignment, mask; | ||
| 47 | struct bio_batch bb; | 48 | struct bio_batch bb; |
| 48 | struct bio *bio; | 49 | struct bio *bio; |
| 49 | int ret = 0; | 50 | int ret = 0; |
| @@ -54,18 +55,20 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 54 | if (!blk_queue_discard(q)) | 55 | if (!blk_queue_discard(q)) |
| 55 | return -EOPNOTSUPP; | 56 | return -EOPNOTSUPP; |
| 56 | 57 | ||
| 58 | /* Zero-sector (unknown) and one-sector granularities are the same. */ | ||
| 59 | granularity = max(q->limits.discard_granularity >> 9, 1U); | ||
| 60 | mask = granularity - 1; | ||
| 61 | alignment = (bdev_discard_alignment(bdev) >> 9) & mask; | ||
| 62 | |||
| 57 | /* | 63 | /* |
| 58 | * Ensure that max_discard_sectors is of the proper | 64 | * Ensure that max_discard_sectors is of the proper |
| 59 | * granularity | 65 | * granularity, so that requests stay aligned after a split. |
| 60 | */ | 66 | */ |
| 61 | max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); | 67 | max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); |
| 68 | max_discard_sectors = round_down(max_discard_sectors, granularity); | ||
| 62 | if (unlikely(!max_discard_sectors)) { | 69 | if (unlikely(!max_discard_sectors)) { |
| 63 | /* Avoid infinite loop below. Being cautious never hurts. */ | 70 | /* Avoid infinite loop below. Being cautious never hurts. */ |
| 64 | return -EOPNOTSUPP; | 71 | return -EOPNOTSUPP; |
| 65 | } else if (q->limits.discard_granularity) { | ||
| 66 | unsigned int disc_sects = q->limits.discard_granularity >> 9; | ||
| 67 | |||
| 68 | max_discard_sectors &= ~(disc_sects - 1); | ||
| 69 | } | 72 | } |
| 70 | 73 | ||
| 71 | if (flags & BLKDEV_DISCARD_SECURE) { | 74 | if (flags & BLKDEV_DISCARD_SECURE) { |
| @@ -79,25 +82,37 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 79 | bb.wait = &wait; | 82 | bb.wait = &wait; |
| 80 | 83 | ||
| 81 | while (nr_sects) { | 84 | while (nr_sects) { |
| 85 | unsigned int req_sects; | ||
| 86 | sector_t end_sect; | ||
| 87 | |||
| 82 | bio = bio_alloc(gfp_mask, 1); | 88 | bio = bio_alloc(gfp_mask, 1); |
| 83 | if (!bio) { | 89 | if (!bio) { |
| 84 | ret = -ENOMEM; | 90 | ret = -ENOMEM; |
| 85 | break; | 91 | break; |
| 86 | } | 92 | } |
| 87 | 93 | ||
| 94 | req_sects = min_t(sector_t, nr_sects, max_discard_sectors); | ||
| 95 | |||
| 96 | /* | ||
| 97 | * If splitting a request, and the next starting sector would be | ||
| 98 | * misaligned, stop the discard at the previous aligned sector. | ||
| 99 | */ | ||
| 100 | end_sect = sector + req_sects; | ||
| 101 | if (req_sects < nr_sects && (end_sect & mask) != alignment) { | ||
| 102 | end_sect = | ||
| 103 | round_down(end_sect - alignment, granularity) | ||
| 104 | + alignment; | ||
| 105 | req_sects = end_sect - sector; | ||
| 106 | } | ||
| 107 | |||
| 88 | bio->bi_sector = sector; | 108 | bio->bi_sector = sector; |
| 89 | bio->bi_end_io = bio_batch_end_io; | 109 | bio->bi_end_io = bio_batch_end_io; |
| 90 | bio->bi_bdev = bdev; | 110 | bio->bi_bdev = bdev; |
| 91 | bio->bi_private = &bb; | 111 | bio->bi_private = &bb; |
| 92 | 112 | ||
| 93 | if (nr_sects > max_discard_sectors) { | 113 | bio->bi_size = req_sects << 9; |
| 94 | bio->bi_size = max_discard_sectors << 9; | 114 | nr_sects -= req_sects; |
| 95 | nr_sects -= max_discard_sectors; | 115 | sector = end_sect; |
| 96 | sector += max_discard_sectors; | ||
| 97 | } else { | ||
| 98 | bio->bi_size = nr_sects << 9; | ||
| 99 | nr_sects = 0; | ||
| 100 | } | ||
| 101 | 116 | ||
| 102 | atomic_inc(&bb.done); | 117 | atomic_inc(&bb.done); |
| 103 | submit_bio(type, bio); | 118 | submit_bio(type, bio); |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 160035f54882..e76279e41162 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
| @@ -110,6 +110,49 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, | |||
| 110 | return 0; | 110 | return 0; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static void | ||
| 114 | __blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec, | ||
| 115 | struct scatterlist *sglist, struct bio_vec **bvprv, | ||
| 116 | struct scatterlist **sg, int *nsegs, int *cluster) | ||
| 117 | { | ||
| 118 | |||
| 119 | int nbytes = bvec->bv_len; | ||
| 120 | |||
| 121 | if (*bvprv && *cluster) { | ||
| 122 | if ((*sg)->length + nbytes > queue_max_segment_size(q)) | ||
| 123 | goto new_segment; | ||
| 124 | |||
| 125 | if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec)) | ||
| 126 | goto new_segment; | ||
| 127 | if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec)) | ||
| 128 | goto new_segment; | ||
| 129 | |||
| 130 | (*sg)->length += nbytes; | ||
| 131 | } else { | ||
| 132 | new_segment: | ||
| 133 | if (!*sg) | ||
| 134 | *sg = sglist; | ||
| 135 | else { | ||
| 136 | /* | ||
| 137 | * If the driver previously mapped a shorter | ||
| 138 | * list, we could see a termination bit | ||
| 139 | * prematurely unless it fully inits the sg | ||
| 140 | * table on each mapping. We KNOW that there | ||
| 141 | * must be more entries here or the driver | ||
| 142 | * would be buggy, so force clear the | ||
| 143 | * termination bit to avoid doing a full | ||
| 144 | * sg_init_table() in drivers for each command. | ||
| 145 | */ | ||
| 146 | (*sg)->page_link &= ~0x02; | ||
| 147 | *sg = sg_next(*sg); | ||
| 148 | } | ||
| 149 | |||
| 150 | sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset); | ||
| 151 | (*nsegs)++; | ||
| 152 | } | ||
| 153 | *bvprv = bvec; | ||
| 154 | } | ||
| 155 | |||
| 113 | /* | 156 | /* |
| 114 | * map a request to scatterlist, return number of sg entries setup. Caller | 157 | * map a request to scatterlist, return number of sg entries setup. Caller |
| 115 | * must make sure sg can hold rq->nr_phys_segments entries | 158 | * must make sure sg can hold rq->nr_phys_segments entries |
| @@ -131,41 +174,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, | |||
| 131 | bvprv = NULL; | 174 | bvprv = NULL; |
| 132 | sg = NULL; | 175 | sg = NULL; |
| 133 | rq_for_each_segment(bvec, rq, iter) { | 176 | rq_for_each_segment(bvec, rq, iter) { |
| 134 | int nbytes = bvec->bv_len; | 177 | __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg, |
| 135 | 178 | &nsegs, &cluster); | |
| 136 | if (bvprv && cluster) { | ||
| 137 | if (sg->length + nbytes > queue_max_segment_size(q)) | ||
| 138 | goto new_segment; | ||
| 139 | |||
| 140 | if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) | ||
| 141 | goto new_segment; | ||
| 142 | if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) | ||
| 143 | goto new_segment; | ||
| 144 | |||
| 145 | sg->length += nbytes; | ||
| 146 | } else { | ||
| 147 | new_segment: | ||
| 148 | if (!sg) | ||
| 149 | sg = sglist; | ||
| 150 | else { | ||
| 151 | /* | ||
| 152 | * If the driver previously mapped a shorter | ||
| 153 | * list, we could see a termination bit | ||
| 154 | * prematurely unless it fully inits the sg | ||
| 155 | * table on each mapping. We KNOW that there | ||
| 156 | * must be more entries here or the driver | ||
| 157 | * would be buggy, so force clear the | ||
| 158 | * termination bit to avoid doing a full | ||
| 159 | * sg_init_table() in drivers for each command. | ||
| 160 | */ | ||
| 161 | sg->page_link &= ~0x02; | ||
| 162 | sg = sg_next(sg); | ||
| 163 | } | ||
| 164 | |||
| 165 | sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset); | ||
| 166 | nsegs++; | ||
| 167 | } | ||
| 168 | bvprv = bvec; | ||
| 169 | } /* segments in rq */ | 179 | } /* segments in rq */ |
| 170 | 180 | ||
| 171 | 181 | ||
| @@ -199,6 +209,43 @@ new_segment: | |||
| 199 | } | 209 | } |
| 200 | EXPORT_SYMBOL(blk_rq_map_sg); | 210 | EXPORT_SYMBOL(blk_rq_map_sg); |
| 201 | 211 | ||
| 212 | /** | ||
| 213 | * blk_bio_map_sg - map a bio to a scatterlist | ||
| 214 | * @q: request_queue in question | ||
| 215 | * @bio: bio being mapped | ||
| 216 | * @sglist: scatterlist being mapped | ||
| 217 | * | ||
| 218 | * Note: | ||
| 219 | * Caller must make sure sg can hold bio->bi_phys_segments entries | ||
| 220 | * | ||
| 221 | * Will return the number of sg entries setup | ||
| 222 | */ | ||
| 223 | int blk_bio_map_sg(struct request_queue *q, struct bio *bio, | ||
| 224 | struct scatterlist *sglist) | ||
| 225 | { | ||
| 226 | struct bio_vec *bvec, *bvprv; | ||
| 227 | struct scatterlist *sg; | ||
| 228 | int nsegs, cluster; | ||
| 229 | unsigned long i; | ||
| 230 | |||
| 231 | nsegs = 0; | ||
| 232 | cluster = blk_queue_cluster(q); | ||
| 233 | |||
| 234 | bvprv = NULL; | ||
| 235 | sg = NULL; | ||
| 236 | bio_for_each_segment(bvec, bio, i) { | ||
| 237 | __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg, | ||
| 238 | &nsegs, &cluster); | ||
| 239 | } /* segments in bio */ | ||
| 240 | |||
| 241 | if (sg) | ||
| 242 | sg_mark_end(sg); | ||
| 243 | |||
| 244 | BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments); | ||
| 245 | return nsegs; | ||
| 246 | } | ||
| 247 | EXPORT_SYMBOL(blk_bio_map_sg); | ||
| 248 | |||
| 202 | static inline int ll_new_hw_segment(struct request_queue *q, | 249 | static inline int ll_new_hw_segment(struct request_queue *q, |
| 203 | struct request *req, | 250 | struct request *req, |
| 204 | struct bio *bio) | 251 | struct bio *bio) |
diff --git a/block/genhd.c b/block/genhd.c index cac7366957c3..d839723303c8 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -835,7 +835,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v) | |||
| 835 | 835 | ||
| 836 | static void *show_partition_start(struct seq_file *seqf, loff_t *pos) | 836 | static void *show_partition_start(struct seq_file *seqf, loff_t *pos) |
| 837 | { | 837 | { |
| 838 | static void *p; | 838 | void *p; |
| 839 | 839 | ||
| 840 | p = disk_seqf_start(seqf, pos); | 840 | p = disk_seqf_start(seqf, pos); |
| 841 | if (!IS_ERR_OR_NULL(p) && !*pos) | 841 | if (!IS_ERR_OR_NULL(p) && !*pos) |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2be8ef1d3093..27cecd313e75 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -115,7 +115,7 @@ config SATA_SIL24 | |||
| 115 | If unsure, say N. | 115 | If unsure, say N. |
| 116 | 116 | ||
| 117 | config ATA_SFF | 117 | config ATA_SFF |
| 118 | bool "ATA SFF support" | 118 | bool "ATA SFF support (for legacy IDE and PATA)" |
| 119 | default y | 119 | default y |
| 120 | help | 120 | help |
| 121 | This option adds support for ATA controllers with SFF | 121 | This option adds support for ATA controllers with SFF |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 062e6a1a248f..50d5dea0ff59 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -256,6 +256,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 256 | { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ | 256 | { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ |
| 257 | { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ | 257 | { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ |
| 258 | { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ | 258 | { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ |
| 259 | { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ | ||
| 260 | { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ | ||
| 261 | { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ | ||
| 262 | { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */ | ||
| 263 | { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */ | ||
| 264 | { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */ | ||
| 265 | { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */ | ||
| 266 | { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */ | ||
| 259 | 267 | ||
| 260 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 268 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
| 261 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 269 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index c2594ddf25b0..57eb1c212a4c 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
| @@ -320,6 +320,7 @@ extern struct device_attribute *ahci_sdev_attrs[]; | |||
| 320 | extern struct ata_port_operations ahci_ops; | 320 | extern struct ata_port_operations ahci_ops; |
| 321 | extern struct ata_port_operations ahci_pmp_retry_srst_ops; | 321 | extern struct ata_port_operations ahci_pmp_retry_srst_ops; |
| 322 | 322 | ||
| 323 | unsigned int ahci_dev_classify(struct ata_port *ap); | ||
| 323 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 324 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
| 324 | u32 opts); | 325 | u32 opts); |
| 325 | void ahci_save_initial_config(struct device *dev, | 326 | void ahci_save_initial_config(struct device *dev, |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3c809bfbccf5..ef773e12af79 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
| @@ -329,6 +329,14 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
| 329 | { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 329 | { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| 330 | /* SATA Controller IDE (Lynx Point) */ | 330 | /* SATA Controller IDE (Lynx Point) */ |
| 331 | { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 331 | { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| 332 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
| 333 | { 0x8086, 0x9c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
| 334 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
| 335 | { 0x8086, 0x9c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
| 336 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
| 337 | { 0x8086, 0x9c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
| 338 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
| 339 | { 0x8086, 0x9c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
| 332 | /* SATA Controller IDE (DH89xxCC) */ | 340 | /* SATA Controller IDE (DH89xxCC) */ |
| 333 | { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 341 | { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| 334 | { } /* terminate list */ | 342 | { } /* terminate list */ |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index f9eaa82311a9..555c07afa05b 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -1139,7 +1139,7 @@ static void ahci_dev_config(struct ata_device *dev) | |||
| 1139 | } | 1139 | } |
| 1140 | } | 1140 | } |
| 1141 | 1141 | ||
| 1142 | static unsigned int ahci_dev_classify(struct ata_port *ap) | 1142 | unsigned int ahci_dev_classify(struct ata_port *ap) |
| 1143 | { | 1143 | { |
| 1144 | void __iomem *port_mmio = ahci_port_base(ap); | 1144 | void __iomem *port_mmio = ahci_port_base(ap); |
| 1145 | struct ata_taskfile tf; | 1145 | struct ata_taskfile tf; |
| @@ -1153,6 +1153,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
| 1153 | 1153 | ||
| 1154 | return ata_dev_classify(&tf); | 1154 | return ata_dev_classify(&tf); |
| 1155 | } | 1155 | } |
| 1156 | EXPORT_SYMBOL_GPL(ahci_dev_classify); | ||
| 1156 | 1157 | ||
| 1157 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 1158 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
| 1158 | u32 opts) | 1159 | u32 opts) |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 902b5a457170..fd9ecf74e631 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
| @@ -60,17 +60,7 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap) | |||
| 60 | if (ap->flags & ATA_FLAG_ACPI_SATA) | 60 | if (ap->flags & ATA_FLAG_ACPI_SATA) |
| 61 | return NULL; | 61 | return NULL; |
| 62 | 62 | ||
| 63 | /* | 63 | return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no); |
| 64 | * If acpi bind operation has already happened, we can get the handle | ||
| 65 | * for the port by checking the corresponding scsi_host device's | ||
| 66 | * firmware node, otherwise we will need to find out the handle from | ||
| 67 | * its parent's acpi node. | ||
| 68 | */ | ||
| 69 | if (ap->scsi_host) | ||
| 70 | return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev); | ||
| 71 | else | ||
| 72 | return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), | ||
| 73 | ap->port_no); | ||
| 74 | } | 64 | } |
| 75 | EXPORT_SYMBOL(ata_ap_acpi_handle); | 65 | EXPORT_SYMBOL(ata_ap_acpi_handle); |
| 76 | 66 | ||
| @@ -1101,6 +1091,9 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle) | |||
| 1101 | if (!*handle) | 1091 | if (!*handle) |
| 1102 | return -ENODEV; | 1092 | return -ENODEV; |
| 1103 | 1093 | ||
| 1094 | if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) | ||
| 1095 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | ||
| 1096 | |||
| 1104 | return 0; | 1097 | return 0; |
| 1105 | } | 1098 | } |
| 1106 | 1099 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fadd5866d40f..8e1039c8e159 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4062,7 +4062,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4062 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, | 4062 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, |
| 4063 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, | 4063 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, |
| 4064 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, | 4064 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, |
| 4065 | { "2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA }, | 4065 | { " 2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA }, |
| 4066 | /* Odd clown on sil3726/4726 PMPs */ | 4066 | /* Odd clown on sil3726/4726 PMPs */ |
| 4067 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, | 4067 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, |
| 4068 | 4068 | ||
| @@ -4128,6 +4128,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4128 | 4128 | ||
| 4129 | /* Devices that do not need bridging limits applied */ | 4129 | /* Devices that do not need bridging limits applied */ |
| 4130 | { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, | 4130 | { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, |
| 4131 | { "BUFFALO HD-QSU2/R5", NULL, ATA_HORKAGE_BRIDGE_OK, }, | ||
| 4131 | 4132 | ||
| 4132 | /* Devices which aren't very happy with higher link speeds */ | 4133 | /* Devices which aren't very happy with higher link speeds */ |
| 4133 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, | 4134 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, |
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 361c75cea57b..24e51056ac26 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 21 | #include <scsi/scsi_host.h> | 21 | #include <scsi/scsi_host.h> |
| 22 | #include <linux/libata.h> | 22 | #include <linux/libata.h> |
| 23 | #include <linux/dmi.h> | ||
| 23 | 24 | ||
| 24 | #define DRV_NAME "pata_atiixp" | 25 | #define DRV_NAME "pata_atiixp" |
| 25 | #define DRV_VERSION "0.4.6" | 26 | #define DRV_VERSION "0.4.6" |
| @@ -33,11 +34,26 @@ enum { | |||
| 33 | ATIIXP_IDE_UDMA_MODE = 0x56 | 34 | ATIIXP_IDE_UDMA_MODE = 0x56 |
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 37 | static const struct dmi_system_id attixp_cable_override_dmi_table[] = { | ||
| 38 | { | ||
| 39 | /* Board has onboard PATA<->SATA converters */ | ||
| 40 | .ident = "MSI E350DM-E33", | ||
| 41 | .matches = { | ||
| 42 | DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), | ||
| 43 | DMI_MATCH(DMI_BOARD_NAME, "E350DM-E33(MS-7720)"), | ||
| 44 | }, | ||
| 45 | }, | ||
| 46 | { } | ||
| 47 | }; | ||
| 48 | |||
| 36 | static int atiixp_cable_detect(struct ata_port *ap) | 49 | static int atiixp_cable_detect(struct ata_port *ap) |
| 37 | { | 50 | { |
| 38 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 51 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
| 39 | u8 udma; | 52 | u8 udma; |
| 40 | 53 | ||
| 54 | if (dmi_check_system(attixp_cable_override_dmi_table)) | ||
| 55 | return ATA_CBL_PATA40_SHORT; | ||
| 56 | |||
| 41 | /* Hack from drivers/ide/pci. Really we want to know how to do the | 57 | /* Hack from drivers/ide/pci. Really we want to know how to do the |
| 42 | raw detection not play follow the bios mode guess */ | 58 | raw detection not play follow the bios mode guess */ |
| 43 | pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); | 59 | pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index ba91b408abad..d84566496746 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c | |||
| @@ -889,6 +889,7 @@ struct bm_aio_ctx { | |||
| 889 | unsigned int done; | 889 | unsigned int done; |
| 890 | unsigned flags; | 890 | unsigned flags; |
| 891 | #define BM_AIO_COPY_PAGES 1 | 891 | #define BM_AIO_COPY_PAGES 1 |
| 892 | #define BM_WRITE_ALL_PAGES 2 | ||
| 892 | int error; | 893 | int error; |
| 893 | struct kref kref; | 894 | struct kref kref; |
| 894 | }; | 895 | }; |
| @@ -1059,7 +1060,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w | |||
| 1059 | if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) | 1060 | if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) |
| 1060 | break; | 1061 | break; |
| 1061 | if (rw & WRITE) { | 1062 | if (rw & WRITE) { |
| 1062 | if (bm_test_page_unchanged(b->bm_pages[i])) { | 1063 | if (!(flags & BM_WRITE_ALL_PAGES) && |
| 1064 | bm_test_page_unchanged(b->bm_pages[i])) { | ||
| 1063 | dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); | 1065 | dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); |
| 1064 | continue; | 1066 | continue; |
| 1065 | } | 1067 | } |
| @@ -1141,6 +1143,17 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local) | |||
| 1141 | } | 1143 | } |
| 1142 | 1144 | ||
| 1143 | /** | 1145 | /** |
| 1146 | * drbd_bm_write_all() - Write the whole bitmap to its on disk location. | ||
| 1147 | * @mdev: DRBD device. | ||
| 1148 | * | ||
| 1149 | * Will write all pages. | ||
| 1150 | */ | ||
| 1151 | int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local) | ||
| 1152 | { | ||
| 1153 | return bm_rw(mdev, WRITE, BM_WRITE_ALL_PAGES, 0); | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | /** | ||
| 1144 | * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed. | 1157 | * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed. |
| 1145 | * @mdev: DRBD device. | 1158 | * @mdev: DRBD device. |
| 1146 | * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages | 1159 | * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index b2ca143d0053..b953cc7c9c00 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
| @@ -1469,6 +1469,7 @@ extern int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr); | |||
| 1469 | extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); | 1469 | extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); |
| 1470 | extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); | 1470 | extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); |
| 1471 | extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); | 1471 | extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); |
| 1472 | extern int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local); | ||
| 1472 | extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local); | 1473 | extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local); |
| 1473 | extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, | 1474 | extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, |
| 1474 | unsigned long al_enr); | 1475 | unsigned long al_enr); |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index dbe6135a2abe..f93a0320e952 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
| @@ -79,6 +79,7 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused); | |||
| 79 | static void md_sync_timer_fn(unsigned long data); | 79 | static void md_sync_timer_fn(unsigned long data); |
| 80 | static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused); | 80 | static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused); |
| 81 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused); | 81 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused); |
| 82 | static void _tl_clear(struct drbd_conf *mdev); | ||
| 82 | 83 | ||
| 83 | MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, " | 84 | MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, " |
| 84 | "Lars Ellenberg <lars@linbit.com>"); | 85 | "Lars Ellenberg <lars@linbit.com>"); |
| @@ -432,19 +433,10 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) | |||
| 432 | 433 | ||
| 433 | /* Actions operating on the disk state, also want to work on | 434 | /* Actions operating on the disk state, also want to work on |
| 434 | requests that got barrier acked. */ | 435 | requests that got barrier acked. */ |
| 435 | switch (what) { | ||
| 436 | case fail_frozen_disk_io: | ||
| 437 | case restart_frozen_disk_io: | ||
| 438 | list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { | ||
| 439 | req = list_entry(le, struct drbd_request, tl_requests); | ||
| 440 | _req_mod(req, what); | ||
| 441 | } | ||
| 442 | 436 | ||
| 443 | case connection_lost_while_pending: | 437 | list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { |
| 444 | case resend: | 438 | req = list_entry(le, struct drbd_request, tl_requests); |
| 445 | break; | 439 | _req_mod(req, what); |
| 446 | default: | ||
| 447 | dev_err(DEV, "what = %d in _tl_restart()\n", what); | ||
| 448 | } | 440 | } |
| 449 | } | 441 | } |
| 450 | 442 | ||
| @@ -459,11 +451,16 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) | |||
| 459 | */ | 451 | */ |
| 460 | void tl_clear(struct drbd_conf *mdev) | 452 | void tl_clear(struct drbd_conf *mdev) |
| 461 | { | 453 | { |
| 454 | spin_lock_irq(&mdev->req_lock); | ||
| 455 | _tl_clear(mdev); | ||
| 456 | spin_unlock_irq(&mdev->req_lock); | ||
| 457 | } | ||
| 458 | |||
| 459 | static void _tl_clear(struct drbd_conf *mdev) | ||
| 460 | { | ||
| 462 | struct list_head *le, *tle; | 461 | struct list_head *le, *tle; |
| 463 | struct drbd_request *r; | 462 | struct drbd_request *r; |
| 464 | 463 | ||
| 465 | spin_lock_irq(&mdev->req_lock); | ||
| 466 | |||
| 467 | _tl_restart(mdev, connection_lost_while_pending); | 464 | _tl_restart(mdev, connection_lost_while_pending); |
| 468 | 465 | ||
| 469 | /* we expect this list to be empty. */ | 466 | /* we expect this list to be empty. */ |
| @@ -482,7 +479,6 @@ void tl_clear(struct drbd_conf *mdev) | |||
| 482 | 479 | ||
| 483 | memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); | 480 | memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); |
| 484 | 481 | ||
| 485 | spin_unlock_irq(&mdev->req_lock); | ||
| 486 | } | 482 | } |
| 487 | 483 | ||
| 488 | void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) | 484 | void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) |
| @@ -1476,12 +1472,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
| 1476 | if (ns.susp_fen) { | 1472 | if (ns.susp_fen) { |
| 1477 | /* case1: The outdate peer handler is successful: */ | 1473 | /* case1: The outdate peer handler is successful: */ |
| 1478 | if (os.pdsk > D_OUTDATED && ns.pdsk <= D_OUTDATED) { | 1474 | if (os.pdsk > D_OUTDATED && ns.pdsk <= D_OUTDATED) { |
| 1479 | tl_clear(mdev); | ||
| 1480 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { | 1475 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { |
| 1481 | drbd_uuid_new_current(mdev); | 1476 | drbd_uuid_new_current(mdev); |
| 1482 | clear_bit(NEW_CUR_UUID, &mdev->flags); | 1477 | clear_bit(NEW_CUR_UUID, &mdev->flags); |
| 1483 | } | 1478 | } |
| 1484 | spin_lock_irq(&mdev->req_lock); | 1479 | spin_lock_irq(&mdev->req_lock); |
| 1480 | _tl_clear(mdev); | ||
| 1485 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); | 1481 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); |
| 1486 | spin_unlock_irq(&mdev->req_lock); | 1482 | spin_unlock_irq(&mdev->req_lock); |
| 1487 | } | 1483 | } |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index fb9dce8daa24..edb490aad8b4 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
| @@ -674,8 +674,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds | |||
| 674 | la_size_changed && md_moved ? "size changed and md moved" : | 674 | la_size_changed && md_moved ? "size changed and md moved" : |
| 675 | la_size_changed ? "size changed" : "md moved"); | 675 | la_size_changed ? "size changed" : "md moved"); |
| 676 | /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ | 676 | /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ |
| 677 | err = drbd_bitmap_io(mdev, &drbd_bm_write, | 677 | err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write, |
| 678 | "size changed", BM_LOCKED_MASK); | 678 | "size changed", BM_LOCKED_MASK); |
| 679 | if (err) { | 679 | if (err) { |
| 680 | rv = dev_size_error; | 680 | rv = dev_size_error; |
| 681 | goto out; | 681 | goto out; |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 910335c30927..01b2ac641c7b 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
| @@ -695,6 +695,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
| 695 | break; | 695 | break; |
| 696 | 696 | ||
| 697 | case resend: | 697 | case resend: |
| 698 | /* Simply complete (local only) READs. */ | ||
| 699 | if (!(req->rq_state & RQ_WRITE) && !req->w.cb) { | ||
| 700 | _req_may_be_done(req, m); | ||
| 701 | break; | ||
| 702 | } | ||
| 703 | |||
| 698 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK | 704 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK |
| 699 | before the connection loss (B&C only); only P_BARRIER_ACK was missing. | 705 | before the connection loss (B&C only); only P_BARRIER_ACK was missing. |
| 700 | Trowing them out of the TL here by pretending we got a BARRIER_ACK | 706 | Trowing them out of the TL here by pretending we got a BARRIER_ACK |
| @@ -834,7 +840,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns | |||
| 834 | req->private_bio = NULL; | 840 | req->private_bio = NULL; |
| 835 | } | 841 | } |
| 836 | if (rw == WRITE) { | 842 | if (rw == WRITE) { |
| 837 | remote = 1; | 843 | /* Need to replicate writes. Unless it is an empty flush, |
| 844 | * which is better mapped to a DRBD P_BARRIER packet, | ||
| 845 | * also for drbd wire protocol compatibility reasons. */ | ||
| 846 | if (unlikely(size == 0)) { | ||
| 847 | /* The only size==0 bios we expect are empty flushes. */ | ||
| 848 | D_ASSERT(bio->bi_rw & REQ_FLUSH); | ||
| 849 | remote = 0; | ||
| 850 | } else | ||
| 851 | remote = 1; | ||
| 838 | } else { | 852 | } else { |
| 839 | /* READ || READA */ | 853 | /* READ || READA */ |
| 840 | if (local) { | 854 | if (local) { |
| @@ -870,8 +884,11 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns | |||
| 870 | * extent. This waits for any resync activity in the corresponding | 884 | * extent. This waits for any resync activity in the corresponding |
| 871 | * resync extent to finish, and, if necessary, pulls in the target | 885 | * resync extent to finish, and, if necessary, pulls in the target |
| 872 | * extent into the activity log, which involves further disk io because | 886 | * extent into the activity log, which involves further disk io because |
| 873 | * of transactional on-disk meta data updates. */ | 887 | * of transactional on-disk meta data updates. |
| 874 | if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) { | 888 | * Empty flushes don't need to go into the activity log, they can only |
| 889 | * flush data for pending writes which are already in there. */ | ||
| 890 | if (rw == WRITE && local && size | ||
| 891 | && !test_bit(AL_SUSPENDED, &mdev->flags)) { | ||
| 875 | req->rq_state |= RQ_IN_ACT_LOG; | 892 | req->rq_state |= RQ_IN_ACT_LOG; |
| 876 | drbd_al_begin_io(mdev, sector); | 893 | drbd_al_begin_io(mdev, sector); |
| 877 | } | 894 | } |
| @@ -994,7 +1011,10 @@ allocate_barrier: | |||
| 994 | if (rw == WRITE && _req_conflicts(req)) | 1011 | if (rw == WRITE && _req_conflicts(req)) |
| 995 | goto fail_conflicting; | 1012 | goto fail_conflicting; |
| 996 | 1013 | ||
| 997 | list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); | 1014 | /* no point in adding empty flushes to the transfer log, |
| 1015 | * they are mapped to drbd barriers already. */ | ||
| 1016 | if (likely(size!=0)) | ||
| 1017 | list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); | ||
| 998 | 1018 | ||
| 999 | /* NOTE remote first: to get the concurrent write detection right, | 1019 | /* NOTE remote first: to get the concurrent write detection right, |
| 1000 | * we must register the request before start of local IO. */ | 1020 | * we must register the request before start of local IO. */ |
| @@ -1014,6 +1034,14 @@ allocate_barrier: | |||
| 1014 | mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) | 1034 | mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) |
| 1015 | maybe_pull_ahead(mdev); | 1035 | maybe_pull_ahead(mdev); |
| 1016 | 1036 | ||
| 1037 | /* If this was a flush, queue a drbd barrier/start a new epoch. | ||
| 1038 | * Unless the current epoch was empty anyways, or we are not currently | ||
| 1039 | * replicating, in which case there is no point. */ | ||
| 1040 | if (unlikely(bio->bi_rw & REQ_FLUSH) | ||
| 1041 | && mdev->newest_tle->n_writes | ||
| 1042 | && drbd_should_do_remote(mdev->state)) | ||
| 1043 | queue_barrier(mdev); | ||
| 1044 | |||
| 1017 | spin_unlock_irq(&mdev->req_lock); | 1045 | spin_unlock_irq(&mdev->req_lock); |
| 1018 | kfree(b); /* if someone else has beaten us to it... */ | 1046 | kfree(b); /* if someone else has beaten us to it... */ |
| 1019 | 1047 | ||
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 17fa04d08be9..b47034e650a5 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c | |||
| @@ -218,7 +218,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | |||
| 218 | 218 | ||
| 219 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | 219 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); |
| 220 | 220 | ||
| 221 | if (atomic_inc_return(&freq_table_users) == 1) | 221 | if (!freq_table) |
| 222 | result = opp_init_cpufreq_table(mpu_dev, &freq_table); | 222 | result = opp_init_cpufreq_table(mpu_dev, &freq_table); |
| 223 | 223 | ||
| 224 | if (result) { | 224 | if (result) { |
| @@ -227,6 +227,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | |||
| 227 | goto fail_ck; | 227 | goto fail_ck; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | atomic_inc_return(&freq_table_users); | ||
| 231 | |||
| 230 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | 232 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); |
| 231 | if (result) | 233 | if (result) |
| 232 | goto fail_table; | 234 | goto fail_table; |
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 53c8c51d5881..93d14070141a 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c | |||
| @@ -63,7 +63,7 @@ static void caam_jr_dequeue(unsigned long devarg) | |||
| 63 | 63 | ||
| 64 | head = ACCESS_ONCE(jrp->head); | 64 | head = ACCESS_ONCE(jrp->head); |
| 65 | 65 | ||
| 66 | spin_lock_bh(&jrp->outlock); | 66 | spin_lock(&jrp->outlock); |
| 67 | 67 | ||
| 68 | sw_idx = tail = jrp->tail; | 68 | sw_idx = tail = jrp->tail; |
| 69 | hw_idx = jrp->out_ring_read_index; | 69 | hw_idx = jrp->out_ring_read_index; |
| @@ -115,7 +115,7 @@ static void caam_jr_dequeue(unsigned long devarg) | |||
| 115 | jrp->tail = tail; | 115 | jrp->tail = tail; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | spin_unlock_bh(&jrp->outlock); | 118 | spin_unlock(&jrp->outlock); |
| 119 | 119 | ||
| 120 | /* Finally, execute user's callback */ | 120 | /* Finally, execute user's callback */ |
| 121 | usercall(dev, userdesc, userstatus, userarg); | 121 | usercall(dev, userdesc, userstatus, userarg); |
| @@ -236,14 +236,14 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, | |||
| 236 | return -EIO; | 236 | return -EIO; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | spin_lock(&jrp->inplock); | 239 | spin_lock_bh(&jrp->inplock); |
| 240 | 240 | ||
| 241 | head = jrp->head; | 241 | head = jrp->head; |
| 242 | tail = ACCESS_ONCE(jrp->tail); | 242 | tail = ACCESS_ONCE(jrp->tail); |
| 243 | 243 | ||
| 244 | if (!rd_reg32(&jrp->rregs->inpring_avail) || | 244 | if (!rd_reg32(&jrp->rregs->inpring_avail) || |
| 245 | CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { | 245 | CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { |
| 246 | spin_unlock(&jrp->inplock); | 246 | spin_unlock_bh(&jrp->inplock); |
| 247 | dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); | 247 | dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); |
| 248 | return -EBUSY; | 248 | return -EBUSY; |
| 249 | } | 249 | } |
| @@ -265,7 +265,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, | |||
| 265 | 265 | ||
| 266 | wr_reg32(&jrp->rregs->inpring_jobadd, 1); | 266 | wr_reg32(&jrp->rregs->inpring_jobadd, 1); |
| 267 | 267 | ||
| 268 | spin_unlock(&jrp->inplock); | 268 | spin_unlock_bh(&jrp->inplock); |
| 269 | 269 | ||
| 270 | return 0; | 270 | return 0; |
| 271 | } | 271 | } |
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index c9c4befb5a8d..df14358d7fa1 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c | |||
| @@ -821,8 +821,8 @@ static int hifn_register_rng(struct hifn_device *dev) | |||
| 821 | /* | 821 | /* |
| 822 | * We must wait at least 256 Pk_clk cycles between two reads of the rng. | 822 | * We must wait at least 256 Pk_clk cycles between two reads of the rng. |
| 823 | */ | 823 | */ |
| 824 | dev->rng_wait_time = DIV_ROUND_UP(NSEC_PER_SEC, dev->pk_clk_freq) * | 824 | dev->rng_wait_time = DIV_ROUND_UP_ULL(NSEC_PER_SEC, |
| 825 | 256; | 825 | dev->pk_clk_freq) * 256; |
| 826 | 826 | ||
| 827 | dev->rng.name = dev->name; | 827 | dev->rng.name = dev->name; |
| 828 | dev->rng.data_present = hifn_rng_data_present, | 828 | dev->rng.data_present = hifn_rng_data_present, |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 08a7aa722d6b..6fbfc244748f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, | |||
| 1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 1982 | return -EINVAL; | 1982 | return -EINVAL; |
| 1983 | 1983 | ||
| 1984 | if (!req->flags) | 1984 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
| 1985 | return -EINVAL; | 1985 | return -EINVAL; |
| 1986 | 1986 | ||
| 1987 | mutex_lock(&dev->mode_config.mutex); | 1987 | mutex_lock(&dev->mode_config.mutex); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a8743c399e83..b7ee230572b7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -87,6 +87,9 @@ static struct edid_quirk { | |||
| 87 | int product_id; | 87 | int product_id; |
| 88 | u32 quirks; | 88 | u32 quirks; |
| 89 | } edid_quirk_list[] = { | 89 | } edid_quirk_list[] = { |
| 90 | /* ASUS VW222S */ | ||
| 91 | { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, | ||
| 92 | |||
| 90 | /* Acer AL1706 */ | 93 | /* Acer AL1706 */ |
| 91 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, | 94 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, |
| 92 | /* Acer F51 */ | 95 | /* Acer F51 */ |
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 30dc22a7156c..8033526bb53b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c | |||
| @@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, | |||
| 1362 | (struct drm_connector **) (psb_intel_crtc + 1); | 1362 | (struct drm_connector **) (psb_intel_crtc + 1); |
| 1363 | psb_intel_crtc->mode_set.num_connectors = 0; | 1363 | psb_intel_crtc->mode_set.num_connectors = 0; |
| 1364 | psb_intel_cursor_init(dev, psb_intel_crtc); | 1364 | psb_intel_cursor_init(dev, psb_intel_crtc); |
| 1365 | |||
| 1366 | /* Set to true so that the pipe is forced off on initial config. */ | ||
| 1367 | psb_intel_crtc->active = true; | ||
| 1365 | } | 1368 | } |
| 1366 | 1369 | ||
| 1367 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 1370 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d9a5372ec56f..60815b861ec2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
| 72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 | 72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 |
| 73 | * entries. For aliasing ppgtt support we just steal them at the end for | 73 | * entries. For aliasing ppgtt support we just steal them at the end for |
| 74 | * now. */ | 74 | * now. */ |
| 75 | first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; | 75 | first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES; |
| 76 | 76 | ||
| 77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); | 77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); |
| 78 | if (!ppgtt) | 78 | if (!ppgtt) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a69a3d0d3acf..2dfa6cf4886b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -1384,7 +1384,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
| 1384 | enum pipe pipe, int reg) | 1384 | enum pipe pipe, int reg) |
| 1385 | { | 1385 | { |
| 1386 | u32 val = I915_READ(reg); | 1386 | u32 val = I915_READ(reg); |
| 1387 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), | 1387 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), |
| 1388 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | 1388 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
| 1389 | reg, pipe_name(pipe)); | 1389 | reg, pipe_name(pipe)); |
| 1390 | 1390 | ||
| @@ -1404,13 +1404,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | |||
| 1404 | 1404 | ||
| 1405 | reg = PCH_ADPA; | 1405 | reg = PCH_ADPA; |
| 1406 | val = I915_READ(reg); | 1406 | val = I915_READ(reg); |
| 1407 | WARN(adpa_pipe_enabled(dev_priv, val, pipe), | 1407 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), |
| 1408 | "PCH VGA enabled on transcoder %c, should be disabled\n", | 1408 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
| 1409 | pipe_name(pipe)); | 1409 | pipe_name(pipe)); |
| 1410 | 1410 | ||
| 1411 | reg = PCH_LVDS; | 1411 | reg = PCH_LVDS; |
| 1412 | val = I915_READ(reg); | 1412 | val = I915_READ(reg); |
| 1413 | WARN(lvds_pipe_enabled(dev_priv, val, pipe), | 1413 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), |
| 1414 | "PCH LVDS enabled on transcoder %c, should be disabled\n", | 1414 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
| 1415 | pipe_name(pipe)); | 1415 | pipe_name(pipe)); |
| 1416 | 1416 | ||
| @@ -1872,7 +1872,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv, | |||
| 1872 | enum pipe pipe, int reg) | 1872 | enum pipe pipe, int reg) |
| 1873 | { | 1873 | { |
| 1874 | u32 val = I915_READ(reg); | 1874 | u32 val = I915_READ(reg); |
| 1875 | if (hdmi_pipe_enabled(dev_priv, val, pipe)) { | 1875 | if (hdmi_pipe_enabled(dev_priv, pipe, val)) { |
| 1876 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", | 1876 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", |
| 1877 | reg, pipe); | 1877 | reg, pipe); |
| 1878 | I915_WRITE(reg, val & ~PORT_ENABLE); | 1878 | I915_WRITE(reg, val & ~PORT_ENABLE); |
| @@ -1894,12 +1894,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, | |||
| 1894 | 1894 | ||
| 1895 | reg = PCH_ADPA; | 1895 | reg = PCH_ADPA; |
| 1896 | val = I915_READ(reg); | 1896 | val = I915_READ(reg); |
| 1897 | if (adpa_pipe_enabled(dev_priv, val, pipe)) | 1897 | if (adpa_pipe_enabled(dev_priv, pipe, val)) |
| 1898 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); | 1898 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); |
| 1899 | 1899 | ||
| 1900 | reg = PCH_LVDS; | 1900 | reg = PCH_LVDS; |
| 1901 | val = I915_READ(reg); | 1901 | val = I915_READ(reg); |
| 1902 | if (lvds_pipe_enabled(dev_priv, val, pipe)) { | 1902 | if (lvds_pipe_enabled(dev_priv, pipe, val)) { |
| 1903 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); | 1903 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); |
| 1904 | I915_WRITE(reg, val & ~LVDS_PORT_EN); | 1904 | I915_WRITE(reg, val & ~LVDS_PORT_EN); |
| 1905 | POSTING_READ(reg); | 1905 | POSTING_READ(reg); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e05c0d3e3440..e9a6f6aaed85 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), | 780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), |
| 781 | }, | 781 | }, |
| 782 | }, | 782 | }, |
| 783 | { | ||
| 784 | .callback = intel_no_lvds_dmi_callback, | ||
| 785 | .ident = "Gigabyte GA-D525TUD", | ||
| 786 | .matches = { | ||
| 787 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), | ||
| 788 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), | ||
| 789 | }, | ||
| 790 | }, | ||
| 783 | 791 | ||
| 784 | { } /* terminating entry */ | 792 | { } /* terminating entry */ |
| 785 | }; | 793 | }; |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index cc8df4de2d92..7644f31a3778 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
| @@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
| 60 | 60 | ||
| 61 | switch (fb->pixel_format) { | 61 | switch (fb->pixel_format) { |
| 62 | case DRM_FORMAT_XBGR8888: | 62 | case DRM_FORMAT_XBGR8888: |
| 63 | sprctl |= SPRITE_FORMAT_RGBX888; | 63 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
| 64 | pixel_size = 4; | 64 | pixel_size = 4; |
| 65 | break; | 65 | break; |
| 66 | case DRM_FORMAT_XRGB8888: | 66 | case DRM_FORMAT_XRGB8888: |
| 67 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; | 67 | sprctl |= SPRITE_FORMAT_RGBX888; |
| 68 | pixel_size = 4; | 68 | pixel_size = 4; |
| 69 | break; | 69 | break; |
| 70 | case DRM_FORMAT_YUYV: | 70 | case DRM_FORMAT_YUYV: |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1866dbb49979..c61014442aa9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
| @@ -736,9 +736,11 @@ nouveau_card_init(struct drm_device *dev) | |||
| 736 | } | 736 | } |
| 737 | break; | 737 | break; |
| 738 | case NV_C0: | 738 | case NV_C0: |
| 739 | nvc0_copy_create(dev, 1); | 739 | if (!(nv_rd32(dev, 0x022500) & 0x00000200)) |
| 740 | nvc0_copy_create(dev, 1); | ||
| 740 | case NV_D0: | 741 | case NV_D0: |
| 741 | nvc0_copy_create(dev, 0); | 742 | if (!(nv_rd32(dev, 0x022500) & 0x00000100)) |
| 743 | nvc0_copy_create(dev, 0); | ||
| 742 | break; | 744 | break; |
| 743 | default: | 745 | default: |
| 744 | break; | 746 | break; |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index f4d4505fe831..2817101fb167 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 258 | radeon_crtc->enabled = true; | 258 | radeon_crtc->enabled = true; |
| 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
| 260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
| 261 | /* disable crtc pair power gating before programming */ | ||
| 262 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) | 261 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
| 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 262 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
| 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 263 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
| @@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 278 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); | 277 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
| 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 278 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
| 280 | radeon_crtc->enabled = false; | 279 | radeon_crtc->enabled = false; |
| 281 | /* power gating is per-pair */ | 280 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
| 282 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { | 281 | atombios_powergate_crtc(crtc, ATOM_ENABLE); |
| 283 | struct drm_crtc *other_crtc; | ||
| 284 | struct radeon_crtc *other_radeon_crtc; | ||
| 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | ||
| 286 | other_radeon_crtc = to_radeon_crtc(other_crtc); | ||
| 287 | if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || | ||
| 288 | ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || | ||
| 289 | ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || | ||
| 290 | ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || | ||
| 291 | ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || | ||
| 292 | ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { | ||
| 293 | /* if both crtcs in the pair are off, enable power gating */ | ||
| 294 | if (other_radeon_crtc->enabled == false) | ||
| 295 | atombios_powergate_crtc(crtc, ATOM_ENABLE); | ||
| 296 | break; | ||
| 297 | } | ||
| 298 | } | ||
| 299 | } | ||
| 300 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 282 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
| 301 | radeon_pm_compute_clocks(rdev); | 283 | radeon_pm_compute_clocks(rdev); |
| 302 | break; | 284 | break; |
| @@ -1682,9 +1664,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
| 1682 | struct drm_device *dev = crtc->dev; | 1664 | struct drm_device *dev = crtc->dev; |
| 1683 | struct radeon_device *rdev = dev->dev_private; | 1665 | struct radeon_device *rdev = dev->dev_private; |
| 1684 | struct radeon_atom_ss ss; | 1666 | struct radeon_atom_ss ss; |
| 1667 | int i; | ||
| 1685 | 1668 | ||
| 1686 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1669 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
| 1687 | 1670 | ||
| 1671 | for (i = 0; i < rdev->num_crtc; i++) { | ||
| 1672 | if (rdev->mode_info.crtcs[i] && | ||
| 1673 | rdev->mode_info.crtcs[i]->enabled && | ||
| 1674 | i != radeon_crtc->crtc_id && | ||
| 1675 | radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { | ||
| 1676 | /* one other crtc is using this pll don't turn | ||
| 1677 | * off the pll | ||
| 1678 | */ | ||
| 1679 | goto done; | ||
| 1680 | } | ||
| 1681 | } | ||
| 1682 | |||
| 1688 | switch (radeon_crtc->pll_id) { | 1683 | switch (radeon_crtc->pll_id) { |
| 1689 | case ATOM_PPLL1: | 1684 | case ATOM_PPLL1: |
| 1690 | case ATOM_PPLL2: | 1685 | case ATOM_PPLL2: |
| @@ -1701,6 +1696,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
| 1701 | default: | 1696 | default: |
| 1702 | break; | 1697 | break; |
| 1703 | } | 1698 | } |
| 1699 | done: | ||
| 1704 | radeon_crtc->pll_id = -1; | 1700 | radeon_crtc->pll_id = -1; |
| 1705 | } | 1701 | } |
| 1706 | 1702 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7712cf5ab33b..3623b98ed3fe 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
| 577 | struct radeon_device *rdev = dev->dev_private; | 577 | struct radeon_device *rdev = dev->dev_private; |
| 578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 580 | u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); | ||
| 581 | u8 tmp; | ||
| 580 | 582 | ||
| 581 | if (!ASIC_IS_DCE4(rdev)) | 583 | if (!ASIC_IS_DCE4(rdev)) |
| 582 | return panel_mode; | 584 | return panel_mode; |
| 583 | 585 | ||
| 584 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 586 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
| 585 | ENCODER_OBJECT_ID_NUTMEG) | 587 | /* DP bridge chips */ |
| 586 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 588 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
| 587 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 589 | if (tmp & 1) |
| 588 | ENCODER_OBJECT_ID_TRAVIS) { | 590 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
| 589 | u8 id[6]; | 591 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
| 590 | int i; | 592 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
| 591 | for (i = 0; i < 6; i++) | ||
| 592 | id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); | ||
| 593 | if (id[0] == 0x73 && | ||
| 594 | id[1] == 0x69 && | ||
| 595 | id[2] == 0x76 && | ||
| 596 | id[3] == 0x61 && | ||
| 597 | id[4] == 0x72 && | ||
| 598 | id[5] == 0x54) | ||
| 599 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 593 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
| 600 | else | 594 | else |
| 601 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 595 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 602 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 596 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| 603 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | 597 | /* eDP */ |
| 598 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | ||
| 604 | if (tmp & 1) | 599 | if (tmp & 1) |
| 605 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 600 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
| 606 | } | 601 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f9bc27fe269a..6e8803a1170c 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1379 | struct drm_device *dev = encoder->dev; | 1379 | struct drm_device *dev = encoder->dev; |
| 1380 | struct radeon_device *rdev = dev->dev_private; | 1380 | struct radeon_device *rdev = dev->dev_private; |
| 1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1382 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1383 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 1382 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1384 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 1383 | struct radeon_connector *radeon_connector = NULL; | 1385 | struct radeon_connector *radeon_connector = NULL; |
| 1384 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | 1386 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; |
| @@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1390 | 1392 | ||
| 1391 | switch (mode) { | 1393 | switch (mode) { |
| 1392 | case DRM_MODE_DPMS_ON: | 1394 | case DRM_MODE_DPMS_ON: |
| 1393 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1395 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
| 1394 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || | 1396 | if (!connector) |
| 1395 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1397 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 1396 | if (ASIC_IS_DCE6(rdev)) { | 1398 | else |
| 1397 | /* It seems we need to call ATOM_ENCODER_CMD_SETUP again | 1399 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); |
| 1398 | * before reenabling encoder on DPMS ON, otherwise we never | 1400 | |
| 1399 | * get picture | 1401 | /* setup and enable the encoder */ |
| 1400 | */ | 1402 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); |
| 1401 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | 1403 | atombios_dig_encoder_setup(encoder, |
| 1404 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
| 1405 | dig->panel_mode); | ||
| 1406 | if (ext_encoder) { | ||
| 1407 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
| 1408 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1409 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1402 | } | 1410 | } |
| 1403 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1411 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1404 | } else { | 1412 | } else if (ASIC_IS_DCE4(rdev)) { |
| 1413 | /* setup and enable the encoder */ | ||
| 1414 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1415 | /* enable the transmitter */ | ||
| 1416 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1405 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1417 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1418 | } else { | ||
| 1419 | /* setup and enable the encoder and transmitter */ | ||
| 1420 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
| 1421 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
| 1422 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1423 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
| 1424 | if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | ||
| 1425 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
| 1406 | } | 1426 | } |
| 1407 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| 1408 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1428 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| @@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1420 | case DRM_MODE_DPMS_STANDBY: | 1440 | case DRM_MODE_DPMS_STANDBY: |
| 1421 | case DRM_MODE_DPMS_SUSPEND: | 1441 | case DRM_MODE_DPMS_SUSPEND: |
| 1422 | case DRM_MODE_DPMS_OFF: | 1442 | case DRM_MODE_DPMS_OFF: |
| 1423 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | 1443 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
| 1444 | /* disable the transmitter */ | ||
| 1424 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1445 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
| 1425 | else | 1446 | } else if (ASIC_IS_DCE4(rdev)) { |
| 1447 | /* disable the transmitter */ | ||
| 1448 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
| 1449 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1450 | } else { | ||
| 1451 | /* disable the encoder and transmitter */ | ||
| 1426 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1452 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
| 1453 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1454 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 1455 | } | ||
| 1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1456 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| 1428 | if (ASIC_IS_DCE4(rdev)) | 1457 | if (ASIC_IS_DCE4(rdev)) |
| 1429 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | 1458 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
| @@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
| 1740 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1769 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
| 1741 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1770 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1742 | struct drm_encoder *test_encoder; | 1771 | struct drm_encoder *test_encoder; |
| 1743 | struct radeon_encoder_atom_dig *dig; | 1772 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 1744 | uint32_t dig_enc_in_use = 0; | 1773 | uint32_t dig_enc_in_use = 0; |
| 1745 | 1774 | ||
| 1746 | /* DCE4/5 */ | 1775 | if (ASIC_IS_DCE6(rdev)) { |
| 1747 | if (ASIC_IS_DCE4(rdev)) { | 1776 | /* DCE6 */ |
| 1748 | dig = radeon_encoder->enc_priv; | 1777 | switch (radeon_encoder->encoder_id) { |
| 1749 | if (ASIC_IS_DCE41(rdev)) { | 1778 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 1779 | if (dig->linkb) | ||
| 1780 | return 1; | ||
| 1781 | else | ||
| 1782 | return 0; | ||
| 1783 | break; | ||
| 1784 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1785 | if (dig->linkb) | ||
| 1786 | return 3; | ||
| 1787 | else | ||
| 1788 | return 2; | ||
| 1789 | break; | ||
| 1790 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1791 | if (dig->linkb) | ||
| 1792 | return 5; | ||
| 1793 | else | ||
| 1794 | return 4; | ||
| 1795 | break; | ||
| 1796 | } | ||
| 1797 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 1798 | /* DCE4/5 */ | ||
| 1799 | if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) { | ||
| 1750 | /* ontario follows DCE4 */ | 1800 | /* ontario follows DCE4 */ |
| 1751 | if (rdev->family == CHIP_PALM) { | 1801 | if (rdev->family == CHIP_PALM) { |
| 1752 | if (dig->linkb) | 1802 | if (dig->linkb) |
| @@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1848 | struct drm_device *dev = encoder->dev; | 1898 | struct drm_device *dev = encoder->dev; |
| 1849 | struct radeon_device *rdev = dev->dev_private; | 1899 | struct radeon_device *rdev = dev->dev_private; |
| 1850 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1900 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1851 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1852 | 1901 | ||
| 1853 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1902 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
| 1854 | 1903 | ||
| 1904 | /* need to call this here rather than in prepare() since we need some crtc info */ | ||
| 1905 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 1906 | |||
| 1855 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | 1907 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { |
| 1856 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1908 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
| 1857 | atombios_yuv_setup(encoder, true); | 1909 | atombios_yuv_setup(encoder, true); |
| @@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1870 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1922 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 1871 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1923 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 1872 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1924 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 1873 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1925 | /* handled in dpms */ |
| 1874 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1875 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 1876 | |||
| 1877 | if (!connector) | ||
| 1878 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | ||
| 1879 | else | ||
| 1880 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); | ||
| 1881 | |||
| 1882 | /* setup and enable the encoder */ | ||
| 1883 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1884 | atombios_dig_encoder_setup(encoder, | ||
| 1885 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
| 1886 | dig->panel_mode); | ||
| 1887 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 1888 | /* disable the transmitter */ | ||
| 1889 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1890 | /* setup and enable the encoder */ | ||
| 1891 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1892 | |||
| 1893 | /* enable the transmitter */ | ||
| 1894 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1895 | } else { | ||
| 1896 | /* disable the encoder and transmitter */ | ||
| 1897 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1898 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 1899 | |||
| 1900 | /* setup and enable the encoder and transmitter */ | ||
| 1901 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
| 1902 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
| 1903 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1904 | } | ||
| 1905 | break; | 1926 | break; |
| 1906 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1927 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
| 1907 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 1928 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
| @@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1922 | break; | 1943 | break; |
| 1923 | } | 1944 | } |
| 1924 | 1945 | ||
| 1925 | if (ext_encoder) { | ||
| 1926 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
| 1927 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1928 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1929 | else | ||
| 1930 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1946 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
| 1934 | 1947 | ||
| 1935 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | 1948 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
| @@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
| 2116 | } | 2129 | } |
| 2117 | 2130 | ||
| 2118 | radeon_atom_output_lock(encoder, true); | 2131 | radeon_atom_output_lock(encoder, true); |
| 2119 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 2120 | 2132 | ||
| 2121 | if (connector) { | 2133 | if (connector) { |
| 2122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 2134 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| @@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
| 2137 | 2149 | ||
| 2138 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 2150 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
| 2139 | { | 2151 | { |
| 2152 | /* need to call this here as we need the crtc set up */ | ||
| 2140 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 2153 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); |
| 2141 | radeon_atom_output_lock(encoder, false); | 2154 | radeon_atom_output_lock(encoder, false); |
| 2142 | } | 2155 | } |
| @@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
| 2177 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2190 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2178 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2191 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2179 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 2192 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 2180 | if (ASIC_IS_DCE4(rdev)) | 2193 | /* handled in dpms */ |
| 2181 | /* disable the transmitter */ | ||
| 2182 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2183 | else { | ||
| 2184 | /* disable the encoder and transmitter */ | ||
| 2185 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2186 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 2187 | } | ||
| 2188 | break; | 2194 | break; |
| 2189 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 2195 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
| 2190 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 2196 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ab74e6b149e7..f37676d7f217 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -63,6 +63,7 @@ struct r600_cs_track { | |||
| 63 | u32 cb_color_size_idx[8]; /* unused */ | 63 | u32 cb_color_size_idx[8]; /* unused */ |
| 64 | u32 cb_target_mask; | 64 | u32 cb_target_mask; |
| 65 | u32 cb_shader_mask; /* unused */ | 65 | u32 cb_shader_mask; /* unused */ |
| 66 | bool is_resolve; | ||
| 66 | u32 cb_color_size[8]; | 67 | u32 cb_color_size[8]; |
| 67 | u32 vgt_strmout_en; | 68 | u32 vgt_strmout_en; |
| 68 | u32 vgt_strmout_buffer_en; | 69 | u32 vgt_strmout_buffer_en; |
| @@ -315,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
| 315 | track->cb_color_bo[i] = NULL; | 316 | track->cb_color_bo[i] = NULL; |
| 316 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 317 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
| 317 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; | 318 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; |
| 318 | } | 319 | track->cb_color_frag_bo[i] = NULL; |
| 320 | track->cb_color_frag_offset[i] = 0xFFFFFFFF; | ||
| 321 | track->cb_color_tile_bo[i] = NULL; | ||
| 322 | track->cb_color_tile_offset[i] = 0xFFFFFFFF; | ||
| 323 | track->cb_color_mask[i] = 0xFFFFFFFF; | ||
| 324 | } | ||
| 325 | track->is_resolve = false; | ||
| 326 | track->nsamples = 16; | ||
| 327 | track->log_nsamples = 4; | ||
| 319 | track->cb_target_mask = 0xFFFFFFFF; | 328 | track->cb_target_mask = 0xFFFFFFFF; |
| 320 | track->cb_shader_mask = 0xFFFFFFFF; | 329 | track->cb_shader_mask = 0xFFFFFFFF; |
| 321 | track->cb_dirty = true; | 330 | track->cb_dirty = true; |
| @@ -352,6 +361,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 352 | volatile u32 *ib = p->ib.ptr; | 361 | volatile u32 *ib = p->ib.ptr; |
| 353 | unsigned array_mode; | 362 | unsigned array_mode; |
| 354 | u32 format; | 363 | u32 format; |
| 364 | /* When resolve is used, the second colorbuffer has always 1 sample. */ | ||
| 365 | unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples; | ||
| 355 | 366 | ||
| 356 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; | 367 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; |
| 357 | format = G_0280A0_FORMAT(track->cb_color_info[i]); | 368 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
| @@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 375 | array_check.group_size = track->group_size; | 386 | array_check.group_size = track->group_size; |
| 376 | array_check.nbanks = track->nbanks; | 387 | array_check.nbanks = track->nbanks; |
| 377 | array_check.npipes = track->npipes; | 388 | array_check.npipes = track->npipes; |
| 378 | array_check.nsamples = track->nsamples; | 389 | array_check.nsamples = nsamples; |
| 379 | array_check.blocksize = r600_fmt_get_blocksize(format); | 390 | array_check.blocksize = r600_fmt_get_blocksize(format); |
| 380 | if (r600_get_array_mode_alignment(&array_check, | 391 | if (r600_get_array_mode_alignment(&array_check, |
| 381 | &pitch_align, &height_align, &depth_align, &base_align)) { | 392 | &pitch_align, &height_align, &depth_align, &base_align)) { |
| @@ -421,7 +432,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 421 | 432 | ||
| 422 | /* check offset */ | 433 | /* check offset */ |
| 423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * | 434 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * |
| 424 | r600_fmt_get_blocksize(format) * track->nsamples; | 435 | r600_fmt_get_blocksize(format) * nsamples; |
| 425 | switch (array_mode) { | 436 | switch (array_mode) { |
| 426 | default: | 437 | default: |
| 427 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 438 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
| @@ -792,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 792 | */ | 803 | */ |
| 793 | if (track->cb_dirty) { | 804 | if (track->cb_dirty) { |
| 794 | tmp = track->cb_target_mask; | 805 | tmp = track->cb_target_mask; |
| 806 | |||
| 807 | /* We must check both colorbuffers for RESOLVE. */ | ||
| 808 | if (track->is_resolve) { | ||
| 809 | tmp |= 0xff; | ||
| 810 | } | ||
| 811 | |||
| 795 | for (i = 0; i < 8; i++) { | 812 | for (i = 0; i < 8; i++) { |
| 796 | if ((tmp >> (i * 4)) & 0xF) { | 813 | if ((tmp >> (i * 4)) & 0xF) { |
| 797 | /* at least one component is enabled */ | 814 | /* at least one component is enabled */ |
| @@ -1281,6 +1298,11 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 1281 | track->nsamples = 1 << tmp; | 1298 | track->nsamples = 1 << tmp; |
| 1282 | track->cb_dirty = true; | 1299 | track->cb_dirty = true; |
| 1283 | break; | 1300 | break; |
| 1301 | case R_028808_CB_COLOR_CONTROL: | ||
| 1302 | tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); | ||
| 1303 | track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; | ||
| 1304 | track->cb_dirty = true; | ||
| 1305 | break; | ||
| 1284 | case R_0280A0_CB_COLOR0_INFO: | 1306 | case R_0280A0_CB_COLOR0_INFO: |
| 1285 | case R_0280A4_CB_COLOR1_INFO: | 1307 | case R_0280A4_CB_COLOR1_INFO: |
| 1286 | case R_0280A8_CB_COLOR2_INFO: | 1308 | case R_0280A8_CB_COLOR2_INFO: |
| @@ -1416,7 +1438,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 1416 | case R_028118_CB_COLOR6_MASK: | 1438 | case R_028118_CB_COLOR6_MASK: |
| 1417 | case R_02811C_CB_COLOR7_MASK: | 1439 | case R_02811C_CB_COLOR7_MASK: |
| 1418 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; | 1440 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; |
| 1419 | track->cb_color_mask[tmp] = ib[idx]; | 1441 | track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx); |
| 1420 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | 1442 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { |
| 1421 | track->cb_dirty = true; | 1443 | track->cb_dirty = true; |
| 1422 | } | 1444 | } |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index bdb69a63062f..fa6f37099ba9 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -66,6 +66,14 @@ | |||
| 66 | #define CC_RB_BACKEND_DISABLE 0x98F4 | 66 | #define CC_RB_BACKEND_DISABLE 0x98F4 |
| 67 | #define BACKEND_DISABLE(x) ((x) << 16) | 67 | #define BACKEND_DISABLE(x) ((x) << 16) |
| 68 | 68 | ||
| 69 | #define R_028808_CB_COLOR_CONTROL 0x28808 | ||
| 70 | #define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4) | ||
| 71 | #define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7) | ||
| 72 | #define C_028808_SPECIAL_OP 0xFFFFFF8F | ||
| 73 | #define V_028808_SPECIAL_NORMAL 0x00 | ||
| 74 | #define V_028808_SPECIAL_DISABLE 0x01 | ||
| 75 | #define V_028808_SPECIAL_RESOLVE_BOX 0x07 | ||
| 76 | |||
| 69 | #define CB_COLOR0_BASE 0x28040 | 77 | #define CB_COLOR0_BASE 0x28040 |
| 70 | #define CB_COLOR1_BASE 0x28044 | 78 | #define CB_COLOR1_BASE 0x28044 |
| 71 | #define CB_COLOR2_BASE 0x28048 | 79 | #define CB_COLOR2_BASE 0x28048 |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d2e243867ac6..7a3daebd732d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -1051,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1051 | if (rdev->flags & RADEON_IS_AGP) | 1051 | if (rdev->flags & RADEON_IS_AGP) |
| 1052 | rdev->need_dma32 = true; | 1052 | rdev->need_dma32 = true; |
| 1053 | if ((rdev->flags & RADEON_IS_PCI) && | 1053 | if ((rdev->flags & RADEON_IS_PCI) && |
| 1054 | (rdev->family < CHIP_RS400)) | 1054 | (rdev->family <= CHIP_RS740)) |
| 1055 | rdev->need_dma32 = true; | 1055 | rdev->need_dma32 = true; |
| 1056 | 1056 | ||
| 1057 | dma_bits = rdev->need_dma32 ? 32 : 40; | 1057 | dma_bits = rdev->need_dma32 ? 32 : 40; |
| @@ -1346,12 +1346,15 @@ retry: | |||
| 1346 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1346 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
| 1347 | radeon_ring_restore(rdev, &rdev->ring[i], | 1347 | radeon_ring_restore(rdev, &rdev->ring[i], |
| 1348 | ring_sizes[i], ring_data[i]); | 1348 | ring_sizes[i], ring_data[i]); |
| 1349 | ring_sizes[i] = 0; | ||
| 1350 | ring_data[i] = NULL; | ||
| 1349 | } | 1351 | } |
| 1350 | 1352 | ||
| 1351 | r = radeon_ib_ring_tests(rdev); | 1353 | r = radeon_ib_ring_tests(rdev); |
| 1352 | if (r) { | 1354 | if (r) { |
| 1353 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); | 1355 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); |
| 1354 | if (saved) { | 1356 | if (saved) { |
| 1357 | saved = false; | ||
| 1355 | radeon_suspend(rdev); | 1358 | radeon_suspend(rdev); |
| 1356 | goto retry; | 1359 | goto retry; |
| 1357 | } | 1360 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 27d22d709c90..8c593ea82c41 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -63,9 +63,10 @@ | |||
| 63 | * 2.19.0 - r600-eg: MSAA textures | 63 | * 2.19.0 - r600-eg: MSAA textures |
| 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query |
| 65 | * 2.21.0 - r600-r700: FMASK and CMASK | 65 | * 2.21.0 - r600-r700: FMASK and CMASK |
| 66 | * 2.22.0 - r600 only: RESOLVE_BOX allowed | ||
| 66 | */ | 67 | */ |
| 67 | #define KMS_DRIVER_MAJOR 2 | 68 | #define KMS_DRIVER_MAJOR 2 |
| 68 | #define KMS_DRIVER_MINOR 21 | 69 | #define KMS_DRIVER_MINOR 22 |
| 69 | #define KMS_DRIVER_PATCHLEVEL 0 | 70 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 70 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 71 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
| 71 | int radeon_driver_unload_kms(struct drm_device *dev); | 72 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index f93e45d869f4..20bfbda7b3f1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
| @@ -744,7 +744,6 @@ r600 0x9400 | |||
| 744 | 0x00028C38 CB_CLRCMP_DST | 744 | 0x00028C38 CB_CLRCMP_DST |
| 745 | 0x00028C3C CB_CLRCMP_MSK | 745 | 0x00028C3C CB_CLRCMP_MSK |
| 746 | 0x00028C34 CB_CLRCMP_SRC | 746 | 0x00028C34 CB_CLRCMP_SRC |
| 747 | 0x00028808 CB_COLOR_CONTROL | ||
| 748 | 0x0002842C CB_FOG_BLUE | 747 | 0x0002842C CB_FOG_BLUE |
| 749 | 0x00028428 CB_FOG_GREEN | 748 | 0x00028428 CB_FOG_GREEN |
| 750 | 0x00028424 CB_FOG_RED | 749 | 0x00028424 CB_FOG_RED |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 60ea284407ce..8bf8a64e5115 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1624,7 +1624,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1624 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1624 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
| 1625 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1625 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
| 1626 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, | 1626 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, |
| 1627 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, | ||
| 1628 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, | 1627 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, |
| 1629 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, | 1628 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, |
| 1630 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, | 1629 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, |
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 351d1f4593e7..4ee578948723 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
| @@ -34,6 +34,12 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = { | |||
| 34 | .matches = { | 34 | .matches = { |
| 35 | DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58") | 35 | DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58") |
| 36 | } | 36 | } |
| 37 | }, { | ||
| 38 | /* Old interface reads the same sensor for fan0 and fan1 */ | ||
| 39 | .ident = "Asus M5A78L", | ||
| 40 | .matches = { | ||
| 41 | DMI_MATCH(DMI_BOARD_NAME, "M5A78L") | ||
| 42 | } | ||
| 37 | }, | 43 | }, |
| 38 | { } | 44 | { } |
| 39 | }; | 45 | }; |
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 92406097efeb..8d1e32d7cd97 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 5 | int generic_ide_suspend(struct device *dev, pm_message_t mesg) |
| 6 | { | 6 | { |
| 7 | ide_drive_t *drive = dev_get_drvdata(dev); | 7 | ide_drive_t *drive = to_ide_device(dev); |
| 8 | ide_drive_t *pair = ide_get_pair_dev(drive); | 8 | ide_drive_t *pair = ide_get_pair_dev(drive); |
| 9 | ide_hwif_t *hwif = drive->hwif; | 9 | ide_hwif_t *hwif = drive->hwif; |
| 10 | struct request *rq; | 10 | struct request *rq; |
| @@ -40,7 +40,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
| 40 | 40 | ||
| 41 | int generic_ide_resume(struct device *dev) | 41 | int generic_ide_resume(struct device *dev) |
| 42 | { | 42 | { |
| 43 | ide_drive_t *drive = dev_get_drvdata(dev); | 43 | ide_drive_t *drive = to_ide_device(dev); |
| 44 | ide_drive_t *pair = ide_get_pair_dev(drive); | 44 | ide_drive_t *pair = ide_get_pair_dev(drive); |
| 45 | ide_hwif_t *hwif = drive->hwif; | 45 | ide_hwif_t *hwif = drive->hwif; |
| 46 | struct request *rq; | 46 | struct request *rq; |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 88cf9d952631..f721fd2155f7 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
| @@ -454,11 +454,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr) | |||
| 454 | 454 | ||
| 455 | win = &vout->win; | 455 | win = &vout->win; |
| 456 | for (i = 0; i < ovid->num_overlays; i++) { | 456 | for (i = 0; i < ovid->num_overlays; i++) { |
| 457 | struct omap_dss_device *dssdev; | ||
| 458 | |||
| 457 | ovl = ovid->overlays[i]; | 459 | ovl = ovid->overlays[i]; |
| 458 | if (!ovl->manager || !ovl->manager->device) | 460 | dssdev = ovl->get_device(ovl); |
| 461 | |||
| 462 | if (!dssdev) | ||
| 459 | return -EINVAL; | 463 | return -EINVAL; |
| 460 | 464 | ||
| 461 | timing = &ovl->manager->device->panel.timings; | 465 | timing = &dssdev->panel.timings; |
| 462 | 466 | ||
| 463 | outw = win->w.width; | 467 | outw = win->w.width; |
| 464 | outh = win->w.height; | 468 | outh = win->w.height; |
| @@ -515,8 +519,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) | |||
| 515 | struct omapvideo_info *ovid = &vout->vid_info; | 519 | struct omapvideo_info *ovid = &vout->vid_info; |
| 516 | 520 | ||
| 517 | for (i = 0; i < ovid->num_overlays; i++) { | 521 | for (i = 0; i < ovid->num_overlays; i++) { |
| 522 | struct omap_dss_device *dssdev; | ||
| 523 | |||
| 518 | ovl = ovid->overlays[i]; | 524 | ovl = ovid->overlays[i]; |
| 519 | if (!ovl->manager || !ovl->manager->device) | 525 | dssdev = ovl->get_device(ovl); |
| 526 | if (!dssdev) | ||
| 520 | return -EINVAL; | 527 | return -EINVAL; |
| 521 | ovl->manager->apply(ovl->manager); | 528 | ovl->manager->apply(ovl->manager); |
| 522 | } | 529 | } |
| @@ -579,12 +586,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) | |||
| 579 | 586 | ||
| 580 | ovid = &vout->vid_info; | 587 | ovid = &vout->vid_info; |
| 581 | ovl = ovid->overlays[0]; | 588 | ovl = ovid->overlays[0]; |
| 582 | /* get the display device attached to the overlay */ | ||
| 583 | if (!ovl->manager || !ovl->manager->device) | ||
| 584 | return; | ||
| 585 | 589 | ||
| 586 | mgr_id = ovl->manager->id; | 590 | mgr_id = ovl->manager->id; |
| 587 | cur_display = ovl->manager->device; | 591 | |
| 592 | /* get the display device attached to the overlay */ | ||
| 593 | cur_display = ovl->get_device(ovl); | ||
| 594 | |||
| 595 | if (!cur_display) | ||
| 596 | return; | ||
| 588 | 597 | ||
| 589 | spin_lock(&vout->vbq_lock); | 598 | spin_lock(&vout->vbq_lock); |
| 590 | do_gettimeofday(&timevalue); | 599 | do_gettimeofday(&timevalue); |
| @@ -948,7 +957,9 @@ static int omap_vout_release(struct file *file) | |||
| 948 | /* Disable all the overlay managers connected with this interface */ | 957 | /* Disable all the overlay managers connected with this interface */ |
| 949 | for (i = 0; i < ovid->num_overlays; i++) { | 958 | for (i = 0; i < ovid->num_overlays; i++) { |
| 950 | struct omap_overlay *ovl = ovid->overlays[i]; | 959 | struct omap_overlay *ovl = ovid->overlays[i]; |
| 951 | if (ovl->manager && ovl->manager->device) | 960 | struct omap_dss_device *dssdev = ovl->get_device(ovl); |
| 961 | |||
| 962 | if (dssdev) | ||
| 952 | ovl->disable(ovl); | 963 | ovl->disable(ovl); |
| 953 | } | 964 | } |
| 954 | /* Turn off the pipeline */ | 965 | /* Turn off the pipeline */ |
| @@ -1081,14 +1092,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh, | |||
| 1081 | struct omapvideo_info *ovid; | 1092 | struct omapvideo_info *ovid; |
| 1082 | struct omap_video_timings *timing; | 1093 | struct omap_video_timings *timing; |
| 1083 | struct omap_vout_device *vout = fh; | 1094 | struct omap_vout_device *vout = fh; |
| 1095 | struct omap_dss_device *dssdev; | ||
| 1084 | 1096 | ||
| 1085 | ovid = &vout->vid_info; | 1097 | ovid = &vout->vid_info; |
| 1086 | ovl = ovid->overlays[0]; | 1098 | ovl = ovid->overlays[0]; |
| 1099 | /* get the display device attached to the overlay */ | ||
| 1100 | dssdev = ovl->get_device(ovl); | ||
| 1087 | 1101 | ||
| 1088 | if (!ovl->manager || !ovl->manager->device) | 1102 | if (!dssdev) |
| 1089 | return -EINVAL; | 1103 | return -EINVAL; |
| 1090 | /* get the display device attached to the overlay */ | 1104 | |
| 1091 | timing = &ovl->manager->device->panel.timings; | 1105 | timing = &dssdev->panel.timings; |
| 1092 | 1106 | ||
| 1093 | vout->fbuf.fmt.height = timing->y_res; | 1107 | vout->fbuf.fmt.height = timing->y_res; |
| 1094 | vout->fbuf.fmt.width = timing->x_res; | 1108 | vout->fbuf.fmt.width = timing->x_res; |
| @@ -1105,6 +1119,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, | |||
| 1105 | struct omapvideo_info *ovid; | 1119 | struct omapvideo_info *ovid; |
| 1106 | struct omap_video_timings *timing; | 1120 | struct omap_video_timings *timing; |
| 1107 | struct omap_vout_device *vout = fh; | 1121 | struct omap_vout_device *vout = fh; |
| 1122 | struct omap_dss_device *dssdev; | ||
| 1108 | 1123 | ||
| 1109 | if (vout->streaming) | 1124 | if (vout->streaming) |
| 1110 | return -EBUSY; | 1125 | return -EBUSY; |
| @@ -1113,13 +1128,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, | |||
| 1113 | 1128 | ||
| 1114 | ovid = &vout->vid_info; | 1129 | ovid = &vout->vid_info; |
| 1115 | ovl = ovid->overlays[0]; | 1130 | ovl = ovid->overlays[0]; |
| 1131 | dssdev = ovl->get_device(ovl); | ||
| 1116 | 1132 | ||
| 1117 | /* get the display device attached to the overlay */ | 1133 | /* get the display device attached to the overlay */ |
| 1118 | if (!ovl->manager || !ovl->manager->device) { | 1134 | if (!dssdev) { |
| 1119 | ret = -EINVAL; | 1135 | ret = -EINVAL; |
| 1120 | goto s_fmt_vid_out_exit; | 1136 | goto s_fmt_vid_out_exit; |
| 1121 | } | 1137 | } |
| 1122 | timing = &ovl->manager->device->panel.timings; | 1138 | timing = &dssdev->panel.timings; |
| 1123 | 1139 | ||
| 1124 | /* We dont support RGB24-packed mode if vrfb rotation | 1140 | /* We dont support RGB24-packed mode if vrfb rotation |
| 1125 | * is enabled*/ | 1141 | * is enabled*/ |
| @@ -1298,6 +1314,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) | |||
| 1298 | struct omapvideo_info *ovid; | 1314 | struct omapvideo_info *ovid; |
| 1299 | struct omap_overlay *ovl; | 1315 | struct omap_overlay *ovl; |
| 1300 | struct omap_video_timings *timing; | 1316 | struct omap_video_timings *timing; |
| 1317 | struct omap_dss_device *dssdev; | ||
| 1301 | 1318 | ||
| 1302 | if (vout->streaming) | 1319 | if (vout->streaming) |
| 1303 | return -EBUSY; | 1320 | return -EBUSY; |
| @@ -1305,13 +1322,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) | |||
| 1305 | mutex_lock(&vout->lock); | 1322 | mutex_lock(&vout->lock); |
| 1306 | ovid = &vout->vid_info; | 1323 | ovid = &vout->vid_info; |
| 1307 | ovl = ovid->overlays[0]; | 1324 | ovl = ovid->overlays[0]; |
| 1325 | /* get the display device attached to the overlay */ | ||
| 1326 | dssdev = ovl->get_device(ovl); | ||
| 1308 | 1327 | ||
| 1309 | if (!ovl->manager || !ovl->manager->device) { | 1328 | if (!dssdev) { |
| 1310 | ret = -EINVAL; | 1329 | ret = -EINVAL; |
| 1311 | goto s_crop_err; | 1330 | goto s_crop_err; |
| 1312 | } | 1331 | } |
| 1313 | /* get the display device attached to the overlay */ | 1332 | |
| 1314 | timing = &ovl->manager->device->panel.timings; | 1333 | timing = &dssdev->panel.timings; |
| 1315 | 1334 | ||
| 1316 | if (is_rotation_90_or_270(vout)) { | 1335 | if (is_rotation_90_or_270(vout)) { |
| 1317 | vout->fbuf.fmt.height = timing->x_res; | 1336 | vout->fbuf.fmt.height = timing->x_res; |
| @@ -1667,7 +1686,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | |||
| 1667 | for (j = 0; j < ovid->num_overlays; j++) { | 1686 | for (j = 0; j < ovid->num_overlays; j++) { |
| 1668 | struct omap_overlay *ovl = ovid->overlays[j]; | 1687 | struct omap_overlay *ovl = ovid->overlays[j]; |
| 1669 | 1688 | ||
| 1670 | if (ovl->manager && ovl->manager->device) { | 1689 | if (ovl->get_device(ovl)) { |
| 1671 | struct omap_overlay_info info; | 1690 | struct omap_overlay_info info; |
| 1672 | ovl->get_overlay_info(ovl, &info); | 1691 | ovl->get_overlay_info(ovl, &info); |
| 1673 | info.paddr = addr; | 1692 | info.paddr = addr; |
| @@ -1690,8 +1709,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | |||
| 1690 | 1709 | ||
| 1691 | for (j = 0; j < ovid->num_overlays; j++) { | 1710 | for (j = 0; j < ovid->num_overlays; j++) { |
| 1692 | struct omap_overlay *ovl = ovid->overlays[j]; | 1711 | struct omap_overlay *ovl = ovid->overlays[j]; |
| 1712 | struct omap_dss_device *dssdev = ovl->get_device(ovl); | ||
| 1693 | 1713 | ||
| 1694 | if (ovl->manager && ovl->manager->device) { | 1714 | if (dssdev) { |
| 1695 | ret = ovl->enable(ovl); | 1715 | ret = ovl->enable(ovl); |
| 1696 | if (ret) | 1716 | if (ret) |
| 1697 | goto streamon_err1; | 1717 | goto streamon_err1; |
| @@ -1726,8 +1746,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | |||
| 1726 | 1746 | ||
| 1727 | for (j = 0; j < ovid->num_overlays; j++) { | 1747 | for (j = 0; j < ovid->num_overlays; j++) { |
| 1728 | struct omap_overlay *ovl = ovid->overlays[j]; | 1748 | struct omap_overlay *ovl = ovid->overlays[j]; |
| 1749 | struct omap_dss_device *dssdev = ovl->get_device(ovl); | ||
| 1729 | 1750 | ||
| 1730 | if (ovl->manager && ovl->manager->device) | 1751 | if (dssdev) |
| 1731 | ovl->disable(ovl); | 1752 | ovl->disable(ovl); |
| 1732 | } | 1753 | } |
| 1733 | 1754 | ||
| @@ -1890,8 +1911,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) | |||
| 1890 | struct video_device *vfd; | 1911 | struct video_device *vfd; |
| 1891 | struct v4l2_pix_format *pix; | 1912 | struct v4l2_pix_format *pix; |
| 1892 | struct v4l2_control *control; | 1913 | struct v4l2_control *control; |
| 1893 | struct omap_dss_device *display = | 1914 | struct omap_overlay *ovl = vout->vid_info.overlays[0]; |
| 1894 | vout->vid_info.overlays[0]->manager->device; | 1915 | struct omap_dss_device *display = ovl->get_device(ovl); |
| 1895 | 1916 | ||
| 1896 | /* set the default pix */ | 1917 | /* set the default pix */ |
| 1897 | pix = &vout->pix; | 1918 | pix = &vout->pix; |
| @@ -2205,8 +2226,10 @@ static int __init omap_vout_probe(struct platform_device *pdev) | |||
| 2205 | */ | 2226 | */ |
| 2206 | for (i = 1; i < vid_dev->num_overlays; i++) { | 2227 | for (i = 1; i < vid_dev->num_overlays; i++) { |
| 2207 | ovl = omap_dss_get_overlay(i); | 2228 | ovl = omap_dss_get_overlay(i); |
| 2208 | if (ovl->manager && ovl->manager->device) { | 2229 | dssdev = ovl->get_device(ovl); |
| 2209 | def_display = ovl->manager->device; | 2230 | |
| 2231 | if (dssdev) { | ||
| 2232 | def_display = dssdev; | ||
| 2210 | } else { | 2233 | } else { |
| 2211 | dev_warn(&pdev->dev, "cannot find display\n"); | 2234 | dev_warn(&pdev->dev, "cannot find display\n"); |
| 2212 | def_display = NULL; | 2235 | def_display = NULL; |
| @@ -2253,8 +2276,10 @@ probe_err1: | |||
| 2253 | for (i = 1; i < vid_dev->num_overlays; i++) { | 2276 | for (i = 1; i < vid_dev->num_overlays; i++) { |
| 2254 | def_display = NULL; | 2277 | def_display = NULL; |
| 2255 | ovl = omap_dss_get_overlay(i); | 2278 | ovl = omap_dss_get_overlay(i); |
| 2256 | if (ovl->manager && ovl->manager->device) | 2279 | dssdev = ovl->get_device(ovl); |
| 2257 | def_display = ovl->manager->device; | 2280 | |
| 2281 | if (dssdev) | ||
| 2282 | def_display = dssdev; | ||
| 2258 | 2283 | ||
| 2259 | if (def_display && def_display->driver) | 2284 | if (def_display && def_display->driver) |
| 2260 | def_display->driver->disable(def_display); | 2285 | def_display->driver->disable(def_display); |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 40a826a7295f..2fb2b9ea97ec 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
| @@ -3804,7 +3804,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp) | |||
| 3804 | case BIODASDSYMMIO: | 3804 | case BIODASDSYMMIO: |
| 3805 | return dasd_symm_io(device, argp); | 3805 | return dasd_symm_io(device, argp); |
| 3806 | default: | 3806 | default: |
| 3807 | return -ENOIOCTLCMD; | 3807 | return -ENOTTY; |
| 3808 | } | 3808 | } |
| 3809 | } | 3809 | } |
| 3810 | 3810 | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index cceae70279f6..654c6921a6d4 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
| @@ -498,12 +498,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 498 | break; | 498 | break; |
| 499 | default: | 499 | default: |
| 500 | /* if the discipline has an ioctl method try it. */ | 500 | /* if the discipline has an ioctl method try it. */ |
| 501 | if (base->discipline->ioctl) { | 501 | rc = -ENOTTY; |
| 502 | if (base->discipline->ioctl) | ||
| 502 | rc = base->discipline->ioctl(block, cmd, argp); | 503 | rc = base->discipline->ioctl(block, cmd, argp); |
| 503 | if (rc == -ENOIOCTLCMD) | ||
| 504 | rc = -EINVAL; | ||
| 505 | } else | ||
| 506 | rc = -EINVAL; | ||
| 507 | } | 504 | } |
| 508 | dasd_put_device(base); | 505 | dasd_put_device(base); |
| 509 | return rc; | 506 | return rc; |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index ea0aaa3f13d0..a9f4049c6769 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
| @@ -47,6 +47,8 @@ struct bcm63xx_spi { | |||
| 47 | /* Platform data */ | 47 | /* Platform data */ |
| 48 | u32 speed_hz; | 48 | u32 speed_hz; |
| 49 | unsigned fifo_size; | 49 | unsigned fifo_size; |
| 50 | unsigned int msg_type_shift; | ||
| 51 | unsigned int msg_ctl_width; | ||
| 50 | 52 | ||
| 51 | /* Data buffers */ | 53 | /* Data buffers */ |
| 52 | const unsigned char *tx_ptr; | 54 | const unsigned char *tx_ptr; |
| @@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, | |||
| 221 | msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); | 223 | msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); |
| 222 | 224 | ||
| 223 | if (t->rx_buf && t->tx_buf) | 225 | if (t->rx_buf && t->tx_buf) |
| 224 | msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); | 226 | msg_ctl |= (SPI_FD_RW << bs->msg_type_shift); |
| 225 | else if (t->rx_buf) | 227 | else if (t->rx_buf) |
| 226 | msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); | 228 | msg_ctl |= (SPI_HD_R << bs->msg_type_shift); |
| 227 | else if (t->tx_buf) | 229 | else if (t->tx_buf) |
| 228 | msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); | 230 | msg_ctl |= (SPI_HD_W << bs->msg_type_shift); |
| 229 | 231 | ||
| 230 | bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); | 232 | switch (bs->msg_ctl_width) { |
| 233 | case 8: | ||
| 234 | bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL); | ||
| 235 | break; | ||
| 236 | case 16: | ||
| 237 | bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); | ||
| 238 | break; | ||
| 239 | } | ||
| 231 | 240 | ||
| 232 | /* Issue the transfer */ | 241 | /* Issue the transfer */ |
| 233 | cmd = SPI_CMD_START_IMMEDIATE; | 242 | cmd = SPI_CMD_START_IMMEDIATE; |
| @@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) | |||
| 406 | master->transfer_one_message = bcm63xx_spi_transfer_one; | 415 | master->transfer_one_message = bcm63xx_spi_transfer_one; |
| 407 | master->mode_bits = MODEBITS; | 416 | master->mode_bits = MODEBITS; |
| 408 | bs->speed_hz = pdata->speed_hz; | 417 | bs->speed_hz = pdata->speed_hz; |
| 418 | bs->msg_type_shift = pdata->msg_type_shift; | ||
| 419 | bs->msg_ctl_width = pdata->msg_ctl_width; | ||
| 409 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); | 420 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); |
| 410 | bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); | 421 | bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); |
| 411 | 422 | ||
| 423 | switch (bs->msg_ctl_width) { | ||
| 424 | case 8: | ||
| 425 | case 16: | ||
| 426 | break; | ||
| 427 | default: | ||
| 428 | dev_err(dev, "unsupported MSG_CTL width: %d\n", | ||
| 429 | bs->msg_ctl_width); | ||
| 430 | goto out_clk_disable; | ||
| 431 | } | ||
| 432 | |||
| 412 | /* Initialize hardware */ | 433 | /* Initialize hardware */ |
| 413 | clk_enable(bs->clk); | 434 | clk_enable(bs->clk); |
| 414 | bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); | 435 | bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); |
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 4beab9447ceb..64a354a54737 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c | |||
| @@ -106,7 +106,8 @@ static void dump_video_chains(void) | |||
| 106 | for (i = 0; i < omap_dss_get_num_overlays(); i++) { | 106 | for (i = 0; i < omap_dss_get_num_overlays(); i++) { |
| 107 | struct omap_overlay *ovl = omap_dss_get_overlay(i); | 107 | struct omap_overlay *ovl = omap_dss_get_overlay(i); |
| 108 | struct omap_overlay_manager *mgr = ovl->manager; | 108 | struct omap_overlay_manager *mgr = ovl->manager; |
| 109 | struct omap_dss_device *dssdev = mgr ? mgr->device : NULL; | 109 | struct omap_dss_device *dssdev = mgr ? |
| 110 | mgr->get_device(mgr) : NULL; | ||
| 110 | if (dssdev) { | 111 | if (dssdev) { |
| 111 | DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, | 112 | DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, |
| 112 | dssdev->name); | 113 | dssdev->name); |
| @@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev, | |||
| 185 | for (j = 0; j < priv->num_encoders; j++) { | 186 | for (j = 0; j < priv->num_encoders; j++) { |
| 186 | struct omap_overlay_manager *mgr = | 187 | struct omap_overlay_manager *mgr = |
| 187 | omap_encoder_get_manager(priv->encoders[j]); | 188 | omap_encoder_get_manager(priv->encoders[j]); |
| 188 | if (mgr->device == dssdev) { | 189 | if (mgr->get_device(mgr) == dssdev) { |
| 189 | drm_mode_connector_attach_encoder(connector, | 190 | drm_mode_connector_attach_encoder(connector, |
| 190 | priv->encoders[j]); | 191 | priv->encoders[j]); |
| 191 | } | 192 | } |
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c index 9f1d23c319cb..f349ee6f0cea 100644 --- a/drivers/video/omap/hwa742.c +++ b/drivers/video/omap/hwa742.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
| 28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 29 | 29 | ||
| 30 | #include <plat/dma.h> | ||
| 31 | #include "omapfb.h" | 30 | #include "omapfb.h" |
| 32 | 31 | ||
| 33 | #define HWA742_REV_CODE_REG 0x0 | 32 | #define HWA742_REV_CODE_REG 0x0 |
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c index d3a311327227..5cca6b373af7 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/omap/lcd_ams_delta.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
| 29 | 29 | ||
| 30 | #include <plat/board-ams-delta.h> | 30 | #include <plat/board-ams-delta.h> |
| 31 | #include <mach/hardware.h> | ||
| 32 | 31 | ||
| 33 | #include "omapfb.h" | 32 | #include "omapfb.h" |
| 34 | 33 | ||
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c index 88c31eb0cd6c..ff4fb624b904 100644 --- a/drivers/video/omap/lcd_palmte.c +++ b/drivers/video/omap/lcd_palmte.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | 25 | ||
| 26 | #include <plat/fpga.h> | ||
| 27 | #include "omapfb.h" | 26 | #include "omapfb.h" |
| 28 | 27 | ||
| 29 | static int palmte_panel_init(struct lcd_panel *panel, | 28 | static int palmte_panel_init(struct lcd_panel *panel, |
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index f54b463709e9..4351c438b76f 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
| @@ -131,15 +131,6 @@ static void omapfb_rqueue_unlock(struct omapfb_device *fbdev) | |||
| 131 | * LCD controller and LCD DMA | 131 | * LCD controller and LCD DMA |
| 132 | * --------------------------------------------------------------------------- | 132 | * --------------------------------------------------------------------------- |
| 133 | */ | 133 | */ |
| 134 | /* Lookup table to map elem size to elem type. */ | ||
| 135 | static const int dma_elem_type[] = { | ||
| 136 | 0, | ||
| 137 | OMAP_DMA_DATA_TYPE_S8, | ||
| 138 | OMAP_DMA_DATA_TYPE_S16, | ||
| 139 | 0, | ||
| 140 | OMAP_DMA_DATA_TYPE_S32, | ||
| 141 | }; | ||
| 142 | |||
| 143 | /* | 134 | /* |
| 144 | * Allocate resources needed for LCD controller and LCD DMA operations. Video | 135 | * Allocate resources needed for LCD controller and LCD DMA operations. Video |
| 145 | * memory is allocated from system memory according to the virtual display | 136 | * memory is allocated from system memory according to the virtual display |
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c index eaeed4340e04..c835aa70f96f 100644 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ b/drivers/video/omap2/displays/panel-acx565akm.c | |||
| @@ -600,6 +600,9 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev) | |||
| 600 | 600 | ||
| 601 | mutex_lock(&md->mutex); | 601 | mutex_lock(&md->mutex); |
| 602 | 602 | ||
| 603 | omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 604 | omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs); | ||
| 605 | |||
| 603 | r = omapdss_sdi_display_enable(dssdev); | 606 | r = omapdss_sdi_display_enable(dssdev); |
| 604 | if (r) { | 607 | if (r) { |
| 605 | pr_err("%s sdi enable failed\n", __func__); | 608 | pr_err("%s sdi enable failed\n", __func__); |
| @@ -731,18 +734,9 @@ static int acx_panel_resume(struct omap_dss_device *dssdev) | |||
| 731 | static void acx_panel_set_timings(struct omap_dss_device *dssdev, | 734 | static void acx_panel_set_timings(struct omap_dss_device *dssdev, |
| 732 | struct omap_video_timings *timings) | 735 | struct omap_video_timings *timings) |
| 733 | { | 736 | { |
| 734 | int r; | 737 | omapdss_sdi_set_timings(dssdev, timings); |
| 735 | |||
| 736 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
| 737 | omapdss_sdi_display_disable(dssdev); | ||
| 738 | 738 | ||
| 739 | dssdev->panel.timings = *timings; | 739 | dssdev->panel.timings = *timings; |
| 740 | |||
| 741 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | ||
| 742 | r = omapdss_sdi_display_enable(dssdev); | ||
| 743 | if (r) | ||
| 744 | dev_err(&dssdev->dev, "%s enable failed\n", __func__); | ||
| 745 | } | ||
| 746 | } | 740 | } |
| 747 | 741 | ||
| 748 | static int acx_panel_check_timings(struct omap_dss_device *dssdev, | 742 | static int acx_panel_check_timings(struct omap_dss_device *dssdev, |
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c index bc5af2500eb9..88295c526815 100644 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ b/drivers/video/omap2/displays/panel-generic-dpi.c | |||
| @@ -545,6 +545,8 @@ struct panel_drv_data { | |||
| 545 | struct omap_dss_device *dssdev; | 545 | struct omap_dss_device *dssdev; |
| 546 | 546 | ||
| 547 | struct panel_config *panel_config; | 547 | struct panel_config *panel_config; |
| 548 | |||
| 549 | struct mutex lock; | ||
| 548 | }; | 550 | }; |
| 549 | 551 | ||
| 550 | static inline struct panel_generic_dpi_data | 552 | static inline struct panel_generic_dpi_data |
| @@ -563,6 +565,9 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev) | |||
| 563 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 565 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
| 564 | return 0; | 566 | return 0; |
| 565 | 567 | ||
| 568 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 569 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 570 | |||
| 566 | r = omapdss_dpi_display_enable(dssdev); | 571 | r = omapdss_dpi_display_enable(dssdev); |
| 567 | if (r) | 572 | if (r) |
| 568 | goto err0; | 573 | goto err0; |
| @@ -634,6 +639,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev) | |||
| 634 | drv_data->dssdev = dssdev; | 639 | drv_data->dssdev = dssdev; |
| 635 | drv_data->panel_config = panel_config; | 640 | drv_data->panel_config = panel_config; |
| 636 | 641 | ||
| 642 | mutex_init(&drv_data->lock); | ||
| 643 | |||
| 637 | dev_set_drvdata(&dssdev->dev, drv_data); | 644 | dev_set_drvdata(&dssdev->dev, drv_data); |
| 638 | 645 | ||
| 639 | return 0; | 646 | return 0; |
| @@ -652,56 +659,108 @@ static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev) | |||
| 652 | 659 | ||
| 653 | static int generic_dpi_panel_enable(struct omap_dss_device *dssdev) | 660 | static int generic_dpi_panel_enable(struct omap_dss_device *dssdev) |
| 654 | { | 661 | { |
| 655 | int r = 0; | 662 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); |
| 663 | int r; | ||
| 664 | |||
| 665 | mutex_lock(&drv_data->lock); | ||
| 656 | 666 | ||
| 657 | r = generic_dpi_panel_power_on(dssdev); | 667 | r = generic_dpi_panel_power_on(dssdev); |
| 658 | if (r) | 668 | if (r) |
| 659 | return r; | 669 | goto err; |
| 660 | 670 | ||
| 661 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | 671 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; |
| 672 | err: | ||
| 673 | mutex_unlock(&drv_data->lock); | ||
| 662 | 674 | ||
| 663 | return 0; | 675 | return r; |
| 664 | } | 676 | } |
| 665 | 677 | ||
| 666 | static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) | 678 | static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) |
| 667 | { | 679 | { |
| 680 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); | ||
| 681 | |||
| 682 | mutex_lock(&drv_data->lock); | ||
| 683 | |||
| 668 | generic_dpi_panel_power_off(dssdev); | 684 | generic_dpi_panel_power_off(dssdev); |
| 669 | 685 | ||
| 670 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | 686 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; |
| 687 | |||
| 688 | mutex_unlock(&drv_data->lock); | ||
| 671 | } | 689 | } |
| 672 | 690 | ||
| 673 | static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev) | 691 | static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev) |
| 674 | { | 692 | { |
| 693 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); | ||
| 694 | |||
| 695 | mutex_lock(&drv_data->lock); | ||
| 696 | |||
| 675 | generic_dpi_panel_power_off(dssdev); | 697 | generic_dpi_panel_power_off(dssdev); |
| 676 | 698 | ||
| 677 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; | 699 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; |
| 678 | 700 | ||
| 701 | mutex_unlock(&drv_data->lock); | ||
| 702 | |||
| 679 | return 0; | 703 | return 0; |
| 680 | } | 704 | } |
| 681 | 705 | ||
| 682 | static int generic_dpi_panel_resume(struct omap_dss_device *dssdev) | 706 | static int generic_dpi_panel_resume(struct omap_dss_device *dssdev) |
| 683 | { | 707 | { |
| 684 | int r = 0; | 708 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); |
| 709 | int r; | ||
| 710 | |||
| 711 | mutex_lock(&drv_data->lock); | ||
| 685 | 712 | ||
| 686 | r = generic_dpi_panel_power_on(dssdev); | 713 | r = generic_dpi_panel_power_on(dssdev); |
| 687 | if (r) | 714 | if (r) |
| 688 | return r; | 715 | goto err; |
| 689 | 716 | ||
| 690 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | 717 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; |
| 691 | 718 | ||
| 692 | return 0; | 719 | err: |
| 720 | mutex_unlock(&drv_data->lock); | ||
| 721 | |||
| 722 | return r; | ||
| 693 | } | 723 | } |
| 694 | 724 | ||
| 695 | static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, | 725 | static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, |
| 696 | struct omap_video_timings *timings) | 726 | struct omap_video_timings *timings) |
| 697 | { | 727 | { |
| 698 | dpi_set_timings(dssdev, timings); | 728 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); |
| 729 | |||
| 730 | mutex_lock(&drv_data->lock); | ||
| 731 | |||
| 732 | omapdss_dpi_set_timings(dssdev, timings); | ||
| 733 | |||
| 734 | dssdev->panel.timings = *timings; | ||
| 735 | |||
| 736 | mutex_unlock(&drv_data->lock); | ||
| 737 | } | ||
| 738 | |||
| 739 | static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, | ||
| 740 | struct omap_video_timings *timings) | ||
| 741 | { | ||
| 742 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); | ||
| 743 | |||
| 744 | mutex_lock(&drv_data->lock); | ||
| 745 | |||
| 746 | *timings = dssdev->panel.timings; | ||
| 747 | |||
| 748 | mutex_unlock(&drv_data->lock); | ||
| 699 | } | 749 | } |
| 700 | 750 | ||
| 701 | static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, | 751 | static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, |
| 702 | struct omap_video_timings *timings) | 752 | struct omap_video_timings *timings) |
| 703 | { | 753 | { |
| 704 | return dpi_check_timings(dssdev, timings); | 754 | struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); |
| 755 | int r; | ||
| 756 | |||
| 757 | mutex_lock(&drv_data->lock); | ||
| 758 | |||
| 759 | r = dpi_check_timings(dssdev, timings); | ||
| 760 | |||
| 761 | mutex_unlock(&drv_data->lock); | ||
| 762 | |||
| 763 | return r; | ||
| 705 | } | 764 | } |
| 706 | 765 | ||
| 707 | static struct omap_dss_driver dpi_driver = { | 766 | static struct omap_dss_driver dpi_driver = { |
| @@ -714,6 +773,7 @@ static struct omap_dss_driver dpi_driver = { | |||
| 714 | .resume = generic_dpi_panel_resume, | 773 | .resume = generic_dpi_panel_resume, |
| 715 | 774 | ||
| 716 | .set_timings = generic_dpi_panel_set_timings, | 775 | .set_timings = generic_dpi_panel_set_timings, |
| 776 | .get_timings = generic_dpi_panel_get_timings, | ||
| 717 | .check_timings = generic_dpi_panel_check_timings, | 777 | .check_timings = generic_dpi_panel_check_timings, |
| 718 | 778 | ||
| 719 | .driver = { | 779 | .driver = { |
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c index 802807798846..90c1cabf244e 100644 --- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c | |||
| @@ -55,6 +55,9 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) | |||
| 55 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 55 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
| 56 | return 0; | 56 | return 0; |
| 57 | 57 | ||
| 58 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 59 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 60 | |||
| 58 | r = omapdss_dpi_display_enable(dssdev); | 61 | r = omapdss_dpi_display_enable(dssdev); |
| 59 | if (r) | 62 | if (r) |
| 60 | goto err0; | 63 | goto err0; |
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c index e6c115373c00..3fc5ad081a21 100644 --- a/drivers/video/omap2/displays/panel-n8x0.c +++ b/drivers/video/omap2/displays/panel-n8x0.c | |||
| @@ -150,11 +150,17 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev, | |||
| 150 | BLIZZARD_SRC_WRITE_LCD : | 150 | BLIZZARD_SRC_WRITE_LCD : |
| 151 | BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE; | 151 | BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE; |
| 152 | 152 | ||
| 153 | omap_rfbi_configure(dssdev, 16, 8); | 153 | omapdss_rfbi_set_pixel_size(dssdev, 16); |
| 154 | omapdss_rfbi_set_data_lines(dssdev, 8); | ||
| 155 | |||
| 156 | omap_rfbi_configure(dssdev); | ||
| 154 | 157 | ||
| 155 | blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18); | 158 | blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18); |
| 156 | 159 | ||
| 157 | omap_rfbi_configure(dssdev, 16, 16); | 160 | omapdss_rfbi_set_pixel_size(dssdev, 16); |
| 161 | omapdss_rfbi_set_data_lines(dssdev, 16); | ||
| 162 | |||
| 163 | omap_rfbi_configure(dssdev); | ||
| 158 | } | 164 | } |
| 159 | 165 | ||
| 160 | static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf, | 166 | static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf, |
| @@ -297,6 +303,12 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev) | |||
| 297 | goto err_plat_en; | 303 | goto err_plat_en; |
| 298 | } | 304 | } |
| 299 | 305 | ||
| 306 | omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res, | ||
| 307 | dssdev->panel.timings.y_res); | ||
| 308 | omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size); | ||
| 309 | omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines); | ||
| 310 | omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings); | ||
| 311 | |||
| 300 | r = omapdss_rfbi_display_enable(dssdev); | 312 | r = omapdss_rfbi_display_enable(dssdev); |
| 301 | if (r) | 313 | if (r) |
| 302 | goto err_rfbi_en; | 314 | goto err_rfbi_en; |
| @@ -477,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev) | |||
| 477 | dssdev->panel.timings.y_res = 480; | 489 | dssdev->panel.timings.y_res = 480; |
| 478 | dssdev->ctrl.pixel_size = 16; | 490 | dssdev->ctrl.pixel_size = 16; |
| 479 | dssdev->ctrl.rfbi_timings = n8x0_panel_timings; | 491 | dssdev->ctrl.rfbi_timings = n8x0_panel_timings; |
| 492 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; | ||
| 480 | 493 | ||
| 481 | memset(&props, 0, sizeof(props)); | 494 | memset(&props, 0, sizeof(props)); |
| 482 | props.max_brightness = 127; | 495 | props.max_brightness = 127; |
| @@ -625,17 +638,25 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev, | |||
| 625 | u16 x, u16 y, u16 w, u16 h) | 638 | u16 x, u16 y, u16 w, u16 h) |
| 626 | { | 639 | { |
| 627 | struct panel_drv_data *ddata = get_drv_data(dssdev); | 640 | struct panel_drv_data *ddata = get_drv_data(dssdev); |
| 641 | u16 dw, dh; | ||
| 628 | 642 | ||
| 629 | dev_dbg(&dssdev->dev, "update\n"); | 643 | dev_dbg(&dssdev->dev, "update\n"); |
| 630 | 644 | ||
| 645 | dw = dssdev->panel.timings.x_res; | ||
| 646 | dh = dssdev->panel.timings.y_res; | ||
| 647 | |||
| 648 | if (x != 0 || y != 0 || w != dw || h != dh) { | ||
| 649 | dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n", | ||
| 650 | x, y, w, h); | ||
| 651 | return -EINVAL; | ||
| 652 | } | ||
| 653 | |||
| 631 | mutex_lock(&ddata->lock); | 654 | mutex_lock(&ddata->lock); |
| 632 | rfbi_bus_lock(); | 655 | rfbi_bus_lock(); |
| 633 | 656 | ||
| 634 | omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h); | ||
| 635 | |||
| 636 | blizzard_ctrl_setup_update(dssdev, x, y, w, h); | 657 | blizzard_ctrl_setup_update(dssdev, x, y, w, h); |
| 637 | 658 | ||
| 638 | omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL); | 659 | omap_rfbi_update(dssdev, update_done, NULL); |
| 639 | 660 | ||
| 640 | mutex_unlock(&ddata->lock); | 661 | mutex_unlock(&ddata->lock); |
| 641 | 662 | ||
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index b122b0f31c43..908fd268f3dc 100644 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c | |||
| @@ -175,6 +175,9 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev) | |||
| 175 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 175 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
| 176 | return 0; | 176 | return 0; |
| 177 | 177 | ||
| 178 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 179 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 180 | |||
| 178 | r = omapdss_dpi_display_enable(dssdev); | 181 | r = omapdss_dpi_display_enable(dssdev); |
| 179 | if (r) | 182 | if (r) |
| 180 | goto err0; | 183 | goto err0; |
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c index 2d35bd388860..9df87640ddd2 100644 --- a/drivers/video/omap2/displays/panel-picodlp.c +++ b/drivers/video/omap2/displays/panel-picodlp.c | |||
| @@ -377,6 +377,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev) | |||
| 377 | * then only i2c commands can be successfully sent to dpp2600 | 377 | * then only i2c commands can be successfully sent to dpp2600 |
| 378 | */ | 378 | */ |
| 379 | msleep(1000); | 379 | msleep(1000); |
| 380 | |||
| 381 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 382 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 383 | |||
| 380 | r = omapdss_dpi_display_enable(dssdev); | 384 | r = omapdss_dpi_display_enable(dssdev); |
| 381 | if (r) { | 385 | if (r) { |
| 382 | dev_err(&dssdev->dev, "failed to enable DPI\n"); | 386 | dev_err(&dssdev->dev, "failed to enable DPI\n"); |
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index bd86ba9ccf76..1ec3b277ff15 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c | |||
| @@ -142,6 +142,9 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev) | |||
| 142 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 142 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
| 143 | return 0; | 143 | return 0; |
| 144 | 144 | ||
| 145 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 146 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 147 | |||
| 145 | r = omapdss_dpi_display_enable(dssdev); | 148 | r = omapdss_dpi_display_enable(dssdev); |
| 146 | if (r) | 149 | if (r) |
| 147 | goto err0; | 150 | goto err0; |
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 3f5acc7771da..4cf94161ff51 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c | |||
| @@ -121,6 +121,18 @@ struct taal_data { | |||
| 121 | 121 | ||
| 122 | struct omap_dss_device *dssdev; | 122 | struct omap_dss_device *dssdev; |
| 123 | 123 | ||
| 124 | /* panel specific HW info */ | ||
| 125 | struct panel_config *panel_config; | ||
| 126 | |||
| 127 | /* panel HW configuration from DT or platform data */ | ||
| 128 | int reset_gpio; | ||
| 129 | int ext_te_gpio; | ||
| 130 | |||
| 131 | bool use_dsi_backlight; | ||
| 132 | |||
| 133 | struct omap_dsi_pin_config pin_config; | ||
| 134 | |||
| 135 | /* runtime variables */ | ||
| 124 | bool enabled; | 136 | bool enabled; |
| 125 | u8 rotate; | 137 | u8 rotate; |
| 126 | bool mirror; | 138 | bool mirror; |
| @@ -145,16 +157,8 @@ struct taal_data { | |||
| 145 | bool ulps_enabled; | 157 | bool ulps_enabled; |
| 146 | unsigned ulps_timeout; | 158 | unsigned ulps_timeout; |
| 147 | struct delayed_work ulps_work; | 159 | struct delayed_work ulps_work; |
| 148 | |||
| 149 | struct panel_config *panel_config; | ||
| 150 | }; | 160 | }; |
| 151 | 161 | ||
| 152 | static inline struct nokia_dsi_panel_data | ||
| 153 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
| 154 | { | ||
| 155 | return (struct nokia_dsi_panel_data *) dssdev->data; | ||
| 156 | } | ||
| 157 | |||
| 158 | static void taal_esd_work(struct work_struct *work); | 162 | static void taal_esd_work(struct work_struct *work); |
| 159 | static void taal_ulps_work(struct work_struct *work); | 163 | static void taal_ulps_work(struct work_struct *work); |
| 160 | 164 | ||
| @@ -371,7 +375,6 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev) | |||
| 371 | static int taal_enter_ulps(struct omap_dss_device *dssdev) | 375 | static int taal_enter_ulps(struct omap_dss_device *dssdev) |
| 372 | { | 376 | { |
| 373 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 377 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 374 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 375 | int r; | 378 | int r; |
| 376 | 379 | ||
| 377 | if (td->ulps_enabled) | 380 | if (td->ulps_enabled) |
| @@ -383,7 +386,8 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev) | |||
| 383 | if (r) | 386 | if (r) |
| 384 | goto err; | 387 | goto err; |
| 385 | 388 | ||
| 386 | disable_irq(gpio_to_irq(panel_data->ext_te_gpio)); | 389 | if (gpio_is_valid(td->ext_te_gpio)) |
| 390 | disable_irq(gpio_to_irq(td->ext_te_gpio)); | ||
| 387 | 391 | ||
| 388 | omapdss_dsi_display_disable(dssdev, false, true); | 392 | omapdss_dsi_display_disable(dssdev, false, true); |
| 389 | 393 | ||
| @@ -405,7 +409,6 @@ err: | |||
| 405 | static int taal_exit_ulps(struct omap_dss_device *dssdev) | 409 | static int taal_exit_ulps(struct omap_dss_device *dssdev) |
| 406 | { | 410 | { |
| 407 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 411 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 408 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 409 | int r; | 412 | int r; |
| 410 | 413 | ||
| 411 | if (!td->ulps_enabled) | 414 | if (!td->ulps_enabled) |
| @@ -425,7 +428,8 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev) | |||
| 425 | goto err2; | 428 | goto err2; |
| 426 | } | 429 | } |
| 427 | 430 | ||
| 428 | enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); | 431 | if (gpio_is_valid(td->ext_te_gpio)) |
| 432 | enable_irq(gpio_to_irq(td->ext_te_gpio)); | ||
| 429 | 433 | ||
| 430 | taal_queue_ulps_work(dssdev); | 434 | taal_queue_ulps_work(dssdev); |
| 431 | 435 | ||
| @@ -438,7 +442,8 @@ err2: | |||
| 438 | 442 | ||
| 439 | r = taal_panel_reset(dssdev); | 443 | r = taal_panel_reset(dssdev); |
| 440 | if (!r) { | 444 | if (!r) { |
| 441 | enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); | 445 | if (gpio_is_valid(td->ext_te_gpio)) |
| 446 | enable_irq(gpio_to_irq(td->ext_te_gpio)); | ||
| 442 | td->ulps_enabled = false; | 447 | td->ulps_enabled = false; |
| 443 | } | 448 | } |
| 444 | err1: | 449 | err1: |
| @@ -835,94 +840,135 @@ static struct attribute_group taal_attr_group = { | |||
| 835 | static void taal_hw_reset(struct omap_dss_device *dssdev) | 840 | static void taal_hw_reset(struct omap_dss_device *dssdev) |
| 836 | { | 841 | { |
| 837 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 842 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 838 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 839 | 843 | ||
| 840 | if (panel_data->reset_gpio == -1) | 844 | if (!gpio_is_valid(td->reset_gpio)) |
| 841 | return; | 845 | return; |
| 842 | 846 | ||
| 843 | gpio_set_value(panel_data->reset_gpio, 1); | 847 | gpio_set_value(td->reset_gpio, 1); |
| 844 | if (td->panel_config->reset_sequence.high) | 848 | if (td->panel_config->reset_sequence.high) |
| 845 | udelay(td->panel_config->reset_sequence.high); | 849 | udelay(td->panel_config->reset_sequence.high); |
| 846 | /* reset the panel */ | 850 | /* reset the panel */ |
| 847 | gpio_set_value(panel_data->reset_gpio, 0); | 851 | gpio_set_value(td->reset_gpio, 0); |
| 848 | /* assert reset */ | 852 | /* assert reset */ |
| 849 | if (td->panel_config->reset_sequence.low) | 853 | if (td->panel_config->reset_sequence.low) |
| 850 | udelay(td->panel_config->reset_sequence.low); | 854 | udelay(td->panel_config->reset_sequence.low); |
| 851 | gpio_set_value(panel_data->reset_gpio, 1); | 855 | gpio_set_value(td->reset_gpio, 1); |
| 852 | /* wait after releasing reset */ | 856 | /* wait after releasing reset */ |
| 853 | if (td->panel_config->sleep.hw_reset) | 857 | if (td->panel_config->sleep.hw_reset) |
| 854 | msleep(td->panel_config->sleep.hw_reset); | 858 | msleep(td->panel_config->sleep.hw_reset); |
| 855 | } | 859 | } |
| 856 | 860 | ||
| 861 | static void taal_probe_pdata(struct taal_data *td, | ||
| 862 | const struct nokia_dsi_panel_data *pdata) | ||
| 863 | { | ||
| 864 | td->reset_gpio = pdata->reset_gpio; | ||
| 865 | |||
| 866 | if (pdata->use_ext_te) | ||
| 867 | td->ext_te_gpio = pdata->ext_te_gpio; | ||
| 868 | else | ||
| 869 | td->ext_te_gpio = -1; | ||
| 870 | |||
| 871 | td->esd_interval = pdata->esd_interval; | ||
| 872 | td->ulps_timeout = pdata->ulps_timeout; | ||
| 873 | |||
| 874 | td->use_dsi_backlight = pdata->use_dsi_backlight; | ||
| 875 | |||
| 876 | td->pin_config = pdata->pin_config; | ||
| 877 | } | ||
| 878 | |||
| 857 | static int taal_probe(struct omap_dss_device *dssdev) | 879 | static int taal_probe(struct omap_dss_device *dssdev) |
| 858 | { | 880 | { |
| 859 | struct backlight_properties props; | 881 | struct backlight_properties props; |
| 860 | struct taal_data *td; | 882 | struct taal_data *td; |
| 861 | struct backlight_device *bldev = NULL; | 883 | struct backlight_device *bldev = NULL; |
| 862 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 863 | struct panel_config *panel_config = NULL; | ||
| 864 | int r, i; | 884 | int r, i; |
| 885 | const char *panel_name; | ||
| 865 | 886 | ||
| 866 | dev_dbg(&dssdev->dev, "probe\n"); | 887 | dev_dbg(&dssdev->dev, "probe\n"); |
| 867 | 888 | ||
| 868 | if (!panel_data || !panel_data->name) { | 889 | td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL); |
| 869 | r = -EINVAL; | 890 | if (!td) |
| 870 | goto err; | 891 | return -ENOMEM; |
| 892 | |||
| 893 | dev_set_drvdata(&dssdev->dev, td); | ||
| 894 | td->dssdev = dssdev; | ||
| 895 | |||
| 896 | if (dssdev->data) { | ||
| 897 | const struct nokia_dsi_panel_data *pdata = dssdev->data; | ||
| 898 | |||
| 899 | taal_probe_pdata(td, pdata); | ||
| 900 | |||
| 901 | panel_name = pdata->name; | ||
| 902 | } else { | ||
| 903 | return -ENODEV; | ||
| 871 | } | 904 | } |
| 872 | 905 | ||
| 906 | if (panel_name == NULL) | ||
| 907 | return -EINVAL; | ||
| 908 | |||
| 873 | for (i = 0; i < ARRAY_SIZE(panel_configs); i++) { | 909 | for (i = 0; i < ARRAY_SIZE(panel_configs); i++) { |
| 874 | if (strcmp(panel_data->name, panel_configs[i].name) == 0) { | 910 | if (strcmp(panel_name, panel_configs[i].name) == 0) { |
| 875 | panel_config = &panel_configs[i]; | 911 | td->panel_config = &panel_configs[i]; |
| 876 | break; | 912 | break; |
| 877 | } | 913 | } |
| 878 | } | 914 | } |
| 879 | 915 | ||
| 880 | if (!panel_config) { | 916 | if (!td->panel_config) |
| 881 | r = -EINVAL; | 917 | return -EINVAL; |
| 882 | goto err; | ||
| 883 | } | ||
| 884 | 918 | ||
| 885 | dssdev->panel.timings = panel_config->timings; | 919 | dssdev->panel.timings = td->panel_config->timings; |
| 886 | dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; | 920 | dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; |
| 887 | 921 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | | |
| 888 | td = kzalloc(sizeof(*td), GFP_KERNEL); | 922 | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; |
| 889 | if (!td) { | ||
| 890 | r = -ENOMEM; | ||
| 891 | goto err; | ||
| 892 | } | ||
| 893 | td->dssdev = dssdev; | ||
| 894 | td->panel_config = panel_config; | ||
| 895 | td->esd_interval = panel_data->esd_interval; | ||
| 896 | td->ulps_enabled = false; | ||
| 897 | td->ulps_timeout = panel_data->ulps_timeout; | ||
| 898 | 923 | ||
| 899 | mutex_init(&td->lock); | 924 | mutex_init(&td->lock); |
| 900 | 925 | ||
| 901 | atomic_set(&td->do_update, 0); | 926 | atomic_set(&td->do_update, 0); |
| 902 | 927 | ||
| 903 | td->workqueue = create_singlethread_workqueue("taal_esd"); | 928 | if (gpio_is_valid(td->reset_gpio)) { |
| 904 | if (td->workqueue == NULL) { | 929 | r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio, |
| 905 | dev_err(&dssdev->dev, "can't create ESD workqueue\n"); | 930 | GPIOF_OUT_INIT_LOW, "taal rst"); |
| 906 | r = -ENOMEM; | 931 | if (r) { |
| 907 | goto err_wq; | 932 | dev_err(&dssdev->dev, "failed to request reset gpio\n"); |
| 933 | return r; | ||
| 934 | } | ||
| 908 | } | 935 | } |
| 909 | INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); | ||
| 910 | INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work); | ||
| 911 | 936 | ||
| 912 | dev_set_drvdata(&dssdev->dev, td); | 937 | if (gpio_is_valid(td->ext_te_gpio)) { |
| 938 | r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio, | ||
| 939 | GPIOF_IN, "taal irq"); | ||
| 940 | if (r) { | ||
| 941 | dev_err(&dssdev->dev, "GPIO request failed\n"); | ||
| 942 | return r; | ||
| 943 | } | ||
| 944 | |||
| 945 | r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio), | ||
| 946 | taal_te_isr, | ||
| 947 | IRQF_TRIGGER_RISING, | ||
| 948 | "taal vsync", dssdev); | ||
| 913 | 949 | ||
| 914 | if (gpio_is_valid(panel_data->reset_gpio)) { | ||
| 915 | r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW, | ||
| 916 | "taal rst"); | ||
| 917 | if (r) { | 950 | if (r) { |
| 918 | dev_err(&dssdev->dev, "failed to request reset gpio\n"); | 951 | dev_err(&dssdev->dev, "IRQ request failed\n"); |
| 919 | goto err_rst_gpio; | 952 | return r; |
| 920 | } | 953 | } |
| 954 | |||
| 955 | INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work, | ||
| 956 | taal_te_timeout_work_callback); | ||
| 957 | |||
| 958 | dev_dbg(&dssdev->dev, "Using GPIO TE\n"); | ||
| 921 | } | 959 | } |
| 922 | 960 | ||
| 961 | td->workqueue = create_singlethread_workqueue("taal_esd"); | ||
| 962 | if (td->workqueue == NULL) { | ||
| 963 | dev_err(&dssdev->dev, "can't create ESD workqueue\n"); | ||
| 964 | return -ENOMEM; | ||
| 965 | } | ||
| 966 | INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); | ||
| 967 | INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work); | ||
| 968 | |||
| 923 | taal_hw_reset(dssdev); | 969 | taal_hw_reset(dssdev); |
| 924 | 970 | ||
| 925 | if (panel_data->use_dsi_backlight) { | 971 | if (td->use_dsi_backlight) { |
| 926 | memset(&props, 0, sizeof(struct backlight_properties)); | 972 | memset(&props, 0, sizeof(struct backlight_properties)); |
| 927 | props.max_brightness = 255; | 973 | props.max_brightness = 255; |
| 928 | 974 | ||
| @@ -943,31 +989,6 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
| 943 | taal_bl_update_status(bldev); | 989 | taal_bl_update_status(bldev); |
| 944 | } | 990 | } |
| 945 | 991 | ||
| 946 | if (panel_data->use_ext_te) { | ||
| 947 | int gpio = panel_data->ext_te_gpio; | ||
| 948 | |||
| 949 | r = gpio_request_one(gpio, GPIOF_IN, "taal irq"); | ||
| 950 | if (r) { | ||
| 951 | dev_err(&dssdev->dev, "GPIO request failed\n"); | ||
| 952 | goto err_gpio; | ||
| 953 | } | ||
| 954 | |||
| 955 | r = request_irq(gpio_to_irq(gpio), taal_te_isr, | ||
| 956 | IRQF_TRIGGER_RISING, | ||
| 957 | "taal vsync", dssdev); | ||
| 958 | |||
| 959 | if (r) { | ||
| 960 | dev_err(&dssdev->dev, "IRQ request failed\n"); | ||
| 961 | gpio_free(gpio); | ||
| 962 | goto err_irq; | ||
| 963 | } | ||
| 964 | |||
| 965 | INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work, | ||
| 966 | taal_te_timeout_work_callback); | ||
| 967 | |||
| 968 | dev_dbg(&dssdev->dev, "Using GPIO TE\n"); | ||
| 969 | } | ||
| 970 | |||
| 971 | r = omap_dsi_request_vc(dssdev, &td->channel); | 992 | r = omap_dsi_request_vc(dssdev, &td->channel); |
| 972 | if (r) { | 993 | if (r) { |
| 973 | dev_err(&dssdev->dev, "failed to get virtual channel\n"); | 994 | dev_err(&dssdev->dev, "failed to get virtual channel\n"); |
| @@ -991,29 +1012,16 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
| 991 | err_vc_id: | 1012 | err_vc_id: |
| 992 | omap_dsi_release_vc(dssdev, td->channel); | 1013 | omap_dsi_release_vc(dssdev, td->channel); |
| 993 | err_req_vc: | 1014 | err_req_vc: |
| 994 | if (panel_data->use_ext_te) | ||
| 995 | free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); | ||
| 996 | err_irq: | ||
| 997 | if (panel_data->use_ext_te) | ||
| 998 | gpio_free(panel_data->ext_te_gpio); | ||
| 999 | err_gpio: | ||
| 1000 | if (bldev != NULL) | 1015 | if (bldev != NULL) |
| 1001 | backlight_device_unregister(bldev); | 1016 | backlight_device_unregister(bldev); |
| 1002 | err_bl: | 1017 | err_bl: |
| 1003 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
| 1004 | gpio_free(panel_data->reset_gpio); | ||
| 1005 | err_rst_gpio: | ||
| 1006 | destroy_workqueue(td->workqueue); | 1018 | destroy_workqueue(td->workqueue); |
| 1007 | err_wq: | ||
| 1008 | kfree(td); | ||
| 1009 | err: | ||
| 1010 | return r; | 1019 | return r; |
| 1011 | } | 1020 | } |
| 1012 | 1021 | ||
| 1013 | static void __exit taal_remove(struct omap_dss_device *dssdev) | 1022 | static void __exit taal_remove(struct omap_dss_device *dssdev) |
| 1014 | { | 1023 | { |
| 1015 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 1024 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 1016 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 1017 | struct backlight_device *bldev; | 1025 | struct backlight_device *bldev; |
| 1018 | 1026 | ||
| 1019 | dev_dbg(&dssdev->dev, "remove\n"); | 1027 | dev_dbg(&dssdev->dev, "remove\n"); |
| @@ -1021,12 +1029,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev) | |||
| 1021 | sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); | 1029 | sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); |
| 1022 | omap_dsi_release_vc(dssdev, td->channel); | 1030 | omap_dsi_release_vc(dssdev, td->channel); |
| 1023 | 1031 | ||
| 1024 | if (panel_data->use_ext_te) { | ||
| 1025 | int gpio = panel_data->ext_te_gpio; | ||
| 1026 | free_irq(gpio_to_irq(gpio), dssdev); | ||
| 1027 | gpio_free(gpio); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | bldev = td->bldev; | 1032 | bldev = td->bldev; |
| 1031 | if (bldev != NULL) { | 1033 | if (bldev != NULL) { |
| 1032 | bldev->props.power = FB_BLANK_POWERDOWN; | 1034 | bldev->props.power = FB_BLANK_POWERDOWN; |
| @@ -1040,26 +1042,31 @@ static void __exit taal_remove(struct omap_dss_device *dssdev) | |||
| 1040 | 1042 | ||
| 1041 | /* reset, to be sure that the panel is in a valid state */ | 1043 | /* reset, to be sure that the panel is in a valid state */ |
| 1042 | taal_hw_reset(dssdev); | 1044 | taal_hw_reset(dssdev); |
| 1043 | |||
| 1044 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
| 1045 | gpio_free(panel_data->reset_gpio); | ||
| 1046 | |||
| 1047 | kfree(td); | ||
| 1048 | } | 1045 | } |
| 1049 | 1046 | ||
| 1050 | static int taal_power_on(struct omap_dss_device *dssdev) | 1047 | static int taal_power_on(struct omap_dss_device *dssdev) |
| 1051 | { | 1048 | { |
| 1052 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 1049 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 1053 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 1054 | u8 id1, id2, id3; | 1050 | u8 id1, id2, id3; |
| 1055 | int r; | 1051 | int r; |
| 1056 | 1052 | ||
| 1057 | r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config); | 1053 | r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); |
| 1058 | if (r) { | 1054 | if (r) { |
| 1059 | dev_err(&dssdev->dev, "failed to configure DSI pins\n"); | 1055 | dev_err(&dssdev->dev, "failed to configure DSI pins\n"); |
| 1060 | goto err0; | 1056 | goto err0; |
| 1061 | }; | 1057 | }; |
| 1062 | 1058 | ||
| 1059 | omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res, | ||
| 1060 | dssdev->panel.timings.y_res); | ||
| 1061 | omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888); | ||
| 1062 | omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE); | ||
| 1063 | |||
| 1064 | r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000); | ||
| 1065 | if (r) { | ||
| 1066 | dev_err(&dssdev->dev, "failed to set HS and LP clocks\n"); | ||
| 1067 | goto err0; | ||
| 1068 | } | ||
| 1069 | |||
| 1063 | r = omapdss_dsi_display_enable(dssdev); | 1070 | r = omapdss_dsi_display_enable(dssdev); |
| 1064 | if (r) { | 1071 | if (r) { |
| 1065 | dev_err(&dssdev->dev, "failed to enable DSI\n"); | 1072 | dev_err(&dssdev->dev, "failed to enable DSI\n"); |
| @@ -1356,7 +1363,6 @@ static int taal_update(struct omap_dss_device *dssdev, | |||
| 1356 | u16 x, u16 y, u16 w, u16 h) | 1363 | u16 x, u16 y, u16 w, u16 h) |
| 1357 | { | 1364 | { |
| 1358 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 1365 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 1359 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 1360 | int r; | 1366 | int r; |
| 1361 | 1367 | ||
| 1362 | dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); | 1368 | dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); |
| @@ -1380,7 +1386,7 @@ static int taal_update(struct omap_dss_device *dssdev, | |||
| 1380 | if (r) | 1386 | if (r) |
| 1381 | goto err; | 1387 | goto err; |
| 1382 | 1388 | ||
| 1383 | if (td->te_enabled && panel_data->use_ext_te) { | 1389 | if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) { |
| 1384 | schedule_delayed_work(&td->te_timeout_work, | 1390 | schedule_delayed_work(&td->te_timeout_work, |
| 1385 | msecs_to_jiffies(250)); | 1391 | msecs_to_jiffies(250)); |
| 1386 | atomic_set(&td->do_update, 1); | 1392 | atomic_set(&td->do_update, 1); |
| @@ -1419,7 +1425,6 @@ static int taal_sync(struct omap_dss_device *dssdev) | |||
| 1419 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) | 1425 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) |
| 1420 | { | 1426 | { |
| 1421 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 1427 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 1422 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 1423 | int r; | 1428 | int r; |
| 1424 | 1429 | ||
| 1425 | if (enable) | 1430 | if (enable) |
| @@ -1427,7 +1432,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) | |||
| 1427 | else | 1432 | else |
| 1428 | r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF); | 1433 | r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF); |
| 1429 | 1434 | ||
| 1430 | if (!panel_data->use_ext_te) | 1435 | if (!gpio_is_valid(td->ext_te_gpio)) |
| 1431 | omapdss_dsi_enable_te(dssdev, enable); | 1436 | omapdss_dsi_enable_te(dssdev, enable); |
| 1432 | 1437 | ||
| 1433 | if (td->panel_config->sleep.enable_te) | 1438 | if (td->panel_config->sleep.enable_te) |
| @@ -1487,6 +1492,7 @@ static int taal_get_te(struct omap_dss_device *dssdev) | |||
| 1487 | static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) | 1492 | static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) |
| 1488 | { | 1493 | { |
| 1489 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 1494 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
| 1495 | u16 dw, dh; | ||
| 1490 | int r; | 1496 | int r; |
| 1491 | 1497 | ||
| 1492 | dev_dbg(&dssdev->dev, "rotate %d\n", rotate); | 1498 | dev_dbg(&dssdev->dev, "rotate %d\n", rotate); |
| @@ -1508,6 +1514,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) | |||
| 1508 | goto err; | 1514 | goto err; |
| 1509 | } | 1515 | } |
| 1510 | 1516 | ||
| 1517 | if (rotate == 0 || rotate == 2) { | ||
| 1518 | dw = dssdev->panel.timings.x_res; | ||
| 1519 | dh = dssdev->panel.timings.y_res; | ||
| 1520 | } else { | ||
| 1521 | dw = dssdev->panel.timings.y_res; | ||
| 1522 | dh = dssdev->panel.timings.x_res; | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | omapdss_dsi_set_size(dssdev, dw, dh); | ||
| 1526 | |||
| 1511 | td->rotate = rotate; | 1527 | td->rotate = rotate; |
| 1512 | 1528 | ||
| 1513 | dsi_bus_unlock(dssdev); | 1529 | dsi_bus_unlock(dssdev); |
| @@ -1726,7 +1742,6 @@ static void taal_esd_work(struct work_struct *work) | |||
| 1726 | struct taal_data *td = container_of(work, struct taal_data, | 1742 | struct taal_data *td = container_of(work, struct taal_data, |
| 1727 | esd_work.work); | 1743 | esd_work.work); |
| 1728 | struct omap_dss_device *dssdev = td->dssdev; | 1744 | struct omap_dss_device *dssdev = td->dssdev; |
| 1729 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
| 1730 | u8 state1, state2; | 1745 | u8 state1, state2; |
| 1731 | int r; | 1746 | int r; |
| 1732 | 1747 | ||
| @@ -1773,7 +1788,7 @@ static void taal_esd_work(struct work_struct *work) | |||
| 1773 | } | 1788 | } |
| 1774 | /* Self-diagnostics result is also shown on TE GPIO line. We need | 1789 | /* Self-diagnostics result is also shown on TE GPIO line. We need |
| 1775 | * to re-enable TE after self diagnostics */ | 1790 | * to re-enable TE after self diagnostics */ |
| 1776 | if (td->te_enabled && panel_data->use_ext_te) { | 1791 | if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) { |
| 1777 | r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); | 1792 | r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); |
| 1778 | if (r) | 1793 | if (r) |
| 1779 | goto err; | 1794 | goto err; |
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c index 40cc0cfa5d17..383811cf8648 100644 --- a/drivers/video/omap2/displays/panel-tfp410.c +++ b/drivers/video/omap2/displays/panel-tfp410.c | |||
| @@ -65,6 +65,9 @@ static int tfp410_power_on(struct omap_dss_device *dssdev) | |||
| 65 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 65 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
| 66 | return 0; | 66 | return 0; |
| 67 | 67 | ||
| 68 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 69 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 70 | |||
| 68 | r = omapdss_dpi_display_enable(dssdev); | 71 | r = omapdss_dpi_display_enable(dssdev); |
| 69 | if (r) | 72 | if (r) |
| 70 | goto err0; | 73 | goto err0; |
| @@ -116,8 +119,8 @@ static int tfp410_probe(struct omap_dss_device *dssdev) | |||
| 116 | } | 119 | } |
| 117 | 120 | ||
| 118 | if (gpio_is_valid(ddata->pd_gpio)) { | 121 | if (gpio_is_valid(ddata->pd_gpio)) { |
| 119 | r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, | 122 | r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio, |
| 120 | "tfp410 pd"); | 123 | GPIOF_OUT_INIT_LOW, "tfp410 pd"); |
| 121 | if (r) { | 124 | if (r) { |
| 122 | dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", | 125 | dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", |
| 123 | ddata->pd_gpio); | 126 | ddata->pd_gpio); |
| @@ -132,8 +135,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev) | |||
| 132 | if (!adapter) { | 135 | if (!adapter) { |
| 133 | dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", | 136 | dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", |
| 134 | i2c_bus_num); | 137 | i2c_bus_num); |
| 135 | r = -EINVAL; | 138 | return -EINVAL; |
| 136 | goto err_i2c; | ||
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | ddata->i2c_adapter = adapter; | 141 | ddata->i2c_adapter = adapter; |
| @@ -142,10 +144,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev) | |||
| 142 | dev_set_drvdata(&dssdev->dev, ddata); | 144 | dev_set_drvdata(&dssdev->dev, ddata); |
| 143 | 145 | ||
| 144 | return 0; | 146 | return 0; |
| 145 | err_i2c: | ||
| 146 | if (gpio_is_valid(ddata->pd_gpio)) | ||
| 147 | gpio_free(ddata->pd_gpio); | ||
| 148 | return r; | ||
| 149 | } | 147 | } |
| 150 | 148 | ||
| 151 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) | 149 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) |
| @@ -157,9 +155,6 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev) | |||
| 157 | if (ddata->i2c_adapter) | 155 | if (ddata->i2c_adapter) |
| 158 | i2c_put_adapter(ddata->i2c_adapter); | 156 | i2c_put_adapter(ddata->i2c_adapter); |
| 159 | 157 | ||
| 160 | if (gpio_is_valid(ddata->pd_gpio)) | ||
| 161 | gpio_free(ddata->pd_gpio); | ||
| 162 | |||
| 163 | dev_set_drvdata(&dssdev->dev, NULL); | 158 | dev_set_drvdata(&dssdev->dev, NULL); |
| 164 | 159 | ||
| 165 | mutex_unlock(&ddata->lock); | 160 | mutex_unlock(&ddata->lock); |
| @@ -231,7 +226,8 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev, | |||
| 231 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 226 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
| 232 | 227 | ||
| 233 | mutex_lock(&ddata->lock); | 228 | mutex_lock(&ddata->lock); |
| 234 | dpi_set_timings(dssdev, timings); | 229 | omapdss_dpi_set_timings(dssdev, timings); |
| 230 | dssdev->panel.timings = *timings; | ||
| 235 | mutex_unlock(&ddata->lock); | 231 | mutex_unlock(&ddata->lock); |
| 236 | } | 232 | } |
| 237 | 233 | ||
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index fa7baa650ae0..b5e6dbc59f0a 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c | |||
| @@ -337,6 +337,9 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) | |||
| 337 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 337 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
| 338 | return 0; | 338 | return 0; |
| 339 | 339 | ||
| 340 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
| 341 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
| 342 | |||
| 340 | r = omapdss_dpi_display_enable(dssdev); | 343 | r = omapdss_dpi_display_enable(dssdev); |
| 341 | if (r) | 344 | if (r) |
| 342 | goto err0; | 345 | goto err0; |
| @@ -480,7 +483,9 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev) | |||
| 480 | static void tpo_td043_set_timings(struct omap_dss_device *dssdev, | 483 | static void tpo_td043_set_timings(struct omap_dss_device *dssdev, |
| 481 | struct omap_video_timings *timings) | 484 | struct omap_video_timings *timings) |
| 482 | { | 485 | { |
| 483 | dpi_set_timings(dssdev, timings); | 486 | omapdss_dpi_set_timings(dssdev, timings); |
| 487 | |||
| 488 | dssdev->panel.timings = *timings; | ||
| 484 | } | 489 | } |
| 485 | 490 | ||
| 486 | static int tpo_td043_check_timings(struct omap_dss_device *dssdev, | 491 | static int tpo_td043_check_timings(struct omap_dss_device *dssdev, |
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index b337a8469fd8..80f5390aa136 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
| @@ -84,7 +84,7 @@ config OMAP2_DSS_SDI | |||
| 84 | 84 | ||
| 85 | config OMAP2_DSS_DSI | 85 | config OMAP2_DSS_DSI |
| 86 | bool "DSI support" | 86 | bool "DSI support" |
| 87 | depends on ARCH_OMAP3 || ARCH_OMAP4 | 87 | depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5 |
| 88 | default n | 88 | default n |
| 89 | help | 89 | help |
| 90 | MIPI DSI (Display Serial Interface) support. | 90 | MIPI DSI (Display Serial Interface) support. |
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index 5c450b0f94d0..4549869bfe1a 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | obj-$(CONFIG_OMAP2_DSS) += omapdss.o | 1 | obj-$(CONFIG_OMAP2_DSS) += omapdss.o |
| 2 | omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ | 2 | omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ |
| 3 | manager.o overlay.o apply.o | 3 | manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o |
| 4 | omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o | 4 | omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o |
| 5 | omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o | 5 | omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o |
| 6 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o | 6 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o |
| 7 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o | 7 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o |
| 8 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | 8 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o |
| 9 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ | 9 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ |
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 0fefc68372b9..19d66f471b4b 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
| @@ -111,9 +111,6 @@ static struct { | |||
| 111 | struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; | 111 | struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; |
| 112 | struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; | 112 | struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; |
| 113 | 113 | ||
| 114 | bool fifo_merge_dirty; | ||
| 115 | bool fifo_merge; | ||
| 116 | |||
| 117 | bool irq_enabled; | 114 | bool irq_enabled; |
| 118 | } dss_data; | 115 | } dss_data; |
| 119 | 116 | ||
| @@ -424,17 +421,25 @@ static void wait_pending_extra_info_updates(void) | |||
| 424 | int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) | 421 | int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) |
| 425 | { | 422 | { |
| 426 | unsigned long timeout = msecs_to_jiffies(500); | 423 | unsigned long timeout = msecs_to_jiffies(500); |
| 427 | struct mgr_priv_data *mp; | 424 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
| 428 | u32 irq; | 425 | u32 irq; |
| 426 | unsigned long flags; | ||
| 429 | int r; | 427 | int r; |
| 430 | int i; | 428 | int i; |
| 431 | struct omap_dss_device *dssdev = mgr->device; | ||
| 432 | 429 | ||
| 433 | if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | 430 | spin_lock_irqsave(&data_lock, flags); |
| 431 | |||
| 432 | if (mgr_manual_update(mgr)) { | ||
| 433 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 434 | return 0; | 434 | return 0; |
| 435 | } | ||
| 435 | 436 | ||
| 436 | if (mgr_manual_update(mgr)) | 437 | if (!mp->enabled) { |
| 438 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 437 | return 0; | 439 | return 0; |
| 440 | } | ||
| 441 | |||
| 442 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 438 | 443 | ||
| 439 | r = dispc_runtime_get(); | 444 | r = dispc_runtime_get(); |
| 440 | if (r) | 445 | if (r) |
| @@ -442,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) | |||
| 442 | 447 | ||
| 443 | irq = dispc_mgr_get_vsync_irq(mgr->id); | 448 | irq = dispc_mgr_get_vsync_irq(mgr->id); |
| 444 | 449 | ||
| 445 | mp = get_mgr_priv(mgr); | ||
| 446 | i = 0; | 450 | i = 0; |
| 447 | while (1) { | 451 | while (1) { |
| 448 | unsigned long flags; | ||
| 449 | bool shadow_dirty, dirty; | 452 | bool shadow_dirty, dirty; |
| 450 | 453 | ||
| 451 | spin_lock_irqsave(&data_lock, flags); | 454 | spin_lock_irqsave(&data_lock, flags); |
| @@ -489,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) | |||
| 489 | { | 492 | { |
| 490 | unsigned long timeout = msecs_to_jiffies(500); | 493 | unsigned long timeout = msecs_to_jiffies(500); |
| 491 | struct ovl_priv_data *op; | 494 | struct ovl_priv_data *op; |
| 492 | struct omap_dss_device *dssdev; | 495 | struct mgr_priv_data *mp; |
| 493 | u32 irq; | 496 | u32 irq; |
| 497 | unsigned long flags; | ||
| 494 | int r; | 498 | int r; |
| 495 | int i; | 499 | int i; |
| 496 | 500 | ||
| 497 | if (!ovl->manager) | 501 | if (!ovl->manager) |
| 498 | return 0; | 502 | return 0; |
| 499 | 503 | ||
| 500 | dssdev = ovl->manager->device; | 504 | mp = get_mgr_priv(ovl->manager); |
| 505 | |||
| 506 | spin_lock_irqsave(&data_lock, flags); | ||
| 501 | 507 | ||
| 502 | if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | 508 | if (ovl_manual_update(ovl)) { |
| 509 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 503 | return 0; | 510 | return 0; |
| 511 | } | ||
| 504 | 512 | ||
| 505 | if (ovl_manual_update(ovl)) | 513 | if (!mp->enabled) { |
| 514 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 506 | return 0; | 515 | return 0; |
| 516 | } | ||
| 517 | |||
| 518 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 507 | 519 | ||
| 508 | r = dispc_runtime_get(); | 520 | r = dispc_runtime_get(); |
| 509 | if (r) | 521 | if (r) |
| @@ -514,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) | |||
| 514 | op = get_ovl_priv(ovl); | 526 | op = get_ovl_priv(ovl); |
| 515 | i = 0; | 527 | i = 0; |
| 516 | while (1) { | 528 | while (1) { |
| 517 | unsigned long flags; | ||
| 518 | bool shadow_dirty, dirty; | 529 | bool shadow_dirty, dirty; |
| 519 | 530 | ||
| 520 | spin_lock_irqsave(&data_lock, flags); | 531 | spin_lock_irqsave(&data_lock, flags); |
| @@ -573,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) | |||
| 573 | 584 | ||
| 574 | replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); | 585 | replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); |
| 575 | 586 | ||
| 576 | r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings); | 587 | r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false); |
| 577 | if (r) { | 588 | if (r) { |
| 578 | /* | 589 | /* |
| 579 | * We can't do much here, as this function can be called from | 590 | * We can't do much here, as this function can be called from |
| @@ -677,40 +688,11 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) | |||
| 677 | mp->shadow_extra_info_dirty = true; | 688 | mp->shadow_extra_info_dirty = true; |
| 678 | } | 689 | } |
| 679 | 690 | ||
| 680 | static void dss_write_regs_common(void) | ||
| 681 | { | ||
| 682 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | ||
| 683 | int i; | ||
| 684 | |||
| 685 | if (!dss_data.fifo_merge_dirty) | ||
| 686 | return; | ||
| 687 | |||
| 688 | for (i = 0; i < num_mgrs; ++i) { | ||
| 689 | struct omap_overlay_manager *mgr; | ||
| 690 | struct mgr_priv_data *mp; | ||
| 691 | |||
| 692 | mgr = omap_dss_get_overlay_manager(i); | ||
| 693 | mp = get_mgr_priv(mgr); | ||
| 694 | |||
| 695 | if (mp->enabled) { | ||
| 696 | if (dss_data.fifo_merge_dirty) { | ||
| 697 | dispc_enable_fifomerge(dss_data.fifo_merge); | ||
| 698 | dss_data.fifo_merge_dirty = false; | ||
| 699 | } | ||
| 700 | |||
| 701 | if (mp->updating) | ||
| 702 | mp->shadow_info_dirty = true; | ||
| 703 | } | ||
| 704 | } | ||
| 705 | } | ||
| 706 | |||
| 707 | static void dss_write_regs(void) | 691 | static void dss_write_regs(void) |
| 708 | { | 692 | { |
| 709 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | 693 | const int num_mgrs = omap_dss_get_num_overlay_managers(); |
| 710 | int i; | 694 | int i; |
| 711 | 695 | ||
| 712 | dss_write_regs_common(); | ||
| 713 | |||
| 714 | for (i = 0; i < num_mgrs; ++i) { | 696 | for (i = 0; i < num_mgrs; ++i) { |
| 715 | struct omap_overlay_manager *mgr; | 697 | struct omap_overlay_manager *mgr; |
| 716 | struct mgr_priv_data *mp; | 698 | struct mgr_priv_data *mp; |
| @@ -799,8 +781,6 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) | |||
| 799 | dss_mgr_write_regs(mgr); | 781 | dss_mgr_write_regs(mgr); |
| 800 | dss_mgr_write_regs_extra(mgr); | 782 | dss_mgr_write_regs_extra(mgr); |
| 801 | 783 | ||
| 802 | dss_write_regs_common(); | ||
| 803 | |||
| 804 | mp->updating = true; | 784 | mp->updating = true; |
| 805 | 785 | ||
| 806 | if (!dss_data.irq_enabled && need_isr()) | 786 | if (!dss_data.irq_enabled && need_isr()) |
| @@ -984,20 +964,11 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, | |||
| 984 | op->extra_info_dirty = true; | 964 | op->extra_info_dirty = true; |
| 985 | } | 965 | } |
| 986 | 966 | ||
| 987 | static void dss_apply_fifo_merge(bool use_fifo_merge) | 967 | static void dss_ovl_setup_fifo(struct omap_overlay *ovl) |
| 988 | { | ||
| 989 | if (dss_data.fifo_merge == use_fifo_merge) | ||
| 990 | return; | ||
| 991 | |||
| 992 | dss_data.fifo_merge = use_fifo_merge; | ||
| 993 | dss_data.fifo_merge_dirty = true; | ||
| 994 | } | ||
| 995 | |||
| 996 | static void dss_ovl_setup_fifo(struct omap_overlay *ovl, | ||
| 997 | bool use_fifo_merge) | ||
| 998 | { | 968 | { |
| 999 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 969 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
| 1000 | u32 fifo_low, fifo_high; | 970 | u32 fifo_low, fifo_high; |
| 971 | bool use_fifo_merge = false; | ||
| 1001 | 972 | ||
| 1002 | if (!op->enabled && !op->enabling) | 973 | if (!op->enabled && !op->enabling) |
| 1003 | return; | 974 | return; |
| @@ -1008,8 +979,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, | |||
| 1008 | dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); | 979 | dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); |
| 1009 | } | 980 | } |
| 1010 | 981 | ||
| 1011 | static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, | 982 | static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) |
| 1012 | bool use_fifo_merge) | ||
| 1013 | { | 983 | { |
| 1014 | struct omap_overlay *ovl; | 984 | struct omap_overlay *ovl; |
| 1015 | struct mgr_priv_data *mp; | 985 | struct mgr_priv_data *mp; |
| @@ -1020,94 +990,19 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, | |||
| 1020 | return; | 990 | return; |
| 1021 | 991 | ||
| 1022 | list_for_each_entry(ovl, &mgr->overlays, list) | 992 | list_for_each_entry(ovl, &mgr->overlays, list) |
| 1023 | dss_ovl_setup_fifo(ovl, use_fifo_merge); | 993 | dss_ovl_setup_fifo(ovl); |
| 1024 | } | ||
| 1025 | |||
| 1026 | static void dss_setup_fifos(bool use_fifo_merge) | ||
| 1027 | { | ||
| 1028 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | ||
| 1029 | struct omap_overlay_manager *mgr; | ||
| 1030 | int i; | ||
| 1031 | |||
| 1032 | for (i = 0; i < num_mgrs; ++i) { | ||
| 1033 | mgr = omap_dss_get_overlay_manager(i); | ||
| 1034 | dss_mgr_setup_fifos(mgr, use_fifo_merge); | ||
| 1035 | } | ||
| 1036 | } | 994 | } |
| 1037 | 995 | ||
| 1038 | static int get_num_used_managers(void) | 996 | static void dss_setup_fifos(void) |
| 1039 | { | 997 | { |
| 1040 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | 998 | const int num_mgrs = omap_dss_get_num_overlay_managers(); |
| 1041 | struct omap_overlay_manager *mgr; | 999 | struct omap_overlay_manager *mgr; |
| 1042 | struct mgr_priv_data *mp; | ||
| 1043 | int i; | 1000 | int i; |
| 1044 | int enabled_mgrs; | ||
| 1045 | |||
| 1046 | enabled_mgrs = 0; | ||
| 1047 | 1001 | ||
| 1048 | for (i = 0; i < num_mgrs; ++i) { | 1002 | for (i = 0; i < num_mgrs; ++i) { |
| 1049 | mgr = omap_dss_get_overlay_manager(i); | 1003 | mgr = omap_dss_get_overlay_manager(i); |
| 1050 | mp = get_mgr_priv(mgr); | 1004 | dss_mgr_setup_fifos(mgr); |
| 1051 | |||
| 1052 | if (!mp->enabled) | ||
| 1053 | continue; | ||
| 1054 | |||
| 1055 | enabled_mgrs++; | ||
| 1056 | } | 1005 | } |
| 1057 | |||
| 1058 | return enabled_mgrs; | ||
| 1059 | } | ||
| 1060 | |||
| 1061 | static int get_num_used_overlays(void) | ||
| 1062 | { | ||
| 1063 | const int num_ovls = omap_dss_get_num_overlays(); | ||
| 1064 | struct omap_overlay *ovl; | ||
| 1065 | struct ovl_priv_data *op; | ||
| 1066 | struct mgr_priv_data *mp; | ||
| 1067 | int i; | ||
| 1068 | int enabled_ovls; | ||
| 1069 | |||
| 1070 | enabled_ovls = 0; | ||
| 1071 | |||
| 1072 | for (i = 0; i < num_ovls; ++i) { | ||
| 1073 | ovl = omap_dss_get_overlay(i); | ||
| 1074 | op = get_ovl_priv(ovl); | ||
| 1075 | |||
| 1076 | if (!op->enabled && !op->enabling) | ||
| 1077 | continue; | ||
| 1078 | |||
| 1079 | mp = get_mgr_priv(ovl->manager); | ||
| 1080 | |||
| 1081 | if (!mp->enabled) | ||
| 1082 | continue; | ||
| 1083 | |||
| 1084 | enabled_ovls++; | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | return enabled_ovls; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | static bool get_use_fifo_merge(void) | ||
| 1091 | { | ||
| 1092 | int enabled_mgrs = get_num_used_managers(); | ||
| 1093 | int enabled_ovls = get_num_used_overlays(); | ||
| 1094 | |||
| 1095 | if (!dss_has_feature(FEAT_FIFO_MERGE)) | ||
| 1096 | return false; | ||
| 1097 | |||
| 1098 | /* | ||
| 1099 | * In theory the only requirement for fifomerge is enabled_ovls <= 1. | ||
| 1100 | * However, if we have two managers enabled and set/unset the fifomerge, | ||
| 1101 | * we need to set the GO bits in particular sequence for the managers, | ||
| 1102 | * and wait in between. | ||
| 1103 | * | ||
| 1104 | * This is rather difficult as new apply calls can happen at any time, | ||
| 1105 | * so we simplify the problem by requiring also that enabled_mgrs <= 1. | ||
| 1106 | * In practice this shouldn't matter, because when only one overlay is | ||
| 1107 | * enabled, most likely only one output is enabled. | ||
| 1108 | */ | ||
| 1109 | |||
| 1110 | return enabled_mgrs <= 1 && enabled_ovls <= 1; | ||
| 1111 | } | 1006 | } |
| 1112 | 1007 | ||
| 1113 | int dss_mgr_enable(struct omap_overlay_manager *mgr) | 1008 | int dss_mgr_enable(struct omap_overlay_manager *mgr) |
| @@ -1115,7 +1010,6 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) | |||
| 1115 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | 1010 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
| 1116 | unsigned long flags; | 1011 | unsigned long flags; |
| 1117 | int r; | 1012 | int r; |
| 1118 | bool fifo_merge; | ||
| 1119 | 1013 | ||
| 1120 | mutex_lock(&apply_lock); | 1014 | mutex_lock(&apply_lock); |
| 1121 | 1015 | ||
| @@ -1133,23 +1027,11 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) | |||
| 1133 | goto err; | 1027 | goto err; |
| 1134 | } | 1028 | } |
| 1135 | 1029 | ||
| 1136 | /* step 1: setup fifos/fifomerge before enabling the manager */ | 1030 | dss_setup_fifos(); |
| 1137 | |||
| 1138 | fifo_merge = get_use_fifo_merge(); | ||
| 1139 | dss_setup_fifos(fifo_merge); | ||
| 1140 | dss_apply_fifo_merge(fifo_merge); | ||
| 1141 | 1031 | ||
| 1142 | dss_write_regs(); | 1032 | dss_write_regs(); |
| 1143 | dss_set_go_bits(); | 1033 | dss_set_go_bits(); |
| 1144 | 1034 | ||
| 1145 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 1146 | |||
| 1147 | /* wait until fifo config is in */ | ||
| 1148 | wait_pending_extra_info_updates(); | ||
| 1149 | |||
| 1150 | /* step 2: enable the manager */ | ||
| 1151 | spin_lock_irqsave(&data_lock, flags); | ||
| 1152 | |||
| 1153 | if (!mgr_manual_update(mgr)) | 1035 | if (!mgr_manual_update(mgr)) |
| 1154 | mp->updating = true; | 1036 | mp->updating = true; |
| 1155 | 1037 | ||
| @@ -1174,7 +1056,6 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) | |||
| 1174 | { | 1056 | { |
| 1175 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | 1057 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
| 1176 | unsigned long flags; | 1058 | unsigned long flags; |
| 1177 | bool fifo_merge; | ||
| 1178 | 1059 | ||
| 1179 | mutex_lock(&apply_lock); | 1060 | mutex_lock(&apply_lock); |
| 1180 | 1061 | ||
| @@ -1189,16 +1070,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) | |||
| 1189 | mp->updating = false; | 1070 | mp->updating = false; |
| 1190 | mp->enabled = false; | 1071 | mp->enabled = false; |
| 1191 | 1072 | ||
| 1192 | fifo_merge = get_use_fifo_merge(); | ||
| 1193 | dss_setup_fifos(fifo_merge); | ||
| 1194 | dss_apply_fifo_merge(fifo_merge); | ||
| 1195 | |||
| 1196 | dss_write_regs(); | ||
| 1197 | dss_set_go_bits(); | ||
| 1198 | |||
| 1199 | spin_unlock_irqrestore(&data_lock, flags); | 1073 | spin_unlock_irqrestore(&data_lock, flags); |
| 1200 | 1074 | ||
| 1201 | wait_pending_extra_info_updates(); | ||
| 1202 | out: | 1075 | out: |
| 1203 | mutex_unlock(&apply_lock); | 1076 | mutex_unlock(&apply_lock); |
| 1204 | } | 1077 | } |
| @@ -1237,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, | |||
| 1237 | spin_unlock_irqrestore(&data_lock, flags); | 1110 | spin_unlock_irqrestore(&data_lock, flags); |
| 1238 | } | 1111 | } |
| 1239 | 1112 | ||
| 1240 | int dss_mgr_set_device(struct omap_overlay_manager *mgr, | 1113 | int dss_mgr_set_output(struct omap_overlay_manager *mgr, |
| 1241 | struct omap_dss_device *dssdev) | 1114 | struct omap_dss_output *output) |
| 1242 | { | 1115 | { |
| 1243 | int r; | 1116 | int r; |
| 1244 | 1117 | ||
| 1245 | mutex_lock(&apply_lock); | 1118 | mutex_lock(&apply_lock); |
| 1246 | 1119 | ||
| 1247 | if (dssdev->manager) { | 1120 | if (mgr->output) { |
| 1248 | DSSERR("display '%s' already has a manager '%s'\n", | 1121 | DSSERR("manager %s is already connected to an output\n", |
| 1249 | dssdev->name, dssdev->manager->name); | 1122 | mgr->name); |
| 1250 | r = -EINVAL; | 1123 | r = -EINVAL; |
| 1251 | goto err; | 1124 | goto err; |
| 1252 | } | 1125 | } |
| 1253 | 1126 | ||
| 1254 | if ((mgr->supported_displays & dssdev->type) == 0) { | 1127 | if ((mgr->supported_outputs & output->id) == 0) { |
| 1255 | DSSERR("display '%s' does not support manager '%s'\n", | 1128 | DSSERR("output does not support manager %s\n", |
| 1256 | dssdev->name, mgr->name); | 1129 | mgr->name); |
| 1257 | r = -EINVAL; | 1130 | r = -EINVAL; |
| 1258 | goto err; | 1131 | goto err; |
| 1259 | } | 1132 | } |
| 1260 | 1133 | ||
| 1261 | dssdev->manager = mgr; | 1134 | output->manager = mgr; |
| 1262 | mgr->device = dssdev; | 1135 | mgr->output = output; |
| 1263 | 1136 | ||
| 1264 | mutex_unlock(&apply_lock); | 1137 | mutex_unlock(&apply_lock); |
| 1265 | 1138 | ||
| @@ -1269,40 +1142,46 @@ err: | |||
| 1269 | return r; | 1142 | return r; |
| 1270 | } | 1143 | } |
| 1271 | 1144 | ||
| 1272 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr) | 1145 | int dss_mgr_unset_output(struct omap_overlay_manager *mgr) |
| 1273 | { | 1146 | { |
| 1274 | int r; | 1147 | int r; |
| 1148 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | ||
| 1149 | unsigned long flags; | ||
| 1275 | 1150 | ||
| 1276 | mutex_lock(&apply_lock); | 1151 | mutex_lock(&apply_lock); |
| 1277 | 1152 | ||
| 1278 | if (!mgr->device) { | 1153 | if (!mgr->output) { |
| 1279 | DSSERR("failed to unset display, display not set.\n"); | 1154 | DSSERR("failed to unset output, output not set\n"); |
| 1280 | r = -EINVAL; | 1155 | r = -EINVAL; |
| 1281 | goto err; | 1156 | goto err; |
| 1282 | } | 1157 | } |
| 1283 | 1158 | ||
| 1284 | /* | 1159 | spin_lock_irqsave(&data_lock, flags); |
| 1285 | * Don't allow currently enabled displays to have the overlay manager | 1160 | |
| 1286 | * pulled out from underneath them | 1161 | if (mp->enabled) { |
| 1287 | */ | 1162 | DSSERR("output can't be unset when manager is enabled\n"); |
| 1288 | if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
| 1289 | r = -EINVAL; | 1163 | r = -EINVAL; |
| 1290 | goto err; | 1164 | goto err1; |
| 1291 | } | 1165 | } |
| 1292 | 1166 | ||
| 1293 | mgr->device->manager = NULL; | 1167 | spin_unlock_irqrestore(&data_lock, flags); |
| 1294 | mgr->device = NULL; | 1168 | |
| 1169 | mgr->output->manager = NULL; | ||
| 1170 | mgr->output = NULL; | ||
| 1295 | 1171 | ||
| 1296 | mutex_unlock(&apply_lock); | 1172 | mutex_unlock(&apply_lock); |
| 1297 | 1173 | ||
| 1298 | return 0; | 1174 | return 0; |
| 1175 | err1: | ||
| 1176 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 1299 | err: | 1177 | err: |
| 1300 | mutex_unlock(&apply_lock); | 1178 | mutex_unlock(&apply_lock); |
| 1179 | |||
| 1301 | return r; | 1180 | return r; |
| 1302 | } | 1181 | } |
| 1303 | 1182 | ||
| 1304 | static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, | 1183 | static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, |
| 1305 | struct omap_video_timings *timings) | 1184 | const struct omap_video_timings *timings) |
| 1306 | { | 1185 | { |
| 1307 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | 1186 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
| 1308 | 1187 | ||
| @@ -1311,24 +1190,22 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, | |||
| 1311 | } | 1190 | } |
| 1312 | 1191 | ||
| 1313 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, | 1192 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, |
| 1314 | struct omap_video_timings *timings) | 1193 | const struct omap_video_timings *timings) |
| 1315 | { | 1194 | { |
| 1316 | unsigned long flags; | 1195 | unsigned long flags; |
| 1317 | 1196 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | |
| 1318 | mutex_lock(&apply_lock); | ||
| 1319 | 1197 | ||
| 1320 | spin_lock_irqsave(&data_lock, flags); | 1198 | spin_lock_irqsave(&data_lock, flags); |
| 1321 | 1199 | ||
| 1322 | dss_apply_mgr_timings(mgr, timings); | 1200 | if (mp->updating) { |
| 1323 | 1201 | DSSERR("cannot set timings for %s: manager needs to be disabled\n", | |
| 1324 | dss_write_regs(); | 1202 | mgr->name); |
| 1325 | dss_set_go_bits(); | 1203 | goto out; |
| 1204 | } | ||
| 1326 | 1205 | ||
| 1206 | dss_apply_mgr_timings(mgr, timings); | ||
| 1207 | out: | ||
| 1327 | spin_unlock_irqrestore(&data_lock, flags); | 1208 | spin_unlock_irqrestore(&data_lock, flags); |
| 1328 | |||
| 1329 | wait_pending_extra_info_updates(); | ||
| 1330 | |||
| 1331 | mutex_unlock(&apply_lock); | ||
| 1332 | } | 1209 | } |
| 1333 | 1210 | ||
| 1334 | static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, | 1211 | static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, |
| @@ -1346,7 +1223,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, | |||
| 1346 | unsigned long flags; | 1223 | unsigned long flags; |
| 1347 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | 1224 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
| 1348 | 1225 | ||
| 1349 | mutex_lock(&apply_lock); | 1226 | spin_lock_irqsave(&data_lock, flags); |
| 1350 | 1227 | ||
| 1351 | if (mp->enabled) { | 1228 | if (mp->enabled) { |
| 1352 | DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n", | 1229 | DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n", |
| @@ -1354,19 +1231,9 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, | |||
| 1354 | goto out; | 1231 | goto out; |
| 1355 | } | 1232 | } |
| 1356 | 1233 | ||
| 1357 | spin_lock_irqsave(&data_lock, flags); | ||
| 1358 | |||
| 1359 | dss_apply_mgr_lcd_config(mgr, config); | 1234 | dss_apply_mgr_lcd_config(mgr, config); |
| 1360 | |||
| 1361 | dss_write_regs(); | ||
| 1362 | dss_set_go_bits(); | ||
| 1363 | |||
| 1364 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 1365 | |||
| 1366 | wait_pending_extra_info_updates(); | ||
| 1367 | |||
| 1368 | out: | 1235 | out: |
| 1369 | mutex_unlock(&apply_lock); | 1236 | spin_unlock_irqrestore(&data_lock, flags); |
| 1370 | } | 1237 | } |
| 1371 | 1238 | ||
| 1372 | int dss_ovl_set_info(struct omap_overlay *ovl, | 1239 | int dss_ovl_set_info(struct omap_overlay *ovl, |
| @@ -1483,6 +1350,13 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) | |||
| 1483 | goto err; | 1350 | goto err; |
| 1484 | } | 1351 | } |
| 1485 | 1352 | ||
| 1353 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 1354 | |||
| 1355 | /* wait for pending extra_info updates to ensure the ovl is disabled */ | ||
| 1356 | wait_pending_extra_info_updates(); | ||
| 1357 | |||
| 1358 | spin_lock_irqsave(&data_lock, flags); | ||
| 1359 | |||
| 1486 | op->channel = -1; | 1360 | op->channel = -1; |
| 1487 | 1361 | ||
| 1488 | ovl->manager = NULL; | 1362 | ovl->manager = NULL; |
| @@ -1517,7 +1391,6 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
| 1517 | { | 1391 | { |
| 1518 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 1392 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
| 1519 | unsigned long flags; | 1393 | unsigned long flags; |
| 1520 | bool fifo_merge; | ||
| 1521 | int r; | 1394 | int r; |
| 1522 | 1395 | ||
| 1523 | mutex_lock(&apply_lock); | 1396 | mutex_lock(&apply_lock); |
| @@ -1527,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
| 1527 | goto err1; | 1400 | goto err1; |
| 1528 | } | 1401 | } |
| 1529 | 1402 | ||
| 1530 | if (ovl->manager == NULL || ovl->manager->device == NULL) { | 1403 | if (ovl->manager == NULL || ovl->manager->output == NULL) { |
| 1531 | r = -EINVAL; | 1404 | r = -EINVAL; |
| 1532 | goto err1; | 1405 | goto err1; |
| 1533 | } | 1406 | } |
| @@ -1543,22 +1416,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
| 1543 | goto err2; | 1416 | goto err2; |
| 1544 | } | 1417 | } |
| 1545 | 1418 | ||
| 1546 | /* step 1: configure fifos/fifomerge for currently enabled ovls */ | 1419 | dss_setup_fifos(); |
| 1547 | |||
| 1548 | fifo_merge = get_use_fifo_merge(); | ||
| 1549 | dss_setup_fifos(fifo_merge); | ||
| 1550 | dss_apply_fifo_merge(fifo_merge); | ||
| 1551 | |||
| 1552 | dss_write_regs(); | ||
| 1553 | dss_set_go_bits(); | ||
| 1554 | |||
| 1555 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 1556 | |||
| 1557 | /* wait for fifo configs to go in */ | ||
| 1558 | wait_pending_extra_info_updates(); | ||
| 1559 | |||
| 1560 | /* step 2: enable the overlay */ | ||
| 1561 | spin_lock_irqsave(&data_lock, flags); | ||
| 1562 | 1420 | ||
| 1563 | op->enabling = false; | 1421 | op->enabling = false; |
| 1564 | dss_apply_ovl_enable(ovl, true); | 1422 | dss_apply_ovl_enable(ovl, true); |
| @@ -1568,9 +1426,6 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
| 1568 | 1426 | ||
| 1569 | spin_unlock_irqrestore(&data_lock, flags); | 1427 | spin_unlock_irqrestore(&data_lock, flags); |
| 1570 | 1428 | ||
| 1571 | /* wait for overlay to be enabled */ | ||
| 1572 | wait_pending_extra_info_updates(); | ||
| 1573 | |||
| 1574 | mutex_unlock(&apply_lock); | 1429 | mutex_unlock(&apply_lock); |
| 1575 | 1430 | ||
| 1576 | return 0; | 1431 | return 0; |
| @@ -1586,7 +1441,6 @@ int dss_ovl_disable(struct omap_overlay *ovl) | |||
| 1586 | { | 1441 | { |
| 1587 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 1442 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
| 1588 | unsigned long flags; | 1443 | unsigned long flags; |
| 1589 | bool fifo_merge; | ||
| 1590 | int r; | 1444 | int r; |
| 1591 | 1445 | ||
| 1592 | mutex_lock(&apply_lock); | 1446 | mutex_lock(&apply_lock); |
| @@ -1596,39 +1450,19 @@ int dss_ovl_disable(struct omap_overlay *ovl) | |||
| 1596 | goto err; | 1450 | goto err; |
| 1597 | } | 1451 | } |
| 1598 | 1452 | ||
| 1599 | if (ovl->manager == NULL || ovl->manager->device == NULL) { | 1453 | if (ovl->manager == NULL || ovl->manager->output == NULL) { |
| 1600 | r = -EINVAL; | 1454 | r = -EINVAL; |
| 1601 | goto err; | 1455 | goto err; |
| 1602 | } | 1456 | } |
| 1603 | 1457 | ||
| 1604 | /* step 1: disable the overlay */ | ||
| 1605 | spin_lock_irqsave(&data_lock, flags); | 1458 | spin_lock_irqsave(&data_lock, flags); |
| 1606 | 1459 | ||
| 1607 | dss_apply_ovl_enable(ovl, false); | 1460 | dss_apply_ovl_enable(ovl, false); |
| 1608 | |||
| 1609 | dss_write_regs(); | 1461 | dss_write_regs(); |
| 1610 | dss_set_go_bits(); | 1462 | dss_set_go_bits(); |
| 1611 | 1463 | ||
| 1612 | spin_unlock_irqrestore(&data_lock, flags); | 1464 | spin_unlock_irqrestore(&data_lock, flags); |
| 1613 | 1465 | ||
| 1614 | /* wait for the overlay to be disabled */ | ||
| 1615 | wait_pending_extra_info_updates(); | ||
| 1616 | |||
| 1617 | /* step 2: configure fifos/fifomerge */ | ||
| 1618 | spin_lock_irqsave(&data_lock, flags); | ||
| 1619 | |||
| 1620 | fifo_merge = get_use_fifo_merge(); | ||
| 1621 | dss_setup_fifos(fifo_merge); | ||
| 1622 | dss_apply_fifo_merge(fifo_merge); | ||
| 1623 | |||
| 1624 | dss_write_regs(); | ||
| 1625 | dss_set_go_bits(); | ||
| 1626 | |||
| 1627 | spin_unlock_irqrestore(&data_lock, flags); | ||
| 1628 | |||
| 1629 | /* wait for fifo config to go in */ | ||
| 1630 | wait_pending_extra_info_updates(); | ||
| 1631 | |||
| 1632 | mutex_unlock(&apply_lock); | 1466 | mutex_unlock(&apply_lock); |
| 1633 | 1467 | ||
| 1634 | return 0; | 1468 | return 0; |
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 58bd9c27369d..b2af72dc20bd 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/device.h> | 33 | #include <linux/device.h> |
| 34 | #include <linux/regulator/consumer.h> | 34 | #include <linux/regulator/consumer.h> |
| 35 | #include <linux/suspend.h> | 35 | #include <linux/suspend.h> |
| 36 | #include <linux/slab.h> | ||
| 36 | 37 | ||
| 37 | #include <video/omapdss.h> | 38 | #include <video/omapdss.h> |
| 38 | 39 | ||
| @@ -57,6 +58,11 @@ bool dss_debug; | |||
| 57 | module_param_named(debug, dss_debug, bool, 0644); | 58 | module_param_named(debug, dss_debug, bool, 0644); |
| 58 | #endif | 59 | #endif |
| 59 | 60 | ||
| 61 | const char *dss_get_default_display_name(void) | ||
| 62 | { | ||
| 63 | return core.default_display_name; | ||
| 64 | } | ||
| 65 | |||
| 60 | /* REGULATORS */ | 66 | /* REGULATORS */ |
| 61 | 67 | ||
| 62 | struct regulator *dss_get_vdds_dsi(void) | 68 | struct regulator *dss_get_vdds_dsi(void) |
| @@ -347,17 +353,14 @@ static int dss_driver_probe(struct device *dev) | |||
| 347 | int r; | 353 | int r; |
| 348 | struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); | 354 | struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); |
| 349 | struct omap_dss_device *dssdev = to_dss_device(dev); | 355 | struct omap_dss_device *dssdev = to_dss_device(dev); |
| 350 | bool force; | ||
| 351 | 356 | ||
| 352 | DSSDBG("driver_probe: dev %s/%s, drv %s\n", | 357 | DSSDBG("driver_probe: dev %s/%s, drv %s\n", |
| 353 | dev_name(dev), dssdev->driver_name, | 358 | dev_name(dev), dssdev->driver_name, |
| 354 | dssdrv->driver.name); | 359 | dssdrv->driver.name); |
| 355 | 360 | ||
| 356 | dss_init_device(core.pdev, dssdev); | 361 | r = dss_init_device(core.pdev, dssdev); |
| 357 | 362 | if (r) | |
| 358 | force = core.default_display_name && | 363 | return r; |
| 359 | strcmp(core.default_display_name, dssdev->name) == 0; | ||
| 360 | dss_recheck_connections(dssdev, force); | ||
| 361 | 364 | ||
| 362 | r = dssdrv->probe(dssdev); | 365 | r = dssdrv->probe(dssdev); |
| 363 | 366 | ||
| @@ -416,54 +419,44 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver) | |||
| 416 | EXPORT_SYMBOL(omap_dss_unregister_driver); | 419 | EXPORT_SYMBOL(omap_dss_unregister_driver); |
| 417 | 420 | ||
| 418 | /* DEVICE */ | 421 | /* DEVICE */ |
| 419 | static void reset_device(struct device *dev, int check) | ||
| 420 | { | ||
| 421 | u8 *dev_p = (u8 *)dev; | ||
| 422 | u8 *dev_end = dev_p + sizeof(*dev); | ||
| 423 | void *saved_pdata; | ||
| 424 | |||
| 425 | saved_pdata = dev->platform_data; | ||
| 426 | if (check) { | ||
| 427 | /* | ||
| 428 | * Check if there is any other setting than platform_data | ||
| 429 | * in struct device; warn that these will be reset by our | ||
| 430 | * init. | ||
| 431 | */ | ||
| 432 | dev->platform_data = NULL; | ||
| 433 | while (dev_p < dev_end) { | ||
| 434 | if (*dev_p) { | ||
| 435 | WARN("%s: struct device fields will be " | ||
| 436 | "discarded\n", | ||
| 437 | __func__); | ||
| 438 | break; | ||
| 439 | } | ||
| 440 | dev_p++; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | memset(dev, 0, sizeof(*dev)); | ||
| 444 | dev->platform_data = saved_pdata; | ||
| 445 | } | ||
| 446 | |||
| 447 | 422 | ||
| 448 | static void omap_dss_dev_release(struct device *dev) | 423 | static void omap_dss_dev_release(struct device *dev) |
| 449 | { | 424 | { |
| 450 | reset_device(dev, 0); | 425 | struct omap_dss_device *dssdev = to_dss_device(dev); |
| 426 | kfree(dssdev); | ||
| 451 | } | 427 | } |
| 452 | 428 | ||
| 453 | int omap_dss_register_device(struct omap_dss_device *dssdev, | 429 | static int disp_num_counter; |
| 454 | struct device *parent, int disp_num) | 430 | |
| 431 | struct omap_dss_device *dss_alloc_and_init_device(struct device *parent) | ||
| 455 | { | 432 | { |
| 456 | WARN_ON(!dssdev->driver_name); | 433 | struct omap_dss_device *dssdev; |
| 434 | |||
| 435 | dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL); | ||
| 436 | if (!dssdev) | ||
| 437 | return NULL; | ||
| 457 | 438 | ||
| 458 | reset_device(&dssdev->dev, 1); | ||
| 459 | dssdev->dev.bus = &dss_bus_type; | 439 | dssdev->dev.bus = &dss_bus_type; |
| 460 | dssdev->dev.parent = parent; | 440 | dssdev->dev.parent = parent; |
| 461 | dssdev->dev.release = omap_dss_dev_release; | 441 | dssdev->dev.release = omap_dss_dev_release; |
| 462 | dev_set_name(&dssdev->dev, "display%d", disp_num); | 442 | dev_set_name(&dssdev->dev, "display%d", disp_num_counter++); |
| 463 | return device_register(&dssdev->dev); | 443 | |
| 444 | device_initialize(&dssdev->dev); | ||
| 445 | |||
| 446 | return dssdev; | ||
| 447 | } | ||
| 448 | |||
| 449 | int dss_add_device(struct omap_dss_device *dssdev) | ||
| 450 | { | ||
| 451 | return device_add(&dssdev->dev); | ||
| 452 | } | ||
| 453 | |||
| 454 | void dss_put_device(struct omap_dss_device *dssdev) | ||
| 455 | { | ||
| 456 | put_device(&dssdev->dev); | ||
| 464 | } | 457 | } |
| 465 | 458 | ||
| 466 | void omap_dss_unregister_device(struct omap_dss_device *dssdev) | 459 | void dss_unregister_device(struct omap_dss_device *dssdev) |
| 467 | { | 460 | { |
| 468 | device_unregister(&dssdev->dev); | 461 | device_unregister(&dssdev->dev); |
| 469 | } | 462 | } |
| @@ -471,15 +464,25 @@ void omap_dss_unregister_device(struct omap_dss_device *dssdev) | |||
| 471 | static int dss_unregister_dss_dev(struct device *dev, void *data) | 464 | static int dss_unregister_dss_dev(struct device *dev, void *data) |
| 472 | { | 465 | { |
| 473 | struct omap_dss_device *dssdev = to_dss_device(dev); | 466 | struct omap_dss_device *dssdev = to_dss_device(dev); |
| 474 | omap_dss_unregister_device(dssdev); | 467 | dss_unregister_device(dssdev); |
| 475 | return 0; | 468 | return 0; |
| 476 | } | 469 | } |
| 477 | 470 | ||
| 478 | void omap_dss_unregister_child_devices(struct device *parent) | 471 | void dss_unregister_child_devices(struct device *parent) |
| 479 | { | 472 | { |
| 480 | device_for_each_child(parent, NULL, dss_unregister_dss_dev); | 473 | device_for_each_child(parent, NULL, dss_unregister_dss_dev); |
| 481 | } | 474 | } |
| 482 | 475 | ||
| 476 | void dss_copy_device_pdata(struct omap_dss_device *dst, | ||
| 477 | const struct omap_dss_device *src) | ||
| 478 | { | ||
| 479 | u8 *d = (u8 *)dst; | ||
| 480 | u8 *s = (u8 *)src; | ||
| 481 | size_t dsize = sizeof(struct device); | ||
| 482 | |||
| 483 | memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize); | ||
| 484 | } | ||
| 485 | |||
| 483 | /* BUS */ | 486 | /* BUS */ |
| 484 | static int __init omap_dss_bus_register(void) | 487 | static int __init omap_dss_bus_register(void) |
| 485 | { | 488 | { |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5b289c5f695b..a173a9481a23 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
| @@ -37,8 +37,6 @@ | |||
| 37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
| 38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
| 39 | 39 | ||
| 40 | #include <plat/clock.h> | ||
| 41 | |||
| 42 | #include <video/omapdss.h> | 40 | #include <video/omapdss.h> |
| 43 | 41 | ||
| 44 | #include "dss.h" | 42 | #include "dss.h" |
| @@ -81,6 +79,30 @@ struct dispc_irq_stats { | |||
| 81 | unsigned irqs[32]; | 79 | unsigned irqs[32]; |
| 82 | }; | 80 | }; |
| 83 | 81 | ||
| 82 | struct dispc_features { | ||
| 83 | u8 sw_start; | ||
| 84 | u8 fp_start; | ||
| 85 | u8 bp_start; | ||
| 86 | u16 sw_max; | ||
| 87 | u16 vp_max; | ||
| 88 | u16 hp_max; | ||
| 89 | int (*calc_scaling) (enum omap_plane plane, | ||
| 90 | const struct omap_video_timings *mgr_timings, | ||
| 91 | u16 width, u16 height, u16 out_width, u16 out_height, | ||
| 92 | enum omap_color_mode color_mode, bool *five_taps, | ||
| 93 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | ||
| 94 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem); | ||
| 95 | unsigned long (*calc_core_clk) (enum omap_plane plane, | ||
| 96 | u16 width, u16 height, u16 out_width, u16 out_height, | ||
| 97 | bool mem_to_mem); | ||
| 98 | u8 num_fifos; | ||
| 99 | |||
| 100 | /* swap GFX & WB fifos */ | ||
| 101 | bool gfx_fifo_workaround:1; | ||
| 102 | }; | ||
| 103 | |||
| 104 | #define DISPC_MAX_NR_FIFOS 5 | ||
| 105 | |||
| 84 | static struct { | 106 | static struct { |
| 85 | struct platform_device *pdev; | 107 | struct platform_device *pdev; |
| 86 | void __iomem *base; | 108 | void __iomem *base; |
| @@ -90,7 +112,9 @@ static struct { | |||
| 90 | int irq; | 112 | int irq; |
| 91 | struct clk *dss_clk; | 113 | struct clk *dss_clk; |
| 92 | 114 | ||
| 93 | u32 fifo_size[MAX_DSS_OVERLAYS]; | 115 | u32 fifo_size[DISPC_MAX_NR_FIFOS]; |
| 116 | /* maps which plane is using a fifo. fifo-id -> plane-id */ | ||
| 117 | int fifo_assignment[DISPC_MAX_NR_FIFOS]; | ||
| 94 | 118 | ||
| 95 | spinlock_t irq_lock; | 119 | spinlock_t irq_lock; |
| 96 | u32 irq_error_mask; | 120 | u32 irq_error_mask; |
| @@ -101,6 +125,8 @@ static struct { | |||
| 101 | bool ctx_valid; | 125 | bool ctx_valid; |
| 102 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; | 126 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; |
| 103 | 127 | ||
| 128 | const struct dispc_features *feat; | ||
| 129 | |||
| 104 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 130 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
| 105 | spinlock_t irq_stats_lock; | 131 | spinlock_t irq_stats_lock; |
| 106 | struct dispc_irq_stats irq_stats; | 132 | struct dispc_irq_stats irq_stats; |
| @@ -210,7 +236,14 @@ static const struct { | |||
| 210 | }, | 236 | }, |
| 211 | }; | 237 | }; |
| 212 | 238 | ||
| 239 | struct color_conv_coef { | ||
| 240 | int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; | ||
| 241 | int full_range; | ||
| 242 | }; | ||
| 243 | |||
| 213 | static void _omap_dispc_set_irqs(void); | 244 | static void _omap_dispc_set_irqs(void); |
| 245 | static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); | ||
| 246 | static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); | ||
| 214 | 247 | ||
| 215 | static inline void dispc_write_reg(const u16 idx, u32 val) | 248 | static inline void dispc_write_reg(const u16 idx, u32 val) |
| 216 | { | 249 | { |
| @@ -508,6 +541,11 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) | |||
| 508 | return mgr_desc[channel].framedone_irq; | 541 | return mgr_desc[channel].framedone_irq; |
| 509 | } | 542 | } |
| 510 | 543 | ||
| 544 | u32 dispc_wb_get_framedone_irq(void) | ||
| 545 | { | ||
| 546 | return DISPC_IRQ_FRAMEDONEWB; | ||
| 547 | } | ||
| 548 | |||
| 511 | bool dispc_mgr_go_busy(enum omap_channel channel) | 549 | bool dispc_mgr_go_busy(enum omap_channel channel) |
| 512 | { | 550 | { |
| 513 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; | 551 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; |
| @@ -535,6 +573,30 @@ void dispc_mgr_go(enum omap_channel channel) | |||
| 535 | mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); | 573 | mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); |
| 536 | } | 574 | } |
| 537 | 575 | ||
| 576 | bool dispc_wb_go_busy(void) | ||
| 577 | { | ||
| 578 | return REG_GET(DISPC_CONTROL2, 6, 6) == 1; | ||
| 579 | } | ||
| 580 | |||
| 581 | void dispc_wb_go(void) | ||
| 582 | { | ||
| 583 | enum omap_plane plane = OMAP_DSS_WB; | ||
| 584 | bool enable, go; | ||
| 585 | |||
| 586 | enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1; | ||
| 587 | |||
| 588 | if (!enable) | ||
| 589 | return; | ||
| 590 | |||
| 591 | go = REG_GET(DISPC_CONTROL2, 6, 6) == 1; | ||
| 592 | if (go) { | ||
| 593 | DSSERR("GO bit not down for WB\n"); | ||
| 594 | return; | ||
| 595 | } | ||
| 596 | |||
| 597 | REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6); | ||
| 598 | } | ||
| 599 | |||
| 538 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) | 600 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) |
| 539 | { | 601 | { |
| 540 | dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); | 602 | dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); |
| @@ -617,41 +679,41 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc, | |||
| 617 | } | 679 | } |
| 618 | } | 680 | } |
| 619 | 681 | ||
| 620 | static void _dispc_setup_color_conv_coef(void) | ||
| 621 | { | ||
| 622 | int i; | ||
| 623 | const struct color_conv_coef { | ||
| 624 | int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; | ||
| 625 | int full_range; | ||
| 626 | } ctbl_bt601_5 = { | ||
| 627 | 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, | ||
| 628 | }; | ||
| 629 | |||
| 630 | const struct color_conv_coef *ct; | ||
| 631 | 682 | ||
| 683 | static void dispc_ovl_write_color_conv_coef(enum omap_plane plane, | ||
| 684 | const struct color_conv_coef *ct) | ||
| 685 | { | ||
| 632 | #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) | 686 | #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) |
| 633 | 687 | ||
| 634 | ct = &ctbl_bt601_5; | 688 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 0), CVAL(ct->rcr, ct->ry)); |
| 689 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 1), CVAL(ct->gy, ct->rcb)); | ||
| 690 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 2), CVAL(ct->gcb, ct->gcr)); | ||
| 691 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 3), CVAL(ct->bcr, ct->by)); | ||
| 692 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 4), CVAL(0, ct->bcb)); | ||
| 635 | 693 | ||
| 636 | for (i = 1; i < dss_feat_get_num_ovls(); i++) { | 694 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ct->full_range, 11, 11); |
| 637 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0), | ||
| 638 | CVAL(ct->rcr, ct->ry)); | ||
| 639 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1), | ||
| 640 | CVAL(ct->gy, ct->rcb)); | ||
| 641 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2), | ||
| 642 | CVAL(ct->gcb, ct->gcr)); | ||
| 643 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3), | ||
| 644 | CVAL(ct->bcr, ct->by)); | ||
| 645 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4), | ||
| 646 | CVAL(0, ct->bcb)); | ||
| 647 | |||
| 648 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range, | ||
| 649 | 11, 11); | ||
| 650 | } | ||
| 651 | 695 | ||
| 652 | #undef CVAL | 696 | #undef CVAL |
| 653 | } | 697 | } |
| 654 | 698 | ||
| 699 | static void dispc_setup_color_conv_coef(void) | ||
| 700 | { | ||
| 701 | int i; | ||
| 702 | int num_ovl = dss_feat_get_num_ovls(); | ||
| 703 | int num_wb = dss_feat_get_num_wbs(); | ||
| 704 | const struct color_conv_coef ctbl_bt601_5_ovl = { | ||
| 705 | 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, | ||
| 706 | }; | ||
| 707 | const struct color_conv_coef ctbl_bt601_5_wb = { | ||
| 708 | 66, 112, -38, 129, -94, -74, 25, -18, 112, 0, | ||
| 709 | }; | ||
| 710 | |||
| 711 | for (i = 1; i < num_ovl; i++) | ||
| 712 | dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_ovl); | ||
| 713 | |||
| 714 | for (; i < num_wb; i++) | ||
| 715 | dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_wb); | ||
| 716 | } | ||
| 655 | 717 | ||
| 656 | static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) | 718 | static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) |
| 657 | { | 719 | { |
| @@ -673,24 +735,32 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr) | |||
| 673 | dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); | 735 | dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); |
| 674 | } | 736 | } |
| 675 | 737 | ||
| 676 | static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y) | 738 | static void dispc_ovl_set_pos(enum omap_plane plane, |
| 739 | enum omap_overlay_caps caps, int x, int y) | ||
| 677 | { | 740 | { |
| 678 | u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); | 741 | u32 val; |
| 742 | |||
| 743 | if ((caps & OMAP_DSS_OVL_CAP_POS) == 0) | ||
| 744 | return; | ||
| 745 | |||
| 746 | val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); | ||
| 679 | 747 | ||
| 680 | dispc_write_reg(DISPC_OVL_POSITION(plane), val); | 748 | dispc_write_reg(DISPC_OVL_POSITION(plane), val); |
| 681 | } | 749 | } |
| 682 | 750 | ||
| 683 | static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height) | 751 | static void dispc_ovl_set_input_size(enum omap_plane plane, int width, |
| 752 | int height) | ||
| 684 | { | 753 | { |
| 685 | u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); | 754 | u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); |
| 686 | 755 | ||
| 687 | if (plane == OMAP_DSS_GFX) | 756 | if (plane == OMAP_DSS_GFX || plane == OMAP_DSS_WB) |
| 688 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); | 757 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); |
| 689 | else | 758 | else |
| 690 | dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); | 759 | dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); |
| 691 | } | 760 | } |
| 692 | 761 | ||
| 693 | static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) | 762 | static void dispc_ovl_set_output_size(enum omap_plane plane, int width, |
| 763 | int height) | ||
| 694 | { | 764 | { |
| 695 | u32 val; | 765 | u32 val; |
| 696 | 766 | ||
| @@ -698,14 +768,16 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) | |||
| 698 | 768 | ||
| 699 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); | 769 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); |
| 700 | 770 | ||
| 701 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); | 771 | if (plane == OMAP_DSS_WB) |
| 772 | dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); | ||
| 773 | else | ||
| 774 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); | ||
| 702 | } | 775 | } |
| 703 | 776 | ||
| 704 | static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder) | 777 | static void dispc_ovl_set_zorder(enum omap_plane plane, |
| 778 | enum omap_overlay_caps caps, u8 zorder) | ||
| 705 | { | 779 | { |
| 706 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 780 | if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) |
| 707 | |||
| 708 | if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) | ||
| 709 | return; | 781 | return; |
| 710 | 782 | ||
| 711 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); | 783 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); |
| @@ -722,23 +794,22 @@ static void dispc_ovl_enable_zorder_planes(void) | |||
| 722 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); | 794 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); |
| 723 | } | 795 | } |
| 724 | 796 | ||
| 725 | static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) | 797 | static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, |
| 798 | enum omap_overlay_caps caps, bool enable) | ||
| 726 | { | 799 | { |
| 727 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 800 | if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) |
| 728 | |||
| 729 | if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) | ||
| 730 | return; | 801 | return; |
| 731 | 802 | ||
| 732 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); | 803 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); |
| 733 | } | 804 | } |
| 734 | 805 | ||
| 735 | static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha) | 806 | static void dispc_ovl_setup_global_alpha(enum omap_plane plane, |
| 807 | enum omap_overlay_caps caps, u8 global_alpha) | ||
| 736 | { | 808 | { |
| 737 | static const unsigned shifts[] = { 0, 8, 16, 24, }; | 809 | static const unsigned shifts[] = { 0, 8, 16, 24, }; |
| 738 | int shift; | 810 | int shift; |
| 739 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
| 740 | 811 | ||
| 741 | if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) | 812 | if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) |
| 742 | return; | 813 | return; |
| 743 | 814 | ||
| 744 | shift = shifts[plane]; | 815 | shift = shifts[plane]; |
| @@ -946,10 +1017,17 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) | |||
| 946 | return channel; | 1017 | return channel; |
| 947 | } | 1018 | } |
| 948 | 1019 | ||
| 1020 | void dispc_wb_set_channel_in(enum dss_writeback_channel channel) | ||
| 1021 | { | ||
| 1022 | enum omap_plane plane = OMAP_DSS_WB; | ||
| 1023 | |||
| 1024 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16); | ||
| 1025 | } | ||
| 1026 | |||
| 949 | static void dispc_ovl_set_burst_size(enum omap_plane plane, | 1027 | static void dispc_ovl_set_burst_size(enum omap_plane plane, |
| 950 | enum omap_burst_size burst_size) | 1028 | enum omap_burst_size burst_size) |
| 951 | { | 1029 | { |
| 952 | static const unsigned shifts[] = { 6, 14, 14, 14, }; | 1030 | static const unsigned shifts[] = { 6, 14, 14, 14, 14, }; |
| 953 | int shift; | 1031 | int shift; |
| 954 | 1032 | ||
| 955 | shift = shifts[plane]; | 1033 | shift = shifts[plane]; |
| @@ -1026,11 +1104,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) | |||
| 1026 | dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); | 1104 | dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); |
| 1027 | } | 1105 | } |
| 1028 | 1106 | ||
| 1029 | static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable) | 1107 | static void dispc_ovl_enable_replication(enum omap_plane plane, |
| 1108 | enum omap_overlay_caps caps, bool enable) | ||
| 1030 | { | 1109 | { |
| 1031 | static const unsigned shifts[] = { 5, 10, 10, 10 }; | 1110 | static const unsigned shifts[] = { 5, 10, 10, 10 }; |
| 1032 | int shift; | 1111 | int shift; |
| 1033 | 1112 | ||
| 1113 | if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) == 0) | ||
| 1114 | return; | ||
| 1115 | |||
| 1034 | shift = shifts[plane]; | 1116 | shift = shifts[plane]; |
| 1035 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); | 1117 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); |
| 1036 | } | 1118 | } |
| @@ -1044,10 +1126,10 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width, | |||
| 1044 | dispc_write_reg(DISPC_SIZE_MGR(channel), val); | 1126 | dispc_write_reg(DISPC_SIZE_MGR(channel), val); |
| 1045 | } | 1127 | } |
| 1046 | 1128 | ||
| 1047 | static void dispc_read_plane_fifo_sizes(void) | 1129 | static void dispc_init_fifos(void) |
| 1048 | { | 1130 | { |
| 1049 | u32 size; | 1131 | u32 size; |
| 1050 | int plane; | 1132 | int fifo; |
| 1051 | u8 start, end; | 1133 | u8 start, end; |
| 1052 | u32 unit; | 1134 | u32 unit; |
| 1053 | 1135 | ||
| @@ -1055,16 +1137,53 @@ static void dispc_read_plane_fifo_sizes(void) | |||
| 1055 | 1137 | ||
| 1056 | dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); | 1138 | dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); |
| 1057 | 1139 | ||
| 1058 | for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) { | 1140 | for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) { |
| 1059 | size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end); | 1141 | size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end); |
| 1060 | size *= unit; | 1142 | size *= unit; |
| 1061 | dispc.fifo_size[plane] = size; | 1143 | dispc.fifo_size[fifo] = size; |
| 1144 | |||
| 1145 | /* | ||
| 1146 | * By default fifos are mapped directly to overlays, fifo 0 to | ||
| 1147 | * ovl 0, fifo 1 to ovl 1, etc. | ||
| 1148 | */ | ||
| 1149 | dispc.fifo_assignment[fifo] = fifo; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* | ||
| 1153 | * The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo | ||
| 1154 | * causes problems with certain use cases, like using the tiler in 2D | ||
| 1155 | * mode. The below hack swaps the fifos of GFX and WB planes, thus | ||
| 1156 | * giving GFX plane a larger fifo. WB but should work fine with a | ||
| 1157 | * smaller fifo. | ||
| 1158 | */ | ||
| 1159 | if (dispc.feat->gfx_fifo_workaround) { | ||
| 1160 | u32 v; | ||
| 1161 | |||
| 1162 | v = dispc_read_reg(DISPC_GLOBAL_BUFFER); | ||
| 1163 | |||
| 1164 | v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */ | ||
| 1165 | v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */ | ||
| 1166 | v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */ | ||
| 1167 | v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */ | ||
| 1168 | |||
| 1169 | dispc_write_reg(DISPC_GLOBAL_BUFFER, v); | ||
| 1170 | |||
| 1171 | dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB; | ||
| 1172 | dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX; | ||
| 1062 | } | 1173 | } |
| 1063 | } | 1174 | } |
| 1064 | 1175 | ||
| 1065 | static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) | 1176 | static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) |
| 1066 | { | 1177 | { |
| 1067 | return dispc.fifo_size[plane]; | 1178 | int fifo; |
| 1179 | u32 size = 0; | ||
| 1180 | |||
| 1181 | for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) { | ||
| 1182 | if (dispc.fifo_assignment[fifo] == plane) | ||
| 1183 | size += dispc.fifo_size[fifo]; | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | return size; | ||
| 1068 | } | 1187 | } |
| 1069 | 1188 | ||
| 1070 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) | 1189 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) |
| @@ -1140,6 +1259,14 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | |||
| 1140 | if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { | 1259 | if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { |
| 1141 | *fifo_low = ovl_fifo_size - burst_size * 2; | 1260 | *fifo_low = ovl_fifo_size - burst_size * 2; |
| 1142 | *fifo_high = total_fifo_size - burst_size; | 1261 | *fifo_high = total_fifo_size - burst_size; |
| 1262 | } else if (plane == OMAP_DSS_WB) { | ||
| 1263 | /* | ||
| 1264 | * Most optimal configuration for writeback is to push out data | ||
| 1265 | * to the interconnect the moment writeback pushes enough pixels | ||
| 1266 | * in the FIFO to form a burst | ||
| 1267 | */ | ||
| 1268 | *fifo_low = 0; | ||
| 1269 | *fifo_high = burst_size; | ||
| 1143 | } else { | 1270 | } else { |
| 1144 | *fifo_low = ovl_fifo_size - burst_size; | 1271 | *fifo_low = ovl_fifo_size - burst_size; |
| 1145 | *fifo_high = total_fifo_size - buf_unit; | 1272 | *fifo_high = total_fifo_size - buf_unit; |
| @@ -1382,6 +1509,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
| 1382 | { | 1509 | { |
| 1383 | int scale_x = out_width != orig_width; | 1510 | int scale_x = out_width != orig_width; |
| 1384 | int scale_y = out_height != orig_height; | 1511 | int scale_y = out_height != orig_height; |
| 1512 | bool chroma_upscale = plane != OMAP_DSS_WB ? true : false; | ||
| 1385 | 1513 | ||
| 1386 | if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) | 1514 | if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) |
| 1387 | return; | 1515 | return; |
| @@ -1389,7 +1517,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
| 1389 | color_mode != OMAP_DSS_COLOR_UYVY && | 1517 | color_mode != OMAP_DSS_COLOR_UYVY && |
| 1390 | color_mode != OMAP_DSS_COLOR_NV12)) { | 1518 | color_mode != OMAP_DSS_COLOR_NV12)) { |
| 1391 | /* reset chroma resampling for RGB formats */ | 1519 | /* reset chroma resampling for RGB formats */ |
| 1392 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); | 1520 | if (plane != OMAP_DSS_WB) |
| 1521 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); | ||
| 1393 | return; | 1522 | return; |
| 1394 | } | 1523 | } |
| 1395 | 1524 | ||
| @@ -1398,23 +1527,34 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
| 1398 | 1527 | ||
| 1399 | switch (color_mode) { | 1528 | switch (color_mode) { |
| 1400 | case OMAP_DSS_COLOR_NV12: | 1529 | case OMAP_DSS_COLOR_NV12: |
| 1401 | /* UV is subsampled by 2 vertically*/ | 1530 | if (chroma_upscale) { |
| 1402 | orig_height >>= 1; | 1531 | /* UV is subsampled by 2 horizontally and vertically */ |
| 1403 | /* UV is subsampled by 2 horz.*/ | 1532 | orig_height >>= 1; |
| 1404 | orig_width >>= 1; | 1533 | orig_width >>= 1; |
| 1534 | } else { | ||
| 1535 | /* UV is downsampled by 2 horizontally and vertically */ | ||
| 1536 | orig_height <<= 1; | ||
| 1537 | orig_width <<= 1; | ||
| 1538 | } | ||
| 1539 | |||
| 1405 | break; | 1540 | break; |
| 1406 | case OMAP_DSS_COLOR_YUV2: | 1541 | case OMAP_DSS_COLOR_YUV2: |
| 1407 | case OMAP_DSS_COLOR_UYVY: | 1542 | case OMAP_DSS_COLOR_UYVY: |
| 1408 | /*For YUV422 with 90/270 rotation, | 1543 | /* For YUV422 with 90/270 rotation, we don't upsample chroma */ |
| 1409 | *we don't upsample chroma | ||
| 1410 | */ | ||
| 1411 | if (rotation == OMAP_DSS_ROT_0 || | 1544 | if (rotation == OMAP_DSS_ROT_0 || |
| 1412 | rotation == OMAP_DSS_ROT_180) | 1545 | rotation == OMAP_DSS_ROT_180) { |
| 1413 | /* UV is subsampled by 2 hrz*/ | 1546 | if (chroma_upscale) |
| 1414 | orig_width >>= 1; | 1547 | /* UV is subsampled by 2 horizontally */ |
| 1548 | orig_width >>= 1; | ||
| 1549 | else | ||
| 1550 | /* UV is downsampled by 2 horizontally */ | ||
| 1551 | orig_width <<= 1; | ||
| 1552 | } | ||
| 1553 | |||
| 1415 | /* must use FIR for YUV422 if rotated */ | 1554 | /* must use FIR for YUV422 if rotated */ |
| 1416 | if (rotation != OMAP_DSS_ROT_0) | 1555 | if (rotation != OMAP_DSS_ROT_0) |
| 1417 | scale_x = scale_y = true; | 1556 | scale_x = scale_y = true; |
| 1557 | |||
| 1418 | break; | 1558 | break; |
| 1419 | default: | 1559 | default: |
| 1420 | BUG(); | 1560 | BUG(); |
| @@ -1430,8 +1570,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
| 1430 | out_width, out_height, five_taps, | 1570 | out_width, out_height, five_taps, |
| 1431 | rotation, DISPC_COLOR_COMPONENT_UV); | 1571 | rotation, DISPC_COLOR_COMPONENT_UV); |
| 1432 | 1572 | ||
| 1433 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), | 1573 | if (plane != OMAP_DSS_WB) |
| 1434 | (scale_x || scale_y) ? 1 : 0, 8, 8); | 1574 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), |
| 1575 | (scale_x || scale_y) ? 1 : 0, 8, 8); | ||
| 1576 | |||
| 1435 | /* set H scaling */ | 1577 | /* set H scaling */ |
| 1436 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); | 1578 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); |
| 1437 | /* set V scaling */ | 1579 | /* set V scaling */ |
| @@ -1847,22 +1989,19 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width, | |||
| 1847 | * This function is used to avoid synclosts in OMAP3, because of some | 1989 | * This function is used to avoid synclosts in OMAP3, because of some |
| 1848 | * undocumented horizontal position and timing related limitations. | 1990 | * undocumented horizontal position and timing related limitations. |
| 1849 | */ | 1991 | */ |
| 1850 | static int check_horiz_timing_omap3(enum omap_channel channel, | 1992 | static int check_horiz_timing_omap3(enum omap_plane plane, |
| 1851 | const struct omap_video_timings *t, u16 pos_x, | 1993 | const struct omap_video_timings *t, u16 pos_x, |
| 1852 | u16 width, u16 height, u16 out_width, u16 out_height) | 1994 | u16 width, u16 height, u16 out_width, u16 out_height) |
| 1853 | { | 1995 | { |
| 1854 | int DS = DIV_ROUND_UP(height, out_height); | 1996 | int DS = DIV_ROUND_UP(height, out_height); |
| 1855 | unsigned long nonactive, lclk, pclk; | 1997 | unsigned long nonactive; |
| 1856 | static const u8 limits[3] = { 8, 10, 20 }; | 1998 | static const u8 limits[3] = { 8, 10, 20 }; |
| 1857 | u64 val, blank; | 1999 | u64 val, blank; |
| 2000 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
| 2001 | unsigned long lclk = dispc_plane_lclk_rate(plane); | ||
| 1858 | int i; | 2002 | int i; |
| 1859 | 2003 | ||
| 1860 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; | 2004 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; |
| 1861 | pclk = dispc_mgr_pclk_rate(channel); | ||
| 1862 | if (dss_mgr_is_lcd(channel)) | ||
| 1863 | lclk = dispc_mgr_lclk_rate(channel); | ||
| 1864 | else | ||
| 1865 | lclk = dispc_fclk_rate(); | ||
| 1866 | 2005 | ||
| 1867 | i = 0; | 2006 | i = 0; |
| 1868 | if (out_height < height) | 2007 | if (out_height < height) |
| @@ -1899,13 +2038,14 @@ static int check_horiz_timing_omap3(enum omap_channel channel, | |||
| 1899 | return 0; | 2038 | return 0; |
| 1900 | } | 2039 | } |
| 1901 | 2040 | ||
| 1902 | static unsigned long calc_core_clk_five_taps(enum omap_channel channel, | 2041 | static unsigned long calc_core_clk_five_taps(enum omap_plane plane, |
| 1903 | const struct omap_video_timings *mgr_timings, u16 width, | 2042 | const struct omap_video_timings *mgr_timings, u16 width, |
| 1904 | u16 height, u16 out_width, u16 out_height, | 2043 | u16 height, u16 out_width, u16 out_height, |
| 1905 | enum omap_color_mode color_mode) | 2044 | enum omap_color_mode color_mode) |
| 1906 | { | 2045 | { |
| 1907 | u32 core_clk = 0; | 2046 | u32 core_clk = 0; |
| 1908 | u64 tmp, pclk = dispc_mgr_pclk_rate(channel); | 2047 | u64 tmp; |
| 2048 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
| 1909 | 2049 | ||
| 1910 | if (height <= out_height && width <= out_width) | 2050 | if (height <= out_height && width <= out_width) |
| 1911 | return (unsigned long) pclk; | 2051 | return (unsigned long) pclk; |
| @@ -1939,11 +2079,22 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel, | |||
| 1939 | return core_clk; | 2079 | return core_clk; |
| 1940 | } | 2080 | } |
| 1941 | 2081 | ||
| 1942 | static unsigned long calc_core_clk(enum omap_channel channel, u16 width, | 2082 | static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, |
| 1943 | u16 height, u16 out_width, u16 out_height) | 2083 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
| 2084 | { | ||
| 2085 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
| 2086 | |||
| 2087 | if (height > out_height && width > out_width) | ||
| 2088 | return pclk * 4; | ||
| 2089 | else | ||
| 2090 | return pclk * 2; | ||
| 2091 | } | ||
| 2092 | |||
| 2093 | static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, | ||
| 2094 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) | ||
| 1944 | { | 2095 | { |
| 1945 | unsigned int hf, vf; | 2096 | unsigned int hf, vf; |
| 1946 | unsigned long pclk = dispc_mgr_pclk_rate(channel); | 2097 | unsigned long pclk = dispc_plane_pclk_rate(plane); |
| 1947 | 2098 | ||
| 1948 | /* | 2099 | /* |
| 1949 | * FIXME how to determine the 'A' factor | 2100 | * FIXME how to determine the 'A' factor |
| @@ -1958,51 +2109,207 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width, | |||
| 1958 | hf = 2; | 2109 | hf = 2; |
| 1959 | else | 2110 | else |
| 1960 | hf = 1; | 2111 | hf = 1; |
| 1961 | |||
| 1962 | if (height > out_height) | 2112 | if (height > out_height) |
| 1963 | vf = 2; | 2113 | vf = 2; |
| 1964 | else | 2114 | else |
| 1965 | vf = 1; | 2115 | vf = 1; |
| 1966 | 2116 | ||
| 1967 | if (cpu_is_omap24xx()) { | 2117 | return pclk * vf * hf; |
| 1968 | if (vf > 1 && hf > 1) | 2118 | } |
| 1969 | return pclk * 4; | 2119 | |
| 1970 | else | 2120 | static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, |
| 1971 | return pclk * 2; | 2121 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
| 1972 | } else if (cpu_is_omap34xx()) { | 2122 | { |
| 1973 | return pclk * vf * hf; | 2123 | unsigned long pclk; |
| 1974 | } else { | 2124 | |
| 1975 | if (hf > 1) | 2125 | /* |
| 1976 | return DIV_ROUND_UP(pclk, out_width) * width; | 2126 | * If the overlay/writeback is in mem to mem mode, there are no |
| 1977 | else | 2127 | * downscaling limitations with respect to pixel clock, return 1 as |
| 1978 | return pclk; | 2128 | * required core clock to represent that we have sufficient enough |
| 2129 | * core clock to do maximum downscaling | ||
| 2130 | */ | ||
| 2131 | if (mem_to_mem) | ||
| 2132 | return 1; | ||
| 2133 | |||
| 2134 | pclk = dispc_plane_pclk_rate(plane); | ||
| 2135 | |||
| 2136 | if (width > out_width) | ||
| 2137 | return DIV_ROUND_UP(pclk, out_width) * width; | ||
| 2138 | else | ||
| 2139 | return pclk; | ||
| 2140 | } | ||
| 2141 | |||
| 2142 | static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, | ||
| 2143 | const struct omap_video_timings *mgr_timings, | ||
| 2144 | u16 width, u16 height, u16 out_width, u16 out_height, | ||
| 2145 | enum omap_color_mode color_mode, bool *five_taps, | ||
| 2146 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | ||
| 2147 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) | ||
| 2148 | { | ||
| 2149 | int error; | ||
| 2150 | u16 in_width, in_height; | ||
| 2151 | int min_factor = min(*decim_x, *decim_y); | ||
| 2152 | const int maxsinglelinewidth = | ||
| 2153 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | ||
| 2154 | |||
| 2155 | *five_taps = false; | ||
| 2156 | |||
| 2157 | do { | ||
| 2158 | in_height = DIV_ROUND_UP(height, *decim_y); | ||
| 2159 | in_width = DIV_ROUND_UP(width, *decim_x); | ||
| 2160 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, | ||
| 2161 | in_height, out_width, out_height, mem_to_mem); | ||
| 2162 | error = (in_width > maxsinglelinewidth || !*core_clk || | ||
| 2163 | *core_clk > dispc_core_clk_rate()); | ||
| 2164 | if (error) { | ||
| 2165 | if (*decim_x == *decim_y) { | ||
| 2166 | *decim_x = min_factor; | ||
| 2167 | ++*decim_y; | ||
| 2168 | } else { | ||
| 2169 | swap(*decim_x, *decim_y); | ||
| 2170 | if (*decim_x < *decim_y) | ||
| 2171 | ++*decim_x; | ||
| 2172 | } | ||
| 2173 | } | ||
| 2174 | } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); | ||
| 2175 | |||
| 2176 | if (in_width > maxsinglelinewidth) { | ||
| 2177 | DSSERR("Cannot scale max input width exceeded"); | ||
| 2178 | return -EINVAL; | ||
| 1979 | } | 2179 | } |
| 2180 | return 0; | ||
| 1980 | } | 2181 | } |
| 1981 | 2182 | ||
| 1982 | static int dispc_ovl_calc_scaling(enum omap_plane plane, | 2183 | static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, |
| 1983 | enum omap_channel channel, | ||
| 1984 | const struct omap_video_timings *mgr_timings, | 2184 | const struct omap_video_timings *mgr_timings, |
| 1985 | u16 width, u16 height, u16 out_width, u16 out_height, | 2185 | u16 width, u16 height, u16 out_width, u16 out_height, |
| 1986 | enum omap_color_mode color_mode, bool *five_taps, | 2186 | enum omap_color_mode color_mode, bool *five_taps, |
| 1987 | int *x_predecim, int *y_predecim, u16 pos_x) | 2187 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
| 2188 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) | ||
| 1988 | { | 2189 | { |
| 1989 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 2190 | int error; |
| 1990 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | 2191 | u16 in_width, in_height; |
| 2192 | int min_factor = min(*decim_x, *decim_y); | ||
| 2193 | const int maxsinglelinewidth = | ||
| 2194 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | ||
| 2195 | |||
| 2196 | do { | ||
| 2197 | in_height = DIV_ROUND_UP(height, *decim_y); | ||
| 2198 | in_width = DIV_ROUND_UP(width, *decim_x); | ||
| 2199 | *core_clk = calc_core_clk_five_taps(plane, mgr_timings, | ||
| 2200 | in_width, in_height, out_width, out_height, color_mode); | ||
| 2201 | |||
| 2202 | error = check_horiz_timing_omap3(plane, mgr_timings, | ||
| 2203 | pos_x, in_width, in_height, out_width, | ||
| 2204 | out_height); | ||
| 2205 | |||
| 2206 | if (in_width > maxsinglelinewidth) | ||
| 2207 | if (in_height > out_height && | ||
| 2208 | in_height < out_height * 2) | ||
| 2209 | *five_taps = false; | ||
| 2210 | if (!*five_taps) | ||
| 2211 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, | ||
| 2212 | in_height, out_width, out_height, | ||
| 2213 | mem_to_mem); | ||
| 2214 | |||
| 2215 | error = (error || in_width > maxsinglelinewidth * 2 || | ||
| 2216 | (in_width > maxsinglelinewidth && *five_taps) || | ||
| 2217 | !*core_clk || *core_clk > dispc_core_clk_rate()); | ||
| 2218 | if (error) { | ||
| 2219 | if (*decim_x == *decim_y) { | ||
| 2220 | *decim_x = min_factor; | ||
| 2221 | ++*decim_y; | ||
| 2222 | } else { | ||
| 2223 | swap(*decim_x, *decim_y); | ||
| 2224 | if (*decim_x < *decim_y) | ||
| 2225 | ++*decim_x; | ||
| 2226 | } | ||
| 2227 | } | ||
| 2228 | } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); | ||
| 2229 | |||
| 2230 | if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height, | ||
| 2231 | out_width, out_height)){ | ||
| 2232 | DSSERR("horizontal timing too tight\n"); | ||
| 2233 | return -EINVAL; | ||
| 2234 | } | ||
| 2235 | |||
| 2236 | if (in_width > (maxsinglelinewidth * 2)) { | ||
| 2237 | DSSERR("Cannot setup scaling"); | ||
| 2238 | DSSERR("width exceeds maximum width possible"); | ||
| 2239 | return -EINVAL; | ||
| 2240 | } | ||
| 2241 | |||
| 2242 | if (in_width > maxsinglelinewidth && *five_taps) { | ||
| 2243 | DSSERR("cannot setup scaling with five taps"); | ||
| 2244 | return -EINVAL; | ||
| 2245 | } | ||
| 2246 | return 0; | ||
| 2247 | } | ||
| 2248 | |||
| 2249 | static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, | ||
| 2250 | const struct omap_video_timings *mgr_timings, | ||
| 2251 | u16 width, u16 height, u16 out_width, u16 out_height, | ||
| 2252 | enum omap_color_mode color_mode, bool *five_taps, | ||
| 2253 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | ||
| 2254 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) | ||
| 2255 | { | ||
| 2256 | u16 in_width, in_width_max; | ||
| 2257 | int decim_x_min = *decim_x; | ||
| 2258 | u16 in_height = DIV_ROUND_UP(height, *decim_y); | ||
| 1991 | const int maxsinglelinewidth = | 2259 | const int maxsinglelinewidth = |
| 1992 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 2260 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
| 2261 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
| 2262 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | ||
| 2263 | |||
| 2264 | if (mem_to_mem) | ||
| 2265 | in_width_max = DIV_ROUND_UP(out_width, maxdownscale); | ||
| 2266 | else | ||
| 2267 | in_width_max = dispc_core_clk_rate() / | ||
| 2268 | DIV_ROUND_UP(pclk, out_width); | ||
| 2269 | |||
| 2270 | *decim_x = DIV_ROUND_UP(width, in_width_max); | ||
| 2271 | |||
| 2272 | *decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min; | ||
| 2273 | if (*decim_x > *x_predecim) | ||
| 2274 | return -EINVAL; | ||
| 2275 | |||
| 2276 | do { | ||
| 2277 | in_width = DIV_ROUND_UP(width, *decim_x); | ||
| 2278 | } while (*decim_x <= *x_predecim && | ||
| 2279 | in_width > maxsinglelinewidth && ++*decim_x); | ||
| 2280 | |||
| 2281 | if (in_width > maxsinglelinewidth) { | ||
| 2282 | DSSERR("Cannot scale width exceeds max line width"); | ||
| 2283 | return -EINVAL; | ||
| 2284 | } | ||
| 2285 | |||
| 2286 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, | ||
| 2287 | out_width, out_height, mem_to_mem); | ||
| 2288 | return 0; | ||
| 2289 | } | ||
| 2290 | |||
| 2291 | static int dispc_ovl_calc_scaling(enum omap_plane plane, | ||
| 2292 | enum omap_overlay_caps caps, | ||
| 2293 | const struct omap_video_timings *mgr_timings, | ||
| 2294 | u16 width, u16 height, u16 out_width, u16 out_height, | ||
| 2295 | enum omap_color_mode color_mode, bool *five_taps, | ||
| 2296 | int *x_predecim, int *y_predecim, u16 pos_x, | ||
| 2297 | enum omap_dss_rotation_type rotation_type, bool mem_to_mem) | ||
| 2298 | { | ||
| 2299 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | ||
| 1993 | const int max_decim_limit = 16; | 2300 | const int max_decim_limit = 16; |
| 1994 | unsigned long core_clk = 0; | 2301 | unsigned long core_clk = 0; |
| 1995 | int decim_x, decim_y, error, min_factor; | 2302 | int decim_x, decim_y, ret; |
| 1996 | u16 in_width, in_height, in_width_max = 0; | ||
| 1997 | 2303 | ||
| 1998 | if (width == out_width && height == out_height) | 2304 | if (width == out_width && height == out_height) |
| 1999 | return 0; | 2305 | return 0; |
| 2000 | 2306 | ||
| 2001 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) | 2307 | if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0) |
| 2002 | return -EINVAL; | 2308 | return -EINVAL; |
| 2003 | 2309 | ||
| 2004 | *x_predecim = max_decim_limit; | 2310 | *x_predecim = max_decim_limit; |
| 2005 | *y_predecim = max_decim_limit; | 2311 | *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER && |
| 2312 | dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit; | ||
| 2006 | 2313 | ||
| 2007 | if (color_mode == OMAP_DSS_COLOR_CLUT1 || | 2314 | if (color_mode == OMAP_DSS_COLOR_CLUT1 || |
| 2008 | color_mode == OMAP_DSS_COLOR_CLUT2 || | 2315 | color_mode == OMAP_DSS_COLOR_CLUT2 || |
| @@ -2017,118 +2324,18 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
| 2017 | decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale); | 2324 | decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale); |
| 2018 | decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale); | 2325 | decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale); |
| 2019 | 2326 | ||
| 2020 | min_factor = min(decim_x, decim_y); | ||
| 2021 | |||
| 2022 | if (decim_x > *x_predecim || out_width > width * 8) | 2327 | if (decim_x > *x_predecim || out_width > width * 8) |
| 2023 | return -EINVAL; | 2328 | return -EINVAL; |
| 2024 | 2329 | ||
| 2025 | if (decim_y > *y_predecim || out_height > height * 8) | 2330 | if (decim_y > *y_predecim || out_height > height * 8) |
| 2026 | return -EINVAL; | 2331 | return -EINVAL; |
| 2027 | 2332 | ||
| 2028 | if (cpu_is_omap24xx()) { | 2333 | ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, |
| 2029 | *five_taps = false; | 2334 | out_width, out_height, color_mode, five_taps, |
| 2030 | 2335 | x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk, | |
| 2031 | do { | 2336 | mem_to_mem); |
| 2032 | in_height = DIV_ROUND_UP(height, decim_y); | 2337 | if (ret) |
| 2033 | in_width = DIV_ROUND_UP(width, decim_x); | 2338 | return ret; |
| 2034 | core_clk = calc_core_clk(channel, in_width, in_height, | ||
| 2035 | out_width, out_height); | ||
| 2036 | error = (in_width > maxsinglelinewidth || !core_clk || | ||
| 2037 | core_clk > dispc_core_clk_rate()); | ||
| 2038 | if (error) { | ||
| 2039 | if (decim_x == decim_y) { | ||
| 2040 | decim_x = min_factor; | ||
| 2041 | decim_y++; | ||
| 2042 | } else { | ||
| 2043 | swap(decim_x, decim_y); | ||
| 2044 | if (decim_x < decim_y) | ||
| 2045 | decim_x++; | ||
| 2046 | } | ||
| 2047 | } | ||
| 2048 | } while (decim_x <= *x_predecim && decim_y <= *y_predecim && | ||
| 2049 | error); | ||
| 2050 | |||
| 2051 | if (in_width > maxsinglelinewidth) { | ||
| 2052 | DSSERR("Cannot scale max input width exceeded"); | ||
| 2053 | return -EINVAL; | ||
| 2054 | } | ||
| 2055 | } else if (cpu_is_omap34xx()) { | ||
| 2056 | |||
| 2057 | do { | ||
| 2058 | in_height = DIV_ROUND_UP(height, decim_y); | ||
| 2059 | in_width = DIV_ROUND_UP(width, decim_x); | ||
| 2060 | core_clk = calc_core_clk_five_taps(channel, mgr_timings, | ||
| 2061 | in_width, in_height, out_width, out_height, | ||
| 2062 | color_mode); | ||
| 2063 | |||
| 2064 | error = check_horiz_timing_omap3(channel, mgr_timings, | ||
| 2065 | pos_x, in_width, in_height, out_width, | ||
| 2066 | out_height); | ||
| 2067 | |||
| 2068 | if (in_width > maxsinglelinewidth) | ||
| 2069 | if (in_height > out_height && | ||
| 2070 | in_height < out_height * 2) | ||
| 2071 | *five_taps = false; | ||
| 2072 | if (!*five_taps) | ||
| 2073 | core_clk = calc_core_clk(channel, in_width, | ||
| 2074 | in_height, out_width, out_height); | ||
| 2075 | error = (error || in_width > maxsinglelinewidth * 2 || | ||
| 2076 | (in_width > maxsinglelinewidth && *five_taps) || | ||
| 2077 | !core_clk || core_clk > dispc_core_clk_rate()); | ||
| 2078 | if (error) { | ||
| 2079 | if (decim_x == decim_y) { | ||
| 2080 | decim_x = min_factor; | ||
| 2081 | decim_y++; | ||
| 2082 | } else { | ||
| 2083 | swap(decim_x, decim_y); | ||
| 2084 | if (decim_x < decim_y) | ||
| 2085 | decim_x++; | ||
| 2086 | } | ||
| 2087 | } | ||
| 2088 | } while (decim_x <= *x_predecim && decim_y <= *y_predecim | ||
| 2089 | && error); | ||
| 2090 | |||
| 2091 | if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, | ||
| 2092 | height, out_width, out_height)){ | ||
| 2093 | DSSERR("horizontal timing too tight\n"); | ||
| 2094 | return -EINVAL; | ||
| 2095 | } | ||
| 2096 | |||
| 2097 | if (in_width > (maxsinglelinewidth * 2)) { | ||
| 2098 | DSSERR("Cannot setup scaling"); | ||
| 2099 | DSSERR("width exceeds maximum width possible"); | ||
| 2100 | return -EINVAL; | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | if (in_width > maxsinglelinewidth && *five_taps) { | ||
| 2104 | DSSERR("cannot setup scaling with five taps"); | ||
| 2105 | return -EINVAL; | ||
| 2106 | } | ||
| 2107 | } else { | ||
| 2108 | int decim_x_min = decim_x; | ||
| 2109 | in_height = DIV_ROUND_UP(height, decim_y); | ||
| 2110 | in_width_max = dispc_core_clk_rate() / | ||
| 2111 | DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), | ||
| 2112 | out_width); | ||
| 2113 | decim_x = DIV_ROUND_UP(width, in_width_max); | ||
| 2114 | |||
| 2115 | decim_x = decim_x > decim_x_min ? decim_x : decim_x_min; | ||
| 2116 | if (decim_x > *x_predecim) | ||
| 2117 | return -EINVAL; | ||
| 2118 | |||
| 2119 | do { | ||
| 2120 | in_width = DIV_ROUND_UP(width, decim_x); | ||
| 2121 | } while (decim_x <= *x_predecim && | ||
| 2122 | in_width > maxsinglelinewidth && decim_x++); | ||
| 2123 | |||
| 2124 | if (in_width > maxsinglelinewidth) { | ||
| 2125 | DSSERR("Cannot scale width exceeds max line width"); | ||
| 2126 | return -EINVAL; | ||
| 2127 | } | ||
| 2128 | |||
| 2129 | core_clk = calc_core_clk(channel, in_width, in_height, | ||
| 2130 | out_width, out_height); | ||
| 2131 | } | ||
| 2132 | 2339 | ||
| 2133 | DSSDBG("required core clk rate = %lu Hz\n", core_clk); | 2340 | DSSDBG("required core clk rate = %lu Hz\n", core_clk); |
| 2134 | DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate()); | 2341 | DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate()); |
| @@ -2146,69 +2353,64 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
| 2146 | return 0; | 2353 | return 0; |
| 2147 | } | 2354 | } |
| 2148 | 2355 | ||
| 2149 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 2356 | static int dispc_ovl_setup_common(enum omap_plane plane, |
| 2150 | bool replication, const struct omap_video_timings *mgr_timings) | 2357 | enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, |
| 2358 | u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, | ||
| 2359 | u16 out_width, u16 out_height, enum omap_color_mode color_mode, | ||
| 2360 | u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, | ||
| 2361 | u8 global_alpha, enum omap_dss_rotation_type rotation_type, | ||
| 2362 | bool replication, const struct omap_video_timings *mgr_timings, | ||
| 2363 | bool mem_to_mem) | ||
| 2151 | { | 2364 | { |
| 2152 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
| 2153 | bool five_taps = true; | 2365 | bool five_taps = true; |
| 2154 | bool fieldmode = 0; | 2366 | bool fieldmode = 0; |
| 2155 | int r, cconv = 0; | 2367 | int r, cconv = 0; |
| 2156 | unsigned offset0, offset1; | 2368 | unsigned offset0, offset1; |
| 2157 | s32 row_inc; | 2369 | s32 row_inc; |
| 2158 | s32 pix_inc; | 2370 | s32 pix_inc; |
| 2159 | u16 frame_height = oi->height; | 2371 | u16 frame_height = height; |
| 2160 | unsigned int field_offset = 0; | 2372 | unsigned int field_offset = 0; |
| 2161 | u16 in_height = oi->height; | 2373 | u16 in_height = height; |
| 2162 | u16 in_width = oi->width; | 2374 | u16 in_width = width; |
| 2163 | u16 out_width, out_height; | ||
| 2164 | enum omap_channel channel; | ||
| 2165 | int x_predecim = 1, y_predecim = 1; | 2375 | int x_predecim = 1, y_predecim = 1; |
| 2166 | bool ilace = mgr_timings->interlace; | 2376 | bool ilace = mgr_timings->interlace; |
| 2167 | 2377 | ||
| 2168 | channel = dispc_ovl_get_channel_out(plane); | 2378 | if (paddr == 0) |
| 2169 | |||
| 2170 | DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " | ||
| 2171 | "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n", | ||
| 2172 | plane, oi->paddr, oi->p_uv_addr, | ||
| 2173 | oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, | ||
| 2174 | oi->out_width, oi->out_height, oi->color_mode, oi->rotation, | ||
| 2175 | oi->mirror, ilace, channel, replication); | ||
| 2176 | |||
| 2177 | if (oi->paddr == 0) | ||
| 2178 | return -EINVAL; | 2379 | return -EINVAL; |
| 2179 | 2380 | ||
| 2180 | out_width = oi->out_width == 0 ? oi->width : oi->out_width; | 2381 | out_width = out_width == 0 ? width : out_width; |
| 2181 | out_height = oi->out_height == 0 ? oi->height : oi->out_height; | 2382 | out_height = out_height == 0 ? height : out_height; |
| 2182 | 2383 | ||
| 2183 | if (ilace && oi->height == out_height) | 2384 | if (ilace && height == out_height) |
| 2184 | fieldmode = 1; | 2385 | fieldmode = 1; |
| 2185 | 2386 | ||
| 2186 | if (ilace) { | 2387 | if (ilace) { |
| 2187 | if (fieldmode) | 2388 | if (fieldmode) |
| 2188 | in_height /= 2; | 2389 | in_height /= 2; |
| 2189 | oi->pos_y /= 2; | 2390 | pos_y /= 2; |
| 2190 | out_height /= 2; | 2391 | out_height /= 2; |
| 2191 | 2392 | ||
| 2192 | DSSDBG("adjusting for ilace: height %d, pos_y %d, " | 2393 | DSSDBG("adjusting for ilace: height %d, pos_y %d, " |
| 2193 | "out_height %d\n", | 2394 | "out_height %d\n", in_height, pos_y, |
| 2194 | in_height, oi->pos_y, out_height); | 2395 | out_height); |
| 2195 | } | 2396 | } |
| 2196 | 2397 | ||
| 2197 | if (!dss_feat_color_mode_supported(plane, oi->color_mode)) | 2398 | if (!dss_feat_color_mode_supported(plane, color_mode)) |
| 2198 | return -EINVAL; | 2399 | return -EINVAL; |
| 2199 | 2400 | ||
| 2200 | r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width, | 2401 | r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, |
| 2201 | in_height, out_width, out_height, oi->color_mode, | 2402 | in_height, out_width, out_height, color_mode, |
| 2202 | &five_taps, &x_predecim, &y_predecim, oi->pos_x); | 2403 | &five_taps, &x_predecim, &y_predecim, pos_x, |
| 2404 | rotation_type, mem_to_mem); | ||
| 2203 | if (r) | 2405 | if (r) |
| 2204 | return r; | 2406 | return r; |
| 2205 | 2407 | ||
| 2206 | in_width = DIV_ROUND_UP(in_width, x_predecim); | 2408 | in_width = DIV_ROUND_UP(in_width, x_predecim); |
| 2207 | in_height = DIV_ROUND_UP(in_height, y_predecim); | 2409 | in_height = DIV_ROUND_UP(in_height, y_predecim); |
| 2208 | 2410 | ||
| 2209 | if (oi->color_mode == OMAP_DSS_COLOR_YUV2 || | 2411 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
| 2210 | oi->color_mode == OMAP_DSS_COLOR_UYVY || | 2412 | color_mode == OMAP_DSS_COLOR_UYVY || |
| 2211 | oi->color_mode == OMAP_DSS_COLOR_NV12) | 2413 | color_mode == OMAP_DSS_COLOR_NV12) |
| 2212 | cconv = 1; | 2414 | cconv = 1; |
| 2213 | 2415 | ||
| 2214 | if (ilace && !fieldmode) { | 2416 | if (ilace && !fieldmode) { |
| @@ -2234,70 +2436,144 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
| 2234 | row_inc = 0; | 2436 | row_inc = 0; |
| 2235 | pix_inc = 0; | 2437 | pix_inc = 0; |
| 2236 | 2438 | ||
| 2237 | if (oi->rotation_type == OMAP_DSS_ROT_TILER) | 2439 | if (rotation_type == OMAP_DSS_ROT_TILER) |
| 2238 | calc_tiler_rotation_offset(oi->screen_width, in_width, | 2440 | calc_tiler_rotation_offset(screen_width, in_width, |
| 2239 | oi->color_mode, fieldmode, field_offset, | 2441 | color_mode, fieldmode, field_offset, |
| 2240 | &offset0, &offset1, &row_inc, &pix_inc, | 2442 | &offset0, &offset1, &row_inc, &pix_inc, |
| 2241 | x_predecim, y_predecim); | 2443 | x_predecim, y_predecim); |
| 2242 | else if (oi->rotation_type == OMAP_DSS_ROT_DMA) | 2444 | else if (rotation_type == OMAP_DSS_ROT_DMA) |
| 2243 | calc_dma_rotation_offset(oi->rotation, oi->mirror, | 2445 | calc_dma_rotation_offset(rotation, mirror, |
| 2244 | oi->screen_width, in_width, frame_height, | 2446 | screen_width, in_width, frame_height, |
| 2245 | oi->color_mode, fieldmode, field_offset, | 2447 | color_mode, fieldmode, field_offset, |
| 2246 | &offset0, &offset1, &row_inc, &pix_inc, | 2448 | &offset0, &offset1, &row_inc, &pix_inc, |
| 2247 | x_predecim, y_predecim); | 2449 | x_predecim, y_predecim); |
| 2248 | else | 2450 | else |
| 2249 | calc_vrfb_rotation_offset(oi->rotation, oi->mirror, | 2451 | calc_vrfb_rotation_offset(rotation, mirror, |
| 2250 | oi->screen_width, in_width, frame_height, | 2452 | screen_width, in_width, frame_height, |
| 2251 | oi->color_mode, fieldmode, field_offset, | 2453 | color_mode, fieldmode, field_offset, |
| 2252 | &offset0, &offset1, &row_inc, &pix_inc, | 2454 | &offset0, &offset1, &row_inc, &pix_inc, |
| 2253 | x_predecim, y_predecim); | 2455 | x_predecim, y_predecim); |
| 2254 | 2456 | ||
| 2255 | DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", | 2457 | DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", |
| 2256 | offset0, offset1, row_inc, pix_inc); | 2458 | offset0, offset1, row_inc, pix_inc); |
| 2257 | 2459 | ||
| 2258 | dispc_ovl_set_color_mode(plane, oi->color_mode); | 2460 | dispc_ovl_set_color_mode(plane, color_mode); |
| 2259 | 2461 | ||
| 2260 | dispc_ovl_configure_burst_type(plane, oi->rotation_type); | 2462 | dispc_ovl_configure_burst_type(plane, rotation_type); |
| 2261 | 2463 | ||
| 2262 | dispc_ovl_set_ba0(plane, oi->paddr + offset0); | 2464 | dispc_ovl_set_ba0(plane, paddr + offset0); |
| 2263 | dispc_ovl_set_ba1(plane, oi->paddr + offset1); | 2465 | dispc_ovl_set_ba1(plane, paddr + offset1); |
| 2264 | 2466 | ||
| 2265 | if (OMAP_DSS_COLOR_NV12 == oi->color_mode) { | 2467 | if (OMAP_DSS_COLOR_NV12 == color_mode) { |
| 2266 | dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0); | 2468 | dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0); |
| 2267 | dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1); | 2469 | dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1); |
| 2268 | } | 2470 | } |
| 2269 | 2471 | ||
| 2270 | |||
| 2271 | dispc_ovl_set_row_inc(plane, row_inc); | 2472 | dispc_ovl_set_row_inc(plane, row_inc); |
| 2272 | dispc_ovl_set_pix_inc(plane, pix_inc); | 2473 | dispc_ovl_set_pix_inc(plane, pix_inc); |
| 2273 | 2474 | ||
| 2274 | DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, | 2475 | DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width, |
| 2275 | in_height, out_width, out_height); | 2476 | in_height, out_width, out_height); |
| 2276 | 2477 | ||
| 2277 | dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); | 2478 | dispc_ovl_set_pos(plane, caps, pos_x, pos_y); |
| 2278 | 2479 | ||
| 2279 | dispc_ovl_set_pic_size(plane, in_width, in_height); | 2480 | dispc_ovl_set_input_size(plane, in_width, in_height); |
| 2280 | 2481 | ||
| 2281 | if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { | 2482 | if (caps & OMAP_DSS_OVL_CAP_SCALE) { |
| 2282 | dispc_ovl_set_scaling(plane, in_width, in_height, out_width, | 2483 | dispc_ovl_set_scaling(plane, in_width, in_height, out_width, |
| 2283 | out_height, ilace, five_taps, fieldmode, | 2484 | out_height, ilace, five_taps, fieldmode, |
| 2284 | oi->color_mode, oi->rotation); | 2485 | color_mode, rotation); |
| 2285 | dispc_ovl_set_vid_size(plane, out_width, out_height); | 2486 | dispc_ovl_set_output_size(plane, out_width, out_height); |
| 2286 | dispc_ovl_set_vid_color_conv(plane, cconv); | 2487 | dispc_ovl_set_vid_color_conv(plane, cconv); |
| 2287 | } | 2488 | } |
| 2288 | 2489 | ||
| 2289 | dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror, | 2490 | dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode); |
| 2290 | oi->color_mode); | ||
| 2291 | 2491 | ||
| 2292 | dispc_ovl_set_zorder(plane, oi->zorder); | 2492 | dispc_ovl_set_zorder(plane, caps, zorder); |
| 2293 | dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha); | 2493 | dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha); |
| 2294 | dispc_ovl_setup_global_alpha(plane, oi->global_alpha); | 2494 | dispc_ovl_setup_global_alpha(plane, caps, global_alpha); |
| 2295 | 2495 | ||
| 2296 | dispc_ovl_enable_replication(plane, replication); | 2496 | dispc_ovl_enable_replication(plane, caps, replication); |
| 2297 | 2497 | ||
| 2298 | return 0; | 2498 | return 0; |
| 2299 | } | 2499 | } |
| 2300 | 2500 | ||
| 2501 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, | ||
| 2502 | bool replication, const struct omap_video_timings *mgr_timings, | ||
| 2503 | bool mem_to_mem) | ||
| 2504 | { | ||
| 2505 | int r; | ||
| 2506 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
| 2507 | enum omap_channel channel; | ||
| 2508 | |||
| 2509 | channel = dispc_ovl_get_channel_out(plane); | ||
| 2510 | |||
| 2511 | DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " | ||
| 2512 | "%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n", | ||
| 2513 | plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x, | ||
| 2514 | oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, | ||
| 2515 | oi->color_mode, oi->rotation, oi->mirror, channel, replication); | ||
| 2516 | |||
| 2517 | r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr, | ||
| 2518 | oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, | ||
| 2519 | oi->out_width, oi->out_height, oi->color_mode, oi->rotation, | ||
| 2520 | oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, | ||
| 2521 | oi->rotation_type, replication, mgr_timings, mem_to_mem); | ||
| 2522 | |||
| 2523 | return r; | ||
| 2524 | } | ||
| 2525 | |||
| 2526 | int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | ||
| 2527 | bool mem_to_mem, const struct omap_video_timings *mgr_timings) | ||
| 2528 | { | ||
| 2529 | int r; | ||
| 2530 | u32 l; | ||
| 2531 | enum omap_plane plane = OMAP_DSS_WB; | ||
| 2532 | const int pos_x = 0, pos_y = 0; | ||
| 2533 | const u8 zorder = 0, global_alpha = 0; | ||
| 2534 | const bool replication = false; | ||
| 2535 | bool truncation; | ||
| 2536 | int in_width = mgr_timings->x_res; | ||
| 2537 | int in_height = mgr_timings->y_res; | ||
| 2538 | enum omap_overlay_caps caps = | ||
| 2539 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA; | ||
| 2540 | |||
| 2541 | DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, " | ||
| 2542 | "rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width, | ||
| 2543 | in_height, wi->width, wi->height, wi->color_mode, wi->rotation, | ||
| 2544 | wi->mirror); | ||
| 2545 | |||
| 2546 | r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr, | ||
| 2547 | wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width, | ||
| 2548 | wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder, | ||
| 2549 | wi->pre_mult_alpha, global_alpha, wi->rotation_type, | ||
| 2550 | replication, mgr_timings, mem_to_mem); | ||
| 2551 | |||
| 2552 | switch (wi->color_mode) { | ||
| 2553 | case OMAP_DSS_COLOR_RGB16: | ||
| 2554 | case OMAP_DSS_COLOR_RGB24P: | ||
| 2555 | case OMAP_DSS_COLOR_ARGB16: | ||
| 2556 | case OMAP_DSS_COLOR_RGBA16: | ||
| 2557 | case OMAP_DSS_COLOR_RGB12U: | ||
| 2558 | case OMAP_DSS_COLOR_ARGB16_1555: | ||
| 2559 | case OMAP_DSS_COLOR_XRGB16_1555: | ||
| 2560 | case OMAP_DSS_COLOR_RGBX16: | ||
| 2561 | truncation = true; | ||
| 2562 | break; | ||
| 2563 | default: | ||
| 2564 | truncation = false; | ||
| 2565 | break; | ||
| 2566 | } | ||
| 2567 | |||
| 2568 | /* setup extra DISPC_WB_ATTRIBUTES */ | ||
| 2569 | l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); | ||
| 2570 | l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */ | ||
| 2571 | l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */ | ||
| 2572 | dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l); | ||
| 2573 | |||
| 2574 | return r; | ||
| 2575 | } | ||
| 2576 | |||
| 2301 | int dispc_ovl_enable(enum omap_plane plane, bool enable) | 2577 | int dispc_ovl_enable(enum omap_plane plane, bool enable) |
| 2302 | { | 2578 | { |
| 2303 | DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); | 2579 | DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); |
| @@ -2450,6 +2726,47 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable) | |||
| 2450 | BUG(); | 2726 | BUG(); |
| 2451 | } | 2727 | } |
| 2452 | 2728 | ||
| 2729 | void dispc_wb_enable(bool enable) | ||
| 2730 | { | ||
| 2731 | enum omap_plane plane = OMAP_DSS_WB; | ||
| 2732 | struct completion frame_done_completion; | ||
| 2733 | bool is_on; | ||
| 2734 | int r; | ||
| 2735 | u32 irq; | ||
| 2736 | |||
| 2737 | is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); | ||
| 2738 | irq = DISPC_IRQ_FRAMEDONEWB; | ||
| 2739 | |||
| 2740 | if (!enable && is_on) { | ||
| 2741 | init_completion(&frame_done_completion); | ||
| 2742 | |||
| 2743 | r = omap_dispc_register_isr(dispc_disable_isr, | ||
| 2744 | &frame_done_completion, irq); | ||
| 2745 | if (r) | ||
| 2746 | DSSERR("failed to register FRAMEDONEWB isr\n"); | ||
| 2747 | } | ||
| 2748 | |||
| 2749 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); | ||
| 2750 | |||
| 2751 | if (!enable && is_on) { | ||
| 2752 | if (!wait_for_completion_timeout(&frame_done_completion, | ||
| 2753 | msecs_to_jiffies(100))) | ||
| 2754 | DSSERR("timeout waiting for FRAMEDONEWB\n"); | ||
| 2755 | |||
| 2756 | r = omap_dispc_unregister_isr(dispc_disable_isr, | ||
| 2757 | &frame_done_completion, irq); | ||
| 2758 | if (r) | ||
| 2759 | DSSERR("failed to unregister FRAMEDONEWB isr\n"); | ||
| 2760 | } | ||
| 2761 | } | ||
| 2762 | |||
| 2763 | bool dispc_wb_is_enabled(void) | ||
| 2764 | { | ||
| 2765 | enum omap_plane plane = OMAP_DSS_WB; | ||
| 2766 | |||
| 2767 | return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); | ||
| 2768 | } | ||
| 2769 | |||
| 2453 | void dispc_lcd_enable_signal_polarity(bool act_high) | 2770 | void dispc_lcd_enable_signal_polarity(bool act_high) |
| 2454 | { | 2771 | { |
| 2455 | if (!dss_has_feature(FEAT_LCDENABLEPOL)) | 2772 | if (!dss_has_feature(FEAT_LCDENABLEPOL)) |
| @@ -2604,24 +2921,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height) | |||
| 2604 | static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, | 2921 | static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, |
| 2605 | int vsw, int vfp, int vbp) | 2922 | int vsw, int vfp, int vbp) |
| 2606 | { | 2923 | { |
| 2607 | if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { | 2924 | if (hsw < 1 || hsw > dispc.feat->sw_max || |
| 2608 | if (hsw < 1 || hsw > 64 || | 2925 | hfp < 1 || hfp > dispc.feat->hp_max || |
| 2609 | hfp < 1 || hfp > 256 || | 2926 | hbp < 1 || hbp > dispc.feat->hp_max || |
| 2610 | hbp < 1 || hbp > 256 || | 2927 | vsw < 1 || vsw > dispc.feat->sw_max || |
| 2611 | vsw < 1 || vsw > 64 || | 2928 | vfp < 0 || vfp > dispc.feat->vp_max || |
| 2612 | vfp < 0 || vfp > 255 || | 2929 | vbp < 0 || vbp > dispc.feat->vp_max) |
| 2613 | vbp < 0 || vbp > 255) | 2930 | return false; |
| 2614 | return false; | ||
| 2615 | } else { | ||
| 2616 | if (hsw < 1 || hsw > 256 || | ||
| 2617 | hfp < 1 || hfp > 4096 || | ||
| 2618 | hbp < 1 || hbp > 4096 || | ||
| 2619 | vsw < 1 || vsw > 256 || | ||
| 2620 | vfp < 0 || vfp > 4095 || | ||
| 2621 | vbp < 0 || vbp > 4095) | ||
| 2622 | return false; | ||
| 2623 | } | ||
| 2624 | |||
| 2625 | return true; | 2931 | return true; |
| 2626 | } | 2932 | } |
| 2627 | 2933 | ||
| @@ -2653,19 +2959,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, | |||
| 2653 | u32 timing_h, timing_v, l; | 2959 | u32 timing_h, timing_v, l; |
| 2654 | bool onoff, rf, ipc; | 2960 | bool onoff, rf, ipc; |
| 2655 | 2961 | ||
| 2656 | if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { | 2962 | timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) | |
| 2657 | timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | | 2963 | FLD_VAL(hfp-1, dispc.feat->fp_start, 8) | |
| 2658 | FLD_VAL(hbp-1, 27, 20); | 2964 | FLD_VAL(hbp-1, dispc.feat->bp_start, 20); |
| 2659 | 2965 | timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) | | |
| 2660 | timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) | | 2966 | FLD_VAL(vfp, dispc.feat->fp_start, 8) | |
| 2661 | FLD_VAL(vbp, 27, 20); | 2967 | FLD_VAL(vbp, dispc.feat->bp_start, 20); |
| 2662 | } else { | ||
| 2663 | timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) | | ||
| 2664 | FLD_VAL(hbp-1, 31, 20); | ||
| 2665 | |||
| 2666 | timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) | | ||
| 2667 | FLD_VAL(vbp, 31, 20); | ||
| 2668 | } | ||
| 2669 | 2968 | ||
| 2670 | dispc_write_reg(DISPC_TIMING_H(channel), timing_h); | 2969 | dispc_write_reg(DISPC_TIMING_H(channel), timing_h); |
| 2671 | dispc_write_reg(DISPC_TIMING_V(channel), timing_v); | 2970 | dispc_write_reg(DISPC_TIMING_V(channel), timing_v); |
| @@ -2871,6 +3170,23 @@ unsigned long dispc_core_clk_rate(void) | |||
| 2871 | return fclk / lcd; | 3170 | return fclk / lcd; |
| 2872 | } | 3171 | } |
| 2873 | 3172 | ||
| 3173 | static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) | ||
| 3174 | { | ||
| 3175 | enum omap_channel channel = dispc_ovl_get_channel_out(plane); | ||
| 3176 | |||
| 3177 | return dispc_mgr_pclk_rate(channel); | ||
| 3178 | } | ||
| 3179 | |||
| 3180 | static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) | ||
| 3181 | { | ||
| 3182 | enum omap_channel channel = dispc_ovl_get_channel_out(plane); | ||
| 3183 | |||
| 3184 | if (dss_mgr_is_lcd(channel)) | ||
| 3185 | return dispc_mgr_lclk_rate(channel); | ||
| 3186 | else | ||
| 3187 | return dispc_fclk_rate(); | ||
| 3188 | |||
| 3189 | } | ||
| 2874 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) | 3190 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) |
| 2875 | { | 3191 | { |
| 2876 | int lcd, pcd; | 3192 | int lcd, pcd; |
| @@ -3491,7 +3807,7 @@ static void dispc_error_worker(struct work_struct *work) | |||
| 3491 | ovl->name); | 3807 | ovl->name); |
| 3492 | dispc_ovl_enable(ovl->id, false); | 3808 | dispc_ovl_enable(ovl->id, false); |
| 3493 | dispc_mgr_go(ovl->manager->id); | 3809 | dispc_mgr_go(ovl->manager->id); |
| 3494 | mdelay(50); | 3810 | msleep(50); |
| 3495 | } | 3811 | } |
| 3496 | } | 3812 | } |
| 3497 | 3813 | ||
| @@ -3503,7 +3819,7 @@ static void dispc_error_worker(struct work_struct *work) | |||
| 3503 | bit = mgr_desc[i].sync_lost_irq; | 3819 | bit = mgr_desc[i].sync_lost_irq; |
| 3504 | 3820 | ||
| 3505 | if (bit & errors) { | 3821 | if (bit & errors) { |
| 3506 | struct omap_dss_device *dssdev = mgr->device; | 3822 | struct omap_dss_device *dssdev = mgr->get_device(mgr); |
| 3507 | bool enable; | 3823 | bool enable; |
| 3508 | 3824 | ||
| 3509 | DSSERR("SYNC_LOST on channel %s, restarting the output " | 3825 | DSSERR("SYNC_LOST on channel %s, restarting the output " |
| @@ -3523,7 +3839,7 @@ static void dispc_error_worker(struct work_struct *work) | |||
| 3523 | } | 3839 | } |
| 3524 | 3840 | ||
| 3525 | dispc_mgr_go(mgr->id); | 3841 | dispc_mgr_go(mgr->id); |
| 3526 | mdelay(50); | 3842 | msleep(50); |
| 3527 | 3843 | ||
| 3528 | if (enable) | 3844 | if (enable) |
| 3529 | dssdev->driver->enable(dssdev); | 3845 | dssdev->driver->enable(dssdev); |
| @@ -3534,9 +3850,13 @@ static void dispc_error_worker(struct work_struct *work) | |||
| 3534 | DSSERR("OCP_ERR\n"); | 3850 | DSSERR("OCP_ERR\n"); |
| 3535 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { | 3851 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { |
| 3536 | struct omap_overlay_manager *mgr; | 3852 | struct omap_overlay_manager *mgr; |
| 3853 | struct omap_dss_device *dssdev; | ||
| 3854 | |||
| 3537 | mgr = omap_dss_get_overlay_manager(i); | 3855 | mgr = omap_dss_get_overlay_manager(i); |
| 3538 | if (mgr->device && mgr->device->driver) | 3856 | dssdev = mgr->get_device(mgr); |
| 3539 | mgr->device->driver->disable(mgr->device); | 3857 | |
| 3858 | if (dssdev && dssdev->driver) | ||
| 3859 | dssdev->driver->disable(dssdev); | ||
| 3540 | } | 3860 | } |
| 3541 | } | 3861 | } |
| 3542 | 3862 | ||
| @@ -3660,17 +3980,98 @@ static void _omap_dispc_initial_config(void) | |||
| 3660 | if (dss_has_feature(FEAT_FUNCGATED)) | 3980 | if (dss_has_feature(FEAT_FUNCGATED)) |
| 3661 | REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); | 3981 | REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); |
| 3662 | 3982 | ||
| 3663 | _dispc_setup_color_conv_coef(); | 3983 | dispc_setup_color_conv_coef(); |
| 3664 | 3984 | ||
| 3665 | dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); | 3985 | dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); |
| 3666 | 3986 | ||
| 3667 | dispc_read_plane_fifo_sizes(); | 3987 | dispc_init_fifos(); |
| 3668 | 3988 | ||
| 3669 | dispc_configure_burst_sizes(); | 3989 | dispc_configure_burst_sizes(); |
| 3670 | 3990 | ||
| 3671 | dispc_ovl_enable_zorder_planes(); | 3991 | dispc_ovl_enable_zorder_planes(); |
| 3672 | } | 3992 | } |
| 3673 | 3993 | ||
| 3994 | static const struct dispc_features omap24xx_dispc_feats __initconst = { | ||
| 3995 | .sw_start = 5, | ||
| 3996 | .fp_start = 15, | ||
| 3997 | .bp_start = 27, | ||
| 3998 | .sw_max = 64, | ||
| 3999 | .vp_max = 255, | ||
| 4000 | .hp_max = 256, | ||
| 4001 | .calc_scaling = dispc_ovl_calc_scaling_24xx, | ||
| 4002 | .calc_core_clk = calc_core_clk_24xx, | ||
| 4003 | .num_fifos = 3, | ||
| 4004 | }; | ||
| 4005 | |||
| 4006 | static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { | ||
| 4007 | .sw_start = 5, | ||
| 4008 | .fp_start = 15, | ||
| 4009 | .bp_start = 27, | ||
| 4010 | .sw_max = 64, | ||
| 4011 | .vp_max = 255, | ||
| 4012 | .hp_max = 256, | ||
| 4013 | .calc_scaling = dispc_ovl_calc_scaling_34xx, | ||
| 4014 | .calc_core_clk = calc_core_clk_34xx, | ||
| 4015 | .num_fifos = 3, | ||
| 4016 | }; | ||
| 4017 | |||
| 4018 | static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { | ||
| 4019 | .sw_start = 7, | ||
| 4020 | .fp_start = 19, | ||
| 4021 | .bp_start = 31, | ||
| 4022 | .sw_max = 256, | ||
| 4023 | .vp_max = 4095, | ||
| 4024 | .hp_max = 4096, | ||
| 4025 | .calc_scaling = dispc_ovl_calc_scaling_34xx, | ||
| 4026 | .calc_core_clk = calc_core_clk_34xx, | ||
| 4027 | .num_fifos = 3, | ||
| 4028 | }; | ||
| 4029 | |||
| 4030 | static const struct dispc_features omap44xx_dispc_feats __initconst = { | ||
| 4031 | .sw_start = 7, | ||
| 4032 | .fp_start = 19, | ||
| 4033 | .bp_start = 31, | ||
| 4034 | .sw_max = 256, | ||
| 4035 | .vp_max = 4095, | ||
| 4036 | .hp_max = 4096, | ||
| 4037 | .calc_scaling = dispc_ovl_calc_scaling_44xx, | ||
| 4038 | .calc_core_clk = calc_core_clk_44xx, | ||
| 4039 | .num_fifos = 5, | ||
| 4040 | .gfx_fifo_workaround = true, | ||
| 4041 | }; | ||
| 4042 | |||
| 4043 | static int __init dispc_init_features(struct device *dev) | ||
| 4044 | { | ||
| 4045 | const struct dispc_features *src; | ||
| 4046 | struct dispc_features *dst; | ||
| 4047 | |||
| 4048 | dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL); | ||
| 4049 | if (!dst) { | ||
| 4050 | dev_err(dev, "Failed to allocate DISPC Features\n"); | ||
| 4051 | return -ENOMEM; | ||
| 4052 | } | ||
| 4053 | |||
| 4054 | if (cpu_is_omap24xx()) { | ||
| 4055 | src = &omap24xx_dispc_feats; | ||
| 4056 | } else if (cpu_is_omap34xx()) { | ||
| 4057 | if (omap_rev() < OMAP3430_REV_ES3_0) | ||
| 4058 | src = &omap34xx_rev1_0_dispc_feats; | ||
| 4059 | else | ||
| 4060 | src = &omap34xx_rev3_0_dispc_feats; | ||
| 4061 | } else if (cpu_is_omap44xx()) { | ||
| 4062 | src = &omap44xx_dispc_feats; | ||
| 4063 | } else if (soc_is_omap54xx()) { | ||
| 4064 | src = &omap44xx_dispc_feats; | ||
| 4065 | } else { | ||
| 4066 | return -ENODEV; | ||
| 4067 | } | ||
| 4068 | |||
| 4069 | memcpy(dst, src, sizeof(*dst)); | ||
| 4070 | dispc.feat = dst; | ||
| 4071 | |||
| 4072 | return 0; | ||
| 4073 | } | ||
| 4074 | |||
| 3674 | /* DISPC HW IP initialisation */ | 4075 | /* DISPC HW IP initialisation */ |
| 3675 | static int __init omap_dispchw_probe(struct platform_device *pdev) | 4076 | static int __init omap_dispchw_probe(struct platform_device *pdev) |
| 3676 | { | 4077 | { |
| @@ -3681,6 +4082,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) | |||
| 3681 | 4082 | ||
| 3682 | dispc.pdev = pdev; | 4083 | dispc.pdev = pdev; |
| 3683 | 4084 | ||
| 4085 | r = dispc_init_features(&dispc.pdev->dev); | ||
| 4086 | if (r) | ||
| 4087 | return r; | ||
| 4088 | |||
| 3684 | spin_lock_init(&dispc.irq_lock); | 4089 | spin_lock_init(&dispc.irq_lock); |
| 3685 | 4090 | ||
| 3686 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 4091 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index 92d8a9be86fc..222363c6e623 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #define DISPC_CONTROL2 0x0238 | 36 | #define DISPC_CONTROL2 0x0238 |
| 37 | #define DISPC_CONFIG2 0x0620 | 37 | #define DISPC_CONFIG2 0x0620 |
| 38 | #define DISPC_DIVISOR 0x0804 | 38 | #define DISPC_DIVISOR 0x0804 |
| 39 | #define DISPC_GLOBAL_BUFFER 0x0800 | ||
| 39 | #define DISPC_CONTROL3 0x0848 | 40 | #define DISPC_CONTROL3 0x0848 |
| 40 | #define DISPC_CONFIG3 0x084C | 41 | #define DISPC_CONFIG3 0x084C |
| 41 | 42 | ||
| @@ -355,6 +356,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane) | |||
| 355 | return 0x014C; | 356 | return 0x014C; |
| 356 | case OMAP_DSS_VIDEO3: | 357 | case OMAP_DSS_VIDEO3: |
| 357 | return 0x0300; | 358 | return 0x0300; |
| 359 | case OMAP_DSS_WB: | ||
| 360 | return 0x0500; | ||
| 358 | default: | 361 | default: |
| 359 | BUG(); | 362 | BUG(); |
| 360 | return 0; | 363 | return 0; |
| @@ -370,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) | |||
| 370 | case OMAP_DSS_VIDEO2: | 373 | case OMAP_DSS_VIDEO2: |
| 371 | return 0x0000; | 374 | return 0x0000; |
| 372 | case OMAP_DSS_VIDEO3: | 375 | case OMAP_DSS_VIDEO3: |
| 376 | case OMAP_DSS_WB: | ||
| 373 | return 0x0008; | 377 | return 0x0008; |
| 374 | default: | 378 | default: |
| 375 | BUG(); | 379 | BUG(); |
| @@ -385,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) | |||
| 385 | case OMAP_DSS_VIDEO2: | 389 | case OMAP_DSS_VIDEO2: |
| 386 | return 0x0004; | 390 | return 0x0004; |
| 387 | case OMAP_DSS_VIDEO3: | 391 | case OMAP_DSS_VIDEO3: |
| 392 | case OMAP_DSS_WB: | ||
| 388 | return 0x000C; | 393 | return 0x000C; |
| 389 | default: | 394 | default: |
| 390 | BUG(); | 395 | BUG(); |
| @@ -404,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) | |||
| 404 | return 0x04BC; | 409 | return 0x04BC; |
| 405 | case OMAP_DSS_VIDEO3: | 410 | case OMAP_DSS_VIDEO3: |
| 406 | return 0x0310; | 411 | return 0x0310; |
| 412 | case OMAP_DSS_WB: | ||
| 413 | return 0x0118; | ||
| 407 | default: | 414 | default: |
| 408 | BUG(); | 415 | BUG(); |
| 409 | return 0; | 416 | return 0; |
| @@ -422,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) | |||
| 422 | return 0x04C0; | 429 | return 0x04C0; |
| 423 | case OMAP_DSS_VIDEO3: | 430 | case OMAP_DSS_VIDEO3: |
| 424 | return 0x0314; | 431 | return 0x0314; |
| 432 | case OMAP_DSS_WB: | ||
| 433 | return 0x011C; | ||
| 425 | default: | 434 | default: |
| 426 | BUG(); | 435 | BUG(); |
| 427 | return 0; | 436 | return 0; |
| @@ -451,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) | |||
| 451 | case OMAP_DSS_VIDEO2: | 460 | case OMAP_DSS_VIDEO2: |
| 452 | return 0x000C; | 461 | return 0x000C; |
| 453 | case OMAP_DSS_VIDEO3: | 462 | case OMAP_DSS_VIDEO3: |
| 463 | case OMAP_DSS_WB: | ||
| 454 | return 0x00A8; | 464 | return 0x00A8; |
| 455 | default: | 465 | default: |
| 456 | BUG(); | 466 | BUG(); |
| @@ -467,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) | |||
| 467 | case OMAP_DSS_VIDEO2: | 477 | case OMAP_DSS_VIDEO2: |
| 468 | return 0x0010; | 478 | return 0x0010; |
| 469 | case OMAP_DSS_VIDEO3: | 479 | case OMAP_DSS_VIDEO3: |
| 480 | case OMAP_DSS_WB: | ||
| 470 | return 0x0070; | 481 | return 0x0070; |
| 471 | default: | 482 | default: |
| 472 | BUG(); | 483 | BUG(); |
| @@ -486,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) | |||
| 486 | return 0x04DC; | 497 | return 0x04DC; |
| 487 | case OMAP_DSS_VIDEO3: | 498 | case OMAP_DSS_VIDEO3: |
| 488 | return 0x032C; | 499 | return 0x032C; |
| 500 | case OMAP_DSS_WB: | ||
| 501 | return 0x0310; | ||
| 489 | default: | 502 | default: |
| 490 | BUG(); | 503 | BUG(); |
| 491 | return 0; | 504 | return 0; |
| @@ -501,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) | |||
| 501 | case OMAP_DSS_VIDEO2: | 514 | case OMAP_DSS_VIDEO2: |
| 502 | return 0x0014; | 515 | return 0x0014; |
| 503 | case OMAP_DSS_VIDEO3: | 516 | case OMAP_DSS_VIDEO3: |
| 517 | case OMAP_DSS_WB: | ||
| 504 | return 0x008C; | 518 | return 0x008C; |
| 505 | default: | 519 | default: |
| 506 | BUG(); | 520 | BUG(); |
| @@ -517,6 +531,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane) | |||
| 517 | case OMAP_DSS_VIDEO2: | 531 | case OMAP_DSS_VIDEO2: |
| 518 | return 0x0018; | 532 | return 0x0018; |
| 519 | case OMAP_DSS_VIDEO3: | 533 | case OMAP_DSS_VIDEO3: |
| 534 | case OMAP_DSS_WB: | ||
| 520 | return 0x0088; | 535 | return 0x0088; |
| 521 | default: | 536 | default: |
| 522 | BUG(); | 537 | BUG(); |
| @@ -533,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) | |||
| 533 | case OMAP_DSS_VIDEO2: | 548 | case OMAP_DSS_VIDEO2: |
| 534 | return 0x001C; | 549 | return 0x001C; |
| 535 | case OMAP_DSS_VIDEO3: | 550 | case OMAP_DSS_VIDEO3: |
| 551 | case OMAP_DSS_WB: | ||
| 536 | return 0x00A4; | 552 | return 0x00A4; |
| 537 | default: | 553 | default: |
| 538 | BUG(); | 554 | BUG(); |
| @@ -549,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) | |||
| 549 | case OMAP_DSS_VIDEO2: | 565 | case OMAP_DSS_VIDEO2: |
| 550 | return 0x0020; | 566 | return 0x0020; |
| 551 | case OMAP_DSS_VIDEO3: | 567 | case OMAP_DSS_VIDEO3: |
| 568 | case OMAP_DSS_WB: | ||
| 552 | return 0x0098; | 569 | return 0x0098; |
| 553 | default: | 570 | default: |
| 554 | BUG(); | 571 | BUG(); |
| @@ -598,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) | |||
| 598 | case OMAP_DSS_VIDEO2: | 615 | case OMAP_DSS_VIDEO2: |
| 599 | return 0x0024; | 616 | return 0x0024; |
| 600 | case OMAP_DSS_VIDEO3: | 617 | case OMAP_DSS_VIDEO3: |
| 618 | case OMAP_DSS_WB: | ||
| 601 | return 0x0090; | 619 | return 0x0090; |
| 602 | default: | 620 | default: |
| 603 | BUG(); | 621 | BUG(); |
| @@ -617,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) | |||
| 617 | return 0x055C; | 635 | return 0x055C; |
| 618 | case OMAP_DSS_VIDEO3: | 636 | case OMAP_DSS_VIDEO3: |
| 619 | return 0x0424; | 637 | return 0x0424; |
| 638 | case OMAP_DSS_WB: | ||
| 639 | return 0x290; | ||
| 620 | default: | 640 | default: |
| 621 | BUG(); | 641 | BUG(); |
| 622 | return 0; | 642 | return 0; |
| @@ -633,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) | |||
| 633 | case OMAP_DSS_VIDEO2: | 653 | case OMAP_DSS_VIDEO2: |
| 634 | return 0x0028; | 654 | return 0x0028; |
| 635 | case OMAP_DSS_VIDEO3: | 655 | case OMAP_DSS_VIDEO3: |
| 656 | case OMAP_DSS_WB: | ||
| 636 | return 0x0094; | 657 | return 0x0094; |
| 637 | default: | 658 | default: |
| 638 | BUG(); | 659 | BUG(); |
| @@ -651,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) | |||
| 651 | case OMAP_DSS_VIDEO2: | 672 | case OMAP_DSS_VIDEO2: |
| 652 | return 0x002C; | 673 | return 0x002C; |
| 653 | case OMAP_DSS_VIDEO3: | 674 | case OMAP_DSS_VIDEO3: |
| 675 | case OMAP_DSS_WB: | ||
| 654 | return 0x0000; | 676 | return 0x0000; |
| 655 | default: | 677 | default: |
| 656 | BUG(); | 678 | BUG(); |
| @@ -670,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) | |||
| 670 | return 0x0560; | 692 | return 0x0560; |
| 671 | case OMAP_DSS_VIDEO3: | 693 | case OMAP_DSS_VIDEO3: |
| 672 | return 0x0428; | 694 | return 0x0428; |
| 695 | case OMAP_DSS_WB: | ||
| 696 | return 0x0294; | ||
| 673 | default: | 697 | default: |
| 674 | BUG(); | 698 | BUG(); |
| 675 | return 0; | 699 | return 0; |
| @@ -686,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) | |||
| 686 | case OMAP_DSS_VIDEO2: | 710 | case OMAP_DSS_VIDEO2: |
| 687 | return 0x0030; | 711 | return 0x0030; |
| 688 | case OMAP_DSS_VIDEO3: | 712 | case OMAP_DSS_VIDEO3: |
| 713 | case OMAP_DSS_WB: | ||
| 689 | return 0x0004; | 714 | return 0x0004; |
| 690 | default: | 715 | default: |
| 691 | BUG(); | 716 | BUG(); |
| @@ -705,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) | |||
| 705 | return 0x0564; | 730 | return 0x0564; |
| 706 | case OMAP_DSS_VIDEO3: | 731 | case OMAP_DSS_VIDEO3: |
| 707 | return 0x042C; | 732 | return 0x042C; |
| 733 | case OMAP_DSS_WB: | ||
| 734 | return 0x0298; | ||
| 708 | default: | 735 | default: |
| 709 | BUG(); | 736 | BUG(); |
| 710 | return 0; | 737 | return 0; |
| @@ -722,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) | |||
| 722 | case OMAP_DSS_VIDEO2: | 749 | case OMAP_DSS_VIDEO2: |
| 723 | return 0x0034 + i * 0x8; | 750 | return 0x0034 + i * 0x8; |
| 724 | case OMAP_DSS_VIDEO3: | 751 | case OMAP_DSS_VIDEO3: |
| 752 | case OMAP_DSS_WB: | ||
| 725 | return 0x0010 + i * 0x8; | 753 | return 0x0010 + i * 0x8; |
| 726 | default: | 754 | default: |
| 727 | BUG(); | 755 | BUG(); |
| @@ -742,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) | |||
| 742 | return 0x0568 + i * 0x8; | 770 | return 0x0568 + i * 0x8; |
| 743 | case OMAP_DSS_VIDEO3: | 771 | case OMAP_DSS_VIDEO3: |
| 744 | return 0x0430 + i * 0x8; | 772 | return 0x0430 + i * 0x8; |
| 773 | case OMAP_DSS_WB: | ||
| 774 | return 0x02A0 + i * 0x8; | ||
| 745 | default: | 775 | default: |
| 746 | BUG(); | 776 | BUG(); |
| 747 | return 0; | 777 | return 0; |
| @@ -759,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) | |||
| 759 | case OMAP_DSS_VIDEO2: | 789 | case OMAP_DSS_VIDEO2: |
| 760 | return 0x0038 + i * 0x8; | 790 | return 0x0038 + i * 0x8; |
| 761 | case OMAP_DSS_VIDEO3: | 791 | case OMAP_DSS_VIDEO3: |
| 792 | case OMAP_DSS_WB: | ||
| 762 | return 0x0014 + i * 0x8; | 793 | return 0x0014 + i * 0x8; |
| 763 | default: | 794 | default: |
| 764 | BUG(); | 795 | BUG(); |
| @@ -779,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) | |||
| 779 | return 0x056C + i * 0x8; | 810 | return 0x056C + i * 0x8; |
| 780 | case OMAP_DSS_VIDEO3: | 811 | case OMAP_DSS_VIDEO3: |
| 781 | return 0x0434 + i * 0x8; | 812 | return 0x0434 + i * 0x8; |
| 813 | case OMAP_DSS_WB: | ||
| 814 | return 0x02A4 + i * 0x8; | ||
| 782 | default: | 815 | default: |
| 783 | BUG(); | 816 | BUG(); |
| 784 | return 0; | 817 | return 0; |
| @@ -795,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) | |||
| 795 | case OMAP_DSS_VIDEO1: | 828 | case OMAP_DSS_VIDEO1: |
| 796 | case OMAP_DSS_VIDEO2: | 829 | case OMAP_DSS_VIDEO2: |
| 797 | case OMAP_DSS_VIDEO3: | 830 | case OMAP_DSS_VIDEO3: |
| 831 | case OMAP_DSS_WB: | ||
| 798 | return 0x0074 + i * 0x4; | 832 | return 0x0074 + i * 0x4; |
| 799 | default: | 833 | default: |
| 800 | BUG(); | 834 | BUG(); |
| @@ -814,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) | |||
| 814 | case OMAP_DSS_VIDEO2: | 848 | case OMAP_DSS_VIDEO2: |
| 815 | return 0x00B4 + i * 0x4; | 849 | return 0x00B4 + i * 0x4; |
| 816 | case OMAP_DSS_VIDEO3: | 850 | case OMAP_DSS_VIDEO3: |
| 851 | case OMAP_DSS_WB: | ||
| 817 | return 0x0050 + i * 0x4; | 852 | return 0x0050 + i * 0x4; |
| 818 | default: | 853 | default: |
| 819 | BUG(); | 854 | BUG(); |
| @@ -834,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) | |||
| 834 | return 0x05A8 + i * 0x4; | 869 | return 0x05A8 + i * 0x4; |
| 835 | case OMAP_DSS_VIDEO3: | 870 | case OMAP_DSS_VIDEO3: |
| 836 | return 0x0470 + i * 0x4; | 871 | return 0x0470 + i * 0x4; |
| 872 | case OMAP_DSS_WB: | ||
| 873 | return 0x02E0 + i * 0x4; | ||
| 837 | default: | 874 | default: |
| 838 | BUG(); | 875 | BUG(); |
| 839 | return 0; | 876 | return 0; |
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 5bd957e85505..ccf8550fafde 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c | |||
| @@ -142,7 +142,11 @@ static ssize_t display_timings_store(struct device *dev, | |||
| 142 | if (r) | 142 | if (r) |
| 143 | return r; | 143 | return r; |
| 144 | 144 | ||
| 145 | dssdev->driver->disable(dssdev); | ||
| 145 | dssdev->driver->set_timings(dssdev, &t); | 146 | dssdev->driver->set_timings(dssdev, &t); |
| 147 | r = dssdev->driver->enable(dssdev); | ||
| 148 | if (r) | ||
| 149 | return r; | ||
| 146 | 150 | ||
| 147 | return size; | 151 | return size; |
| 148 | } | 152 | } |
| @@ -316,26 +320,117 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev, | |||
| 316 | } | 320 | } |
| 317 | EXPORT_SYMBOL(omapdss_default_get_timings); | 321 | EXPORT_SYMBOL(omapdss_default_get_timings); |
| 318 | 322 | ||
| 319 | void dss_init_device(struct platform_device *pdev, | 323 | /* |
| 324 | * Connect dssdev to a manager if the manager is free or if force is specified. | ||
| 325 | * Connect all overlays to that manager if they are free or if force is | ||
| 326 | * specified. | ||
| 327 | */ | ||
| 328 | static int dss_init_connections(struct omap_dss_device *dssdev, bool force) | ||
| 329 | { | ||
| 330 | struct omap_dss_output *out; | ||
| 331 | struct omap_overlay_manager *mgr; | ||
| 332 | int i, r; | ||
| 333 | |||
| 334 | out = omapdss_get_output_from_dssdev(dssdev); | ||
| 335 | |||
| 336 | WARN_ON(dssdev->output); | ||
| 337 | WARN_ON(out->device); | ||
| 338 | |||
| 339 | r = omapdss_output_set_device(out, dssdev); | ||
| 340 | if (r) { | ||
| 341 | DSSERR("failed to connect output to new device\n"); | ||
| 342 | return r; | ||
| 343 | } | ||
| 344 | |||
| 345 | mgr = omap_dss_get_overlay_manager(dssdev->channel); | ||
| 346 | |||
| 347 | if (mgr->output && !force) | ||
| 348 | return 0; | ||
| 349 | |||
| 350 | if (mgr->output) | ||
| 351 | mgr->unset_output(mgr); | ||
| 352 | |||
| 353 | r = mgr->set_output(mgr, out); | ||
| 354 | if (r) { | ||
| 355 | DSSERR("failed to connect manager to output of new device\n"); | ||
| 356 | |||
| 357 | /* remove the output-device connection we just made */ | ||
| 358 | omapdss_output_unset_device(out); | ||
| 359 | return r; | ||
| 360 | } | ||
| 361 | |||
| 362 | for (i = 0; i < omap_dss_get_num_overlays(); ++i) { | ||
| 363 | struct omap_overlay *ovl = omap_dss_get_overlay(i); | ||
| 364 | |||
| 365 | if (!ovl->manager || force) { | ||
| 366 | if (ovl->manager) | ||
| 367 | ovl->unset_manager(ovl); | ||
| 368 | |||
| 369 | r = ovl->set_manager(ovl, mgr); | ||
| 370 | if (r) { | ||
| 371 | DSSERR("failed to set initial overlay\n"); | ||
| 372 | return r; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | return 0; | ||
| 378 | } | ||
| 379 | |||
| 380 | static void dss_uninit_connections(struct omap_dss_device *dssdev) | ||
| 381 | { | ||
| 382 | if (dssdev->output) { | ||
| 383 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 384 | |||
| 385 | if (mgr) | ||
| 386 | mgr->unset_output(mgr); | ||
| 387 | |||
| 388 | omapdss_output_unset_device(dssdev->output); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | int dss_init_device(struct platform_device *pdev, | ||
| 320 | struct omap_dss_device *dssdev) | 393 | struct omap_dss_device *dssdev) |
| 321 | { | 394 | { |
| 322 | struct device_attribute *attr; | 395 | struct device_attribute *attr; |
| 323 | int i; | 396 | int i, r; |
| 324 | int r; | 397 | const char *def_disp_name = dss_get_default_display_name(); |
| 398 | bool force; | ||
| 399 | |||
| 400 | force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0; | ||
| 401 | dss_init_connections(dssdev, force); | ||
| 325 | 402 | ||
| 326 | /* create device sysfs files */ | 403 | /* create device sysfs files */ |
| 327 | i = 0; | 404 | i = 0; |
| 328 | while ((attr = display_sysfs_attrs[i++]) != NULL) { | 405 | while ((attr = display_sysfs_attrs[i++]) != NULL) { |
| 329 | r = device_create_file(&dssdev->dev, attr); | 406 | r = device_create_file(&dssdev->dev, attr); |
| 330 | if (r) | 407 | if (r) { |
| 408 | for (i = i - 2; i >= 0; i--) { | ||
| 409 | attr = display_sysfs_attrs[i]; | ||
| 410 | device_remove_file(&dssdev->dev, attr); | ||
| 411 | } | ||
| 412 | |||
| 413 | dss_uninit_connections(dssdev); | ||
| 414 | |||
| 331 | DSSERR("failed to create sysfs file\n"); | 415 | DSSERR("failed to create sysfs file\n"); |
| 416 | return r; | ||
| 417 | } | ||
| 332 | } | 418 | } |
| 333 | 419 | ||
| 334 | /* create display? sysfs links */ | 420 | /* create display? sysfs links */ |
| 335 | r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj, | 421 | r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj, |
| 336 | dev_name(&dssdev->dev)); | 422 | dev_name(&dssdev->dev)); |
| 337 | if (r) | 423 | if (r) { |
| 424 | while ((attr = display_sysfs_attrs[i++]) != NULL) | ||
| 425 | device_remove_file(&dssdev->dev, attr); | ||
| 426 | |||
| 427 | dss_uninit_connections(dssdev); | ||
| 428 | |||
| 338 | DSSERR("failed to create sysfs display link\n"); | 429 | DSSERR("failed to create sysfs display link\n"); |
| 430 | return r; | ||
| 431 | } | ||
| 432 | |||
| 433 | return 0; | ||
| 339 | } | 434 | } |
| 340 | 435 | ||
| 341 | void dss_uninit_device(struct platform_device *pdev, | 436 | void dss_uninit_device(struct platform_device *pdev, |
| @@ -349,8 +444,7 @@ void dss_uninit_device(struct platform_device *pdev, | |||
| 349 | while ((attr = display_sysfs_attrs[i++]) != NULL) | 444 | while ((attr = display_sysfs_attrs[i++]) != NULL) |
| 350 | device_remove_file(&dssdev->dev, attr); | 445 | device_remove_file(&dssdev->dev, attr); |
| 351 | 446 | ||
| 352 | if (dssdev->manager) | 447 | dss_uninit_connections(dssdev); |
| 353 | dssdev->manager->unset_device(dssdev->manager); | ||
| 354 | } | 448 | } |
| 355 | 449 | ||
| 356 | static int dss_suspend_device(struct device *dev, void *data) | 450 | static int dss_suspend_device(struct device *dev, void *data) |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 3266be23fc0d..56748cf8760e 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
| @@ -29,17 +29,24 @@ | |||
| 29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
| 30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
| 31 | #include <linux/regulator/consumer.h> | 31 | #include <linux/regulator/consumer.h> |
| 32 | #include <linux/string.h> | ||
| 32 | 33 | ||
| 33 | #include <video/omapdss.h> | 34 | #include <video/omapdss.h> |
| 34 | #include <plat/cpu.h> | ||
| 35 | 35 | ||
| 36 | #include "dss.h" | 36 | #include "dss.h" |
| 37 | #include "dss_features.h" | ||
| 37 | 38 | ||
| 38 | static struct { | 39 | static struct { |
| 39 | struct regulator *vdds_dsi_reg; | 40 | struct regulator *vdds_dsi_reg; |
| 40 | struct platform_device *dsidev; | 41 | struct platform_device *dsidev; |
| 41 | 42 | ||
| 43 | struct mutex lock; | ||
| 44 | |||
| 45 | struct omap_video_timings timings; | ||
| 42 | struct dss_lcd_mgr_config mgr_config; | 46 | struct dss_lcd_mgr_config mgr_config; |
| 47 | int data_lines; | ||
| 48 | |||
| 49 | struct omap_dss_output output; | ||
| 43 | } dpi; | 50 | } dpi; |
| 44 | 51 | ||
| 45 | static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) | 52 | static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) |
| @@ -121,7 +128,8 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, | |||
| 121 | 128 | ||
| 122 | static int dpi_set_mode(struct omap_dss_device *dssdev) | 129 | static int dpi_set_mode(struct omap_dss_device *dssdev) |
| 123 | { | 130 | { |
| 124 | struct omap_video_timings *t = &dssdev->panel.timings; | 131 | struct omap_video_timings *t = &dpi.timings; |
| 132 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 125 | int lck_div = 0, pck_div = 0; | 133 | int lck_div = 0, pck_div = 0; |
| 126 | unsigned long fck = 0; | 134 | unsigned long fck = 0; |
| 127 | unsigned long pck; | 135 | unsigned long pck; |
| @@ -146,37 +154,44 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) | |||
| 146 | t->pixel_clock = pck; | 154 | t->pixel_clock = pck; |
| 147 | } | 155 | } |
| 148 | 156 | ||
| 149 | dss_mgr_set_timings(dssdev->manager, t); | 157 | dss_mgr_set_timings(mgr, t); |
| 150 | 158 | ||
| 151 | return 0; | 159 | return 0; |
| 152 | } | 160 | } |
| 153 | 161 | ||
| 154 | static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) | 162 | static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) |
| 155 | { | 163 | { |
| 164 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 165 | |||
| 156 | dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; | 166 | dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; |
| 157 | 167 | ||
| 158 | dpi.mgr_config.stallmode = false; | 168 | dpi.mgr_config.stallmode = false; |
| 159 | dpi.mgr_config.fifohandcheck = false; | 169 | dpi.mgr_config.fifohandcheck = false; |
| 160 | 170 | ||
| 161 | dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines; | 171 | dpi.mgr_config.video_port_width = dpi.data_lines; |
| 162 | 172 | ||
| 163 | dpi.mgr_config.lcden_sig_polarity = 0; | 173 | dpi.mgr_config.lcden_sig_polarity = 0; |
| 164 | 174 | ||
| 165 | dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config); | 175 | dss_mgr_set_lcd_config(mgr, &dpi.mgr_config); |
| 166 | } | 176 | } |
| 167 | 177 | ||
| 168 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | 178 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) |
| 169 | { | 179 | { |
| 180 | struct omap_dss_output *out = dssdev->output; | ||
| 170 | int r; | 181 | int r; |
| 171 | 182 | ||
| 172 | if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) { | 183 | mutex_lock(&dpi.lock); |
| 184 | |||
| 185 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) { | ||
| 173 | DSSERR("no VDSS_DSI regulator\n"); | 186 | DSSERR("no VDSS_DSI regulator\n"); |
| 174 | return -ENODEV; | 187 | r = -ENODEV; |
| 188 | goto err_no_reg; | ||
| 175 | } | 189 | } |
| 176 | 190 | ||
| 177 | if (dssdev->manager == NULL) { | 191 | if (out == NULL || out->manager == NULL) { |
| 178 | DSSERR("failed to enable display: no manager\n"); | 192 | DSSERR("failed to enable display: no output/manager\n"); |
| 179 | return -ENODEV; | 193 | r = -ENODEV; |
| 194 | goto err_no_out_mgr; | ||
| 180 | } | 195 | } |
| 181 | 196 | ||
| 182 | r = omap_dss_start_device(dssdev); | 197 | r = omap_dss_start_device(dssdev); |
| @@ -185,7 +200,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
| 185 | goto err_start_dev; | 200 | goto err_start_dev; |
| 186 | } | 201 | } |
| 187 | 202 | ||
| 188 | if (cpu_is_omap34xx()) { | 203 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { |
| 189 | r = regulator_enable(dpi.vdds_dsi_reg); | 204 | r = regulator_enable(dpi.vdds_dsi_reg); |
| 190 | if (r) | 205 | if (r) |
| 191 | goto err_reg_enable; | 206 | goto err_reg_enable; |
| @@ -195,6 +210,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
| 195 | if (r) | 210 | if (r) |
| 196 | goto err_get_dispc; | 211 | goto err_get_dispc; |
| 197 | 212 | ||
| 213 | r = dss_dpi_select_source(dssdev->channel); | ||
| 214 | if (r) | ||
| 215 | goto err_src_sel; | ||
| 216 | |||
| 198 | if (dpi_use_dsi_pll(dssdev)) { | 217 | if (dpi_use_dsi_pll(dssdev)) { |
| 199 | r = dsi_runtime_get(dpi.dsidev); | 218 | r = dsi_runtime_get(dpi.dsidev); |
| 200 | if (r) | 219 | if (r) |
| @@ -213,10 +232,12 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
| 213 | 232 | ||
| 214 | mdelay(2); | 233 | mdelay(2); |
| 215 | 234 | ||
| 216 | r = dss_mgr_enable(dssdev->manager); | 235 | r = dss_mgr_enable(out->manager); |
| 217 | if (r) | 236 | if (r) |
| 218 | goto err_mgr_enable; | 237 | goto err_mgr_enable; |
| 219 | 238 | ||
| 239 | mutex_unlock(&dpi.lock); | ||
| 240 | |||
| 220 | return 0; | 241 | return 0; |
| 221 | 242 | ||
| 222 | err_mgr_enable: | 243 | err_mgr_enable: |
| @@ -227,20 +248,28 @@ err_dsi_pll_init: | |||
| 227 | if (dpi_use_dsi_pll(dssdev)) | 248 | if (dpi_use_dsi_pll(dssdev)) |
| 228 | dsi_runtime_put(dpi.dsidev); | 249 | dsi_runtime_put(dpi.dsidev); |
| 229 | err_get_dsi: | 250 | err_get_dsi: |
| 251 | err_src_sel: | ||
| 230 | dispc_runtime_put(); | 252 | dispc_runtime_put(); |
| 231 | err_get_dispc: | 253 | err_get_dispc: |
| 232 | if (cpu_is_omap34xx()) | 254 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) |
| 233 | regulator_disable(dpi.vdds_dsi_reg); | 255 | regulator_disable(dpi.vdds_dsi_reg); |
| 234 | err_reg_enable: | 256 | err_reg_enable: |
| 235 | omap_dss_stop_device(dssdev); | 257 | omap_dss_stop_device(dssdev); |
| 236 | err_start_dev: | 258 | err_start_dev: |
| 259 | err_no_out_mgr: | ||
| 260 | err_no_reg: | ||
| 261 | mutex_unlock(&dpi.lock); | ||
| 237 | return r; | 262 | return r; |
| 238 | } | 263 | } |
| 239 | EXPORT_SYMBOL(omapdss_dpi_display_enable); | 264 | EXPORT_SYMBOL(omapdss_dpi_display_enable); |
| 240 | 265 | ||
| 241 | void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) | 266 | void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) |
| 242 | { | 267 | { |
| 243 | dss_mgr_disable(dssdev->manager); | 268 | struct omap_overlay_manager *mgr = dssdev->output->manager; |
| 269 | |||
| 270 | mutex_lock(&dpi.lock); | ||
| 271 | |||
| 272 | dss_mgr_disable(mgr); | ||
| 244 | 273 | ||
| 245 | if (dpi_use_dsi_pll(dssdev)) { | 274 | if (dpi_use_dsi_pll(dssdev)) { |
| 246 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 275 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
| @@ -250,44 +279,39 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) | |||
| 250 | 279 | ||
| 251 | dispc_runtime_put(); | 280 | dispc_runtime_put(); |
| 252 | 281 | ||
| 253 | if (cpu_is_omap34xx()) | 282 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) |
| 254 | regulator_disable(dpi.vdds_dsi_reg); | 283 | regulator_disable(dpi.vdds_dsi_reg); |
| 255 | 284 | ||
| 256 | omap_dss_stop_device(dssdev); | 285 | omap_dss_stop_device(dssdev); |
| 286 | |||
| 287 | mutex_unlock(&dpi.lock); | ||
| 257 | } | 288 | } |
| 258 | EXPORT_SYMBOL(omapdss_dpi_display_disable); | 289 | EXPORT_SYMBOL(omapdss_dpi_display_disable); |
| 259 | 290 | ||
| 260 | void dpi_set_timings(struct omap_dss_device *dssdev, | 291 | void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, |
| 261 | struct omap_video_timings *timings) | 292 | struct omap_video_timings *timings) |
| 262 | { | 293 | { |
| 263 | int r; | ||
| 264 | |||
| 265 | DSSDBG("dpi_set_timings\n"); | 294 | DSSDBG("dpi_set_timings\n"); |
| 266 | dssdev->panel.timings = *timings; | ||
| 267 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | ||
| 268 | r = dispc_runtime_get(); | ||
| 269 | if (r) | ||
| 270 | return; | ||
| 271 | 295 | ||
| 272 | dpi_set_mode(dssdev); | 296 | mutex_lock(&dpi.lock); |
| 273 | 297 | ||
| 274 | dispc_runtime_put(); | 298 | dpi.timings = *timings; |
| 275 | } else { | 299 | |
| 276 | dss_mgr_set_timings(dssdev->manager, timings); | 300 | mutex_unlock(&dpi.lock); |
| 277 | } | ||
| 278 | } | 301 | } |
| 279 | EXPORT_SYMBOL(dpi_set_timings); | 302 | EXPORT_SYMBOL(omapdss_dpi_set_timings); |
| 280 | 303 | ||
| 281 | int dpi_check_timings(struct omap_dss_device *dssdev, | 304 | int dpi_check_timings(struct omap_dss_device *dssdev, |
| 282 | struct omap_video_timings *timings) | 305 | struct omap_video_timings *timings) |
| 283 | { | 306 | { |
| 284 | int r; | 307 | int r; |
| 308 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 285 | int lck_div, pck_div; | 309 | int lck_div, pck_div; |
| 286 | unsigned long fck; | 310 | unsigned long fck; |
| 287 | unsigned long pck; | 311 | unsigned long pck; |
| 288 | struct dispc_clock_info dispc_cinfo; | 312 | struct dispc_clock_info dispc_cinfo; |
| 289 | 313 | ||
| 290 | if (dss_mgr_check_timings(dssdev->manager, timings)) | 314 | if (dss_mgr_check_timings(mgr, timings)) |
| 291 | return -EINVAL; | 315 | return -EINVAL; |
| 292 | 316 | ||
| 293 | if (timings->pixel_clock == 0) | 317 | if (timings->pixel_clock == 0) |
| @@ -325,11 +349,22 @@ int dpi_check_timings(struct omap_dss_device *dssdev, | |||
| 325 | } | 349 | } |
| 326 | EXPORT_SYMBOL(dpi_check_timings); | 350 | EXPORT_SYMBOL(dpi_check_timings); |
| 327 | 351 | ||
| 352 | void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | ||
| 353 | { | ||
| 354 | mutex_lock(&dpi.lock); | ||
| 355 | |||
| 356 | dpi.data_lines = data_lines; | ||
| 357 | |||
| 358 | mutex_unlock(&dpi.lock); | ||
| 359 | } | ||
| 360 | EXPORT_SYMBOL(omapdss_dpi_set_data_lines); | ||
| 361 | |||
| 328 | static int __init dpi_init_display(struct omap_dss_device *dssdev) | 362 | static int __init dpi_init_display(struct omap_dss_device *dssdev) |
| 329 | { | 363 | { |
| 330 | DSSDBG("init_display\n"); | 364 | DSSDBG("init_display\n"); |
| 331 | 365 | ||
| 332 | if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) { | 366 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && |
| 367 | dpi.vdds_dsi_reg == NULL) { | ||
| 333 | struct regulator *vdds_dsi; | 368 | struct regulator *vdds_dsi; |
| 334 | 369 | ||
| 335 | vdds_dsi = dss_get_vdds_dsi(); | 370 | vdds_dsi = dss_get_vdds_dsi(); |
| @@ -351,10 +386,14 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev) | |||
| 351 | return 0; | 386 | return 0; |
| 352 | } | 387 | } |
| 353 | 388 | ||
| 354 | static void __init dpi_probe_pdata(struct platform_device *pdev) | 389 | static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev) |
| 355 | { | 390 | { |
| 356 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | 391 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
| 357 | int i, r; | 392 | const char *def_disp_name = dss_get_default_display_name(); |
| 393 | struct omap_dss_device *def_dssdev; | ||
| 394 | int i; | ||
| 395 | |||
| 396 | def_dssdev = NULL; | ||
| 358 | 397 | ||
| 359 | for (i = 0; i < pdata->num_devices; ++i) { | 398 | for (i = 0; i < pdata->num_devices; ++i) { |
| 360 | struct omap_dss_device *dssdev = pdata->devices[i]; | 399 | struct omap_dss_device *dssdev = pdata->devices[i]; |
| @@ -362,21 +401,75 @@ static void __init dpi_probe_pdata(struct platform_device *pdev) | |||
| 362 | if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) | 401 | if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) |
| 363 | continue; | 402 | continue; |
| 364 | 403 | ||
| 365 | r = dpi_init_display(dssdev); | 404 | if (def_dssdev == NULL) |
| 366 | if (r) { | 405 | def_dssdev = dssdev; |
| 367 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 406 | |
| 368 | continue; | 407 | if (def_disp_name != NULL && |
| 408 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
| 409 | def_dssdev = dssdev; | ||
| 410 | break; | ||
| 369 | } | 411 | } |
| 412 | } | ||
| 370 | 413 | ||
| 371 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | 414 | return def_dssdev; |
| 372 | if (r) | 415 | } |
| 373 | DSSERR("device %s register failed: %d\n", | 416 | |
| 374 | dssdev->name, r); | 417 | static void __init dpi_probe_pdata(struct platform_device *dpidev) |
| 418 | { | ||
| 419 | struct omap_dss_device *plat_dssdev; | ||
| 420 | struct omap_dss_device *dssdev; | ||
| 421 | int r; | ||
| 422 | |||
| 423 | plat_dssdev = dpi_find_dssdev(dpidev); | ||
| 424 | |||
| 425 | if (!plat_dssdev) | ||
| 426 | return; | ||
| 427 | |||
| 428 | dssdev = dss_alloc_and_init_device(&dpidev->dev); | ||
| 429 | if (!dssdev) | ||
| 430 | return; | ||
| 431 | |||
| 432 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
| 433 | |||
| 434 | r = dpi_init_display(dssdev); | ||
| 435 | if (r) { | ||
| 436 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
| 437 | dss_put_device(dssdev); | ||
| 438 | return; | ||
| 439 | } | ||
| 440 | |||
| 441 | r = dss_add_device(dssdev); | ||
| 442 | if (r) { | ||
| 443 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
| 444 | dss_put_device(dssdev); | ||
| 445 | return; | ||
| 375 | } | 446 | } |
| 376 | } | 447 | } |
| 377 | 448 | ||
| 449 | static void __init dpi_init_output(struct platform_device *pdev) | ||
| 450 | { | ||
| 451 | struct omap_dss_output *out = &dpi.output; | ||
| 452 | |||
| 453 | out->pdev = pdev; | ||
| 454 | out->id = OMAP_DSS_OUTPUT_DPI; | ||
| 455 | out->type = OMAP_DISPLAY_TYPE_DPI; | ||
| 456 | |||
| 457 | dss_register_output(out); | ||
| 458 | } | ||
| 459 | |||
| 460 | static void __exit dpi_uninit_output(struct platform_device *pdev) | ||
| 461 | { | ||
| 462 | struct omap_dss_output *out = &dpi.output; | ||
| 463 | |||
| 464 | dss_unregister_output(out); | ||
| 465 | } | ||
| 466 | |||
| 378 | static int __init omap_dpi_probe(struct platform_device *pdev) | 467 | static int __init omap_dpi_probe(struct platform_device *pdev) |
| 379 | { | 468 | { |
| 469 | mutex_init(&dpi.lock); | ||
| 470 | |||
| 471 | dpi_init_output(pdev); | ||
| 472 | |||
| 380 | dpi_probe_pdata(pdev); | 473 | dpi_probe_pdata(pdev); |
| 381 | 474 | ||
| 382 | return 0; | 475 | return 0; |
| @@ -384,7 +477,9 @@ static int __init omap_dpi_probe(struct platform_device *pdev) | |||
| 384 | 477 | ||
| 385 | static int __exit omap_dpi_remove(struct platform_device *pdev) | 478 | static int __exit omap_dpi_remove(struct platform_device *pdev) |
| 386 | { | 479 | { |
| 387 | omap_dss_unregister_child_devices(&pdev->dev); | 480 | dss_unregister_child_devices(&pdev->dev); |
| 481 | |||
| 482 | dpi_uninit_output(pdev); | ||
| 388 | 483 | ||
| 389 | return 0; | 484 | return 0; |
| 390 | } | 485 | } |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index b07e8864f82f..e37e6d868acd 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | 41 | ||
| 42 | #include <video/omapdss.h> | 42 | #include <video/omapdss.h> |
| 43 | #include <video/mipi_display.h> | 43 | #include <video/mipi_display.h> |
| 44 | #include <plat/clock.h> | ||
| 45 | 44 | ||
| 46 | #include "dss.h" | 45 | #include "dss.h" |
| 47 | #include "dss_features.h" | 46 | #include "dss_features.h" |
| @@ -333,6 +332,12 @@ struct dsi_data { | |||
| 333 | unsigned scp_clk_refcount; | 332 | unsigned scp_clk_refcount; |
| 334 | 333 | ||
| 335 | struct dss_lcd_mgr_config mgr_config; | 334 | struct dss_lcd_mgr_config mgr_config; |
| 335 | struct omap_video_timings timings; | ||
| 336 | enum omap_dss_dsi_pixel_format pix_fmt; | ||
| 337 | enum omap_dss_dsi_mode mode; | ||
| 338 | struct omap_dss_dsi_videomode_timings vm_timings; | ||
| 339 | |||
| 340 | struct omap_dss_output output; | ||
| 336 | }; | 341 | }; |
| 337 | 342 | ||
| 338 | struct dsi_packet_sent_handler_data { | 343 | struct dsi_packet_sent_handler_data { |
| @@ -340,8 +345,6 @@ struct dsi_packet_sent_handler_data { | |||
| 340 | struct completion *completion; | 345 | struct completion *completion; |
| 341 | }; | 346 | }; |
| 342 | 347 | ||
| 343 | static struct platform_device *dsi_pdev_map[MAX_NUM_DSI]; | ||
| 344 | |||
| 345 | #ifdef DEBUG | 348 | #ifdef DEBUG |
| 346 | static bool dsi_perf; | 349 | static bool dsi_perf; |
| 347 | module_param(dsi_perf, bool, 0644); | 350 | module_param(dsi_perf, bool, 0644); |
| @@ -354,12 +357,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside | |||
| 354 | 357 | ||
| 355 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) | 358 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) |
| 356 | { | 359 | { |
| 357 | return dsi_pdev_map[dssdev->phy.dsi.module]; | 360 | return dssdev->output->pdev; |
| 358 | } | 361 | } |
| 359 | 362 | ||
| 360 | struct platform_device *dsi_get_dsidev_from_id(int module) | 363 | struct platform_device *dsi_get_dsidev_from_id(int module) |
| 361 | { | 364 | { |
| 362 | return dsi_pdev_map[module]; | 365 | struct omap_dss_output *out; |
| 366 | enum omap_dss_output_id id; | ||
| 367 | |||
| 368 | id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; | ||
| 369 | |||
| 370 | out = omap_dss_get_output(id); | ||
| 371 | |||
| 372 | return out->pdev; | ||
| 363 | } | 373 | } |
| 364 | 374 | ||
| 365 | static inline void dsi_write_reg(struct platform_device *dsidev, | 375 | static inline void dsi_write_reg(struct platform_device *dsidev, |
| @@ -1450,6 +1460,148 @@ found: | |||
| 1450 | return 0; | 1460 | return 0; |
| 1451 | } | 1461 | } |
| 1452 | 1462 | ||
| 1463 | static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, | ||
| 1464 | unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo) | ||
| 1465 | { | ||
| 1466 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 1467 | struct dsi_clock_info cur, best; | ||
| 1468 | |||
| 1469 | DSSDBG("dsi_pll_calc_ddrfreq\n"); | ||
| 1470 | |||
| 1471 | memset(&best, 0, sizeof(best)); | ||
| 1472 | memset(&cur, 0, sizeof(cur)); | ||
| 1473 | |||
| 1474 | cur.clkin = clk_get_rate(dsi->sys_clk); | ||
| 1475 | |||
| 1476 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { | ||
| 1477 | cur.fint = cur.clkin / cur.regn; | ||
| 1478 | |||
| 1479 | if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) | ||
| 1480 | continue; | ||
| 1481 | |||
| 1482 | /* DSIPHY(MHz) = (2 * regm / regn) * clkin */ | ||
| 1483 | for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { | ||
| 1484 | unsigned long a, b; | ||
| 1485 | |||
| 1486 | a = 2 * cur.regm * (cur.clkin/1000); | ||
| 1487 | b = cur.regn; | ||
| 1488 | cur.clkin4ddr = a / b * 1000; | ||
| 1489 | |||
| 1490 | if (cur.clkin4ddr > 1800 * 1000 * 1000) | ||
| 1491 | break; | ||
| 1492 | |||
| 1493 | if (abs(cur.clkin4ddr - req_clkin4ddr) < | ||
| 1494 | abs(best.clkin4ddr - req_clkin4ddr)) { | ||
| 1495 | best = cur; | ||
| 1496 | DSSDBG("best %ld\n", best.clkin4ddr); | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | if (cur.clkin4ddr == req_clkin4ddr) | ||
| 1500 | goto found; | ||
| 1501 | } | ||
| 1502 | } | ||
| 1503 | found: | ||
| 1504 | if (cinfo) | ||
| 1505 | *cinfo = best; | ||
| 1506 | |||
| 1507 | return 0; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev, | ||
| 1511 | struct dsi_clock_info *cinfo) | ||
| 1512 | { | ||
| 1513 | unsigned long max_dsi_fck; | ||
| 1514 | |||
| 1515 | max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); | ||
| 1516 | |||
| 1517 | cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); | ||
| 1518 | cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev, | ||
| 1522 | unsigned long req_pck, struct dsi_clock_info *cinfo, | ||
| 1523 | struct dispc_clock_info *dispc_cinfo) | ||
| 1524 | { | ||
| 1525 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 1526 | unsigned regm_dispc, best_regm_dispc; | ||
| 1527 | unsigned long dispc_clk, best_dispc_clk; | ||
| 1528 | int min_fck_per_pck; | ||
| 1529 | unsigned long max_dss_fck; | ||
| 1530 | struct dispc_clock_info best_dispc; | ||
| 1531 | bool match; | ||
| 1532 | |||
| 1533 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | ||
| 1534 | |||
| 1535 | min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; | ||
| 1536 | |||
| 1537 | if (min_fck_per_pck && | ||
| 1538 | req_pck * min_fck_per_pck > max_dss_fck) { | ||
| 1539 | DSSERR("Requested pixel clock not possible with the current " | ||
| 1540 | "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " | ||
| 1541 | "the constraint off.\n"); | ||
| 1542 | min_fck_per_pck = 0; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | retry: | ||
| 1546 | best_regm_dispc = 0; | ||
| 1547 | best_dispc_clk = 0; | ||
| 1548 | memset(&best_dispc, 0, sizeof(best_dispc)); | ||
| 1549 | match = false; | ||
| 1550 | |||
| 1551 | for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) { | ||
| 1552 | struct dispc_clock_info cur_dispc; | ||
| 1553 | |||
| 1554 | dispc_clk = cinfo->clkin4ddr / regm_dispc; | ||
| 1555 | |||
| 1556 | /* this will narrow down the search a bit, | ||
| 1557 | * but still give pixclocks below what was | ||
| 1558 | * requested */ | ||
| 1559 | if (dispc_clk < req_pck) | ||
| 1560 | break; | ||
| 1561 | |||
| 1562 | if (dispc_clk > max_dss_fck) | ||
| 1563 | continue; | ||
| 1564 | |||
| 1565 | if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck) | ||
| 1566 | continue; | ||
| 1567 | |||
| 1568 | match = true; | ||
| 1569 | |||
| 1570 | dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc); | ||
| 1571 | |||
| 1572 | if (abs(cur_dispc.pck - req_pck) < | ||
| 1573 | abs(best_dispc.pck - req_pck)) { | ||
| 1574 | best_regm_dispc = regm_dispc; | ||
| 1575 | best_dispc_clk = dispc_clk; | ||
| 1576 | best_dispc = cur_dispc; | ||
| 1577 | |||
| 1578 | if (cur_dispc.pck == req_pck) | ||
| 1579 | goto found; | ||
| 1580 | } | ||
| 1581 | } | ||
| 1582 | |||
| 1583 | if (!match) { | ||
| 1584 | if (min_fck_per_pck) { | ||
| 1585 | DSSERR("Could not find suitable clock settings.\n" | ||
| 1586 | "Turning FCK/PCK constraint off and" | ||
| 1587 | "trying again.\n"); | ||
| 1588 | min_fck_per_pck = 0; | ||
| 1589 | goto retry; | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | DSSERR("Could not find suitable clock settings.\n"); | ||
| 1593 | |||
| 1594 | return -EINVAL; | ||
| 1595 | } | ||
| 1596 | found: | ||
| 1597 | cinfo->regm_dispc = best_regm_dispc; | ||
| 1598 | cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk; | ||
| 1599 | |||
| 1600 | *dispc_cinfo = best_dispc; | ||
| 1601 | |||
| 1602 | return 0; | ||
| 1603 | } | ||
| 1604 | |||
| 1453 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 1605 | int dsi_pll_set_clock_div(struct platform_device *dsidev, |
| 1454 | struct dsi_clock_info *cinfo) | 1606 | struct dsi_clock_info *cinfo) |
| 1455 | { | 1607 | { |
| @@ -1526,21 +1678,27 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
| 1526 | 1678 | ||
| 1527 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); | 1679 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); |
| 1528 | 1680 | ||
| 1681 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
| 1682 | |||
| 1529 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { | 1683 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { |
| 1530 | f = cinfo->fint < 1000000 ? 0x3 : | 1684 | f = cinfo->fint < 1000000 ? 0x3 : |
| 1531 | cinfo->fint < 1250000 ? 0x4 : | 1685 | cinfo->fint < 1250000 ? 0x4 : |
| 1532 | cinfo->fint < 1500000 ? 0x5 : | 1686 | cinfo->fint < 1500000 ? 0x5 : |
| 1533 | cinfo->fint < 1750000 ? 0x6 : | 1687 | cinfo->fint < 1750000 ? 0x6 : |
| 1534 | 0x7; | 1688 | 0x7; |
| 1535 | } | ||
| 1536 | 1689 | ||
| 1537 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
| 1538 | |||
| 1539 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) | ||
| 1540 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | 1690 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ |
| 1691 | } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) { | ||
| 1692 | f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4; | ||
| 1693 | |||
| 1694 | l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */ | ||
| 1695 | } | ||
| 1696 | |||
| 1541 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | 1697 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ |
| 1542 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ | 1698 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ |
| 1543 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ | 1699 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ |
| 1700 | if (dss_has_feature(FEAT_DSI_PLL_REFSEL)) | ||
| 1701 | l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */ | ||
| 1544 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); | 1702 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); |
| 1545 | 1703 | ||
| 1546 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ | 1704 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ |
| @@ -2004,15 +2162,16 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) | |||
| 2004 | return 1194 * 3; /* 1194x24 bits */ | 2162 | return 1194 * 3; /* 1194x24 bits */ |
| 2005 | case 6: | 2163 | case 6: |
| 2006 | return 1365 * 3; /* 1365x24 bits */ | 2164 | return 1365 * 3; /* 1365x24 bits */ |
| 2165 | case 7: | ||
| 2166 | return 1920 * 3; /* 1920x24 bits */ | ||
| 2007 | default: | 2167 | default: |
| 2008 | BUG(); | 2168 | BUG(); |
| 2009 | return 0; | 2169 | return 0; |
| 2010 | } | 2170 | } |
| 2011 | } | 2171 | } |
| 2012 | 2172 | ||
| 2013 | static int dsi_set_lane_config(struct omap_dss_device *dssdev) | 2173 | static int dsi_set_lane_config(struct platform_device *dsidev) |
| 2014 | { | 2174 | { |
| 2015 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2016 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2175 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 2017 | static const u8 offsets[] = { 0, 4, 8, 12, 16 }; | 2176 | static const u8 offsets[] = { 0, 4, 8, 12, 16 }; |
| 2018 | static const enum dsi_lane_function functions[] = { | 2177 | static const enum dsi_lane_function functions[] = { |
| @@ -2136,9 +2295,16 @@ static void dsi_cio_timings(struct platform_device *dsidev) | |||
| 2136 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r); | 2295 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r); |
| 2137 | 2296 | ||
| 2138 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); | 2297 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); |
| 2139 | r = FLD_MOD(r, tlpx_half, 22, 16); | 2298 | r = FLD_MOD(r, tlpx_half, 20, 16); |
| 2140 | r = FLD_MOD(r, tclk_trail, 15, 8); | 2299 | r = FLD_MOD(r, tclk_trail, 15, 8); |
| 2141 | r = FLD_MOD(r, tclk_zero, 7, 0); | 2300 | r = FLD_MOD(r, tclk_zero, 7, 0); |
| 2301 | |||
| 2302 | if (dss_has_feature(FEAT_DSI_PHY_DCC)) { | ||
| 2303 | r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */ | ||
| 2304 | r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */ | ||
| 2305 | r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */ | ||
| 2306 | } | ||
| 2307 | |||
| 2142 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); | 2308 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); |
| 2143 | 2309 | ||
| 2144 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); | 2310 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); |
| @@ -2147,10 +2313,9 @@ static void dsi_cio_timings(struct platform_device *dsidev) | |||
| 2147 | } | 2313 | } |
| 2148 | 2314 | ||
| 2149 | /* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */ | 2315 | /* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */ |
| 2150 | static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev, | 2316 | static void dsi_cio_enable_lane_override(struct platform_device *dsidev, |
| 2151 | unsigned mask_p, unsigned mask_n) | 2317 | unsigned mask_p, unsigned mask_n) |
| 2152 | { | 2318 | { |
| 2153 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2154 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2319 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 2155 | int i; | 2320 | int i; |
| 2156 | u32 l; | 2321 | u32 l; |
| @@ -2197,9 +2362,8 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev) | |||
| 2197 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); | 2362 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); |
| 2198 | } | 2363 | } |
| 2199 | 2364 | ||
| 2200 | static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) | 2365 | static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev) |
| 2201 | { | 2366 | { |
| 2202 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2203 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2367 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 2204 | int t, i; | 2368 | int t, i; |
| 2205 | bool in_use[DSI_MAX_NR_LANES]; | 2369 | bool in_use[DSI_MAX_NR_LANES]; |
| @@ -2247,9 +2411,8 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) | |||
| 2247 | } | 2411 | } |
| 2248 | 2412 | ||
| 2249 | /* return bitmask of enabled lanes, lane0 being the lsb */ | 2413 | /* return bitmask of enabled lanes, lane0 being the lsb */ |
| 2250 | static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev) | 2414 | static unsigned dsi_get_lane_mask(struct platform_device *dsidev) |
| 2251 | { | 2415 | { |
| 2252 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2253 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2416 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 2254 | unsigned mask = 0; | 2417 | unsigned mask = 0; |
| 2255 | int i; | 2418 | int i; |
| @@ -2262,16 +2425,15 @@ static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev) | |||
| 2262 | return mask; | 2425 | return mask; |
| 2263 | } | 2426 | } |
| 2264 | 2427 | ||
| 2265 | static int dsi_cio_init(struct omap_dss_device *dssdev) | 2428 | static int dsi_cio_init(struct platform_device *dsidev) |
| 2266 | { | 2429 | { |
| 2267 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2268 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2430 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 2269 | int r; | 2431 | int r; |
| 2270 | u32 l; | 2432 | u32 l; |
| 2271 | 2433 | ||
| 2272 | DSSDBGF(); | 2434 | DSSDBGF(); |
| 2273 | 2435 | ||
| 2274 | r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); | 2436 | r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); |
| 2275 | if (r) | 2437 | if (r) |
| 2276 | return r; | 2438 | return r; |
| 2277 | 2439 | ||
| @@ -2288,7 +2450,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
| 2288 | goto err_scp_clk_dom; | 2450 | goto err_scp_clk_dom; |
| 2289 | } | 2451 | } |
| 2290 | 2452 | ||
| 2291 | r = dsi_set_lane_config(dssdev); | 2453 | r = dsi_set_lane_config(dsidev); |
| 2292 | if (r) | 2454 | if (r) |
| 2293 | goto err_scp_clk_dom; | 2455 | goto err_scp_clk_dom; |
| 2294 | 2456 | ||
| @@ -2323,7 +2485,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
| 2323 | mask_p |= 1 << i; | 2485 | mask_p |= 1 << i; |
| 2324 | } | 2486 | } |
| 2325 | 2487 | ||
| 2326 | dsi_cio_enable_lane_override(dssdev, mask_p, 0); | 2488 | dsi_cio_enable_lane_override(dsidev, mask_p, 0); |
| 2327 | } | 2489 | } |
| 2328 | 2490 | ||
| 2329 | r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); | 2491 | r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); |
| @@ -2340,7 +2502,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
| 2340 | dsi_if_enable(dsidev, false); | 2502 | dsi_if_enable(dsidev, false); |
| 2341 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ | 2503 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ |
| 2342 | 2504 | ||
| 2343 | r = dsi_cio_wait_tx_clk_esc_reset(dssdev); | 2505 | r = dsi_cio_wait_tx_clk_esc_reset(dsidev); |
| 2344 | if (r) | 2506 | if (r) |
| 2345 | goto err_tx_clk_esc_rst; | 2507 | goto err_tx_clk_esc_rst; |
| 2346 | 2508 | ||
| @@ -2360,10 +2522,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
| 2360 | 2522 | ||
| 2361 | dsi_cio_timings(dsidev); | 2523 | dsi_cio_timings(dsidev); |
| 2362 | 2524 | ||
| 2363 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 2525 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 2364 | /* DDR_CLK_ALWAYS_ON */ | 2526 | /* DDR_CLK_ALWAYS_ON */ |
| 2365 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, | 2527 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, |
| 2366 | dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13); | 2528 | dsi->vm_timings.ddr_clk_always_on, 13, 13); |
| 2367 | } | 2529 | } |
| 2368 | 2530 | ||
| 2369 | dsi->ulps_enabled = false; | 2531 | dsi->ulps_enabled = false; |
| @@ -2381,13 +2543,12 @@ err_cio_pwr: | |||
| 2381 | dsi_cio_disable_lane_override(dsidev); | 2543 | dsi_cio_disable_lane_override(dsidev); |
| 2382 | err_scp_clk_dom: | 2544 | err_scp_clk_dom: |
| 2383 | dsi_disable_scp_clk(dsidev); | 2545 | dsi_disable_scp_clk(dsidev); |
| 2384 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); | 2546 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); |
| 2385 | return r; | 2547 | return r; |
| 2386 | } | 2548 | } |
| 2387 | 2549 | ||
| 2388 | static void dsi_cio_uninit(struct omap_dss_device *dssdev) | 2550 | static void dsi_cio_uninit(struct platform_device *dsidev) |
| 2389 | { | 2551 | { |
| 2390 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2391 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2552 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 2392 | 2553 | ||
| 2393 | /* DDR_CLK_ALWAYS_ON */ | 2554 | /* DDR_CLK_ALWAYS_ON */ |
| @@ -2395,7 +2556,7 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev) | |||
| 2395 | 2556 | ||
| 2396 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); | 2557 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); |
| 2397 | dsi_disable_scp_clk(dsidev); | 2558 | dsi_disable_scp_clk(dsidev); |
| 2398 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); | 2559 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); |
| 2399 | } | 2560 | } |
| 2400 | 2561 | ||
| 2401 | static void dsi_config_tx_fifo(struct platform_device *dsidev, | 2562 | static void dsi_config_tx_fifo(struct platform_device *dsidev, |
| @@ -2685,6 +2846,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | |||
| 2685 | bool enable) | 2846 | bool enable) |
| 2686 | { | 2847 | { |
| 2687 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 2848 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 2849 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 2688 | 2850 | ||
| 2689 | DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); | 2851 | DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); |
| 2690 | 2852 | ||
| @@ -2701,7 +2863,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | |||
| 2701 | dsi_force_tx_stop_mode_io(dsidev); | 2863 | dsi_force_tx_stop_mode_io(dsidev); |
| 2702 | 2864 | ||
| 2703 | /* start the DDR clock by sending a NULL packet */ | 2865 | /* start the DDR clock by sending a NULL packet */ |
| 2704 | if (dssdev->panel.dsi_vm_data.ddr_clk_always_on && enable) | 2866 | if (dsi->vm_timings.ddr_clk_always_on && enable) |
| 2705 | dsi_vc_send_null(dssdev, channel); | 2867 | dsi_vc_send_null(dssdev, channel); |
| 2706 | } | 2868 | } |
| 2707 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); | 2869 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); |
| @@ -2987,10 +3149,9 @@ int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) | |||
| 2987 | } | 3149 | } |
| 2988 | EXPORT_SYMBOL(dsi_vc_send_null); | 3150 | EXPORT_SYMBOL(dsi_vc_send_null); |
| 2989 | 3151 | ||
| 2990 | static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev, | 3152 | static int dsi_vc_write_nosync_common(struct platform_device *dsidev, |
| 2991 | int channel, u8 *data, int len, enum dss_dsi_content_type type) | 3153 | int channel, u8 *data, int len, enum dss_dsi_content_type type) |
| 2992 | { | 3154 | { |
| 2993 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 2994 | int r; | 3155 | int r; |
| 2995 | 3156 | ||
| 2996 | if (len == 0) { | 3157 | if (len == 0) { |
| @@ -3021,7 +3182,9 @@ static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev, | |||
| 3021 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, | 3182 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, |
| 3022 | u8 *data, int len) | 3183 | u8 *data, int len) |
| 3023 | { | 3184 | { |
| 3024 | return dsi_vc_write_nosync_common(dssdev, channel, data, len, | 3185 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 3186 | |||
| 3187 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, | ||
| 3025 | DSS_DSI_CONTENT_DCS); | 3188 | DSS_DSI_CONTENT_DCS); |
| 3026 | } | 3189 | } |
| 3027 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | 3190 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); |
| @@ -3029,7 +3192,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | |||
| 3029 | int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, | 3192 | int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, |
| 3030 | u8 *data, int len) | 3193 | u8 *data, int len) |
| 3031 | { | 3194 | { |
| 3032 | return dsi_vc_write_nosync_common(dssdev, channel, data, len, | 3195 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 3196 | |||
| 3197 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, | ||
| 3033 | DSS_DSI_CONTENT_GENERIC); | 3198 | DSS_DSI_CONTENT_GENERIC); |
| 3034 | } | 3199 | } |
| 3035 | EXPORT_SYMBOL(dsi_vc_generic_write_nosync); | 3200 | EXPORT_SYMBOL(dsi_vc_generic_write_nosync); |
| @@ -3040,7 +3205,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel, | |||
| 3040 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3205 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 3041 | int r; | 3206 | int r; |
| 3042 | 3207 | ||
| 3043 | r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type); | 3208 | r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type); |
| 3044 | if (r) | 3209 | if (r) |
| 3045 | goto err; | 3210 | goto err; |
| 3046 | 3211 | ||
| @@ -3118,10 +3283,9 @@ int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel, | |||
| 3118 | } | 3283 | } |
| 3119 | EXPORT_SYMBOL(dsi_vc_generic_write_2); | 3284 | EXPORT_SYMBOL(dsi_vc_generic_write_2); |
| 3120 | 3285 | ||
| 3121 | static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev, | 3286 | static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev, |
| 3122 | int channel, u8 dcs_cmd) | 3287 | int channel, u8 dcs_cmd) |
| 3123 | { | 3288 | { |
| 3124 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 3125 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 3289 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 3126 | int r; | 3290 | int r; |
| 3127 | 3291 | ||
| @@ -3139,10 +3303,9 @@ static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev, | |||
| 3139 | return 0; | 3303 | return 0; |
| 3140 | } | 3304 | } |
| 3141 | 3305 | ||
| 3142 | static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev, | 3306 | static int dsi_vc_generic_send_read_request(struct platform_device *dsidev, |
| 3143 | int channel, u8 *reqdata, int reqlen) | 3307 | int channel, u8 *reqdata, int reqlen) |
| 3144 | { | 3308 | { |
| 3145 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 3146 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 3309 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 3147 | u16 data; | 3310 | u16 data; |
| 3148 | u8 data_type; | 3311 | u8 data_type; |
| @@ -3291,7 +3454,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | |||
| 3291 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3454 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 3292 | int r; | 3455 | int r; |
| 3293 | 3456 | ||
| 3294 | r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd); | 3457 | r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd); |
| 3295 | if (r) | 3458 | if (r) |
| 3296 | goto err; | 3459 | goto err; |
| 3297 | 3460 | ||
| @@ -3322,7 +3485,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel, | |||
| 3322 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3485 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 3323 | int r; | 3486 | int r; |
| 3324 | 3487 | ||
| 3325 | r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen); | 3488 | r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen); |
| 3326 | if (r) | 3489 | if (r) |
| 3327 | return r; | 3490 | return r; |
| 3328 | 3491 | ||
| @@ -3604,15 +3767,15 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev, | |||
| 3604 | (total_ticks * 1000) / (fck / 1000 / 1000)); | 3767 | (total_ticks * 1000) / (fck / 1000 / 1000)); |
| 3605 | } | 3768 | } |
| 3606 | 3769 | ||
| 3607 | static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev) | 3770 | static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev) |
| 3608 | { | 3771 | { |
| 3609 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3772 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 3610 | int num_line_buffers; | 3773 | int num_line_buffers; |
| 3611 | 3774 | ||
| 3612 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 3775 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 3613 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 3776 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
| 3614 | unsigned line_buf_size = dsi_get_line_buf_size(dsidev); | 3777 | unsigned line_buf_size = dsi_get_line_buf_size(dsidev); |
| 3615 | struct omap_video_timings *timings = &dssdev->panel.timings; | 3778 | struct omap_video_timings *timings = &dsi->timings; |
| 3616 | /* | 3779 | /* |
| 3617 | * Don't use line buffers if width is greater than the video | 3780 | * Don't use line buffers if width is greater than the video |
| 3618 | * port's line buffer size | 3781 | * port's line buffer size |
| @@ -3630,11 +3793,11 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev) | |||
| 3630 | REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12); | 3793 | REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12); |
| 3631 | } | 3794 | } |
| 3632 | 3795 | ||
| 3633 | static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) | 3796 | static void dsi_config_vp_sync_events(struct platform_device *dsidev) |
| 3634 | { | 3797 | { |
| 3635 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3798 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 3636 | bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end; | 3799 | bool vsync_end = dsi->vm_timings.vp_vsync_end; |
| 3637 | bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; | 3800 | bool hsync_end = dsi->vm_timings.vp_hsync_end; |
| 3638 | u32 r; | 3801 | u32 r; |
| 3639 | 3802 | ||
| 3640 | r = dsi_read_reg(dsidev, DSI_CTRL); | 3803 | r = dsi_read_reg(dsidev, DSI_CTRL); |
| @@ -3648,13 +3811,13 @@ static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) | |||
| 3648 | dsi_write_reg(dsidev, DSI_CTRL, r); | 3811 | dsi_write_reg(dsidev, DSI_CTRL, r); |
| 3649 | } | 3812 | } |
| 3650 | 3813 | ||
| 3651 | static void dsi_config_blanking_modes(struct omap_dss_device *dssdev) | 3814 | static void dsi_config_blanking_modes(struct platform_device *dsidev) |
| 3652 | { | 3815 | { |
| 3653 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3816 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 3654 | int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode; | 3817 | int blanking_mode = dsi->vm_timings.blanking_mode; |
| 3655 | int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode; | 3818 | int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode; |
| 3656 | int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode; | 3819 | int hbp_blanking_mode = dsi->vm_timings.hbp_blanking_mode; |
| 3657 | int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode; | 3820 | int hsa_blanking_mode = dsi->vm_timings.hsa_blanking_mode; |
| 3658 | u32 r; | 3821 | u32 r; |
| 3659 | 3822 | ||
| 3660 | /* | 3823 | /* |
| @@ -3741,8 +3904,8 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) | |||
| 3741 | int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; | 3904 | int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; |
| 3742 | int tclk_trail, ths_exit, exiths_clk; | 3905 | int tclk_trail, ths_exit, exiths_clk; |
| 3743 | bool ddr_alwon; | 3906 | bool ddr_alwon; |
| 3744 | struct omap_video_timings *timings = &dssdev->panel.timings; | 3907 | struct omap_video_timings *timings = &dsi->timings; |
| 3745 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 3908 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
| 3746 | int ndl = dsi->num_lanes_used - 1; | 3909 | int ndl = dsi->num_lanes_used - 1; |
| 3747 | int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; | 3910 | int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; |
| 3748 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; | 3911 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; |
| @@ -3852,6 +4015,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) | |||
| 3852 | static int dsi_proto_config(struct omap_dss_device *dssdev) | 4015 | static int dsi_proto_config(struct omap_dss_device *dssdev) |
| 3853 | { | 4016 | { |
| 3854 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4017 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4018 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 3855 | u32 r; | 4019 | u32 r; |
| 3856 | int buswidth = 0; | 4020 | int buswidth = 0; |
| 3857 | 4021 | ||
| @@ -3871,7 +4035,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
| 3871 | dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true); | 4035 | dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true); |
| 3872 | dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true); | 4036 | dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true); |
| 3873 | 4037 | ||
| 3874 | switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) { | 4038 | switch (dsi_get_pixel_size(dsi->pix_fmt)) { |
| 3875 | case 16: | 4039 | case 16: |
| 3876 | buswidth = 0; | 4040 | buswidth = 0; |
| 3877 | break; | 4041 | break; |
| @@ -3903,11 +4067,11 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
| 3903 | 4067 | ||
| 3904 | dsi_write_reg(dsidev, DSI_CTRL, r); | 4068 | dsi_write_reg(dsidev, DSI_CTRL, r); |
| 3905 | 4069 | ||
| 3906 | dsi_config_vp_num_line_buffers(dssdev); | 4070 | dsi_config_vp_num_line_buffers(dsidev); |
| 3907 | 4071 | ||
| 3908 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4072 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 3909 | dsi_config_vp_sync_events(dssdev); | 4073 | dsi_config_vp_sync_events(dsidev); |
| 3910 | dsi_config_blanking_modes(dssdev); | 4074 | dsi_config_blanking_modes(dsidev); |
| 3911 | dsi_config_cmd_mode_interleaving(dssdev); | 4075 | dsi_config_cmd_mode_interleaving(dssdev); |
| 3912 | } | 4076 | } |
| 3913 | 4077 | ||
| @@ -3919,9 +4083,8 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
| 3919 | return 0; | 4083 | return 0; |
| 3920 | } | 4084 | } |
| 3921 | 4085 | ||
| 3922 | static void dsi_proto_timings(struct omap_dss_device *dssdev) | 4086 | static void dsi_proto_timings(struct platform_device *dsidev) |
| 3923 | { | 4087 | { |
| 3924 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 3925 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4088 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 3926 | unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; | 4089 | unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; |
| 3927 | unsigned tclk_pre, tclk_post; | 4090 | unsigned tclk_pre, tclk_post; |
| @@ -3941,7 +4104,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
| 3941 | ths_exit = FLD_GET(r, 7, 0); | 4104 | ths_exit = FLD_GET(r, 7, 0); |
| 3942 | 4105 | ||
| 3943 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); | 4106 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); |
| 3944 | tlpx = FLD_GET(r, 22, 16) * 2; | 4107 | tlpx = FLD_GET(r, 20, 16) * 2; |
| 3945 | tclk_trail = FLD_GET(r, 15, 8); | 4108 | tclk_trail = FLD_GET(r, 15, 8); |
| 3946 | tclk_zero = FLD_GET(r, 7, 0); | 4109 | tclk_zero = FLD_GET(r, 7, 0); |
| 3947 | 4110 | ||
| @@ -3984,18 +4147,18 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
| 3984 | DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", | 4147 | DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", |
| 3985 | enter_hs_mode_lat, exit_hs_mode_lat); | 4148 | enter_hs_mode_lat, exit_hs_mode_lat); |
| 3986 | 4149 | ||
| 3987 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4150 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 3988 | /* TODO: Implement a video mode check_timings function */ | 4151 | /* TODO: Implement a video mode check_timings function */ |
| 3989 | int hsa = dssdev->panel.dsi_vm_data.hsa; | 4152 | int hsa = dsi->vm_timings.hsa; |
| 3990 | int hfp = dssdev->panel.dsi_vm_data.hfp; | 4153 | int hfp = dsi->vm_timings.hfp; |
| 3991 | int hbp = dssdev->panel.dsi_vm_data.hbp; | 4154 | int hbp = dsi->vm_timings.hbp; |
| 3992 | int vsa = dssdev->panel.dsi_vm_data.vsa; | 4155 | int vsa = dsi->vm_timings.vsa; |
| 3993 | int vfp = dssdev->panel.dsi_vm_data.vfp; | 4156 | int vfp = dsi->vm_timings.vfp; |
| 3994 | int vbp = dssdev->panel.dsi_vm_data.vbp; | 4157 | int vbp = dsi->vm_timings.vbp; |
| 3995 | int window_sync = dssdev->panel.dsi_vm_data.window_sync; | 4158 | int window_sync = dsi->vm_timings.window_sync; |
| 3996 | bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; | 4159 | bool hsync_end = dsi->vm_timings.vp_hsync_end; |
| 3997 | struct omap_video_timings *timings = &dssdev->panel.timings; | 4160 | struct omap_video_timings *timings = &dsi->timings; |
| 3998 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 4161 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
| 3999 | int tl, t_he, width_bytes; | 4162 | int tl, t_he, width_bytes; |
| 4000 | 4163 | ||
| 4001 | t_he = hsync_end ? | 4164 | t_he = hsync_end ? |
| @@ -4100,16 +4263,84 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | |||
| 4100 | } | 4263 | } |
| 4101 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); | 4264 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); |
| 4102 | 4265 | ||
| 4103 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | 4266 | int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, |
| 4267 | unsigned long ddr_clk, unsigned long lp_clk) | ||
| 4104 | { | 4268 | { |
| 4105 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4269 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4270 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4271 | struct dsi_clock_info cinfo; | ||
| 4272 | struct dispc_clock_info dispc_cinfo; | ||
| 4273 | unsigned lp_clk_div; | ||
| 4274 | unsigned long dsi_fclk; | ||
| 4106 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 4275 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); |
| 4276 | unsigned long pck; | ||
| 4277 | int r; | ||
| 4278 | |||
| 4279 | DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk); | ||
| 4280 | |||
| 4281 | mutex_lock(&dsi->lock); | ||
| 4282 | |||
| 4283 | /* Calculate PLL output clock */ | ||
| 4284 | r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo); | ||
| 4285 | if (r) | ||
| 4286 | goto err; | ||
| 4287 | |||
| 4288 | /* Calculate PLL's DSI clock */ | ||
| 4289 | dsi_pll_calc_dsi_fck(dsidev, &cinfo); | ||
| 4290 | |||
| 4291 | /* Calculate PLL's DISPC clock and pck & lck divs */ | ||
| 4292 | pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; | ||
| 4293 | DSSDBG("finding dispc dividers for pck %lu\n", pck); | ||
| 4294 | r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo); | ||
| 4295 | if (r) | ||
| 4296 | goto err; | ||
| 4297 | |||
| 4298 | /* Calculate LP clock */ | ||
| 4299 | dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk; | ||
| 4300 | lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); | ||
| 4301 | |||
| 4302 | dssdev->clocks.dsi.regn = cinfo.regn; | ||
| 4303 | dssdev->clocks.dsi.regm = cinfo.regm; | ||
| 4304 | dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; | ||
| 4305 | dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; | ||
| 4306 | |||
| 4307 | dssdev->clocks.dsi.lp_clk_div = lp_clk_div; | ||
| 4308 | |||
| 4309 | dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div; | ||
| 4310 | dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div; | ||
| 4311 | |||
| 4312 | dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK; | ||
| 4313 | |||
| 4314 | dssdev->clocks.dispc.channel.lcd_clk_src = | ||
| 4315 | dsi->module_id == 0 ? | ||
| 4316 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : | ||
| 4317 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; | ||
| 4318 | |||
| 4319 | dssdev->clocks.dsi.dsi_fclk_src = | ||
| 4320 | dsi->module_id == 0 ? | ||
| 4321 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : | ||
| 4322 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI; | ||
| 4323 | |||
| 4324 | mutex_unlock(&dsi->lock); | ||
| 4325 | return 0; | ||
| 4326 | err: | ||
| 4327 | mutex_unlock(&dsi->lock); | ||
| 4328 | return r; | ||
| 4329 | } | ||
| 4330 | EXPORT_SYMBOL(omapdss_dsi_set_clocks); | ||
| 4331 | |||
| 4332 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | ||
| 4333 | { | ||
| 4334 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 4335 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4336 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 4337 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); | ||
| 4107 | u8 data_type; | 4338 | u8 data_type; |
| 4108 | u16 word_count; | 4339 | u16 word_count; |
| 4109 | int r; | 4340 | int r; |
| 4110 | 4341 | ||
| 4111 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4342 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 4112 | switch (dssdev->panel.dsi_pix_fmt) { | 4343 | switch (dsi->pix_fmt) { |
| 4113 | case OMAP_DSS_DSI_FMT_RGB888: | 4344 | case OMAP_DSS_DSI_FMT_RGB888: |
| 4114 | data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; | 4345 | data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; |
| 4115 | break; | 4346 | break; |
| @@ -4133,7 +4364,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | |||
| 4133 | /* MODE, 1 = video mode */ | 4364 | /* MODE, 1 = video mode */ |
| 4134 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4); | 4365 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4); |
| 4135 | 4366 | ||
| 4136 | word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8); | 4367 | word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8); |
| 4137 | 4368 | ||
| 4138 | dsi_vc_write_long_header(dsidev, channel, data_type, | 4369 | dsi_vc_write_long_header(dsidev, channel, data_type, |
| 4139 | word_count, 0); | 4370 | word_count, 0); |
| @@ -4142,9 +4373,9 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | |||
| 4142 | dsi_if_enable(dsidev, true); | 4373 | dsi_if_enable(dsidev, true); |
| 4143 | } | 4374 | } |
| 4144 | 4375 | ||
| 4145 | r = dss_mgr_enable(dssdev->manager); | 4376 | r = dss_mgr_enable(mgr); |
| 4146 | if (r) { | 4377 | if (r) { |
| 4147 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4378 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 4148 | dsi_if_enable(dsidev, false); | 4379 | dsi_if_enable(dsidev, false); |
| 4149 | dsi_vc_enable(dsidev, channel, false); | 4380 | dsi_vc_enable(dsidev, channel, false); |
| 4150 | } | 4381 | } |
| @@ -4159,8 +4390,10 @@ EXPORT_SYMBOL(dsi_enable_video_output); | |||
| 4159 | void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) | 4390 | void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) |
| 4160 | { | 4391 | { |
| 4161 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4392 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4393 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4394 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 4162 | 4395 | ||
| 4163 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4396 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
| 4164 | dsi_if_enable(dsidev, false); | 4397 | dsi_if_enable(dsidev, false); |
| 4165 | dsi_vc_enable(dsidev, channel, false); | 4398 | dsi_vc_enable(dsidev, channel, false); |
| 4166 | 4399 | ||
| @@ -4171,15 +4404,15 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) | |||
| 4171 | dsi_if_enable(dsidev, true); | 4404 | dsi_if_enable(dsidev, true); |
| 4172 | } | 4405 | } |
| 4173 | 4406 | ||
| 4174 | dss_mgr_disable(dssdev->manager); | 4407 | dss_mgr_disable(mgr); |
| 4175 | } | 4408 | } |
| 4176 | EXPORT_SYMBOL(dsi_disable_video_output); | 4409 | EXPORT_SYMBOL(dsi_disable_video_output); |
| 4177 | 4410 | ||
| 4178 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | 4411 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev) |
| 4179 | u16 w, u16 h) | ||
| 4180 | { | 4412 | { |
| 4181 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4413 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4182 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4414 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4415 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 4183 | unsigned bytespp; | 4416 | unsigned bytespp; |
| 4184 | unsigned bytespl; | 4417 | unsigned bytespl; |
| 4185 | unsigned bytespf; | 4418 | unsigned bytespf; |
| @@ -4190,12 +4423,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
| 4190 | int r; | 4423 | int r; |
| 4191 | const unsigned channel = dsi->update_channel; | 4424 | const unsigned channel = dsi->update_channel; |
| 4192 | const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); | 4425 | const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); |
| 4426 | u16 w = dsi->timings.x_res; | ||
| 4427 | u16 h = dsi->timings.y_res; | ||
| 4193 | 4428 | ||
| 4194 | DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h); | 4429 | DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h); |
| 4195 | 4430 | ||
| 4196 | dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP); | 4431 | dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP); |
| 4197 | 4432 | ||
| 4198 | bytespp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8; | 4433 | bytespp = dsi_get_pixel_size(dsi->pix_fmt) / 8; |
| 4199 | bytespl = w * bytespp; | 4434 | bytespl = w * bytespp; |
| 4200 | bytespf = bytespl * h; | 4435 | bytespf = bytespl * h; |
| 4201 | 4436 | ||
| @@ -4239,7 +4474,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
| 4239 | msecs_to_jiffies(250)); | 4474 | msecs_to_jiffies(250)); |
| 4240 | BUG_ON(r == 0); | 4475 | BUG_ON(r == 0); |
| 4241 | 4476 | ||
| 4242 | dss_mgr_start_update(dssdev->manager); | 4477 | dss_mgr_set_timings(mgr, &dsi->timings); |
| 4478 | |||
| 4479 | dss_mgr_start_update(mgr); | ||
| 4243 | 4480 | ||
| 4244 | if (dsi->te_enabled) { | 4481 | if (dsi->te_enabled) { |
| 4245 | /* disable LP_RX_TO, so that we can receive TE. Time to wait | 4482 | /* disable LP_RX_TO, so that we can receive TE. Time to wait |
| @@ -4297,8 +4534,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) | |||
| 4297 | 4534 | ||
| 4298 | static void dsi_framedone_irq_callback(void *data, u32 mask) | 4535 | static void dsi_framedone_irq_callback(void *data, u32 mask) |
| 4299 | { | 4536 | { |
| 4300 | struct omap_dss_device *dssdev = (struct omap_dss_device *) data; | 4537 | struct platform_device *dsidev = (struct platform_device *) data; |
| 4301 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 4302 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4538 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4303 | 4539 | ||
| 4304 | /* Note: We get FRAMEDONE when DISPC has finished sending pixels and | 4540 | /* Note: We get FRAMEDONE when DISPC has finished sending pixels and |
| @@ -4325,13 +4561,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel, | |||
| 4325 | dsi->framedone_callback = callback; | 4561 | dsi->framedone_callback = callback; |
| 4326 | dsi->framedone_data = data; | 4562 | dsi->framedone_data = data; |
| 4327 | 4563 | ||
| 4328 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 4564 | dw = dsi->timings.x_res; |
| 4565 | dh = dsi->timings.y_res; | ||
| 4329 | 4566 | ||
| 4330 | #ifdef DEBUG | 4567 | #ifdef DEBUG |
| 4331 | dsi->update_bytes = dw * dh * | 4568 | dsi->update_bytes = dw * dh * |
| 4332 | dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8; | 4569 | dsi_get_pixel_size(dsi->pix_fmt) / 8; |
| 4333 | #endif | 4570 | #endif |
| 4334 | dsi_update_screen_dispc(dssdev, dw, dh); | 4571 | dsi_update_screen_dispc(dssdev); |
| 4335 | 4572 | ||
| 4336 | return 0; | 4573 | return 0; |
| 4337 | } | 4574 | } |
| @@ -4367,28 +4604,22 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
| 4367 | { | 4604 | { |
| 4368 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4605 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4369 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4606 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4370 | struct omap_video_timings timings; | 4607 | struct omap_overlay_manager *mgr = dssdev->output->manager; |
| 4371 | int r; | 4608 | int r; |
| 4372 | u32 irq = 0; | 4609 | u32 irq = 0; |
| 4373 | 4610 | ||
| 4374 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4611 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { |
| 4375 | u16 dw, dh; | 4612 | dsi->timings.hsw = 1; |
| 4376 | 4613 | dsi->timings.hfp = 1; | |
| 4377 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 4614 | dsi->timings.hbp = 1; |
| 4378 | 4615 | dsi->timings.vsw = 1; | |
| 4379 | timings.x_res = dw; | 4616 | dsi->timings.vfp = 0; |
| 4380 | timings.y_res = dh; | 4617 | dsi->timings.vbp = 0; |
| 4381 | timings.hsw = 1; | ||
| 4382 | timings.hfp = 1; | ||
| 4383 | timings.hbp = 1; | ||
| 4384 | timings.vsw = 1; | ||
| 4385 | timings.vfp = 0; | ||
| 4386 | timings.vbp = 0; | ||
| 4387 | 4618 | ||
| 4388 | irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); | 4619 | irq = dispc_mgr_get_framedone_irq(mgr->id); |
| 4389 | 4620 | ||
| 4390 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, | 4621 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, |
| 4391 | (void *) dssdev, irq); | 4622 | (void *) dsidev, irq); |
| 4392 | if (r) { | 4623 | if (r) { |
| 4393 | DSSERR("can't get FRAMEDONE irq\n"); | 4624 | DSSERR("can't get FRAMEDONE irq\n"); |
| 4394 | goto err; | 4625 | goto err; |
| @@ -4397,8 +4628,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
| 4397 | dsi->mgr_config.stallmode = true; | 4628 | dsi->mgr_config.stallmode = true; |
| 4398 | dsi->mgr_config.fifohandcheck = true; | 4629 | dsi->mgr_config.fifohandcheck = true; |
| 4399 | } else { | 4630 | } else { |
| 4400 | timings = dssdev->panel.timings; | ||
| 4401 | |||
| 4402 | dsi->mgr_config.stallmode = false; | 4631 | dsi->mgr_config.stallmode = false; |
| 4403 | dsi->mgr_config.fifohandcheck = false; | 4632 | dsi->mgr_config.fifohandcheck = false; |
| 4404 | } | 4633 | } |
| @@ -4407,14 +4636,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
| 4407 | * override interlace, logic level and edge related parameters in | 4636 | * override interlace, logic level and edge related parameters in |
| 4408 | * omap_video_timings with default values | 4637 | * omap_video_timings with default values |
| 4409 | */ | 4638 | */ |
| 4410 | timings.interlace = false; | 4639 | dsi->timings.interlace = false; |
| 4411 | timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | 4640 | dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; |
| 4412 | timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | 4641 | dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; |
| 4413 | timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | 4642 | dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; |
| 4414 | timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; | 4643 | dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; |
| 4415 | timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | 4644 | dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; |
| 4416 | 4645 | ||
| 4417 | dss_mgr_set_timings(dssdev->manager, &timings); | 4646 | dss_mgr_set_timings(mgr, &dsi->timings); |
| 4418 | 4647 | ||
| 4419 | r = dsi_configure_dispc_clocks(dssdev); | 4648 | r = dsi_configure_dispc_clocks(dssdev); |
| 4420 | if (r) | 4649 | if (r) |
| @@ -4422,29 +4651,33 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
| 4422 | 4651 | ||
| 4423 | dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; | 4652 | dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; |
| 4424 | dsi->mgr_config.video_port_width = | 4653 | dsi->mgr_config.video_port_width = |
| 4425 | dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 4654 | dsi_get_pixel_size(dsi->pix_fmt); |
| 4426 | dsi->mgr_config.lcden_sig_polarity = 0; | 4655 | dsi->mgr_config.lcden_sig_polarity = 0; |
| 4427 | 4656 | ||
| 4428 | dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config); | 4657 | dss_mgr_set_lcd_config(mgr, &dsi->mgr_config); |
| 4429 | 4658 | ||
| 4430 | return 0; | 4659 | return 0; |
| 4431 | err1: | 4660 | err1: |
| 4432 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) | 4661 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) |
| 4433 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, | 4662 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, |
| 4434 | (void *) dssdev, irq); | 4663 | (void *) dsidev, irq); |
| 4435 | err: | 4664 | err: |
| 4436 | return r; | 4665 | return r; |
| 4437 | } | 4666 | } |
| 4438 | 4667 | ||
| 4439 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) | 4668 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) |
| 4440 | { | 4669 | { |
| 4441 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4670 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4671 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4672 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 4673 | |||
| 4674 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { | ||
| 4442 | u32 irq; | 4675 | u32 irq; |
| 4443 | 4676 | ||
| 4444 | irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); | 4677 | irq = dispc_mgr_get_framedone_irq(mgr->id); |
| 4445 | 4678 | ||
| 4446 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, | 4679 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, |
| 4447 | (void *) dssdev, irq); | 4680 | (void *) dsidev, irq); |
| 4448 | } | 4681 | } |
| 4449 | } | 4682 | } |
| 4450 | 4683 | ||
| @@ -4477,6 +4710,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
| 4477 | { | 4710 | { |
| 4478 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4711 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4479 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4712 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4713 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 4480 | int r; | 4714 | int r; |
| 4481 | 4715 | ||
| 4482 | r = dsi_pll_init(dsidev, true, true); | 4716 | r = dsi_pll_init(dsidev, true, true); |
| @@ -4489,18 +4723,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
| 4489 | 4723 | ||
| 4490 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); | 4724 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); |
| 4491 | dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); | 4725 | dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); |
| 4492 | dss_select_lcd_clk_source(dssdev->manager->id, | 4726 | dss_select_lcd_clk_source(mgr->id, |
| 4493 | dssdev->clocks.dispc.channel.lcd_clk_src); | 4727 | dssdev->clocks.dispc.channel.lcd_clk_src); |
| 4494 | 4728 | ||
| 4495 | DSSDBG("PLL OK\n"); | 4729 | DSSDBG("PLL OK\n"); |
| 4496 | 4730 | ||
| 4497 | r = dsi_cio_init(dssdev); | 4731 | r = dsi_cio_init(dsidev); |
| 4498 | if (r) | 4732 | if (r) |
| 4499 | goto err2; | 4733 | goto err2; |
| 4500 | 4734 | ||
| 4501 | _dsi_print_reset_status(dsidev); | 4735 | _dsi_print_reset_status(dsidev); |
| 4502 | 4736 | ||
| 4503 | dsi_proto_timings(dssdev); | 4737 | dsi_proto_timings(dsidev); |
| 4504 | dsi_set_lp_clk_divisor(dssdev); | 4738 | dsi_set_lp_clk_divisor(dssdev); |
| 4505 | 4739 | ||
| 4506 | if (1) | 4740 | if (1) |
| @@ -4520,11 +4754,11 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
| 4520 | 4754 | ||
| 4521 | return 0; | 4755 | return 0; |
| 4522 | err3: | 4756 | err3: |
| 4523 | dsi_cio_uninit(dssdev); | 4757 | dsi_cio_uninit(dsidev); |
| 4524 | err2: | 4758 | err2: |
| 4525 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 4759 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
| 4526 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4760 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
| 4527 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); | 4761 | dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); |
| 4528 | 4762 | ||
| 4529 | err1: | 4763 | err1: |
| 4530 | dsi_pll_uninit(dsidev, true); | 4764 | dsi_pll_uninit(dsidev, true); |
| @@ -4537,6 +4771,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, | |||
| 4537 | { | 4771 | { |
| 4538 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4772 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4539 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4773 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4774 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 4540 | 4775 | ||
| 4541 | if (enter_ulps && !dsi->ulps_enabled) | 4776 | if (enter_ulps && !dsi->ulps_enabled) |
| 4542 | dsi_enter_ulps(dsidev); | 4777 | dsi_enter_ulps(dsidev); |
| @@ -4550,8 +4785,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, | |||
| 4550 | 4785 | ||
| 4551 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 4786 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
| 4552 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4787 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
| 4553 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); | 4788 | dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); |
| 4554 | dsi_cio_uninit(dssdev); | 4789 | dsi_cio_uninit(dsidev); |
| 4555 | dsi_pll_uninit(dsidev, disconnect_lanes); | 4790 | dsi_pll_uninit(dsidev, disconnect_lanes); |
| 4556 | } | 4791 | } |
| 4557 | 4792 | ||
| @@ -4559,6 +4794,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | |||
| 4559 | { | 4794 | { |
| 4560 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4795 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4561 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4796 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4797 | struct omap_dss_output *out = dssdev->output; | ||
| 4562 | int r = 0; | 4798 | int r = 0; |
| 4563 | 4799 | ||
| 4564 | DSSDBG("dsi_display_enable\n"); | 4800 | DSSDBG("dsi_display_enable\n"); |
| @@ -4567,8 +4803,8 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | |||
| 4567 | 4803 | ||
| 4568 | mutex_lock(&dsi->lock); | 4804 | mutex_lock(&dsi->lock); |
| 4569 | 4805 | ||
| 4570 | if (dssdev->manager == NULL) { | 4806 | if (out == NULL || out->manager == NULL) { |
| 4571 | DSSERR("failed to enable display: no manager\n"); | 4807 | DSSERR("failed to enable display: no output/manager\n"); |
| 4572 | r = -ENODEV; | 4808 | r = -ENODEV; |
| 4573 | goto err_start_dev; | 4809 | goto err_start_dev; |
| 4574 | } | 4810 | } |
| @@ -4653,17 +4889,83 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | |||
| 4653 | } | 4889 | } |
| 4654 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | 4890 | EXPORT_SYMBOL(omapdss_dsi_enable_te); |
| 4655 | 4891 | ||
| 4656 | static int __init dsi_init_display(struct omap_dss_device *dssdev) | 4892 | void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, |
| 4893 | struct omap_video_timings *timings) | ||
| 4657 | { | 4894 | { |
| 4658 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4895 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
| 4659 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4896 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 4660 | 4897 | ||
| 4661 | DSSDBG("DSI init\n"); | 4898 | mutex_lock(&dsi->lock); |
| 4662 | 4899 | ||
| 4663 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4900 | dsi->timings = *timings; |
| 4664 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | | 4901 | |
| 4665 | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; | 4902 | mutex_unlock(&dsi->lock); |
| 4666 | } | 4903 | } |
| 4904 | EXPORT_SYMBOL(omapdss_dsi_set_timings); | ||
| 4905 | |||
| 4906 | void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) | ||
| 4907 | { | ||
| 4908 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 4909 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4910 | |||
| 4911 | mutex_lock(&dsi->lock); | ||
| 4912 | |||
| 4913 | dsi->timings.x_res = w; | ||
| 4914 | dsi->timings.y_res = h; | ||
| 4915 | |||
| 4916 | mutex_unlock(&dsi->lock); | ||
| 4917 | } | ||
| 4918 | EXPORT_SYMBOL(omapdss_dsi_set_size); | ||
| 4919 | |||
| 4920 | void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, | ||
| 4921 | enum omap_dss_dsi_pixel_format fmt) | ||
| 4922 | { | ||
| 4923 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 4924 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4925 | |||
| 4926 | mutex_lock(&dsi->lock); | ||
| 4927 | |||
| 4928 | dsi->pix_fmt = fmt; | ||
| 4929 | |||
| 4930 | mutex_unlock(&dsi->lock); | ||
| 4931 | } | ||
| 4932 | EXPORT_SYMBOL(omapdss_dsi_set_pixel_format); | ||
| 4933 | |||
| 4934 | void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, | ||
| 4935 | enum omap_dss_dsi_mode mode) | ||
| 4936 | { | ||
| 4937 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 4938 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4939 | |||
| 4940 | mutex_lock(&dsi->lock); | ||
| 4941 | |||
| 4942 | dsi->mode = mode; | ||
| 4943 | |||
| 4944 | mutex_unlock(&dsi->lock); | ||
| 4945 | } | ||
| 4946 | EXPORT_SYMBOL(omapdss_dsi_set_operation_mode); | ||
| 4947 | |||
| 4948 | void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, | ||
| 4949 | struct omap_dss_dsi_videomode_timings *timings) | ||
| 4950 | { | ||
| 4951 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
| 4952 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4953 | |||
| 4954 | mutex_lock(&dsi->lock); | ||
| 4955 | |||
| 4956 | dsi->vm_timings = *timings; | ||
| 4957 | |||
| 4958 | mutex_unlock(&dsi->lock); | ||
| 4959 | } | ||
| 4960 | EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings); | ||
| 4961 | |||
| 4962 | static int __init dsi_init_display(struct omap_dss_device *dssdev) | ||
| 4963 | { | ||
| 4964 | struct platform_device *dsidev = | ||
| 4965 | dsi_get_dsidev_from_id(dssdev->phy.dsi.module); | ||
| 4966 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 4967 | |||
| 4968 | DSSDBG("DSI init\n"); | ||
| 4667 | 4969 | ||
| 4668 | if (dsi->vdds_dsi_reg == NULL) { | 4970 | if (dsi->vdds_dsi_reg == NULL) { |
| 4669 | struct regulator *vdds_dsi; | 4971 | struct regulator *vdds_dsi; |
| @@ -4806,11 +5108,15 @@ static void dsi_put_clocks(struct platform_device *dsidev) | |||
| 4806 | clk_put(dsi->sys_clk); | 5108 | clk_put(dsi->sys_clk); |
| 4807 | } | 5109 | } |
| 4808 | 5110 | ||
| 4809 | static void __init dsi_probe_pdata(struct platform_device *dsidev) | 5111 | static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev) |
| 4810 | { | 5112 | { |
| 4811 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 5113 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
| 4812 | struct omap_dss_board_info *pdata = dsidev->dev.platform_data; | 5114 | struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); |
| 4813 | int i, r; | 5115 | const char *def_disp_name = dss_get_default_display_name(); |
| 5116 | struct omap_dss_device *def_dssdev; | ||
| 5117 | int i; | ||
| 5118 | |||
| 5119 | def_dssdev = NULL; | ||
| 4814 | 5120 | ||
| 4815 | for (i = 0; i < pdata->num_devices; ++i) { | 5121 | for (i = 0; i < pdata->num_devices; ++i) { |
| 4816 | struct omap_dss_device *dssdev = pdata->devices[i]; | 5122 | struct omap_dss_device *dssdev = pdata->devices[i]; |
| @@ -4821,19 +5127,73 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev) | |||
| 4821 | if (dssdev->phy.dsi.module != dsi->module_id) | 5127 | if (dssdev->phy.dsi.module != dsi->module_id) |
| 4822 | continue; | 5128 | continue; |
| 4823 | 5129 | ||
| 4824 | r = dsi_init_display(dssdev); | 5130 | if (def_dssdev == NULL) |
| 4825 | if (r) { | 5131 | def_dssdev = dssdev; |
| 4826 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 5132 | |
| 4827 | continue; | 5133 | if (def_disp_name != NULL && |
| 5134 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
| 5135 | def_dssdev = dssdev; | ||
| 5136 | break; | ||
| 4828 | } | 5137 | } |
| 5138 | } | ||
| 4829 | 5139 | ||
| 4830 | r = omap_dss_register_device(dssdev, &dsidev->dev, i); | 5140 | return def_dssdev; |
| 4831 | if (r) | 5141 | } |
| 4832 | DSSERR("device %s register failed: %d\n", | 5142 | |
| 4833 | dssdev->name, r); | 5143 | static void __init dsi_probe_pdata(struct platform_device *dsidev) |
| 5144 | { | ||
| 5145 | struct omap_dss_device *plat_dssdev; | ||
| 5146 | struct omap_dss_device *dssdev; | ||
| 5147 | int r; | ||
| 5148 | |||
| 5149 | plat_dssdev = dsi_find_dssdev(dsidev); | ||
| 5150 | |||
| 5151 | if (!plat_dssdev) | ||
| 5152 | return; | ||
| 5153 | |||
| 5154 | dssdev = dss_alloc_and_init_device(&dsidev->dev); | ||
| 5155 | if (!dssdev) | ||
| 5156 | return; | ||
| 5157 | |||
| 5158 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
| 5159 | |||
| 5160 | r = dsi_init_display(dssdev); | ||
| 5161 | if (r) { | ||
| 5162 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
| 5163 | dss_put_device(dssdev); | ||
| 5164 | return; | ||
| 5165 | } | ||
| 5166 | |||
| 5167 | r = dss_add_device(dssdev); | ||
| 5168 | if (r) { | ||
| 5169 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
| 5170 | dss_put_device(dssdev); | ||
| 5171 | return; | ||
| 4834 | } | 5172 | } |
| 4835 | } | 5173 | } |
| 4836 | 5174 | ||
| 5175 | static void __init dsi_init_output(struct platform_device *dsidev) | ||
| 5176 | { | ||
| 5177 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 5178 | struct omap_dss_output *out = &dsi->output; | ||
| 5179 | |||
| 5180 | out->pdev = dsidev; | ||
| 5181 | out->id = dsi->module_id == 0 ? | ||
| 5182 | OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; | ||
| 5183 | |||
| 5184 | out->type = OMAP_DISPLAY_TYPE_DSI; | ||
| 5185 | |||
| 5186 | dss_register_output(out); | ||
| 5187 | } | ||
| 5188 | |||
| 5189 | static void __exit dsi_uninit_output(struct platform_device *dsidev) | ||
| 5190 | { | ||
| 5191 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
| 5192 | struct omap_dss_output *out = &dsi->output; | ||
| 5193 | |||
| 5194 | dss_unregister_output(out); | ||
| 5195 | } | ||
| 5196 | |||
| 4837 | /* DSI1 HW IP initialisation */ | 5197 | /* DSI1 HW IP initialisation */ |
| 4838 | static int __init omap_dsihw_probe(struct platform_device *dsidev) | 5198 | static int __init omap_dsihw_probe(struct platform_device *dsidev) |
| 4839 | { | 5199 | { |
| @@ -4848,7 +5208,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev) | |||
| 4848 | 5208 | ||
| 4849 | dsi->module_id = dsidev->id; | 5209 | dsi->module_id = dsidev->id; |
| 4850 | dsi->pdev = dsidev; | 5210 | dsi->pdev = dsidev; |
| 4851 | dsi_pdev_map[dsi->module_id] = dsidev; | ||
| 4852 | dev_set_drvdata(&dsidev->dev, dsi); | 5211 | dev_set_drvdata(&dsidev->dev, dsi); |
| 4853 | 5212 | ||
| 4854 | spin_lock_init(&dsi->irq_lock); | 5213 | spin_lock_init(&dsi->irq_lock); |
| @@ -4928,6 +5287,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev) | |||
| 4928 | else | 5287 | else |
| 4929 | dsi->num_lanes_supported = 3; | 5288 | dsi->num_lanes_supported = 3; |
| 4930 | 5289 | ||
| 5290 | dsi_init_output(dsidev); | ||
| 5291 | |||
| 4931 | dsi_probe_pdata(dsidev); | 5292 | dsi_probe_pdata(dsidev); |
| 4932 | 5293 | ||
| 4933 | dsi_runtime_put(dsidev); | 5294 | dsi_runtime_put(dsidev); |
| @@ -4957,7 +5318,9 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) | |||
| 4957 | 5318 | ||
| 4958 | WARN_ON(dsi->scp_clk_refcount > 0); | 5319 | WARN_ON(dsi->scp_clk_refcount > 0); |
| 4959 | 5320 | ||
| 4960 | omap_dss_unregister_child_devices(&dsidev->dev); | 5321 | dss_unregister_child_devices(&dsidev->dev); |
| 5322 | |||
| 5323 | dsi_uninit_output(dsidev); | ||
| 4961 | 5324 | ||
| 4962 | pm_runtime_disable(&dsidev->dev); | 5325 | pm_runtime_disable(&dsidev->dev); |
| 4963 | 5326 | ||
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 04b4586113e3..2ab1c3e96553 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
| @@ -31,11 +31,11 @@ | |||
| 31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
| 32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
| 34 | #include <linux/gfp.h> | ||
| 34 | 35 | ||
| 35 | #include <video/omapdss.h> | 36 | #include <video/omapdss.h> |
| 36 | 37 | ||
| 37 | #include <plat/cpu.h> | 38 | #include <plat/cpu.h> |
| 38 | #include <plat/clock.h> | ||
| 39 | 39 | ||
| 40 | #include "dss.h" | 40 | #include "dss.h" |
| 41 | #include "dss_features.h" | 41 | #include "dss_features.h" |
| @@ -65,6 +65,13 @@ struct dss_reg { | |||
| 65 | static int dss_runtime_get(void); | 65 | static int dss_runtime_get(void); |
| 66 | static void dss_runtime_put(void); | 66 | static void dss_runtime_put(void); |
| 67 | 67 | ||
| 68 | struct dss_features { | ||
| 69 | u8 fck_div_max; | ||
| 70 | u8 dss_fck_multiplier; | ||
| 71 | const char *clk_name; | ||
| 72 | int (*dpi_select_source)(enum omap_channel channel); | ||
| 73 | }; | ||
| 74 | |||
| 68 | static struct { | 75 | static struct { |
| 69 | struct platform_device *pdev; | 76 | struct platform_device *pdev; |
| 70 | void __iomem *base; | 77 | void __iomem *base; |
| @@ -83,6 +90,8 @@ static struct { | |||
| 83 | 90 | ||
| 84 | bool ctx_valid; | 91 | bool ctx_valid; |
| 85 | u32 ctx[DSS_SZ_REGS / sizeof(u32)]; | 92 | u32 ctx[DSS_SZ_REGS / sizeof(u32)]; |
| 93 | |||
| 94 | const struct dss_features *feat; | ||
| 86 | } dss; | 95 | } dss; |
| 87 | 96 | ||
| 88 | static const char * const dss_generic_clk_source_names[] = { | 97 | static const char * const dss_generic_clk_source_names[] = { |
| @@ -144,7 +153,7 @@ static void dss_restore_context(void) | |||
| 144 | #undef SR | 153 | #undef SR |
| 145 | #undef RR | 154 | #undef RR |
| 146 | 155 | ||
| 147 | void dss_sdi_init(u8 datapairs) | 156 | void dss_sdi_init(int datapairs) |
| 148 | { | 157 | { |
| 149 | u32 l; | 158 | u32 l; |
| 150 | 159 | ||
| @@ -236,7 +245,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src) | |||
| 236 | return dss_generic_clk_source_names[clk_src]; | 245 | return dss_generic_clk_source_names[clk_src]; |
| 237 | } | 246 | } |
| 238 | 247 | ||
| 239 | |||
| 240 | void dss_dump_clocks(struct seq_file *s) | 248 | void dss_dump_clocks(struct seq_file *s) |
| 241 | { | 249 | { |
| 242 | unsigned long dpll4_ck_rate; | 250 | unsigned long dpll4_ck_rate; |
| @@ -259,18 +267,10 @@ void dss_dump_clocks(struct seq_file *s) | |||
| 259 | 267 | ||
| 260 | seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); | 268 | seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); |
| 261 | 269 | ||
| 262 | if (cpu_is_omap3630() || cpu_is_omap44xx()) | 270 | seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n", |
| 263 | seq_printf(s, "%s (%s) = %lu / %lu = %lu\n", | 271 | fclk_name, fclk_real_name, dpll4_ck_rate, |
| 264 | fclk_name, fclk_real_name, | 272 | dpll4_ck_rate / dpll4_m4_ck_rate, |
| 265 | dpll4_ck_rate, | 273 | dss.feat->dss_fck_multiplier, fclk_rate); |
| 266 | dpll4_ck_rate / dpll4_m4_ck_rate, | ||
| 267 | fclk_rate); | ||
| 268 | else | ||
| 269 | seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n", | ||
| 270 | fclk_name, fclk_real_name, | ||
| 271 | dpll4_ck_rate, | ||
| 272 | dpll4_ck_rate / dpll4_m4_ck_rate, | ||
| 273 | fclk_rate); | ||
| 274 | } else { | 274 | } else { |
| 275 | seq_printf(s, "%s (%s) = %lu\n", | 275 | seq_printf(s, "%s (%s) = %lu\n", |
| 276 | fclk_name, fclk_real_name, | 276 | fclk_name, fclk_real_name, |
| @@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) | |||
| 431 | } | 431 | } |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | /* calculate clock rates using dividers in cinfo */ | ||
| 435 | int dss_calc_clock_rates(struct dss_clock_info *cinfo) | ||
| 436 | { | ||
| 437 | if (dss.dpll4_m4_ck) { | ||
| 438 | unsigned long prate; | ||
| 439 | u16 fck_div_max = 16; | ||
| 440 | |||
| 441 | if (cpu_is_omap3630() || cpu_is_omap44xx()) | ||
| 442 | fck_div_max = 32; | ||
| 443 | |||
| 444 | if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0) | ||
| 445 | return -EINVAL; | ||
| 446 | |||
| 447 | prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); | ||
| 448 | |||
| 449 | cinfo->fck = prate / cinfo->fck_div; | ||
| 450 | } else { | ||
| 451 | if (cinfo->fck_div != 0) | ||
| 452 | return -EINVAL; | ||
| 453 | cinfo->fck = clk_get_rate(dss.dss_clk); | ||
| 454 | } | ||
| 455 | |||
| 456 | return 0; | ||
| 457 | } | ||
| 458 | |||
| 459 | int dss_set_clock_div(struct dss_clock_info *cinfo) | 434 | int dss_set_clock_div(struct dss_clock_info *cinfo) |
| 460 | { | 435 | { |
| 461 | if (dss.dpll4_m4_ck) { | 436 | if (dss.dpll4_m4_ck) { |
| @@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo) | |||
| 478 | return 0; | 453 | return 0; |
| 479 | } | 454 | } |
| 480 | 455 | ||
| 481 | int dss_get_clock_div(struct dss_clock_info *cinfo) | ||
| 482 | { | ||
| 483 | cinfo->fck = clk_get_rate(dss.dss_clk); | ||
| 484 | |||
| 485 | if (dss.dpll4_m4_ck) { | ||
| 486 | unsigned long prate; | ||
| 487 | |||
| 488 | prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); | ||
| 489 | |||
| 490 | if (cpu_is_omap3630() || cpu_is_omap44xx()) | ||
| 491 | cinfo->fck_div = prate / (cinfo->fck); | ||
| 492 | else | ||
| 493 | cinfo->fck_div = prate / (cinfo->fck / 2); | ||
| 494 | } else { | ||
| 495 | cinfo->fck_div = 0; | ||
| 496 | } | ||
| 497 | |||
| 498 | return 0; | ||
| 499 | } | ||
| 500 | |||
| 501 | unsigned long dss_get_dpll4_rate(void) | 456 | unsigned long dss_get_dpll4_rate(void) |
| 502 | { | 457 | { |
| 503 | if (dss.dpll4_m4_ck) | 458 | if (dss.dpll4_m4_ck) |
| @@ -515,7 +470,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, | |||
| 515 | 470 | ||
| 516 | unsigned long fck, max_dss_fck; | 471 | unsigned long fck, max_dss_fck; |
| 517 | 472 | ||
| 518 | u16 fck_div, fck_div_max = 16; | 473 | u16 fck_div; |
| 519 | 474 | ||
| 520 | int match = 0; | 475 | int match = 0; |
| 521 | int min_fck_per_pck; | 476 | int min_fck_per_pck; |
| @@ -525,9 +480,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, | |||
| 525 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | 480 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); |
| 526 | 481 | ||
| 527 | fck = clk_get_rate(dss.dss_clk); | 482 | fck = clk_get_rate(dss.dss_clk); |
| 528 | if (req_pck == dss.cache_req_pck && | 483 | if (req_pck == dss.cache_req_pck && prate == dss.cache_prate && |
| 529 | ((cpu_is_omap34xx() && prate == dss.cache_prate) || | 484 | dss.cache_dss_cinfo.fck == fck) { |
| 530 | dss.cache_dss_cinfo.fck == fck)) { | ||
| 531 | DSSDBG("dispc clock info found from cache.\n"); | 485 | DSSDBG("dispc clock info found from cache.\n"); |
| 532 | *dss_cinfo = dss.cache_dss_cinfo; | 486 | *dss_cinfo = dss.cache_dss_cinfo; |
| 533 | *dispc_cinfo = dss.cache_dispc_cinfo; | 487 | *dispc_cinfo = dss.cache_dispc_cinfo; |
| @@ -564,16 +518,10 @@ retry: | |||
| 564 | 518 | ||
| 565 | goto found; | 519 | goto found; |
| 566 | } else { | 520 | } else { |
| 567 | if (cpu_is_omap3630() || cpu_is_omap44xx()) | 521 | for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) { |
| 568 | fck_div_max = 32; | ||
| 569 | |||
| 570 | for (fck_div = fck_div_max; fck_div > 0; --fck_div) { | ||
| 571 | struct dispc_clock_info cur_dispc; | 522 | struct dispc_clock_info cur_dispc; |
| 572 | 523 | ||
| 573 | if (fck_div_max == 32) | 524 | fck = prate / fck_div * dss.feat->dss_fck_multiplier; |
| 574 | fck = prate / fck_div; | ||
| 575 | else | ||
| 576 | fck = prate / fck_div * 2; | ||
| 577 | 525 | ||
| 578 | if (fck > max_dss_fck) | 526 | if (fck > max_dss_fck) |
| 579 | continue; | 527 | continue; |
| @@ -648,9 +596,18 @@ void dss_set_dac_pwrdn_bgz(bool enable) | |||
| 648 | REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ | 596 | REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ |
| 649 | } | 597 | } |
| 650 | 598 | ||
| 651 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi) | 599 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src) |
| 652 | { | 600 | { |
| 653 | REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */ | 601 | enum omap_display_type dp; |
| 602 | dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT); | ||
| 603 | |||
| 604 | /* Complain about invalid selections */ | ||
| 605 | WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC)); | ||
| 606 | WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI)); | ||
| 607 | |||
| 608 | /* Select only if we have options */ | ||
| 609 | if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI)) | ||
| 610 | REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */ | ||
| 654 | } | 611 | } |
| 655 | 612 | ||
| 656 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void) | 613 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void) |
| @@ -661,9 +618,71 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void) | |||
| 661 | if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0) | 618 | if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0) |
| 662 | return DSS_VENC_TV_CLK; | 619 | return DSS_VENC_TV_CLK; |
| 663 | 620 | ||
| 621 | if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0) | ||
| 622 | return DSS_HDMI_M_PCLK; | ||
| 623 | |||
| 664 | return REG_GET(DSS_CONTROL, 15, 15); | 624 | return REG_GET(DSS_CONTROL, 15, 15); |
| 665 | } | 625 | } |
| 666 | 626 | ||
| 627 | static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel) | ||
| 628 | { | ||
| 629 | if (channel != OMAP_DSS_CHANNEL_LCD) | ||
| 630 | return -EINVAL; | ||
| 631 | |||
| 632 | return 0; | ||
| 633 | } | ||
| 634 | |||
| 635 | static int dss_dpi_select_source_omap4(enum omap_channel channel) | ||
| 636 | { | ||
| 637 | int val; | ||
| 638 | |||
| 639 | switch (channel) { | ||
| 640 | case OMAP_DSS_CHANNEL_LCD2: | ||
| 641 | val = 0; | ||
| 642 | break; | ||
| 643 | case OMAP_DSS_CHANNEL_DIGIT: | ||
| 644 | val = 1; | ||
| 645 | break; | ||
| 646 | default: | ||
| 647 | return -EINVAL; | ||
| 648 | } | ||
| 649 | |||
| 650 | REG_FLD_MOD(DSS_CONTROL, val, 17, 17); | ||
| 651 | |||
| 652 | return 0; | ||
| 653 | } | ||
| 654 | |||
| 655 | static int dss_dpi_select_source_omap5(enum omap_channel channel) | ||
| 656 | { | ||
| 657 | int val; | ||
| 658 | |||
| 659 | switch (channel) { | ||
| 660 | case OMAP_DSS_CHANNEL_LCD: | ||
| 661 | val = 1; | ||
| 662 | break; | ||
| 663 | case OMAP_DSS_CHANNEL_LCD2: | ||
| 664 | val = 2; | ||
| 665 | break; | ||
| 666 | case OMAP_DSS_CHANNEL_LCD3: | ||
| 667 | val = 3; | ||
| 668 | break; | ||
| 669 | case OMAP_DSS_CHANNEL_DIGIT: | ||
| 670 | val = 0; | ||
| 671 | break; | ||
| 672 | default: | ||
| 673 | return -EINVAL; | ||
| 674 | } | ||
| 675 | |||
| 676 | REG_FLD_MOD(DSS_CONTROL, val, 17, 16); | ||
| 677 | |||
| 678 | return 0; | ||
| 679 | } | ||
| 680 | |||
| 681 | int dss_dpi_select_source(enum omap_channel channel) | ||
| 682 | { | ||
| 683 | return dss.feat->dpi_select_source(channel); | ||
| 684 | } | ||
| 685 | |||
| 667 | static int dss_get_clocks(void) | 686 | static int dss_get_clocks(void) |
| 668 | { | 687 | { |
| 669 | struct clk *clk; | 688 | struct clk *clk; |
| @@ -678,22 +697,11 @@ static int dss_get_clocks(void) | |||
| 678 | 697 | ||
| 679 | dss.dss_clk = clk; | 698 | dss.dss_clk = clk; |
| 680 | 699 | ||
| 681 | if (cpu_is_omap34xx()) { | 700 | clk = clk_get(NULL, dss.feat->clk_name); |
| 682 | clk = clk_get(NULL, "dpll4_m4_ck"); | 701 | if (IS_ERR(clk)) { |
| 683 | if (IS_ERR(clk)) { | 702 | DSSERR("Failed to get %s\n", dss.feat->clk_name); |
| 684 | DSSERR("Failed to get dpll4_m4_ck\n"); | 703 | r = PTR_ERR(clk); |
| 685 | r = PTR_ERR(clk); | 704 | goto err; |
| 686 | goto err; | ||
| 687 | } | ||
| 688 | } else if (cpu_is_omap44xx()) { | ||
| 689 | clk = clk_get(NULL, "dpll_per_m5x2_ck"); | ||
| 690 | if (IS_ERR(clk)) { | ||
| 691 | DSSERR("Failed to get dpll_per_m5x2_ck\n"); | ||
| 692 | r = PTR_ERR(clk); | ||
| 693 | goto err; | ||
| 694 | } | ||
| 695 | } else { /* omap24xx */ | ||
| 696 | clk = NULL; | ||
| 697 | } | 705 | } |
| 698 | 706 | ||
| 699 | dss.dpll4_m4_ck = clk; | 707 | dss.dpll4_m4_ck = clk; |
| @@ -749,6 +757,71 @@ void dss_debug_dump_clocks(struct seq_file *s) | |||
| 749 | } | 757 | } |
| 750 | #endif | 758 | #endif |
| 751 | 759 | ||
| 760 | static const struct dss_features omap24xx_dss_feats __initconst = { | ||
| 761 | .fck_div_max = 16, | ||
| 762 | .dss_fck_multiplier = 2, | ||
| 763 | .clk_name = NULL, | ||
| 764 | .dpi_select_source = &dss_dpi_select_source_omap2_omap3, | ||
| 765 | }; | ||
| 766 | |||
| 767 | static const struct dss_features omap34xx_dss_feats __initconst = { | ||
| 768 | .fck_div_max = 16, | ||
| 769 | .dss_fck_multiplier = 2, | ||
| 770 | .clk_name = "dpll4_m4_ck", | ||
| 771 | .dpi_select_source = &dss_dpi_select_source_omap2_omap3, | ||
| 772 | }; | ||
| 773 | |||
| 774 | static const struct dss_features omap3630_dss_feats __initconst = { | ||
| 775 | .fck_div_max = 32, | ||
| 776 | .dss_fck_multiplier = 1, | ||
| 777 | .clk_name = "dpll4_m4_ck", | ||
| 778 | .dpi_select_source = &dss_dpi_select_source_omap2_omap3, | ||
| 779 | }; | ||
| 780 | |||
| 781 | static const struct dss_features omap44xx_dss_feats __initconst = { | ||
| 782 | .fck_div_max = 32, | ||
| 783 | .dss_fck_multiplier = 1, | ||
| 784 | .clk_name = "dpll_per_m5x2_ck", | ||
| 785 | .dpi_select_source = &dss_dpi_select_source_omap4, | ||
| 786 | }; | ||
| 787 | |||
| 788 | static const struct dss_features omap54xx_dss_feats __initconst = { | ||
| 789 | .fck_div_max = 64, | ||
| 790 | .dss_fck_multiplier = 1, | ||
| 791 | .clk_name = "dpll_per_h12x2_ck", | ||
| 792 | .dpi_select_source = &dss_dpi_select_source_omap5, | ||
| 793 | }; | ||
| 794 | |||
| 795 | static int __init dss_init_features(struct device *dev) | ||
| 796 | { | ||
| 797 | const struct dss_features *src; | ||
| 798 | struct dss_features *dst; | ||
| 799 | |||
| 800 | dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL); | ||
| 801 | if (!dst) { | ||
| 802 | dev_err(dev, "Failed to allocate local DSS Features\n"); | ||
| 803 | return -ENOMEM; | ||
| 804 | } | ||
| 805 | |||
| 806 | if (cpu_is_omap24xx()) | ||
| 807 | src = &omap24xx_dss_feats; | ||
| 808 | else if (cpu_is_omap34xx()) | ||
| 809 | src = &omap34xx_dss_feats; | ||
| 810 | else if (cpu_is_omap3630()) | ||
| 811 | src = &omap3630_dss_feats; | ||
| 812 | else if (cpu_is_omap44xx()) | ||
| 813 | src = &omap44xx_dss_feats; | ||
| 814 | else if (soc_is_omap54xx()) | ||
| 815 | src = &omap54xx_dss_feats; | ||
| 816 | else | ||
| 817 | return -ENODEV; | ||
| 818 | |||
| 819 | memcpy(dst, src, sizeof(*dst)); | ||
| 820 | dss.feat = dst; | ||
| 821 | |||
| 822 | return 0; | ||
| 823 | } | ||
| 824 | |||
| 752 | /* DSS HW IP initialisation */ | 825 | /* DSS HW IP initialisation */ |
| 753 | static int __init omap_dsshw_probe(struct platform_device *pdev) | 826 | static int __init omap_dsshw_probe(struct platform_device *pdev) |
| 754 | { | 827 | { |
| @@ -758,6 +831,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) | |||
| 758 | 831 | ||
| 759 | dss.pdev = pdev; | 832 | dss.pdev = pdev; |
| 760 | 833 | ||
| 834 | r = dss_init_features(&dss.pdev->dev); | ||
| 835 | if (r) | ||
| 836 | return r; | ||
| 837 | |||
| 761 | dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); | 838 | dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); |
| 762 | if (!dss_mem) { | 839 | if (!dss_mem) { |
| 763 | DSSERR("can't get IORESOURCE_MEM DSS\n"); | 840 | DSSERR("can't get IORESOURCE_MEM DSS\n"); |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index f67afe76f217..6728892f9dad 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
| @@ -113,6 +113,17 @@ enum dss_dsi_content_type { | |||
| 113 | DSS_DSI_CONTENT_GENERIC, | 113 | DSS_DSI_CONTENT_GENERIC, |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | enum dss_writeback_channel { | ||
| 117 | DSS_WB_LCD1_MGR = 0, | ||
| 118 | DSS_WB_LCD2_MGR = 1, | ||
| 119 | DSS_WB_TV_MGR = 2, | ||
| 120 | DSS_WB_OVL0 = 3, | ||
| 121 | DSS_WB_OVL1 = 4, | ||
| 122 | DSS_WB_OVL2 = 5, | ||
| 123 | DSS_WB_OVL3 = 6, | ||
| 124 | DSS_WB_LCD3_MGR = 7, | ||
| 125 | }; | ||
| 126 | |||
| 116 | struct dss_clock_info { | 127 | struct dss_clock_info { |
| 117 | /* rates that we get with dividers below */ | 128 | /* rates that we get with dividers below */ |
| 118 | unsigned long fck; | 129 | unsigned long fck; |
| @@ -175,6 +186,7 @@ struct seq_file; | |||
| 175 | struct platform_device; | 186 | struct platform_device; |
| 176 | 187 | ||
| 177 | /* core */ | 188 | /* core */ |
| 189 | const char *dss_get_default_display_name(void); | ||
| 178 | struct bus_type *dss_get_bus(void); | 190 | struct bus_type *dss_get_bus(void); |
| 179 | struct regulator *dss_get_vdds_dsi(void); | 191 | struct regulator *dss_get_vdds_dsi(void); |
| 180 | struct regulator *dss_get_vdds_sdi(void); | 192 | struct regulator *dss_get_vdds_sdi(void); |
| @@ -184,10 +196,13 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); | |||
| 184 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput); | 196 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput); |
| 185 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); | 197 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); |
| 186 | 198 | ||
| 187 | int omap_dss_register_device(struct omap_dss_device *dssdev, | 199 | struct omap_dss_device *dss_alloc_and_init_device(struct device *parent); |
| 188 | struct device *parent, int disp_num); | 200 | int dss_add_device(struct omap_dss_device *dssdev); |
| 189 | void omap_dss_unregister_device(struct omap_dss_device *dssdev); | 201 | void dss_unregister_device(struct omap_dss_device *dssdev); |
| 190 | void omap_dss_unregister_child_devices(struct device *parent); | 202 | void dss_unregister_child_devices(struct device *parent); |
| 203 | void dss_put_device(struct omap_dss_device *dssdev); | ||
| 204 | void dss_copy_device_pdata(struct omap_dss_device *dst, | ||
| 205 | const struct omap_dss_device *src); | ||
| 191 | 206 | ||
| 192 | /* apply */ | 207 | /* apply */ |
| 193 | void dss_apply_init(void); | 208 | void dss_apply_init(void); |
| @@ -205,8 +220,11 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, | |||
| 205 | int dss_mgr_set_device(struct omap_overlay_manager *mgr, | 220 | int dss_mgr_set_device(struct omap_overlay_manager *mgr, |
| 206 | struct omap_dss_device *dssdev); | 221 | struct omap_dss_device *dssdev); |
| 207 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr); | 222 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr); |
| 223 | int dss_mgr_set_output(struct omap_overlay_manager *mgr, | ||
| 224 | struct omap_dss_output *output); | ||
| 225 | int dss_mgr_unset_output(struct omap_overlay_manager *mgr); | ||
| 208 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, | 226 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, |
| 209 | struct omap_video_timings *timings); | 227 | const struct omap_video_timings *timings); |
| 210 | void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, | 228 | void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, |
| 211 | const struct dss_lcd_mgr_config *config); | 229 | const struct dss_lcd_mgr_config *config); |
| 212 | const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); | 230 | const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); |
| @@ -222,12 +240,17 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, | |||
| 222 | struct omap_overlay_manager *mgr); | 240 | struct omap_overlay_manager *mgr); |
| 223 | int dss_ovl_unset_manager(struct omap_overlay *ovl); | 241 | int dss_ovl_unset_manager(struct omap_overlay *ovl); |
| 224 | 242 | ||
| 243 | /* output */ | ||
| 244 | void dss_register_output(struct omap_dss_output *out); | ||
| 245 | void dss_unregister_output(struct omap_dss_output *out); | ||
| 246 | struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev); | ||
| 247 | |||
| 225 | /* display */ | 248 | /* display */ |
| 226 | int dss_suspend_all_devices(void); | 249 | int dss_suspend_all_devices(void); |
| 227 | int dss_resume_all_devices(void); | 250 | int dss_resume_all_devices(void); |
| 228 | void dss_disable_all_devices(void); | 251 | void dss_disable_all_devices(void); |
| 229 | 252 | ||
| 230 | void dss_init_device(struct platform_device *pdev, | 253 | int dss_init_device(struct platform_device *pdev, |
| 231 | struct omap_dss_device *dssdev); | 254 | struct omap_dss_device *dssdev); |
| 232 | void dss_uninit_device(struct platform_device *pdev, | 255 | void dss_uninit_device(struct platform_device *pdev, |
| 233 | struct omap_dss_device *dssdev); | 256 | struct omap_dss_device *dssdev); |
| @@ -254,22 +277,29 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id) | |||
| 254 | return false; | 277 | return false; |
| 255 | } | 278 | } |
| 256 | 279 | ||
| 280 | int dss_manager_kobj_init(struct omap_overlay_manager *mgr, | ||
| 281 | struct platform_device *pdev); | ||
| 282 | void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr); | ||
| 283 | |||
| 257 | /* overlay */ | 284 | /* overlay */ |
| 258 | void dss_init_overlays(struct platform_device *pdev); | 285 | void dss_init_overlays(struct platform_device *pdev); |
| 259 | void dss_uninit_overlays(struct platform_device *pdev); | 286 | void dss_uninit_overlays(struct platform_device *pdev); |
| 260 | void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); | 287 | void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); |
| 261 | void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); | ||
| 262 | int dss_ovl_simple_check(struct omap_overlay *ovl, | 288 | int dss_ovl_simple_check(struct omap_overlay *ovl, |
| 263 | const struct omap_overlay_info *info); | 289 | const struct omap_overlay_info *info); |
| 264 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, | 290 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, |
| 265 | const struct omap_video_timings *mgr_timings); | 291 | const struct omap_video_timings *mgr_timings); |
| 266 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, | 292 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, |
| 267 | enum omap_color_mode mode); | 293 | enum omap_color_mode mode); |
| 294 | int dss_overlay_kobj_init(struct omap_overlay *ovl, | ||
| 295 | struct platform_device *pdev); | ||
| 296 | void dss_overlay_kobj_uninit(struct omap_overlay *ovl); | ||
| 268 | 297 | ||
| 269 | /* DSS */ | 298 | /* DSS */ |
| 270 | int dss_init_platform_driver(void) __init; | 299 | int dss_init_platform_driver(void) __init; |
| 271 | void dss_uninit_platform_driver(void); | 300 | void dss_uninit_platform_driver(void); |
| 272 | 301 | ||
| 302 | int dss_dpi_select_source(enum omap_channel channel); | ||
| 273 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | 303 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); |
| 274 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); | 304 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); |
| 275 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | 305 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); |
| @@ -279,7 +309,7 @@ void dss_dump_clocks(struct seq_file *s); | |||
| 279 | void dss_debug_dump_clocks(struct seq_file *s); | 309 | void dss_debug_dump_clocks(struct seq_file *s); |
| 280 | #endif | 310 | #endif |
| 281 | 311 | ||
| 282 | void dss_sdi_init(u8 datapairs); | 312 | void dss_sdi_init(int datapairs); |
| 283 | int dss_sdi_enable(void); | 313 | int dss_sdi_enable(void); |
| 284 | void dss_sdi_disable(void); | 314 | void dss_sdi_disable(void); |
| 285 | 315 | ||
| @@ -296,9 +326,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type); | |||
| 296 | void dss_set_dac_pwrdn_bgz(bool enable); | 326 | void dss_set_dac_pwrdn_bgz(bool enable); |
| 297 | 327 | ||
| 298 | unsigned long dss_get_dpll4_rate(void); | 328 | unsigned long dss_get_dpll4_rate(void); |
| 299 | int dss_calc_clock_rates(struct dss_clock_info *cinfo); | ||
| 300 | int dss_set_clock_div(struct dss_clock_info *cinfo); | 329 | int dss_set_clock_div(struct dss_clock_info *cinfo); |
| 301 | int dss_get_clock_div(struct dss_clock_info *cinfo); | ||
| 302 | int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, | 330 | int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, |
| 303 | struct dispc_clock_info *dispc_cinfo); | 331 | struct dispc_clock_info *dispc_cinfo); |
| 304 | 332 | ||
| @@ -427,8 +455,9 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | |||
| 427 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | 455 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, |
| 428 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, | 456 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, |
| 429 | bool manual_update); | 457 | bool manual_update); |
| 430 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 458 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, |
| 431 | bool replication, const struct omap_video_timings *mgr_timings); | 459 | bool replication, const struct omap_video_timings *mgr_timings, |
| 460 | bool mem_to_mem); | ||
| 432 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | 461 | int dispc_ovl_enable(enum omap_plane plane, bool enable); |
| 433 | void dispc_ovl_set_channel_out(enum omap_plane plane, | 462 | void dispc_ovl_set_channel_out(enum omap_plane plane, |
| 434 | enum omap_channel channel); | 463 | enum omap_channel channel); |
| @@ -457,6 +486,15 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, | |||
| 457 | void dispc_mgr_setup(enum omap_channel channel, | 486 | void dispc_mgr_setup(enum omap_channel channel, |
| 458 | struct omap_overlay_manager_info *info); | 487 | struct omap_overlay_manager_info *info); |
| 459 | 488 | ||
| 489 | u32 dispc_wb_get_framedone_irq(void); | ||
| 490 | bool dispc_wb_go_busy(void); | ||
| 491 | void dispc_wb_go(void); | ||
| 492 | void dispc_wb_enable(bool enable); | ||
| 493 | bool dispc_wb_is_enabled(void); | ||
| 494 | void dispc_wb_set_channel_in(enum dss_writeback_channel channel); | ||
| 495 | int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | ||
| 496 | bool mem_to_mem, const struct omap_video_timings *timings); | ||
| 497 | |||
| 460 | /* VENC */ | 498 | /* VENC */ |
| 461 | #ifdef CONFIG_OMAP2_DSS_VENC | 499 | #ifdef CONFIG_OMAP2_DSS_VENC |
| 462 | int venc_init_platform_driver(void) __init; | 500 | int venc_init_platform_driver(void) __init; |
| @@ -469,6 +507,20 @@ static inline unsigned long venc_get_pixel_clock(void) | |||
| 469 | return 0; | 507 | return 0; |
| 470 | } | 508 | } |
| 471 | #endif | 509 | #endif |
| 510 | int omapdss_venc_display_enable(struct omap_dss_device *dssdev); | ||
| 511 | void omapdss_venc_display_disable(struct omap_dss_device *dssdev); | ||
| 512 | void omapdss_venc_set_timings(struct omap_dss_device *dssdev, | ||
| 513 | struct omap_video_timings *timings); | ||
| 514 | int omapdss_venc_check_timings(struct omap_dss_device *dssdev, | ||
| 515 | struct omap_video_timings *timings); | ||
| 516 | u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev); | ||
| 517 | int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss); | ||
| 518 | void omapdss_venc_set_type(struct omap_dss_device *dssdev, | ||
| 519 | enum omap_dss_venc_type type); | ||
| 520 | void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, | ||
| 521 | bool invert_polarity); | ||
| 522 | int venc_panel_init(void); | ||
| 523 | void venc_panel_exit(void); | ||
| 472 | 524 | ||
| 473 | /* HDMI */ | 525 | /* HDMI */ |
| 474 | #ifdef CONFIG_OMAP4_DSS_HDMI | 526 | #ifdef CONFIG_OMAP4_DSS_HDMI |
| @@ -484,7 +536,8 @@ static inline unsigned long hdmi_get_pixel_clock(void) | |||
| 484 | #endif | 536 | #endif |
| 485 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); | 537 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); |
| 486 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); | 538 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); |
| 487 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); | 539 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, |
| 540 | struct omap_video_timings *timings); | ||
| 488 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | 541 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, |
| 489 | struct omap_video_timings *timings); | 542 | struct omap_video_timings *timings); |
| 490 | int omapdss_hdmi_read_edid(u8 *buf, int len); | 543 | int omapdss_hdmi_read_edid(u8 *buf, int len); |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 938709724f0c..acbc1e1efba3 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
| @@ -46,7 +46,9 @@ struct omap_dss_features { | |||
| 46 | 46 | ||
| 47 | const int num_mgrs; | 47 | const int num_mgrs; |
| 48 | const int num_ovls; | 48 | const int num_ovls; |
| 49 | const int num_wbs; | ||
| 49 | const enum omap_display_type *supported_displays; | 50 | const enum omap_display_type *supported_displays; |
| 51 | const enum omap_dss_output_id *supported_outputs; | ||
| 50 | const enum omap_color_mode *supported_color_modes; | 52 | const enum omap_color_mode *supported_color_modes; |
| 51 | const enum omap_overlay_caps *overlay_caps; | 53 | const enum omap_overlay_caps *overlay_caps; |
| 52 | const char * const *clksrc_names; | 54 | const char * const *clksrc_names; |
| @@ -106,6 +108,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = { | |||
| 106 | [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, | 108 | [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, |
| 107 | }; | 109 | }; |
| 108 | 110 | ||
| 111 | static const struct dss_reg_field omap5_dss_reg_fields[] = { | ||
| 112 | [FEAT_REG_FIRHINC] = { 12, 0 }, | ||
| 113 | [FEAT_REG_FIRVINC] = { 28, 16 }, | ||
| 114 | [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, | ||
| 115 | [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, | ||
| 116 | [FEAT_REG_FIFOSIZE] = { 15, 0 }, | ||
| 117 | [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, | ||
| 118 | [FEAT_REG_VERTICALACCU] = { 26, 16 }, | ||
| 119 | [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 }, | ||
| 120 | [FEAT_REG_DSIPLL_REGN] = { 8, 1 }, | ||
| 121 | [FEAT_REG_DSIPLL_REGM] = { 20, 9 }, | ||
| 122 | [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 }, | ||
| 123 | [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, | ||
| 124 | }; | ||
| 125 | |||
| 109 | static const enum omap_display_type omap2_dss_supported_displays[] = { | 126 | static const enum omap_display_type omap2_dss_supported_displays[] = { |
| 110 | /* OMAP_DSS_CHANNEL_LCD */ | 127 | /* OMAP_DSS_CHANNEL_LCD */ |
| 111 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, | 128 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, |
| @@ -144,6 +161,76 @@ static const enum omap_display_type omap4_dss_supported_displays[] = { | |||
| 144 | OMAP_DISPLAY_TYPE_DSI, | 161 | OMAP_DISPLAY_TYPE_DSI, |
| 145 | }; | 162 | }; |
| 146 | 163 | ||
| 164 | static const enum omap_display_type omap5_dss_supported_displays[] = { | ||
| 165 | /* OMAP_DSS_CHANNEL_LCD */ | ||
| 166 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | | ||
| 167 | OMAP_DISPLAY_TYPE_DSI, | ||
| 168 | |||
| 169 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
| 170 | OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI, | ||
| 171 | |||
| 172 | /* OMAP_DSS_CHANNEL_LCD2 */ | ||
| 173 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | | ||
| 174 | OMAP_DISPLAY_TYPE_DSI, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static const enum omap_dss_output_id omap2_dss_supported_outputs[] = { | ||
| 178 | /* OMAP_DSS_CHANNEL_LCD */ | ||
| 179 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, | ||
| 180 | |||
| 181 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
| 182 | OMAP_DSS_OUTPUT_VENC, | ||
| 183 | }; | ||
| 184 | |||
| 185 | static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = { | ||
| 186 | /* OMAP_DSS_CHANNEL_LCD */ | ||
| 187 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 188 | OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1, | ||
| 189 | |||
| 190 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
| 191 | OMAP_DSS_OUTPUT_VENC, | ||
| 192 | }; | ||
| 193 | |||
| 194 | static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = { | ||
| 195 | /* OMAP_DSS_CHANNEL_LCD */ | ||
| 196 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 197 | OMAP_DSS_OUTPUT_DSI1, | ||
| 198 | |||
| 199 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
| 200 | OMAP_DSS_OUTPUT_VENC, | ||
| 201 | }; | ||
| 202 | |||
| 203 | static const enum omap_dss_output_id omap4_dss_supported_outputs[] = { | ||
| 204 | /* OMAP_DSS_CHANNEL_LCD */ | ||
| 205 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 206 | OMAP_DSS_OUTPUT_DSI1, | ||
| 207 | |||
| 208 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
| 209 | OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI | | ||
| 210 | OMAP_DSS_OUTPUT_DPI, | ||
| 211 | |||
| 212 | /* OMAP_DSS_CHANNEL_LCD2 */ | ||
| 213 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 214 | OMAP_DSS_OUTPUT_DSI2, | ||
| 215 | }; | ||
| 216 | |||
| 217 | static const enum omap_dss_output_id omap5_dss_supported_outputs[] = { | ||
| 218 | /* OMAP_DSS_CHANNEL_LCD */ | ||
| 219 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 220 | OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2, | ||
| 221 | |||
| 222 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
| 223 | OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI, | ||
| 224 | |||
| 225 | /* OMAP_DSS_CHANNEL_LCD2 */ | ||
| 226 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 227 | OMAP_DSS_OUTPUT_DSI1, | ||
| 228 | |||
| 229 | /* OMAP_DSS_CHANNEL_LCD3 */ | ||
| 230 | OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | | ||
| 231 | OMAP_DSS_OUTPUT_DSI2, | ||
| 232 | }; | ||
| 233 | |||
| 147 | static const enum omap_color_mode omap2_dss_supported_color_modes[] = { | 234 | static const enum omap_color_mode omap2_dss_supported_color_modes[] = { |
| 148 | /* OMAP_DSS_GFX */ | 235 | /* OMAP_DSS_GFX */ |
| 149 | OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | | 236 | OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | |
| @@ -224,58 +311,80 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = { | |||
| 224 | OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | | 311 | OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | |
| 225 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | | 312 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | |
| 226 | OMAP_DSS_COLOR_RGBX32, | 313 | OMAP_DSS_COLOR_RGBX32, |
| 314 | |||
| 315 | /* OMAP_DSS_WB */ | ||
| 316 | OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | | ||
| 317 | OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | | ||
| 318 | OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | | ||
| 319 | OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | | ||
| 320 | OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | | ||
| 321 | OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | | ||
| 322 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | | ||
| 323 | OMAP_DSS_COLOR_RGBX32, | ||
| 227 | }; | 324 | }; |
| 228 | 325 | ||
| 229 | static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { | 326 | static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { |
| 230 | /* OMAP_DSS_GFX */ | 327 | /* OMAP_DSS_GFX */ |
| 231 | 0, | 328 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, |
| 232 | 329 | ||
| 233 | /* OMAP_DSS_VIDEO1 */ | 330 | /* OMAP_DSS_VIDEO1 */ |
| 234 | OMAP_DSS_OVL_CAP_SCALE, | 331 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
| 332 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 235 | 333 | ||
| 236 | /* OMAP_DSS_VIDEO2 */ | 334 | /* OMAP_DSS_VIDEO2 */ |
| 237 | OMAP_DSS_OVL_CAP_SCALE, | 335 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
| 336 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 238 | }; | 337 | }; |
| 239 | 338 | ||
| 240 | static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = { | 339 | static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = { |
| 241 | /* OMAP_DSS_GFX */ | 340 | /* OMAP_DSS_GFX */ |
| 242 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA, | 341 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS | |
| 342 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 243 | 343 | ||
| 244 | /* OMAP_DSS_VIDEO1 */ | 344 | /* OMAP_DSS_VIDEO1 */ |
| 245 | OMAP_DSS_OVL_CAP_SCALE, | 345 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
| 346 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 246 | 347 | ||
| 247 | /* OMAP_DSS_VIDEO2 */ | 348 | /* OMAP_DSS_VIDEO2 */ |
| 248 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA, | 349 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
| 350 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 249 | }; | 351 | }; |
| 250 | 352 | ||
| 251 | static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = { | 353 | static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = { |
| 252 | /* OMAP_DSS_GFX */ | 354 | /* OMAP_DSS_GFX */ |
| 253 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA, | 355 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | |
| 356 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 254 | 357 | ||
| 255 | /* OMAP_DSS_VIDEO1 */ | 358 | /* OMAP_DSS_VIDEO1 */ |
| 256 | OMAP_DSS_OVL_CAP_SCALE, | 359 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
| 360 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 257 | 361 | ||
| 258 | /* OMAP_DSS_VIDEO2 */ | 362 | /* OMAP_DSS_VIDEO2 */ |
| 259 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 363 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
| 260 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA, | 364 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS | |
| 365 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 261 | }; | 366 | }; |
| 262 | 367 | ||
| 263 | static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { | 368 | static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { |
| 264 | /* OMAP_DSS_GFX */ | 369 | /* OMAP_DSS_GFX */ |
| 265 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | | 370 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | |
| 266 | OMAP_DSS_OVL_CAP_ZORDER, | 371 | OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS | |
| 372 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 267 | 373 | ||
| 268 | /* OMAP_DSS_VIDEO1 */ | 374 | /* OMAP_DSS_VIDEO1 */ |
| 269 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 375 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
| 270 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, | 376 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | |
| 377 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 271 | 378 | ||
| 272 | /* OMAP_DSS_VIDEO2 */ | 379 | /* OMAP_DSS_VIDEO2 */ |
| 273 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 380 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
| 274 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, | 381 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | |
| 382 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 275 | 383 | ||
| 276 | /* OMAP_DSS_VIDEO3 */ | 384 | /* OMAP_DSS_VIDEO3 */ |
| 277 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 385 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
| 278 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, | 386 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | |
| 387 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
| 279 | }; | 388 | }; |
| 280 | 389 | ||
| 281 | static const char * const omap2_dss_clk_source_names[] = { | 390 | static const char * const omap2_dss_clk_source_names[] = { |
| @@ -298,6 +407,14 @@ static const char * const omap4_dss_clk_source_names[] = { | |||
| 298 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", | 407 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", |
| 299 | }; | 408 | }; |
| 300 | 409 | ||
| 410 | static const char * const omap5_dss_clk_source_names[] = { | ||
| 411 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1", | ||
| 412 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2", | ||
| 413 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK", | ||
| 414 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1", | ||
| 415 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2", | ||
| 416 | }; | ||
| 417 | |||
| 301 | static const struct dss_param_range omap2_dss_param_range[] = { | 418 | static const struct dss_param_range omap2_dss_param_range[] = { |
| 302 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, | 419 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, |
| 303 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, | 420 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, |
| @@ -326,6 +443,7 @@ static const struct dss_param_range omap3_dss_param_range[] = { | |||
| 326 | [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 }, | 443 | [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 }, |
| 327 | [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 }, | 444 | [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 }, |
| 328 | [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, | 445 | [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, |
| 446 | [FEAT_PARAM_DSI_FCK] = { 0, 173000000 }, | ||
| 329 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, | 447 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, |
| 330 | [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, | 448 | [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, |
| 331 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | 449 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, |
| @@ -341,6 +459,23 @@ static const struct dss_param_range omap4_dss_param_range[] = { | |||
| 341 | [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, | 459 | [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, |
| 342 | [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, | 460 | [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, |
| 343 | [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, | 461 | [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, |
| 462 | [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, | ||
| 463 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, | ||
| 464 | [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, | ||
| 465 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | ||
| 466 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, | ||
| 467 | }; | ||
| 468 | |||
| 469 | static const struct dss_param_range omap5_dss_param_range[] = { | ||
| 470 | [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, | ||
| 471 | [FEAT_PARAM_DSS_PCD] = { 1, 255 }, | ||
| 472 | [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, | ||
| 473 | [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, | ||
| 474 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, | ||
| 475 | [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, | ||
| 476 | [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, | ||
| 477 | [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, | ||
| 478 | [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, | ||
| 344 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, | 479 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, |
| 345 | [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, | 480 | [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, |
| 346 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | 481 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, |
| @@ -373,6 +508,26 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = { | |||
| 373 | FEAT_ALPHA_FIXED_ZORDER, | 508 | FEAT_ALPHA_FIXED_ZORDER, |
| 374 | FEAT_FIFO_MERGE, | 509 | FEAT_FIFO_MERGE, |
| 375 | FEAT_OMAP3_DSI_FIFO_BUG, | 510 | FEAT_OMAP3_DSI_FIFO_BUG, |
| 511 | FEAT_DPI_USES_VDDS_DSI, | ||
| 512 | }; | ||
| 513 | |||
| 514 | static const enum dss_feat_id am35xx_dss_feat_list[] = { | ||
| 515 | FEAT_LCDENABLEPOL, | ||
| 516 | FEAT_LCDENABLESIGNAL, | ||
| 517 | FEAT_PCKFREEENABLE, | ||
| 518 | FEAT_FUNCGATED, | ||
| 519 | FEAT_LINEBUFFERSPLIT, | ||
| 520 | FEAT_ROWREPEATENABLE, | ||
| 521 | FEAT_RESIZECONF, | ||
| 522 | FEAT_DSI_PLL_FREQSEL, | ||
| 523 | FEAT_DSI_REVERSE_TXCLKESC, | ||
| 524 | FEAT_VENC_REQUIRES_TV_DAC_CLK, | ||
| 525 | FEAT_CPR, | ||
| 526 | FEAT_PRELOAD, | ||
| 527 | FEAT_FIR_COEF_V, | ||
| 528 | FEAT_ALPHA_FIXED_ZORDER, | ||
| 529 | FEAT_FIFO_MERGE, | ||
| 530 | FEAT_OMAP3_DSI_FIFO_BUG, | ||
| 376 | }; | 531 | }; |
| 377 | 532 | ||
| 378 | static const enum dss_feat_id omap3630_dss_feat_list[] = { | 533 | static const enum dss_feat_id omap3630_dss_feat_list[] = { |
| @@ -447,6 +602,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = { | |||
| 447 | FEAT_BURST_2D, | 602 | FEAT_BURST_2D, |
| 448 | }; | 603 | }; |
| 449 | 604 | ||
| 605 | static const enum dss_feat_id omap5_dss_feat_list[] = { | ||
| 606 | FEAT_MGR_LCD2, | ||
| 607 | FEAT_CORE_CLK_DIV, | ||
| 608 | FEAT_LCD_CLK_SRC, | ||
| 609 | FEAT_DSI_DCS_CMD_CONFIG_VC, | ||
| 610 | FEAT_DSI_VC_OCP_WIDTH, | ||
| 611 | FEAT_DSI_GNQ, | ||
| 612 | FEAT_HDMI_CTS_SWMODE, | ||
| 613 | FEAT_HDMI_AUDIO_USE_MCLK, | ||
| 614 | FEAT_HANDLE_UV_SEPARATE, | ||
| 615 | FEAT_ATTR2, | ||
| 616 | FEAT_CPR, | ||
| 617 | FEAT_PRELOAD, | ||
| 618 | FEAT_FIR_COEF_V, | ||
| 619 | FEAT_ALPHA_FREE_ZORDER, | ||
| 620 | FEAT_FIFO_MERGE, | ||
| 621 | FEAT_BURST_2D, | ||
| 622 | FEAT_DSI_PLL_SELFREQDCO, | ||
| 623 | FEAT_DSI_PLL_REFSEL, | ||
| 624 | FEAT_DSI_PHY_DCC, | ||
| 625 | }; | ||
| 626 | |||
| 450 | /* OMAP2 DSS Features */ | 627 | /* OMAP2 DSS Features */ |
| 451 | static const struct omap_dss_features omap2_dss_features = { | 628 | static const struct omap_dss_features omap2_dss_features = { |
| 452 | .reg_fields = omap2_dss_reg_fields, | 629 | .reg_fields = omap2_dss_reg_fields, |
| @@ -458,6 +635,7 @@ static const struct omap_dss_features omap2_dss_features = { | |||
| 458 | .num_mgrs = 2, | 635 | .num_mgrs = 2, |
| 459 | .num_ovls = 3, | 636 | .num_ovls = 3, |
| 460 | .supported_displays = omap2_dss_supported_displays, | 637 | .supported_displays = omap2_dss_supported_displays, |
| 638 | .supported_outputs = omap2_dss_supported_outputs, | ||
| 461 | .supported_color_modes = omap2_dss_supported_color_modes, | 639 | .supported_color_modes = omap2_dss_supported_color_modes, |
| 462 | .overlay_caps = omap2_dss_overlay_caps, | 640 | .overlay_caps = omap2_dss_overlay_caps, |
| 463 | .clksrc_names = omap2_dss_clk_source_names, | 641 | .clksrc_names = omap2_dss_clk_source_names, |
| @@ -478,6 +656,31 @@ static const struct omap_dss_features omap3430_dss_features = { | |||
| 478 | .num_mgrs = 2, | 656 | .num_mgrs = 2, |
| 479 | .num_ovls = 3, | 657 | .num_ovls = 3, |
| 480 | .supported_displays = omap3430_dss_supported_displays, | 658 | .supported_displays = omap3430_dss_supported_displays, |
| 659 | .supported_outputs = omap3430_dss_supported_outputs, | ||
| 660 | .supported_color_modes = omap3_dss_supported_color_modes, | ||
| 661 | .overlay_caps = omap3430_dss_overlay_caps, | ||
| 662 | .clksrc_names = omap3_dss_clk_source_names, | ||
| 663 | .dss_params = omap3_dss_param_range, | ||
| 664 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, | ||
| 665 | .buffer_size_unit = 1, | ||
| 666 | .burst_size_unit = 8, | ||
| 667 | }; | ||
| 668 | |||
| 669 | /* | ||
| 670 | * AM35xx DSS Features. This is basically OMAP3 DSS Features without the | ||
| 671 | * vdds_dsi regulator. | ||
| 672 | */ | ||
| 673 | static const struct omap_dss_features am35xx_dss_features = { | ||
| 674 | .reg_fields = omap3_dss_reg_fields, | ||
| 675 | .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), | ||
| 676 | |||
| 677 | .features = am35xx_dss_feat_list, | ||
| 678 | .num_features = ARRAY_SIZE(am35xx_dss_feat_list), | ||
| 679 | |||
| 680 | .num_mgrs = 2, | ||
| 681 | .num_ovls = 3, | ||
| 682 | .supported_displays = omap3430_dss_supported_displays, | ||
| 683 | .supported_outputs = omap3430_dss_supported_outputs, | ||
| 481 | .supported_color_modes = omap3_dss_supported_color_modes, | 684 | .supported_color_modes = omap3_dss_supported_color_modes, |
| 482 | .overlay_caps = omap3430_dss_overlay_caps, | 685 | .overlay_caps = omap3430_dss_overlay_caps, |
| 483 | .clksrc_names = omap3_dss_clk_source_names, | 686 | .clksrc_names = omap3_dss_clk_source_names, |
| @@ -497,6 +700,7 @@ static const struct omap_dss_features omap3630_dss_features = { | |||
| 497 | .num_mgrs = 2, | 700 | .num_mgrs = 2, |
| 498 | .num_ovls = 3, | 701 | .num_ovls = 3, |
| 499 | .supported_displays = omap3630_dss_supported_displays, | 702 | .supported_displays = omap3630_dss_supported_displays, |
| 703 | .supported_outputs = omap3630_dss_supported_outputs, | ||
| 500 | .supported_color_modes = omap3_dss_supported_color_modes, | 704 | .supported_color_modes = omap3_dss_supported_color_modes, |
| 501 | .overlay_caps = omap3630_dss_overlay_caps, | 705 | .overlay_caps = omap3630_dss_overlay_caps, |
| 502 | .clksrc_names = omap3_dss_clk_source_names, | 706 | .clksrc_names = omap3_dss_clk_source_names, |
| @@ -517,7 +721,9 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { | |||
| 517 | 721 | ||
| 518 | .num_mgrs = 3, | 722 | .num_mgrs = 3, |
| 519 | .num_ovls = 4, | 723 | .num_ovls = 4, |
| 724 | .num_wbs = 1, | ||
| 520 | .supported_displays = omap4_dss_supported_displays, | 725 | .supported_displays = omap4_dss_supported_displays, |
| 726 | .supported_outputs = omap4_dss_supported_outputs, | ||
| 521 | .supported_color_modes = omap4_dss_supported_color_modes, | 727 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 522 | .overlay_caps = omap4_dss_overlay_caps, | 728 | .overlay_caps = omap4_dss_overlay_caps, |
| 523 | .clksrc_names = omap4_dss_clk_source_names, | 729 | .clksrc_names = omap4_dss_clk_source_names, |
| @@ -537,7 +743,9 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { | |||
| 537 | 743 | ||
| 538 | .num_mgrs = 3, | 744 | .num_mgrs = 3, |
| 539 | .num_ovls = 4, | 745 | .num_ovls = 4, |
| 746 | .num_wbs = 1, | ||
| 540 | .supported_displays = omap4_dss_supported_displays, | 747 | .supported_displays = omap4_dss_supported_displays, |
| 748 | .supported_outputs = omap4_dss_supported_outputs, | ||
| 541 | .supported_color_modes = omap4_dss_supported_color_modes, | 749 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 542 | .overlay_caps = omap4_dss_overlay_caps, | 750 | .overlay_caps = omap4_dss_overlay_caps, |
| 543 | .clksrc_names = omap4_dss_clk_source_names, | 751 | .clksrc_names = omap4_dss_clk_source_names, |
| @@ -557,7 +765,9 @@ static const struct omap_dss_features omap4_dss_features = { | |||
| 557 | 765 | ||
| 558 | .num_mgrs = 3, | 766 | .num_mgrs = 3, |
| 559 | .num_ovls = 4, | 767 | .num_ovls = 4, |
| 768 | .num_wbs = 1, | ||
| 560 | .supported_displays = omap4_dss_supported_displays, | 769 | .supported_displays = omap4_dss_supported_displays, |
| 770 | .supported_outputs = omap4_dss_supported_outputs, | ||
| 561 | .supported_color_modes = omap4_dss_supported_color_modes, | 771 | .supported_color_modes = omap4_dss_supported_color_modes, |
| 562 | .overlay_caps = omap4_dss_overlay_caps, | 772 | .overlay_caps = omap4_dss_overlay_caps, |
| 563 | .clksrc_names = omap4_dss_clk_source_names, | 773 | .clksrc_names = omap4_dss_clk_source_names, |
| @@ -567,6 +777,27 @@ static const struct omap_dss_features omap4_dss_features = { | |||
| 567 | .burst_size_unit = 16, | 777 | .burst_size_unit = 16, |
| 568 | }; | 778 | }; |
| 569 | 779 | ||
| 780 | /* OMAP5 DSS Features */ | ||
| 781 | static const struct omap_dss_features omap5_dss_features = { | ||
| 782 | .reg_fields = omap5_dss_reg_fields, | ||
| 783 | .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields), | ||
| 784 | |||
| 785 | .features = omap5_dss_feat_list, | ||
| 786 | .num_features = ARRAY_SIZE(omap5_dss_feat_list), | ||
| 787 | |||
| 788 | .num_mgrs = 3, | ||
| 789 | .num_ovls = 4, | ||
| 790 | .supported_displays = omap5_dss_supported_displays, | ||
| 791 | .supported_outputs = omap5_dss_supported_outputs, | ||
| 792 | .supported_color_modes = omap4_dss_supported_color_modes, | ||
| 793 | .overlay_caps = omap4_dss_overlay_caps, | ||
| 794 | .clksrc_names = omap5_dss_clk_source_names, | ||
| 795 | .dss_params = omap5_dss_param_range, | ||
| 796 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | ||
| 797 | .buffer_size_unit = 16, | ||
| 798 | .burst_size_unit = 16, | ||
| 799 | }; | ||
| 800 | |||
| 570 | #if defined(CONFIG_OMAP4_DSS_HDMI) | 801 | #if defined(CONFIG_OMAP4_DSS_HDMI) |
| 571 | /* HDMI OMAP4 Functions*/ | 802 | /* HDMI OMAP4 Functions*/ |
| 572 | static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { | 803 | static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { |
| @@ -612,6 +843,11 @@ int dss_feat_get_num_ovls(void) | |||
| 612 | return omap_current_dss_features->num_ovls; | 843 | return omap_current_dss_features->num_ovls; |
| 613 | } | 844 | } |
| 614 | 845 | ||
| 846 | int dss_feat_get_num_wbs(void) | ||
| 847 | { | ||
| 848 | return omap_current_dss_features->num_wbs; | ||
| 849 | } | ||
| 850 | |||
| 615 | unsigned long dss_feat_get_param_min(enum dss_range_param param) | 851 | unsigned long dss_feat_get_param_min(enum dss_range_param param) |
| 616 | { | 852 | { |
| 617 | return omap_current_dss_features->dss_params[param].min; | 853 | return omap_current_dss_features->dss_params[param].min; |
| @@ -627,6 +863,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel | |||
| 627 | return omap_current_dss_features->supported_displays[channel]; | 863 | return omap_current_dss_features->supported_displays[channel]; |
| 628 | } | 864 | } |
| 629 | 865 | ||
| 866 | enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel) | ||
| 867 | { | ||
| 868 | return omap_current_dss_features->supported_outputs[channel]; | ||
| 869 | } | ||
| 870 | |||
| 630 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) | 871 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) |
| 631 | { | 872 | { |
| 632 | return omap_current_dss_features->supported_color_modes[plane]; | 873 | return omap_current_dss_features->supported_color_modes[plane]; |
| @@ -694,8 +935,13 @@ void dss_features_init(void) | |||
| 694 | omap_current_dss_features = &omap2_dss_features; | 935 | omap_current_dss_features = &omap2_dss_features; |
| 695 | else if (cpu_is_omap3630()) | 936 | else if (cpu_is_omap3630()) |
| 696 | omap_current_dss_features = &omap3630_dss_features; | 937 | omap_current_dss_features = &omap3630_dss_features; |
| 697 | else if (cpu_is_omap34xx()) | 938 | else if (cpu_is_omap34xx()) { |
| 698 | omap_current_dss_features = &omap3430_dss_features; | 939 | if (soc_is_am35xx()) { |
| 940 | omap_current_dss_features = &am35xx_dss_features; | ||
| 941 | } else { | ||
| 942 | omap_current_dss_features = &omap3430_dss_features; | ||
| 943 | } | ||
| 944 | } | ||
| 699 | else if (omap_rev() == OMAP4430_REV_ES1_0) | 945 | else if (omap_rev() == OMAP4430_REV_ES1_0) |
| 700 | omap_current_dss_features = &omap4430_es1_0_dss_features; | 946 | omap_current_dss_features = &omap4430_es1_0_dss_features; |
| 701 | else if (omap_rev() == OMAP4430_REV_ES2_0 || | 947 | else if (omap_rev() == OMAP4430_REV_ES2_0 || |
| @@ -704,6 +950,8 @@ void dss_features_init(void) | |||
| 704 | omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; | 950 | omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; |
| 705 | else if (cpu_is_omap44xx()) | 951 | else if (cpu_is_omap44xx()) |
| 706 | omap_current_dss_features = &omap4_dss_features; | 952 | omap_current_dss_features = &omap4_dss_features; |
| 953 | else if (soc_is_omap54xx()) | ||
| 954 | omap_current_dss_features = &omap5_dss_features; | ||
| 707 | else | 955 | else |
| 708 | DSSWARN("Unsupported OMAP version"); | 956 | DSSWARN("Unsupported OMAP version"); |
| 709 | } | 957 | } |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 996ffcbfed58..9218113b5e88 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
| @@ -50,6 +50,7 @@ enum dss_feat_id { | |||
| 50 | FEAT_DSI_VC_OCP_WIDTH, | 50 | FEAT_DSI_VC_OCP_WIDTH, |
| 51 | FEAT_DSI_REVERSE_TXCLKESC, | 51 | FEAT_DSI_REVERSE_TXCLKESC, |
| 52 | FEAT_DSI_GNQ, | 52 | FEAT_DSI_GNQ, |
| 53 | FEAT_DPI_USES_VDDS_DSI, | ||
| 53 | FEAT_HDMI_CTS_SWMODE, | 54 | FEAT_HDMI_CTS_SWMODE, |
| 54 | FEAT_HDMI_AUDIO_USE_MCLK, | 55 | FEAT_HDMI_AUDIO_USE_MCLK, |
| 55 | FEAT_HANDLE_UV_SEPARATE, | 56 | FEAT_HANDLE_UV_SEPARATE, |
| @@ -64,6 +65,9 @@ enum dss_feat_id { | |||
| 64 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ | 65 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ |
| 65 | FEAT_OMAP3_DSI_FIFO_BUG, | 66 | FEAT_OMAP3_DSI_FIFO_BUG, |
| 66 | FEAT_BURST_2D, | 67 | FEAT_BURST_2D, |
| 68 | FEAT_DSI_PLL_SELFREQDCO, | ||
| 69 | FEAT_DSI_PLL_REFSEL, | ||
| 70 | FEAT_DSI_PHY_DCC, | ||
| 67 | }; | 71 | }; |
| 68 | 72 | ||
| 69 | /* DSS register field id */ | 73 | /* DSS register field id */ |
| @@ -91,6 +95,7 @@ enum dss_range_param { | |||
| 91 | FEAT_PARAM_DSIPLL_REGM_DSI, | 95 | FEAT_PARAM_DSIPLL_REGM_DSI, |
| 92 | FEAT_PARAM_DSIPLL_FINT, | 96 | FEAT_PARAM_DSIPLL_FINT, |
| 93 | FEAT_PARAM_DSIPLL_LPDIV, | 97 | FEAT_PARAM_DSIPLL_LPDIV, |
| 98 | FEAT_PARAM_DSI_FCK, | ||
| 94 | FEAT_PARAM_DOWNSCALE, | 99 | FEAT_PARAM_DOWNSCALE, |
| 95 | FEAT_PARAM_LINEWIDTH, | 100 | FEAT_PARAM_LINEWIDTH, |
| 96 | FEAT_PARAM_MGR_WIDTH, | 101 | FEAT_PARAM_MGR_WIDTH, |
| @@ -100,9 +105,11 @@ enum dss_range_param { | |||
| 100 | /* DSS Feature Functions */ | 105 | /* DSS Feature Functions */ |
| 101 | int dss_feat_get_num_mgrs(void); | 106 | int dss_feat_get_num_mgrs(void); |
| 102 | int dss_feat_get_num_ovls(void); | 107 | int dss_feat_get_num_ovls(void); |
| 108 | int dss_feat_get_num_wbs(void); | ||
| 103 | unsigned long dss_feat_get_param_min(enum dss_range_param param); | 109 | unsigned long dss_feat_get_param_min(enum dss_range_param param); |
| 104 | unsigned long dss_feat_get_param_max(enum dss_range_param param); | 110 | unsigned long dss_feat_get_param_max(enum dss_range_param param); |
| 105 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); | 111 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); |
| 112 | enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel); | ||
| 106 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); | 113 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); |
| 107 | enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); | 114 | enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); |
| 108 | bool dss_feat_color_mode_supported(enum omap_plane plane, | 115 | bool dss_feat_color_mode_supported(enum omap_plane plane, |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 060216fdc578..a48a7dd75b33 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
| 34 | #include <linux/clk.h> | 34 | #include <linux/clk.h> |
| 35 | #include <linux/gpio.h> | ||
| 36 | #include <linux/regulator/consumer.h> | ||
| 35 | #include <video/omapdss.h> | 37 | #include <video/omapdss.h> |
| 36 | 38 | ||
| 37 | #include "ti_hdmi.h" | 39 | #include "ti_hdmi.h" |
| @@ -61,6 +63,13 @@ static struct { | |||
| 61 | struct hdmi_ip_data ip_data; | 63 | struct hdmi_ip_data ip_data; |
| 62 | 64 | ||
| 63 | struct clk *sys_clk; | 65 | struct clk *sys_clk; |
| 66 | struct regulator *vdda_hdmi_dac_reg; | ||
| 67 | |||
| 68 | int ct_cp_hpd_gpio; | ||
| 69 | int ls_oe_gpio; | ||
| 70 | int hpd_gpio; | ||
| 71 | |||
| 72 | struct omap_dss_output output; | ||
| 64 | } hdmi; | 73 | } hdmi; |
| 65 | 74 | ||
| 66 | /* | 75 | /* |
| @@ -314,12 +323,47 @@ static void hdmi_runtime_put(void) | |||
| 314 | 323 | ||
| 315 | static int __init hdmi_init_display(struct omap_dss_device *dssdev) | 324 | static int __init hdmi_init_display(struct omap_dss_device *dssdev) |
| 316 | { | 325 | { |
| 326 | int r; | ||
| 327 | |||
| 328 | struct gpio gpios[] = { | ||
| 329 | { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" }, | ||
| 330 | { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" }, | ||
| 331 | { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" }, | ||
| 332 | }; | ||
| 333 | |||
| 317 | DSSDBG("init_display\n"); | 334 | DSSDBG("init_display\n"); |
| 318 | 335 | ||
| 319 | dss_init_hdmi_ip_ops(&hdmi.ip_data); | 336 | dss_init_hdmi_ip_ops(&hdmi.ip_data); |
| 337 | |||
| 338 | if (hdmi.vdda_hdmi_dac_reg == NULL) { | ||
| 339 | struct regulator *reg; | ||
| 340 | |||
| 341 | reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); | ||
| 342 | |||
| 343 | if (IS_ERR(reg)) { | ||
| 344 | DSSERR("can't get VDDA_HDMI_DAC regulator\n"); | ||
| 345 | return PTR_ERR(reg); | ||
| 346 | } | ||
| 347 | |||
| 348 | hdmi.vdda_hdmi_dac_reg = reg; | ||
| 349 | } | ||
| 350 | |||
| 351 | r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); | ||
| 352 | if (r) | ||
| 353 | return r; | ||
| 354 | |||
| 320 | return 0; | 355 | return 0; |
| 321 | } | 356 | } |
| 322 | 357 | ||
| 358 | static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev) | ||
| 359 | { | ||
| 360 | DSSDBG("uninit_display\n"); | ||
| 361 | |||
| 362 | gpio_free(hdmi.ct_cp_hpd_gpio); | ||
| 363 | gpio_free(hdmi.ls_oe_gpio); | ||
| 364 | gpio_free(hdmi.hpd_gpio); | ||
| 365 | } | ||
| 366 | |||
| 323 | static const struct hdmi_config *hdmi_find_timing( | 367 | static const struct hdmi_config *hdmi_find_timing( |
| 324 | const struct hdmi_config *timings_arr, | 368 | const struct hdmi_config *timings_arr, |
| 325 | int len) | 369 | int len) |
| @@ -459,32 +503,30 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, | |||
| 459 | static int hdmi_power_on(struct omap_dss_device *dssdev) | 503 | static int hdmi_power_on(struct omap_dss_device *dssdev) |
| 460 | { | 504 | { |
| 461 | int r; | 505 | int r; |
| 462 | const struct hdmi_config *timing; | ||
| 463 | struct omap_video_timings *p; | 506 | struct omap_video_timings *p; |
| 507 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 464 | unsigned long phy; | 508 | unsigned long phy; |
| 465 | 509 | ||
| 510 | gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); | ||
| 511 | gpio_set_value(hdmi.ls_oe_gpio, 1); | ||
| 512 | |||
| 513 | /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */ | ||
| 514 | udelay(300); | ||
| 515 | |||
| 516 | r = regulator_enable(hdmi.vdda_hdmi_dac_reg); | ||
| 517 | if (r) | ||
| 518 | goto err_vdac_enable; | ||
| 519 | |||
| 466 | r = hdmi_runtime_get(); | 520 | r = hdmi_runtime_get(); |
| 467 | if (r) | 521 | if (r) |
| 468 | return r; | 522 | goto err_runtime_get; |
| 469 | 523 | ||
| 470 | dss_mgr_disable(dssdev->manager); | 524 | dss_mgr_disable(mgr); |
| 471 | 525 | ||
| 472 | p = &dssdev->panel.timings; | 526 | p = &hdmi.ip_data.cfg.timings; |
| 473 | 527 | ||
| 474 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", | 528 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); |
| 475 | dssdev->panel.timings.x_res, | ||
| 476 | dssdev->panel.timings.y_res); | ||
| 477 | 529 | ||
| 478 | timing = hdmi_get_timings(); | ||
| 479 | if (timing == NULL) { | ||
| 480 | /* HDMI code 4 corresponds to 640 * 480 VGA */ | ||
| 481 | hdmi.ip_data.cfg.cm.code = 4; | ||
| 482 | /* DVI mode 1 corresponds to HDMI 0 to DVI */ | ||
| 483 | hdmi.ip_data.cfg.cm.mode = HDMI_DVI; | ||
| 484 | hdmi.ip_data.cfg = vesa_timings[0]; | ||
| 485 | } else { | ||
| 486 | hdmi.ip_data.cfg = *timing; | ||
| 487 | } | ||
| 488 | phy = p->pixel_clock; | 530 | phy = p->pixel_clock; |
| 489 | 531 | ||
| 490 | hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); | 532 | hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); |
| @@ -495,13 +537,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) | |||
| 495 | r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); | 537 | r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); |
| 496 | if (r) { | 538 | if (r) { |
| 497 | DSSDBG("Failed to lock PLL\n"); | 539 | DSSDBG("Failed to lock PLL\n"); |
| 498 | goto err; | 540 | goto err_pll_enable; |
| 499 | } | 541 | } |
| 500 | 542 | ||
| 501 | r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); | 543 | r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); |
| 502 | if (r) { | 544 | if (r) { |
| 503 | DSSDBG("Failed to start PHY\n"); | 545 | DSSDBG("Failed to start PHY\n"); |
| 504 | goto err; | 546 | goto err_phy_enable; |
| 505 | } | 547 | } |
| 506 | 548 | ||
| 507 | hdmi.ip_data.ops->video_configure(&hdmi.ip_data); | 549 | hdmi.ip_data.ops->video_configure(&hdmi.ip_data); |
| @@ -521,13 +563,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) | |||
| 521 | dispc_enable_gamma_table(0); | 563 | dispc_enable_gamma_table(0); |
| 522 | 564 | ||
| 523 | /* tv size */ | 565 | /* tv size */ |
| 524 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); | 566 | dss_mgr_set_timings(mgr, p); |
| 525 | 567 | ||
| 526 | r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); | 568 | r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); |
| 527 | if (r) | 569 | if (r) |
| 528 | goto err_vid_enable; | 570 | goto err_vid_enable; |
| 529 | 571 | ||
| 530 | r = dss_mgr_enable(dssdev->manager); | 572 | r = dss_mgr_enable(mgr); |
| 531 | if (r) | 573 | if (r) |
| 532 | goto err_mgr_enable; | 574 | goto err_mgr_enable; |
| 533 | 575 | ||
| @@ -537,20 +579,33 @@ err_mgr_enable: | |||
| 537 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); | 579 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); |
| 538 | err_vid_enable: | 580 | err_vid_enable: |
| 539 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); | 581 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); |
| 582 | err_phy_enable: | ||
| 540 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); | 583 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); |
| 541 | err: | 584 | err_pll_enable: |
| 542 | hdmi_runtime_put(); | 585 | hdmi_runtime_put(); |
| 586 | err_runtime_get: | ||
| 587 | regulator_disable(hdmi.vdda_hdmi_dac_reg); | ||
| 588 | err_vdac_enable: | ||
| 589 | gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); | ||
| 590 | gpio_set_value(hdmi.ls_oe_gpio, 0); | ||
| 543 | return -EIO; | 591 | return -EIO; |
| 544 | } | 592 | } |
| 545 | 593 | ||
| 546 | static void hdmi_power_off(struct omap_dss_device *dssdev) | 594 | static void hdmi_power_off(struct omap_dss_device *dssdev) |
| 547 | { | 595 | { |
| 548 | dss_mgr_disable(dssdev->manager); | 596 | struct omap_overlay_manager *mgr = dssdev->output->manager; |
| 597 | |||
| 598 | dss_mgr_disable(mgr); | ||
| 549 | 599 | ||
| 550 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); | 600 | hdmi.ip_data.ops->video_disable(&hdmi.ip_data); |
| 551 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); | 601 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); |
| 552 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); | 602 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); |
| 553 | hdmi_runtime_put(); | 603 | hdmi_runtime_put(); |
| 604 | |||
| 605 | regulator_disable(hdmi.vdda_hdmi_dac_reg); | ||
| 606 | |||
| 607 | gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); | ||
| 608 | gpio_set_value(hdmi.ls_oe_gpio, 0); | ||
| 554 | } | 609 | } |
| 555 | 610 | ||
| 556 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | 611 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, |
| @@ -567,25 +622,22 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | |||
| 567 | 622 | ||
| 568 | } | 623 | } |
| 569 | 624 | ||
| 570 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) | 625 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, |
| 626 | struct omap_video_timings *timings) | ||
| 571 | { | 627 | { |
| 572 | struct hdmi_cm cm; | 628 | struct hdmi_cm cm; |
| 629 | const struct hdmi_config *t; | ||
| 573 | 630 | ||
| 574 | cm = hdmi_get_code(&dssdev->panel.timings); | 631 | mutex_lock(&hdmi.lock); |
| 575 | hdmi.ip_data.cfg.cm.code = cm.code; | ||
| 576 | hdmi.ip_data.cfg.cm.mode = cm.mode; | ||
| 577 | 632 | ||
| 578 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | 633 | cm = hdmi_get_code(timings); |
| 579 | int r; | 634 | hdmi.ip_data.cfg.cm = cm; |
| 580 | 635 | ||
| 581 | hdmi_power_off(dssdev); | 636 | t = hdmi_get_timings(); |
| 637 | if (t != NULL) | ||
| 638 | hdmi.ip_data.cfg = *t; | ||
| 582 | 639 | ||
| 583 | r = hdmi_power_on(dssdev); | 640 | mutex_unlock(&hdmi.lock); |
| 584 | if (r) | ||
| 585 | DSSERR("failed to power on device\n"); | ||
| 586 | } else { | ||
| 587 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); | ||
| 588 | } | ||
| 589 | } | 641 | } |
| 590 | 642 | ||
| 591 | static void hdmi_dump_regs(struct seq_file *s) | 643 | static void hdmi_dump_regs(struct seq_file *s) |
| @@ -640,20 +692,20 @@ bool omapdss_hdmi_detect(void) | |||
| 640 | 692 | ||
| 641 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) | 693 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) |
| 642 | { | 694 | { |
| 643 | struct omap_dss_hdmi_data *priv = dssdev->data; | 695 | struct omap_dss_output *out = dssdev->output; |
| 644 | int r = 0; | 696 | int r = 0; |
| 645 | 697 | ||
| 646 | DSSDBG("ENTER hdmi_display_enable\n"); | 698 | DSSDBG("ENTER hdmi_display_enable\n"); |
| 647 | 699 | ||
| 648 | mutex_lock(&hdmi.lock); | 700 | mutex_lock(&hdmi.lock); |
| 649 | 701 | ||
| 650 | if (dssdev->manager == NULL) { | 702 | if (out == NULL || out->manager == NULL) { |
| 651 | DSSERR("failed to enable display: no manager\n"); | 703 | DSSERR("failed to enable display: no output/manager\n"); |
| 652 | r = -ENODEV; | 704 | r = -ENODEV; |
| 653 | goto err0; | 705 | goto err0; |
| 654 | } | 706 | } |
| 655 | 707 | ||
| 656 | hdmi.ip_data.hpd_gpio = priv->hpd_gpio; | 708 | hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio; |
| 657 | 709 | ||
| 658 | r = omap_dss_start_device(dssdev); | 710 | r = omap_dss_start_device(dssdev); |
| 659 | if (r) { | 711 | if (r) { |
| @@ -661,26 +713,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) | |||
| 661 | goto err0; | 713 | goto err0; |
| 662 | } | 714 | } |
| 663 | 715 | ||
| 664 | if (dssdev->platform_enable) { | ||
| 665 | r = dssdev->platform_enable(dssdev); | ||
| 666 | if (r) { | ||
| 667 | DSSERR("failed to enable GPIO's\n"); | ||
| 668 | goto err1; | ||
| 669 | } | ||
| 670 | } | ||
| 671 | |||
| 672 | r = hdmi_power_on(dssdev); | 716 | r = hdmi_power_on(dssdev); |
| 673 | if (r) { | 717 | if (r) { |
| 674 | DSSERR("failed to power on device\n"); | 718 | DSSERR("failed to power on device\n"); |
| 675 | goto err2; | 719 | goto err1; |
| 676 | } | 720 | } |
| 677 | 721 | ||
| 678 | mutex_unlock(&hdmi.lock); | 722 | mutex_unlock(&hdmi.lock); |
| 679 | return 0; | 723 | return 0; |
| 680 | 724 | ||
| 681 | err2: | ||
| 682 | if (dssdev->platform_disable) | ||
| 683 | dssdev->platform_disable(dssdev); | ||
| 684 | err1: | 725 | err1: |
| 685 | omap_dss_stop_device(dssdev); | 726 | omap_dss_stop_device(dssdev); |
| 686 | err0: | 727 | err0: |
| @@ -696,9 +737,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) | |||
| 696 | 737 | ||
| 697 | hdmi_power_off(dssdev); | 738 | hdmi_power_off(dssdev); |
| 698 | 739 | ||
| 699 | if (dssdev->platform_disable) | ||
| 700 | dssdev->platform_disable(dssdev); | ||
| 701 | |||
| 702 | omap_dss_stop_device(dssdev); | 740 | omap_dss_stop_device(dssdev); |
| 703 | 741 | ||
| 704 | mutex_unlock(&hdmi.lock); | 742 | mutex_unlock(&hdmi.lock); |
| @@ -869,10 +907,14 @@ int hdmi_audio_config(struct omap_dss_audio *audio) | |||
| 869 | 907 | ||
| 870 | #endif | 908 | #endif |
| 871 | 909 | ||
| 872 | static void __init hdmi_probe_pdata(struct platform_device *pdev) | 910 | static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev) |
| 873 | { | 911 | { |
| 874 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | 912 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
| 875 | int r, i; | 913 | const char *def_disp_name = dss_get_default_display_name(); |
| 914 | struct omap_dss_device *def_dssdev; | ||
| 915 | int i; | ||
| 916 | |||
| 917 | def_dssdev = NULL; | ||
| 876 | 918 | ||
| 877 | for (i = 0; i < pdata->num_devices; ++i) { | 919 | for (i = 0; i < pdata->num_devices; ++i) { |
| 878 | struct omap_dss_device *dssdev = pdata->devices[i]; | 920 | struct omap_dss_device *dssdev = pdata->devices[i]; |
| @@ -880,17 +922,76 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev) | |||
| 880 | if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) | 922 | if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) |
| 881 | continue; | 923 | continue; |
| 882 | 924 | ||
| 883 | r = hdmi_init_display(dssdev); | 925 | if (def_dssdev == NULL) |
| 884 | if (r) { | 926 | def_dssdev = dssdev; |
| 885 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 927 | |
| 886 | continue; | 928 | if (def_disp_name != NULL && |
| 929 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
| 930 | def_dssdev = dssdev; | ||
| 931 | break; | ||
| 887 | } | 932 | } |
| 933 | } | ||
| 888 | 934 | ||
| 889 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | 935 | return def_dssdev; |
| 890 | if (r) | 936 | } |
| 891 | DSSERR("device %s register failed: %d\n", | 937 | |
| 892 | dssdev->name, r); | 938 | static void __init hdmi_probe_pdata(struct platform_device *pdev) |
| 939 | { | ||
| 940 | struct omap_dss_device *plat_dssdev; | ||
| 941 | struct omap_dss_device *dssdev; | ||
| 942 | struct omap_dss_hdmi_data *priv; | ||
| 943 | int r; | ||
| 944 | |||
| 945 | plat_dssdev = hdmi_find_dssdev(pdev); | ||
| 946 | |||
| 947 | if (!plat_dssdev) | ||
| 948 | return; | ||
| 949 | |||
| 950 | dssdev = dss_alloc_and_init_device(&pdev->dev); | ||
| 951 | if (!dssdev) | ||
| 952 | return; | ||
| 953 | |||
| 954 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
| 955 | |||
| 956 | priv = dssdev->data; | ||
| 957 | |||
| 958 | hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio; | ||
| 959 | hdmi.ls_oe_gpio = priv->ls_oe_gpio; | ||
| 960 | hdmi.hpd_gpio = priv->hpd_gpio; | ||
| 961 | |||
| 962 | dssdev->channel = OMAP_DSS_CHANNEL_DIGIT; | ||
| 963 | |||
| 964 | r = hdmi_init_display(dssdev); | ||
| 965 | if (r) { | ||
| 966 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
| 967 | dss_put_device(dssdev); | ||
| 968 | return; | ||
| 893 | } | 969 | } |
| 970 | |||
| 971 | r = dss_add_device(dssdev); | ||
| 972 | if (r) { | ||
| 973 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
| 974 | dss_put_device(dssdev); | ||
| 975 | return; | ||
| 976 | } | ||
| 977 | } | ||
| 978 | |||
| 979 | static void __init hdmi_init_output(struct platform_device *pdev) | ||
| 980 | { | ||
| 981 | struct omap_dss_output *out = &hdmi.output; | ||
| 982 | |||
| 983 | out->pdev = pdev; | ||
| 984 | out->id = OMAP_DSS_OUTPUT_HDMI; | ||
| 985 | out->type = OMAP_DISPLAY_TYPE_HDMI; | ||
| 986 | |||
| 987 | dss_register_output(out); | ||
| 988 | } | ||
| 989 | |||
| 990 | static void __exit hdmi_uninit_output(struct platform_device *pdev) | ||
| 991 | { | ||
| 992 | struct omap_dss_output *out = &hdmi.output; | ||
| 993 | |||
| 994 | dss_unregister_output(out); | ||
| 894 | } | 995 | } |
| 895 | 996 | ||
| 896 | /* HDMI HW IP initialisation */ | 997 | /* HDMI HW IP initialisation */ |
| @@ -929,23 +1030,37 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev) | |||
| 929 | hdmi.ip_data.core_av_offset = HDMI_CORE_AV; | 1030 | hdmi.ip_data.core_av_offset = HDMI_CORE_AV; |
| 930 | hdmi.ip_data.pll_offset = HDMI_PLLCTRL; | 1031 | hdmi.ip_data.pll_offset = HDMI_PLLCTRL; |
| 931 | hdmi.ip_data.phy_offset = HDMI_PHY; | 1032 | hdmi.ip_data.phy_offset = HDMI_PHY; |
| 1033 | |||
| 932 | mutex_init(&hdmi.ip_data.lock); | 1034 | mutex_init(&hdmi.ip_data.lock); |
| 933 | 1035 | ||
| 934 | hdmi_panel_init(); | 1036 | hdmi_panel_init(); |
| 935 | 1037 | ||
| 936 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); | 1038 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); |
| 937 | 1039 | ||
| 1040 | hdmi_init_output(pdev); | ||
| 1041 | |||
| 938 | hdmi_probe_pdata(pdev); | 1042 | hdmi_probe_pdata(pdev); |
| 939 | 1043 | ||
| 940 | return 0; | 1044 | return 0; |
| 941 | } | 1045 | } |
| 942 | 1046 | ||
| 1047 | static int __exit hdmi_remove_child(struct device *dev, void *data) | ||
| 1048 | { | ||
| 1049 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
| 1050 | hdmi_uninit_display(dssdev); | ||
| 1051 | return 0; | ||
| 1052 | } | ||
| 1053 | |||
| 943 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | 1054 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) |
| 944 | { | 1055 | { |
| 945 | omap_dss_unregister_child_devices(&pdev->dev); | 1056 | device_for_each_child(&pdev->dev, NULL, hdmi_remove_child); |
| 1057 | |||
| 1058 | dss_unregister_child_devices(&pdev->dev); | ||
| 946 | 1059 | ||
| 947 | hdmi_panel_exit(); | 1060 | hdmi_panel_exit(); |
| 948 | 1061 | ||
| 1062 | hdmi_uninit_output(pdev); | ||
| 1063 | |||
| 949 | pm_runtime_disable(&pdev->dev); | 1064 | pm_runtime_disable(&pdev->dev); |
| 950 | 1065 | ||
| 951 | hdmi_put_clocks(); | 1066 | hdmi_put_clocks(); |
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c index e10844faadf9..69fb115bab32 100644 --- a/drivers/video/omap2/dss/hdmi_panel.c +++ b/drivers/video/omap2/dss/hdmi_panel.c | |||
| @@ -41,17 +41,34 @@ static struct { | |||
| 41 | 41 | ||
| 42 | static int hdmi_panel_probe(struct omap_dss_device *dssdev) | 42 | static int hdmi_panel_probe(struct omap_dss_device *dssdev) |
| 43 | { | 43 | { |
| 44 | /* Initialize default timings to VGA in DVI mode */ | ||
| 45 | const struct omap_video_timings default_timings = { | ||
| 46 | .x_res = 640, | ||
| 47 | .y_res = 480, | ||
| 48 | .pixel_clock = 25175, | ||
| 49 | .hsw = 96, | ||
| 50 | .hfp = 16, | ||
| 51 | .hbp = 48, | ||
| 52 | .vsw = 2, | ||
| 53 | .vfp = 11, | ||
| 54 | .vbp = 31, | ||
| 55 | |||
| 56 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
| 57 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
| 58 | |||
| 59 | .interlace = false, | ||
| 60 | }; | ||
| 61 | |||
| 44 | DSSDBG("ENTER hdmi_panel_probe\n"); | 62 | DSSDBG("ENTER hdmi_panel_probe\n"); |
| 45 | 63 | ||
| 46 | dssdev->panel.timings = (struct omap_video_timings) | 64 | dssdev->panel.timings = default_timings; |
| 47 | { 640, 480, 25175, 96, 16, 48, 2, 11, 31, | ||
| 48 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
| 49 | false, | ||
| 50 | }; | ||
| 51 | 65 | ||
| 52 | DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", | 66 | DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", |
| 53 | dssdev->panel.timings.x_res, | 67 | dssdev->panel.timings.x_res, |
| 54 | dssdev->panel.timings.y_res); | 68 | dssdev->panel.timings.y_res); |
| 69 | |||
| 70 | omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings); | ||
| 71 | |||
| 55 | return 0; | 72 | return 0; |
| 56 | } | 73 | } |
| 57 | 74 | ||
| @@ -228,6 +245,8 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev) | |||
| 228 | goto err; | 245 | goto err; |
| 229 | } | 246 | } |
| 230 | 247 | ||
| 248 | omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings); | ||
| 249 | |||
| 231 | r = omapdss_hdmi_display_enable(dssdev); | 250 | r = omapdss_hdmi_display_enable(dssdev); |
| 232 | if (r) { | 251 | if (r) { |
| 233 | DSSERR("failed to power on\n"); | 252 | DSSERR("failed to power on\n"); |
| @@ -336,8 +355,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev, | |||
| 336 | */ | 355 | */ |
| 337 | hdmi_panel_audio_disable(dssdev); | 356 | hdmi_panel_audio_disable(dssdev); |
| 338 | 357 | ||
| 358 | omapdss_hdmi_display_set_timing(dssdev, timings); | ||
| 339 | dssdev->panel.timings = *timings; | 359 | dssdev->panel.timings = *timings; |
| 340 | omapdss_hdmi_display_set_timing(dssdev); | ||
| 341 | 360 | ||
| 342 | mutex_unlock(&hdmi.lock); | 361 | mutex_unlock(&hdmi.lock); |
| 343 | } | 362 | } |
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c new file mode 100644 index 000000000000..9a2fb59b6f89 --- /dev/null +++ b/drivers/video/omap2/dss/manager-sysfs.c | |||
| @@ -0,0 +1,512 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Nokia Corporation | ||
| 3 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
| 4 | * | ||
| 5 | * Some code and ideas taken from drivers/video/omap/ driver | ||
| 6 | * by Imre Deak. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License version 2 as published by | ||
| 10 | * the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 15 | * more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License along with | ||
| 18 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #define DSS_SUBSYS_NAME "MANAGER" | ||
| 22 | |||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/jiffies.h> | ||
| 28 | |||
| 29 | #include <video/omapdss.h> | ||
| 30 | |||
| 31 | #include "dss.h" | ||
| 32 | #include "dss_features.h" | ||
| 33 | |||
| 34 | static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) | ||
| 35 | { | ||
| 36 | return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name); | ||
| 37 | } | ||
| 38 | |||
| 39 | static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) | ||
| 40 | { | ||
| 41 | struct omap_dss_device *dssdev = mgr->get_device(mgr); | ||
| 42 | |||
| 43 | return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ? | ||
| 44 | dssdev->name : "<none>"); | ||
| 45 | } | ||
| 46 | |||
| 47 | static ssize_t manager_display_store(struct omap_overlay_manager *mgr, | ||
| 48 | const char *buf, size_t size) | ||
| 49 | { | ||
| 50 | int r = 0; | ||
| 51 | size_t len = size; | ||
| 52 | struct omap_dss_device *dssdev = NULL; | ||
| 53 | |||
| 54 | int match(struct omap_dss_device *dssdev, void *data) | ||
| 55 | { | ||
| 56 | const char *str = data; | ||
| 57 | return sysfs_streq(dssdev->name, str); | ||
| 58 | } | ||
| 59 | |||
| 60 | if (buf[size-1] == '\n') | ||
| 61 | --len; | ||
| 62 | |||
| 63 | if (len > 0) | ||
| 64 | dssdev = omap_dss_find_device((void *)buf, match); | ||
| 65 | |||
| 66 | if (len > 0 && dssdev == NULL) | ||
| 67 | return -EINVAL; | ||
| 68 | |||
| 69 | if (dssdev) | ||
| 70 | DSSDBG("display %s found\n", dssdev->name); | ||
| 71 | |||
| 72 | if (mgr->output) { | ||
| 73 | r = mgr->unset_output(mgr); | ||
| 74 | if (r) { | ||
| 75 | DSSERR("failed to unset current output\n"); | ||
| 76 | goto put_device; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | if (dssdev) { | ||
| 81 | struct omap_dss_output *out = dssdev->output; | ||
| 82 | |||
| 83 | /* | ||
| 84 | * a registered device should have an output connected to it | ||
| 85 | * already | ||
| 86 | */ | ||
| 87 | if (!out) { | ||
| 88 | DSSERR("device has no output connected to it\n"); | ||
| 89 | goto put_device; | ||
| 90 | } | ||
| 91 | |||
| 92 | r = mgr->set_output(mgr, out); | ||
| 93 | if (r) { | ||
| 94 | DSSERR("failed to set manager output\n"); | ||
| 95 | goto put_device; | ||
| 96 | } | ||
| 97 | |||
| 98 | r = mgr->apply(mgr); | ||
| 99 | if (r) { | ||
| 100 | DSSERR("failed to apply dispc config\n"); | ||
| 101 | goto put_device; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | put_device: | ||
| 106 | if (dssdev) | ||
| 107 | omap_dss_put_device(dssdev); | ||
| 108 | |||
| 109 | return r ? r : size; | ||
| 110 | } | ||
| 111 | |||
| 112 | static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, | ||
| 113 | char *buf) | ||
| 114 | { | ||
| 115 | struct omap_overlay_manager_info info; | ||
| 116 | |||
| 117 | mgr->get_manager_info(mgr, &info); | ||
| 118 | |||
| 119 | return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color); | ||
| 120 | } | ||
| 121 | |||
| 122 | static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, | ||
| 123 | const char *buf, size_t size) | ||
| 124 | { | ||
| 125 | struct omap_overlay_manager_info info; | ||
| 126 | u32 color; | ||
| 127 | int r; | ||
| 128 | |||
| 129 | r = kstrtouint(buf, 0, &color); | ||
| 130 | if (r) | ||
| 131 | return r; | ||
| 132 | |||
| 133 | mgr->get_manager_info(mgr, &info); | ||
| 134 | |||
| 135 | info.default_color = color; | ||
| 136 | |||
| 137 | r = mgr->set_manager_info(mgr, &info); | ||
| 138 | if (r) | ||
| 139 | return r; | ||
| 140 | |||
| 141 | r = mgr->apply(mgr); | ||
| 142 | if (r) | ||
| 143 | return r; | ||
| 144 | |||
| 145 | return size; | ||
| 146 | } | ||
| 147 | |||
| 148 | static const char *trans_key_type_str[] = { | ||
| 149 | "gfx-destination", | ||
| 150 | "video-source", | ||
| 151 | }; | ||
| 152 | |||
| 153 | static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr, | ||
| 154 | char *buf) | ||
| 155 | { | ||
| 156 | enum omap_dss_trans_key_type key_type; | ||
| 157 | struct omap_overlay_manager_info info; | ||
| 158 | |||
| 159 | mgr->get_manager_info(mgr, &info); | ||
| 160 | |||
| 161 | key_type = info.trans_key_type; | ||
| 162 | BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str)); | ||
| 163 | |||
| 164 | return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]); | ||
| 165 | } | ||
| 166 | |||
| 167 | static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr, | ||
| 168 | const char *buf, size_t size) | ||
| 169 | { | ||
| 170 | enum omap_dss_trans_key_type key_type; | ||
| 171 | struct omap_overlay_manager_info info; | ||
| 172 | int r; | ||
| 173 | |||
| 174 | for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST; | ||
| 175 | key_type < ARRAY_SIZE(trans_key_type_str); key_type++) { | ||
| 176 | if (sysfs_streq(buf, trans_key_type_str[key_type])) | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | |||
| 180 | if (key_type == ARRAY_SIZE(trans_key_type_str)) | ||
| 181 | return -EINVAL; | ||
| 182 | |||
| 183 | mgr->get_manager_info(mgr, &info); | ||
| 184 | |||
| 185 | info.trans_key_type = key_type; | ||
| 186 | |||
| 187 | r = mgr->set_manager_info(mgr, &info); | ||
| 188 | if (r) | ||
| 189 | return r; | ||
| 190 | |||
| 191 | r = mgr->apply(mgr); | ||
| 192 | if (r) | ||
| 193 | return r; | ||
| 194 | |||
| 195 | return size; | ||
| 196 | } | ||
| 197 | |||
| 198 | static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, | ||
| 199 | char *buf) | ||
| 200 | { | ||
| 201 | struct omap_overlay_manager_info info; | ||
| 202 | |||
| 203 | mgr->get_manager_info(mgr, &info); | ||
| 204 | |||
| 205 | return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key); | ||
| 206 | } | ||
| 207 | |||
| 208 | static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, | ||
| 209 | const char *buf, size_t size) | ||
| 210 | { | ||
| 211 | struct omap_overlay_manager_info info; | ||
| 212 | u32 key_value; | ||
| 213 | int r; | ||
| 214 | |||
| 215 | r = kstrtouint(buf, 0, &key_value); | ||
| 216 | if (r) | ||
| 217 | return r; | ||
| 218 | |||
| 219 | mgr->get_manager_info(mgr, &info); | ||
| 220 | |||
| 221 | info.trans_key = key_value; | ||
| 222 | |||
| 223 | r = mgr->set_manager_info(mgr, &info); | ||
| 224 | if (r) | ||
| 225 | return r; | ||
| 226 | |||
| 227 | r = mgr->apply(mgr); | ||
| 228 | if (r) | ||
| 229 | return r; | ||
| 230 | |||
| 231 | return size; | ||
| 232 | } | ||
| 233 | |||
| 234 | static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr, | ||
| 235 | char *buf) | ||
| 236 | { | ||
| 237 | struct omap_overlay_manager_info info; | ||
| 238 | |||
| 239 | mgr->get_manager_info(mgr, &info); | ||
| 240 | |||
| 241 | return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled); | ||
| 242 | } | ||
| 243 | |||
| 244 | static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, | ||
| 245 | const char *buf, size_t size) | ||
| 246 | { | ||
| 247 | struct omap_overlay_manager_info info; | ||
| 248 | bool enable; | ||
| 249 | int r; | ||
| 250 | |||
| 251 | r = strtobool(buf, &enable); | ||
| 252 | if (r) | ||
| 253 | return r; | ||
| 254 | |||
| 255 | mgr->get_manager_info(mgr, &info); | ||
| 256 | |||
| 257 | info.trans_enabled = enable; | ||
| 258 | |||
| 259 | r = mgr->set_manager_info(mgr, &info); | ||
| 260 | if (r) | ||
| 261 | return r; | ||
| 262 | |||
| 263 | r = mgr->apply(mgr); | ||
| 264 | if (r) | ||
| 265 | return r; | ||
| 266 | |||
| 267 | return size; | ||
| 268 | } | ||
| 269 | |||
| 270 | static ssize_t manager_alpha_blending_enabled_show( | ||
| 271 | struct omap_overlay_manager *mgr, char *buf) | ||
| 272 | { | ||
| 273 | struct omap_overlay_manager_info info; | ||
| 274 | |||
| 275 | mgr->get_manager_info(mgr, &info); | ||
| 276 | |||
| 277 | WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); | ||
| 278 | |||
| 279 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 280 | info.partial_alpha_enabled); | ||
| 281 | } | ||
| 282 | |||
| 283 | static ssize_t manager_alpha_blending_enabled_store( | ||
| 284 | struct omap_overlay_manager *mgr, | ||
| 285 | const char *buf, size_t size) | ||
| 286 | { | ||
| 287 | struct omap_overlay_manager_info info; | ||
| 288 | bool enable; | ||
| 289 | int r; | ||
| 290 | |||
| 291 | WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); | ||
| 292 | |||
| 293 | r = strtobool(buf, &enable); | ||
| 294 | if (r) | ||
| 295 | return r; | ||
| 296 | |||
| 297 | mgr->get_manager_info(mgr, &info); | ||
| 298 | |||
| 299 | info.partial_alpha_enabled = enable; | ||
| 300 | |||
| 301 | r = mgr->set_manager_info(mgr, &info); | ||
| 302 | if (r) | ||
| 303 | return r; | ||
| 304 | |||
| 305 | r = mgr->apply(mgr); | ||
| 306 | if (r) | ||
| 307 | return r; | ||
| 308 | |||
| 309 | return size; | ||
| 310 | } | ||
| 311 | |||
| 312 | static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, | ||
| 313 | char *buf) | ||
| 314 | { | ||
| 315 | struct omap_overlay_manager_info info; | ||
| 316 | |||
| 317 | mgr->get_manager_info(mgr, &info); | ||
| 318 | |||
| 319 | return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable); | ||
| 320 | } | ||
| 321 | |||
| 322 | static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, | ||
| 323 | const char *buf, size_t size) | ||
| 324 | { | ||
| 325 | struct omap_overlay_manager_info info; | ||
| 326 | int r; | ||
| 327 | bool enable; | ||
| 328 | |||
| 329 | if (!dss_has_feature(FEAT_CPR)) | ||
| 330 | return -ENODEV; | ||
| 331 | |||
| 332 | r = strtobool(buf, &enable); | ||
| 333 | if (r) | ||
| 334 | return r; | ||
| 335 | |||
| 336 | mgr->get_manager_info(mgr, &info); | ||
| 337 | |||
| 338 | if (info.cpr_enable == enable) | ||
| 339 | return size; | ||
| 340 | |||
| 341 | info.cpr_enable = enable; | ||
| 342 | |||
| 343 | r = mgr->set_manager_info(mgr, &info); | ||
| 344 | if (r) | ||
| 345 | return r; | ||
| 346 | |||
| 347 | r = mgr->apply(mgr); | ||
| 348 | if (r) | ||
| 349 | return r; | ||
| 350 | |||
| 351 | return size; | ||
| 352 | } | ||
| 353 | |||
| 354 | static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr, | ||
| 355 | char *buf) | ||
| 356 | { | ||
| 357 | struct omap_overlay_manager_info info; | ||
| 358 | |||
| 359 | mgr->get_manager_info(mgr, &info); | ||
| 360 | |||
| 361 | return snprintf(buf, PAGE_SIZE, | ||
| 362 | "%d %d %d %d %d %d %d %d %d\n", | ||
| 363 | info.cpr_coefs.rr, | ||
| 364 | info.cpr_coefs.rg, | ||
| 365 | info.cpr_coefs.rb, | ||
| 366 | info.cpr_coefs.gr, | ||
| 367 | info.cpr_coefs.gg, | ||
| 368 | info.cpr_coefs.gb, | ||
| 369 | info.cpr_coefs.br, | ||
| 370 | info.cpr_coefs.bg, | ||
| 371 | info.cpr_coefs.bb); | ||
| 372 | } | ||
| 373 | |||
| 374 | static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr, | ||
| 375 | const char *buf, size_t size) | ||
| 376 | { | ||
| 377 | struct omap_overlay_manager_info info; | ||
| 378 | struct omap_dss_cpr_coefs coefs; | ||
| 379 | int r, i; | ||
| 380 | s16 *arr; | ||
| 381 | |||
| 382 | if (!dss_has_feature(FEAT_CPR)) | ||
| 383 | return -ENODEV; | ||
| 384 | |||
| 385 | if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd", | ||
| 386 | &coefs.rr, &coefs.rg, &coefs.rb, | ||
| 387 | &coefs.gr, &coefs.gg, &coefs.gb, | ||
| 388 | &coefs.br, &coefs.bg, &coefs.bb) != 9) | ||
| 389 | return -EINVAL; | ||
| 390 | |||
| 391 | arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb, | ||
| 392 | coefs.gr, coefs.gg, coefs.gb, | ||
| 393 | coefs.br, coefs.bg, coefs.bb }; | ||
| 394 | |||
| 395 | for (i = 0; i < 9; ++i) { | ||
| 396 | if (arr[i] < -512 || arr[i] > 511) | ||
| 397 | return -EINVAL; | ||
| 398 | } | ||
| 399 | |||
| 400 | mgr->get_manager_info(mgr, &info); | ||
| 401 | |||
| 402 | info.cpr_coefs = coefs; | ||
| 403 | |||
| 404 | r = mgr->set_manager_info(mgr, &info); | ||
| 405 | if (r) | ||
| 406 | return r; | ||
| 407 | |||
| 408 | r = mgr->apply(mgr); | ||
| 409 | if (r) | ||
| 410 | return r; | ||
| 411 | |||
| 412 | return size; | ||
| 413 | } | ||
| 414 | |||
| 415 | struct manager_attribute { | ||
| 416 | struct attribute attr; | ||
| 417 | ssize_t (*show)(struct omap_overlay_manager *, char *); | ||
| 418 | ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t); | ||
| 419 | }; | ||
| 420 | |||
| 421 | #define MANAGER_ATTR(_name, _mode, _show, _store) \ | ||
| 422 | struct manager_attribute manager_attr_##_name = \ | ||
| 423 | __ATTR(_name, _mode, _show, _store) | ||
| 424 | |||
| 425 | static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); | ||
| 426 | static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, | ||
| 427 | manager_display_show, manager_display_store); | ||
| 428 | static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, | ||
| 429 | manager_default_color_show, manager_default_color_store); | ||
| 430 | static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, | ||
| 431 | manager_trans_key_type_show, manager_trans_key_type_store); | ||
| 432 | static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, | ||
| 433 | manager_trans_key_value_show, manager_trans_key_value_store); | ||
| 434 | static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, | ||
| 435 | manager_trans_key_enabled_show, | ||
| 436 | manager_trans_key_enabled_store); | ||
| 437 | static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, | ||
| 438 | manager_alpha_blending_enabled_show, | ||
| 439 | manager_alpha_blending_enabled_store); | ||
| 440 | static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, | ||
| 441 | manager_cpr_enable_show, | ||
| 442 | manager_cpr_enable_store); | ||
| 443 | static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, | ||
| 444 | manager_cpr_coef_show, | ||
| 445 | manager_cpr_coef_store); | ||
| 446 | |||
| 447 | |||
| 448 | static struct attribute *manager_sysfs_attrs[] = { | ||
| 449 | &manager_attr_name.attr, | ||
| 450 | &manager_attr_display.attr, | ||
| 451 | &manager_attr_default_color.attr, | ||
| 452 | &manager_attr_trans_key_type.attr, | ||
| 453 | &manager_attr_trans_key_value.attr, | ||
| 454 | &manager_attr_trans_key_enabled.attr, | ||
| 455 | &manager_attr_alpha_blending_enabled.attr, | ||
| 456 | &manager_attr_cpr_enable.attr, | ||
| 457 | &manager_attr_cpr_coef.attr, | ||
| 458 | NULL | ||
| 459 | }; | ||
| 460 | |||
| 461 | static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr, | ||
| 462 | char *buf) | ||
| 463 | { | ||
| 464 | struct omap_overlay_manager *manager; | ||
| 465 | struct manager_attribute *manager_attr; | ||
| 466 | |||
| 467 | manager = container_of(kobj, struct omap_overlay_manager, kobj); | ||
| 468 | manager_attr = container_of(attr, struct manager_attribute, attr); | ||
| 469 | |||
| 470 | if (!manager_attr->show) | ||
| 471 | return -ENOENT; | ||
| 472 | |||
| 473 | return manager_attr->show(manager, buf); | ||
| 474 | } | ||
| 475 | |||
| 476 | static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, | ||
| 477 | const char *buf, size_t size) | ||
| 478 | { | ||
| 479 | struct omap_overlay_manager *manager; | ||
| 480 | struct manager_attribute *manager_attr; | ||
| 481 | |||
| 482 | manager = container_of(kobj, struct omap_overlay_manager, kobj); | ||
| 483 | manager_attr = container_of(attr, struct manager_attribute, attr); | ||
| 484 | |||
| 485 | if (!manager_attr->store) | ||
| 486 | return -ENOENT; | ||
| 487 | |||
| 488 | return manager_attr->store(manager, buf, size); | ||
| 489 | } | ||
| 490 | |||
| 491 | static const struct sysfs_ops manager_sysfs_ops = { | ||
| 492 | .show = manager_attr_show, | ||
| 493 | .store = manager_attr_store, | ||
| 494 | }; | ||
| 495 | |||
| 496 | static struct kobj_type manager_ktype = { | ||
| 497 | .sysfs_ops = &manager_sysfs_ops, | ||
| 498 | .default_attrs = manager_sysfs_attrs, | ||
| 499 | }; | ||
| 500 | |||
| 501 | int dss_manager_kobj_init(struct omap_overlay_manager *mgr, | ||
| 502 | struct platform_device *pdev) | ||
| 503 | { | ||
| 504 | return kobject_init_and_add(&mgr->kobj, &manager_ktype, | ||
| 505 | &pdev->dev.kobj, "manager%d", mgr->id); | ||
| 506 | } | ||
| 507 | |||
| 508 | void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr) | ||
| 509 | { | ||
| 510 | kobject_del(&mgr->kobj); | ||
| 511 | kobject_put(&mgr->kobj); | ||
| 512 | } | ||
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 53710fadc82d..c54d2f620ce3 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c | |||
| @@ -36,463 +36,15 @@ | |||
| 36 | static int num_managers; | 36 | static int num_managers; |
| 37 | static struct omap_overlay_manager *managers; | 37 | static struct omap_overlay_manager *managers; |
| 38 | 38 | ||
| 39 | static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) | 39 | static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) |
| 40 | { | 40 | { |
| 41 | return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name); | 41 | return mgr->output ? mgr->output->device : NULL; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) | ||
| 45 | { | ||
| 46 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
| 47 | mgr->device ? mgr->device->name : "<none>"); | ||
| 48 | } | ||
| 49 | |||
| 50 | static ssize_t manager_display_store(struct omap_overlay_manager *mgr, | ||
| 51 | const char *buf, size_t size) | ||
| 52 | { | ||
| 53 | int r = 0; | ||
| 54 | size_t len = size; | ||
| 55 | struct omap_dss_device *dssdev = NULL; | ||
| 56 | |||
| 57 | int match(struct omap_dss_device *dssdev, void *data) | ||
| 58 | { | ||
| 59 | const char *str = data; | ||
| 60 | return sysfs_streq(dssdev->name, str); | ||
| 61 | } | ||
| 62 | |||
| 63 | if (buf[size-1] == '\n') | ||
| 64 | --len; | ||
| 65 | |||
| 66 | if (len > 0) | ||
| 67 | dssdev = omap_dss_find_device((void *)buf, match); | ||
| 68 | |||
| 69 | if (len > 0 && dssdev == NULL) | ||
| 70 | return -EINVAL; | ||
| 71 | |||
| 72 | if (dssdev) | ||
| 73 | DSSDBG("display %s found\n", dssdev->name); | ||
| 74 | |||
| 75 | if (mgr->device) { | ||
| 76 | r = mgr->unset_device(mgr); | ||
| 77 | if (r) { | ||
| 78 | DSSERR("failed to unset display\n"); | ||
| 79 | goto put_device; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | if (dssdev) { | ||
| 84 | r = mgr->set_device(mgr, dssdev); | ||
| 85 | if (r) { | ||
| 86 | DSSERR("failed to set manager\n"); | ||
| 87 | goto put_device; | ||
| 88 | } | ||
| 89 | |||
| 90 | r = mgr->apply(mgr); | ||
| 91 | if (r) { | ||
| 92 | DSSERR("failed to apply dispc config\n"); | ||
| 93 | goto put_device; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | put_device: | ||
| 98 | if (dssdev) | ||
| 99 | omap_dss_put_device(dssdev); | ||
| 100 | |||
| 101 | return r ? r : size; | ||
| 102 | } | ||
| 103 | |||
| 104 | static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, | ||
| 105 | char *buf) | ||
| 106 | { | ||
| 107 | struct omap_overlay_manager_info info; | ||
| 108 | |||
| 109 | mgr->get_manager_info(mgr, &info); | ||
| 110 | |||
| 111 | return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color); | ||
| 112 | } | ||
| 113 | |||
| 114 | static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, | ||
| 115 | const char *buf, size_t size) | ||
| 116 | { | ||
| 117 | struct omap_overlay_manager_info info; | ||
| 118 | u32 color; | ||
| 119 | int r; | ||
| 120 | |||
| 121 | r = kstrtouint(buf, 0, &color); | ||
| 122 | if (r) | ||
| 123 | return r; | ||
| 124 | |||
| 125 | mgr->get_manager_info(mgr, &info); | ||
| 126 | |||
| 127 | info.default_color = color; | ||
| 128 | |||
| 129 | r = mgr->set_manager_info(mgr, &info); | ||
| 130 | if (r) | ||
| 131 | return r; | ||
| 132 | |||
| 133 | r = mgr->apply(mgr); | ||
| 134 | if (r) | ||
| 135 | return r; | ||
| 136 | |||
| 137 | return size; | ||
| 138 | } | ||
| 139 | |||
| 140 | static const char *trans_key_type_str[] = { | ||
| 141 | "gfx-destination", | ||
| 142 | "video-source", | ||
| 143 | }; | ||
| 144 | |||
| 145 | static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr, | ||
| 146 | char *buf) | ||
| 147 | { | ||
| 148 | enum omap_dss_trans_key_type key_type; | ||
| 149 | struct omap_overlay_manager_info info; | ||
| 150 | |||
| 151 | mgr->get_manager_info(mgr, &info); | ||
| 152 | |||
| 153 | key_type = info.trans_key_type; | ||
| 154 | BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str)); | ||
| 155 | |||
| 156 | return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]); | ||
| 157 | } | ||
| 158 | |||
| 159 | static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr, | ||
| 160 | const char *buf, size_t size) | ||
| 161 | { | ||
| 162 | enum omap_dss_trans_key_type key_type; | ||
| 163 | struct omap_overlay_manager_info info; | ||
| 164 | int r; | ||
| 165 | |||
| 166 | for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST; | ||
| 167 | key_type < ARRAY_SIZE(trans_key_type_str); key_type++) { | ||
| 168 | if (sysfs_streq(buf, trans_key_type_str[key_type])) | ||
| 169 | break; | ||
| 170 | } | ||
| 171 | |||
| 172 | if (key_type == ARRAY_SIZE(trans_key_type_str)) | ||
| 173 | return -EINVAL; | ||
| 174 | |||
| 175 | mgr->get_manager_info(mgr, &info); | ||
| 176 | |||
| 177 | info.trans_key_type = key_type; | ||
| 178 | |||
| 179 | r = mgr->set_manager_info(mgr, &info); | ||
| 180 | if (r) | ||
| 181 | return r; | ||
| 182 | |||
| 183 | r = mgr->apply(mgr); | ||
| 184 | if (r) | ||
| 185 | return r; | ||
| 186 | |||
| 187 | return size; | ||
| 188 | } | ||
| 189 | |||
| 190 | static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, | ||
| 191 | char *buf) | ||
| 192 | { | ||
| 193 | struct omap_overlay_manager_info info; | ||
| 194 | |||
| 195 | mgr->get_manager_info(mgr, &info); | ||
| 196 | |||
| 197 | return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key); | ||
| 198 | } | ||
| 199 | |||
| 200 | static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, | ||
| 201 | const char *buf, size_t size) | ||
| 202 | { | ||
| 203 | struct omap_overlay_manager_info info; | ||
| 204 | u32 key_value; | ||
| 205 | int r; | ||
| 206 | |||
| 207 | r = kstrtouint(buf, 0, &key_value); | ||
| 208 | if (r) | ||
| 209 | return r; | ||
| 210 | |||
| 211 | mgr->get_manager_info(mgr, &info); | ||
| 212 | |||
| 213 | info.trans_key = key_value; | ||
| 214 | |||
| 215 | r = mgr->set_manager_info(mgr, &info); | ||
| 216 | if (r) | ||
| 217 | return r; | ||
| 218 | |||
| 219 | r = mgr->apply(mgr); | ||
| 220 | if (r) | ||
| 221 | return r; | ||
| 222 | |||
| 223 | return size; | ||
| 224 | } | ||
| 225 | |||
| 226 | static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr, | ||
| 227 | char *buf) | ||
| 228 | { | ||
| 229 | struct omap_overlay_manager_info info; | ||
| 230 | |||
| 231 | mgr->get_manager_info(mgr, &info); | ||
| 232 | |||
| 233 | return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled); | ||
| 234 | } | ||
| 235 | |||
| 236 | static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, | ||
| 237 | const char *buf, size_t size) | ||
| 238 | { | ||
| 239 | struct omap_overlay_manager_info info; | ||
| 240 | bool enable; | ||
| 241 | int r; | ||
| 242 | |||
| 243 | r = strtobool(buf, &enable); | ||
| 244 | if (r) | ||
| 245 | return r; | ||
| 246 | |||
| 247 | mgr->get_manager_info(mgr, &info); | ||
| 248 | |||
| 249 | info.trans_enabled = enable; | ||
| 250 | |||
| 251 | r = mgr->set_manager_info(mgr, &info); | ||
| 252 | if (r) | ||
| 253 | return r; | ||
| 254 | |||
| 255 | r = mgr->apply(mgr); | ||
| 256 | if (r) | ||
| 257 | return r; | ||
| 258 | |||
| 259 | return size; | ||
| 260 | } | ||
| 261 | |||
| 262 | static ssize_t manager_alpha_blending_enabled_show( | ||
| 263 | struct omap_overlay_manager *mgr, char *buf) | ||
| 264 | { | ||
| 265 | struct omap_overlay_manager_info info; | ||
| 266 | |||
| 267 | mgr->get_manager_info(mgr, &info); | ||
| 268 | |||
| 269 | WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); | ||
| 270 | |||
| 271 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 272 | info.partial_alpha_enabled); | ||
| 273 | } | ||
| 274 | |||
| 275 | static ssize_t manager_alpha_blending_enabled_store( | ||
| 276 | struct omap_overlay_manager *mgr, | ||
| 277 | const char *buf, size_t size) | ||
| 278 | { | ||
| 279 | struct omap_overlay_manager_info info; | ||
| 280 | bool enable; | ||
| 281 | int r; | ||
| 282 | |||
| 283 | WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); | ||
| 284 | |||
| 285 | r = strtobool(buf, &enable); | ||
| 286 | if (r) | ||
| 287 | return r; | ||
| 288 | |||
| 289 | mgr->get_manager_info(mgr, &info); | ||
| 290 | |||
| 291 | info.partial_alpha_enabled = enable; | ||
| 292 | |||
| 293 | r = mgr->set_manager_info(mgr, &info); | ||
| 294 | if (r) | ||
| 295 | return r; | ||
| 296 | |||
| 297 | r = mgr->apply(mgr); | ||
| 298 | if (r) | ||
| 299 | return r; | ||
| 300 | |||
| 301 | return size; | ||
| 302 | } | ||
| 303 | |||
| 304 | static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, | ||
| 305 | char *buf) | ||
| 306 | { | ||
| 307 | struct omap_overlay_manager_info info; | ||
| 308 | |||
| 309 | mgr->get_manager_info(mgr, &info); | ||
| 310 | |||
| 311 | return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable); | ||
| 312 | } | ||
| 313 | |||
| 314 | static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, | ||
| 315 | const char *buf, size_t size) | ||
| 316 | { | ||
| 317 | struct omap_overlay_manager_info info; | ||
| 318 | int r; | ||
| 319 | bool enable; | ||
| 320 | |||
| 321 | if (!dss_has_feature(FEAT_CPR)) | ||
| 322 | return -ENODEV; | ||
| 323 | |||
| 324 | r = strtobool(buf, &enable); | ||
| 325 | if (r) | ||
| 326 | return r; | ||
| 327 | |||
| 328 | mgr->get_manager_info(mgr, &info); | ||
| 329 | |||
| 330 | if (info.cpr_enable == enable) | ||
| 331 | return size; | ||
| 332 | |||
| 333 | info.cpr_enable = enable; | ||
| 334 | |||
| 335 | r = mgr->set_manager_info(mgr, &info); | ||
| 336 | if (r) | ||
| 337 | return r; | ||
| 338 | |||
| 339 | r = mgr->apply(mgr); | ||
| 340 | if (r) | ||
| 341 | return r; | ||
| 342 | |||
| 343 | return size; | ||
| 344 | } | ||
| 345 | |||
| 346 | static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr, | ||
| 347 | char *buf) | ||
| 348 | { | ||
| 349 | struct omap_overlay_manager_info info; | ||
| 350 | |||
| 351 | mgr->get_manager_info(mgr, &info); | ||
| 352 | |||
| 353 | return snprintf(buf, PAGE_SIZE, | ||
| 354 | "%d %d %d %d %d %d %d %d %d\n", | ||
| 355 | info.cpr_coefs.rr, | ||
| 356 | info.cpr_coefs.rg, | ||
| 357 | info.cpr_coefs.rb, | ||
| 358 | info.cpr_coefs.gr, | ||
| 359 | info.cpr_coefs.gg, | ||
| 360 | info.cpr_coefs.gb, | ||
| 361 | info.cpr_coefs.br, | ||
| 362 | info.cpr_coefs.bg, | ||
| 363 | info.cpr_coefs.bb); | ||
| 364 | } | ||
| 365 | |||
| 366 | static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr, | ||
| 367 | const char *buf, size_t size) | ||
| 368 | { | ||
| 369 | struct omap_overlay_manager_info info; | ||
| 370 | struct omap_dss_cpr_coefs coefs; | ||
| 371 | int r, i; | ||
| 372 | s16 *arr; | ||
| 373 | |||
| 374 | if (!dss_has_feature(FEAT_CPR)) | ||
| 375 | return -ENODEV; | ||
| 376 | |||
| 377 | if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd", | ||
| 378 | &coefs.rr, &coefs.rg, &coefs.rb, | ||
| 379 | &coefs.gr, &coefs.gg, &coefs.gb, | ||
| 380 | &coefs.br, &coefs.bg, &coefs.bb) != 9) | ||
| 381 | return -EINVAL; | ||
| 382 | |||
| 383 | arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb, | ||
| 384 | coefs.gr, coefs.gg, coefs.gb, | ||
| 385 | coefs.br, coefs.bg, coefs.bb }; | ||
| 386 | |||
| 387 | for (i = 0; i < 9; ++i) { | ||
| 388 | if (arr[i] < -512 || arr[i] > 511) | ||
| 389 | return -EINVAL; | ||
| 390 | } | ||
| 391 | |||
| 392 | mgr->get_manager_info(mgr, &info); | ||
| 393 | |||
| 394 | info.cpr_coefs = coefs; | ||
| 395 | |||
| 396 | r = mgr->set_manager_info(mgr, &info); | ||
| 397 | if (r) | ||
| 398 | return r; | ||
| 399 | |||
| 400 | r = mgr->apply(mgr); | ||
| 401 | if (r) | ||
| 402 | return r; | ||
| 403 | |||
| 404 | return size; | ||
| 405 | } | ||
| 406 | |||
| 407 | struct manager_attribute { | ||
| 408 | struct attribute attr; | ||
| 409 | ssize_t (*show)(struct omap_overlay_manager *, char *); | ||
| 410 | ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t); | ||
| 411 | }; | ||
| 412 | |||
| 413 | #define MANAGER_ATTR(_name, _mode, _show, _store) \ | ||
| 414 | struct manager_attribute manager_attr_##_name = \ | ||
| 415 | __ATTR(_name, _mode, _show, _store) | ||
| 416 | |||
| 417 | static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); | ||
| 418 | static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, | ||
| 419 | manager_display_show, manager_display_store); | ||
| 420 | static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, | ||
| 421 | manager_default_color_show, manager_default_color_store); | ||
| 422 | static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, | ||
| 423 | manager_trans_key_type_show, manager_trans_key_type_store); | ||
| 424 | static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, | ||
| 425 | manager_trans_key_value_show, manager_trans_key_value_store); | ||
| 426 | static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, | ||
| 427 | manager_trans_key_enabled_show, | ||
| 428 | manager_trans_key_enabled_store); | ||
| 429 | static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, | ||
| 430 | manager_alpha_blending_enabled_show, | ||
| 431 | manager_alpha_blending_enabled_store); | ||
| 432 | static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, | ||
| 433 | manager_cpr_enable_show, | ||
| 434 | manager_cpr_enable_store); | ||
| 435 | static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, | ||
| 436 | manager_cpr_coef_show, | ||
| 437 | manager_cpr_coef_store); | ||
| 438 | |||
| 439 | |||
| 440 | static struct attribute *manager_sysfs_attrs[] = { | ||
| 441 | &manager_attr_name.attr, | ||
| 442 | &manager_attr_display.attr, | ||
| 443 | &manager_attr_default_color.attr, | ||
| 444 | &manager_attr_trans_key_type.attr, | ||
| 445 | &manager_attr_trans_key_value.attr, | ||
| 446 | &manager_attr_trans_key_enabled.attr, | ||
| 447 | &manager_attr_alpha_blending_enabled.attr, | ||
| 448 | &manager_attr_cpr_enable.attr, | ||
| 449 | &manager_attr_cpr_coef.attr, | ||
| 450 | NULL | ||
| 451 | }; | ||
| 452 | |||
| 453 | static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr, | ||
| 454 | char *buf) | ||
| 455 | { | ||
| 456 | struct omap_overlay_manager *manager; | ||
| 457 | struct manager_attribute *manager_attr; | ||
| 458 | |||
| 459 | manager = container_of(kobj, struct omap_overlay_manager, kobj); | ||
| 460 | manager_attr = container_of(attr, struct manager_attribute, attr); | ||
| 461 | |||
| 462 | if (!manager_attr->show) | ||
| 463 | return -ENOENT; | ||
| 464 | |||
| 465 | return manager_attr->show(manager, buf); | ||
| 466 | } | ||
| 467 | |||
| 468 | static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, | ||
| 469 | const char *buf, size_t size) | ||
| 470 | { | ||
| 471 | struct omap_overlay_manager *manager; | ||
| 472 | struct manager_attribute *manager_attr; | ||
| 473 | |||
| 474 | manager = container_of(kobj, struct omap_overlay_manager, kobj); | ||
| 475 | manager_attr = container_of(attr, struct manager_attribute, attr); | ||
| 476 | |||
| 477 | if (!manager_attr->store) | ||
| 478 | return -ENOENT; | ||
| 479 | |||
| 480 | return manager_attr->store(manager, buf, size); | ||
| 481 | } | ||
| 482 | |||
| 483 | static const struct sysfs_ops manager_sysfs_ops = { | ||
| 484 | .show = manager_attr_show, | ||
| 485 | .store = manager_attr_store, | ||
| 486 | }; | ||
| 487 | |||
| 488 | static struct kobj_type manager_ktype = { | ||
| 489 | .sysfs_ops = &manager_sysfs_ops, | ||
| 490 | .default_attrs = manager_sysfs_attrs, | ||
| 491 | }; | ||
| 492 | |||
| 493 | static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) | 44 | static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) |
| 494 | { | 45 | { |
| 495 | unsigned long timeout = msecs_to_jiffies(500); | 46 | unsigned long timeout = msecs_to_jiffies(500); |
| 47 | struct omap_dss_device *dssdev = mgr->get_device(mgr); | ||
| 496 | u32 irq; | 48 | u32 irq; |
| 497 | int r; | 49 | int r; |
| 498 | 50 | ||
| @@ -500,9 +52,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) | |||
| 500 | if (r) | 52 | if (r) |
| 501 | return r; | 53 | return r; |
| 502 | 54 | ||
| 503 | if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) | 55 | if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) |
| 504 | irq = DISPC_IRQ_EVSYNC_ODD; | 56 | irq = DISPC_IRQ_EVSYNC_ODD; |
| 505 | else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) | 57 | else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) |
| 506 | irq = DISPC_IRQ_EVSYNC_EVEN; | 58 | irq = DISPC_IRQ_EVSYNC_EVEN; |
| 507 | else | 59 | else |
| 508 | irq = dispc_mgr_get_vsync_irq(mgr->id); | 60 | irq = dispc_mgr_get_vsync_irq(mgr->id); |
| @@ -547,23 +99,24 @@ int dss_init_overlay_managers(struct platform_device *pdev) | |||
| 547 | break; | 99 | break; |
| 548 | } | 100 | } |
| 549 | 101 | ||
| 550 | mgr->set_device = &dss_mgr_set_device; | 102 | mgr->set_output = &dss_mgr_set_output; |
| 551 | mgr->unset_device = &dss_mgr_unset_device; | 103 | mgr->unset_output = &dss_mgr_unset_output; |
| 552 | mgr->apply = &omap_dss_mgr_apply; | 104 | mgr->apply = &omap_dss_mgr_apply; |
| 553 | mgr->set_manager_info = &dss_mgr_set_info; | 105 | mgr->set_manager_info = &dss_mgr_set_info; |
| 554 | mgr->get_manager_info = &dss_mgr_get_info; | 106 | mgr->get_manager_info = &dss_mgr_get_info; |
| 555 | mgr->wait_for_go = &dss_mgr_wait_for_go; | 107 | mgr->wait_for_go = &dss_mgr_wait_for_go; |
| 556 | mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; | 108 | mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; |
| 109 | mgr->get_device = &dss_mgr_get_device; | ||
| 557 | 110 | ||
| 558 | mgr->caps = 0; | 111 | mgr->caps = 0; |
| 559 | mgr->supported_displays = | 112 | mgr->supported_displays = |
| 560 | dss_feat_get_supported_displays(mgr->id); | 113 | dss_feat_get_supported_displays(mgr->id); |
| 114 | mgr->supported_outputs = | ||
| 115 | dss_feat_get_supported_outputs(mgr->id); | ||
| 561 | 116 | ||
| 562 | INIT_LIST_HEAD(&mgr->overlays); | 117 | INIT_LIST_HEAD(&mgr->overlays); |
| 563 | 118 | ||
| 564 | r = kobject_init_and_add(&mgr->kobj, &manager_ktype, | 119 | r = dss_manager_kobj_init(mgr, pdev); |
| 565 | &pdev->dev.kobj, "manager%d", i); | ||
| 566 | |||
| 567 | if (r) | 120 | if (r) |
| 568 | DSSERR("failed to create sysfs file\n"); | 121 | DSSERR("failed to create sysfs file\n"); |
| 569 | } | 122 | } |
| @@ -577,9 +130,7 @@ void dss_uninit_overlay_managers(struct platform_device *pdev) | |||
| 577 | 130 | ||
| 578 | for (i = 0; i < num_managers; ++i) { | 131 | for (i = 0; i < num_managers; ++i) { |
| 579 | struct omap_overlay_manager *mgr = &managers[i]; | 132 | struct omap_overlay_manager *mgr = &managers[i]; |
| 580 | 133 | dss_manager_kobj_uninit(mgr); | |
| 581 | kobject_del(&mgr->kobj); | ||
| 582 | kobject_put(&mgr->kobj); | ||
| 583 | } | 134 | } |
| 584 | 135 | ||
| 585 | kfree(managers); | 136 | kfree(managers); |
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c new file mode 100644 index 000000000000..813f26682b7a --- /dev/null +++ b/drivers/video/omap2/dss/output.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Texas Instruments Ltd | ||
| 3 | * Author: Archit Taneja <archit@ti.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 as published by | ||
| 7 | * the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/slab.h> | ||
| 22 | |||
| 23 | #include <video/omapdss.h> | ||
| 24 | |||
| 25 | #include "dss.h" | ||
| 26 | |||
| 27 | static LIST_HEAD(output_list); | ||
| 28 | static DEFINE_MUTEX(output_lock); | ||
| 29 | |||
| 30 | int omapdss_output_set_device(struct omap_dss_output *out, | ||
| 31 | struct omap_dss_device *dssdev) | ||
| 32 | { | ||
| 33 | int r; | ||
| 34 | |||
| 35 | mutex_lock(&output_lock); | ||
| 36 | |||
| 37 | if (out->device) { | ||
| 38 | DSSERR("output already has device %s connected to it\n", | ||
| 39 | out->device->name); | ||
| 40 | r = -EINVAL; | ||
| 41 | goto err; | ||
| 42 | } | ||
| 43 | |||
| 44 | if (out->type != dssdev->type) { | ||
| 45 | DSSERR("output type and display type don't match\n"); | ||
| 46 | r = -EINVAL; | ||
| 47 | goto err; | ||
| 48 | } | ||
| 49 | |||
| 50 | out->device = dssdev; | ||
| 51 | dssdev->output = out; | ||
| 52 | |||
| 53 | mutex_unlock(&output_lock); | ||
| 54 | |||
| 55 | return 0; | ||
| 56 | err: | ||
| 57 | mutex_unlock(&output_lock); | ||
| 58 | |||
| 59 | return r; | ||
| 60 | } | ||
| 61 | EXPORT_SYMBOL(omapdss_output_set_device); | ||
| 62 | |||
| 63 | int omapdss_output_unset_device(struct omap_dss_output *out) | ||
| 64 | { | ||
| 65 | int r; | ||
| 66 | |||
| 67 | mutex_lock(&output_lock); | ||
| 68 | |||
| 69 | if (!out->device) { | ||
| 70 | DSSERR("output doesn't have a device connected to it\n"); | ||
| 71 | r = -EINVAL; | ||
| 72 | goto err; | ||
| 73 | } | ||
| 74 | |||
| 75 | if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
| 76 | DSSERR("device %s is not disabled, cannot unset device\n", | ||
| 77 | out->device->name); | ||
| 78 | r = -EINVAL; | ||
| 79 | goto err; | ||
| 80 | } | ||
| 81 | |||
| 82 | out->device->output = NULL; | ||
| 83 | out->device = NULL; | ||
| 84 | |||
| 85 | mutex_unlock(&output_lock); | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | err: | ||
| 89 | mutex_unlock(&output_lock); | ||
| 90 | |||
| 91 | return r; | ||
| 92 | } | ||
| 93 | EXPORT_SYMBOL(omapdss_output_unset_device); | ||
| 94 | |||
| 95 | void dss_register_output(struct omap_dss_output *out) | ||
| 96 | { | ||
| 97 | list_add_tail(&out->list, &output_list); | ||
| 98 | } | ||
| 99 | |||
| 100 | void dss_unregister_output(struct omap_dss_output *out) | ||
| 101 | { | ||
| 102 | list_del(&out->list); | ||
| 103 | } | ||
| 104 | |||
| 105 | struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id) | ||
| 106 | { | ||
| 107 | struct omap_dss_output *out; | ||
| 108 | |||
| 109 | list_for_each_entry(out, &output_list, list) { | ||
| 110 | if (out->id == id) | ||
| 111 | return out; | ||
| 112 | } | ||
| 113 | |||
| 114 | return NULL; | ||
| 115 | } | ||
| 116 | |||
| 117 | struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev) | ||
| 118 | { | ||
| 119 | struct omap_dss_output *out = NULL; | ||
| 120 | enum omap_dss_output_id id; | ||
| 121 | |||
| 122 | switch (dssdev->type) { | ||
| 123 | case OMAP_DISPLAY_TYPE_DPI: | ||
| 124 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI); | ||
| 125 | break; | ||
| 126 | case OMAP_DISPLAY_TYPE_DBI: | ||
| 127 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI); | ||
| 128 | break; | ||
| 129 | case OMAP_DISPLAY_TYPE_SDI: | ||
| 130 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI); | ||
| 131 | break; | ||
| 132 | case OMAP_DISPLAY_TYPE_VENC: | ||
| 133 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC); | ||
| 134 | break; | ||
| 135 | case OMAP_DISPLAY_TYPE_HDMI: | ||
| 136 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI); | ||
| 137 | break; | ||
| 138 | case OMAP_DISPLAY_TYPE_DSI: | ||
| 139 | id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 : | ||
| 140 | OMAP_DSS_OUTPUT_DSI2; | ||
| 141 | out = omap_dss_get_output(id); | ||
| 142 | break; | ||
| 143 | default: | ||
| 144 | break; | ||
| 145 | } | ||
| 146 | |||
| 147 | return out; | ||
| 148 | } | ||
diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/omap2/dss/overlay-sysfs.c new file mode 100644 index 000000000000..4cc5ddebfb34 --- /dev/null +++ b/drivers/video/omap2/dss/overlay-sysfs.c | |||
| @@ -0,0 +1,456 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Nokia Corporation | ||
| 3 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
| 4 | * | ||
| 5 | * Some code and ideas taken from drivers/video/omap/ driver | ||
| 6 | * by Imre Deak. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License version 2 as published by | ||
| 10 | * the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 15 | * more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License along with | ||
| 18 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #define DSS_SUBSYS_NAME "OVERLAY" | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/err.h> | ||
| 25 | #include <linux/sysfs.h> | ||
| 26 | #include <linux/kobject.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | |||
| 29 | #include <video/omapdss.h> | ||
| 30 | |||
| 31 | #include "dss.h" | ||
| 32 | #include "dss_features.h" | ||
| 33 | |||
| 34 | static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf) | ||
| 35 | { | ||
| 36 | return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name); | ||
| 37 | } | ||
| 38 | |||
| 39 | static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf) | ||
| 40 | { | ||
| 41 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
| 42 | ovl->manager ? ovl->manager->name : "<none>"); | ||
| 43 | } | ||
| 44 | |||
| 45 | static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf, | ||
| 46 | size_t size) | ||
| 47 | { | ||
| 48 | int i, r; | ||
| 49 | struct omap_overlay_manager *mgr = NULL; | ||
| 50 | struct omap_overlay_manager *old_mgr; | ||
| 51 | int len = size; | ||
| 52 | |||
| 53 | if (buf[size-1] == '\n') | ||
| 54 | --len; | ||
| 55 | |||
| 56 | if (len > 0) { | ||
| 57 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { | ||
| 58 | mgr = omap_dss_get_overlay_manager(i); | ||
| 59 | |||
| 60 | if (sysfs_streq(buf, mgr->name)) | ||
| 61 | break; | ||
| 62 | |||
| 63 | mgr = NULL; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | if (len > 0 && mgr == NULL) | ||
| 68 | return -EINVAL; | ||
| 69 | |||
| 70 | if (mgr) | ||
| 71 | DSSDBG("manager %s found\n", mgr->name); | ||
| 72 | |||
| 73 | if (mgr == ovl->manager) | ||
| 74 | return size; | ||
| 75 | |||
| 76 | old_mgr = ovl->manager; | ||
| 77 | |||
| 78 | r = dispc_runtime_get(); | ||
| 79 | if (r) | ||
| 80 | return r; | ||
| 81 | |||
| 82 | /* detach old manager */ | ||
| 83 | if (old_mgr) { | ||
| 84 | r = ovl->unset_manager(ovl); | ||
| 85 | if (r) { | ||
| 86 | DSSERR("detach failed\n"); | ||
| 87 | goto err; | ||
| 88 | } | ||
| 89 | |||
| 90 | r = old_mgr->apply(old_mgr); | ||
| 91 | if (r) | ||
| 92 | goto err; | ||
| 93 | } | ||
| 94 | |||
| 95 | if (mgr) { | ||
| 96 | r = ovl->set_manager(ovl, mgr); | ||
| 97 | if (r) { | ||
| 98 | DSSERR("Failed to attach overlay\n"); | ||
| 99 | goto err; | ||
| 100 | } | ||
| 101 | |||
| 102 | r = mgr->apply(mgr); | ||
| 103 | if (r) | ||
| 104 | goto err; | ||
| 105 | } | ||
| 106 | |||
| 107 | dispc_runtime_put(); | ||
| 108 | |||
| 109 | return size; | ||
| 110 | |||
| 111 | err: | ||
| 112 | dispc_runtime_put(); | ||
| 113 | return r; | ||
| 114 | } | ||
| 115 | |||
| 116 | static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) | ||
| 117 | { | ||
| 118 | struct omap_overlay_info info; | ||
| 119 | |||
| 120 | ovl->get_overlay_info(ovl, &info); | ||
| 121 | |||
| 122 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", | ||
| 123 | info.width, info.height); | ||
| 124 | } | ||
| 125 | |||
| 126 | static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf) | ||
| 127 | { | ||
| 128 | struct omap_overlay_info info; | ||
| 129 | |||
| 130 | ovl->get_overlay_info(ovl, &info); | ||
| 131 | |||
| 132 | return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width); | ||
| 133 | } | ||
| 134 | |||
| 135 | static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf) | ||
| 136 | { | ||
| 137 | struct omap_overlay_info info; | ||
| 138 | |||
| 139 | ovl->get_overlay_info(ovl, &info); | ||
| 140 | |||
| 141 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", | ||
| 142 | info.pos_x, info.pos_y); | ||
| 143 | } | ||
| 144 | |||
| 145 | static ssize_t overlay_position_store(struct omap_overlay *ovl, | ||
| 146 | const char *buf, size_t size) | ||
| 147 | { | ||
| 148 | int r; | ||
| 149 | char *last; | ||
| 150 | struct omap_overlay_info info; | ||
| 151 | |||
| 152 | ovl->get_overlay_info(ovl, &info); | ||
| 153 | |||
| 154 | info.pos_x = simple_strtoul(buf, &last, 10); | ||
| 155 | ++last; | ||
| 156 | if (last - buf >= size) | ||
| 157 | return -EINVAL; | ||
| 158 | |||
| 159 | info.pos_y = simple_strtoul(last, &last, 10); | ||
| 160 | |||
| 161 | r = ovl->set_overlay_info(ovl, &info); | ||
| 162 | if (r) | ||
| 163 | return r; | ||
| 164 | |||
| 165 | if (ovl->manager) { | ||
| 166 | r = ovl->manager->apply(ovl->manager); | ||
| 167 | if (r) | ||
| 168 | return r; | ||
| 169 | } | ||
| 170 | |||
| 171 | return size; | ||
| 172 | } | ||
| 173 | |||
| 174 | static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf) | ||
| 175 | { | ||
| 176 | struct omap_overlay_info info; | ||
| 177 | |||
| 178 | ovl->get_overlay_info(ovl, &info); | ||
| 179 | |||
| 180 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", | ||
| 181 | info.out_width, info.out_height); | ||
| 182 | } | ||
| 183 | |||
| 184 | static ssize_t overlay_output_size_store(struct omap_overlay *ovl, | ||
| 185 | const char *buf, size_t size) | ||
| 186 | { | ||
| 187 | int r; | ||
| 188 | char *last; | ||
| 189 | struct omap_overlay_info info; | ||
| 190 | |||
| 191 | ovl->get_overlay_info(ovl, &info); | ||
| 192 | |||
| 193 | info.out_width = simple_strtoul(buf, &last, 10); | ||
| 194 | ++last; | ||
| 195 | if (last - buf >= size) | ||
| 196 | return -EINVAL; | ||
| 197 | |||
| 198 | info.out_height = simple_strtoul(last, &last, 10); | ||
| 199 | |||
| 200 | r = ovl->set_overlay_info(ovl, &info); | ||
| 201 | if (r) | ||
| 202 | return r; | ||
| 203 | |||
| 204 | if (ovl->manager) { | ||
| 205 | r = ovl->manager->apply(ovl->manager); | ||
| 206 | if (r) | ||
| 207 | return r; | ||
| 208 | } | ||
| 209 | |||
| 210 | return size; | ||
| 211 | } | ||
| 212 | |||
| 213 | static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf) | ||
| 214 | { | ||
| 215 | return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl)); | ||
| 216 | } | ||
| 217 | |||
| 218 | static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, | ||
| 219 | size_t size) | ||
| 220 | { | ||
| 221 | int r; | ||
| 222 | bool enable; | ||
| 223 | |||
| 224 | r = strtobool(buf, &enable); | ||
| 225 | if (r) | ||
| 226 | return r; | ||
| 227 | |||
| 228 | if (enable) | ||
| 229 | r = ovl->enable(ovl); | ||
| 230 | else | ||
| 231 | r = ovl->disable(ovl); | ||
| 232 | |||
| 233 | if (r) | ||
| 234 | return r; | ||
| 235 | |||
| 236 | return size; | ||
| 237 | } | ||
| 238 | |||
| 239 | static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf) | ||
| 240 | { | ||
| 241 | struct omap_overlay_info info; | ||
| 242 | |||
| 243 | ovl->get_overlay_info(ovl, &info); | ||
| 244 | |||
| 245 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 246 | info.global_alpha); | ||
| 247 | } | ||
| 248 | |||
| 249 | static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl, | ||
| 250 | const char *buf, size_t size) | ||
| 251 | { | ||
| 252 | int r; | ||
| 253 | u8 alpha; | ||
| 254 | struct omap_overlay_info info; | ||
| 255 | |||
| 256 | if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) | ||
| 257 | return -ENODEV; | ||
| 258 | |||
| 259 | r = kstrtou8(buf, 0, &alpha); | ||
| 260 | if (r) | ||
| 261 | return r; | ||
| 262 | |||
| 263 | ovl->get_overlay_info(ovl, &info); | ||
| 264 | |||
| 265 | info.global_alpha = alpha; | ||
| 266 | |||
| 267 | r = ovl->set_overlay_info(ovl, &info); | ||
| 268 | if (r) | ||
| 269 | return r; | ||
| 270 | |||
| 271 | if (ovl->manager) { | ||
| 272 | r = ovl->manager->apply(ovl->manager); | ||
| 273 | if (r) | ||
| 274 | return r; | ||
| 275 | } | ||
| 276 | |||
| 277 | return size; | ||
| 278 | } | ||
| 279 | |||
| 280 | static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl, | ||
| 281 | char *buf) | ||
| 282 | { | ||
| 283 | struct omap_overlay_info info; | ||
| 284 | |||
| 285 | ovl->get_overlay_info(ovl, &info); | ||
| 286 | |||
| 287 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 288 | info.pre_mult_alpha); | ||
| 289 | } | ||
| 290 | |||
| 291 | static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, | ||
| 292 | const char *buf, size_t size) | ||
| 293 | { | ||
| 294 | int r; | ||
| 295 | u8 alpha; | ||
| 296 | struct omap_overlay_info info; | ||
| 297 | |||
| 298 | if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) | ||
| 299 | return -ENODEV; | ||
| 300 | |||
| 301 | r = kstrtou8(buf, 0, &alpha); | ||
| 302 | if (r) | ||
| 303 | return r; | ||
| 304 | |||
| 305 | ovl->get_overlay_info(ovl, &info); | ||
| 306 | |||
| 307 | info.pre_mult_alpha = alpha; | ||
| 308 | |||
| 309 | r = ovl->set_overlay_info(ovl, &info); | ||
| 310 | if (r) | ||
| 311 | return r; | ||
| 312 | |||
| 313 | if (ovl->manager) { | ||
| 314 | r = ovl->manager->apply(ovl->manager); | ||
| 315 | if (r) | ||
| 316 | return r; | ||
| 317 | } | ||
| 318 | |||
| 319 | return size; | ||
| 320 | } | ||
| 321 | |||
| 322 | static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf) | ||
| 323 | { | ||
| 324 | struct omap_overlay_info info; | ||
| 325 | |||
| 326 | ovl->get_overlay_info(ovl, &info); | ||
| 327 | |||
| 328 | return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder); | ||
| 329 | } | ||
| 330 | |||
| 331 | static ssize_t overlay_zorder_store(struct omap_overlay *ovl, | ||
| 332 | const char *buf, size_t size) | ||
| 333 | { | ||
| 334 | int r; | ||
| 335 | u8 zorder; | ||
| 336 | struct omap_overlay_info info; | ||
| 337 | |||
| 338 | if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) | ||
| 339 | return -ENODEV; | ||
| 340 | |||
| 341 | r = kstrtou8(buf, 0, &zorder); | ||
| 342 | if (r) | ||
| 343 | return r; | ||
| 344 | |||
| 345 | ovl->get_overlay_info(ovl, &info); | ||
| 346 | |||
| 347 | info.zorder = zorder; | ||
| 348 | |||
| 349 | r = ovl->set_overlay_info(ovl, &info); | ||
| 350 | if (r) | ||
| 351 | return r; | ||
| 352 | |||
| 353 | if (ovl->manager) { | ||
| 354 | r = ovl->manager->apply(ovl->manager); | ||
| 355 | if (r) | ||
| 356 | return r; | ||
| 357 | } | ||
| 358 | |||
| 359 | return size; | ||
| 360 | } | ||
| 361 | |||
| 362 | struct overlay_attribute { | ||
| 363 | struct attribute attr; | ||
| 364 | ssize_t (*show)(struct omap_overlay *, char *); | ||
| 365 | ssize_t (*store)(struct omap_overlay *, const char *, size_t); | ||
| 366 | }; | ||
| 367 | |||
| 368 | #define OVERLAY_ATTR(_name, _mode, _show, _store) \ | ||
| 369 | struct overlay_attribute overlay_attr_##_name = \ | ||
| 370 | __ATTR(_name, _mode, _show, _store) | ||
| 371 | |||
| 372 | static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL); | ||
| 373 | static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR, | ||
| 374 | overlay_manager_show, overlay_manager_store); | ||
| 375 | static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL); | ||
| 376 | static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL); | ||
| 377 | static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR, | ||
| 378 | overlay_position_show, overlay_position_store); | ||
| 379 | static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR, | ||
| 380 | overlay_output_size_show, overlay_output_size_store); | ||
| 381 | static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR, | ||
| 382 | overlay_enabled_show, overlay_enabled_store); | ||
| 383 | static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, | ||
| 384 | overlay_global_alpha_show, overlay_global_alpha_store); | ||
| 385 | static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, | ||
| 386 | overlay_pre_mult_alpha_show, | ||
| 387 | overlay_pre_mult_alpha_store); | ||
| 388 | static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, | ||
| 389 | overlay_zorder_show, overlay_zorder_store); | ||
| 390 | |||
| 391 | static struct attribute *overlay_sysfs_attrs[] = { | ||
| 392 | &overlay_attr_name.attr, | ||
| 393 | &overlay_attr_manager.attr, | ||
| 394 | &overlay_attr_input_size.attr, | ||
| 395 | &overlay_attr_screen_width.attr, | ||
| 396 | &overlay_attr_position.attr, | ||
| 397 | &overlay_attr_output_size.attr, | ||
| 398 | &overlay_attr_enabled.attr, | ||
| 399 | &overlay_attr_global_alpha.attr, | ||
| 400 | &overlay_attr_pre_mult_alpha.attr, | ||
| 401 | &overlay_attr_zorder.attr, | ||
| 402 | NULL | ||
| 403 | }; | ||
| 404 | |||
| 405 | static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr, | ||
| 406 | char *buf) | ||
| 407 | { | ||
| 408 | struct omap_overlay *overlay; | ||
| 409 | struct overlay_attribute *overlay_attr; | ||
| 410 | |||
| 411 | overlay = container_of(kobj, struct omap_overlay, kobj); | ||
| 412 | overlay_attr = container_of(attr, struct overlay_attribute, attr); | ||
| 413 | |||
| 414 | if (!overlay_attr->show) | ||
| 415 | return -ENOENT; | ||
| 416 | |||
| 417 | return overlay_attr->show(overlay, buf); | ||
| 418 | } | ||
| 419 | |||
| 420 | static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr, | ||
| 421 | const char *buf, size_t size) | ||
| 422 | { | ||
| 423 | struct omap_overlay *overlay; | ||
| 424 | struct overlay_attribute *overlay_attr; | ||
| 425 | |||
| 426 | overlay = container_of(kobj, struct omap_overlay, kobj); | ||
| 427 | overlay_attr = container_of(attr, struct overlay_attribute, attr); | ||
| 428 | |||
| 429 | if (!overlay_attr->store) | ||
| 430 | return -ENOENT; | ||
| 431 | |||
| 432 | return overlay_attr->store(overlay, buf, size); | ||
| 433 | } | ||
| 434 | |||
| 435 | static const struct sysfs_ops overlay_sysfs_ops = { | ||
| 436 | .show = overlay_attr_show, | ||
| 437 | .store = overlay_attr_store, | ||
| 438 | }; | ||
| 439 | |||
| 440 | static struct kobj_type overlay_ktype = { | ||
| 441 | .sysfs_ops = &overlay_sysfs_ops, | ||
| 442 | .default_attrs = overlay_sysfs_attrs, | ||
| 443 | }; | ||
| 444 | |||
| 445 | int dss_overlay_kobj_init(struct omap_overlay *ovl, | ||
| 446 | struct platform_device *pdev) | ||
| 447 | { | ||
| 448 | return kobject_init_and_add(&ovl->kobj, &overlay_ktype, | ||
| 449 | &pdev->dev.kobj, "overlay%d", ovl->id); | ||
| 450 | } | ||
| 451 | |||
| 452 | void dss_overlay_kobj_uninit(struct omap_overlay *ovl) | ||
| 453 | { | ||
| 454 | kobject_del(&ovl->kobj); | ||
| 455 | kobject_put(&ovl->kobj); | ||
| 456 | } | ||
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 952c6fad9a81..45f4994bc6b0 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c | |||
| @@ -26,13 +26,11 @@ | |||
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
| 28 | #include <linux/sysfs.h> | 28 | #include <linux/sysfs.h> |
| 29 | #include <linux/kobject.h> | ||
| 30 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
| 31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 33 | 32 | ||
| 34 | #include <video/omapdss.h> | 33 | #include <video/omapdss.h> |
| 35 | #include <plat/cpu.h> | ||
| 36 | 34 | ||
| 37 | #include "dss.h" | 35 | #include "dss.h" |
| 38 | #include "dss_features.h" | 36 | #include "dss_features.h" |
| @@ -40,417 +38,13 @@ | |||
| 40 | static int num_overlays; | 38 | static int num_overlays; |
| 41 | static struct omap_overlay *overlays; | 39 | static struct omap_overlay *overlays; |
| 42 | 40 | ||
| 43 | static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf) | 41 | static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) |
| 44 | { | 42 | { |
| 45 | return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name); | 43 | return ovl->manager ? |
| 44 | (ovl->manager->output ? ovl->manager->output->device : NULL) : | ||
| 45 | NULL; | ||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf) | ||
| 49 | { | ||
| 50 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
| 51 | ovl->manager ? ovl->manager->name : "<none>"); | ||
| 52 | } | ||
| 53 | |||
| 54 | static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf, | ||
| 55 | size_t size) | ||
| 56 | { | ||
| 57 | int i, r; | ||
| 58 | struct omap_overlay_manager *mgr = NULL; | ||
| 59 | struct omap_overlay_manager *old_mgr; | ||
| 60 | int len = size; | ||
| 61 | |||
| 62 | if (buf[size-1] == '\n') | ||
| 63 | --len; | ||
| 64 | |||
| 65 | if (len > 0) { | ||
| 66 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { | ||
| 67 | mgr = omap_dss_get_overlay_manager(i); | ||
| 68 | |||
| 69 | if (sysfs_streq(buf, mgr->name)) | ||
| 70 | break; | ||
| 71 | |||
| 72 | mgr = NULL; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | if (len > 0 && mgr == NULL) | ||
| 77 | return -EINVAL; | ||
| 78 | |||
| 79 | if (mgr) | ||
| 80 | DSSDBG("manager %s found\n", mgr->name); | ||
| 81 | |||
| 82 | if (mgr == ovl->manager) | ||
| 83 | return size; | ||
| 84 | |||
| 85 | old_mgr = ovl->manager; | ||
| 86 | |||
| 87 | r = dispc_runtime_get(); | ||
| 88 | if (r) | ||
| 89 | return r; | ||
| 90 | |||
| 91 | /* detach old manager */ | ||
| 92 | if (old_mgr) { | ||
| 93 | r = ovl->unset_manager(ovl); | ||
| 94 | if (r) { | ||
| 95 | DSSERR("detach failed\n"); | ||
| 96 | goto err; | ||
| 97 | } | ||
| 98 | |||
| 99 | r = old_mgr->apply(old_mgr); | ||
| 100 | if (r) | ||
| 101 | goto err; | ||
| 102 | } | ||
| 103 | |||
| 104 | if (mgr) { | ||
| 105 | r = ovl->set_manager(ovl, mgr); | ||
| 106 | if (r) { | ||
| 107 | DSSERR("Failed to attach overlay\n"); | ||
| 108 | goto err; | ||
| 109 | } | ||
| 110 | |||
| 111 | r = mgr->apply(mgr); | ||
| 112 | if (r) | ||
| 113 | goto err; | ||
| 114 | } | ||
| 115 | |||
| 116 | dispc_runtime_put(); | ||
| 117 | |||
| 118 | return size; | ||
| 119 | |||
| 120 | err: | ||
| 121 | dispc_runtime_put(); | ||
| 122 | return r; | ||
| 123 | } | ||
| 124 | |||
| 125 | static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) | ||
| 126 | { | ||
| 127 | struct omap_overlay_info info; | ||
| 128 | |||
| 129 | ovl->get_overlay_info(ovl, &info); | ||
| 130 | |||
| 131 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", | ||
| 132 | info.width, info.height); | ||
| 133 | } | ||
| 134 | |||
| 135 | static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf) | ||
| 136 | { | ||
| 137 | struct omap_overlay_info info; | ||
| 138 | |||
| 139 | ovl->get_overlay_info(ovl, &info); | ||
| 140 | |||
| 141 | return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width); | ||
| 142 | } | ||
| 143 | |||
| 144 | static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf) | ||
| 145 | { | ||
| 146 | struct omap_overlay_info info; | ||
| 147 | |||
| 148 | ovl->get_overlay_info(ovl, &info); | ||
| 149 | |||
| 150 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", | ||
| 151 | info.pos_x, info.pos_y); | ||
| 152 | } | ||
| 153 | |||
| 154 | static ssize_t overlay_position_store(struct omap_overlay *ovl, | ||
| 155 | const char *buf, size_t size) | ||
| 156 | { | ||
| 157 | int r; | ||
| 158 | char *last; | ||
| 159 | struct omap_overlay_info info; | ||
| 160 | |||
| 161 | ovl->get_overlay_info(ovl, &info); | ||
| 162 | |||
| 163 | info.pos_x = simple_strtoul(buf, &last, 10); | ||
| 164 | ++last; | ||
| 165 | if (last - buf >= size) | ||
| 166 | return -EINVAL; | ||
| 167 | |||
| 168 | info.pos_y = simple_strtoul(last, &last, 10); | ||
| 169 | |||
| 170 | r = ovl->set_overlay_info(ovl, &info); | ||
| 171 | if (r) | ||
| 172 | return r; | ||
| 173 | |||
| 174 | if (ovl->manager) { | ||
| 175 | r = ovl->manager->apply(ovl->manager); | ||
| 176 | if (r) | ||
| 177 | return r; | ||
| 178 | } | ||
| 179 | |||
| 180 | return size; | ||
| 181 | } | ||
| 182 | |||
| 183 | static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf) | ||
| 184 | { | ||
| 185 | struct omap_overlay_info info; | ||
| 186 | |||
| 187 | ovl->get_overlay_info(ovl, &info); | ||
| 188 | |||
| 189 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", | ||
| 190 | info.out_width, info.out_height); | ||
| 191 | } | ||
| 192 | |||
| 193 | static ssize_t overlay_output_size_store(struct omap_overlay *ovl, | ||
| 194 | const char *buf, size_t size) | ||
| 195 | { | ||
| 196 | int r; | ||
| 197 | char *last; | ||
| 198 | struct omap_overlay_info info; | ||
| 199 | |||
| 200 | ovl->get_overlay_info(ovl, &info); | ||
| 201 | |||
| 202 | info.out_width = simple_strtoul(buf, &last, 10); | ||
| 203 | ++last; | ||
| 204 | if (last - buf >= size) | ||
| 205 | return -EINVAL; | ||
| 206 | |||
| 207 | info.out_height = simple_strtoul(last, &last, 10); | ||
| 208 | |||
| 209 | r = ovl->set_overlay_info(ovl, &info); | ||
| 210 | if (r) | ||
| 211 | return r; | ||
| 212 | |||
| 213 | if (ovl->manager) { | ||
| 214 | r = ovl->manager->apply(ovl->manager); | ||
| 215 | if (r) | ||
| 216 | return r; | ||
| 217 | } | ||
| 218 | |||
| 219 | return size; | ||
| 220 | } | ||
| 221 | |||
| 222 | static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf) | ||
| 223 | { | ||
| 224 | return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl)); | ||
| 225 | } | ||
| 226 | |||
| 227 | static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, | ||
| 228 | size_t size) | ||
| 229 | { | ||
| 230 | int r; | ||
| 231 | bool enable; | ||
| 232 | |||
| 233 | r = strtobool(buf, &enable); | ||
| 234 | if (r) | ||
| 235 | return r; | ||
| 236 | |||
| 237 | if (enable) | ||
| 238 | r = ovl->enable(ovl); | ||
| 239 | else | ||
| 240 | r = ovl->disable(ovl); | ||
| 241 | |||
| 242 | if (r) | ||
| 243 | return r; | ||
| 244 | |||
| 245 | return size; | ||
| 246 | } | ||
| 247 | |||
| 248 | static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf) | ||
| 249 | { | ||
| 250 | struct omap_overlay_info info; | ||
| 251 | |||
| 252 | ovl->get_overlay_info(ovl, &info); | ||
| 253 | |||
| 254 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 255 | info.global_alpha); | ||
| 256 | } | ||
| 257 | |||
| 258 | static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl, | ||
| 259 | const char *buf, size_t size) | ||
| 260 | { | ||
| 261 | int r; | ||
| 262 | u8 alpha; | ||
| 263 | struct omap_overlay_info info; | ||
| 264 | |||
| 265 | if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) | ||
| 266 | return -ENODEV; | ||
| 267 | |||
| 268 | r = kstrtou8(buf, 0, &alpha); | ||
| 269 | if (r) | ||
| 270 | return r; | ||
| 271 | |||
| 272 | ovl->get_overlay_info(ovl, &info); | ||
| 273 | |||
| 274 | info.global_alpha = alpha; | ||
| 275 | |||
| 276 | r = ovl->set_overlay_info(ovl, &info); | ||
| 277 | if (r) | ||
| 278 | return r; | ||
| 279 | |||
| 280 | if (ovl->manager) { | ||
| 281 | r = ovl->manager->apply(ovl->manager); | ||
| 282 | if (r) | ||
| 283 | return r; | ||
| 284 | } | ||
| 285 | |||
| 286 | return size; | ||
| 287 | } | ||
| 288 | |||
| 289 | static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl, | ||
| 290 | char *buf) | ||
| 291 | { | ||
| 292 | struct omap_overlay_info info; | ||
| 293 | |||
| 294 | ovl->get_overlay_info(ovl, &info); | ||
| 295 | |||
| 296 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 297 | info.pre_mult_alpha); | ||
| 298 | } | ||
| 299 | |||
| 300 | static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, | ||
| 301 | const char *buf, size_t size) | ||
| 302 | { | ||
| 303 | int r; | ||
| 304 | u8 alpha; | ||
| 305 | struct omap_overlay_info info; | ||
| 306 | |||
| 307 | if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) | ||
| 308 | return -ENODEV; | ||
| 309 | |||
| 310 | r = kstrtou8(buf, 0, &alpha); | ||
| 311 | if (r) | ||
| 312 | return r; | ||
| 313 | |||
| 314 | ovl->get_overlay_info(ovl, &info); | ||
| 315 | |||
| 316 | info.pre_mult_alpha = alpha; | ||
| 317 | |||
| 318 | r = ovl->set_overlay_info(ovl, &info); | ||
| 319 | if (r) | ||
| 320 | return r; | ||
| 321 | |||
| 322 | if (ovl->manager) { | ||
| 323 | r = ovl->manager->apply(ovl->manager); | ||
| 324 | if (r) | ||
| 325 | return r; | ||
| 326 | } | ||
| 327 | |||
| 328 | return size; | ||
| 329 | } | ||
| 330 | |||
| 331 | static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf) | ||
| 332 | { | ||
| 333 | struct omap_overlay_info info; | ||
| 334 | |||
| 335 | ovl->get_overlay_info(ovl, &info); | ||
| 336 | |||
| 337 | return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder); | ||
| 338 | } | ||
| 339 | |||
| 340 | static ssize_t overlay_zorder_store(struct omap_overlay *ovl, | ||
| 341 | const char *buf, size_t size) | ||
| 342 | { | ||
| 343 | int r; | ||
| 344 | u8 zorder; | ||
| 345 | struct omap_overlay_info info; | ||
| 346 | |||
| 347 | if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) | ||
| 348 | return -ENODEV; | ||
| 349 | |||
| 350 | r = kstrtou8(buf, 0, &zorder); | ||
| 351 | if (r) | ||
| 352 | return r; | ||
| 353 | |||
| 354 | ovl->get_overlay_info(ovl, &info); | ||
| 355 | |||
| 356 | info.zorder = zorder; | ||
| 357 | |||
| 358 | r = ovl->set_overlay_info(ovl, &info); | ||
| 359 | if (r) | ||
| 360 | return r; | ||
| 361 | |||
| 362 | if (ovl->manager) { | ||
| 363 | r = ovl->manager->apply(ovl->manager); | ||
| 364 | if (r) | ||
| 365 | return r; | ||
| 366 | } | ||
| 367 | |||
| 368 | return size; | ||
| 369 | } | ||
| 370 | |||
| 371 | struct overlay_attribute { | ||
| 372 | struct attribute attr; | ||
| 373 | ssize_t (*show)(struct omap_overlay *, char *); | ||
| 374 | ssize_t (*store)(struct omap_overlay *, const char *, size_t); | ||
| 375 | }; | ||
| 376 | |||
| 377 | #define OVERLAY_ATTR(_name, _mode, _show, _store) \ | ||
| 378 | struct overlay_attribute overlay_attr_##_name = \ | ||
| 379 | __ATTR(_name, _mode, _show, _store) | ||
| 380 | |||
| 381 | static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL); | ||
| 382 | static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR, | ||
| 383 | overlay_manager_show, overlay_manager_store); | ||
| 384 | static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL); | ||
| 385 | static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL); | ||
| 386 | static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR, | ||
| 387 | overlay_position_show, overlay_position_store); | ||
| 388 | static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR, | ||
| 389 | overlay_output_size_show, overlay_output_size_store); | ||
| 390 | static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR, | ||
| 391 | overlay_enabled_show, overlay_enabled_store); | ||
| 392 | static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, | ||
| 393 | overlay_global_alpha_show, overlay_global_alpha_store); | ||
| 394 | static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, | ||
| 395 | overlay_pre_mult_alpha_show, | ||
| 396 | overlay_pre_mult_alpha_store); | ||
| 397 | static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, | ||
| 398 | overlay_zorder_show, overlay_zorder_store); | ||
| 399 | |||
| 400 | static struct attribute *overlay_sysfs_attrs[] = { | ||
| 401 | &overlay_attr_name.attr, | ||
| 402 | &overlay_attr_manager.attr, | ||
| 403 | &overlay_attr_input_size.attr, | ||
| 404 | &overlay_attr_screen_width.attr, | ||
| 405 | &overlay_attr_position.attr, | ||
| 406 | &overlay_attr_output_size.attr, | ||
| 407 | &overlay_attr_enabled.attr, | ||
| 408 | &overlay_attr_global_alpha.attr, | ||
| 409 | &overlay_attr_pre_mult_alpha.attr, | ||
| 410 | &overlay_attr_zorder.attr, | ||
| 411 | NULL | ||
| 412 | }; | ||
| 413 | |||
| 414 | static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr, | ||
| 415 | char *buf) | ||
| 416 | { | ||
| 417 | struct omap_overlay *overlay; | ||
| 418 | struct overlay_attribute *overlay_attr; | ||
| 419 | |||
| 420 | overlay = container_of(kobj, struct omap_overlay, kobj); | ||
| 421 | overlay_attr = container_of(attr, struct overlay_attribute, attr); | ||
| 422 | |||
| 423 | if (!overlay_attr->show) | ||
| 424 | return -ENOENT; | ||
| 425 | |||
| 426 | return overlay_attr->show(overlay, buf); | ||
| 427 | } | ||
| 428 | |||
| 429 | static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr, | ||
| 430 | const char *buf, size_t size) | ||
| 431 | { | ||
| 432 | struct omap_overlay *overlay; | ||
| 433 | struct overlay_attribute *overlay_attr; | ||
| 434 | |||
| 435 | overlay = container_of(kobj, struct omap_overlay, kobj); | ||
| 436 | overlay_attr = container_of(attr, struct overlay_attribute, attr); | ||
| 437 | |||
| 438 | if (!overlay_attr->store) | ||
| 439 | return -ENOENT; | ||
| 440 | |||
| 441 | return overlay_attr->store(overlay, buf, size); | ||
| 442 | } | ||
| 443 | |||
| 444 | static const struct sysfs_ops overlay_sysfs_ops = { | ||
| 445 | .show = overlay_attr_show, | ||
| 446 | .store = overlay_attr_store, | ||
| 447 | }; | ||
| 448 | |||
| 449 | static struct kobj_type overlay_ktype = { | ||
| 450 | .sysfs_ops = &overlay_sysfs_ops, | ||
| 451 | .default_attrs = overlay_sysfs_attrs, | ||
| 452 | }; | ||
| 453 | |||
| 454 | int omap_dss_get_num_overlays(void) | 48 | int omap_dss_get_num_overlays(void) |
| 455 | { | 49 | { |
| 456 | return num_overlays; | 50 | return num_overlays; |
| @@ -507,97 +101,25 @@ void dss_init_overlays(struct platform_device *pdev) | |||
| 507 | ovl->set_overlay_info = &dss_ovl_set_info; | 101 | ovl->set_overlay_info = &dss_ovl_set_info; |
| 508 | ovl->get_overlay_info = &dss_ovl_get_info; | 102 | ovl->get_overlay_info = &dss_ovl_get_info; |
| 509 | ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; | 103 | ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; |
| 104 | ovl->get_device = &dss_ovl_get_device; | ||
| 510 | 105 | ||
| 511 | ovl->caps = dss_feat_get_overlay_caps(ovl->id); | 106 | ovl->caps = dss_feat_get_overlay_caps(ovl->id); |
| 512 | ovl->supported_modes = | 107 | ovl->supported_modes = |
| 513 | dss_feat_get_supported_color_modes(ovl->id); | 108 | dss_feat_get_supported_color_modes(ovl->id); |
| 514 | 109 | ||
| 515 | r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, | 110 | r = dss_overlay_kobj_init(ovl, pdev); |
| 516 | &pdev->dev.kobj, "overlay%d", i); | ||
| 517 | |||
| 518 | if (r) | 111 | if (r) |
| 519 | DSSERR("failed to create sysfs file\n"); | 112 | DSSERR("failed to create sysfs file\n"); |
| 520 | } | 113 | } |
| 521 | } | 114 | } |
| 522 | 115 | ||
| 523 | /* connect overlays to the new device, if not already connected. if force | ||
| 524 | * selected, connect always. */ | ||
| 525 | void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) | ||
| 526 | { | ||
| 527 | int i; | ||
| 528 | struct omap_overlay_manager *lcd_mgr; | ||
| 529 | struct omap_overlay_manager *tv_mgr; | ||
| 530 | struct omap_overlay_manager *lcd2_mgr = NULL; | ||
| 531 | struct omap_overlay_manager *lcd3_mgr = NULL; | ||
| 532 | struct omap_overlay_manager *mgr = NULL; | ||
| 533 | |||
| 534 | lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD); | ||
| 535 | tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT); | ||
| 536 | if (dss_has_feature(FEAT_MGR_LCD3)) | ||
| 537 | lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3); | ||
| 538 | if (dss_has_feature(FEAT_MGR_LCD2)) | ||
| 539 | lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2); | ||
| 540 | |||
| 541 | if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) { | ||
| 542 | if (!lcd3_mgr->device || force) { | ||
| 543 | if (lcd3_mgr->device) | ||
| 544 | lcd3_mgr->unset_device(lcd3_mgr); | ||
| 545 | lcd3_mgr->set_device(lcd3_mgr, dssdev); | ||
| 546 | mgr = lcd3_mgr; | ||
| 547 | } | ||
| 548 | } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { | ||
| 549 | if (!lcd2_mgr->device || force) { | ||
| 550 | if (lcd2_mgr->device) | ||
| 551 | lcd2_mgr->unset_device(lcd2_mgr); | ||
| 552 | lcd2_mgr->set_device(lcd2_mgr, dssdev); | ||
| 553 | mgr = lcd2_mgr; | ||
| 554 | } | ||
| 555 | } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC | ||
| 556 | && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { | ||
| 557 | if (!lcd_mgr->device || force) { | ||
| 558 | if (lcd_mgr->device) | ||
| 559 | lcd_mgr->unset_device(lcd_mgr); | ||
| 560 | lcd_mgr->set_device(lcd_mgr, dssdev); | ||
| 561 | mgr = lcd_mgr; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | |||
| 565 | if (dssdev->type == OMAP_DISPLAY_TYPE_VENC | ||
| 566 | || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { | ||
| 567 | if (!tv_mgr->device || force) { | ||
| 568 | if (tv_mgr->device) | ||
| 569 | tv_mgr->unset_device(tv_mgr); | ||
| 570 | tv_mgr->set_device(tv_mgr, dssdev); | ||
| 571 | mgr = tv_mgr; | ||
| 572 | } | ||
| 573 | } | ||
| 574 | |||
| 575 | if (mgr) { | ||
| 576 | dispc_runtime_get(); | ||
| 577 | |||
| 578 | for (i = 0; i < dss_feat_get_num_ovls(); i++) { | ||
| 579 | struct omap_overlay *ovl; | ||
| 580 | ovl = omap_dss_get_overlay(i); | ||
| 581 | if (!ovl->manager || force) { | ||
| 582 | if (ovl->manager) | ||
| 583 | ovl->unset_manager(ovl); | ||
| 584 | ovl->set_manager(ovl, mgr); | ||
| 585 | } | ||
| 586 | } | ||
| 587 | |||
| 588 | dispc_runtime_put(); | ||
| 589 | } | ||
| 590 | } | ||
| 591 | |||
| 592 | void dss_uninit_overlays(struct platform_device *pdev) | 116 | void dss_uninit_overlays(struct platform_device *pdev) |
| 593 | { | 117 | { |
| 594 | int i; | 118 | int i; |
| 595 | 119 | ||
| 596 | for (i = 0; i < num_overlays; ++i) { | 120 | for (i = 0; i < num_overlays; ++i) { |
| 597 | struct omap_overlay *ovl = &overlays[i]; | 121 | struct omap_overlay *ovl = &overlays[i]; |
| 598 | 122 | dss_overlay_kobj_uninit(ovl); | |
| 599 | kobject_del(&ovl->kobj); | ||
| 600 | kobject_put(&ovl->kobj); | ||
| 601 | } | 123 | } |
| 602 | 124 | ||
| 603 | kfree(overlays); | 125 | kfree(overlays); |
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 7c087424b634..7282e5af3e1a 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c | |||
| @@ -111,6 +111,13 @@ static struct { | |||
| 111 | struct omap_dss_device *dssdev[2]; | 111 | struct omap_dss_device *dssdev[2]; |
| 112 | 112 | ||
| 113 | struct semaphore bus_lock; | 113 | struct semaphore bus_lock; |
| 114 | |||
| 115 | struct omap_video_timings timings; | ||
| 116 | int pixel_size; | ||
| 117 | int data_lines; | ||
| 118 | struct rfbi_timings intf_timings; | ||
| 119 | |||
| 120 | struct omap_dss_output output; | ||
| 114 | } rfbi; | 121 | } rfbi; |
| 115 | 122 | ||
| 116 | static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) | 123 | static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) |
| @@ -300,30 +307,23 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, | |||
| 300 | } | 307 | } |
| 301 | EXPORT_SYMBOL(omap_rfbi_write_pixels); | 308 | EXPORT_SYMBOL(omap_rfbi_write_pixels); |
| 302 | 309 | ||
| 303 | static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, | 310 | static int rfbi_transfer_area(struct omap_dss_device *dssdev, |
| 304 | u16 height, void (*callback)(void *data), void *data) | 311 | void (*callback)(void *data), void *data) |
| 305 | { | 312 | { |
| 306 | u32 l; | 313 | u32 l; |
| 307 | int r; | 314 | int r; |
| 308 | struct omap_video_timings timings = { | 315 | struct omap_overlay_manager *mgr = dssdev->output->manager; |
| 309 | .hsw = 1, | 316 | u16 width = rfbi.timings.x_res; |
| 310 | .hfp = 1, | 317 | u16 height = rfbi.timings.y_res; |
| 311 | .hbp = 1, | ||
| 312 | .vsw = 1, | ||
| 313 | .vfp = 0, | ||
| 314 | .vbp = 0, | ||
| 315 | .x_res = width, | ||
| 316 | .y_res = height, | ||
| 317 | }; | ||
| 318 | 318 | ||
| 319 | /*BUG_ON(callback == 0);*/ | 319 | /*BUG_ON(callback == 0);*/ |
| 320 | BUG_ON(rfbi.framedone_callback != NULL); | 320 | BUG_ON(rfbi.framedone_callback != NULL); |
| 321 | 321 | ||
| 322 | DSSDBG("rfbi_transfer_area %dx%d\n", width, height); | 322 | DSSDBG("rfbi_transfer_area %dx%d\n", width, height); |
| 323 | 323 | ||
| 324 | dss_mgr_set_timings(dssdev->manager, &timings); | 324 | dss_mgr_set_timings(mgr, &rfbi.timings); |
| 325 | 325 | ||
| 326 | r = dss_mgr_enable(dssdev->manager); | 326 | r = dss_mgr_enable(mgr); |
| 327 | if (r) | 327 | if (r) |
| 328 | return r; | 328 | return r; |
| 329 | 329 | ||
| @@ -770,62 +770,45 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines) | |||
| 770 | return 0; | 770 | return 0; |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size, | 773 | int omap_rfbi_configure(struct omap_dss_device *dssdev) |
| 774 | int data_lines) | ||
| 775 | { | 774 | { |
| 776 | return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines); | 775 | return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size, |
| 776 | rfbi.data_lines); | ||
| 777 | } | 777 | } |
| 778 | EXPORT_SYMBOL(omap_rfbi_configure); | 778 | EXPORT_SYMBOL(omap_rfbi_configure); |
| 779 | 779 | ||
| 780 | int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, | 780 | int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), |
| 781 | u16 *x, u16 *y, u16 *w, u16 *h) | 781 | void *data) |
| 782 | { | 782 | { |
| 783 | u16 dw, dh; | 783 | return rfbi_transfer_area(dssdev, callback, data); |
| 784 | struct omap_video_timings timings = { | 784 | } |
| 785 | .hsw = 1, | 785 | EXPORT_SYMBOL(omap_rfbi_update); |
| 786 | .hfp = 1, | ||
| 787 | .hbp = 1, | ||
| 788 | .vsw = 1, | ||
| 789 | .vfp = 0, | ||
| 790 | .vbp = 0, | ||
| 791 | .x_res = *w, | ||
| 792 | .y_res = *h, | ||
| 793 | }; | ||
| 794 | |||
| 795 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | ||
| 796 | |||
| 797 | if (*x > dw || *y > dh) | ||
| 798 | return -EINVAL; | ||
| 799 | |||
| 800 | if (*x + *w > dw) | ||
| 801 | return -EINVAL; | ||
| 802 | |||
| 803 | if (*y + *h > dh) | ||
| 804 | return -EINVAL; | ||
| 805 | |||
| 806 | if (*w == 1) | ||
| 807 | return -EINVAL; | ||
| 808 | |||
| 809 | if (*w == 0 || *h == 0) | ||
| 810 | return -EINVAL; | ||
| 811 | |||
| 812 | dss_mgr_set_timings(dssdev->manager, &timings); | ||
| 813 | 786 | ||
| 814 | return 0; | 787 | void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) |
| 788 | { | ||
| 789 | rfbi.timings.x_res = w; | ||
| 790 | rfbi.timings.y_res = h; | ||
| 815 | } | 791 | } |
| 816 | EXPORT_SYMBOL(omap_rfbi_prepare_update); | 792 | EXPORT_SYMBOL(omapdss_rfbi_set_size); |
| 817 | 793 | ||
| 818 | int omap_rfbi_update(struct omap_dss_device *dssdev, | 794 | void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) |
| 819 | u16 x, u16 y, u16 w, u16 h, | ||
| 820 | void (*callback)(void *), void *data) | ||
| 821 | { | 795 | { |
| 822 | int r; | 796 | rfbi.pixel_size = pixel_size; |
| 797 | } | ||
| 798 | EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size); | ||
| 823 | 799 | ||
| 824 | r = rfbi_transfer_area(dssdev, w, h, callback, data); | 800 | void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) |
| 801 | { | ||
| 802 | rfbi.data_lines = data_lines; | ||
| 803 | } | ||
| 804 | EXPORT_SYMBOL(omapdss_rfbi_set_data_lines); | ||
| 825 | 805 | ||
| 826 | return r; | 806 | void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev, |
| 807 | struct rfbi_timings *timings) | ||
| 808 | { | ||
| 809 | rfbi.intf_timings = *timings; | ||
| 827 | } | 810 | } |
| 828 | EXPORT_SYMBOL(omap_rfbi_update); | 811 | EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings); |
| 829 | 812 | ||
| 830 | static void rfbi_dump_regs(struct seq_file *s) | 813 | static void rfbi_dump_regs(struct seq_file *s) |
| 831 | { | 814 | { |
| @@ -869,6 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s) | |||
| 869 | 852 | ||
| 870 | static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) | 853 | static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) |
| 871 | { | 854 | { |
| 855 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 872 | struct dss_lcd_mgr_config mgr_config; | 856 | struct dss_lcd_mgr_config mgr_config; |
| 873 | 857 | ||
| 874 | mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; | 858 | mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; |
| @@ -877,18 +861,40 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) | |||
| 877 | /* Do we need fifohandcheck for RFBI? */ | 861 | /* Do we need fifohandcheck for RFBI? */ |
| 878 | mgr_config.fifohandcheck = false; | 862 | mgr_config.fifohandcheck = false; |
| 879 | 863 | ||
| 880 | mgr_config.video_port_width = dssdev->ctrl.pixel_size; | 864 | mgr_config.video_port_width = rfbi.pixel_size; |
| 881 | mgr_config.lcden_sig_polarity = 0; | 865 | mgr_config.lcden_sig_polarity = 0; |
| 882 | 866 | ||
| 883 | dss_mgr_set_lcd_config(dssdev->manager, &mgr_config); | 867 | dss_mgr_set_lcd_config(mgr, &mgr_config); |
| 868 | |||
| 869 | /* | ||
| 870 | * Set rfbi.timings with default values, the x_res and y_res fields | ||
| 871 | * are expected to be already configured by the panel driver via | ||
| 872 | * omapdss_rfbi_set_size() | ||
| 873 | */ | ||
| 874 | rfbi.timings.hsw = 1; | ||
| 875 | rfbi.timings.hfp = 1; | ||
| 876 | rfbi.timings.hbp = 1; | ||
| 877 | rfbi.timings.vsw = 1; | ||
| 878 | rfbi.timings.vfp = 0; | ||
| 879 | rfbi.timings.vbp = 0; | ||
| 880 | |||
| 881 | rfbi.timings.interlace = false; | ||
| 882 | rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
| 883 | rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
| 884 | rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
| 885 | rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
| 886 | rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
| 887 | |||
| 888 | dss_mgr_set_timings(mgr, &rfbi.timings); | ||
| 884 | } | 889 | } |
| 885 | 890 | ||
| 886 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | 891 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) |
| 887 | { | 892 | { |
| 893 | struct omap_dss_output *out = dssdev->output; | ||
| 888 | int r; | 894 | int r; |
| 889 | 895 | ||
| 890 | if (dssdev->manager == NULL) { | 896 | if (out == NULL || out->manager == NULL) { |
| 891 | DSSERR("failed to enable display: no manager\n"); | 897 | DSSERR("failed to enable display: no output/manager\n"); |
| 892 | return -ENODEV; | 898 | return -ENODEV; |
| 893 | } | 899 | } |
| 894 | 900 | ||
| @@ -911,13 +917,10 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | |||
| 911 | 917 | ||
| 912 | rfbi_config_lcd_manager(dssdev); | 918 | rfbi_config_lcd_manager(dssdev); |
| 913 | 919 | ||
| 914 | rfbi_configure(dssdev->phy.rfbi.channel, | 920 | rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size, |
| 915 | dssdev->ctrl.pixel_size, | 921 | rfbi.data_lines); |
| 916 | dssdev->phy.rfbi.data_lines); | ||
| 917 | |||
| 918 | rfbi_set_timings(dssdev->phy.rfbi.channel, | ||
| 919 | &dssdev->ctrl.rfbi_timings); | ||
| 920 | 922 | ||
| 923 | rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings); | ||
| 921 | 924 | ||
| 922 | return 0; | 925 | return 0; |
| 923 | err1: | 926 | err1: |
| @@ -941,14 +944,17 @@ EXPORT_SYMBOL(omapdss_rfbi_display_disable); | |||
| 941 | static int __init rfbi_init_display(struct omap_dss_device *dssdev) | 944 | static int __init rfbi_init_display(struct omap_dss_device *dssdev) |
| 942 | { | 945 | { |
| 943 | rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; | 946 | rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; |
| 944 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; | ||
| 945 | return 0; | 947 | return 0; |
| 946 | } | 948 | } |
| 947 | 949 | ||
| 948 | static void __init rfbi_probe_pdata(struct platform_device *pdev) | 950 | static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev) |
| 949 | { | 951 | { |
| 950 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | 952 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
| 951 | int i, r; | 953 | const char *def_disp_name = dss_get_default_display_name(); |
| 954 | struct omap_dss_device *def_dssdev; | ||
| 955 | int i; | ||
| 956 | |||
| 957 | def_dssdev = NULL; | ||
| 952 | 958 | ||
| 953 | for (i = 0; i < pdata->num_devices; ++i) { | 959 | for (i = 0; i < pdata->num_devices; ++i) { |
| 954 | struct omap_dss_device *dssdev = pdata->devices[i]; | 960 | struct omap_dss_device *dssdev = pdata->devices[i]; |
| @@ -956,17 +962,67 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev) | |||
| 956 | if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) | 962 | if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) |
| 957 | continue; | 963 | continue; |
| 958 | 964 | ||
| 959 | r = rfbi_init_display(dssdev); | 965 | if (def_dssdev == NULL) |
| 960 | if (r) { | 966 | def_dssdev = dssdev; |
| 961 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 967 | |
| 962 | continue; | 968 | if (def_disp_name != NULL && |
| 969 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
| 970 | def_dssdev = dssdev; | ||
| 971 | break; | ||
| 963 | } | 972 | } |
| 973 | } | ||
| 974 | |||
| 975 | return def_dssdev; | ||
| 976 | } | ||
| 977 | |||
| 978 | static void __init rfbi_probe_pdata(struct platform_device *rfbidev) | ||
| 979 | { | ||
| 980 | struct omap_dss_device *plat_dssdev; | ||
| 981 | struct omap_dss_device *dssdev; | ||
| 982 | int r; | ||
| 983 | |||
| 984 | plat_dssdev = rfbi_find_dssdev(rfbidev); | ||
| 985 | |||
| 986 | if (!plat_dssdev) | ||
| 987 | return; | ||
| 988 | |||
| 989 | dssdev = dss_alloc_and_init_device(&rfbidev->dev); | ||
| 990 | if (!dssdev) | ||
| 991 | return; | ||
| 992 | |||
| 993 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
| 964 | 994 | ||
| 965 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | 995 | r = rfbi_init_display(dssdev); |
| 966 | if (r) | 996 | if (r) { |
| 967 | DSSERR("device %s register failed: %d\n", | 997 | DSSERR("device %s init failed: %d\n", dssdev->name, r); |
| 968 | dssdev->name, r); | 998 | dss_put_device(dssdev); |
| 999 | return; | ||
| 969 | } | 1000 | } |
| 1001 | |||
| 1002 | r = dss_add_device(dssdev); | ||
| 1003 | if (r) { | ||
| 1004 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
| 1005 | dss_put_device(dssdev); | ||
| 1006 | return; | ||
| 1007 | } | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | static void __init rfbi_init_output(struct platform_device *pdev) | ||
| 1011 | { | ||
| 1012 | struct omap_dss_output *out = &rfbi.output; | ||
| 1013 | |||
| 1014 | out->pdev = pdev; | ||
| 1015 | out->id = OMAP_DSS_OUTPUT_DBI; | ||
| 1016 | out->type = OMAP_DISPLAY_TYPE_DBI; | ||
| 1017 | |||
| 1018 | dss_register_output(out); | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | static void __exit rfbi_uninit_output(struct platform_device *pdev) | ||
| 1022 | { | ||
| 1023 | struct omap_dss_output *out = &rfbi.output; | ||
| 1024 | |||
| 1025 | dss_unregister_output(out); | ||
| 970 | } | 1026 | } |
| 971 | 1027 | ||
| 972 | /* RFBI HW IP initialisation */ | 1028 | /* RFBI HW IP initialisation */ |
| @@ -1020,6 +1076,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev) | |||
| 1020 | 1076 | ||
| 1021 | dss_debugfs_create_file("rfbi", rfbi_dump_regs); | 1077 | dss_debugfs_create_file("rfbi", rfbi_dump_regs); |
| 1022 | 1078 | ||
| 1079 | rfbi_init_output(pdev); | ||
| 1080 | |||
| 1023 | rfbi_probe_pdata(pdev); | 1081 | rfbi_probe_pdata(pdev); |
| 1024 | 1082 | ||
| 1025 | return 0; | 1083 | return 0; |
| @@ -1031,8 +1089,12 @@ err_runtime_get: | |||
| 1031 | 1089 | ||
| 1032 | static int __exit omap_rfbihw_remove(struct platform_device *pdev) | 1090 | static int __exit omap_rfbihw_remove(struct platform_device *pdev) |
| 1033 | { | 1091 | { |
| 1034 | omap_dss_unregister_child_devices(&pdev->dev); | 1092 | dss_unregister_child_devices(&pdev->dev); |
| 1093 | |||
| 1094 | rfbi_uninit_output(pdev); | ||
| 1095 | |||
| 1035 | pm_runtime_disable(&pdev->dev); | 1096 | pm_runtime_disable(&pdev->dev); |
| 1097 | |||
| 1036 | return 0; | 1098 | return 0; |
| 1037 | } | 1099 | } |
| 1038 | 1100 | ||
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index f43bfe17b3b6..7760851f6e5d 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/regulator/consumer.h> | 25 | #include <linux/regulator/consumer.h> |
| 26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
| 27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
| 28 | #include <linux/string.h> | ||
| 28 | 29 | ||
| 29 | #include <video/omapdss.h> | 30 | #include <video/omapdss.h> |
| 30 | #include "dss.h" | 31 | #include "dss.h" |
| @@ -34,10 +35,16 @@ static struct { | |||
| 34 | struct regulator *vdds_sdi_reg; | 35 | struct regulator *vdds_sdi_reg; |
| 35 | 36 | ||
| 36 | struct dss_lcd_mgr_config mgr_config; | 37 | struct dss_lcd_mgr_config mgr_config; |
| 38 | struct omap_video_timings timings; | ||
| 39 | int datapairs; | ||
| 40 | |||
| 41 | struct omap_dss_output output; | ||
| 37 | } sdi; | 42 | } sdi; |
| 38 | 43 | ||
| 39 | static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) | 44 | static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) |
| 40 | { | 45 | { |
| 46 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 47 | |||
| 41 | sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; | 48 | sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; |
| 42 | 49 | ||
| 43 | sdi.mgr_config.stallmode = false; | 50 | sdi.mgr_config.stallmode = false; |
| @@ -46,19 +53,20 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) | |||
| 46 | sdi.mgr_config.video_port_width = 24; | 53 | sdi.mgr_config.video_port_width = 24; |
| 47 | sdi.mgr_config.lcden_sig_polarity = 1; | 54 | sdi.mgr_config.lcden_sig_polarity = 1; |
| 48 | 55 | ||
| 49 | dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config); | 56 | dss_mgr_set_lcd_config(mgr, &sdi.mgr_config); |
| 50 | } | 57 | } |
| 51 | 58 | ||
| 52 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | 59 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) |
| 53 | { | 60 | { |
| 54 | struct omap_video_timings *t = &dssdev->panel.timings; | 61 | struct omap_dss_output *out = dssdev->output; |
| 62 | struct omap_video_timings *t = &sdi.timings; | ||
| 55 | struct dss_clock_info dss_cinfo; | 63 | struct dss_clock_info dss_cinfo; |
| 56 | struct dispc_clock_info dispc_cinfo; | 64 | struct dispc_clock_info dispc_cinfo; |
| 57 | unsigned long pck; | 65 | unsigned long pck; |
| 58 | int r; | 66 | int r; |
| 59 | 67 | ||
| 60 | if (dssdev->manager == NULL) { | 68 | if (out == NULL || out->manager == NULL) { |
| 61 | DSSERR("failed to enable display: no manager\n"); | 69 | DSSERR("failed to enable display: no output/manager\n"); |
| 62 | return -ENODEV; | 70 | return -ENODEV; |
| 63 | } | 71 | } |
| 64 | 72 | ||
| @@ -77,8 +85,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
| 77 | goto err_get_dispc; | 85 | goto err_get_dispc; |
| 78 | 86 | ||
| 79 | /* 15.5.9.1.2 */ | 87 | /* 15.5.9.1.2 */ |
| 80 | dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | 88 | t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; |
| 81 | dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | 89 | t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; |
| 82 | 90 | ||
| 83 | r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); | 91 | r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); |
| 84 | if (r) | 92 | if (r) |
| @@ -97,7 +105,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
| 97 | } | 105 | } |
| 98 | 106 | ||
| 99 | 107 | ||
| 100 | dss_mgr_set_timings(dssdev->manager, t); | 108 | dss_mgr_set_timings(out->manager, t); |
| 101 | 109 | ||
| 102 | r = dss_set_clock_div(&dss_cinfo); | 110 | r = dss_set_clock_div(&dss_cinfo); |
| 103 | if (r) | 111 | if (r) |
| @@ -116,16 +124,15 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
| 116 | * need to care about the shadow register mechanism for pck-free. The | 124 | * need to care about the shadow register mechanism for pck-free. The |
| 117 | * exact reason for this is unknown. | 125 | * exact reason for this is unknown. |
| 118 | */ | 126 | */ |
| 119 | dispc_mgr_set_clock_div(dssdev->manager->id, | 127 | dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info); |
| 120 | &sdi.mgr_config.clock_info); | ||
| 121 | 128 | ||
| 122 | dss_sdi_init(dssdev->phy.sdi.datapairs); | 129 | dss_sdi_init(sdi.datapairs); |
| 123 | r = dss_sdi_enable(); | 130 | r = dss_sdi_enable(); |
| 124 | if (r) | 131 | if (r) |
| 125 | goto err_sdi_enable; | 132 | goto err_sdi_enable; |
| 126 | mdelay(2); | 133 | mdelay(2); |
| 127 | 134 | ||
| 128 | r = dss_mgr_enable(dssdev->manager); | 135 | r = dss_mgr_enable(out->manager); |
| 129 | if (r) | 136 | if (r) |
| 130 | goto err_mgr_enable; | 137 | goto err_mgr_enable; |
| 131 | 138 | ||
| @@ -148,7 +155,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable); | |||
| 148 | 155 | ||
| 149 | void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) | 156 | void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) |
| 150 | { | 157 | { |
| 151 | dss_mgr_disable(dssdev->manager); | 158 | struct omap_overlay_manager *mgr = dssdev->output->manager; |
| 159 | |||
| 160 | dss_mgr_disable(mgr); | ||
| 152 | 161 | ||
| 153 | dss_sdi_disable(); | 162 | dss_sdi_disable(); |
| 154 | 163 | ||
| @@ -160,6 +169,19 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) | |||
| 160 | } | 169 | } |
| 161 | EXPORT_SYMBOL(omapdss_sdi_display_disable); | 170 | EXPORT_SYMBOL(omapdss_sdi_display_disable); |
| 162 | 171 | ||
| 172 | void omapdss_sdi_set_timings(struct omap_dss_device *dssdev, | ||
| 173 | struct omap_video_timings *timings) | ||
| 174 | { | ||
| 175 | sdi.timings = *timings; | ||
| 176 | } | ||
| 177 | EXPORT_SYMBOL(omapdss_sdi_set_timings); | ||
| 178 | |||
| 179 | void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) | ||
| 180 | { | ||
| 181 | sdi.datapairs = datapairs; | ||
| 182 | } | ||
| 183 | EXPORT_SYMBOL(omapdss_sdi_set_datapairs); | ||
| 184 | |||
| 163 | static int __init sdi_init_display(struct omap_dss_device *dssdev) | 185 | static int __init sdi_init_display(struct omap_dss_device *dssdev) |
| 164 | { | 186 | { |
| 165 | DSSDBG("SDI init\n"); | 187 | DSSDBG("SDI init\n"); |
| @@ -180,10 +202,14 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev) | |||
| 180 | return 0; | 202 | return 0; |
| 181 | } | 203 | } |
| 182 | 204 | ||
| 183 | static void __init sdi_probe_pdata(struct platform_device *pdev) | 205 | static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev) |
| 184 | { | 206 | { |
| 185 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | 207 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
| 186 | int i, r; | 208 | const char *def_disp_name = dss_get_default_display_name(); |
| 209 | struct omap_dss_device *def_dssdev; | ||
| 210 | int i; | ||
| 211 | |||
| 212 | def_dssdev = NULL; | ||
| 187 | 213 | ||
| 188 | for (i = 0; i < pdata->num_devices; ++i) { | 214 | for (i = 0; i < pdata->num_devices; ++i) { |
| 189 | struct omap_dss_device *dssdev = pdata->devices[i]; | 215 | struct omap_dss_device *dssdev = pdata->devices[i]; |
| @@ -191,21 +217,73 @@ static void __init sdi_probe_pdata(struct platform_device *pdev) | |||
| 191 | if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) | 217 | if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) |
| 192 | continue; | 218 | continue; |
| 193 | 219 | ||
| 194 | r = sdi_init_display(dssdev); | 220 | if (def_dssdev == NULL) |
| 195 | if (r) { | 221 | def_dssdev = dssdev; |
| 196 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 222 | |
| 197 | continue; | 223 | if (def_disp_name != NULL && |
| 224 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
| 225 | def_dssdev = dssdev; | ||
| 226 | break; | ||
| 198 | } | 227 | } |
| 228 | } | ||
| 229 | |||
| 230 | return def_dssdev; | ||
| 231 | } | ||
| 232 | |||
| 233 | static void __init sdi_probe_pdata(struct platform_device *sdidev) | ||
| 234 | { | ||
| 235 | struct omap_dss_device *plat_dssdev; | ||
| 236 | struct omap_dss_device *dssdev; | ||
| 237 | int r; | ||
| 238 | |||
| 239 | plat_dssdev = sdi_find_dssdev(sdidev); | ||
| 199 | 240 | ||
| 200 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | 241 | if (!plat_dssdev) |
| 201 | if (r) | 242 | return; |
| 202 | DSSERR("device %s register failed: %d\n", | 243 | |
| 203 | dssdev->name, r); | 244 | dssdev = dss_alloc_and_init_device(&sdidev->dev); |
| 245 | if (!dssdev) | ||
| 246 | return; | ||
| 247 | |||
| 248 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
| 249 | |||
| 250 | r = sdi_init_display(dssdev); | ||
| 251 | if (r) { | ||
| 252 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
| 253 | dss_put_device(dssdev); | ||
| 254 | return; | ||
| 204 | } | 255 | } |
| 256 | |||
| 257 | r = dss_add_device(dssdev); | ||
| 258 | if (r) { | ||
| 259 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
| 260 | dss_put_device(dssdev); | ||
| 261 | return; | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | static void __init sdi_init_output(struct platform_device *pdev) | ||
| 266 | { | ||
| 267 | struct omap_dss_output *out = &sdi.output; | ||
| 268 | |||
| 269 | out->pdev = pdev; | ||
| 270 | out->id = OMAP_DSS_OUTPUT_SDI; | ||
| 271 | out->type = OMAP_DISPLAY_TYPE_SDI; | ||
| 272 | |||
| 273 | dss_register_output(out); | ||
| 274 | } | ||
| 275 | |||
| 276 | static void __exit sdi_uninit_output(struct platform_device *pdev) | ||
| 277 | { | ||
| 278 | struct omap_dss_output *out = &sdi.output; | ||
| 279 | |||
| 280 | dss_unregister_output(out); | ||
| 205 | } | 281 | } |
| 206 | 282 | ||
| 207 | static int __init omap_sdi_probe(struct platform_device *pdev) | 283 | static int __init omap_sdi_probe(struct platform_device *pdev) |
| 208 | { | 284 | { |
| 285 | sdi_init_output(pdev); | ||
| 286 | |||
| 209 | sdi_probe_pdata(pdev); | 287 | sdi_probe_pdata(pdev); |
| 210 | 288 | ||
| 211 | return 0; | 289 | return 0; |
| @@ -213,7 +291,9 @@ static int __init omap_sdi_probe(struct platform_device *pdev) | |||
| 213 | 291 | ||
| 214 | static int __exit omap_sdi_remove(struct platform_device *pdev) | 292 | static int __exit omap_sdi_remove(struct platform_device *pdev) |
| 215 | { | 293 | { |
| 216 | omap_dss_unregister_child_devices(&pdev->dev); | 294 | dss_unregister_child_devices(&pdev->dev); |
| 295 | |||
| 296 | sdi_uninit_output(pdev); | ||
| 217 | 297 | ||
| 218 | return 0; | 298 | return 0; |
| 219 | } | 299 | } |
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 3a220877461a..56efa3bb465d 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c | |||
| @@ -36,7 +36,6 @@ | |||
| 36 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
| 37 | 37 | ||
| 38 | #include <video/omapdss.h> | 38 | #include <video/omapdss.h> |
| 39 | #include <plat/cpu.h> | ||
| 40 | 39 | ||
| 41 | #include "dss.h" | 40 | #include "dss.h" |
| 42 | #include "dss_features.h" | 41 | #include "dss_features.h" |
| @@ -300,6 +299,12 @@ static struct { | |||
| 300 | struct regulator *vdda_dac_reg; | 299 | struct regulator *vdda_dac_reg; |
| 301 | 300 | ||
| 302 | struct clk *tv_dac_clk; | 301 | struct clk *tv_dac_clk; |
| 302 | |||
| 303 | struct omap_video_timings timings; | ||
| 304 | enum omap_dss_venc_type type; | ||
| 305 | bool invert_polarity; | ||
| 306 | |||
| 307 | struct omap_dss_output output; | ||
| 303 | } venc; | 308 | } venc; |
| 304 | 309 | ||
| 305 | static inline void venc_write_reg(int idx, u32 val) | 310 | static inline void venc_write_reg(int idx, u32 val) |
| @@ -424,65 +429,67 @@ static const struct venc_config *venc_timings_to_config( | |||
| 424 | 429 | ||
| 425 | static int venc_power_on(struct omap_dss_device *dssdev) | 430 | static int venc_power_on(struct omap_dss_device *dssdev) |
| 426 | { | 431 | { |
| 432 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 427 | u32 l; | 433 | u32 l; |
| 428 | int r; | 434 | int r; |
| 429 | 435 | ||
| 436 | r = venc_runtime_get(); | ||
| 437 | if (r) | ||
| 438 | goto err0; | ||
| 439 | |||
| 430 | venc_reset(); | 440 | venc_reset(); |
| 431 | venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); | 441 | venc_write_config(venc_timings_to_config(&venc.timings)); |
| 432 | 442 | ||
| 433 | dss_set_venc_output(dssdev->phy.venc.type); | 443 | dss_set_venc_output(venc.type); |
| 434 | dss_set_dac_pwrdn_bgz(1); | 444 | dss_set_dac_pwrdn_bgz(1); |
| 435 | 445 | ||
| 436 | l = 0; | 446 | l = 0; |
| 437 | 447 | ||
| 438 | if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) | 448 | if (venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) |
| 439 | l |= 1 << 1; | 449 | l |= 1 << 1; |
| 440 | else /* S-Video */ | 450 | else /* S-Video */ |
| 441 | l |= (1 << 0) | (1 << 2); | 451 | l |= (1 << 0) | (1 << 2); |
| 442 | 452 | ||
| 443 | if (dssdev->phy.venc.invert_polarity == false) | 453 | if (venc.invert_polarity == false) |
| 444 | l |= 1 << 3; | 454 | l |= 1 << 3; |
| 445 | 455 | ||
| 446 | venc_write_reg(VENC_OUTPUT_CONTROL, l); | 456 | venc_write_reg(VENC_OUTPUT_CONTROL, l); |
| 447 | 457 | ||
| 448 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); | 458 | dss_mgr_set_timings(mgr, &venc.timings); |
| 449 | 459 | ||
| 450 | r = regulator_enable(venc.vdda_dac_reg); | 460 | r = regulator_enable(venc.vdda_dac_reg); |
| 451 | if (r) | 461 | if (r) |
| 452 | goto err; | 462 | goto err1; |
| 453 | |||
| 454 | if (dssdev->platform_enable) | ||
| 455 | dssdev->platform_enable(dssdev); | ||
| 456 | 463 | ||
| 457 | r = dss_mgr_enable(dssdev->manager); | 464 | r = dss_mgr_enable(mgr); |
| 458 | if (r) | 465 | if (r) |
| 459 | goto err; | 466 | goto err2; |
| 460 | 467 | ||
| 461 | return 0; | 468 | return 0; |
| 462 | 469 | ||
| 463 | err: | 470 | err2: |
| 471 | regulator_disable(venc.vdda_dac_reg); | ||
| 472 | err1: | ||
| 464 | venc_write_reg(VENC_OUTPUT_CONTROL, 0); | 473 | venc_write_reg(VENC_OUTPUT_CONTROL, 0); |
| 465 | dss_set_dac_pwrdn_bgz(0); | 474 | dss_set_dac_pwrdn_bgz(0); |
| 466 | 475 | ||
| 467 | if (dssdev->platform_disable) | 476 | venc_runtime_put(); |
| 468 | dssdev->platform_disable(dssdev); | 477 | err0: |
| 469 | |||
| 470 | regulator_disable(venc.vdda_dac_reg); | ||
| 471 | |||
| 472 | return r; | 478 | return r; |
| 473 | } | 479 | } |
| 474 | 480 | ||
| 475 | static void venc_power_off(struct omap_dss_device *dssdev) | 481 | static void venc_power_off(struct omap_dss_device *dssdev) |
| 476 | { | 482 | { |
| 483 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
| 484 | |||
| 477 | venc_write_reg(VENC_OUTPUT_CONTROL, 0); | 485 | venc_write_reg(VENC_OUTPUT_CONTROL, 0); |
| 478 | dss_set_dac_pwrdn_bgz(0); | 486 | dss_set_dac_pwrdn_bgz(0); |
| 479 | 487 | ||
| 480 | dss_mgr_disable(dssdev->manager); | 488 | dss_mgr_disable(mgr); |
| 481 | |||
| 482 | if (dssdev->platform_disable) | ||
| 483 | dssdev->platform_disable(dssdev); | ||
| 484 | 489 | ||
| 485 | regulator_disable(venc.vdda_dac_reg); | 490 | regulator_disable(venc.vdda_dac_reg); |
| 491 | |||
| 492 | venc_runtime_put(); | ||
| 486 | } | 493 | } |
| 487 | 494 | ||
| 488 | unsigned long venc_get_pixel_clock(void) | 495 | unsigned long venc_get_pixel_clock(void) |
| @@ -491,171 +498,83 @@ unsigned long venc_get_pixel_clock(void) | |||
| 491 | return 13500000; | 498 | return 13500000; |
| 492 | } | 499 | } |
| 493 | 500 | ||
| 494 | static ssize_t display_output_type_show(struct device *dev, | 501 | int omapdss_venc_display_enable(struct omap_dss_device *dssdev) |
| 495 | struct device_attribute *attr, char *buf) | ||
| 496 | { | 502 | { |
| 497 | struct omap_dss_device *dssdev = to_dss_device(dev); | 503 | struct omap_dss_output *out = dssdev->output; |
| 498 | const char *ret; | 504 | int r; |
| 499 | |||
| 500 | switch (dssdev->phy.venc.type) { | ||
| 501 | case OMAP_DSS_VENC_TYPE_COMPOSITE: | ||
| 502 | ret = "composite"; | ||
| 503 | break; | ||
| 504 | case OMAP_DSS_VENC_TYPE_SVIDEO: | ||
| 505 | ret = "svideo"; | ||
| 506 | break; | ||
| 507 | default: | ||
| 508 | return -EINVAL; | ||
| 509 | } | ||
| 510 | |||
| 511 | return snprintf(buf, PAGE_SIZE, "%s\n", ret); | ||
| 512 | } | ||
| 513 | 505 | ||
| 514 | static ssize_t display_output_type_store(struct device *dev, | 506 | DSSDBG("venc_display_enable\n"); |
| 515 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 516 | { | ||
| 517 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
| 518 | enum omap_dss_venc_type new_type; | ||
| 519 | |||
| 520 | if (sysfs_streq("composite", buf)) | ||
| 521 | new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; | ||
| 522 | else if (sysfs_streq("svideo", buf)) | ||
| 523 | new_type = OMAP_DSS_VENC_TYPE_SVIDEO; | ||
| 524 | else | ||
| 525 | return -EINVAL; | ||
| 526 | 507 | ||
| 527 | mutex_lock(&venc.venc_lock); | 508 | mutex_lock(&venc.venc_lock); |
| 528 | 509 | ||
| 529 | if (dssdev->phy.venc.type != new_type) { | 510 | if (out == NULL || out->manager == NULL) { |
| 530 | dssdev->phy.venc.type = new_type; | 511 | DSSERR("Failed to enable display: no output/manager\n"); |
| 531 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | 512 | r = -ENODEV; |
| 532 | venc_power_off(dssdev); | 513 | goto err0; |
| 533 | venc_power_on(dssdev); | ||
| 534 | } | ||
| 535 | } | 514 | } |
| 536 | 515 | ||
| 537 | mutex_unlock(&venc.venc_lock); | ||
| 538 | |||
| 539 | return size; | ||
| 540 | } | ||
| 541 | |||
| 542 | static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR, | ||
| 543 | display_output_type_show, display_output_type_store); | ||
| 544 | |||
| 545 | /* driver */ | ||
| 546 | static int venc_panel_probe(struct omap_dss_device *dssdev) | ||
| 547 | { | ||
| 548 | dssdev->panel.timings = omap_dss_pal_timings; | ||
| 549 | |||
| 550 | return device_create_file(&dssdev->dev, &dev_attr_output_type); | ||
| 551 | } | ||
| 552 | |||
| 553 | static void venc_panel_remove(struct omap_dss_device *dssdev) | ||
| 554 | { | ||
| 555 | device_remove_file(&dssdev->dev, &dev_attr_output_type); | ||
| 556 | } | ||
| 557 | |||
| 558 | static int venc_panel_enable(struct omap_dss_device *dssdev) | ||
| 559 | { | ||
| 560 | int r = 0; | ||
| 561 | |||
| 562 | DSSDBG("venc_enable_display\n"); | ||
| 563 | |||
| 564 | mutex_lock(&venc.venc_lock); | ||
| 565 | |||
| 566 | r = omap_dss_start_device(dssdev); | 516 | r = omap_dss_start_device(dssdev); |
| 567 | if (r) { | 517 | if (r) { |
| 568 | DSSERR("failed to start device\n"); | 518 | DSSERR("failed to start device\n"); |
| 569 | goto err0; | 519 | goto err0; |
| 570 | } | 520 | } |
| 571 | 521 | ||
| 572 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { | 522 | if (dssdev->platform_enable) |
| 573 | r = -EINVAL; | 523 | dssdev->platform_enable(dssdev); |
| 574 | goto err1; | ||
| 575 | } | ||
| 576 | 524 | ||
| 577 | r = venc_runtime_get(); | ||
| 578 | if (r) | ||
| 579 | goto err1; | ||
| 580 | 525 | ||
| 581 | r = venc_power_on(dssdev); | 526 | r = venc_power_on(dssdev); |
| 582 | if (r) | 527 | if (r) |
| 583 | goto err2; | 528 | goto err1; |
| 584 | 529 | ||
| 585 | venc.wss_data = 0; | 530 | venc.wss_data = 0; |
| 586 | 531 | ||
| 587 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
| 588 | |||
| 589 | mutex_unlock(&venc.venc_lock); | 532 | mutex_unlock(&venc.venc_lock); |
| 533 | |||
| 590 | return 0; | 534 | return 0; |
| 591 | err2: | ||
| 592 | venc_runtime_put(); | ||
| 593 | err1: | 535 | err1: |
| 536 | if (dssdev->platform_disable) | ||
| 537 | dssdev->platform_disable(dssdev); | ||
| 594 | omap_dss_stop_device(dssdev); | 538 | omap_dss_stop_device(dssdev); |
| 595 | err0: | 539 | err0: |
| 596 | mutex_unlock(&venc.venc_lock); | 540 | mutex_unlock(&venc.venc_lock); |
| 597 | |||
| 598 | return r; | 541 | return r; |
| 599 | } | 542 | } |
| 600 | 543 | ||
| 601 | static void venc_panel_disable(struct omap_dss_device *dssdev) | 544 | void omapdss_venc_display_disable(struct omap_dss_device *dssdev) |
| 602 | { | 545 | { |
| 603 | DSSDBG("venc_disable_display\n"); | 546 | DSSDBG("venc_display_disable\n"); |
| 604 | 547 | ||
| 605 | mutex_lock(&venc.venc_lock); | 548 | mutex_lock(&venc.venc_lock); |
| 606 | 549 | ||
| 607 | if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) | ||
| 608 | goto end; | ||
| 609 | |||
| 610 | if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { | ||
| 611 | /* suspended is the same as disabled with venc */ | ||
| 612 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
| 613 | goto end; | ||
| 614 | } | ||
| 615 | |||
| 616 | venc_power_off(dssdev); | 550 | venc_power_off(dssdev); |
| 617 | 551 | ||
| 618 | venc_runtime_put(); | ||
| 619 | |||
| 620 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
| 621 | |||
| 622 | omap_dss_stop_device(dssdev); | 552 | omap_dss_stop_device(dssdev); |
| 623 | end: | ||
| 624 | mutex_unlock(&venc.venc_lock); | ||
| 625 | } | ||
| 626 | 553 | ||
| 627 | static int venc_panel_suspend(struct omap_dss_device *dssdev) | 554 | if (dssdev->platform_disable) |
| 628 | { | 555 | dssdev->platform_disable(dssdev); |
| 629 | venc_panel_disable(dssdev); | ||
| 630 | return 0; | ||
| 631 | } | ||
| 632 | 556 | ||
| 633 | static int venc_panel_resume(struct omap_dss_device *dssdev) | 557 | mutex_unlock(&venc.venc_lock); |
| 634 | { | ||
| 635 | return venc_panel_enable(dssdev); | ||
| 636 | } | 558 | } |
| 637 | 559 | ||
| 638 | static void venc_set_timings(struct omap_dss_device *dssdev, | 560 | void omapdss_venc_set_timings(struct omap_dss_device *dssdev, |
| 639 | struct omap_video_timings *timings) | 561 | struct omap_video_timings *timings) |
| 640 | { | 562 | { |
| 641 | DSSDBG("venc_set_timings\n"); | 563 | DSSDBG("venc_set_timings\n"); |
| 642 | 564 | ||
| 565 | mutex_lock(&venc.venc_lock); | ||
| 566 | |||
| 643 | /* Reset WSS data when the TV standard changes. */ | 567 | /* Reset WSS data when the TV standard changes. */ |
| 644 | if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings))) | 568 | if (memcmp(&venc.timings, timings, sizeof(*timings))) |
| 645 | venc.wss_data = 0; | 569 | venc.wss_data = 0; |
| 646 | 570 | ||
| 647 | dssdev->panel.timings = *timings; | 571 | venc.timings = *timings; |
| 648 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | 572 | |
| 649 | /* turn the venc off and on to get new timings to use */ | 573 | mutex_unlock(&venc.venc_lock); |
| 650 | venc_panel_disable(dssdev); | ||
| 651 | venc_panel_enable(dssdev); | ||
| 652 | } else { | ||
| 653 | dss_mgr_set_timings(dssdev->manager, timings); | ||
| 654 | } | ||
| 655 | } | 574 | } |
| 656 | 575 | ||
| 657 | static int venc_check_timings(struct omap_dss_device *dssdev, | 576 | int omapdss_venc_check_timings(struct omap_dss_device *dssdev, |
| 658 | struct omap_video_timings *timings) | 577 | struct omap_video_timings *timings) |
| 659 | { | 578 | { |
| 660 | DSSDBG("venc_check_timings\n"); | 579 | DSSDBG("venc_check_timings\n"); |
| 661 | 580 | ||
| @@ -668,13 +587,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev, | |||
| 668 | return -EINVAL; | 587 | return -EINVAL; |
| 669 | } | 588 | } |
| 670 | 589 | ||
| 671 | static u32 venc_get_wss(struct omap_dss_device *dssdev) | 590 | u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev) |
| 672 | { | 591 | { |
| 673 | /* Invert due to VENC_L21_WC_CTL:INV=1 */ | 592 | /* Invert due to VENC_L21_WC_CTL:INV=1 */ |
| 674 | return (venc.wss_data >> 8) ^ 0xfffff; | 593 | return (venc.wss_data >> 8) ^ 0xfffff; |
| 675 | } | 594 | } |
| 676 | 595 | ||
| 677 | static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) | 596 | int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss) |
| 678 | { | 597 | { |
| 679 | const struct venc_config *config; | 598 | const struct venc_config *config; |
| 680 | int r; | 599 | int r; |
| @@ -683,7 +602,7 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) | |||
| 683 | 602 | ||
| 684 | mutex_lock(&venc.venc_lock); | 603 | mutex_lock(&venc.venc_lock); |
| 685 | 604 | ||
| 686 | config = venc_timings_to_config(&dssdev->panel.timings); | 605 | config = venc_timings_to_config(&venc.timings); |
| 687 | 606 | ||
| 688 | /* Invert due to VENC_L21_WC_CTL:INV=1 */ | 607 | /* Invert due to VENC_L21_WC_CTL:INV=1 */ |
| 689 | venc.wss_data = (wss ^ 0xfffff) << 8; | 608 | venc.wss_data = (wss ^ 0xfffff) << 8; |
| @@ -703,30 +622,25 @@ err: | |||
| 703 | return r; | 622 | return r; |
| 704 | } | 623 | } |
| 705 | 624 | ||
| 706 | static struct omap_dss_driver venc_driver = { | 625 | void omapdss_venc_set_type(struct omap_dss_device *dssdev, |
| 707 | .probe = venc_panel_probe, | 626 | enum omap_dss_venc_type type) |
| 708 | .remove = venc_panel_remove, | 627 | { |
| 628 | mutex_lock(&venc.venc_lock); | ||
| 709 | 629 | ||
| 710 | .enable = venc_panel_enable, | 630 | venc.type = type; |
| 711 | .disable = venc_panel_disable, | ||
| 712 | .suspend = venc_panel_suspend, | ||
| 713 | .resume = venc_panel_resume, | ||
| 714 | 631 | ||
| 715 | .get_resolution = omapdss_default_get_resolution, | 632 | mutex_unlock(&venc.venc_lock); |
| 716 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, | 633 | } |
| 717 | 634 | ||
| 718 | .set_timings = venc_set_timings, | 635 | void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, |
| 719 | .check_timings = venc_check_timings, | 636 | bool invert_polarity) |
| 637 | { | ||
| 638 | mutex_lock(&venc.venc_lock); | ||
| 720 | 639 | ||
| 721 | .get_wss = venc_get_wss, | 640 | venc.invert_polarity = invert_polarity; |
| 722 | .set_wss = venc_set_wss, | ||
| 723 | 641 | ||
| 724 | .driver = { | 642 | mutex_unlock(&venc.venc_lock); |
| 725 | .name = "venc", | 643 | } |
| 726 | .owner = THIS_MODULE, | ||
| 727 | }, | ||
| 728 | }; | ||
| 729 | /* driver end */ | ||
| 730 | 644 | ||
| 731 | static int __init venc_init_display(struct omap_dss_device *dssdev) | 645 | static int __init venc_init_display(struct omap_dss_device *dssdev) |
| 732 | { | 646 | { |
| @@ -752,11 +666,6 @@ static void venc_dump_regs(struct seq_file *s) | |||
| 752 | { | 666 | { |
| 753 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) | 667 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) |
| 754 | 668 | ||
| 755 | if (cpu_is_omap44xx()) { | ||
| 756 | seq_printf(s, "VENC currently disabled on OMAP44xx\n"); | ||
| 757 | return; | ||
| 758 | } | ||
| 759 | |||
| 760 | if (venc_runtime_get()) | 669 | if (venc_runtime_get()) |
| 761 | return; | 670 | return; |
| 762 | 671 | ||
| @@ -832,10 +741,14 @@ static void venc_put_clocks(void) | |||
| 832 | clk_put(venc.tv_dac_clk); | 741 | clk_put(venc.tv_dac_clk); |
| 833 | } | 742 | } |
| 834 | 743 | ||
| 835 | static void __init venc_probe_pdata(struct platform_device *pdev) | 744 | static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev) |
| 836 | { | 745 | { |
| 837 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | 746 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
| 838 | int r, i; | 747 | const char *def_disp_name = dss_get_default_display_name(); |
| 748 | struct omap_dss_device *def_dssdev; | ||
| 749 | int i; | ||
| 750 | |||
| 751 | def_dssdev = NULL; | ||
| 839 | 752 | ||
| 840 | for (i = 0; i < pdata->num_devices; ++i) { | 753 | for (i = 0; i < pdata->num_devices; ++i) { |
| 841 | struct omap_dss_device *dssdev = pdata->devices[i]; | 754 | struct omap_dss_device *dssdev = pdata->devices[i]; |
| @@ -843,17 +756,69 @@ static void __init venc_probe_pdata(struct platform_device *pdev) | |||
| 843 | if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) | 756 | if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) |
| 844 | continue; | 757 | continue; |
| 845 | 758 | ||
| 846 | r = venc_init_display(dssdev); | 759 | if (def_dssdev == NULL) |
| 847 | if (r) { | 760 | def_dssdev = dssdev; |
| 848 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 761 | |
| 849 | continue; | 762 | if (def_disp_name != NULL && |
| 763 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
| 764 | def_dssdev = dssdev; | ||
| 765 | break; | ||
| 850 | } | 766 | } |
| 767 | } | ||
| 768 | |||
| 769 | return def_dssdev; | ||
| 770 | } | ||
| 771 | |||
| 772 | static void __init venc_probe_pdata(struct platform_device *vencdev) | ||
| 773 | { | ||
| 774 | struct omap_dss_device *plat_dssdev; | ||
| 775 | struct omap_dss_device *dssdev; | ||
| 776 | int r; | ||
| 777 | |||
| 778 | plat_dssdev = venc_find_dssdev(vencdev); | ||
| 851 | 779 | ||
| 852 | r = omap_dss_register_device(dssdev, &pdev->dev, i); | 780 | if (!plat_dssdev) |
| 853 | if (r) | 781 | return; |
| 854 | DSSERR("device %s register failed: %d\n", | 782 | |
| 855 | dssdev->name, r); | 783 | dssdev = dss_alloc_and_init_device(&vencdev->dev); |
| 784 | if (!dssdev) | ||
| 785 | return; | ||
| 786 | |||
| 787 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
| 788 | |||
| 789 | dssdev->channel = OMAP_DSS_CHANNEL_DIGIT; | ||
| 790 | |||
| 791 | r = venc_init_display(dssdev); | ||
| 792 | if (r) { | ||
| 793 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
| 794 | dss_put_device(dssdev); | ||
| 795 | return; | ||
| 856 | } | 796 | } |
| 797 | |||
| 798 | r = dss_add_device(dssdev); | ||
| 799 | if (r) { | ||
| 800 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
| 801 | dss_put_device(dssdev); | ||
| 802 | return; | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | static void __init venc_init_output(struct platform_device *pdev) | ||
| 807 | { | ||
| 808 | struct omap_dss_output *out = &venc.output; | ||
| 809 | |||
| 810 | out->pdev = pdev; | ||
| 811 | out->id = OMAP_DSS_OUTPUT_VENC; | ||
| 812 | out->type = OMAP_DISPLAY_TYPE_VENC; | ||
| 813 | |||
| 814 | dss_register_output(out); | ||
| 815 | } | ||
| 816 | |||
| 817 | static void __exit venc_uninit_output(struct platform_device *pdev) | ||
| 818 | { | ||
| 819 | struct omap_dss_output *out = &venc.output; | ||
| 820 | |||
| 821 | dss_unregister_output(out); | ||
| 857 | } | 822 | } |
| 858 | 823 | ||
| 859 | /* VENC HW IP initialisation */ | 824 | /* VENC HW IP initialisation */ |
| @@ -897,17 +862,19 @@ static int __init omap_venchw_probe(struct platform_device *pdev) | |||
| 897 | 862 | ||
| 898 | venc_runtime_put(); | 863 | venc_runtime_put(); |
| 899 | 864 | ||
| 900 | r = omap_dss_register_driver(&venc_driver); | 865 | r = venc_panel_init(); |
| 901 | if (r) | 866 | if (r) |
| 902 | goto err_reg_panel_driver; | 867 | goto err_panel_init; |
| 903 | 868 | ||
| 904 | dss_debugfs_create_file("venc", venc_dump_regs); | 869 | dss_debugfs_create_file("venc", venc_dump_regs); |
| 905 | 870 | ||
| 871 | venc_init_output(pdev); | ||
| 872 | |||
| 906 | venc_probe_pdata(pdev); | 873 | venc_probe_pdata(pdev); |
| 907 | 874 | ||
| 908 | return 0; | 875 | return 0; |
| 909 | 876 | ||
| 910 | err_reg_panel_driver: | 877 | err_panel_init: |
| 911 | err_runtime_get: | 878 | err_runtime_get: |
| 912 | pm_runtime_disable(&pdev->dev); | 879 | pm_runtime_disable(&pdev->dev); |
| 913 | venc_put_clocks(); | 880 | venc_put_clocks(); |
| @@ -916,14 +883,16 @@ err_runtime_get: | |||
| 916 | 883 | ||
| 917 | static int __exit omap_venchw_remove(struct platform_device *pdev) | 884 | static int __exit omap_venchw_remove(struct platform_device *pdev) |
| 918 | { | 885 | { |
| 919 | omap_dss_unregister_child_devices(&pdev->dev); | 886 | dss_unregister_child_devices(&pdev->dev); |
| 920 | 887 | ||
| 921 | if (venc.vdda_dac_reg != NULL) { | 888 | if (venc.vdda_dac_reg != NULL) { |
| 922 | regulator_put(venc.vdda_dac_reg); | 889 | regulator_put(venc.vdda_dac_reg); |
| 923 | venc.vdda_dac_reg = NULL; | 890 | venc.vdda_dac_reg = NULL; |
| 924 | } | 891 | } |
| 925 | 892 | ||
| 926 | omap_dss_unregister_driver(&venc_driver); | 893 | venc_panel_exit(); |
| 894 | |||
| 895 | venc_uninit_output(pdev); | ||
| 927 | 896 | ||
| 928 | pm_runtime_disable(&pdev->dev); | 897 | pm_runtime_disable(&pdev->dev); |
| 929 | venc_put_clocks(); | 898 | venc_put_clocks(); |
| @@ -971,16 +940,10 @@ static struct platform_driver omap_venchw_driver = { | |||
| 971 | 940 | ||
| 972 | int __init venc_init_platform_driver(void) | 941 | int __init venc_init_platform_driver(void) |
| 973 | { | 942 | { |
| 974 | if (cpu_is_omap44xx()) | ||
| 975 | return 0; | ||
| 976 | |||
| 977 | return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe); | 943 | return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe); |
| 978 | } | 944 | } |
| 979 | 945 | ||
| 980 | void __exit venc_uninit_platform_driver(void) | 946 | void __exit venc_uninit_platform_driver(void) |
| 981 | { | 947 | { |
| 982 | if (cpu_is_omap44xx()) | ||
| 983 | return; | ||
| 984 | |||
| 985 | platform_driver_unregister(&omap_venchw_driver); | 948 | platform_driver_unregister(&omap_venchw_driver); |
| 986 | } | 949 | } |
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c new file mode 100644 index 000000000000..d55b8784ecfd --- /dev/null +++ b/drivers/video/omap2/dss/venc_panel.c | |||
| @@ -0,0 +1,251 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Nokia Corporation | ||
| 3 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
| 4 | * | ||
| 5 | * VENC panel driver | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 14 | * more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along with | ||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/mutex.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | |||
| 26 | #include <video/omapdss.h> | ||
| 27 | |||
| 28 | #include "dss.h" | ||
| 29 | |||
| 30 | static struct { | ||
| 31 | struct mutex lock; | ||
| 32 | } venc_panel; | ||
| 33 | |||
| 34 | static ssize_t display_output_type_show(struct device *dev, | ||
| 35 | struct device_attribute *attr, char *buf) | ||
| 36 | { | ||
| 37 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
| 38 | const char *ret; | ||
| 39 | |||
| 40 | switch (dssdev->phy.venc.type) { | ||
| 41 | case OMAP_DSS_VENC_TYPE_COMPOSITE: | ||
| 42 | ret = "composite"; | ||
| 43 | break; | ||
| 44 | case OMAP_DSS_VENC_TYPE_SVIDEO: | ||
| 45 | ret = "svideo"; | ||
| 46 | break; | ||
| 47 | default: | ||
| 48 | return -EINVAL; | ||
| 49 | } | ||
| 50 | |||
| 51 | return snprintf(buf, PAGE_SIZE, "%s\n", ret); | ||
| 52 | } | ||
| 53 | |||
| 54 | static ssize_t display_output_type_store(struct device *dev, | ||
| 55 | struct device_attribute *attr, const char *buf, size_t size) | ||
| 56 | { | ||
| 57 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
| 58 | enum omap_dss_venc_type new_type; | ||
| 59 | |||
| 60 | if (sysfs_streq("composite", buf)) | ||
| 61 | new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; | ||
| 62 | else if (sysfs_streq("svideo", buf)) | ||
| 63 | new_type = OMAP_DSS_VENC_TYPE_SVIDEO; | ||
| 64 | else | ||
| 65 | return -EINVAL; | ||
| 66 | |||
| 67 | mutex_lock(&venc_panel.lock); | ||
| 68 | |||
| 69 | if (dssdev->phy.venc.type != new_type) { | ||
| 70 | dssdev->phy.venc.type = new_type; | ||
| 71 | omapdss_venc_set_type(dssdev, new_type); | ||
| 72 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | ||
| 73 | omapdss_venc_display_disable(dssdev); | ||
| 74 | omapdss_venc_display_enable(dssdev); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | mutex_unlock(&venc_panel.lock); | ||
| 79 | |||
| 80 | return size; | ||
| 81 | } | ||
| 82 | |||
| 83 | static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR, | ||
| 84 | display_output_type_show, display_output_type_store); | ||
| 85 | |||
| 86 | static int venc_panel_probe(struct omap_dss_device *dssdev) | ||
| 87 | { | ||
| 88 | /* set default timings to PAL */ | ||
| 89 | const struct omap_video_timings default_timings = { | ||
| 90 | .x_res = 720, | ||
| 91 | .y_res = 574, | ||
| 92 | .pixel_clock = 13500, | ||
| 93 | .hsw = 64, | ||
| 94 | .hfp = 12, | ||
| 95 | .hbp = 68, | ||
| 96 | .vsw = 5, | ||
| 97 | .vfp = 5, | ||
| 98 | .vbp = 41, | ||
| 99 | |||
| 100 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
| 101 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
| 102 | |||
| 103 | .interlace = true, | ||
| 104 | }; | ||
| 105 | |||
| 106 | mutex_init(&venc_panel.lock); | ||
| 107 | |||
| 108 | dssdev->panel.timings = default_timings; | ||
| 109 | |||
| 110 | return device_create_file(&dssdev->dev, &dev_attr_output_type); | ||
| 111 | } | ||
| 112 | |||
| 113 | static void venc_panel_remove(struct omap_dss_device *dssdev) | ||
| 114 | { | ||
| 115 | device_remove_file(&dssdev->dev, &dev_attr_output_type); | ||
| 116 | } | ||
| 117 | |||
| 118 | static int venc_panel_enable(struct omap_dss_device *dssdev) | ||
| 119 | { | ||
| 120 | int r; | ||
| 121 | |||
| 122 | dev_dbg(&dssdev->dev, "venc_panel_enable\n"); | ||
| 123 | |||
| 124 | mutex_lock(&venc_panel.lock); | ||
| 125 | |||
| 126 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
| 127 | r = -EINVAL; | ||
| 128 | goto err; | ||
| 129 | } | ||
| 130 | |||
| 131 | omapdss_venc_set_timings(dssdev, &dssdev->panel.timings); | ||
| 132 | omapdss_venc_set_type(dssdev, dssdev->phy.venc.type); | ||
| 133 | omapdss_venc_invert_vid_out_polarity(dssdev, | ||
| 134 | dssdev->phy.venc.invert_polarity); | ||
| 135 | |||
| 136 | r = omapdss_venc_display_enable(dssdev); | ||
| 137 | if (r) | ||
| 138 | goto err; | ||
| 139 | |||
| 140 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
| 141 | |||
| 142 | mutex_unlock(&venc_panel.lock); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | err: | ||
| 146 | mutex_unlock(&venc_panel.lock); | ||
| 147 | |||
| 148 | return r; | ||
| 149 | } | ||
| 150 | |||
| 151 | static void venc_panel_disable(struct omap_dss_device *dssdev) | ||
| 152 | { | ||
| 153 | dev_dbg(&dssdev->dev, "venc_panel_disable\n"); | ||
| 154 | |||
| 155 | mutex_lock(&venc_panel.lock); | ||
| 156 | |||
| 157 | if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) | ||
| 158 | goto end; | ||
| 159 | |||
| 160 | if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { | ||
| 161 | /* suspended is the same as disabled with venc */ | ||
| 162 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
| 163 | goto end; | ||
| 164 | } | ||
| 165 | |||
| 166 | omapdss_venc_display_disable(dssdev); | ||
| 167 | |||
| 168 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
| 169 | end: | ||
| 170 | mutex_unlock(&venc_panel.lock); | ||
| 171 | } | ||
| 172 | |||
| 173 | static int venc_panel_suspend(struct omap_dss_device *dssdev) | ||
| 174 | { | ||
| 175 | venc_panel_disable(dssdev); | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | |||
| 179 | static int venc_panel_resume(struct omap_dss_device *dssdev) | ||
| 180 | { | ||
| 181 | return venc_panel_enable(dssdev); | ||
| 182 | } | ||
| 183 | |||
| 184 | static void venc_panel_set_timings(struct omap_dss_device *dssdev, | ||
| 185 | struct omap_video_timings *timings) | ||
| 186 | { | ||
| 187 | dev_dbg(&dssdev->dev, "venc_panel_set_timings\n"); | ||
| 188 | |||
| 189 | mutex_lock(&venc_panel.lock); | ||
| 190 | |||
| 191 | omapdss_venc_set_timings(dssdev, timings); | ||
| 192 | dssdev->panel.timings = *timings; | ||
| 193 | |||
| 194 | mutex_unlock(&venc_panel.lock); | ||
| 195 | } | ||
| 196 | |||
| 197 | static int venc_panel_check_timings(struct omap_dss_device *dssdev, | ||
| 198 | struct omap_video_timings *timings) | ||
| 199 | { | ||
| 200 | dev_dbg(&dssdev->dev, "venc_panel_check_timings\n"); | ||
| 201 | |||
| 202 | return omapdss_venc_check_timings(dssdev, timings); | ||
| 203 | } | ||
| 204 | |||
| 205 | static u32 venc_panel_get_wss(struct omap_dss_device *dssdev) | ||
| 206 | { | ||
| 207 | dev_dbg(&dssdev->dev, "venc_panel_get_wss\n"); | ||
| 208 | |||
| 209 | return omapdss_venc_get_wss(dssdev); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss) | ||
| 213 | { | ||
| 214 | dev_dbg(&dssdev->dev, "venc_panel_set_wss\n"); | ||
| 215 | |||
| 216 | return omapdss_venc_set_wss(dssdev, wss); | ||
| 217 | } | ||
| 218 | |||
| 219 | static struct omap_dss_driver venc_driver = { | ||
| 220 | .probe = venc_panel_probe, | ||
| 221 | .remove = venc_panel_remove, | ||
| 222 | |||
| 223 | .enable = venc_panel_enable, | ||
| 224 | .disable = venc_panel_disable, | ||
| 225 | .suspend = venc_panel_suspend, | ||
| 226 | .resume = venc_panel_resume, | ||
| 227 | |||
| 228 | .get_resolution = omapdss_default_get_resolution, | ||
| 229 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, | ||
| 230 | |||
| 231 | .set_timings = venc_panel_set_timings, | ||
| 232 | .check_timings = venc_panel_check_timings, | ||
| 233 | |||
| 234 | .get_wss = venc_panel_get_wss, | ||
| 235 | .set_wss = venc_panel_set_wss, | ||
| 236 | |||
| 237 | .driver = { | ||
| 238 | .name = "venc", | ||
| 239 | .owner = THIS_MODULE, | ||
| 240 | }, | ||
| 241 | }; | ||
| 242 | |||
| 243 | int venc_panel_init(void) | ||
| 244 | { | ||
| 245 | return omap_dss_register_driver(&venc_driver); | ||
| 246 | } | ||
| 247 | |||
| 248 | void venc_panel_exit(void) | ||
| 249 | { | ||
| 250 | omap_dss_unregister_driver(&venc_driver); | ||
| 251 | } | ||
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index c6cf372d22c5..606b89f12351 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c | |||
| @@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) | |||
| 599 | struct omapfb_info *ofbi = FB2OFB(fbi); | 599 | struct omapfb_info *ofbi = FB2OFB(fbi); |
| 600 | struct omapfb2_device *fbdev = ofbi->fbdev; | 600 | struct omapfb2_device *fbdev = ofbi->fbdev; |
| 601 | struct omap_dss_device *display = fb2display(fbi); | 601 | struct omap_dss_device *display = fb2display(fbi); |
| 602 | struct omap_overlay_manager *mgr; | ||
| 602 | 603 | ||
| 603 | union { | 604 | union { |
| 604 | struct omapfb_update_window_old uwnd_o; | 605 | struct omapfb_update_window_old uwnd_o; |
| @@ -786,12 +787,14 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) | |||
| 786 | 787 | ||
| 787 | case OMAPFB_WAITFORVSYNC: | 788 | case OMAPFB_WAITFORVSYNC: |
| 788 | DBG("ioctl WAITFORVSYNC\n"); | 789 | DBG("ioctl WAITFORVSYNC\n"); |
| 789 | if (!display) { | 790 | if (!display && !display->output && !display->output->manager) { |
| 790 | r = -EINVAL; | 791 | r = -EINVAL; |
| 791 | break; | 792 | break; |
| 792 | } | 793 | } |
| 793 | 794 | ||
| 794 | r = display->manager->wait_for_vsync(display->manager); | 795 | mgr = display->output->manager; |
| 796 | |||
| 797 | r = mgr->wait_for_vsync(mgr); | ||
| 795 | break; | 798 | break; |
| 796 | 799 | ||
| 797 | case OMAPFB_WAITFORGO: | 800 | case OMAPFB_WAITFORGO: |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index fc671d3d8004..b103793516db 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
| @@ -1592,6 +1592,20 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev) | |||
| 1592 | return 0; | 1592 | return 0; |
| 1593 | } | 1593 | } |
| 1594 | 1594 | ||
| 1595 | static void omapfb_clear_fb(struct fb_info *fbi) | ||
| 1596 | { | ||
| 1597 | const struct fb_fillrect rect = { | ||
| 1598 | .dx = 0, | ||
| 1599 | .dy = 0, | ||
| 1600 | .width = fbi->var.xres_virtual, | ||
| 1601 | .height = fbi->var.yres_virtual, | ||
| 1602 | .color = 0, | ||
| 1603 | .rop = ROP_COPY, | ||
| 1604 | }; | ||
| 1605 | |||
| 1606 | cfb_fillrect(fbi, &rect); | ||
| 1607 | } | ||
| 1608 | |||
| 1595 | int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) | 1609 | int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) |
| 1596 | { | 1610 | { |
| 1597 | struct omapfb_info *ofbi = FB2OFB(fbi); | 1611 | struct omapfb_info *ofbi = FB2OFB(fbi); |
| @@ -1661,6 +1675,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) | |||
| 1661 | goto err; | 1675 | goto err; |
| 1662 | } | 1676 | } |
| 1663 | 1677 | ||
| 1678 | omapfb_clear_fb(fbi); | ||
| 1679 | |||
| 1664 | return 0; | 1680 | return 0; |
| 1665 | err: | 1681 | err: |
| 1666 | omapfb_free_fbmem(fbi); | 1682 | omapfb_free_fbmem(fbi); |
| @@ -1945,6 +1961,16 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) | |||
| 1945 | } | 1961 | } |
| 1946 | } | 1962 | } |
| 1947 | 1963 | ||
| 1964 | for (i = 0; i < fbdev->num_fbs; i++) { | ||
| 1965 | struct fb_info *fbi = fbdev->fbs[i]; | ||
| 1966 | struct omapfb_info *ofbi = FB2OFB(fbi); | ||
| 1967 | |||
| 1968 | if (ofbi->region->size == 0) | ||
| 1969 | continue; | ||
| 1970 | |||
| 1971 | omapfb_clear_fb(fbi); | ||
| 1972 | } | ||
| 1973 | |||
| 1948 | DBG("fb_infos initialized\n"); | 1974 | DBG("fb_infos initialized\n"); |
| 1949 | 1975 | ||
| 1950 | for (i = 0; i < fbdev->num_fbs; i++) { | 1976 | for (i = 0; i < fbdev->num_fbs; i++) { |
| @@ -2353,6 +2379,7 @@ static int __init omapfb_probe(struct platform_device *pdev) | |||
| 2353 | struct omap_overlay *ovl; | 2379 | struct omap_overlay *ovl; |
| 2354 | struct omap_dss_device *def_display; | 2380 | struct omap_dss_device *def_display; |
| 2355 | struct omap_dss_device *dssdev; | 2381 | struct omap_dss_device *dssdev; |
| 2382 | struct omap_dss_device *ovl_device; | ||
| 2356 | 2383 | ||
| 2357 | DBG("omapfb_probe\n"); | 2384 | DBG("omapfb_probe\n"); |
| 2358 | 2385 | ||
| @@ -2426,8 +2453,9 @@ static int __init omapfb_probe(struct platform_device *pdev) | |||
| 2426 | /* gfx overlay should be the default one. find a display | 2453 | /* gfx overlay should be the default one. find a display |
| 2427 | * connected to that, and use it as default display */ | 2454 | * connected to that, and use it as default display */ |
| 2428 | ovl = omap_dss_get_overlay(0); | 2455 | ovl = omap_dss_get_overlay(0); |
| 2429 | if (ovl->manager && ovl->manager->device) { | 2456 | ovl_device = ovl->get_device(ovl); |
| 2430 | def_display = ovl->manager->device; | 2457 | if (ovl_device) { |
| 2458 | def_display = ovl_device; | ||
| 2431 | } else { | 2459 | } else { |
| 2432 | dev_warn(&pdev->dev, "cannot find default display\n"); | 2460 | dev_warn(&pdev->dev, "cannot find default display\n"); |
| 2433 | def_display = NULL; | 2461 | def_display = NULL; |
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index 30361a09aecd..5ced9b334d35 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h | |||
| @@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi) | |||
| 148 | 148 | ||
| 149 | /* XXX: returns the display connected to first attached overlay */ | 149 | /* XXX: returns the display connected to first attached overlay */ |
| 150 | for (i = 0; i < ofbi->num_overlays; i++) { | 150 | for (i = 0; i < ofbi->num_overlays; i++) { |
| 151 | if (ofbi->overlays[i]->manager) | 151 | struct omap_overlay *ovl = ofbi->overlays[i]; |
| 152 | return ofbi->overlays[i]->manager->device; | 152 | |
| 153 | return ovl->get_device(ovl); | ||
| 153 | } | 154 | } |
| 154 | 155 | ||
| 155 | return NULL; | 156 | return NULL; |
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c index 87e421e25afe..f2b15c4a75bc 100644 --- a/drivers/video/omap2/vram.c +++ b/drivers/video/omap2/vram.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <asm/setup.h> | 34 | #include <asm/setup.h> |
| 35 | 35 | ||
| 36 | #include <plat/vram.h> | 36 | #include <plat/vram.h> |
| 37 | #include <plat/dma.h> | ||
| 38 | 37 | ||
| 39 | #ifdef DEBUG | 38 | #ifdef DEBUG |
| 40 | #define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__) | 39 | #define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__) |
| @@ -250,59 +249,6 @@ int omap_vram_reserve(unsigned long paddr, size_t size) | |||
| 250 | } | 249 | } |
| 251 | EXPORT_SYMBOL(omap_vram_reserve); | 250 | EXPORT_SYMBOL(omap_vram_reserve); |
| 252 | 251 | ||
| 253 | static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data) | ||
| 254 | { | ||
| 255 | struct completion *compl = data; | ||
| 256 | complete(compl); | ||
| 257 | } | ||
| 258 | |||
| 259 | static int _omap_vram_clear(u32 paddr, unsigned pages) | ||
| 260 | { | ||
| 261 | struct completion compl; | ||
| 262 | unsigned elem_count; | ||
| 263 | unsigned frame_count; | ||
| 264 | int r; | ||
| 265 | int lch; | ||
| 266 | |||
| 267 | init_completion(&compl); | ||
| 268 | |||
| 269 | r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA", | ||
| 270 | _omap_vram_dma_cb, | ||
| 271 | &compl, &lch); | ||
| 272 | if (r) { | ||
| 273 | pr_err("VRAM: request_dma failed for memory clear\n"); | ||
| 274 | return -EBUSY; | ||
| 275 | } | ||
| 276 | |||
| 277 | elem_count = pages * PAGE_SIZE / 4; | ||
| 278 | frame_count = 1; | ||
| 279 | |||
| 280 | omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32, | ||
| 281 | elem_count, frame_count, | ||
| 282 | OMAP_DMA_SYNC_ELEMENT, | ||
| 283 | 0, 0); | ||
| 284 | |||
| 285 | omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC, | ||
| 286 | paddr, 0, 0); | ||
| 287 | |||
| 288 | omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000); | ||
| 289 | |||
| 290 | omap_start_dma(lch); | ||
| 291 | |||
| 292 | if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) { | ||
| 293 | omap_stop_dma(lch); | ||
| 294 | pr_err("VRAM: dma timeout while clearing memory\n"); | ||
| 295 | r = -EIO; | ||
| 296 | goto err; | ||
| 297 | } | ||
| 298 | |||
| 299 | r = 0; | ||
| 300 | err: | ||
| 301 | omap_free_dma(lch); | ||
| 302 | |||
| 303 | return r; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int _omap_vram_alloc(unsigned pages, unsigned long *paddr) | 252 | static int _omap_vram_alloc(unsigned pages, unsigned long *paddr) |
| 307 | { | 253 | { |
| 308 | struct vram_region *rm; | 254 | struct vram_region *rm; |
| @@ -337,8 +283,6 @@ found: | |||
| 337 | 283 | ||
| 338 | *paddr = start; | 284 | *paddr = start; |
| 339 | 285 | ||
| 340 | _omap_vram_clear(start, pages); | ||
| 341 | |||
| 342 | return 0; | 286 | return 0; |
| 343 | } | 287 | } |
| 344 | 288 | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 3fe82d0e8caa..5b06d31ab6a9 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
| @@ -166,18 +166,17 @@ static long booke_wdt_ioctl(struct file *file, | |||
| 166 | 166 | ||
| 167 | switch (cmd) { | 167 | switch (cmd) { |
| 168 | case WDIOC_GETSUPPORT: | 168 | case WDIOC_GETSUPPORT: |
| 169 | if (copy_to_user((void *)arg, &ident, sizeof(ident))) | 169 | return copy_to_user(p, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 170 | return -EFAULT; | ||
| 171 | case WDIOC_GETSTATUS: | 170 | case WDIOC_GETSTATUS: |
| 172 | return put_user(0, p); | 171 | return put_user(0, p); |
| 173 | case WDIOC_GETBOOTSTATUS: | 172 | case WDIOC_GETBOOTSTATUS: |
| 174 | /* XXX: something is clearing TSR */ | 173 | /* XXX: something is clearing TSR */ |
| 175 | tmp = mfspr(SPRN_TSR) & TSR_WRS(3); | 174 | tmp = mfspr(SPRN_TSR) & TSR_WRS(3); |
| 176 | /* returns CARDRESET if last reset was caused by the WDT */ | 175 | /* returns CARDRESET if last reset was caused by the WDT */ |
| 177 | return (tmp ? WDIOF_CARDRESET : 0); | 176 | return put_user((tmp ? WDIOF_CARDRESET : 0), p); |
| 178 | case WDIOC_SETOPTIONS: | 177 | case WDIOC_SETOPTIONS: |
| 179 | if (get_user(tmp, p)) | 178 | if (get_user(tmp, p)) |
| 180 | return -EINVAL; | 179 | return -EFAULT; |
| 181 | if (tmp == WDIOS_ENABLECARD) { | 180 | if (tmp == WDIOS_ENABLECARD) { |
| 182 | booke_wdt_ping(); | 181 | booke_wdt_ping(); |
| 183 | break; | 182 | break; |
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index 3f75129eb0a9..f7abbaeebcaf 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
| 24 | #include <linux/delay.h> | ||
| 25 | 24 | ||
| 26 | #include <linux/mfd/da9052/reg.h> | 25 | #include <linux/mfd/da9052/reg.h> |
| 27 | #include <linux/mfd/da9052/da9052.h> | 26 | #include <linux/mfd/da9052/da9052.h> |
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index d4c50d63acbc..97ca359ae2bd 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c | |||
| @@ -101,19 +101,6 @@ static int platform_pci_resume(struct pci_dev *pdev) | |||
| 101 | return 0; | 101 | return 0; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | static void __devinit prepare_shared_info(void) | ||
| 105 | { | ||
| 106 | #ifdef CONFIG_KEXEC | ||
| 107 | unsigned long addr; | ||
| 108 | struct shared_info *hvm_shared_info; | ||
| 109 | |||
| 110 | addr = alloc_xen_mmio(PAGE_SIZE); | ||
| 111 | hvm_shared_info = ioremap(addr, PAGE_SIZE); | ||
| 112 | memset(hvm_shared_info, 0, PAGE_SIZE); | ||
| 113 | xen_hvm_prepare_kexec(hvm_shared_info, addr >> PAGE_SHIFT); | ||
| 114 | #endif | ||
| 115 | } | ||
| 116 | |||
| 117 | static int __devinit platform_pci_init(struct pci_dev *pdev, | 104 | static int __devinit platform_pci_init(struct pci_dev *pdev, |
| 118 | const struct pci_device_id *ent) | 105 | const struct pci_device_id *ent) |
| 119 | { | 106 | { |
| @@ -151,8 +138,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, | |||
| 151 | platform_mmio = mmio_addr; | 138 | platform_mmio = mmio_addr; |
| 152 | platform_mmiolen = mmio_len; | 139 | platform_mmiolen = mmio_len; |
| 153 | 140 | ||
| 154 | prepare_shared_info(); | ||
| 155 | |||
| 156 | if (!xen_have_vector_callback) { | 141 | if (!xen_have_vector_callback) { |
| 157 | ret = xen_allocate_irq(pdev); | 142 | ret = xen_allocate_irq(pdev); |
| 158 | if (ret) { | 143 | if (ret) { |
| @@ -73,7 +73,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) | |||
| 73 | { | 73 | { |
| 74 | unsigned int sz = sizeof(struct bio) + extra_size; | 74 | unsigned int sz = sizeof(struct bio) + extra_size; |
| 75 | struct kmem_cache *slab = NULL; | 75 | struct kmem_cache *slab = NULL; |
| 76 | struct bio_slab *bslab; | 76 | struct bio_slab *bslab, *new_bio_slabs; |
| 77 | unsigned int i, entry = -1; | 77 | unsigned int i, entry = -1; |
| 78 | 78 | ||
| 79 | mutex_lock(&bio_slab_lock); | 79 | mutex_lock(&bio_slab_lock); |
| @@ -97,11 +97,12 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) | |||
| 97 | 97 | ||
| 98 | if (bio_slab_nr == bio_slab_max && entry == -1) { | 98 | if (bio_slab_nr == bio_slab_max && entry == -1) { |
| 99 | bio_slab_max <<= 1; | 99 | bio_slab_max <<= 1; |
| 100 | bio_slabs = krealloc(bio_slabs, | 100 | new_bio_slabs = krealloc(bio_slabs, |
| 101 | bio_slab_max * sizeof(struct bio_slab), | 101 | bio_slab_max * sizeof(struct bio_slab), |
| 102 | GFP_KERNEL); | 102 | GFP_KERNEL); |
| 103 | if (!bio_slabs) | 103 | if (!new_bio_slabs) |
| 104 | goto out_unlock; | 104 | goto out_unlock; |
| 105 | bio_slabs = new_bio_slabs; | ||
| 105 | } | 106 | } |
| 106 | if (entry == -1) | 107 | if (entry == -1) |
| 107 | entry = bio_slab_nr++; | 108 | entry = bio_slab_nr++; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 1e519195d45b..38e721b35d45 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -1578,10 +1578,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 1578 | unsigned long nr_segs, loff_t pos) | 1578 | unsigned long nr_segs, loff_t pos) |
| 1579 | { | 1579 | { |
| 1580 | struct file *file = iocb->ki_filp; | 1580 | struct file *file = iocb->ki_filp; |
| 1581 | struct blk_plug plug; | ||
| 1581 | ssize_t ret; | 1582 | ssize_t ret; |
| 1582 | 1583 | ||
| 1583 | BUG_ON(iocb->ki_pos != pos); | 1584 | BUG_ON(iocb->ki_pos != pos); |
| 1584 | 1585 | ||
| 1586 | blk_start_plug(&plug); | ||
| 1585 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); | 1587 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
| 1586 | if (ret > 0 || ret == -EIOCBQUEUED) { | 1588 | if (ret > 0 || ret == -EIOCBQUEUED) { |
| 1587 | ssize_t err; | 1589 | ssize_t err; |
| @@ -1590,6 +1592,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 1590 | if (err < 0 && ret > 0) | 1592 | if (err < 0 && ret > 0) |
| 1591 | ret = err; | 1593 | ret = err; |
| 1592 | } | 1594 | } |
| 1595 | blk_finish_plug(&plug); | ||
| 1593 | return ret; | 1596 | return ret; |
| 1594 | } | 1597 | } |
| 1595 | EXPORT_SYMBOL_GPL(blkdev_aio_write); | 1598 | EXPORT_SYMBOL_GPL(blkdev_aio_write); |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index a256f3b2a845..ff6475f409d6 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
| @@ -1438,10 +1438,10 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, | |||
| 1438 | ret = extent_from_logical(fs_info, logical, path, | 1438 | ret = extent_from_logical(fs_info, logical, path, |
| 1439 | &found_key); | 1439 | &found_key); |
| 1440 | btrfs_release_path(path); | 1440 | btrfs_release_path(path); |
| 1441 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) | ||
| 1442 | ret = -EINVAL; | ||
| 1443 | if (ret < 0) | 1441 | if (ret < 0) |
| 1444 | return ret; | 1442 | return ret; |
| 1443 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) | ||
| 1444 | return -EINVAL; | ||
| 1445 | 1445 | ||
| 1446 | extent_item_pos = logical - found_key.objectid; | 1446 | extent_item_pos = logical - found_key.objectid; |
| 1447 | ret = iterate_extent_inodes(fs_info, found_key.objectid, | 1447 | ret = iterate_extent_inodes(fs_info, found_key.objectid, |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 86eff48dab78..43d1c5a3a030 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -818,6 +818,7 @@ static void free_workspace(int type, struct list_head *workspace) | |||
| 818 | btrfs_compress_op[idx]->free_workspace(workspace); | 818 | btrfs_compress_op[idx]->free_workspace(workspace); |
| 819 | atomic_dec(alloc_workspace); | 819 | atomic_dec(alloc_workspace); |
| 820 | wake: | 820 | wake: |
| 821 | smp_mb(); | ||
| 821 | if (waitqueue_active(workspace_wait)) | 822 | if (waitqueue_active(workspace_wait)) |
| 822 | wake_up(workspace_wait); | 823 | wake_up(workspace_wait); |
| 823 | } | 824 | } |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9d7621f271ff..6d183f60d63a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -421,12 +421,6 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info, | |||
| 421 | spin_unlock(&fs_info->tree_mod_seq_lock); | 421 | spin_unlock(&fs_info->tree_mod_seq_lock); |
| 422 | 422 | ||
| 423 | /* | 423 | /* |
| 424 | * we removed the lowest blocker from the blocker list, so there may be | ||
| 425 | * more processible delayed refs. | ||
| 426 | */ | ||
| 427 | wake_up(&fs_info->tree_mod_seq_wait); | ||
| 428 | |||
| 429 | /* | ||
| 430 | * anything that's lower than the lowest existing (read: blocked) | 424 | * anything that's lower than the lowest existing (read: blocked) |
| 431 | * sequence number can be removed from the tree. | 425 | * sequence number can be removed from the tree. |
| 432 | */ | 426 | */ |
| @@ -631,6 +625,9 @@ __tree_mod_log_free_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb) | |||
| 631 | u32 nritems; | 625 | u32 nritems; |
| 632 | int ret; | 626 | int ret; |
| 633 | 627 | ||
| 628 | if (btrfs_header_level(eb) == 0) | ||
| 629 | return; | ||
| 630 | |||
| 634 | nritems = btrfs_header_nritems(eb); | 631 | nritems = btrfs_header_nritems(eb); |
| 635 | for (i = nritems - 1; i >= 0; i--) { | 632 | for (i = nritems - 1; i >= 0; i--) { |
| 636 | ret = tree_mod_log_insert_key_locked(fs_info, eb, i, | 633 | ret = tree_mod_log_insert_key_locked(fs_info, eb, i, |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 4bab807227ad..0d195b507660 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1252,7 +1252,6 @@ struct btrfs_fs_info { | |||
| 1252 | atomic_t tree_mod_seq; | 1252 | atomic_t tree_mod_seq; |
| 1253 | struct list_head tree_mod_seq_list; | 1253 | struct list_head tree_mod_seq_list; |
| 1254 | struct seq_list tree_mod_seq_elem; | 1254 | struct seq_list tree_mod_seq_elem; |
| 1255 | wait_queue_head_t tree_mod_seq_wait; | ||
| 1256 | 1255 | ||
| 1257 | /* this protects tree_mod_log */ | 1256 | /* this protects tree_mod_log */ |
| 1258 | rwlock_t tree_mod_log_lock; | 1257 | rwlock_t tree_mod_log_lock; |
| @@ -3192,7 +3191,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
| 3192 | int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | 3191 | int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, |
| 3193 | struct bio *bio, u32 *dst); | 3192 | struct bio *bio, u32 *dst); |
| 3194 | int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, | 3193 | int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, |
| 3195 | struct bio *bio, u64 logical_offset, u32 *dst); | 3194 | struct bio *bio, u64 logical_offset); |
| 3196 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 3195 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
| 3197 | struct btrfs_root *root, | 3196 | struct btrfs_root *root, |
| 3198 | u64 objectid, u64 pos, | 3197 | u64 objectid, u64 pos, |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 335605c8ceab..07d5eeb1e6f1 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
| @@ -512,8 +512,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) | |||
| 512 | 512 | ||
| 513 | rb_erase(&delayed_item->rb_node, root); | 513 | rb_erase(&delayed_item->rb_node, root); |
| 514 | delayed_item->delayed_node->count--; | 514 | delayed_item->delayed_node->count--; |
| 515 | atomic_dec(&delayed_root->items); | 515 | if (atomic_dec_return(&delayed_root->items) < |
| 516 | if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND && | 516 | BTRFS_DELAYED_BACKGROUND && |
| 517 | waitqueue_active(&delayed_root->wait)) | 517 | waitqueue_active(&delayed_root->wait)) |
| 518 | wake_up(&delayed_root->wait); | 518 | wake_up(&delayed_root->wait); |
| 519 | } | 519 | } |
| @@ -1028,9 +1028,10 @@ do_again: | |||
| 1028 | btrfs_release_delayed_item(prev); | 1028 | btrfs_release_delayed_item(prev); |
| 1029 | ret = 0; | 1029 | ret = 0; |
| 1030 | btrfs_release_path(path); | 1030 | btrfs_release_path(path); |
| 1031 | if (curr) | 1031 | if (curr) { |
| 1032 | mutex_unlock(&node->mutex); | ||
| 1032 | goto do_again; | 1033 | goto do_again; |
| 1033 | else | 1034 | } else |
| 1034 | goto delete_fail; | 1035 | goto delete_fail; |
| 1035 | } | 1036 | } |
| 1036 | 1037 | ||
| @@ -1055,8 +1056,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) | |||
| 1055 | delayed_node->count--; | 1056 | delayed_node->count--; |
| 1056 | 1057 | ||
| 1057 | delayed_root = delayed_node->root->fs_info->delayed_root; | 1058 | delayed_root = delayed_node->root->fs_info->delayed_root; |
| 1058 | atomic_dec(&delayed_root->items); | 1059 | if (atomic_dec_return(&delayed_root->items) < |
| 1059 | if (atomic_read(&delayed_root->items) < | ||
| 1060 | BTRFS_DELAYED_BACKGROUND && | 1060 | BTRFS_DELAYED_BACKGROUND && |
| 1061 | waitqueue_active(&delayed_root->wait)) | 1061 | waitqueue_active(&delayed_root->wait)) |
| 1062 | wake_up(&delayed_root->wait); | 1062 | wake_up(&delayed_root->wait); |
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index da7419ed01bb..ae9411773397 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
| @@ -38,17 +38,14 @@ | |||
| 38 | static int comp_tree_refs(struct btrfs_delayed_tree_ref *ref2, | 38 | static int comp_tree_refs(struct btrfs_delayed_tree_ref *ref2, |
| 39 | struct btrfs_delayed_tree_ref *ref1) | 39 | struct btrfs_delayed_tree_ref *ref1) |
| 40 | { | 40 | { |
| 41 | if (ref1->node.type == BTRFS_TREE_BLOCK_REF_KEY) { | 41 | if (ref1->root < ref2->root) |
| 42 | if (ref1->root < ref2->root) | 42 | return -1; |
| 43 | return -1; | 43 | if (ref1->root > ref2->root) |
| 44 | if (ref1->root > ref2->root) | 44 | return 1; |
| 45 | return 1; | 45 | if (ref1->parent < ref2->parent) |
| 46 | } else { | 46 | return -1; |
| 47 | if (ref1->parent < ref2->parent) | 47 | if (ref1->parent > ref2->parent) |
| 48 | return -1; | 48 | return 1; |
| 49 | if (ref1->parent > ref2->parent) | ||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | return 0; | 49 | return 0; |
| 53 | } | 50 | } |
| 54 | 51 | ||
| @@ -85,7 +82,8 @@ static int comp_data_refs(struct btrfs_delayed_data_ref *ref2, | |||
| 85 | * type of the delayed backrefs and content of delayed backrefs. | 82 | * type of the delayed backrefs and content of delayed backrefs. |
| 86 | */ | 83 | */ |
| 87 | static int comp_entry(struct btrfs_delayed_ref_node *ref2, | 84 | static int comp_entry(struct btrfs_delayed_ref_node *ref2, |
| 88 | struct btrfs_delayed_ref_node *ref1) | 85 | struct btrfs_delayed_ref_node *ref1, |
| 86 | bool compare_seq) | ||
| 89 | { | 87 | { |
| 90 | if (ref1->bytenr < ref2->bytenr) | 88 | if (ref1->bytenr < ref2->bytenr) |
| 91 | return -1; | 89 | return -1; |
| @@ -102,10 +100,12 @@ static int comp_entry(struct btrfs_delayed_ref_node *ref2, | |||
| 102 | if (ref1->type > ref2->type) | 100 | if (ref1->type > ref2->type) |
| 103 | return 1; | 101 | return 1; |
| 104 | /* merging of sequenced refs is not allowed */ | 102 | /* merging of sequenced refs is not allowed */ |
| 105 | if (ref1->seq < ref2->seq) | 103 | if (compare_seq) { |
| 106 | return -1; | 104 | if (ref1->seq < ref2->seq) |
| 107 | if (ref1->seq > ref2->seq) | 105 | return -1; |
| 108 | return 1; | 106 | if (ref1->seq > ref2->seq) |
| 107 | return 1; | ||
| 108 | } | ||
| 109 | if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY || | 109 | if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY || |
| 110 | ref1->type == BTRFS_SHARED_BLOCK_REF_KEY) { | 110 | ref1->type == BTRFS_SHARED_BLOCK_REF_KEY) { |
| 111 | return comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref2), | 111 | return comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref2), |
| @@ -139,7 +139,7 @@ static struct btrfs_delayed_ref_node *tree_insert(struct rb_root *root, | |||
| 139 | entry = rb_entry(parent_node, struct btrfs_delayed_ref_node, | 139 | entry = rb_entry(parent_node, struct btrfs_delayed_ref_node, |
| 140 | rb_node); | 140 | rb_node); |
| 141 | 141 | ||
| 142 | cmp = comp_entry(entry, ins); | 142 | cmp = comp_entry(entry, ins, 1); |
| 143 | if (cmp < 0) | 143 | if (cmp < 0) |
| 144 | p = &(*p)->rb_left; | 144 | p = &(*p)->rb_left; |
| 145 | else if (cmp > 0) | 145 | else if (cmp > 0) |
| @@ -233,6 +233,114 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans, | |||
| 233 | return 0; | 233 | return 0; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | static void inline drop_delayed_ref(struct btrfs_trans_handle *trans, | ||
| 237 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 238 | struct btrfs_delayed_ref_node *ref) | ||
| 239 | { | ||
| 240 | rb_erase(&ref->rb_node, &delayed_refs->root); | ||
| 241 | ref->in_tree = 0; | ||
| 242 | btrfs_put_delayed_ref(ref); | ||
| 243 | delayed_refs->num_entries--; | ||
| 244 | if (trans->delayed_ref_updates) | ||
| 245 | trans->delayed_ref_updates--; | ||
| 246 | } | ||
| 247 | |||
| 248 | static int merge_ref(struct btrfs_trans_handle *trans, | ||
| 249 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 250 | struct btrfs_delayed_ref_node *ref, u64 seq) | ||
| 251 | { | ||
| 252 | struct rb_node *node; | ||
| 253 | int merged = 0; | ||
| 254 | int mod = 0; | ||
| 255 | int done = 0; | ||
| 256 | |||
| 257 | node = rb_prev(&ref->rb_node); | ||
| 258 | while (node) { | ||
| 259 | struct btrfs_delayed_ref_node *next; | ||
| 260 | |||
| 261 | next = rb_entry(node, struct btrfs_delayed_ref_node, rb_node); | ||
| 262 | node = rb_prev(node); | ||
| 263 | if (next->bytenr != ref->bytenr) | ||
| 264 | break; | ||
| 265 | if (seq && next->seq >= seq) | ||
| 266 | break; | ||
| 267 | if (comp_entry(ref, next, 0)) | ||
| 268 | continue; | ||
| 269 | |||
| 270 | if (ref->action == next->action) { | ||
| 271 | mod = next->ref_mod; | ||
| 272 | } else { | ||
| 273 | if (ref->ref_mod < next->ref_mod) { | ||
| 274 | struct btrfs_delayed_ref_node *tmp; | ||
| 275 | |||
| 276 | tmp = ref; | ||
| 277 | ref = next; | ||
| 278 | next = tmp; | ||
| 279 | done = 1; | ||
| 280 | } | ||
| 281 | mod = -next->ref_mod; | ||
| 282 | } | ||
| 283 | |||
| 284 | merged++; | ||
| 285 | drop_delayed_ref(trans, delayed_refs, next); | ||
| 286 | ref->ref_mod += mod; | ||
| 287 | if (ref->ref_mod == 0) { | ||
| 288 | drop_delayed_ref(trans, delayed_refs, ref); | ||
| 289 | break; | ||
| 290 | } else { | ||
| 291 | /* | ||
| 292 | * You can't have multiples of the same ref on a tree | ||
| 293 | * block. | ||
| 294 | */ | ||
| 295 | WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY || | ||
| 296 | ref->type == BTRFS_SHARED_BLOCK_REF_KEY); | ||
| 297 | } | ||
| 298 | |||
| 299 | if (done) | ||
| 300 | break; | ||
| 301 | node = rb_prev(&ref->rb_node); | ||
| 302 | } | ||
| 303 | |||
| 304 | return merged; | ||
| 305 | } | ||
| 306 | |||
| 307 | void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, | ||
| 308 | struct btrfs_fs_info *fs_info, | ||
| 309 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 310 | struct btrfs_delayed_ref_head *head) | ||
| 311 | { | ||
| 312 | struct rb_node *node; | ||
| 313 | u64 seq = 0; | ||
| 314 | |||
| 315 | spin_lock(&fs_info->tree_mod_seq_lock); | ||
| 316 | if (!list_empty(&fs_info->tree_mod_seq_list)) { | ||
| 317 | struct seq_list *elem; | ||
| 318 | |||
| 319 | elem = list_first_entry(&fs_info->tree_mod_seq_list, | ||
| 320 | struct seq_list, list); | ||
| 321 | seq = elem->seq; | ||
| 322 | } | ||
| 323 | spin_unlock(&fs_info->tree_mod_seq_lock); | ||
| 324 | |||
| 325 | node = rb_prev(&head->node.rb_node); | ||
| 326 | while (node) { | ||
| 327 | struct btrfs_delayed_ref_node *ref; | ||
| 328 | |||
| 329 | ref = rb_entry(node, struct btrfs_delayed_ref_node, | ||
| 330 | rb_node); | ||
| 331 | if (ref->bytenr != head->node.bytenr) | ||
| 332 | break; | ||
| 333 | |||
| 334 | /* We can't merge refs that are outside of our seq count */ | ||
| 335 | if (seq && ref->seq >= seq) | ||
| 336 | break; | ||
| 337 | if (merge_ref(trans, delayed_refs, ref, seq)) | ||
| 338 | node = rb_prev(&head->node.rb_node); | ||
| 339 | else | ||
| 340 | node = rb_prev(node); | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 236 | int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, | 344 | int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, |
| 237 | struct btrfs_delayed_ref_root *delayed_refs, | 345 | struct btrfs_delayed_ref_root *delayed_refs, |
| 238 | u64 seq) | 346 | u64 seq) |
| @@ -336,18 +444,11 @@ update_existing_ref(struct btrfs_trans_handle *trans, | |||
| 336 | * every changing the extent allocation tree. | 444 | * every changing the extent allocation tree. |
| 337 | */ | 445 | */ |
| 338 | existing->ref_mod--; | 446 | existing->ref_mod--; |
| 339 | if (existing->ref_mod == 0) { | 447 | if (existing->ref_mod == 0) |
| 340 | rb_erase(&existing->rb_node, | 448 | drop_delayed_ref(trans, delayed_refs, existing); |
| 341 | &delayed_refs->root); | 449 | else |
| 342 | existing->in_tree = 0; | ||
| 343 | btrfs_put_delayed_ref(existing); | ||
| 344 | delayed_refs->num_entries--; | ||
| 345 | if (trans->delayed_ref_updates) | ||
| 346 | trans->delayed_ref_updates--; | ||
| 347 | } else { | ||
| 348 | WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY || | 450 | WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY || |
| 349 | existing->type == BTRFS_SHARED_BLOCK_REF_KEY); | 451 | existing->type == BTRFS_SHARED_BLOCK_REF_KEY); |
| 350 | } | ||
| 351 | } else { | 452 | } else { |
| 352 | WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY || | 453 | WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY || |
| 353 | existing->type == BTRFS_SHARED_BLOCK_REF_KEY); | 454 | existing->type == BTRFS_SHARED_BLOCK_REF_KEY); |
| @@ -662,9 +763,6 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
| 662 | add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, | 763 | add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, |
| 663 | num_bytes, parent, ref_root, level, action, | 764 | num_bytes, parent, ref_root, level, action, |
| 664 | for_cow); | 765 | for_cow); |
| 665 | if (!need_ref_seq(for_cow, ref_root) && | ||
| 666 | waitqueue_active(&fs_info->tree_mod_seq_wait)) | ||
| 667 | wake_up(&fs_info->tree_mod_seq_wait); | ||
| 668 | spin_unlock(&delayed_refs->lock); | 766 | spin_unlock(&delayed_refs->lock); |
| 669 | if (need_ref_seq(for_cow, ref_root)) | 767 | if (need_ref_seq(for_cow, ref_root)) |
| 670 | btrfs_qgroup_record_ref(trans, &ref->node, extent_op); | 768 | btrfs_qgroup_record_ref(trans, &ref->node, extent_op); |
| @@ -713,9 +811,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
| 713 | add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, | 811 | add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, |
| 714 | num_bytes, parent, ref_root, owner, offset, | 812 | num_bytes, parent, ref_root, owner, offset, |
| 715 | action, for_cow); | 813 | action, for_cow); |
| 716 | if (!need_ref_seq(for_cow, ref_root) && | ||
| 717 | waitqueue_active(&fs_info->tree_mod_seq_wait)) | ||
| 718 | wake_up(&fs_info->tree_mod_seq_wait); | ||
| 719 | spin_unlock(&delayed_refs->lock); | 814 | spin_unlock(&delayed_refs->lock); |
| 720 | if (need_ref_seq(for_cow, ref_root)) | 815 | if (need_ref_seq(for_cow, ref_root)) |
| 721 | btrfs_qgroup_record_ref(trans, &ref->node, extent_op); | 816 | btrfs_qgroup_record_ref(trans, &ref->node, extent_op); |
| @@ -744,8 +839,6 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | |||
| 744 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, | 839 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, |
| 745 | extent_op->is_data); | 840 | extent_op->is_data); |
| 746 | 841 | ||
| 747 | if (waitqueue_active(&fs_info->tree_mod_seq_wait)) | ||
| 748 | wake_up(&fs_info->tree_mod_seq_wait); | ||
| 749 | spin_unlock(&delayed_refs->lock); | 842 | spin_unlock(&delayed_refs->lock); |
| 750 | return 0; | 843 | return 0; |
| 751 | } | 844 | } |
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index 0d7c90c366b6..ab5300595847 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h | |||
| @@ -167,6 +167,10 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | |||
| 167 | struct btrfs_trans_handle *trans, | 167 | struct btrfs_trans_handle *trans, |
| 168 | u64 bytenr, u64 num_bytes, | 168 | u64 bytenr, u64 num_bytes, |
| 169 | struct btrfs_delayed_extent_op *extent_op); | 169 | struct btrfs_delayed_extent_op *extent_op); |
| 170 | void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, | ||
| 171 | struct btrfs_fs_info *fs_info, | ||
| 172 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 173 | struct btrfs_delayed_ref_head *head); | ||
| 170 | 174 | ||
| 171 | struct btrfs_delayed_ref_head * | 175 | struct btrfs_delayed_ref_head * |
| 172 | btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr); | 176 | btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62e0cafd6e25..22e98e04c2ea 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -377,9 +377,13 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, | |||
| 377 | ret = read_extent_buffer_pages(io_tree, eb, start, | 377 | ret = read_extent_buffer_pages(io_tree, eb, start, |
| 378 | WAIT_COMPLETE, | 378 | WAIT_COMPLETE, |
| 379 | btree_get_extent, mirror_num); | 379 | btree_get_extent, mirror_num); |
| 380 | if (!ret && !verify_parent_transid(io_tree, eb, | 380 | if (!ret) { |
| 381 | if (!verify_parent_transid(io_tree, eb, | ||
| 381 | parent_transid, 0)) | 382 | parent_transid, 0)) |
| 382 | break; | 383 | break; |
| 384 | else | ||
| 385 | ret = -EIO; | ||
| 386 | } | ||
| 383 | 387 | ||
| 384 | /* | 388 | /* |
| 385 | * This buffer's crc is fine, but its contents are corrupted, so | 389 | * This buffer's crc is fine, but its contents are corrupted, so |
| @@ -754,9 +758,7 @@ static void run_one_async_done(struct btrfs_work *work) | |||
| 754 | limit = btrfs_async_submit_limit(fs_info); | 758 | limit = btrfs_async_submit_limit(fs_info); |
| 755 | limit = limit * 2 / 3; | 759 | limit = limit * 2 / 3; |
| 756 | 760 | ||
| 757 | atomic_dec(&fs_info->nr_async_submits); | 761 | if (atomic_dec_return(&fs_info->nr_async_submits) < limit && |
| 758 | |||
| 759 | if (atomic_read(&fs_info->nr_async_submits) < limit && | ||
| 760 | waitqueue_active(&fs_info->async_submit_wait)) | 762 | waitqueue_active(&fs_info->async_submit_wait)) |
| 761 | wake_up(&fs_info->async_submit_wait); | 763 | wake_up(&fs_info->async_submit_wait); |
| 762 | 764 | ||
| @@ -2032,8 +2034,6 @@ int open_ctree(struct super_block *sb, | |||
| 2032 | fs_info->free_chunk_space = 0; | 2034 | fs_info->free_chunk_space = 0; |
| 2033 | fs_info->tree_mod_log = RB_ROOT; | 2035 | fs_info->tree_mod_log = RB_ROOT; |
| 2034 | 2036 | ||
| 2035 | init_waitqueue_head(&fs_info->tree_mod_seq_wait); | ||
| 2036 | |||
| 2037 | /* readahead state */ | 2037 | /* readahead state */ |
| 2038 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); | 2038 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); |
| 2039 | spin_lock_init(&fs_info->reada_lock); | 2039 | spin_lock_init(&fs_info->reada_lock); |
| @@ -2528,8 +2528,7 @@ retry_root_backup: | |||
| 2528 | goto fail_trans_kthread; | 2528 | goto fail_trans_kthread; |
| 2529 | 2529 | ||
| 2530 | /* do not make disk changes in broken FS */ | 2530 | /* do not make disk changes in broken FS */ |
| 2531 | if (btrfs_super_log_root(disk_super) != 0 && | 2531 | if (btrfs_super_log_root(disk_super) != 0) { |
| 2532 | !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) { | ||
| 2533 | u64 bytenr = btrfs_super_log_root(disk_super); | 2532 | u64 bytenr = btrfs_super_log_root(disk_super); |
| 2534 | 2533 | ||
| 2535 | if (fs_devices->rw_devices == 0) { | 2534 | if (fs_devices->rw_devices == 0) { |
| @@ -3189,30 +3188,14 @@ int close_ctree(struct btrfs_root *root) | |||
| 3189 | /* clear out the rbtree of defraggable inodes */ | 3188 | /* clear out the rbtree of defraggable inodes */ |
| 3190 | btrfs_run_defrag_inodes(fs_info); | 3189 | btrfs_run_defrag_inodes(fs_info); |
| 3191 | 3190 | ||
| 3192 | /* | ||
| 3193 | * Here come 2 situations when btrfs is broken to flip readonly: | ||
| 3194 | * | ||
| 3195 | * 1. when btrfs flips readonly somewhere else before | ||
| 3196 | * btrfs_commit_super, sb->s_flags has MS_RDONLY flag, | ||
| 3197 | * and btrfs will skip to write sb directly to keep | ||
| 3198 | * ERROR state on disk. | ||
| 3199 | * | ||
| 3200 | * 2. when btrfs flips readonly just in btrfs_commit_super, | ||
| 3201 | * and in such case, btrfs cannot write sb via btrfs_commit_super, | ||
| 3202 | * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag, | ||
| 3203 | * btrfs will cleanup all FS resources first and write sb then. | ||
| 3204 | */ | ||
| 3205 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { | 3191 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { |
| 3206 | ret = btrfs_commit_super(root); | 3192 | ret = btrfs_commit_super(root); |
| 3207 | if (ret) | 3193 | if (ret) |
| 3208 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); | 3194 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); |
| 3209 | } | 3195 | } |
| 3210 | 3196 | ||
| 3211 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 3197 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) |
| 3212 | ret = btrfs_error_commit_super(root); | 3198 | btrfs_error_commit_super(root); |
| 3213 | if (ret) | ||
| 3214 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); | ||
| 3215 | } | ||
| 3216 | 3199 | ||
| 3217 | btrfs_put_block_group_cache(fs_info); | 3200 | btrfs_put_block_group_cache(fs_info); |
| 3218 | 3201 | ||
| @@ -3434,18 +3417,11 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | |||
| 3434 | if (read_only) | 3417 | if (read_only) |
| 3435 | return 0; | 3418 | return 0; |
| 3436 | 3419 | ||
| 3437 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | ||
| 3438 | printk(KERN_WARNING "warning: mount fs with errors, " | ||
| 3439 | "running btrfsck is recommended\n"); | ||
| 3440 | } | ||
| 3441 | |||
| 3442 | return 0; | 3420 | return 0; |
| 3443 | } | 3421 | } |
| 3444 | 3422 | ||
| 3445 | int btrfs_error_commit_super(struct btrfs_root *root) | 3423 | void btrfs_error_commit_super(struct btrfs_root *root) |
| 3446 | { | 3424 | { |
| 3447 | int ret; | ||
| 3448 | |||
| 3449 | mutex_lock(&root->fs_info->cleaner_mutex); | 3425 | mutex_lock(&root->fs_info->cleaner_mutex); |
| 3450 | btrfs_run_delayed_iputs(root); | 3426 | btrfs_run_delayed_iputs(root); |
| 3451 | mutex_unlock(&root->fs_info->cleaner_mutex); | 3427 | mutex_unlock(&root->fs_info->cleaner_mutex); |
| @@ -3455,10 +3431,6 @@ int btrfs_error_commit_super(struct btrfs_root *root) | |||
| 3455 | 3431 | ||
| 3456 | /* cleanup FS via transaction */ | 3432 | /* cleanup FS via transaction */ |
| 3457 | btrfs_cleanup_transaction(root); | 3433 | btrfs_cleanup_transaction(root); |
| 3458 | |||
| 3459 | ret = write_ctree_super(NULL, root, 0); | ||
| 3460 | |||
| 3461 | return ret; | ||
| 3462 | } | 3434 | } |
| 3463 | 3435 | ||
| 3464 | static void btrfs_destroy_ordered_operations(struct btrfs_root *root) | 3436 | static void btrfs_destroy_ordered_operations(struct btrfs_root *root) |
| @@ -3782,14 +3754,17 @@ int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
| 3782 | /* FIXME: cleanup wait for commit */ | 3754 | /* FIXME: cleanup wait for commit */ |
| 3783 | t->in_commit = 1; | 3755 | t->in_commit = 1; |
| 3784 | t->blocked = 1; | 3756 | t->blocked = 1; |
| 3757 | smp_mb(); | ||
| 3785 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) | 3758 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) |
| 3786 | wake_up(&root->fs_info->transaction_blocked_wait); | 3759 | wake_up(&root->fs_info->transaction_blocked_wait); |
| 3787 | 3760 | ||
| 3788 | t->blocked = 0; | 3761 | t->blocked = 0; |
| 3762 | smp_mb(); | ||
| 3789 | if (waitqueue_active(&root->fs_info->transaction_wait)) | 3763 | if (waitqueue_active(&root->fs_info->transaction_wait)) |
| 3790 | wake_up(&root->fs_info->transaction_wait); | 3764 | wake_up(&root->fs_info->transaction_wait); |
| 3791 | 3765 | ||
| 3792 | t->commit_done = 1; | 3766 | t->commit_done = 1; |
| 3767 | smp_mb(); | ||
| 3793 | if (waitqueue_active(&t->commit_wait)) | 3768 | if (waitqueue_active(&t->commit_wait)) |
| 3794 | wake_up(&t->commit_wait); | 3769 | wake_up(&t->commit_wait); |
| 3795 | 3770 | ||
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 95e147eea239..c5b00a735fef 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
| @@ -54,7 +54,7 @@ int write_ctree_super(struct btrfs_trans_handle *trans, | |||
| 54 | struct btrfs_root *root, int max_mirrors); | 54 | struct btrfs_root *root, int max_mirrors); |
| 55 | struct buffer_head *btrfs_read_dev_super(struct block_device *bdev); | 55 | struct buffer_head *btrfs_read_dev_super(struct block_device *bdev); |
| 56 | int btrfs_commit_super(struct btrfs_root *root); | 56 | int btrfs_commit_super(struct btrfs_root *root); |
| 57 | int btrfs_error_commit_super(struct btrfs_root *root); | 57 | void btrfs_error_commit_super(struct btrfs_root *root); |
| 58 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | 58 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
| 59 | u64 bytenr, u32 blocksize); | 59 | u64 bytenr, u32 blocksize); |
| 60 | struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | 60 | struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4e1b153b7c47..ba58024d40d3 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -2252,6 +2252,16 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
| 2252 | } | 2252 | } |
| 2253 | 2253 | ||
| 2254 | /* | 2254 | /* |
| 2255 | * We need to try and merge add/drops of the same ref since we | ||
| 2256 | * can run into issues with relocate dropping the implicit ref | ||
| 2257 | * and then it being added back again before the drop can | ||
| 2258 | * finish. If we merged anything we need to re-loop so we can | ||
| 2259 | * get a good ref. | ||
| 2260 | */ | ||
| 2261 | btrfs_merge_delayed_refs(trans, fs_info, delayed_refs, | ||
| 2262 | locked_ref); | ||
| 2263 | |||
| 2264 | /* | ||
| 2255 | * locked_ref is the head node, so we have to go one | 2265 | * locked_ref is the head node, so we have to go one |
| 2256 | * node back for any delayed ref updates | 2266 | * node back for any delayed ref updates |
| 2257 | */ | 2267 | */ |
| @@ -2318,12 +2328,23 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
| 2318 | ref->in_tree = 0; | 2328 | ref->in_tree = 0; |
| 2319 | rb_erase(&ref->rb_node, &delayed_refs->root); | 2329 | rb_erase(&ref->rb_node, &delayed_refs->root); |
| 2320 | delayed_refs->num_entries--; | 2330 | delayed_refs->num_entries--; |
| 2321 | /* | 2331 | if (locked_ref) { |
| 2322 | * we modified num_entries, but as we're currently running | 2332 | /* |
| 2323 | * delayed refs, skip | 2333 | * when we play the delayed ref, also correct the |
| 2324 | * wake_up(&delayed_refs->seq_wait); | 2334 | * ref_mod on head |
| 2325 | * here. | 2335 | */ |
| 2326 | */ | 2336 | switch (ref->action) { |
| 2337 | case BTRFS_ADD_DELAYED_REF: | ||
| 2338 | case BTRFS_ADD_DELAYED_EXTENT: | ||
| 2339 | locked_ref->node.ref_mod -= ref->ref_mod; | ||
| 2340 | break; | ||
| 2341 | case BTRFS_DROP_DELAYED_REF: | ||
| 2342 | locked_ref->node.ref_mod += ref->ref_mod; | ||
| 2343 | break; | ||
| 2344 | default: | ||
| 2345 | WARN_ON(1); | ||
| 2346 | } | ||
| 2347 | } | ||
| 2327 | spin_unlock(&delayed_refs->lock); | 2348 | spin_unlock(&delayed_refs->lock); |
| 2328 | 2349 | ||
| 2329 | ret = run_one_delayed_ref(trans, root, ref, extent_op, | 2350 | ret = run_one_delayed_ref(trans, root, ref, extent_op, |
| @@ -2350,22 +2371,6 @@ next: | |||
| 2350 | return count; | 2371 | return count; |
| 2351 | } | 2372 | } |
| 2352 | 2373 | ||
| 2353 | static void wait_for_more_refs(struct btrfs_fs_info *fs_info, | ||
| 2354 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 2355 | unsigned long num_refs, | ||
| 2356 | struct list_head *first_seq) | ||
| 2357 | { | ||
| 2358 | spin_unlock(&delayed_refs->lock); | ||
| 2359 | pr_debug("waiting for more refs (num %ld, first %p)\n", | ||
| 2360 | num_refs, first_seq); | ||
| 2361 | wait_event(fs_info->tree_mod_seq_wait, | ||
| 2362 | num_refs != delayed_refs->num_entries || | ||
| 2363 | fs_info->tree_mod_seq_list.next != first_seq); | ||
| 2364 | pr_debug("done waiting for more refs (num %ld, first %p)\n", | ||
| 2365 | delayed_refs->num_entries, fs_info->tree_mod_seq_list.next); | ||
| 2366 | spin_lock(&delayed_refs->lock); | ||
| 2367 | } | ||
| 2368 | |||
| 2369 | #ifdef SCRAMBLE_DELAYED_REFS | 2374 | #ifdef SCRAMBLE_DELAYED_REFS |
| 2370 | /* | 2375 | /* |
| 2371 | * Normally delayed refs get processed in ascending bytenr order. This | 2376 | * Normally delayed refs get processed in ascending bytenr order. This |
| @@ -2460,13 +2465,11 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
| 2460 | struct btrfs_delayed_ref_root *delayed_refs; | 2465 | struct btrfs_delayed_ref_root *delayed_refs; |
| 2461 | struct btrfs_delayed_ref_node *ref; | 2466 | struct btrfs_delayed_ref_node *ref; |
| 2462 | struct list_head cluster; | 2467 | struct list_head cluster; |
| 2463 | struct list_head *first_seq = NULL; | ||
| 2464 | int ret; | 2468 | int ret; |
| 2465 | u64 delayed_start; | 2469 | u64 delayed_start; |
| 2466 | int run_all = count == (unsigned long)-1; | 2470 | int run_all = count == (unsigned long)-1; |
| 2467 | int run_most = 0; | 2471 | int run_most = 0; |
| 2468 | unsigned long num_refs = 0; | 2472 | int loops; |
| 2469 | int consider_waiting; | ||
| 2470 | 2473 | ||
| 2471 | /* We'll clean this up in btrfs_cleanup_transaction */ | 2474 | /* We'll clean this up in btrfs_cleanup_transaction */ |
| 2472 | if (trans->aborted) | 2475 | if (trans->aborted) |
| @@ -2484,7 +2487,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
| 2484 | delayed_refs = &trans->transaction->delayed_refs; | 2487 | delayed_refs = &trans->transaction->delayed_refs; |
| 2485 | INIT_LIST_HEAD(&cluster); | 2488 | INIT_LIST_HEAD(&cluster); |
| 2486 | again: | 2489 | again: |
| 2487 | consider_waiting = 0; | 2490 | loops = 0; |
| 2488 | spin_lock(&delayed_refs->lock); | 2491 | spin_lock(&delayed_refs->lock); |
| 2489 | 2492 | ||
| 2490 | #ifdef SCRAMBLE_DELAYED_REFS | 2493 | #ifdef SCRAMBLE_DELAYED_REFS |
| @@ -2512,31 +2515,6 @@ again: | |||
| 2512 | if (ret) | 2515 | if (ret) |
| 2513 | break; | 2516 | break; |
| 2514 | 2517 | ||
| 2515 | if (delayed_start >= delayed_refs->run_delayed_start) { | ||
| 2516 | if (consider_waiting == 0) { | ||
| 2517 | /* | ||
| 2518 | * btrfs_find_ref_cluster looped. let's do one | ||
| 2519 | * more cycle. if we don't run any delayed ref | ||
| 2520 | * during that cycle (because we can't because | ||
| 2521 | * all of them are blocked) and if the number of | ||
| 2522 | * refs doesn't change, we avoid busy waiting. | ||
| 2523 | */ | ||
| 2524 | consider_waiting = 1; | ||
| 2525 | num_refs = delayed_refs->num_entries; | ||
| 2526 | first_seq = root->fs_info->tree_mod_seq_list.next; | ||
| 2527 | } else { | ||
| 2528 | wait_for_more_refs(root->fs_info, delayed_refs, | ||
| 2529 | num_refs, first_seq); | ||
| 2530 | /* | ||
| 2531 | * after waiting, things have changed. we | ||
| 2532 | * dropped the lock and someone else might have | ||
| 2533 | * run some refs, built new clusters and so on. | ||
| 2534 | * therefore, we restart staleness detection. | ||
| 2535 | */ | ||
| 2536 | consider_waiting = 0; | ||
| 2537 | } | ||
| 2538 | } | ||
| 2539 | |||
| 2540 | ret = run_clustered_refs(trans, root, &cluster); | 2518 | ret = run_clustered_refs(trans, root, &cluster); |
| 2541 | if (ret < 0) { | 2519 | if (ret < 0) { |
| 2542 | spin_unlock(&delayed_refs->lock); | 2520 | spin_unlock(&delayed_refs->lock); |
| @@ -2549,9 +2527,26 @@ again: | |||
| 2549 | if (count == 0) | 2527 | if (count == 0) |
| 2550 | break; | 2528 | break; |
| 2551 | 2529 | ||
| 2552 | if (ret || delayed_refs->run_delayed_start == 0) { | 2530 | if (delayed_start >= delayed_refs->run_delayed_start) { |
| 2531 | if (loops == 0) { | ||
| 2532 | /* | ||
| 2533 | * btrfs_find_ref_cluster looped. let's do one | ||
| 2534 | * more cycle. if we don't run any delayed ref | ||
| 2535 | * during that cycle (because we can't because | ||
| 2536 | * all of them are blocked), bail out. | ||
| 2537 | */ | ||
| 2538 | loops = 1; | ||
| 2539 | } else { | ||
| 2540 | /* | ||
| 2541 | * no runnable refs left, stop trying | ||
| 2542 | */ | ||
| 2543 | BUG_ON(run_all); | ||
| 2544 | break; | ||
| 2545 | } | ||
| 2546 | } | ||
| 2547 | if (ret) { | ||
| 2553 | /* refs were run, let's reset staleness detection */ | 2548 | /* refs were run, let's reset staleness detection */ |
| 2554 | consider_waiting = 0; | 2549 | loops = 0; |
| 2555 | } | 2550 | } |
| 2556 | } | 2551 | } |
| 2557 | 2552 | ||
| @@ -3007,17 +3002,16 @@ again: | |||
| 3007 | } | 3002 | } |
| 3008 | spin_unlock(&block_group->lock); | 3003 | spin_unlock(&block_group->lock); |
| 3009 | 3004 | ||
| 3010 | num_pages = (int)div64_u64(block_group->key.offset, 1024 * 1024 * 1024); | 3005 | /* |
| 3006 | * Try to preallocate enough space based on how big the block group is. | ||
| 3007 | * Keep in mind this has to include any pinned space which could end up | ||
| 3008 | * taking up quite a bit since it's not folded into the other space | ||
| 3009 | * cache. | ||
| 3010 | */ | ||
| 3011 | num_pages = (int)div64_u64(block_group->key.offset, 256 * 1024 * 1024); | ||
| 3011 | if (!num_pages) | 3012 | if (!num_pages) |
| 3012 | num_pages = 1; | 3013 | num_pages = 1; |
| 3013 | 3014 | ||
| 3014 | /* | ||
| 3015 | * Just to make absolutely sure we have enough space, we're going to | ||
| 3016 | * preallocate 12 pages worth of space for each block group. In | ||
| 3017 | * practice we ought to use at most 8, but we need extra space so we can | ||
| 3018 | * add our header and have a terminator between the extents and the | ||
| 3019 | * bitmaps. | ||
| 3020 | */ | ||
| 3021 | num_pages *= 16; | 3015 | num_pages *= 16; |
| 3022 | num_pages *= PAGE_CACHE_SIZE; | 3016 | num_pages *= PAGE_CACHE_SIZE; |
| 3023 | 3017 | ||
| @@ -4571,8 +4565,10 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
| 4571 | if (root->fs_info->quota_enabled) { | 4565 | if (root->fs_info->quota_enabled) { |
| 4572 | ret = btrfs_qgroup_reserve(root, num_bytes + | 4566 | ret = btrfs_qgroup_reserve(root, num_bytes + |
| 4573 | nr_extents * root->leafsize); | 4567 | nr_extents * root->leafsize); |
| 4574 | if (ret) | 4568 | if (ret) { |
| 4569 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
| 4575 | return ret; | 4570 | return ret; |
| 4571 | } | ||
| 4576 | } | 4572 | } |
| 4577 | 4573 | ||
| 4578 | ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); | 4574 | ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); |
| @@ -5294,9 +5290,6 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, | |||
| 5294 | rb_erase(&head->node.rb_node, &delayed_refs->root); | 5290 | rb_erase(&head->node.rb_node, &delayed_refs->root); |
| 5295 | 5291 | ||
| 5296 | delayed_refs->num_entries--; | 5292 | delayed_refs->num_entries--; |
| 5297 | smp_mb(); | ||
| 5298 | if (waitqueue_active(&root->fs_info->tree_mod_seq_wait)) | ||
| 5299 | wake_up(&root->fs_info->tree_mod_seq_wait); | ||
| 5300 | 5293 | ||
| 5301 | /* | 5294 | /* |
| 5302 | * we don't take a ref on the node because we're removing it from the | 5295 | * we don't take a ref on the node because we're removing it from the |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 45c81bb4ac82..4c878476bb91 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -2330,23 +2330,10 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
| 2330 | if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { | 2330 | if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { |
| 2331 | ret = tree->ops->readpage_end_io_hook(page, start, end, | 2331 | ret = tree->ops->readpage_end_io_hook(page, start, end, |
| 2332 | state, mirror); | 2332 | state, mirror); |
| 2333 | if (ret) { | 2333 | if (ret) |
| 2334 | /* no IO indicated but software detected errors | ||
| 2335 | * in the block, either checksum errors or | ||
| 2336 | * issues with the contents */ | ||
| 2337 | struct btrfs_root *root = | ||
| 2338 | BTRFS_I(page->mapping->host)->root; | ||
| 2339 | struct btrfs_device *device; | ||
| 2340 | |||
| 2341 | uptodate = 0; | 2334 | uptodate = 0; |
| 2342 | device = btrfs_find_device_for_logical( | 2335 | else |
| 2343 | root, start, mirror); | ||
| 2344 | if (device) | ||
| 2345 | btrfs_dev_stat_inc_and_print(device, | ||
| 2346 | BTRFS_DEV_STAT_CORRUPTION_ERRS); | ||
| 2347 | } else { | ||
| 2348 | clean_io_failure(start, page); | 2336 | clean_io_failure(start, page); |
| 2349 | } | ||
| 2350 | } | 2337 | } |
| 2351 | 2338 | ||
| 2352 | if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) { | 2339 | if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) { |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index b45b9de0c21d..857d93cd01dc 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
| @@ -272,9 +272,9 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, | 274 | int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, |
| 275 | struct bio *bio, u64 offset, u32 *dst) | 275 | struct bio *bio, u64 offset) |
| 276 | { | 276 | { |
| 277 | return __btrfs_lookup_bio_sums(root, inode, bio, offset, dst, 1); | 277 | return __btrfs_lookup_bio_sums(root, inode, bio, offset, NULL, 1); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | 280 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6e8f416773d4..ec154f954646 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -1008,9 +1008,7 @@ static noinline void async_cow_submit(struct btrfs_work *work) | |||
| 1008 | nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >> | 1008 | nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >> |
| 1009 | PAGE_CACHE_SHIFT; | 1009 | PAGE_CACHE_SHIFT; |
| 1010 | 1010 | ||
| 1011 | atomic_sub(nr_pages, &root->fs_info->async_delalloc_pages); | 1011 | if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) < |
| 1012 | |||
| 1013 | if (atomic_read(&root->fs_info->async_delalloc_pages) < | ||
| 1014 | 5 * 1024 * 1024 && | 1012 | 5 * 1024 * 1024 && |
| 1015 | waitqueue_active(&root->fs_info->async_submit_wait)) | 1013 | waitqueue_active(&root->fs_info->async_submit_wait)) |
| 1016 | wake_up(&root->fs_info->async_submit_wait); | 1014 | wake_up(&root->fs_info->async_submit_wait); |
| @@ -1885,8 +1883,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) | |||
| 1885 | trans = btrfs_join_transaction_nolock(root); | 1883 | trans = btrfs_join_transaction_nolock(root); |
| 1886 | else | 1884 | else |
| 1887 | trans = btrfs_join_transaction(root); | 1885 | trans = btrfs_join_transaction(root); |
| 1888 | if (IS_ERR(trans)) | 1886 | if (IS_ERR(trans)) { |
| 1889 | return PTR_ERR(trans); | 1887 | ret = PTR_ERR(trans); |
| 1888 | trans = NULL; | ||
| 1889 | goto out; | ||
| 1890 | } | ||
| 1890 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1891 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 1891 | ret = btrfs_update_inode_fallback(trans, root, inode); | 1892 | ret = btrfs_update_inode_fallback(trans, root, inode); |
| 1892 | if (ret) /* -ENOMEM or corruption */ | 1893 | if (ret) /* -ENOMEM or corruption */ |
| @@ -3174,7 +3175,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, | |||
| 3174 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); | 3175 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); |
| 3175 | inode_inc_iversion(dir); | 3176 | inode_inc_iversion(dir); |
| 3176 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | 3177 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
| 3177 | ret = btrfs_update_inode(trans, root, dir); | 3178 | ret = btrfs_update_inode_fallback(trans, root, dir); |
| 3178 | if (ret) | 3179 | if (ret) |
| 3179 | btrfs_abort_transaction(trans, root, ret); | 3180 | btrfs_abort_transaction(trans, root, ret); |
| 3180 | out: | 3181 | out: |
| @@ -5774,18 +5775,112 @@ out: | |||
| 5774 | return ret; | 5775 | return ret; |
| 5775 | } | 5776 | } |
| 5776 | 5777 | ||
| 5778 | static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend, | ||
| 5779 | struct extent_state **cached_state, int writing) | ||
| 5780 | { | ||
| 5781 | struct btrfs_ordered_extent *ordered; | ||
| 5782 | int ret = 0; | ||
| 5783 | |||
| 5784 | while (1) { | ||
| 5785 | lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 5786 | 0, cached_state); | ||
| 5787 | /* | ||
| 5788 | * We're concerned with the entire range that we're going to be | ||
| 5789 | * doing DIO to, so we need to make sure theres no ordered | ||
| 5790 | * extents in this range. | ||
| 5791 | */ | ||
| 5792 | ordered = btrfs_lookup_ordered_range(inode, lockstart, | ||
| 5793 | lockend - lockstart + 1); | ||
| 5794 | |||
| 5795 | /* | ||
| 5796 | * We need to make sure there are no buffered pages in this | ||
| 5797 | * range either, we could have raced between the invalidate in | ||
| 5798 | * generic_file_direct_write and locking the extent. The | ||
| 5799 | * invalidate needs to happen so that reads after a write do not | ||
| 5800 | * get stale data. | ||
| 5801 | */ | ||
| 5802 | if (!ordered && (!writing || | ||
| 5803 | !test_range_bit(&BTRFS_I(inode)->io_tree, | ||
| 5804 | lockstart, lockend, EXTENT_UPTODATE, 0, | ||
| 5805 | *cached_state))) | ||
| 5806 | break; | ||
| 5807 | |||
| 5808 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 5809 | cached_state, GFP_NOFS); | ||
| 5810 | |||
| 5811 | if (ordered) { | ||
| 5812 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
| 5813 | btrfs_put_ordered_extent(ordered); | ||
| 5814 | } else { | ||
| 5815 | /* Screw you mmap */ | ||
| 5816 | ret = filemap_write_and_wait_range(inode->i_mapping, | ||
| 5817 | lockstart, | ||
| 5818 | lockend); | ||
| 5819 | if (ret) | ||
| 5820 | break; | ||
| 5821 | |||
| 5822 | /* | ||
| 5823 | * If we found a page that couldn't be invalidated just | ||
| 5824 | * fall back to buffered. | ||
| 5825 | */ | ||
| 5826 | ret = invalidate_inode_pages2_range(inode->i_mapping, | ||
| 5827 | lockstart >> PAGE_CACHE_SHIFT, | ||
| 5828 | lockend >> PAGE_CACHE_SHIFT); | ||
| 5829 | if (ret) | ||
| 5830 | break; | ||
| 5831 | } | ||
| 5832 | |||
| 5833 | cond_resched(); | ||
| 5834 | } | ||
| 5835 | |||
| 5836 | return ret; | ||
| 5837 | } | ||
| 5838 | |||
| 5777 | static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | 5839 | static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, |
| 5778 | struct buffer_head *bh_result, int create) | 5840 | struct buffer_head *bh_result, int create) |
| 5779 | { | 5841 | { |
| 5780 | struct extent_map *em; | 5842 | struct extent_map *em; |
| 5781 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5843 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5844 | struct extent_state *cached_state = NULL; | ||
| 5782 | u64 start = iblock << inode->i_blkbits; | 5845 | u64 start = iblock << inode->i_blkbits; |
| 5846 | u64 lockstart, lockend; | ||
| 5783 | u64 len = bh_result->b_size; | 5847 | u64 len = bh_result->b_size; |
| 5784 | struct btrfs_trans_handle *trans; | 5848 | struct btrfs_trans_handle *trans; |
| 5849 | int unlock_bits = EXTENT_LOCKED; | ||
| 5850 | int ret; | ||
| 5851 | |||
| 5852 | if (create) { | ||
| 5853 | ret = btrfs_delalloc_reserve_space(inode, len); | ||
| 5854 | if (ret) | ||
| 5855 | return ret; | ||
| 5856 | unlock_bits |= EXTENT_DELALLOC | EXTENT_DIRTY; | ||
| 5857 | } else { | ||
| 5858 | len = min_t(u64, len, root->sectorsize); | ||
| 5859 | } | ||
| 5860 | |||
| 5861 | lockstart = start; | ||
| 5862 | lockend = start + len - 1; | ||
| 5863 | |||
| 5864 | /* | ||
| 5865 | * If this errors out it's because we couldn't invalidate pagecache for | ||
| 5866 | * this range and we need to fallback to buffered. | ||
| 5867 | */ | ||
| 5868 | if (lock_extent_direct(inode, lockstart, lockend, &cached_state, create)) | ||
| 5869 | return -ENOTBLK; | ||
| 5870 | |||
| 5871 | if (create) { | ||
| 5872 | ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, | ||
| 5873 | lockend, EXTENT_DELALLOC, NULL, | ||
| 5874 | &cached_state, GFP_NOFS); | ||
| 5875 | if (ret) | ||
| 5876 | goto unlock_err; | ||
| 5877 | } | ||
| 5785 | 5878 | ||
| 5786 | em = btrfs_get_extent(inode, NULL, 0, start, len, 0); | 5879 | em = btrfs_get_extent(inode, NULL, 0, start, len, 0); |
| 5787 | if (IS_ERR(em)) | 5880 | if (IS_ERR(em)) { |
| 5788 | return PTR_ERR(em); | 5881 | ret = PTR_ERR(em); |
| 5882 | goto unlock_err; | ||
| 5883 | } | ||
| 5789 | 5884 | ||
| 5790 | /* | 5885 | /* |
| 5791 | * Ok for INLINE and COMPRESSED extents we need to fallback on buffered | 5886 | * Ok for INLINE and COMPRESSED extents we need to fallback on buffered |
| @@ -5804,17 +5899,16 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
| 5804 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) || | 5899 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) || |
| 5805 | em->block_start == EXTENT_MAP_INLINE) { | 5900 | em->block_start == EXTENT_MAP_INLINE) { |
| 5806 | free_extent_map(em); | 5901 | free_extent_map(em); |
| 5807 | return -ENOTBLK; | 5902 | ret = -ENOTBLK; |
| 5903 | goto unlock_err; | ||
| 5808 | } | 5904 | } |
| 5809 | 5905 | ||
| 5810 | /* Just a good old fashioned hole, return */ | 5906 | /* Just a good old fashioned hole, return */ |
| 5811 | if (!create && (em->block_start == EXTENT_MAP_HOLE || | 5907 | if (!create && (em->block_start == EXTENT_MAP_HOLE || |
| 5812 | test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 5908 | test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
| 5813 | free_extent_map(em); | 5909 | free_extent_map(em); |
| 5814 | /* DIO will do one hole at a time, so just unlock a sector */ | 5910 | ret = 0; |
| 5815 | unlock_extent(&BTRFS_I(inode)->io_tree, start, | 5911 | goto unlock_err; |
| 5816 | start + root->sectorsize - 1); | ||
| 5817 | return 0; | ||
| 5818 | } | 5912 | } |
| 5819 | 5913 | ||
| 5820 | /* | 5914 | /* |
| @@ -5827,8 +5921,9 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
| 5827 | * | 5921 | * |
| 5828 | */ | 5922 | */ |
| 5829 | if (!create) { | 5923 | if (!create) { |
| 5830 | len = em->len - (start - em->start); | 5924 | len = min(len, em->len - (start - em->start)); |
| 5831 | goto map; | 5925 | lockstart = start + len; |
| 5926 | goto unlock; | ||
| 5832 | } | 5927 | } |
| 5833 | 5928 | ||
| 5834 | if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) || | 5929 | if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) || |
| @@ -5860,7 +5955,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
| 5860 | btrfs_end_transaction(trans, root); | 5955 | btrfs_end_transaction(trans, root); |
| 5861 | if (ret) { | 5956 | if (ret) { |
| 5862 | free_extent_map(em); | 5957 | free_extent_map(em); |
| 5863 | return ret; | 5958 | goto unlock_err; |
| 5864 | } | 5959 | } |
| 5865 | goto unlock; | 5960 | goto unlock; |
| 5866 | } | 5961 | } |
| @@ -5873,14 +5968,12 @@ must_cow: | |||
| 5873 | */ | 5968 | */ |
| 5874 | len = bh_result->b_size; | 5969 | len = bh_result->b_size; |
| 5875 | em = btrfs_new_extent_direct(inode, em, start, len); | 5970 | em = btrfs_new_extent_direct(inode, em, start, len); |
| 5876 | if (IS_ERR(em)) | 5971 | if (IS_ERR(em)) { |
| 5877 | return PTR_ERR(em); | 5972 | ret = PTR_ERR(em); |
| 5973 | goto unlock_err; | ||
| 5974 | } | ||
| 5878 | len = min(len, em->len - (start - em->start)); | 5975 | len = min(len, em->len - (start - em->start)); |
| 5879 | unlock: | 5976 | unlock: |
| 5880 | clear_extent_bit(&BTRFS_I(inode)->io_tree, start, start + len - 1, | ||
| 5881 | EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DIRTY, 1, | ||
| 5882 | 0, NULL, GFP_NOFS); | ||
| 5883 | map: | ||
| 5884 | bh_result->b_blocknr = (em->block_start + (start - em->start)) >> | 5977 | bh_result->b_blocknr = (em->block_start + (start - em->start)) >> |
| 5885 | inode->i_blkbits; | 5978 | inode->i_blkbits; |
| 5886 | bh_result->b_size = len; | 5979 | bh_result->b_size = len; |
| @@ -5898,9 +5991,44 @@ map: | |||
| 5898 | i_size_write(inode, start + len); | 5991 | i_size_write(inode, start + len); |
| 5899 | } | 5992 | } |
| 5900 | 5993 | ||
| 5994 | /* | ||
| 5995 | * In the case of write we need to clear and unlock the entire range, | ||
| 5996 | * in the case of read we need to unlock only the end area that we | ||
| 5997 | * aren't using if there is any left over space. | ||
| 5998 | */ | ||
| 5999 | if (lockstart < lockend) { | ||
| 6000 | if (create && len < lockend - lockstart) { | ||
| 6001 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, | ||
| 6002 | lockstart + len - 1, unlock_bits, 1, 0, | ||
| 6003 | &cached_state, GFP_NOFS); | ||
| 6004 | /* | ||
| 6005 | * Beside unlock, we also need to cleanup reserved space | ||
| 6006 | * for the left range by attaching EXTENT_DO_ACCOUNTING. | ||
| 6007 | */ | ||
| 6008 | clear_extent_bit(&BTRFS_I(inode)->io_tree, | ||
| 6009 | lockstart + len, lockend, | ||
| 6010 | unlock_bits | EXTENT_DO_ACCOUNTING, | ||
| 6011 | 1, 0, NULL, GFP_NOFS); | ||
| 6012 | } else { | ||
| 6013 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, | ||
| 6014 | lockend, unlock_bits, 1, 0, | ||
| 6015 | &cached_state, GFP_NOFS); | ||
| 6016 | } | ||
| 6017 | } else { | ||
| 6018 | free_extent_state(cached_state); | ||
| 6019 | } | ||
| 6020 | |||
| 5901 | free_extent_map(em); | 6021 | free_extent_map(em); |
| 5902 | 6022 | ||
| 5903 | return 0; | 6023 | return 0; |
| 6024 | |||
| 6025 | unlock_err: | ||
| 6026 | if (create) | ||
| 6027 | unlock_bits |= EXTENT_DO_ACCOUNTING; | ||
| 6028 | |||
| 6029 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 6030 | unlock_bits, 1, 0, &cached_state, GFP_NOFS); | ||
| 6031 | return ret; | ||
| 5904 | } | 6032 | } |
| 5905 | 6033 | ||
| 5906 | struct btrfs_dio_private { | 6034 | struct btrfs_dio_private { |
| @@ -5908,7 +6036,6 @@ struct btrfs_dio_private { | |||
| 5908 | u64 logical_offset; | 6036 | u64 logical_offset; |
| 5909 | u64 disk_bytenr; | 6037 | u64 disk_bytenr; |
| 5910 | u64 bytes; | 6038 | u64 bytes; |
| 5911 | u32 *csums; | ||
| 5912 | void *private; | 6039 | void *private; |
| 5913 | 6040 | ||
| 5914 | /* number of bios pending for this dio */ | 6041 | /* number of bios pending for this dio */ |
| @@ -5928,7 +6055,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) | |||
| 5928 | struct inode *inode = dip->inode; | 6055 | struct inode *inode = dip->inode; |
| 5929 | struct btrfs_root *root = BTRFS_I(inode)->root; | 6056 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5930 | u64 start; | 6057 | u64 start; |
| 5931 | u32 *private = dip->csums; | ||
| 5932 | 6058 | ||
| 5933 | start = dip->logical_offset; | 6059 | start = dip->logical_offset; |
| 5934 | do { | 6060 | do { |
| @@ -5936,8 +6062,12 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) | |||
| 5936 | struct page *page = bvec->bv_page; | 6062 | struct page *page = bvec->bv_page; |
| 5937 | char *kaddr; | 6063 | char *kaddr; |
| 5938 | u32 csum = ~(u32)0; | 6064 | u32 csum = ~(u32)0; |
| 6065 | u64 private = ~(u32)0; | ||
| 5939 | unsigned long flags; | 6066 | unsigned long flags; |
| 5940 | 6067 | ||
| 6068 | if (get_state_private(&BTRFS_I(inode)->io_tree, | ||
| 6069 | start, &private)) | ||
| 6070 | goto failed; | ||
| 5941 | local_irq_save(flags); | 6071 | local_irq_save(flags); |
| 5942 | kaddr = kmap_atomic(page); | 6072 | kaddr = kmap_atomic(page); |
| 5943 | csum = btrfs_csum_data(root, kaddr + bvec->bv_offset, | 6073 | csum = btrfs_csum_data(root, kaddr + bvec->bv_offset, |
| @@ -5947,18 +6077,18 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) | |||
| 5947 | local_irq_restore(flags); | 6077 | local_irq_restore(flags); |
| 5948 | 6078 | ||
| 5949 | flush_dcache_page(bvec->bv_page); | 6079 | flush_dcache_page(bvec->bv_page); |
| 5950 | if (csum != *private) { | 6080 | if (csum != private) { |
| 6081 | failed: | ||
| 5951 | printk(KERN_ERR "btrfs csum failed ino %llu off" | 6082 | printk(KERN_ERR "btrfs csum failed ino %llu off" |
| 5952 | " %llu csum %u private %u\n", | 6083 | " %llu csum %u private %u\n", |
| 5953 | (unsigned long long)btrfs_ino(inode), | 6084 | (unsigned long long)btrfs_ino(inode), |
| 5954 | (unsigned long long)start, | 6085 | (unsigned long long)start, |
| 5955 | csum, *private); | 6086 | csum, (unsigned)private); |
| 5956 | err = -EIO; | 6087 | err = -EIO; |
| 5957 | } | 6088 | } |
| 5958 | } | 6089 | } |
| 5959 | 6090 | ||
| 5960 | start += bvec->bv_len; | 6091 | start += bvec->bv_len; |
| 5961 | private++; | ||
| 5962 | bvec++; | 6092 | bvec++; |
| 5963 | } while (bvec <= bvec_end); | 6093 | } while (bvec <= bvec_end); |
| 5964 | 6094 | ||
| @@ -5966,7 +6096,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) | |||
| 5966 | dip->logical_offset + dip->bytes - 1); | 6096 | dip->logical_offset + dip->bytes - 1); |
| 5967 | bio->bi_private = dip->private; | 6097 | bio->bi_private = dip->private; |
| 5968 | 6098 | ||
| 5969 | kfree(dip->csums); | ||
| 5970 | kfree(dip); | 6099 | kfree(dip); |
| 5971 | 6100 | ||
| 5972 | /* If we had a csum failure make sure to clear the uptodate flag */ | 6101 | /* If we had a csum failure make sure to clear the uptodate flag */ |
| @@ -6072,7 +6201,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | |||
| 6072 | 6201 | ||
| 6073 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 6202 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, |
| 6074 | int rw, u64 file_offset, int skip_sum, | 6203 | int rw, u64 file_offset, int skip_sum, |
| 6075 | u32 *csums, int async_submit) | 6204 | int async_submit) |
| 6076 | { | 6205 | { |
| 6077 | int write = rw & REQ_WRITE; | 6206 | int write = rw & REQ_WRITE; |
| 6078 | struct btrfs_root *root = BTRFS_I(inode)->root; | 6207 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| @@ -6105,8 +6234,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
| 6105 | if (ret) | 6234 | if (ret) |
| 6106 | goto err; | 6235 | goto err; |
| 6107 | } else if (!skip_sum) { | 6236 | } else if (!skip_sum) { |
| 6108 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, | 6237 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, file_offset); |
| 6109 | file_offset, csums); | ||
| 6110 | if (ret) | 6238 | if (ret) |
| 6111 | goto err; | 6239 | goto err; |
| 6112 | } | 6240 | } |
| @@ -6132,10 +6260,8 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 6132 | u64 submit_len = 0; | 6260 | u64 submit_len = 0; |
| 6133 | u64 map_length; | 6261 | u64 map_length; |
| 6134 | int nr_pages = 0; | 6262 | int nr_pages = 0; |
| 6135 | u32 *csums = dip->csums; | ||
| 6136 | int ret = 0; | 6263 | int ret = 0; |
| 6137 | int async_submit = 0; | 6264 | int async_submit = 0; |
| 6138 | int write = rw & REQ_WRITE; | ||
| 6139 | 6265 | ||
| 6140 | map_length = orig_bio->bi_size; | 6266 | map_length = orig_bio->bi_size; |
| 6141 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | 6267 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, |
| @@ -6171,16 +6297,13 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 6171 | atomic_inc(&dip->pending_bios); | 6297 | atomic_inc(&dip->pending_bios); |
| 6172 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | 6298 | ret = __btrfs_submit_dio_bio(bio, inode, rw, |
| 6173 | file_offset, skip_sum, | 6299 | file_offset, skip_sum, |
| 6174 | csums, async_submit); | 6300 | async_submit); |
| 6175 | if (ret) { | 6301 | if (ret) { |
| 6176 | bio_put(bio); | 6302 | bio_put(bio); |
| 6177 | atomic_dec(&dip->pending_bios); | 6303 | atomic_dec(&dip->pending_bios); |
| 6178 | goto out_err; | 6304 | goto out_err; |
| 6179 | } | 6305 | } |
| 6180 | 6306 | ||
| 6181 | /* Write's use the ordered csums */ | ||
| 6182 | if (!write && !skip_sum) | ||
| 6183 | csums = csums + nr_pages; | ||
| 6184 | start_sector += submit_len >> 9; | 6307 | start_sector += submit_len >> 9; |
| 6185 | file_offset += submit_len; | 6308 | file_offset += submit_len; |
| 6186 | 6309 | ||
| @@ -6210,7 +6333,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
| 6210 | 6333 | ||
| 6211 | submit: | 6334 | submit: |
| 6212 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | 6335 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, |
| 6213 | csums, async_submit); | 6336 | async_submit); |
| 6214 | if (!ret) | 6337 | if (!ret) |
| 6215 | return 0; | 6338 | return 0; |
| 6216 | 6339 | ||
| @@ -6246,17 +6369,6 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | |||
| 6246 | ret = -ENOMEM; | 6369 | ret = -ENOMEM; |
| 6247 | goto free_ordered; | 6370 | goto free_ordered; |
| 6248 | } | 6371 | } |
| 6249 | dip->csums = NULL; | ||
| 6250 | |||
| 6251 | /* Write's use the ordered csum stuff, so we don't need dip->csums */ | ||
| 6252 | if (!write && !skip_sum) { | ||
| 6253 | dip->csums = kmalloc(sizeof(u32) * bio->bi_vcnt, GFP_NOFS); | ||
| 6254 | if (!dip->csums) { | ||
| 6255 | kfree(dip); | ||
| 6256 | ret = -ENOMEM; | ||
| 6257 | goto free_ordered; | ||
| 6258 | } | ||
| 6259 | } | ||
| 6260 | 6372 | ||
| 6261 | dip->private = bio->bi_private; | 6373 | dip->private = bio->bi_private; |
| 6262 | dip->inode = inode; | 6374 | dip->inode = inode; |
| @@ -6341,132 +6453,22 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
| 6341 | out: | 6453 | out: |
| 6342 | return retval; | 6454 | return retval; |
| 6343 | } | 6455 | } |
| 6456 | |||
| 6344 | static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | 6457 | static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, |
| 6345 | const struct iovec *iov, loff_t offset, | 6458 | const struct iovec *iov, loff_t offset, |
| 6346 | unsigned long nr_segs) | 6459 | unsigned long nr_segs) |
| 6347 | { | 6460 | { |
| 6348 | struct file *file = iocb->ki_filp; | 6461 | struct file *file = iocb->ki_filp; |
| 6349 | struct inode *inode = file->f_mapping->host; | 6462 | struct inode *inode = file->f_mapping->host; |
| 6350 | struct btrfs_ordered_extent *ordered; | ||
| 6351 | struct extent_state *cached_state = NULL; | ||
| 6352 | u64 lockstart, lockend; | ||
| 6353 | ssize_t ret; | ||
| 6354 | int writing = rw & WRITE; | ||
| 6355 | int write_bits = 0; | ||
| 6356 | size_t count = iov_length(iov, nr_segs); | ||
| 6357 | 6463 | ||
| 6358 | if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, | 6464 | if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, |
| 6359 | offset, nr_segs)) { | 6465 | offset, nr_segs)) |
| 6360 | return 0; | 6466 | return 0; |
| 6361 | } | ||
| 6362 | |||
| 6363 | lockstart = offset; | ||
| 6364 | lockend = offset + count - 1; | ||
| 6365 | |||
| 6366 | if (writing) { | ||
| 6367 | ret = btrfs_delalloc_reserve_space(inode, count); | ||
| 6368 | if (ret) | ||
| 6369 | goto out; | ||
| 6370 | } | ||
| 6371 | |||
| 6372 | while (1) { | ||
| 6373 | lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 6374 | 0, &cached_state); | ||
| 6375 | /* | ||
| 6376 | * We're concerned with the entire range that we're going to be | ||
| 6377 | * doing DIO to, so we need to make sure theres no ordered | ||
| 6378 | * extents in this range. | ||
| 6379 | */ | ||
| 6380 | ordered = btrfs_lookup_ordered_range(inode, lockstart, | ||
| 6381 | lockend - lockstart + 1); | ||
| 6382 | |||
| 6383 | /* | ||
| 6384 | * We need to make sure there are no buffered pages in this | ||
| 6385 | * range either, we could have raced between the invalidate in | ||
| 6386 | * generic_file_direct_write and locking the extent. The | ||
| 6387 | * invalidate needs to happen so that reads after a write do not | ||
| 6388 | * get stale data. | ||
| 6389 | */ | ||
| 6390 | if (!ordered && (!writing || | ||
| 6391 | !test_range_bit(&BTRFS_I(inode)->io_tree, | ||
| 6392 | lockstart, lockend, EXTENT_UPTODATE, 0, | ||
| 6393 | cached_state))) | ||
| 6394 | break; | ||
| 6395 | |||
| 6396 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 6397 | &cached_state, GFP_NOFS); | ||
| 6398 | |||
| 6399 | if (ordered) { | ||
| 6400 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
| 6401 | btrfs_put_ordered_extent(ordered); | ||
| 6402 | } else { | ||
| 6403 | /* Screw you mmap */ | ||
| 6404 | ret = filemap_write_and_wait_range(file->f_mapping, | ||
| 6405 | lockstart, | ||
| 6406 | lockend); | ||
| 6407 | if (ret) | ||
| 6408 | goto out; | ||
| 6409 | |||
| 6410 | /* | ||
| 6411 | * If we found a page that couldn't be invalidated just | ||
| 6412 | * fall back to buffered. | ||
| 6413 | */ | ||
| 6414 | ret = invalidate_inode_pages2_range(file->f_mapping, | ||
| 6415 | lockstart >> PAGE_CACHE_SHIFT, | ||
| 6416 | lockend >> PAGE_CACHE_SHIFT); | ||
| 6417 | if (ret) { | ||
| 6418 | if (ret == -EBUSY) | ||
| 6419 | ret = 0; | ||
| 6420 | goto out; | ||
| 6421 | } | ||
| 6422 | } | ||
| 6423 | |||
| 6424 | cond_resched(); | ||
| 6425 | } | ||
| 6426 | 6467 | ||
| 6427 | /* | 6468 | return __blockdev_direct_IO(rw, iocb, inode, |
| 6428 | * we don't use btrfs_set_extent_delalloc because we don't want | ||
| 6429 | * the dirty or uptodate bits | ||
| 6430 | */ | ||
| 6431 | if (writing) { | ||
| 6432 | write_bits = EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING; | ||
| 6433 | ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 6434 | EXTENT_DELALLOC, NULL, &cached_state, | ||
| 6435 | GFP_NOFS); | ||
| 6436 | if (ret) { | ||
| 6437 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, | ||
| 6438 | lockend, EXTENT_LOCKED | write_bits, | ||
| 6439 | 1, 0, &cached_state, GFP_NOFS); | ||
| 6440 | goto out; | ||
| 6441 | } | ||
| 6442 | } | ||
| 6443 | |||
| 6444 | free_extent_state(cached_state); | ||
| 6445 | cached_state = NULL; | ||
| 6446 | |||
| 6447 | ret = __blockdev_direct_IO(rw, iocb, inode, | ||
| 6448 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, | 6469 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, |
| 6449 | iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, | 6470 | iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, |
| 6450 | btrfs_submit_direct, 0); | 6471 | btrfs_submit_direct, 0); |
| 6451 | |||
| 6452 | if (ret < 0 && ret != -EIOCBQUEUED) { | ||
| 6453 | clear_extent_bit(&BTRFS_I(inode)->io_tree, offset, | ||
| 6454 | offset + iov_length(iov, nr_segs) - 1, | ||
| 6455 | EXTENT_LOCKED | write_bits, 1, 0, | ||
| 6456 | &cached_state, GFP_NOFS); | ||
| 6457 | } else if (ret >= 0 && ret < iov_length(iov, nr_segs)) { | ||
| 6458 | /* | ||
| 6459 | * We're falling back to buffered, unlock the section we didn't | ||
| 6460 | * do IO on. | ||
| 6461 | */ | ||
| 6462 | clear_extent_bit(&BTRFS_I(inode)->io_tree, offset + ret, | ||
| 6463 | offset + iov_length(iov, nr_segs) - 1, | ||
| 6464 | EXTENT_LOCKED | write_bits, 1, 0, | ||
| 6465 | &cached_state, GFP_NOFS); | ||
| 6466 | } | ||
| 6467 | out: | ||
| 6468 | free_extent_state(cached_state); | ||
| 6469 | return ret; | ||
| 6470 | } | 6472 | } |
| 6471 | 6473 | ||
| 6472 | static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 6474 | static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7bb755677a22..9df50fa8a078 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -424,7 +424,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 424 | uuid_le_gen(&new_uuid); | 424 | uuid_le_gen(&new_uuid); |
| 425 | memcpy(root_item.uuid, new_uuid.b, BTRFS_UUID_SIZE); | 425 | memcpy(root_item.uuid, new_uuid.b, BTRFS_UUID_SIZE); |
| 426 | root_item.otime.sec = cpu_to_le64(cur_time.tv_sec); | 426 | root_item.otime.sec = cpu_to_le64(cur_time.tv_sec); |
| 427 | root_item.otime.nsec = cpu_to_le64(cur_time.tv_nsec); | 427 | root_item.otime.nsec = cpu_to_le32(cur_time.tv_nsec); |
| 428 | root_item.ctime = root_item.otime; | 428 | root_item.ctime = root_item.otime; |
| 429 | btrfs_set_root_ctransid(&root_item, trans->transid); | 429 | btrfs_set_root_ctransid(&root_item, trans->transid); |
| 430 | btrfs_set_root_otransid(&root_item, trans->transid); | 430 | btrfs_set_root_otransid(&root_item, trans->transid); |
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index a44eff074805..2a1762c66041 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
| @@ -67,7 +67,7 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) | |||
| 67 | { | 67 | { |
| 68 | if (eb->lock_nested) { | 68 | if (eb->lock_nested) { |
| 69 | read_lock(&eb->lock); | 69 | read_lock(&eb->lock); |
| 70 | if (&eb->lock_nested && current->pid == eb->lock_owner) { | 70 | if (eb->lock_nested && current->pid == eb->lock_owner) { |
| 71 | read_unlock(&eb->lock); | 71 | read_unlock(&eb->lock); |
| 72 | return; | 72 | return; |
| 73 | } | 73 | } |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index bc424ae5a81a..38b42e7bc91d 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
| @@ -1364,13 +1364,17 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |||
| 1364 | spin_lock(&fs_info->qgroup_lock); | 1364 | spin_lock(&fs_info->qgroup_lock); |
| 1365 | 1365 | ||
| 1366 | dstgroup = add_qgroup_rb(fs_info, objectid); | 1366 | dstgroup = add_qgroup_rb(fs_info, objectid); |
| 1367 | if (!dstgroup) | 1367 | if (IS_ERR(dstgroup)) { |
| 1368 | ret = PTR_ERR(dstgroup); | ||
| 1368 | goto unlock; | 1369 | goto unlock; |
| 1370 | } | ||
| 1369 | 1371 | ||
| 1370 | if (srcid) { | 1372 | if (srcid) { |
| 1371 | srcgroup = find_qgroup_rb(fs_info, srcid); | 1373 | srcgroup = find_qgroup_rb(fs_info, srcid); |
| 1372 | if (!srcgroup) | 1374 | if (!srcgroup) { |
| 1375 | ret = -EINVAL; | ||
| 1373 | goto unlock; | 1376 | goto unlock; |
| 1377 | } | ||
| 1374 | dstgroup->rfer = srcgroup->rfer - level_size; | 1378 | dstgroup->rfer = srcgroup->rfer - level_size; |
| 1375 | dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size; | 1379 | dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size; |
| 1376 | srcgroup->excl = level_size; | 1380 | srcgroup->excl = level_size; |
| @@ -1379,8 +1383,10 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |||
| 1379 | qgroup_dirty(fs_info, srcgroup); | 1383 | qgroup_dirty(fs_info, srcgroup); |
| 1380 | } | 1384 | } |
| 1381 | 1385 | ||
| 1382 | if (!inherit) | 1386 | if (!inherit) { |
| 1387 | ret = -EINVAL; | ||
| 1383 | goto unlock; | 1388 | goto unlock; |
| 1389 | } | ||
| 1384 | 1390 | ||
| 1385 | i_qgroups = (u64 *)(inherit + 1); | 1391 | i_qgroups = (u64 *)(inherit + 1); |
| 1386 | for (i = 0; i < inherit->num_qgroups; ++i) { | 1392 | for (i = 0; i < inherit->num_qgroups; ++i) { |
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 6bb465cca20f..10d8e4d88071 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
| @@ -544,8 +544,8 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans, | |||
| 544 | struct timespec ct = CURRENT_TIME; | 544 | struct timespec ct = CURRENT_TIME; |
| 545 | 545 | ||
| 546 | spin_lock(&root->root_times_lock); | 546 | spin_lock(&root->root_times_lock); |
| 547 | item->ctransid = trans->transid; | 547 | item->ctransid = cpu_to_le64(trans->transid); |
| 548 | item->ctime.sec = cpu_to_le64(ct.tv_sec); | 548 | item->ctime.sec = cpu_to_le64(ct.tv_sec); |
| 549 | item->ctime.nsec = cpu_to_le64(ct.tv_nsec); | 549 | item->ctime.nsec = cpu_to_le32(ct.tv_nsec); |
| 550 | spin_unlock(&root->root_times_lock); | 550 | spin_unlock(&root->root_times_lock); |
| 551 | } | 551 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f2eb24c477a3..83d6f9f9c220 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -838,7 +838,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
| 838 | struct btrfs_trans_handle *trans; | 838 | struct btrfs_trans_handle *trans; |
| 839 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); | 839 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
| 840 | struct btrfs_root *root = fs_info->tree_root; | 840 | struct btrfs_root *root = fs_info->tree_root; |
| 841 | int ret; | ||
| 842 | 841 | ||
| 843 | trace_btrfs_sync_fs(wait); | 842 | trace_btrfs_sync_fs(wait); |
| 844 | 843 | ||
| @@ -849,11 +848,17 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
| 849 | 848 | ||
| 850 | btrfs_wait_ordered_extents(root, 0, 0); | 849 | btrfs_wait_ordered_extents(root, 0, 0); |
| 851 | 850 | ||
| 852 | trans = btrfs_start_transaction(root, 0); | 851 | spin_lock(&fs_info->trans_lock); |
| 852 | if (!fs_info->running_transaction) { | ||
| 853 | spin_unlock(&fs_info->trans_lock); | ||
| 854 | return 0; | ||
| 855 | } | ||
| 856 | spin_unlock(&fs_info->trans_lock); | ||
| 857 | |||
| 858 | trans = btrfs_join_transaction(root); | ||
| 853 | if (IS_ERR(trans)) | 859 | if (IS_ERR(trans)) |
| 854 | return PTR_ERR(trans); | 860 | return PTR_ERR(trans); |
| 855 | ret = btrfs_commit_transaction(trans, root); | 861 | return btrfs_commit_transaction(trans, root); |
| 856 | return ret; | ||
| 857 | } | 862 | } |
| 858 | 863 | ||
| 859 | static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) | 864 | static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) |
| @@ -1530,6 +1535,8 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root) | |||
| 1530 | while (cur_devices) { | 1535 | while (cur_devices) { |
| 1531 | head = &cur_devices->devices; | 1536 | head = &cur_devices->devices; |
| 1532 | list_for_each_entry(dev, head, dev_list) { | 1537 | list_for_each_entry(dev, head, dev_list) { |
| 1538 | if (dev->missing) | ||
| 1539 | continue; | ||
| 1533 | if (!first_dev || dev->devid < first_dev->devid) | 1540 | if (!first_dev || dev->devid < first_dev->devid) |
| 1534 | first_dev = dev; | 1541 | first_dev = dev; |
| 1535 | } | 1542 | } |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 17be3dedacba..27c26004e050 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -1031,6 +1031,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 1031 | 1031 | ||
| 1032 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 1032 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
| 1033 | dentry->d_name.len * 2); | 1033 | dentry->d_name.len * 2); |
| 1034 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; | ||
| 1034 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 1035 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
| 1035 | if (ret) | 1036 | if (ret) |
| 1036 | goto abort_trans_dput; | 1037 | goto abort_trans_dput; |
| @@ -1066,7 +1067,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 1066 | memcpy(new_root_item->parent_uuid, root->root_item.uuid, | 1067 | memcpy(new_root_item->parent_uuid, root->root_item.uuid, |
| 1067 | BTRFS_UUID_SIZE); | 1068 | BTRFS_UUID_SIZE); |
| 1068 | new_root_item->otime.sec = cpu_to_le64(cur_time.tv_sec); | 1069 | new_root_item->otime.sec = cpu_to_le64(cur_time.tv_sec); |
| 1069 | new_root_item->otime.nsec = cpu_to_le64(cur_time.tv_nsec); | 1070 | new_root_item->otime.nsec = cpu_to_le32(cur_time.tv_nsec); |
| 1070 | btrfs_set_root_otransid(new_root_item, trans->transid); | 1071 | btrfs_set_root_otransid(new_root_item, trans->transid); |
| 1071 | memset(&new_root_item->stime, 0, sizeof(new_root_item->stime)); | 1072 | memset(&new_root_item->stime, 0, sizeof(new_root_item->stime)); |
| 1072 | memset(&new_root_item->rtime, 0, sizeof(new_root_item->rtime)); | 1073 | memset(&new_root_item->rtime, 0, sizeof(new_root_item->rtime)); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index e86ae04abe6a..88b969aeeb71 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -227,9 +227,8 @@ loop_lock: | |||
| 227 | cur = pending; | 227 | cur = pending; |
| 228 | pending = pending->bi_next; | 228 | pending = pending->bi_next; |
| 229 | cur->bi_next = NULL; | 229 | cur->bi_next = NULL; |
| 230 | atomic_dec(&fs_info->nr_async_bios); | ||
| 231 | 230 | ||
| 232 | if (atomic_read(&fs_info->nr_async_bios) < limit && | 231 | if (atomic_dec_return(&fs_info->nr_async_bios) < limit && |
| 233 | waitqueue_active(&fs_info->async_submit_wait)) | 232 | waitqueue_active(&fs_info->async_submit_wait)) |
| 234 | wake_up(&fs_info->async_submit_wait); | 233 | wake_up(&fs_info->async_submit_wait); |
| 235 | 234 | ||
| @@ -569,9 +568,11 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
| 569 | memcpy(new_device, device, sizeof(*new_device)); | 568 | memcpy(new_device, device, sizeof(*new_device)); |
| 570 | 569 | ||
| 571 | /* Safe because we are under uuid_mutex */ | 570 | /* Safe because we are under uuid_mutex */ |
| 572 | name = rcu_string_strdup(device->name->str, GFP_NOFS); | 571 | if (device->name) { |
| 573 | BUG_ON(device->name && !name); /* -ENOMEM */ | 572 | name = rcu_string_strdup(device->name->str, GFP_NOFS); |
| 574 | rcu_assign_pointer(new_device->name, name); | 573 | BUG_ON(device->name && !name); /* -ENOMEM */ |
| 574 | rcu_assign_pointer(new_device->name, name); | ||
| 575 | } | ||
| 575 | new_device->bdev = NULL; | 576 | new_device->bdev = NULL; |
| 576 | new_device->writeable = 0; | 577 | new_device->writeable = 0; |
| 577 | new_device->in_fs_metadata = 0; | 578 | new_device->in_fs_metadata = 0; |
| @@ -4605,28 +4606,6 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
| 4605 | return ret; | 4606 | return ret; |
| 4606 | } | 4607 | } |
| 4607 | 4608 | ||
| 4608 | struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root, | ||
| 4609 | u64 logical, int mirror_num) | ||
| 4610 | { | ||
| 4611 | struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; | ||
| 4612 | int ret; | ||
| 4613 | u64 map_length = 0; | ||
| 4614 | struct btrfs_bio *bbio = NULL; | ||
| 4615 | struct btrfs_device *device; | ||
| 4616 | |||
| 4617 | BUG_ON(mirror_num == 0); | ||
| 4618 | ret = btrfs_map_block(map_tree, WRITE, logical, &map_length, &bbio, | ||
| 4619 | mirror_num); | ||
| 4620 | if (ret) { | ||
| 4621 | BUG_ON(bbio != NULL); | ||
| 4622 | return NULL; | ||
| 4623 | } | ||
| 4624 | BUG_ON(mirror_num != bbio->mirror_num); | ||
| 4625 | device = bbio->stripes[mirror_num - 1].dev; | ||
| 4626 | kfree(bbio); | ||
| 4627 | return device; | ||
| 4628 | } | ||
| 4629 | |||
| 4630 | int btrfs_read_chunk_tree(struct btrfs_root *root) | 4609 | int btrfs_read_chunk_tree(struct btrfs_root *root) |
| 4631 | { | 4610 | { |
| 4632 | struct btrfs_path *path; | 4611 | struct btrfs_path *path; |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 5479325987b3..53c06af92e8d 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
| @@ -289,8 +289,6 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); | |||
| 289 | int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); | 289 | int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); |
| 290 | int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, | 290 | int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, |
| 291 | u64 *start, u64 *max_avail); | 291 | u64 *start, u64 *max_avail); |
| 292 | struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root, | ||
| 293 | u64 logical, int mirror_num); | ||
| 294 | void btrfs_dev_stat_print_on_error(struct btrfs_device *device); | 292 | void btrfs_dev_stat_print_on_error(struct btrfs_device *device); |
| 295 | void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index); | 293 | void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index); |
| 296 | int btrfs_get_dev_stats(struct btrfs_root *root, | 294 | int btrfs_get_dev_stats(struct btrfs_root *root, |
diff --git a/fs/buffer.c b/fs/buffer.c index 9f6d2e41281d..58e2e7b77372 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -914,7 +914,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head) | |||
| 914 | /* | 914 | /* |
| 915 | * Initialise the state of a blockdev page's buffers. | 915 | * Initialise the state of a blockdev page's buffers. |
| 916 | */ | 916 | */ |
| 917 | static void | 917 | static sector_t |
| 918 | init_page_buffers(struct page *page, struct block_device *bdev, | 918 | init_page_buffers(struct page *page, struct block_device *bdev, |
| 919 | sector_t block, int size) | 919 | sector_t block, int size) |
| 920 | { | 920 | { |
| @@ -936,33 +936,41 @@ init_page_buffers(struct page *page, struct block_device *bdev, | |||
| 936 | block++; | 936 | block++; |
| 937 | bh = bh->b_this_page; | 937 | bh = bh->b_this_page; |
| 938 | } while (bh != head); | 938 | } while (bh != head); |
| 939 | |||
| 940 | /* | ||
| 941 | * Caller needs to validate requested block against end of device. | ||
| 942 | */ | ||
| 943 | return end_block; | ||
| 939 | } | 944 | } |
| 940 | 945 | ||
| 941 | /* | 946 | /* |
| 942 | * Create the page-cache page that contains the requested block. | 947 | * Create the page-cache page that contains the requested block. |
| 943 | * | 948 | * |
| 944 | * This is user purely for blockdev mappings. | 949 | * This is used purely for blockdev mappings. |
| 945 | */ | 950 | */ |
| 946 | static struct page * | 951 | static int |
| 947 | grow_dev_page(struct block_device *bdev, sector_t block, | 952 | grow_dev_page(struct block_device *bdev, sector_t block, |
| 948 | pgoff_t index, int size) | 953 | pgoff_t index, int size, int sizebits) |
| 949 | { | 954 | { |
| 950 | struct inode *inode = bdev->bd_inode; | 955 | struct inode *inode = bdev->bd_inode; |
| 951 | struct page *page; | 956 | struct page *page; |
| 952 | struct buffer_head *bh; | 957 | struct buffer_head *bh; |
| 958 | sector_t end_block; | ||
| 959 | int ret = 0; /* Will call free_more_memory() */ | ||
| 953 | 960 | ||
| 954 | page = find_or_create_page(inode->i_mapping, index, | 961 | page = find_or_create_page(inode->i_mapping, index, |
| 955 | (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE); | 962 | (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE); |
| 956 | if (!page) | 963 | if (!page) |
| 957 | return NULL; | 964 | return ret; |
| 958 | 965 | ||
| 959 | BUG_ON(!PageLocked(page)); | 966 | BUG_ON(!PageLocked(page)); |
| 960 | 967 | ||
| 961 | if (page_has_buffers(page)) { | 968 | if (page_has_buffers(page)) { |
| 962 | bh = page_buffers(page); | 969 | bh = page_buffers(page); |
| 963 | if (bh->b_size == size) { | 970 | if (bh->b_size == size) { |
| 964 | init_page_buffers(page, bdev, block, size); | 971 | end_block = init_page_buffers(page, bdev, |
| 965 | return page; | 972 | index << sizebits, size); |
| 973 | goto done; | ||
| 966 | } | 974 | } |
| 967 | if (!try_to_free_buffers(page)) | 975 | if (!try_to_free_buffers(page)) |
| 968 | goto failed; | 976 | goto failed; |
| @@ -982,14 +990,14 @@ grow_dev_page(struct block_device *bdev, sector_t block, | |||
| 982 | */ | 990 | */ |
| 983 | spin_lock(&inode->i_mapping->private_lock); | 991 | spin_lock(&inode->i_mapping->private_lock); |
| 984 | link_dev_buffers(page, bh); | 992 | link_dev_buffers(page, bh); |
| 985 | init_page_buffers(page, bdev, block, size); | 993 | end_block = init_page_buffers(page, bdev, index << sizebits, size); |
| 986 | spin_unlock(&inode->i_mapping->private_lock); | 994 | spin_unlock(&inode->i_mapping->private_lock); |
| 987 | return page; | 995 | done: |
| 988 | 996 | ret = (block < end_block) ? 1 : -ENXIO; | |
| 989 | failed: | 997 | failed: |
| 990 | unlock_page(page); | 998 | unlock_page(page); |
| 991 | page_cache_release(page); | 999 | page_cache_release(page); |
| 992 | return NULL; | 1000 | return ret; |
| 993 | } | 1001 | } |
| 994 | 1002 | ||
| 995 | /* | 1003 | /* |
| @@ -999,7 +1007,6 @@ failed: | |||
| 999 | static int | 1007 | static int |
| 1000 | grow_buffers(struct block_device *bdev, sector_t block, int size) | 1008 | grow_buffers(struct block_device *bdev, sector_t block, int size) |
| 1001 | { | 1009 | { |
| 1002 | struct page *page; | ||
| 1003 | pgoff_t index; | 1010 | pgoff_t index; |
| 1004 | int sizebits; | 1011 | int sizebits; |
| 1005 | 1012 | ||
| @@ -1023,22 +1030,14 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) | |||
| 1023 | bdevname(bdev, b)); | 1030 | bdevname(bdev, b)); |
| 1024 | return -EIO; | 1031 | return -EIO; |
| 1025 | } | 1032 | } |
| 1026 | block = index << sizebits; | 1033 | |
| 1027 | /* Create a page with the proper size buffers.. */ | 1034 | /* Create a page with the proper size buffers.. */ |
| 1028 | page = grow_dev_page(bdev, block, index, size); | 1035 | return grow_dev_page(bdev, block, index, size, sizebits); |
| 1029 | if (!page) | ||
| 1030 | return 0; | ||
| 1031 | unlock_page(page); | ||
| 1032 | page_cache_release(page); | ||
| 1033 | return 1; | ||
| 1034 | } | 1036 | } |
| 1035 | 1037 | ||
| 1036 | static struct buffer_head * | 1038 | static struct buffer_head * |
| 1037 | __getblk_slow(struct block_device *bdev, sector_t block, int size) | 1039 | __getblk_slow(struct block_device *bdev, sector_t block, int size) |
| 1038 | { | 1040 | { |
| 1039 | int ret; | ||
| 1040 | struct buffer_head *bh; | ||
| 1041 | |||
| 1042 | /* Size must be multiple of hard sectorsize */ | 1041 | /* Size must be multiple of hard sectorsize */ |
| 1043 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || | 1042 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || |
| 1044 | (size < 512 || size > PAGE_SIZE))) { | 1043 | (size < 512 || size > PAGE_SIZE))) { |
| @@ -1051,21 +1050,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) | |||
| 1051 | return NULL; | 1050 | return NULL; |
| 1052 | } | 1051 | } |
| 1053 | 1052 | ||
| 1054 | retry: | 1053 | for (;;) { |
| 1055 | bh = __find_get_block(bdev, block, size); | 1054 | struct buffer_head *bh; |
| 1056 | if (bh) | 1055 | int ret; |
| 1057 | return bh; | ||
| 1058 | 1056 | ||
| 1059 | ret = grow_buffers(bdev, block, size); | ||
| 1060 | if (ret == 0) { | ||
| 1061 | free_more_memory(); | ||
| 1062 | goto retry; | ||
| 1063 | } else if (ret > 0) { | ||
| 1064 | bh = __find_get_block(bdev, block, size); | 1057 | bh = __find_get_block(bdev, block, size); |
| 1065 | if (bh) | 1058 | if (bh) |
| 1066 | return bh; | 1059 | return bh; |
| 1060 | |||
| 1061 | ret = grow_buffers(bdev, block, size); | ||
| 1062 | if (ret < 0) | ||
| 1063 | return NULL; | ||
| 1064 | if (ret == 0) | ||
| 1065 | free_more_memory(); | ||
| 1067 | } | 1066 | } |
| 1068 | return NULL; | ||
| 1069 | } | 1067 | } |
| 1070 | 1068 | ||
| 1071 | /* | 1069 | /* |
| @@ -1321,10 +1319,6 @@ EXPORT_SYMBOL(__find_get_block); | |||
| 1321 | * which corresponds to the passed block_device, block and size. The | 1319 | * which corresponds to the passed block_device, block and size. The |
| 1322 | * returned buffer has its reference count incremented. | 1320 | * returned buffer has its reference count incremented. |
| 1323 | * | 1321 | * |
| 1324 | * __getblk() cannot fail - it just keeps trying. If you pass it an | ||
| 1325 | * illegal block number, __getblk() will happily return a buffer_head | ||
| 1326 | * which represents the non-existent block. Very weird. | ||
| 1327 | * | ||
| 1328 | * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers() | 1322 | * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers() |
| 1329 | * attempt is failing. FIXME, perhaps? | 1323 | * attempt is failing. FIXME, perhaps? |
| 1330 | */ | 1324 | */ |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 1faf4cb56f39..f86c720dba0e 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
| @@ -1062,6 +1062,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1062 | unsigned long user_addr; | 1062 | unsigned long user_addr; |
| 1063 | size_t bytes; | 1063 | size_t bytes; |
| 1064 | struct buffer_head map_bh = { 0, }; | 1064 | struct buffer_head map_bh = { 0, }; |
| 1065 | struct blk_plug plug; | ||
| 1065 | 1066 | ||
| 1066 | if (rw & WRITE) | 1067 | if (rw & WRITE) |
| 1067 | rw = WRITE_ODIRECT; | 1068 | rw = WRITE_ODIRECT; |
| @@ -1177,6 +1178,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1177 | PAGE_SIZE - user_addr / PAGE_SIZE); | 1178 | PAGE_SIZE - user_addr / PAGE_SIZE); |
| 1178 | } | 1179 | } |
| 1179 | 1180 | ||
| 1181 | blk_start_plug(&plug); | ||
| 1182 | |||
| 1180 | for (seg = 0; seg < nr_segs; seg++) { | 1183 | for (seg = 0; seg < nr_segs; seg++) { |
| 1181 | user_addr = (unsigned long)iov[seg].iov_base; | 1184 | user_addr = (unsigned long)iov[seg].iov_base; |
| 1182 | sdio.size += bytes = iov[seg].iov_len; | 1185 | sdio.size += bytes = iov[seg].iov_len; |
| @@ -1235,6 +1238,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1235 | if (sdio.bio) | 1238 | if (sdio.bio) |
| 1236 | dio_bio_submit(dio, &sdio); | 1239 | dio_bio_submit(dio, &sdio); |
| 1237 | 1240 | ||
| 1241 | blk_finish_plug(&plug); | ||
| 1242 | |||
| 1238 | /* | 1243 | /* |
| 1239 | * It is possible that, we return short IO due to end of file. | 1244 | * It is possible that, we return short IO due to end of file. |
| 1240 | * In that case, we need to release all the pages we got hold on. | 1245 | * In that case, we need to release all the pages we got hold on. |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 09357508ec9a..a2862339323b 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
| @@ -1113,6 +1113,11 @@ static void mark_journal_empty(journal_t *journal) | |||
| 1113 | 1113 | ||
| 1114 | BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); | 1114 | BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); |
| 1115 | spin_lock(&journal->j_state_lock); | 1115 | spin_lock(&journal->j_state_lock); |
| 1116 | /* Is it already empty? */ | ||
| 1117 | if (sb->s_start == 0) { | ||
| 1118 | spin_unlock(&journal->j_state_lock); | ||
| 1119 | return; | ||
| 1120 | } | ||
| 1116 | jbd_debug(1, "JBD: Marking journal as empty (seq %d)\n", | 1121 | jbd_debug(1, "JBD: Marking journal as empty (seq %d)\n", |
| 1117 | journal->j_tail_sequence); | 1122 | journal->j_tail_sequence); |
| 1118 | 1123 | ||
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index df0de27c2733..e784a217b500 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c | |||
| @@ -26,6 +26,7 @@ static int sync_request(struct page *page, struct block_device *bdev, int rw) | |||
| 26 | struct completion complete; | 26 | struct completion complete; |
| 27 | 27 | ||
| 28 | bio_init(&bio); | 28 | bio_init(&bio); |
| 29 | bio.bi_max_vecs = 1; | ||
| 29 | bio.bi_io_vec = &bio_vec; | 30 | bio.bi_io_vec = &bio_vec; |
| 30 | bio_vec.bv_page = page; | 31 | bio_vec.bv_page = page; |
| 31 | bio_vec.bv_len = PAGE_SIZE; | 32 | bio_vec.bv_len = PAGE_SIZE; |
| @@ -95,12 +96,11 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, | |||
| 95 | struct address_space *mapping = super->s_mapping_inode->i_mapping; | 96 | struct address_space *mapping = super->s_mapping_inode->i_mapping; |
| 96 | struct bio *bio; | 97 | struct bio *bio; |
| 97 | struct page *page; | 98 | struct page *page; |
| 98 | struct request_queue *q = bdev_get_queue(sb->s_bdev); | 99 | unsigned int max_pages; |
| 99 | unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); | ||
| 100 | int i; | 100 | int i; |
| 101 | 101 | ||
| 102 | if (max_pages > BIO_MAX_PAGES) | 102 | max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev)); |
| 103 | max_pages = BIO_MAX_PAGES; | 103 | |
| 104 | bio = bio_alloc(GFP_NOFS, max_pages); | 104 | bio = bio_alloc(GFP_NOFS, max_pages); |
| 105 | BUG_ON(!bio); | 105 | BUG_ON(!bio); |
| 106 | 106 | ||
| @@ -190,12 +190,11 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index, | |||
| 190 | { | 190 | { |
| 191 | struct logfs_super *super = logfs_super(sb); | 191 | struct logfs_super *super = logfs_super(sb); |
| 192 | struct bio *bio; | 192 | struct bio *bio; |
| 193 | struct request_queue *q = bdev_get_queue(sb->s_bdev); | 193 | unsigned int max_pages; |
| 194 | unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); | ||
| 195 | int i; | 194 | int i; |
| 196 | 195 | ||
| 197 | if (max_pages > BIO_MAX_PAGES) | 196 | max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev)); |
| 198 | max_pages = BIO_MAX_PAGES; | 197 | |
| 199 | bio = bio_alloc(GFP_NOFS, max_pages); | 198 | bio = bio_alloc(GFP_NOFS, max_pages); |
| 200 | BUG_ON(!bio); | 199 | BUG_ON(!bio); |
| 201 | 200 | ||
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index a422f42238b2..6984562738d3 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
| @@ -156,10 +156,26 @@ static void __logfs_destroy_inode(struct inode *inode) | |||
| 156 | call_rcu(&inode->i_rcu, logfs_i_callback); | 156 | call_rcu(&inode->i_rcu, logfs_i_callback); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static void __logfs_destroy_meta_inode(struct inode *inode) | ||
| 160 | { | ||
| 161 | struct logfs_inode *li = logfs_inode(inode); | ||
| 162 | BUG_ON(li->li_block); | ||
| 163 | call_rcu(&inode->i_rcu, logfs_i_callback); | ||
| 164 | } | ||
| 165 | |||
| 159 | static void logfs_destroy_inode(struct inode *inode) | 166 | static void logfs_destroy_inode(struct inode *inode) |
| 160 | { | 167 | { |
| 161 | struct logfs_inode *li = logfs_inode(inode); | 168 | struct logfs_inode *li = logfs_inode(inode); |
| 162 | 169 | ||
| 170 | if (inode->i_ino < LOGFS_RESERVED_INOS) { | ||
| 171 | /* | ||
| 172 | * The reserved inodes are never destroyed unless we are in | ||
| 173 | * unmont path. | ||
| 174 | */ | ||
| 175 | __logfs_destroy_meta_inode(inode); | ||
| 176 | return; | ||
| 177 | } | ||
| 178 | |||
| 163 | BUG_ON(list_empty(&li->li_freeing_list)); | 179 | BUG_ON(list_empty(&li->li_freeing_list)); |
| 164 | spin_lock(&logfs_inode_lock); | 180 | spin_lock(&logfs_inode_lock); |
| 165 | li->li_refcount--; | 181 | li->li_refcount--; |
| @@ -373,8 +389,8 @@ static void logfs_put_super(struct super_block *sb) | |||
| 373 | { | 389 | { |
| 374 | struct logfs_super *super = logfs_super(sb); | 390 | struct logfs_super *super = logfs_super(sb); |
| 375 | /* kill the meta-inodes */ | 391 | /* kill the meta-inodes */ |
| 376 | iput(super->s_master_inode); | ||
| 377 | iput(super->s_segfile_inode); | 392 | iput(super->s_segfile_inode); |
| 393 | iput(super->s_master_inode); | ||
| 378 | iput(super->s_mapping_inode); | 394 | iput(super->s_mapping_inode); |
| 379 | } | 395 | } |
| 380 | 396 | ||
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 1e1c369df22b..2a09b8d73989 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
| @@ -565,7 +565,7 @@ static void write_wbuf(struct super_block *sb, struct logfs_area *area, | |||
| 565 | index = ofs >> PAGE_SHIFT; | 565 | index = ofs >> PAGE_SHIFT; |
| 566 | page_ofs = ofs & (PAGE_SIZE - 1); | 566 | page_ofs = ofs & (PAGE_SIZE - 1); |
| 567 | 567 | ||
| 568 | page = find_lock_page(mapping, index); | 568 | page = find_or_create_page(mapping, index, GFP_NOFS); |
| 569 | BUG_ON(!page); | 569 | BUG_ON(!page); |
| 570 | memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize); | 570 | memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize); |
| 571 | unlock_page(page); | 571 | unlock_page(page); |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index f1cb512c5019..5be0abef603d 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
| @@ -2189,7 +2189,6 @@ void logfs_evict_inode(struct inode *inode) | |||
| 2189 | return; | 2189 | return; |
| 2190 | } | 2190 | } |
| 2191 | 2191 | ||
| 2192 | BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS); | ||
| 2193 | page = inode_to_page(inode); | 2192 | page = inode_to_page(inode); |
| 2194 | BUG_ON(!page); /* FIXME: Use emergency page */ | 2193 | BUG_ON(!page); /* FIXME: Use emergency page */ |
| 2195 | logfs_put_write_page(page); | 2194 | logfs_put_write_page(page); |
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index e28d090c98d6..038da0991794 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c | |||
| @@ -886,7 +886,7 @@ static struct logfs_area *alloc_area(struct super_block *sb) | |||
| 886 | 886 | ||
| 887 | static void map_invalidatepage(struct page *page, unsigned long l) | 887 | static void map_invalidatepage(struct page *page, unsigned long l) |
| 888 | { | 888 | { |
| 889 | BUG(); | 889 | return; |
| 890 | } | 890 | } |
| 891 | 891 | ||
| 892 | static int map_releasepage(struct page *page, gfp_t g) | 892 | static int map_releasepage(struct page *page, gfp_t g) |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index cbaf4f8bb7b7..4c7bd35b1876 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -651,12 +651,12 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c | |||
| 651 | 651 | ||
| 652 | if (clp->cl_minorversion == 0) { | 652 | if (clp->cl_minorversion == 0) { |
| 653 | if (!clp->cl_cred.cr_principal && | 653 | if (!clp->cl_cred.cr_principal && |
| 654 | (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) | 654 | (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5)) |
| 655 | return -EINVAL; | 655 | return -EINVAL; |
| 656 | args.client_name = clp->cl_cred.cr_principal; | 656 | args.client_name = clp->cl_cred.cr_principal; |
| 657 | args.prognumber = conn->cb_prog, | 657 | args.prognumber = conn->cb_prog, |
| 658 | args.protocol = XPRT_TRANSPORT_TCP; | 658 | args.protocol = XPRT_TRANSPORT_TCP; |
| 659 | args.authflavor = clp->cl_flavor; | 659 | args.authflavor = clp->cl_cred.cr_flavor; |
| 660 | clp->cl_cb_ident = conn->cb_ident; | 660 | clp->cl_cb_ident = conn->cb_ident; |
| 661 | } else { | 661 | } else { |
| 662 | if (!conn->cb_xprt) | 662 | if (!conn->cb_xprt) |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index e6173147f982..22bd0a66c356 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
| @@ -231,7 +231,6 @@ struct nfs4_client { | |||
| 231 | nfs4_verifier cl_verifier; /* generated by client */ | 231 | nfs4_verifier cl_verifier; /* generated by client */ |
| 232 | time_t cl_time; /* time of last lease renewal */ | 232 | time_t cl_time; /* time of last lease renewal */ |
| 233 | struct sockaddr_storage cl_addr; /* client ipaddress */ | 233 | struct sockaddr_storage cl_addr; /* client ipaddress */ |
| 234 | u32 cl_flavor; /* setclientid pseudoflavor */ | ||
| 235 | struct svc_cred cl_cred; /* setclientid principal */ | 234 | struct svc_cred cl_cred; /* setclientid principal */ |
| 236 | clientid_t cl_clientid; /* generated by server */ | 235 | clientid_t cl_clientid; /* generated by server */ |
| 237 | nfs4_verifier cl_confirm; /* generated by server */ | 236 | nfs4_verifier cl_confirm; /* generated by server */ |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 36a29b753c79..c495a3055e2a 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -1589,10 +1589,10 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
| 1589 | goto out; | 1589 | goto out; |
| 1590 | } | 1590 | } |
| 1591 | 1591 | ||
| 1592 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
| 1593 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1592 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
| 1594 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1593 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
| 1595 | 1594 | ||
| 1595 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
| 1596 | spin_lock(&dq_data_lock); | 1596 | spin_lock(&dq_data_lock); |
| 1597 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1597 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1598 | if (!dquots[cnt]) | 1598 | if (!dquots[cnt]) |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 4c0c7d163d15..a98b7740a0fc 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
| @@ -1334,9 +1334,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
| 1334 | else if (bitmap == 0) | 1334 | else if (bitmap == 0) |
| 1335 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; | 1335 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; |
| 1336 | 1336 | ||
| 1337 | reiserfs_write_unlock(sb); | ||
| 1338 | bh = sb_bread(sb, block); | 1337 | bh = sb_bread(sb, block); |
| 1339 | reiserfs_write_lock(sb); | ||
| 1340 | if (bh == NULL) | 1338 | if (bh == NULL) |
| 1341 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " | 1339 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " |
| 1342 | "reading failed", __func__, block); | 1340 | "reading failed", __func__, block); |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a6d4268fb6c1..855da58db145 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -76,10 +76,10 @@ void reiserfs_evict_inode(struct inode *inode) | |||
| 76 | ; | 76 | ; |
| 77 | } | 77 | } |
| 78 | out: | 78 | out: |
| 79 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
| 79 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ | 80 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ |
| 80 | dquot_drop(inode); | 81 | dquot_drop(inode); |
| 81 | inode->i_blocks = 0; | 82 | inode->i_blocks = 0; |
| 82 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
| 83 | return; | 83 | return; |
| 84 | 84 | ||
| 85 | no_delete: | 85 | no_delete: |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 8b8cc4e945f4..760de723dadb 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
| @@ -167,7 +167,7 @@ struct ubifs_global_debug_info { | |||
| 167 | #define ubifs_dbg_msg(type, fmt, ...) \ | 167 | #define ubifs_dbg_msg(type, fmt, ...) \ |
| 168 | pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__) | 168 | pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__) |
| 169 | 169 | ||
| 170 | #define DBG_KEY_BUF_LEN 32 | 170 | #define DBG_KEY_BUF_LEN 48 |
| 171 | #define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ | 171 | #define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ |
| 172 | char __tmp_key_buf[DBG_KEY_BUF_LEN]; \ | 172 | char __tmp_key_buf[DBG_KEY_BUF_LEN]; \ |
| 173 | pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__, \ | 173 | pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__, \ |
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index ce33b2beb151..8640920766ed 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c | |||
| @@ -1749,7 +1749,10 @@ int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr) | |||
| 1749 | return 0; | 1749 | return 0; |
| 1750 | 1750 | ||
| 1751 | out_err: | 1751 | out_err: |
| 1752 | ubifs_lpt_free(c, 0); | 1752 | if (wr) |
| 1753 | ubifs_lpt_free(c, 1); | ||
| 1754 | if (rd) | ||
| 1755 | ubifs_lpt_free(c, 0); | ||
| 1753 | return err; | 1756 | return err; |
| 1754 | } | 1757 | } |
| 1755 | 1758 | ||
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index c30d976b4be8..edeec499c048 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
| @@ -788,7 +788,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
| 788 | 788 | ||
| 789 | corrupted_rescan: | 789 | corrupted_rescan: |
| 790 | /* Re-scan the corrupted data with verbose messages */ | 790 | /* Re-scan the corrupted data with verbose messages */ |
| 791 | ubifs_err("corruptio %d", ret); | 791 | ubifs_err("corruption %d", ret); |
| 792 | ubifs_scan_a_node(c, buf, len, lnum, offs, 1); | 792 | ubifs_scan_a_node(c, buf, len, lnum, offs, 1); |
| 793 | corrupted: | 793 | corrupted: |
| 794 | ubifs_scanned_corruption(c, lnum, offs, buf); | 794 | ubifs_scanned_corruption(c, lnum, offs, buf); |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index eba46d4a7619..94d78fc5d4e0 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
| @@ -1026,7 +1026,6 @@ int ubifs_replay_journal(struct ubifs_info *c) | |||
| 1026 | c->replaying = 1; | 1026 | c->replaying = 1; |
| 1027 | lnum = c->ltail_lnum = c->lhead_lnum; | 1027 | lnum = c->ltail_lnum = c->lhead_lnum; |
| 1028 | 1028 | ||
| 1029 | lnum = UBIFS_LOG_LNUM; | ||
| 1030 | do { | 1029 | do { |
| 1031 | err = replay_log_leb(c, lnum, 0, c->sbuf); | 1030 | err = replay_log_leb(c, lnum, 0, c->sbuf); |
| 1032 | if (err == 1) | 1031 | if (err == 1) |
| @@ -1035,7 +1034,7 @@ int ubifs_replay_journal(struct ubifs_info *c) | |||
| 1035 | if (err) | 1034 | if (err) |
| 1036 | goto out; | 1035 | goto out; |
| 1037 | lnum = ubifs_next_log_lnum(c, lnum); | 1036 | lnum = ubifs_next_log_lnum(c, lnum); |
| 1038 | } while (lnum != UBIFS_LOG_LNUM); | 1037 | } while (lnum != c->ltail_lnum); |
| 1039 | 1038 | ||
| 1040 | err = replay_buds(c); | 1039 | err = replay_buds(c); |
| 1041 | if (err) | 1040 | if (err) |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index c3fa6c5327a3..71a197f0f93d 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -1157,9 +1157,6 @@ static int check_free_space(struct ubifs_info *c) | |||
| 1157 | * | 1157 | * |
| 1158 | * This function mounts UBIFS file system. Returns zero in case of success and | 1158 | * This function mounts UBIFS file system. Returns zero in case of success and |
| 1159 | * a negative error code in case of failure. | 1159 | * a negative error code in case of failure. |
| 1160 | * | ||
| 1161 | * Note, the function does not de-allocate resources it it fails half way | ||
| 1162 | * through, and the caller has to do this instead. | ||
| 1163 | */ | 1160 | */ |
| 1164 | static int mount_ubifs(struct ubifs_info *c) | 1161 | static int mount_ubifs(struct ubifs_info *c) |
| 1165 | { | 1162 | { |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index fafaad795cd6..aa233469b3c1 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
| @@ -1124,14 +1124,17 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
| 1124 | if (err) | 1124 | if (err) |
| 1125 | return err; | 1125 | return err; |
| 1126 | down_write(&iinfo->i_data_sem); | 1126 | down_write(&iinfo->i_data_sem); |
| 1127 | } else | 1127 | } else { |
| 1128 | iinfo->i_lenAlloc = newsize; | 1128 | iinfo->i_lenAlloc = newsize; |
| 1129 | goto set_size; | ||
| 1130 | } | ||
| 1129 | } | 1131 | } |
| 1130 | err = udf_extend_file(inode, newsize); | 1132 | err = udf_extend_file(inode, newsize); |
| 1131 | if (err) { | 1133 | if (err) { |
| 1132 | up_write(&iinfo->i_data_sem); | 1134 | up_write(&iinfo->i_data_sem); |
| 1133 | return err; | 1135 | return err; |
| 1134 | } | 1136 | } |
| 1137 | set_size: | ||
| 1135 | truncate_setsize(inode, newsize); | 1138 | truncate_setsize(inode, newsize); |
| 1136 | up_write(&iinfo->i_data_sem); | 1139 | up_write(&iinfo->i_data_sem); |
| 1137 | } else { | 1140 | } else { |
diff --git a/fs/udf/super.c b/fs/udf/super.c index dcbf98722afc..18fc038a438d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -1344,6 +1344,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
| 1344 | udf_err(sb, "error loading logical volume descriptor: " | 1344 | udf_err(sb, "error loading logical volume descriptor: " |
| 1345 | "Partition table too long (%u > %lu)\n", table_len, | 1345 | "Partition table too long (%u > %lu)\n", table_len, |
| 1346 | sb->s_blocksize - sizeof(*lvd)); | 1346 | sb->s_blocksize - sizeof(*lvd)); |
| 1347 | ret = 1; | ||
| 1347 | goto out_bh; | 1348 | goto out_bh; |
| 1348 | } | 1349 | } |
| 1349 | 1350 | ||
| @@ -1388,8 +1389,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
| 1388 | UDF_ID_SPARABLE, | 1389 | UDF_ID_SPARABLE, |
| 1389 | strlen(UDF_ID_SPARABLE))) { | 1390 | strlen(UDF_ID_SPARABLE))) { |
| 1390 | if (udf_load_sparable_map(sb, map, | 1391 | if (udf_load_sparable_map(sb, map, |
| 1391 | (struct sparablePartitionMap *)gpm) < 0) | 1392 | (struct sparablePartitionMap *)gpm) < 0) { |
| 1393 | ret = 1; | ||
| 1392 | goto out_bh; | 1394 | goto out_bh; |
| 1395 | } | ||
| 1393 | } else if (!strncmp(upm2->partIdent.ident, | 1396 | } else if (!strncmp(upm2->partIdent.ident, |
| 1394 | UDF_ID_METADATA, | 1397 | UDF_ID_METADATA, |
| 1395 | strlen(UDF_ID_METADATA))) { | 1398 | strlen(UDF_ID_METADATA))) { |
| @@ -2000,6 +2003,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 2000 | if (!silent) | 2003 | if (!silent) |
| 2001 | pr_notice("Rescanning with blocksize %d\n", | 2004 | pr_notice("Rescanning with blocksize %d\n", |
| 2002 | UDF_DEFAULT_BLOCKSIZE); | 2005 | UDF_DEFAULT_BLOCKSIZE); |
| 2006 | brelse(sbi->s_lvid_bh); | ||
| 2007 | sbi->s_lvid_bh = NULL; | ||
| 2003 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; | 2008 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; |
| 2004 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | 2009 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
| 2005 | } | 2010 | } |
diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index f9c3fe304a17..69cf4fcde03e 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c | |||
| @@ -179,12 +179,14 @@ xfs_ioc_trim( | |||
| 179 | * used by the fstrim application. In the end it really doesn't | 179 | * used by the fstrim application. In the end it really doesn't |
| 180 | * matter as trimming blocks is an advisory interface. | 180 | * matter as trimming blocks is an advisory interface. |
| 181 | */ | 181 | */ |
| 182 | if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) || | ||
| 183 | range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp))) | ||
| 184 | return -XFS_ERROR(EINVAL); | ||
| 185 | |||
| 182 | start = BTOBB(range.start); | 186 | start = BTOBB(range.start); |
| 183 | end = start + BTOBBT(range.len) - 1; | 187 | end = start + BTOBBT(range.len) - 1; |
| 184 | minlen = BTOBB(max_t(u64, granularity, range.minlen)); | 188 | minlen = BTOBB(max_t(u64, granularity, range.minlen)); |
| 185 | 189 | ||
| 186 | if (XFS_BB_TO_FSB(mp, start) >= mp->m_sb.sb_dblocks) | ||
| 187 | return -XFS_ERROR(EINVAL); | ||
| 188 | if (end > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1) | 190 | if (end > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1) |
| 189 | end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)- 1; | 191 | end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)- 1; |
| 190 | 192 | ||
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 21e37b55f7e5..5aceb3f8ecd6 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
| @@ -962,23 +962,22 @@ xfs_dialloc( | |||
| 962 | if (!pag->pagi_freecount && !okalloc) | 962 | if (!pag->pagi_freecount && !okalloc) |
| 963 | goto nextag; | 963 | goto nextag; |
| 964 | 964 | ||
| 965 | /* | ||
| 966 | * Then read in the AGI buffer and recheck with the AGI buffer | ||
| 967 | * lock held. | ||
| 968 | */ | ||
| 965 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); | 969 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); |
| 966 | if (error) | 970 | if (error) |
| 967 | goto out_error; | 971 | goto out_error; |
| 968 | 972 | ||
| 969 | /* | ||
| 970 | * Once the AGI has been read in we have to recheck | ||
| 971 | * pagi_freecount with the AGI buffer lock held. | ||
| 972 | */ | ||
| 973 | if (pag->pagi_freecount) { | 973 | if (pag->pagi_freecount) { |
| 974 | xfs_perag_put(pag); | 974 | xfs_perag_put(pag); |
| 975 | goto out_alloc; | 975 | goto out_alloc; |
| 976 | } | 976 | } |
| 977 | 977 | ||
| 978 | if (!okalloc) { | 978 | if (!okalloc) |
| 979 | xfs_trans_brelse(tp, agbp); | 979 | goto nextag_relse_buffer; |
| 980 | goto nextag; | 980 | |
| 981 | } | ||
| 982 | 981 | ||
| 983 | error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced); | 982 | error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced); |
| 984 | if (error) { | 983 | if (error) { |
| @@ -1007,6 +1006,8 @@ xfs_dialloc( | |||
| 1007 | return 0; | 1006 | return 0; |
| 1008 | } | 1007 | } |
| 1009 | 1008 | ||
| 1009 | nextag_relse_buffer: | ||
| 1010 | xfs_trans_brelse(tp, agbp); | ||
| 1010 | nextag: | 1011 | nextag: |
| 1011 | xfs_perag_put(pag); | 1012 | xfs_perag_put(pag); |
| 1012 | if (++agno == mp->m_sb.sb_agcount) | 1013 | if (++agno == mp->m_sb.sb_agcount) |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 92d4331cd4f1..ca28a4ba4b54 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
| @@ -857,7 +857,7 @@ xfs_rtbuf_get( | |||
| 857 | xfs_buf_t *bp; /* block buffer, result */ | 857 | xfs_buf_t *bp; /* block buffer, result */ |
| 858 | xfs_inode_t *ip; /* bitmap or summary inode */ | 858 | xfs_inode_t *ip; /* bitmap or summary inode */ |
| 859 | xfs_bmbt_irec_t map; | 859 | xfs_bmbt_irec_t map; |
| 860 | int nmap; | 860 | int nmap = 1; |
| 861 | int error; /* error value */ | 861 | int error; /* error value */ |
| 862 | 862 | ||
| 863 | ip = issum ? mp->m_rsumip : mp->m_rbmip; | 863 | ip = issum ? mp->m_rsumip : mp->m_rbmip; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ced362533e3c..bfacf0d5a225 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -118,7 +118,8 @@ enum drm_mode_status { | |||
| 118 | .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ | 118 | .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ |
| 119 | .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \ | 119 | .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \ |
| 120 | .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ | 120 | .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ |
| 121 | .vscan = (vs), .flags = (f), .vrefresh = 0 | 121 | .vscan = (vs), .flags = (f), .vrefresh = 0, \ |
| 122 | .base.type = DRM_MODE_OBJECT_MODE | ||
| 122 | 123 | ||
| 123 | #define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ | 124 | #define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ |
| 124 | 125 | ||
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 5581980b14f6..3d6301b6ec16 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h | |||
| @@ -359,8 +359,9 @@ struct drm_mode_mode_cmd { | |||
| 359 | struct drm_mode_modeinfo mode; | 359 | struct drm_mode_modeinfo mode; |
| 360 | }; | 360 | }; |
| 361 | 361 | ||
| 362 | #define DRM_MODE_CURSOR_BO (1<<0) | 362 | #define DRM_MODE_CURSOR_BO 0x01 |
| 363 | #define DRM_MODE_CURSOR_MOVE (1<<1) | 363 | #define DRM_MODE_CURSOR_MOVE 0x02 |
| 364 | #define DRM_MODE_CURSOR_FLAGS 0x03 | ||
| 364 | 365 | ||
| 365 | /* | 366 | /* |
| 366 | * depending on the value in flags different members are used. | 367 | * depending on the value in flags different members are used. |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 4e72a9d48232..4a2ab7c85393 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -601,7 +601,7 @@ static inline void blk_clear_rl_full(struct request_list *rl, bool sync) | |||
| 601 | * it already be started by driver. | 601 | * it already be started by driver. |
| 602 | */ | 602 | */ |
| 603 | #define RQ_NOMERGE_FLAGS \ | 603 | #define RQ_NOMERGE_FLAGS \ |
| 604 | (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) | 604 | (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD) |
| 605 | #define rq_mergeable(rq) \ | 605 | #define rq_mergeable(rq) \ |
| 606 | (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ | 606 | (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ |
| 607 | (((rq)->cmd_flags & REQ_DISCARD) || \ | 607 | (((rq)->cmd_flags & REQ_DISCARD) || \ |
| @@ -894,6 +894,8 @@ extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); | |||
| 894 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); | 894 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); |
| 895 | 895 | ||
| 896 | extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); | 896 | extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); |
| 897 | extern int blk_bio_map_sg(struct request_queue *q, struct bio *bio, | ||
| 898 | struct scatterlist *sglist); | ||
| 897 | extern void blk_dump_rq_flags(struct request *, char *); | 899 | extern void blk_dump_rq_flags(struct request *, char *); |
| 898 | extern long nr_blockdev_pages(void); | 900 | extern long nr_blockdev_pages(void); |
| 899 | 901 | ||
| @@ -1139,6 +1141,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector | |||
| 1139 | & (lim->discard_granularity - 1); | 1141 | & (lim->discard_granularity - 1); |
| 1140 | } | 1142 | } |
| 1141 | 1143 | ||
| 1144 | static inline int bdev_discard_alignment(struct block_device *bdev) | ||
| 1145 | { | ||
| 1146 | struct request_queue *q = bdev_get_queue(bdev); | ||
| 1147 | |||
| 1148 | if (bdev != bdev->bd_contains) | ||
| 1149 | return bdev->bd_part->discard_alignment; | ||
| 1150 | |||
| 1151 | return q->limits.discard_alignment; | ||
| 1152 | } | ||
| 1153 | |||
| 1142 | static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) | 1154 | static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) |
| 1143 | { | 1155 | { |
| 1144 | if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1) | 1156 | if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1) |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 040b13b5c14a..279b1eaa8b73 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
| @@ -194,6 +194,10 @@ static inline int cpuidle_play_dead(void) {return -ENODEV; } | |||
| 194 | 194 | ||
| 195 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED | 195 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED |
| 196 | void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a); | 196 | void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a); |
| 197 | #else | ||
| 198 | static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a) | ||
| 199 | { | ||
| 200 | } | ||
| 197 | #endif | 201 | #endif |
| 198 | 202 | ||
| 199 | /****************************** | 203 | /****************************** |
diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 603bec2913b0..06177ba10a16 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h | |||
| @@ -58,13 +58,6 @@ union ktime { | |||
| 58 | 58 | ||
| 59 | typedef union ktime ktime_t; /* Kill this */ | 59 | typedef union ktime ktime_t; /* Kill this */ |
| 60 | 60 | ||
| 61 | #define KTIME_MAX ((s64)~((u64)1 << 63)) | ||
| 62 | #if (BITS_PER_LONG == 64) | ||
| 63 | # define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) | ||
| 64 | #else | ||
| 65 | # define KTIME_SEC_MAX LONG_MAX | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* | 61 | /* |
| 69 | * ktime_t definitions when using the 64-bit scalar representation: | 62 | * ktime_t definitions when using the 64-bit scalar representation: |
| 70 | */ | 63 | */ |
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 51bf8ada6dc0..49258e0ed1c6 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #define MV643XX_ETH_SIZE_REG_4 0x2224 | 15 | #define MV643XX_ETH_SIZE_REG_4 0x2224 |
| 16 | #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 | 16 | #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 |
| 17 | 17 | ||
| 18 | #define MV643XX_TX_CSUM_DEFAULT_LIMIT 0 | ||
| 19 | |||
| 18 | struct mv643xx_eth_shared_platform_data { | 20 | struct mv643xx_eth_shared_platform_data { |
| 19 | struct mbus_dram_target_info *dram; | 21 | struct mbus_dram_target_info *dram; |
| 20 | struct platform_device *shared_smi; | 22 | struct platform_device *shared_smi; |
diff --git a/include/linux/time.h b/include/linux/time.h index c81c5e40fcb5..b51e664c83e7 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
| @@ -107,11 +107,36 @@ static inline struct timespec timespec_sub(struct timespec lhs, | |||
| 107 | return ts_delta; | 107 | return ts_delta; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | #define KTIME_MAX ((s64)~((u64)1 << 63)) | ||
| 111 | #if (BITS_PER_LONG == 64) | ||
| 112 | # define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) | ||
| 113 | #else | ||
| 114 | # define KTIME_SEC_MAX LONG_MAX | ||
| 115 | #endif | ||
| 116 | |||
| 110 | /* | 117 | /* |
| 111 | * Returns true if the timespec is norm, false if denorm: | 118 | * Returns true if the timespec is norm, false if denorm: |
| 112 | */ | 119 | */ |
| 113 | #define timespec_valid(ts) \ | 120 | static inline bool timespec_valid(const struct timespec *ts) |
| 114 | (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) | 121 | { |
| 122 | /* Dates before 1970 are bogus */ | ||
| 123 | if (ts->tv_sec < 0) | ||
| 124 | return false; | ||
| 125 | /* Can't have more nanoseconds then a second */ | ||
| 126 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | ||
| 127 | return false; | ||
| 128 | return true; | ||
| 129 | } | ||
| 130 | |||
| 131 | static inline bool timespec_valid_strict(const struct timespec *ts) | ||
| 132 | { | ||
| 133 | if (!timespec_valid(ts)) | ||
| 134 | return false; | ||
| 135 | /* Disallow values that could overflow ktime_t */ | ||
| 136 | if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) | ||
| 137 | return false; | ||
| 138 | return true; | ||
| 139 | } | ||
| 115 | 140 | ||
| 116 | extern void read_persistent_clock(struct timespec *ts); | 141 | extern void read_persistent_clock(struct timespec *ts); |
| 117 | extern void read_boot_clock(struct timespec *ts); | 142 | extern void read_boot_clock(struct timespec *ts); |
diff --git a/include/video/omapdss.h b/include/video/omapdss.h index a6267a2d292b..3729173b7fbc 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h | |||
| @@ -48,10 +48,10 @@ | |||
| 48 | #define DISPC_IRQ_FRAMEDONEWB (1 << 23) | 48 | #define DISPC_IRQ_FRAMEDONEWB (1 << 23) |
| 49 | #define DISPC_IRQ_FRAMEDONETV (1 << 24) | 49 | #define DISPC_IRQ_FRAMEDONETV (1 << 24) |
| 50 | #define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25) | 50 | #define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25) |
| 51 | #define DISPC_IRQ_FRAMEDONE3 (1 << 26) | 51 | #define DISPC_IRQ_SYNC_LOST3 (1 << 27) |
| 52 | #define DISPC_IRQ_VSYNC3 (1 << 27) | 52 | #define DISPC_IRQ_VSYNC3 (1 << 28) |
| 53 | #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 28) | 53 | #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29) |
| 54 | #define DISPC_IRQ_SYNC_LOST3 (1 << 29) | 54 | #define DISPC_IRQ_FRAMEDONE3 (1 << 30) |
| 55 | 55 | ||
| 56 | struct omap_dss_device; | 56 | struct omap_dss_device; |
| 57 | struct omap_overlay_manager; | 57 | struct omap_overlay_manager; |
| @@ -73,6 +73,7 @@ enum omap_plane { | |||
| 73 | OMAP_DSS_VIDEO1 = 1, | 73 | OMAP_DSS_VIDEO1 = 1, |
| 74 | OMAP_DSS_VIDEO2 = 2, | 74 | OMAP_DSS_VIDEO2 = 2, |
| 75 | OMAP_DSS_VIDEO3 = 3, | 75 | OMAP_DSS_VIDEO3 = 3, |
| 76 | OMAP_DSS_WB = 4, | ||
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | enum omap_channel { | 79 | enum omap_channel { |
| @@ -186,6 +187,8 @@ enum omap_overlay_caps { | |||
| 186 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1, | 187 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1, |
| 187 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2, | 188 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2, |
| 188 | OMAP_DSS_OVL_CAP_ZORDER = 1 << 3, | 189 | OMAP_DSS_OVL_CAP_ZORDER = 1 << 3, |
| 190 | OMAP_DSS_OVL_CAP_POS = 1 << 4, | ||
| 191 | OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5, | ||
| 189 | }; | 192 | }; |
| 190 | 193 | ||
| 191 | enum omap_overlay_manager_caps { | 194 | enum omap_overlay_manager_caps { |
| @@ -207,6 +210,16 @@ enum omap_hdmi_flags { | |||
| 207 | OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0, | 210 | OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0, |
| 208 | }; | 211 | }; |
| 209 | 212 | ||
| 213 | enum omap_dss_output_id { | ||
| 214 | OMAP_DSS_OUTPUT_DPI = 1 << 0, | ||
| 215 | OMAP_DSS_OUTPUT_DBI = 1 << 1, | ||
| 216 | OMAP_DSS_OUTPUT_SDI = 1 << 2, | ||
| 217 | OMAP_DSS_OUTPUT_DSI1 = 1 << 3, | ||
| 218 | OMAP_DSS_OUTPUT_DSI2 = 1 << 4, | ||
| 219 | OMAP_DSS_OUTPUT_VENC = 1 << 5, | ||
| 220 | OMAP_DSS_OUTPUT_HDMI = 1 << 6, | ||
| 221 | }; | ||
| 222 | |||
| 210 | /* RFBI */ | 223 | /* RFBI */ |
| 211 | 224 | ||
| 212 | struct rfbi_timings { | 225 | struct rfbi_timings { |
| @@ -243,7 +256,7 @@ void rfbi_bus_unlock(void); | |||
| 243 | 256 | ||
| 244 | /* DSI */ | 257 | /* DSI */ |
| 245 | 258 | ||
| 246 | struct omap_dss_dsi_videomode_data { | 259 | struct omap_dss_dsi_videomode_timings { |
| 247 | /* DSI video mode blanking data */ | 260 | /* DSI video mode blanking data */ |
| 248 | /* Unit: byte clock cycles */ | 261 | /* Unit: byte clock cycles */ |
| 249 | u16 hsa; | 262 | u16 hsa; |
| @@ -424,6 +437,8 @@ struct omap_overlay { | |||
| 424 | struct omap_overlay_info *info); | 437 | struct omap_overlay_info *info); |
| 425 | 438 | ||
| 426 | int (*wait_for_go)(struct omap_overlay *ovl); | 439 | int (*wait_for_go)(struct omap_overlay *ovl); |
| 440 | |||
| 441 | struct omap_dss_device *(*get_device)(struct omap_overlay *ovl); | ||
| 427 | }; | 442 | }; |
| 428 | 443 | ||
| 429 | struct omap_overlay_manager_info { | 444 | struct omap_overlay_manager_info { |
| @@ -448,9 +463,10 @@ struct omap_overlay_manager { | |||
| 448 | enum omap_overlay_manager_caps caps; | 463 | enum omap_overlay_manager_caps caps; |
| 449 | struct list_head overlays; | 464 | struct list_head overlays; |
| 450 | enum omap_display_type supported_displays; | 465 | enum omap_display_type supported_displays; |
| 466 | enum omap_dss_output_id supported_outputs; | ||
| 451 | 467 | ||
| 452 | /* dynamic fields */ | 468 | /* dynamic fields */ |
| 453 | struct omap_dss_device *device; | 469 | struct omap_dss_output *output; |
| 454 | 470 | ||
| 455 | /* | 471 | /* |
| 456 | * The following functions do not block: | 472 | * The following functions do not block: |
| @@ -463,9 +479,9 @@ struct omap_overlay_manager { | |||
| 463 | * interrupt context | 479 | * interrupt context |
| 464 | */ | 480 | */ |
| 465 | 481 | ||
| 466 | int (*set_device)(struct omap_overlay_manager *mgr, | 482 | int (*set_output)(struct omap_overlay_manager *mgr, |
| 467 | struct omap_dss_device *dssdev); | 483 | struct omap_dss_output *output); |
| 468 | int (*unset_device)(struct omap_overlay_manager *mgr); | 484 | int (*unset_output)(struct omap_overlay_manager *mgr); |
| 469 | 485 | ||
| 470 | int (*set_manager_info)(struct omap_overlay_manager *mgr, | 486 | int (*set_manager_info)(struct omap_overlay_manager *mgr, |
| 471 | struct omap_overlay_manager_info *info); | 487 | struct omap_overlay_manager_info *info); |
| @@ -475,6 +491,8 @@ struct omap_overlay_manager { | |||
| 475 | int (*apply)(struct omap_overlay_manager *mgr); | 491 | int (*apply)(struct omap_overlay_manager *mgr); |
| 476 | int (*wait_for_go)(struct omap_overlay_manager *mgr); | 492 | int (*wait_for_go)(struct omap_overlay_manager *mgr); |
| 477 | int (*wait_for_vsync)(struct omap_overlay_manager *mgr); | 493 | int (*wait_for_vsync)(struct omap_overlay_manager *mgr); |
| 494 | |||
| 495 | struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr); | ||
| 478 | }; | 496 | }; |
| 479 | 497 | ||
| 480 | /* 22 pins means 1 clk lane and 10 data lanes */ | 498 | /* 22 pins means 1 clk lane and 10 data lanes */ |
| @@ -492,6 +510,37 @@ struct omap_dsi_pin_config { | |||
| 492 | int pins[OMAP_DSS_MAX_DSI_PINS]; | 510 | int pins[OMAP_DSS_MAX_DSI_PINS]; |
| 493 | }; | 511 | }; |
| 494 | 512 | ||
| 513 | struct omap_dss_writeback_info { | ||
| 514 | u32 paddr; | ||
| 515 | u32 p_uv_addr; | ||
| 516 | u16 buf_width; | ||
| 517 | u16 width; | ||
| 518 | u16 height; | ||
| 519 | enum omap_color_mode color_mode; | ||
| 520 | u8 rotation; | ||
| 521 | enum omap_dss_rotation_type rotation_type; | ||
| 522 | bool mirror; | ||
| 523 | u8 pre_mult_alpha; | ||
| 524 | }; | ||
| 525 | |||
| 526 | struct omap_dss_output { | ||
| 527 | struct list_head list; | ||
| 528 | |||
| 529 | /* display type supported by the output */ | ||
| 530 | enum omap_display_type type; | ||
| 531 | |||
| 532 | /* output instance */ | ||
| 533 | enum omap_dss_output_id id; | ||
| 534 | |||
| 535 | /* output's platform device pointer */ | ||
| 536 | struct platform_device *pdev; | ||
| 537 | |||
| 538 | /* dynamic fields */ | ||
| 539 | struct omap_overlay_manager *manager; | ||
| 540 | |||
| 541 | struct omap_dss_device *device; | ||
| 542 | }; | ||
| 543 | |||
| 495 | struct omap_dss_device { | 544 | struct omap_dss_device { |
| 496 | struct device dev; | 545 | struct device dev; |
| 497 | 546 | ||
| @@ -564,7 +613,7 @@ struct omap_dss_device { | |||
| 564 | 613 | ||
| 565 | enum omap_dss_dsi_pixel_format dsi_pix_fmt; | 614 | enum omap_dss_dsi_pixel_format dsi_pix_fmt; |
| 566 | enum omap_dss_dsi_mode dsi_mode; | 615 | enum omap_dss_dsi_mode dsi_mode; |
| 567 | struct omap_dss_dsi_videomode_data dsi_vm_data; | 616 | struct omap_dss_dsi_videomode_timings dsi_vm_timings; |
| 568 | } panel; | 617 | } panel; |
| 569 | 618 | ||
| 570 | struct { | 619 | struct { |
| @@ -590,7 +639,7 @@ struct omap_dss_device { | |||
| 590 | 639 | ||
| 591 | enum omap_display_caps caps; | 640 | enum omap_display_caps caps; |
| 592 | 641 | ||
| 593 | struct omap_overlay_manager *manager; | 642 | struct omap_dss_output *output; |
| 594 | 643 | ||
| 595 | enum omap_dss_display_state state; | 644 | enum omap_dss_display_state state; |
| 596 | 645 | ||
| @@ -605,6 +654,8 @@ struct omap_dss_device { | |||
| 605 | 654 | ||
| 606 | struct omap_dss_hdmi_data | 655 | struct omap_dss_hdmi_data |
| 607 | { | 656 | { |
| 657 | int ct_cp_hpd_gpio; | ||
| 658 | int ls_oe_gpio; | ||
| 608 | int hpd_gpio; | 659 | int hpd_gpio; |
| 609 | }; | 660 | }; |
| 610 | 661 | ||
| @@ -699,6 +750,11 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num); | |||
| 699 | int omap_dss_get_num_overlays(void); | 750 | int omap_dss_get_num_overlays(void); |
| 700 | struct omap_overlay *omap_dss_get_overlay(int num); | 751 | struct omap_overlay *omap_dss_get_overlay(int num); |
| 701 | 752 | ||
| 753 | struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id); | ||
| 754 | int omapdss_output_set_device(struct omap_dss_output *out, | ||
| 755 | struct omap_dss_device *dssdev); | ||
| 756 | int omapdss_output_unset_device(struct omap_dss_output *out); | ||
| 757 | |||
| 702 | void omapdss_default_get_resolution(struct omap_dss_device *dssdev, | 758 | void omapdss_default_get_resolution(struct omap_dss_device *dssdev, |
| 703 | u16 *xres, u16 *yres); | 759 | u16 *xres, u16 *yres); |
| 704 | int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); | 760 | int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); |
| @@ -719,6 +775,15 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, | |||
| 719 | void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | 775 | void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, |
| 720 | bool enable); | 776 | bool enable); |
| 721 | int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); | 777 | int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); |
| 778 | void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, | ||
| 779 | struct omap_video_timings *timings); | ||
| 780 | void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h); | ||
| 781 | void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, | ||
| 782 | enum omap_dss_dsi_pixel_format fmt); | ||
| 783 | void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, | ||
| 784 | enum omap_dss_dsi_mode mode); | ||
| 785 | void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, | ||
| 786 | struct omap_dss_dsi_videomode_timings *timings); | ||
| 722 | 787 | ||
| 723 | int omap_dsi_update(struct omap_dss_device *dssdev, int channel, | 788 | int omap_dsi_update(struct omap_dss_device *dssdev, int channel, |
| 724 | void (*callback)(int, void *), void *data); | 789 | void (*callback)(int, void *), void *data); |
| @@ -727,6 +792,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id); | |||
| 727 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); | 792 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); |
| 728 | int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | 793 | int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, |
| 729 | const struct omap_dsi_pin_config *pin_cfg); | 794 | const struct omap_dsi_pin_config *pin_cfg); |
| 795 | int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, | ||
| 796 | unsigned long ddr_clk, unsigned long lp_clk); | ||
| 730 | 797 | ||
| 731 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); | 798 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); |
| 732 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, | 799 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, |
| @@ -734,22 +801,29 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, | |||
| 734 | 801 | ||
| 735 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev); | 802 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev); |
| 736 | void omapdss_dpi_display_disable(struct omap_dss_device *dssdev); | 803 | void omapdss_dpi_display_disable(struct omap_dss_device *dssdev); |
| 737 | void dpi_set_timings(struct omap_dss_device *dssdev, | 804 | void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, |
| 738 | struct omap_video_timings *timings); | 805 | struct omap_video_timings *timings); |
| 739 | int dpi_check_timings(struct omap_dss_device *dssdev, | 806 | int dpi_check_timings(struct omap_dss_device *dssdev, |
| 740 | struct omap_video_timings *timings); | 807 | struct omap_video_timings *timings); |
| 808 | void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines); | ||
| 741 | 809 | ||
| 742 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev); | 810 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev); |
| 743 | void omapdss_sdi_display_disable(struct omap_dss_device *dssdev); | 811 | void omapdss_sdi_display_disable(struct omap_dss_device *dssdev); |
| 812 | void omapdss_sdi_set_timings(struct omap_dss_device *dssdev, | ||
| 813 | struct omap_video_timings *timings); | ||
| 814 | void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs); | ||
| 744 | 815 | ||
| 745 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev); | 816 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev); |
| 746 | void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev); | 817 | void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev); |
| 747 | int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, | 818 | int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), |
| 748 | u16 *x, u16 *y, u16 *w, u16 *h); | 819 | void *data); |
| 749 | int omap_rfbi_update(struct omap_dss_device *dssdev, | 820 | int omap_rfbi_configure(struct omap_dss_device *dssdev); |
| 750 | u16 x, u16 y, u16 w, u16 h, | 821 | void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h); |
| 751 | void (*callback)(void *), void *data); | 822 | void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, |
| 752 | int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size, | 823 | int pixel_size); |
| 824 | void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, | ||
| 753 | int data_lines); | 825 | int data_lines); |
| 826 | void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev, | ||
| 827 | struct rfbi_timings *timings); | ||
| 754 | 828 | ||
| 755 | #endif | 829 | #endif |
diff --git a/include/xen/events.h b/include/xen/events.h index 9c641deb65d2..04399b28e821 100644 --- a/include/xen/events.h +++ b/include/xen/events.h | |||
| @@ -58,8 +58,6 @@ void notify_remote_via_irq(int irq); | |||
| 58 | 58 | ||
| 59 | void xen_irq_resume(void); | 59 | void xen_irq_resume(void); |
| 60 | 60 | ||
| 61 | void xen_hvm_prepare_kexec(struct shared_info *sip, unsigned long pfn); | ||
| 62 | |||
| 63 | /* Clear an irq's pending state, in preparation for polling on it */ | 61 | /* Clear an irq's pending state, in preparation for polling on it */ |
| 64 | void xen_clear_irq_pending(int irq); | 62 | void xen_clear_irq_pending(int irq); |
| 65 | void xen_set_irq_pending(int irq); | 63 | void xen_set_irq_pending(int irq); |
diff --git a/kernel/fork.c b/kernel/fork.c index 3bd2280d79f6..2c8857e12855 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -455,8 +455,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
| 455 | if (retval) | 455 | if (retval) |
| 456 | goto out; | 456 | goto out; |
| 457 | 457 | ||
| 458 | if (file && uprobe_mmap(tmp)) | 458 | if (file) |
| 459 | goto out; | 459 | uprobe_mmap(tmp); |
| 460 | } | 460 | } |
| 461 | /* a new mm has just been created */ | 461 | /* a new mm has just been created */ |
| 462 | arch_dup_mmap(oldmm, mm); | 462 | arch_dup_mmap(oldmm, mm); |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e16af197a2bc..34e5eac81424 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -115,6 +115,7 @@ static void tk_xtime_add(struct timekeeper *tk, const struct timespec *ts) | |||
| 115 | { | 115 | { |
| 116 | tk->xtime_sec += ts->tv_sec; | 116 | tk->xtime_sec += ts->tv_sec; |
| 117 | tk->xtime_nsec += (u64)ts->tv_nsec << tk->shift; | 117 | tk->xtime_nsec += (u64)ts->tv_nsec << tk->shift; |
| 118 | tk_normalize_xtime(tk); | ||
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm) | 121 | static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm) |
| @@ -276,7 +277,7 @@ static void timekeeping_forward_now(struct timekeeper *tk) | |||
| 276 | tk->xtime_nsec += cycle_delta * tk->mult; | 277 | tk->xtime_nsec += cycle_delta * tk->mult; |
| 277 | 278 | ||
| 278 | /* If arch requires, add in gettimeoffset() */ | 279 | /* If arch requires, add in gettimeoffset() */ |
| 279 | tk->xtime_nsec += arch_gettimeoffset() << tk->shift; | 280 | tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift; |
| 280 | 281 | ||
| 281 | tk_normalize_xtime(tk); | 282 | tk_normalize_xtime(tk); |
| 282 | 283 | ||
| @@ -427,7 +428,7 @@ int do_settimeofday(const struct timespec *tv) | |||
| 427 | struct timespec ts_delta, xt; | 428 | struct timespec ts_delta, xt; |
| 428 | unsigned long flags; | 429 | unsigned long flags; |
| 429 | 430 | ||
| 430 | if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) | 431 | if (!timespec_valid_strict(tv)) |
| 431 | return -EINVAL; | 432 | return -EINVAL; |
| 432 | 433 | ||
| 433 | write_seqlock_irqsave(&tk->lock, flags); | 434 | write_seqlock_irqsave(&tk->lock, flags); |
| @@ -463,6 +464,8 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
| 463 | { | 464 | { |
| 464 | struct timekeeper *tk = &timekeeper; | 465 | struct timekeeper *tk = &timekeeper; |
| 465 | unsigned long flags; | 466 | unsigned long flags; |
| 467 | struct timespec tmp; | ||
| 468 | int ret = 0; | ||
| 466 | 469 | ||
| 467 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | 470 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) |
| 468 | return -EINVAL; | 471 | return -EINVAL; |
| @@ -471,10 +474,17 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
| 471 | 474 | ||
| 472 | timekeeping_forward_now(tk); | 475 | timekeeping_forward_now(tk); |
| 473 | 476 | ||
| 477 | /* Make sure the proposed value is valid */ | ||
| 478 | tmp = timespec_add(tk_xtime(tk), *ts); | ||
| 479 | if (!timespec_valid_strict(&tmp)) { | ||
| 480 | ret = -EINVAL; | ||
| 481 | goto error; | ||
| 482 | } | ||
| 474 | 483 | ||
| 475 | tk_xtime_add(tk, ts); | 484 | tk_xtime_add(tk, ts); |
| 476 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); | 485 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); |
| 477 | 486 | ||
| 487 | error: /* even if we error out, we forwarded the time, so call update */ | ||
| 478 | timekeeping_update(tk, true); | 488 | timekeeping_update(tk, true); |
| 479 | 489 | ||
| 480 | write_sequnlock_irqrestore(&tk->lock, flags); | 490 | write_sequnlock_irqrestore(&tk->lock, flags); |
| @@ -482,7 +492,7 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
| 482 | /* signal hrtimers about time change */ | 492 | /* signal hrtimers about time change */ |
| 483 | clock_was_set(); | 493 | clock_was_set(); |
| 484 | 494 | ||
| 485 | return 0; | 495 | return ret; |
| 486 | } | 496 | } |
| 487 | EXPORT_SYMBOL(timekeeping_inject_offset); | 497 | EXPORT_SYMBOL(timekeeping_inject_offset); |
| 488 | 498 | ||
| @@ -649,7 +659,20 @@ void __init timekeeping_init(void) | |||
| 649 | struct timespec now, boot, tmp; | 659 | struct timespec now, boot, tmp; |
| 650 | 660 | ||
| 651 | read_persistent_clock(&now); | 661 | read_persistent_clock(&now); |
| 662 | if (!timespec_valid_strict(&now)) { | ||
| 663 | pr_warn("WARNING: Persistent clock returned invalid value!\n" | ||
| 664 | " Check your CMOS/BIOS settings.\n"); | ||
| 665 | now.tv_sec = 0; | ||
| 666 | now.tv_nsec = 0; | ||
| 667 | } | ||
| 668 | |||
| 652 | read_boot_clock(&boot); | 669 | read_boot_clock(&boot); |
| 670 | if (!timespec_valid_strict(&boot)) { | ||
| 671 | pr_warn("WARNING: Boot clock returned invalid value!\n" | ||
| 672 | " Check your CMOS/BIOS settings.\n"); | ||
| 673 | boot.tv_sec = 0; | ||
| 674 | boot.tv_nsec = 0; | ||
| 675 | } | ||
| 653 | 676 | ||
| 654 | seqlock_init(&tk->lock); | 677 | seqlock_init(&tk->lock); |
| 655 | 678 | ||
| @@ -690,7 +713,7 @@ static struct timespec timekeeping_suspend_time; | |||
| 690 | static void __timekeeping_inject_sleeptime(struct timekeeper *tk, | 713 | static void __timekeeping_inject_sleeptime(struct timekeeper *tk, |
| 691 | struct timespec *delta) | 714 | struct timespec *delta) |
| 692 | { | 715 | { |
| 693 | if (!timespec_valid(delta)) { | 716 | if (!timespec_valid_strict(delta)) { |
| 694 | printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid " | 717 | printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid " |
| 695 | "sleep delta value!\n"); | 718 | "sleep delta value!\n"); |
| 696 | return; | 719 | return; |
| @@ -1129,6 +1152,10 @@ static void update_wall_time(void) | |||
| 1129 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; | 1152 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; |
| 1130 | #endif | 1153 | #endif |
| 1131 | 1154 | ||
| 1155 | /* Check if there's really nothing to do */ | ||
| 1156 | if (offset < tk->cycle_interval) | ||
| 1157 | goto out; | ||
| 1158 | |||
| 1132 | /* | 1159 | /* |
| 1133 | * With NO_HZ we may have to accumulate many cycle_intervals | 1160 | * With NO_HZ we may have to accumulate many cycle_intervals |
| 1134 | * (think "ticks") worth of time at once. To do this efficiently, | 1161 | * (think "ticks") worth of time at once. To do this efficiently, |
| @@ -1161,9 +1188,9 @@ static void update_wall_time(void) | |||
| 1161 | * the vsyscall implementations are converted to use xtime_nsec | 1188 | * the vsyscall implementations are converted to use xtime_nsec |
| 1162 | * (shifted nanoseconds), this can be killed. | 1189 | * (shifted nanoseconds), this can be killed. |
| 1163 | */ | 1190 | */ |
| 1164 | remainder = tk->xtime_nsec & ((1 << tk->shift) - 1); | 1191 | remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1); |
| 1165 | tk->xtime_nsec -= remainder; | 1192 | tk->xtime_nsec -= remainder; |
| 1166 | tk->xtime_nsec += 1 << tk->shift; | 1193 | tk->xtime_nsec += 1ULL << tk->shift; |
| 1167 | tk->ntp_error += remainder << tk->ntp_error_shift; | 1194 | tk->ntp_error += remainder << tk->ntp_error_shift; |
| 1168 | 1195 | ||
| 1169 | /* | 1196 | /* |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 60e4d7875672..6b245f64c8dd 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
| @@ -506,6 +506,8 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) | |||
| 506 | int size; | 506 | int size; |
| 507 | 507 | ||
| 508 | syscall_nr = syscall_get_nr(current, regs); | 508 | syscall_nr = syscall_get_nr(current, regs); |
| 509 | if (syscall_nr < 0) | ||
| 510 | return; | ||
| 509 | if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) | 511 | if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) |
| 510 | return; | 512 | return; |
| 511 | 513 | ||
| @@ -580,6 +582,8 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) | |||
| 580 | int size; | 582 | int size; |
| 581 | 583 | ||
| 582 | syscall_nr = syscall_get_nr(current, regs); | 584 | syscall_nr = syscall_get_nr(current, regs); |
| 585 | if (syscall_nr < 0) | ||
| 586 | return; | ||
| 583 | if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) | 587 | if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) |
| 584 | return; | 588 | return; |
| 585 | 589 | ||
diff --git a/mm/filemap.c b/mm/filemap.c index fa5ca304148e..384344575c37 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -1412,12 +1412,8 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 1412 | retval = filemap_write_and_wait_range(mapping, pos, | 1412 | retval = filemap_write_and_wait_range(mapping, pos, |
| 1413 | pos + iov_length(iov, nr_segs) - 1); | 1413 | pos + iov_length(iov, nr_segs) - 1); |
| 1414 | if (!retval) { | 1414 | if (!retval) { |
| 1415 | struct blk_plug plug; | ||
| 1416 | |||
| 1417 | blk_start_plug(&plug); | ||
| 1418 | retval = mapping->a_ops->direct_IO(READ, iocb, | 1415 | retval = mapping->a_ops->direct_IO(READ, iocb, |
| 1419 | iov, pos, nr_segs); | 1416 | iov, pos, nr_segs); |
| 1420 | blk_finish_plug(&plug); | ||
| 1421 | } | 1417 | } |
| 1422 | if (retval > 0) { | 1418 | if (retval > 0) { |
| 1423 | *ppos = pos + retval; | 1419 | *ppos = pos + retval; |
| @@ -2527,14 +2523,12 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 2527 | { | 2523 | { |
| 2528 | struct file *file = iocb->ki_filp; | 2524 | struct file *file = iocb->ki_filp; |
| 2529 | struct inode *inode = file->f_mapping->host; | 2525 | struct inode *inode = file->f_mapping->host; |
| 2530 | struct blk_plug plug; | ||
| 2531 | ssize_t ret; | 2526 | ssize_t ret; |
| 2532 | 2527 | ||
| 2533 | BUG_ON(iocb->ki_pos != pos); | 2528 | BUG_ON(iocb->ki_pos != pos); |
| 2534 | 2529 | ||
| 2535 | sb_start_write(inode->i_sb); | 2530 | sb_start_write(inode->i_sb); |
| 2536 | mutex_lock(&inode->i_mutex); | 2531 | mutex_lock(&inode->i_mutex); |
| 2537 | blk_start_plug(&plug); | ||
| 2538 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); | 2532 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
| 2539 | mutex_unlock(&inode->i_mutex); | 2533 | mutex_unlock(&inode->i_mutex); |
| 2540 | 2534 | ||
| @@ -2545,7 +2539,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 2545 | if (err < 0 && ret > 0) | 2539 | if (err < 0 && ret > 0) |
| 2546 | ret = err; | 2540 | ret = err; |
| 2547 | } | 2541 | } |
| 2548 | blk_finish_plug(&plug); | ||
| 2549 | sb_end_write(inode->i_sb); | 2542 | sb_end_write(inode->i_sb); |
| 2550 | return ret; | 2543 | return ret; |
| 2551 | } | 2544 | } |
| @@ -1356,9 +1356,8 @@ out: | |||
| 1356 | } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) | 1356 | } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) |
| 1357 | make_pages_present(addr, addr + len); | 1357 | make_pages_present(addr, addr + len); |
| 1358 | 1358 | ||
| 1359 | if (file && uprobe_mmap(vma)) | 1359 | if (file) |
| 1360 | /* matching probes but cannot insert */ | 1360 | uprobe_mmap(vma); |
| 1361 | goto unmap_and_free_vma; | ||
| 1362 | 1361 | ||
| 1363 | return addr; | 1362 | return addr; |
| 1364 | 1363 | ||
| @@ -3260,6 +3260,7 @@ force_grow: | |||
| 3260 | 3260 | ||
| 3261 | /* cache_grow can reenable interrupts, then ac could change. */ | 3261 | /* cache_grow can reenable interrupts, then ac could change. */ |
| 3262 | ac = cpu_cache_get(cachep); | 3262 | ac = cpu_cache_get(cachep); |
| 3263 | node = numa_mem_id(); | ||
| 3263 | 3264 | ||
| 3264 | /* no objects in sight? abort */ | 3265 | /* no objects in sight? abort */ |
| 3265 | if (!x && (ac->avail == 0 || force_refill)) | 3266 | if (!x && (ac->avail == 0 || force_refill)) |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 88f2bf671960..bac973a31367 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
| @@ -316,7 +316,6 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt) | |||
| 316 | */ | 316 | */ |
| 317 | void svc_xprt_enqueue(struct svc_xprt *xprt) | 317 | void svc_xprt_enqueue(struct svc_xprt *xprt) |
| 318 | { | 318 | { |
| 319 | struct svc_serv *serv = xprt->xpt_server; | ||
| 320 | struct svc_pool *pool; | 319 | struct svc_pool *pool; |
| 321 | struct svc_rqst *rqstp; | 320 | struct svc_rqst *rqstp; |
| 322 | int cpu; | 321 | int cpu; |
| @@ -362,8 +361,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
| 362 | rqstp, rqstp->rq_xprt); | 361 | rqstp, rqstp->rq_xprt); |
| 363 | rqstp->rq_xprt = xprt; | 362 | rqstp->rq_xprt = xprt; |
| 364 | svc_xprt_get(xprt); | 363 | svc_xprt_get(xprt); |
| 365 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
| 366 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
| 367 | pool->sp_stats.threads_woken++; | 364 | pool->sp_stats.threads_woken++; |
| 368 | wake_up(&rqstp->rq_wait); | 365 | wake_up(&rqstp->rq_wait); |
| 369 | } else { | 366 | } else { |
| @@ -640,8 +637,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 640 | if (xprt) { | 637 | if (xprt) { |
| 641 | rqstp->rq_xprt = xprt; | 638 | rqstp->rq_xprt = xprt; |
| 642 | svc_xprt_get(xprt); | 639 | svc_xprt_get(xprt); |
| 643 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
| 644 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
| 645 | 640 | ||
| 646 | /* As there is a shortage of threads and this request | 641 | /* As there is a shortage of threads and this request |
| 647 | * had to be queued, don't allow the thread to wait so | 642 | * had to be queued, don't allow the thread to wait so |
| @@ -738,6 +733,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 738 | else | 733 | else |
| 739 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | 734 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); |
| 740 | dprintk("svc: got len=%d\n", len); | 735 | dprintk("svc: got len=%d\n", len); |
| 736 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
| 737 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
| 741 | } | 738 | } |
| 742 | svc_xprt_received(xprt); | 739 | svc_xprt_received(xprt); |
| 743 | 740 | ||
| @@ -794,7 +791,8 @@ int svc_send(struct svc_rqst *rqstp) | |||
| 794 | 791 | ||
| 795 | /* Grab mutex to serialize outgoing data. */ | 792 | /* Grab mutex to serialize outgoing data. */ |
| 796 | mutex_lock(&xprt->xpt_mutex); | 793 | mutex_lock(&xprt->xpt_mutex); |
| 797 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | 794 | if (test_bit(XPT_DEAD, &xprt->xpt_flags) |
| 795 | || test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
| 798 | len = -ENOTCONN; | 796 | len = -ENOTCONN; |
| 799 | else | 797 | else |
| 800 | len = xprt->xpt_ops->xpo_sendto(rqstp); | 798 | len = xprt->xpt_ops->xpo_sendto(rqstp); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 18bc130255a7..998aa8c1807c 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -1129,9 +1129,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
| 1129 | if (len >= 0) | 1129 | if (len >= 0) |
| 1130 | svsk->sk_tcplen += len; | 1130 | svsk->sk_tcplen += len; |
| 1131 | if (len != want) { | 1131 | if (len != want) { |
| 1132 | svc_tcp_save_pages(svsk, rqstp); | ||
| 1132 | if (len < 0 && len != -EAGAIN) | 1133 | if (len < 0 && len != -EAGAIN) |
| 1133 | goto err_other; | 1134 | goto err_other; |
| 1134 | svc_tcp_save_pages(svsk, rqstp); | ||
| 1135 | dprintk("svc: incomplete TCP record (%d of %d)\n", | 1135 | dprintk("svc: incomplete TCP record (%d of %d)\n", |
| 1136 | svsk->sk_tcplen, svsk->sk_reclen); | 1136 | svsk->sk_tcplen, svsk->sk_reclen); |
| 1137 | goto err_noclose; | 1137 | goto err_noclose; |
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 2884e67ee625..213362850abd 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources | |||
| @@ -10,10 +10,12 @@ util/ctype.c | |||
| 10 | util/evlist.c | 10 | util/evlist.c |
| 11 | util/evsel.c | 11 | util/evsel.c |
| 12 | util/cpumap.c | 12 | util/cpumap.c |
| 13 | util/hweight.c | ||
| 13 | util/thread_map.c | 14 | util/thread_map.c |
| 14 | util/util.c | 15 | util/util.c |
| 15 | util/xyarray.c | 16 | util/xyarray.c |
| 16 | util/cgroup.c | 17 | util/cgroup.c |
| 17 | util/debugfs.c | 18 | util/debugfs.c |
| 19 | util/rblist.c | ||
| 18 | util/strlist.c | 20 | util/strlist.c |
| 19 | ../../lib/rbtree.c | 21 | ../../lib/rbtree.c |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 246852397e30..d617f69131d7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -1976,9 +1976,10 @@ static long kvm_vcpu_compat_ioctl(struct file *filp, | |||
| 1976 | if (copy_from_user(&csigset, sigmask_arg->sigset, | 1976 | if (copy_from_user(&csigset, sigmask_arg->sigset, |
| 1977 | sizeof csigset)) | 1977 | sizeof csigset)) |
| 1978 | goto out; | 1978 | goto out; |
| 1979 | } | 1979 | sigset_from_compat(&sigset, &csigset); |
| 1980 | sigset_from_compat(&sigset, &csigset); | 1980 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); |
| 1981 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); | 1981 | } else |
| 1982 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, NULL); | ||
| 1982 | break; | 1983 | break; |
| 1983 | } | 1984 | } |
| 1984 | default: | 1985 | default: |
