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: |