diff options
423 files changed, 5819 insertions, 3672 deletions
diff --git a/Documentation/ABI/obsolete/proc-pid-oom_adj b/Documentation/ABI/obsolete/proc-pid-oom_adj new file mode 100644 index 000000000000..cf63f264ce0f --- /dev/null +++ b/Documentation/ABI/obsolete/proc-pid-oom_adj | |||
@@ -0,0 +1,22 @@ | |||
1 | What: /proc/<pid>/oom_adj | ||
2 | When: August 2012 | ||
3 | Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's | ||
4 | badness heuristic used to determine which task to kill when the kernel | ||
5 | is out of memory. | ||
6 | |||
7 | The badness heuristic has since been rewritten since the introduction of | ||
8 | this tunable such that its meaning is deprecated. The value was | ||
9 | implemented as a bitshift on a score generated by the badness() | ||
10 | function that did not have any precise units of measure. With the | ||
11 | rewrite, the score is given as a proportion of available memory to the | ||
12 | task allocating pages, so using a bitshift which grows the score | ||
13 | exponentially is, thus, impossible to tune with fine granularity. | ||
14 | |||
15 | A much more powerful interface, /proc/<pid>/oom_score_adj, was | ||
16 | introduced with the oom killer rewrite that allows users to increase or | ||
17 | decrease the badness() score linearly. This interface will replace | ||
18 | /proc/<pid>/oom_adj. | ||
19 | |||
20 | A warning will be emitted to the kernel log if an application uses this | ||
21 | deprecated interface. After it is printed once, future warnings will be | ||
22 | suppressed until the kernel is rebooted. | ||
diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt index d5af3f630814..71cfbdc0f74d 100644 --- a/Documentation/block/switching-sched.txt +++ b/Documentation/block/switching-sched.txt | |||
@@ -16,7 +16,7 @@ you can do so by typing: | |||
16 | As of the Linux 2.6.10 kernel, it is now possible to change the | 16 | As of the Linux 2.6.10 kernel, it is now possible to change the |
17 | IO scheduler for a given block device on the fly (thus making it possible, | 17 | IO scheduler for a given block device on the fly (thus making it possible, |
18 | for instance, to set the CFQ scheduler for the system default, but | 18 | for instance, to set the CFQ scheduler for the system default, but |
19 | set a specific device to use the anticipatory or noop schedulers - which | 19 | set a specific device to use the deadline or noop schedulers - which |
20 | can improve that device's throughput). | 20 | can improve that device's throughput). |
21 | 21 | ||
22 | To set a specific scheduler, simply do this: | 22 | To set a specific scheduler, simply do this: |
@@ -31,7 +31,7 @@ a "cat /sys/block/DEV/queue/scheduler" - the list of valid names | |||
31 | will be displayed, with the currently selected scheduler in brackets: | 31 | will be displayed, with the currently selected scheduler in brackets: |
32 | 32 | ||
33 | # cat /sys/block/hda/queue/scheduler | 33 | # cat /sys/block/hda/queue/scheduler |
34 | noop anticipatory deadline [cfq] | 34 | noop deadline [cfq] |
35 | # echo anticipatory > /sys/block/hda/queue/scheduler | 35 | # echo deadline > /sys/block/hda/queue/scheduler |
36 | # cat /sys/block/hda/queue/scheduler | 36 | # cat /sys/block/hda/queue/scheduler |
37 | noop [anticipatory] deadline cfq | 37 | noop [deadline] cfq |
diff --git a/Documentation/filesystems/xfs-delayed-logging-design.txt b/Documentation/filesystems/xfs-delayed-logging-design.txt index 96d0df28bed3..7445bf335dae 100644 --- a/Documentation/filesystems/xfs-delayed-logging-design.txt +++ b/Documentation/filesystems/xfs-delayed-logging-design.txt | |||
@@ -794,17 +794,6 @@ designed. | |||
794 | 794 | ||
795 | Roadmap: | 795 | Roadmap: |
796 | 796 | ||
797 | 2.6.37 Remove experimental tag from mount option | ||
798 | => should be roughly 6 months after initial merge | ||
799 | => enough time to: | ||
800 | => gain confidence and fix problems reported by early | ||
801 | adopters (a.k.a. guinea pigs) | ||
802 | => address worst performance regressions and undesired | ||
803 | behaviours | ||
804 | => start tuning/optimising code for parallelism | ||
805 | => start tuning/optimising algorithms consuming | ||
806 | excessive CPU time | ||
807 | |||
808 | 2.6.39 Switch default mount option to use delayed logging | 797 | 2.6.39 Switch default mount option to use delayed logging |
809 | => should be roughly 12 months after initial merge | 798 | => should be roughly 12 months after initial merge |
810 | => enough time to shake out remaining problems before next round of | 799 | => enough time to shake out remaining problems before next round of |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ed45e9802aa8..92e83e53148f 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -706,7 +706,7 @@ and is between 256 and 4096 characters. It is defined in the file | |||
706 | arch/x86/kernel/cpu/cpufreq/elanfreq.c. | 706 | arch/x86/kernel/cpu/cpufreq/elanfreq.c. |
707 | 707 | ||
708 | elevator= [IOSCHED] | 708 | elevator= [IOSCHED] |
709 | Format: {"anticipatory" | "cfq" | "deadline" | "noop"} | 709 | Format: {"cfq" | "deadline" | "noop"} |
710 | See Documentation/block/as-iosched.txt and | 710 | See Documentation/block/as-iosched.txt and |
711 | Documentation/block/deadline-iosched.txt for details. | 711 | Documentation/block/deadline-iosched.txt for details. |
712 | 712 | ||
diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 8fd5ca2ae32d..58b266bd1846 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds-class.txt | |||
@@ -60,15 +60,18 @@ Hardware accelerated blink of LEDs | |||
60 | 60 | ||
61 | Some LEDs can be programmed to blink without any CPU interaction. To | 61 | Some LEDs can be programmed to blink without any CPU interaction. To |
62 | support this feature, a LED driver can optionally implement the | 62 | support this feature, a LED driver can optionally implement the |
63 | blink_set() function (see <linux/leds.h>). If implemented, triggers can | 63 | blink_set() function (see <linux/leds.h>). To set an LED to blinking, |
64 | attempt to use it before falling back to software timers. The blink_set() | 64 | however, it is better to use use the API function led_blink_set(), |
65 | function should return 0 if the blink setting is supported, or -EINVAL | 65 | as it will check and implement software fallback if necessary. |
66 | otherwise, which means that LED blinking will be handled by software. | 66 | |
67 | 67 | To turn off blinking again, use the API function led_brightness_set() | |
68 | The blink_set() function should choose a user friendly blinking | 68 | as that will not just set the LED brightness but also stop any software |
69 | value if it is called with *delay_on==0 && *delay_off==0 parameters. In | 69 | timers that may have been required for blinking. |
70 | this case the driver should give back the chosen value through delay_on | 70 | |
71 | and delay_off parameters to the leds subsystem. | 71 | The blink_set() function should choose a user friendly blinking value |
72 | if it is called with *delay_on==0 && *delay_off==0 parameters. In this | ||
73 | case the driver should give back the chosen value through delay_on and | ||
74 | delay_off parameters to the leds subsystem. | ||
72 | 75 | ||
73 | Setting the brightness to zero with brightness_set() callback function | 76 | Setting the brightness to zero with brightness_set() callback function |
74 | should completely turn off the LED and cancel the previously programmed | 77 | should completely turn off the LED and cancel the previously programmed |
diff --git a/Documentation/leds/leds-lp5521.txt b/Documentation/leds/leds-lp5521.txt new file mode 100644 index 000000000000..c4d8d151e0fe --- /dev/null +++ b/Documentation/leds/leds-lp5521.txt | |||
@@ -0,0 +1,88 @@ | |||
1 | Kernel driver for lp5521 | ||
2 | ======================== | ||
3 | |||
4 | * National Semiconductor LP5521 led driver chip | ||
5 | * Datasheet: http://www.national.com/pf/LP/LP5521.html | ||
6 | |||
7 | Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo | ||
8 | Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) | ||
9 | |||
10 | Description | ||
11 | ----------- | ||
12 | |||
13 | LP5521 can drive up to 3 channels. Leds can be controlled directly via | ||
14 | the led class control interface. Channels have generic names: | ||
15 | lp5521:channelx, where x is 0 .. 2 | ||
16 | |||
17 | All three channels can be also controlled using the engine micro programs. | ||
18 | More details of the instructions can be found from the public data sheet. | ||
19 | |||
20 | Control interface for the engines: | ||
21 | x is 1 .. 3 | ||
22 | enginex_mode : disabled, load, run | ||
23 | enginex_load : store program (visible only in engine load mode) | ||
24 | |||
25 | Example (start to blink the channel 2 led): | ||
26 | cd /sys/class/leds/lp5521:channel2/device | ||
27 | echo "load" > engine3_mode | ||
28 | echo "037f4d0003ff6000" > engine3_load | ||
29 | echo "run" > engine3_mode | ||
30 | |||
31 | stop the engine: | ||
32 | echo "disabled" > engine3_mode | ||
33 | |||
34 | sysfs contains a selftest entry. | ||
35 | The test communicates with the chip and checks that | ||
36 | the clock mode is automatically set to the requested one. | ||
37 | |||
38 | Each channel has its own led current settings. | ||
39 | /sys/class/leds/lp5521:channel0/led_current - RW | ||
40 | /sys/class/leds/lp5521:channel0/max_current - RO | ||
41 | Format: 10x mA i.e 10 means 1.0 mA | ||
42 | |||
43 | example platform data: | ||
44 | |||
45 | Note: chan_nr can have values between 0 and 2. | ||
46 | |||
47 | static struct lp5521_led_config lp5521_led_config[] = { | ||
48 | { | ||
49 | .chan_nr = 0, | ||
50 | .led_current = 50, | ||
51 | .max_current = 130, | ||
52 | }, { | ||
53 | .chan_nr = 1, | ||
54 | .led_current = 0, | ||
55 | .max_current = 130, | ||
56 | }, { | ||
57 | .chan_nr = 2, | ||
58 | .led_current = 0, | ||
59 | .max_current = 130, | ||
60 | } | ||
61 | }; | ||
62 | |||
63 | static int lp5521_setup(void) | ||
64 | { | ||
65 | /* setup HW resources */ | ||
66 | } | ||
67 | |||
68 | static void lp5521_release(void) | ||
69 | { | ||
70 | /* Release HW resources */ | ||
71 | } | ||
72 | |||
73 | static void lp5521_enable(bool state) | ||
74 | { | ||
75 | /* Control of chip enable signal */ | ||
76 | } | ||
77 | |||
78 | static struct lp5521_platform_data lp5521_platform_data = { | ||
79 | .led_config = lp5521_led_config, | ||
80 | .num_channels = ARRAY_SIZE(lp5521_led_config), | ||
81 | .clock_mode = LP5521_CLOCK_EXT, | ||
82 | .setup_resources = lp5521_setup, | ||
83 | .release_resources = lp5521_release, | ||
84 | .enable = lp5521_enable, | ||
85 | }; | ||
86 | |||
87 | If the current is set to 0 in the platform data, that channel is | ||
88 | disabled and it is not visible in the sysfs. | ||
diff --git a/Documentation/leds/leds-lp5523.txt b/Documentation/leds/leds-lp5523.txt new file mode 100644 index 000000000000..fad2feb8b7ce --- /dev/null +++ b/Documentation/leds/leds-lp5523.txt | |||
@@ -0,0 +1,83 @@ | |||
1 | Kernel driver for lp5523 | ||
2 | ======================== | ||
3 | |||
4 | * National Semiconductor LP5523 led driver chip | ||
5 | * Datasheet: http://www.national.com/pf/LP/LP5523.html | ||
6 | |||
7 | Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo | ||
8 | Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) | ||
9 | |||
10 | Description | ||
11 | ----------- | ||
12 | LP5523 can drive up to 9 channels. Leds can be controlled directly via | ||
13 | the led class control interface. Channels have generic names: | ||
14 | lp5523:channelx where x is 0...8 | ||
15 | |||
16 | The chip provides 3 engines. Each engine can control channels without | ||
17 | interaction from the main CPU. Details of the micro engine code can be found | ||
18 | from the public data sheet. Leds can be muxed to different channels. | ||
19 | |||
20 | Control interface for the engines: | ||
21 | x is 1 .. 3 | ||
22 | enginex_mode : disabled, load, run | ||
23 | enginex_load : microcode load (visible only in load mode) | ||
24 | enginex_leds : led mux control (visible only in load mode) | ||
25 | |||
26 | cd /sys/class/leds/lp5523:channel2/device | ||
27 | echo "load" > engine3_mode | ||
28 | echo "9d80400004ff05ff437f0000" > engine3_load | ||
29 | echo "111111111" > engine3_leds | ||
30 | echo "run" > engine3_mode | ||
31 | |||
32 | sysfs contains a selftest entry. It measures each channel | ||
33 | voltage level and checks if it looks reasonable. If the level is too high, | ||
34 | the led is missing; if the level is too low, there is a short circuit. | ||
35 | |||
36 | Selftest uses always the current from the platform data. | ||
37 | |||
38 | Each channel contains led current settings. | ||
39 | /sys/class/leds/lp5523:channel2/led_current - RW | ||
40 | /sys/class/leds/lp5523:channel2/max_current - RO | ||
41 | Format: 10x mA i.e 10 means 1.0 mA | ||
42 | |||
43 | Example platform data: | ||
44 | |||
45 | Note - chan_nr can have values between 0 and 8. | ||
46 | |||
47 | static struct lp5523_led_config lp5523_led_config[] = { | ||
48 | { | ||
49 | .chan_nr = 0, | ||
50 | .led_current = 50, | ||
51 | .max_current = 130, | ||
52 | }, | ||
53 | ... | ||
54 | }, { | ||
55 | .chan_nr = 8, | ||
56 | .led_current = 50, | ||
57 | .max_current = 130, | ||
58 | } | ||
59 | }; | ||
60 | |||
61 | static int lp5523_setup(void) | ||
62 | { | ||
63 | /* Setup HW resources */ | ||
64 | } | ||
65 | |||
66 | static void lp5523_release(void) | ||
67 | { | ||
68 | /* Release HW resources */ | ||
69 | } | ||
70 | |||
71 | static void lp5523_enable(bool state) | ||
72 | { | ||
73 | /* Control chip enable signal */ | ||
74 | } | ||
75 | |||
76 | static struct lp5523_platform_data lp5523_platform_data = { | ||
77 | .led_config = lp5523_led_config, | ||
78 | .num_channels = ARRAY_SIZE(lp5523_led_config), | ||
79 | .clock_mode = LP5523_CLOCK_EXT, | ||
80 | .setup_resources = lp5523_setup, | ||
81 | .release_resources = lp5523_release, | ||
82 | .enable = lp5523_enable, | ||
83 | }; | ||
diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt index 221f38be98f4..19f8278c3854 100644 --- a/Documentation/rbtree.txt +++ b/Documentation/rbtree.txt | |||
@@ -21,8 +21,8 @@ three rotations, respectively, to balance the tree), with slightly slower | |||
21 | To quote Linux Weekly News: | 21 | To quote Linux Weekly News: |
22 | 22 | ||
23 | There are a number of red-black trees in use in the kernel. | 23 | There are a number of red-black trees in use in the kernel. |
24 | The anticipatory, deadline, and CFQ I/O schedulers all employ | 24 | The deadline and CFQ I/O schedulers employ rbtrees to |
25 | rbtrees to track requests; the packet CD/DVD driver does the same. | 25 | track requests; the packet CD/DVD driver does the same. |
26 | The high-resolution timer code uses an rbtree to organize outstanding | 26 | The high-resolution timer code uses an rbtree to organize outstanding |
27 | timer requests. The ext3 filesystem tracks directory entries in a | 27 | timer requests. The ext3 filesystem tracks directory entries in a |
28 | red-black tree. Virtual memory areas (VMAs) are tracked with red-black | 28 | red-black tree. Virtual memory areas (VMAs) are tracked with red-black |
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 3894eaa23486..209e1584c3dc 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -28,6 +28,7 @@ show up in /proc/sys/kernel: | |||
28 | - core_uses_pid | 28 | - core_uses_pid |
29 | - ctrl-alt-del | 29 | - ctrl-alt-del |
30 | - dentry-state | 30 | - dentry-state |
31 | - dmesg_restrict | ||
31 | - domainname | 32 | - domainname |
32 | - hostname | 33 | - hostname |
33 | - hotplug | 34 | - hotplug |
@@ -213,6 +214,19 @@ to decide what to do with it. | |||
213 | 214 | ||
214 | ============================================================== | 215 | ============================================================== |
215 | 216 | ||
217 | dmesg_restrict: | ||
218 | |||
219 | This toggle indicates whether unprivileged users are prevented from using | ||
220 | dmesg(8) to view messages from the kernel's log buffer. When | ||
221 | dmesg_restrict is set to (0) there are no restrictions. When | ||
222 | dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use | ||
223 | dmesg(8). | ||
224 | |||
225 | The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default | ||
226 | value of dmesg_restrict. | ||
227 | |||
228 | ============================================================== | ||
229 | |||
216 | domainname & hostname: | 230 | domainname & hostname: |
217 | 231 | ||
218 | These files can be used to set the NIS/YP domainname and the | 232 | These files can be used to set the NIS/YP domainname and the |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a19a5266d5fc..8ae3d48d504c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -6,7 +6,7 @@ config ARM | |||
6 | select HAVE_MEMBLOCK | 6 | select HAVE_MEMBLOCK |
7 | select RTC_LIB | 7 | select RTC_LIB |
8 | select SYS_SUPPORTS_APM_EMULATION | 8 | select SYS_SUPPORTS_APM_EMULATION |
9 | select GENERIC_ATOMIC64 if (!CPU_32v6K) | 9 | select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI) |
10 | select HAVE_OPROFILE if (HAVE_PERF_EVENTS) | 10 | select HAVE_OPROFILE if (HAVE_PERF_EVENTS) |
11 | select HAVE_ARCH_KGDB | 11 | select HAVE_ARCH_KGDB |
12 | select HAVE_KPROBES if (!XIP_KERNEL) | 12 | select HAVE_KPROBES if (!XIP_KERNEL) |
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index ada6359160eb..772f95f1aecd 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -251,15 +251,16 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, | |||
251 | writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); | 251 | writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); |
252 | 252 | ||
253 | /* | 253 | /* |
254 | * Set priority on all interrupts. | 254 | * Set priority on all global interrupts. |
255 | */ | 255 | */ |
256 | for (i = 0; i < max_irq; i += 4) | 256 | for (i = 32; i < max_irq; i += 4) |
257 | writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); | 257 | writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); |
258 | 258 | ||
259 | /* | 259 | /* |
260 | * Disable all interrupts. | 260 | * Disable all interrupts. Leave the PPI and SGIs alone |
261 | * as these enables are banked registers. | ||
261 | */ | 262 | */ |
262 | for (i = 0; i < max_irq; i += 32) | 263 | for (i = 32; i < max_irq; i += 32) |
263 | writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); | 264 | writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); |
264 | 265 | ||
265 | /* | 266 | /* |
@@ -277,11 +278,30 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, | |||
277 | 278 | ||
278 | void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) | 279 | void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) |
279 | { | 280 | { |
281 | void __iomem *dist_base; | ||
282 | int i; | ||
283 | |||
280 | if (gic_nr >= MAX_GIC_NR) | 284 | if (gic_nr >= MAX_GIC_NR) |
281 | BUG(); | 285 | BUG(); |
282 | 286 | ||
287 | dist_base = gic_data[gic_nr].dist_base; | ||
288 | BUG_ON(!dist_base); | ||
289 | |||
283 | gic_data[gic_nr].cpu_base = base; | 290 | gic_data[gic_nr].cpu_base = base; |
284 | 291 | ||
292 | /* | ||
293 | * Deal with the banked PPI and SGI interrupts - disable all | ||
294 | * PPI interrupts, ensure all SGI interrupts are enabled. | ||
295 | */ | ||
296 | writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); | ||
297 | writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); | ||
298 | |||
299 | /* | ||
300 | * Set priority on PPI and SGI interrupts | ||
301 | */ | ||
302 | for (i = 0; i < 32; i += 4) | ||
303 | writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); | ||
304 | |||
285 | writel(0xf0, base + GIC_CPU_PRIMASK); | 305 | writel(0xf0, base + GIC_CPU_PRIMASK); |
286 | writel(1, base + GIC_CPU_CTRL); | 306 | writel(1, base + GIC_CPU_CTRL); |
287 | } | 307 | } |
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 6700c7fc7ebd..21fa272301f8 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h | |||
@@ -75,7 +75,7 @@ extern unsigned long it8152_base_address; | |||
75 | IT8152_PD_IRQ(1) USB (USBR) | 75 | IT8152_PD_IRQ(1) USB (USBR) |
76 | IT8152_PD_IRQ(0) Audio controller (ACR) | 76 | IT8152_PD_IRQ(0) Audio controller (ACR) |
77 | */ | 77 | */ |
78 | #define IT8152_IRQ(x) (IRQ_BOARD_END + (x)) | 78 | #define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) |
79 | 79 | ||
80 | /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ | 80 | /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ |
81 | #define IT8152_LD_IRQ_COUNT 9 | 81 | #define IT8152_LD_IRQ_COUNT 9 |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 54593b0c241b..21e3a4ab3b8c 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -748,8 +748,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
748 | breakpoint_handler(addr, regs); | 748 | breakpoint_handler(addr, regs); |
749 | break; | 749 | break; |
750 | case ARM_ENTRY_ASYNC_WATCHPOINT: | 750 | case ARM_ENTRY_ASYNC_WATCHPOINT: |
751 | WARN_ON("Asynchronous watchpoint exception taken. " | 751 | WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n"); |
752 | "Debugging results may be unreliable"); | ||
753 | case ARM_ENTRY_SYNC_WATCHPOINT: | 752 | case ARM_ENTRY_SYNC_WATCHPOINT: |
754 | watchpoint_handler(addr, regs); | 753 | watchpoint_handler(addr, regs); |
755 | break; | 754 | break; |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 49643b1467e6..07a50357492a 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -1749,7 +1749,7 @@ static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) | |||
1749 | static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, | 1749 | static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, |
1750 | enum armv7_counters counter) | 1750 | enum armv7_counters counter) |
1751 | { | 1751 | { |
1752 | int ret; | 1752 | int ret = 0; |
1753 | 1753 | ||
1754 | if (counter == ARMV7_CYCLE_COUNTER) | 1754 | if (counter == ARMV7_CYCLE_COUNTER) |
1755 | ret = pmnc & ARMV7_FLAG_C; | 1755 | ret = pmnc & ARMV7_FLAG_C; |
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 20b7411e47fd..c2e112e1a05f 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c | |||
@@ -28,7 +28,7 @@ int notrace unwind_frame(struct stackframe *frame) | |||
28 | 28 | ||
29 | /* only go to a higher address on the stack */ | 29 | /* only go to a higher address on the stack */ |
30 | low = frame->sp; | 30 | low = frame->sp; |
31 | high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; | 31 | high = ALIGN(low, THREAD_SIZE); |
32 | 32 | ||
33 | /* check current frame pointer is within bounds */ | 33 | /* check current frame pointer is within bounds */ |
34 | if (fp < (low + 12) || fp + 4 >= high) | 34 | if (fp < (low + 12) || fp + 4 >= high) |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index cda78d59aa31..446aee97436f 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -53,10 +53,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long); | |||
53 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) | 53 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) |
54 | { | 54 | { |
55 | #ifdef CONFIG_KALLSYMS | 55 | #ifdef CONFIG_KALLSYMS |
56 | char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN]; | 56 | printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); |
57 | sprint_symbol(sym1, where); | ||
58 | sprint_symbol(sym2, from); | ||
59 | printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2); | ||
60 | #else | 57 | #else |
61 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); | 58 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); |
62 | #endif | 59 | #endif |
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index 2a161765f6d5..d2cb0b3c9872 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c | |||
@@ -279,7 +279,7 @@ int unwind_frame(struct stackframe *frame) | |||
279 | 279 | ||
280 | /* only go to a higher address on the stack */ | 280 | /* only go to a higher address on the stack */ |
281 | low = frame->sp; | 281 | low = frame->sp; |
282 | high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; | 282 | high = ALIGN(low, THREAD_SIZE); |
283 | 283 | ||
284 | pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, | 284 | pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, |
285 | frame->pc, frame->lr, frame->sp); | 285 | frame->pc, frame->lr, frame->sp); |
diff --git a/arch/arm/mach-ep93xx/include/mach/dma.h b/arch/arm/mach-ep93xx/include/mach/dma.h index 3a5961d3f3b1..5e31b2b25da9 100644 --- a/arch/arm/mach-ep93xx/include/mach/dma.h +++ b/arch/arm/mach-ep93xx/include/mach/dma.h | |||
@@ -1,5 +1,13 @@ | |||
1 | /* | 1 | /** |
2 | * arch/arm/mach-ep93xx/include/mach/dma.h | 2 | * DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine |
3 | * | ||
4 | * The EP93xx DMA M2P subsystem handles DMA transfers between memory and | ||
5 | * peripherals. DMA M2P channels are available for audio, UARTs and IrDA. | ||
6 | * See chapter 10 of the EP93xx users guide for full details on the DMA M2P | ||
7 | * engine. | ||
8 | * | ||
9 | * See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code. | ||
10 | * | ||
3 | */ | 11 | */ |
4 | 12 | ||
5 | #ifndef __ASM_ARCH_DMA_H | 13 | #ifndef __ASM_ARCH_DMA_H |
@@ -8,12 +16,34 @@ | |||
8 | #include <linux/list.h> | 16 | #include <linux/list.h> |
9 | #include <linux/types.h> | 17 | #include <linux/types.h> |
10 | 18 | ||
19 | /** | ||
20 | * struct ep93xx_dma_buffer - Information about a buffer to be transferred | ||
21 | * using the DMA M2P engine | ||
22 | * | ||
23 | * @list: Entry in DMA buffer list | ||
24 | * @bus_addr: Physical address of the buffer | ||
25 | * @size: Size of the buffer in bytes | ||
26 | */ | ||
11 | struct ep93xx_dma_buffer { | 27 | struct ep93xx_dma_buffer { |
12 | struct list_head list; | 28 | struct list_head list; |
13 | u32 bus_addr; | 29 | u32 bus_addr; |
14 | u16 size; | 30 | u16 size; |
15 | }; | 31 | }; |
16 | 32 | ||
33 | /** | ||
34 | * struct ep93xx_dma_m2p_client - Information about a DMA M2P client | ||
35 | * | ||
36 | * @name: Unique name for this client | ||
37 | * @flags: Client flags | ||
38 | * @cookie: User data to pass to callback functions | ||
39 | * @buffer_started: Non NULL function to call when a transfer is started. | ||
40 | * The arguments are the user data cookie and the DMA | ||
41 | * buffer which is starting. | ||
42 | * @buffer_finished: Non NULL function to call when a transfer is completed. | ||
43 | * The arguments are the user data cookie, the DMA buffer | ||
44 | * which has completed, and a boolean flag indicating if | ||
45 | * the transfer had an error. | ||
46 | */ | ||
17 | struct ep93xx_dma_m2p_client { | 47 | struct ep93xx_dma_m2p_client { |
18 | char *name; | 48 | char *name; |
19 | u8 flags; | 49 | u8 flags; |
@@ -24,10 +54,11 @@ struct ep93xx_dma_m2p_client { | |||
24 | struct ep93xx_dma_buffer *buf, | 54 | struct ep93xx_dma_buffer *buf, |
25 | int bytes, int error); | 55 | int bytes, int error); |
26 | 56 | ||
27 | /* Internal to the DMA code. */ | 57 | /* private: Internal use only */ |
28 | void *channel; | 58 | void *channel; |
29 | }; | 59 | }; |
30 | 60 | ||
61 | /* DMA M2P ports */ | ||
31 | #define EP93XX_DMA_M2P_PORT_I2S1 0x00 | 62 | #define EP93XX_DMA_M2P_PORT_I2S1 0x00 |
32 | #define EP93XX_DMA_M2P_PORT_I2S2 0x01 | 63 | #define EP93XX_DMA_M2P_PORT_I2S2 0x01 |
33 | #define EP93XX_DMA_M2P_PORT_AAC1 0x02 | 64 | #define EP93XX_DMA_M2P_PORT_AAC1 0x02 |
@@ -39,18 +70,80 @@ struct ep93xx_dma_m2p_client { | |||
39 | #define EP93XX_DMA_M2P_PORT_UART3 0x08 | 70 | #define EP93XX_DMA_M2P_PORT_UART3 0x08 |
40 | #define EP93XX_DMA_M2P_PORT_IRDA 0x09 | 71 | #define EP93XX_DMA_M2P_PORT_IRDA 0x09 |
41 | #define EP93XX_DMA_M2P_PORT_MASK 0x0f | 72 | #define EP93XX_DMA_M2P_PORT_MASK 0x0f |
42 | #define EP93XX_DMA_M2P_TX 0x00 | ||
43 | #define EP93XX_DMA_M2P_RX 0x10 | ||
44 | #define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 | ||
45 | #define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 | ||
46 | #define EP93XX_DMA_M2P_ERROR_MASK 0x60 | ||
47 | 73 | ||
48 | int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p); | 74 | /* DMA M2P client flags */ |
75 | #define EP93XX_DMA_M2P_TX 0x00 /* Memory to peripheral */ | ||
76 | #define EP93XX_DMA_M2P_RX 0x10 /* Peripheral to memory */ | ||
77 | |||
78 | /* | ||
79 | * DMA M2P client error handling flags. See the EP93xx users guide | ||
80 | * documentation on the DMA M2P CONTROL register for more details | ||
81 | */ | ||
82 | #define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 /* Abort on peripheral error */ | ||
83 | #define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 /* Ignore peripheral errors */ | ||
84 | #define EP93XX_DMA_M2P_ERROR_MASK 0x60 /* Mask of error bits */ | ||
85 | |||
86 | /** | ||
87 | * ep93xx_dma_m2p_client_register - Register a client with the DMA M2P | ||
88 | * subsystem | ||
89 | * | ||
90 | * @m2p: Client information to register | ||
91 | * returns 0 on success | ||
92 | * | ||
93 | * The DMA M2P subsystem allocates a channel and an interrupt line for the DMA | ||
94 | * client | ||
95 | */ | ||
96 | int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p); | ||
97 | |||
98 | /** | ||
99 | * ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P | ||
100 | * subsystem | ||
101 | * | ||
102 | * @m2p: Client to unregister | ||
103 | * | ||
104 | * Any transfers currently in progress will be completed in hardware, but | ||
105 | * ignored in software. | ||
106 | */ | ||
49 | void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p); | 107 | void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p); |
108 | |||
109 | /** | ||
110 | * ep93xx_dma_m2p_submit - Submit a DMA M2P transfer | ||
111 | * | ||
112 | * @m2p: DMA Client to submit the transfer on | ||
113 | * @buf: DMA Buffer to submit | ||
114 | * | ||
115 | * If the current or next transfer positions are free on the M2P client then | ||
116 | * the transfer is started immediately. If not, the transfer is added to the | ||
117 | * list of pending transfers. This function must not be called from the | ||
118 | * buffer_finished callback for an M2P channel. | ||
119 | * | ||
120 | */ | ||
50 | void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p, | 121 | void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p, |
51 | struct ep93xx_dma_buffer *buf); | 122 | struct ep93xx_dma_buffer *buf); |
123 | |||
124 | /** | ||
125 | * ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list | ||
126 | * for an M2P channel | ||
127 | * | ||
128 | * @m2p: DMA Client to submit the transfer on | ||
129 | * @buf: DMA Buffer to submit | ||
130 | * | ||
131 | * This function must only be called from the buffer_finished callback for an | ||
132 | * M2P channel. It is commonly used to add the next transfer in a chained list | ||
133 | * of DMA transfers. | ||
134 | */ | ||
52 | void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p, | 135 | void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p, |
53 | struct ep93xx_dma_buffer *buf); | 136 | struct ep93xx_dma_buffer *buf); |
137 | |||
138 | /** | ||
139 | * ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client | ||
140 | * | ||
141 | * @m2p: DMA client to flush transfers on | ||
142 | * | ||
143 | * Any transfers currently in progress will be completed in hardware, but | ||
144 | * ignored in software. | ||
145 | * | ||
146 | */ | ||
54 | void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p); | 147 | void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p); |
55 | 148 | ||
56 | #endif /* __ASM_ARCH_DMA_H */ | 149 | #endif /* __ASM_ARCH_DMA_H */ |
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 51ff23b72d3a..3688123b5ad8 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -854,10 +854,9 @@ int __init kirkwood_find_tclk(void) | |||
854 | 854 | ||
855 | kirkwood_pcie_id(&dev, &rev); | 855 | kirkwood_pcie_id(&dev, &rev); |
856 | 856 | ||
857 | if ((dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 || | 857 | if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID) |
858 | rev == MV88F6281_REV_A1)) || | 858 | if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0) |
859 | (dev == MV88F6282_DEV_ID)) | 859 | return 200000000; |
860 | return 200000000; | ||
861 | 860 | ||
862 | return 166666667; | 861 | return 166666667; |
863 | } | 862 | } |
diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c index 4aa86e4a152c..a31c9499ab36 100644 --- a/arch/arm/mach-kirkwood/d2net_v2-setup.c +++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c | |||
@@ -225,5 +225,5 @@ MACHINE_START(D2NET_V2, "LaCie d2 Network v2") | |||
225 | .init_machine = d2net_v2_init, | 225 | .init_machine = d2net_v2_init, |
226 | .map_io = kirkwood_map_io, | 226 | .map_io = kirkwood_map_io, |
227 | .init_irq = kirkwood_init_irq, | 227 | .init_irq = kirkwood_init_irq, |
228 | .timer = &lacie_v2_timer, | 228 | .timer = &kirkwood_timer, |
229 | MACHINE_END | 229 | MACHINE_END |
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c index d3ea1b6c8a02..285edab776e9 100644 --- a/arch/arm/mach-kirkwood/lacie_v2-common.c +++ b/arch/arm/mach-kirkwood/lacie_v2-common.c | |||
@@ -111,17 +111,3 @@ void __init lacie_v2_hdd_power_init(int hdd_num) | |||
111 | pr_err("Failed to power up HDD%d\n", i + 1); | 111 | pr_err("Failed to power up HDD%d\n", i + 1); |
112 | } | 112 | } |
113 | } | 113 | } |
114 | |||
115 | /***************************************************************************** | ||
116 | * Timer | ||
117 | ****************************************************************************/ | ||
118 | |||
119 | static void lacie_v2_timer_init(void) | ||
120 | { | ||
121 | kirkwood_tclk = 166666667; | ||
122 | orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); | ||
123 | } | ||
124 | |||
125 | struct sys_timer lacie_v2_timer = { | ||
126 | .init = lacie_v2_timer_init, | ||
127 | }; | ||
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h index af521315b87b..fc64f578536e 100644 --- a/arch/arm/mach-kirkwood/lacie_v2-common.h +++ b/arch/arm/mach-kirkwood/lacie_v2-common.h | |||
@@ -13,6 +13,4 @@ void lacie_v2_register_flash(void); | |||
13 | void lacie_v2_register_i2c_devices(void); | 13 | void lacie_v2_register_i2c_devices(void); |
14 | void lacie_v2_hdd_power_init(int hdd_num); | 14 | void lacie_v2_hdd_power_init(int hdd_num); |
15 | 15 | ||
16 | extern struct sys_timer lacie_v2_timer; | ||
17 | |||
18 | #endif | 16 | #endif |
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c index 065187d177c6..27901f702feb 100644 --- a/arch/arm/mach-kirkwood/mpp.c +++ b/arch/arm/mach-kirkwood/mpp.c | |||
@@ -59,7 +59,7 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list) | |||
59 | } | 59 | } |
60 | printk("\n"); | 60 | printk("\n"); |
61 | 61 | ||
62 | while (*mpp_list) { | 62 | for ( ; *mpp_list; mpp_list++) { |
63 | unsigned int num = MPP_NUM(*mpp_list); | 63 | unsigned int num = MPP_NUM(*mpp_list); |
64 | unsigned int sel = MPP_SEL(*mpp_list); | 64 | unsigned int sel = MPP_SEL(*mpp_list); |
65 | int shift, gpio_mode; | 65 | int shift, gpio_mode; |
@@ -88,8 +88,6 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list) | |||
88 | if (sel != 0) | 88 | if (sel != 0) |
89 | gpio_mode = 0; | 89 | gpio_mode = 0; |
90 | orion_gpio_set_valid(num, gpio_mode); | 90 | orion_gpio_set_valid(num, gpio_mode); |
91 | |||
92 | mpp_list++; | ||
93 | } | 91 | } |
94 | 92 | ||
95 | printk(KERN_DEBUG " final MPP regs:"); | 93 | printk(KERN_DEBUG " final MPP regs:"); |
diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c index 5ea66f1f4178..65ee21fd2f3b 100644 --- a/arch/arm/mach-kirkwood/netspace_v2-setup.c +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c | |||
@@ -262,7 +262,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") | |||
262 | .init_machine = netspace_v2_init, | 262 | .init_machine = netspace_v2_init, |
263 | .map_io = kirkwood_map_io, | 263 | .map_io = kirkwood_map_io, |
264 | .init_irq = kirkwood_init_irq, | 264 | .init_irq = kirkwood_init_irq, |
265 | .timer = &lacie_v2_timer, | 265 | .timer = &kirkwood_timer, |
266 | MACHINE_END | 266 | MACHINE_END |
267 | #endif | 267 | #endif |
268 | 268 | ||
@@ -272,7 +272,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2") | |||
272 | .init_machine = netspace_v2_init, | 272 | .init_machine = netspace_v2_init, |
273 | .map_io = kirkwood_map_io, | 273 | .map_io = kirkwood_map_io, |
274 | .init_irq = kirkwood_init_irq, | 274 | .init_irq = kirkwood_init_irq, |
275 | .timer = &lacie_v2_timer, | 275 | .timer = &kirkwood_timer, |
276 | MACHINE_END | 276 | MACHINE_END |
277 | #endif | 277 | #endif |
278 | 278 | ||
@@ -282,6 +282,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2") | |||
282 | .init_machine = netspace_v2_init, | 282 | .init_machine = netspace_v2_init, |
283 | .map_io = kirkwood_map_io, | 283 | .map_io = kirkwood_map_io, |
284 | .init_irq = kirkwood_init_irq, | 284 | .init_irq = kirkwood_init_irq, |
285 | .timer = &lacie_v2_timer, | 285 | .timer = &kirkwood_timer, |
286 | MACHINE_END | 286 | MACHINE_END |
287 | #endif | 287 | #endif |
diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c index a1b45d501aef..93afd3c8bfd8 100644 --- a/arch/arm/mach-kirkwood/netxbig_v2-setup.c +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c | |||
@@ -403,7 +403,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") | |||
403 | .init_machine = netxbig_v2_init, | 403 | .init_machine = netxbig_v2_init, |
404 | .map_io = kirkwood_map_io, | 404 | .map_io = kirkwood_map_io, |
405 | .init_irq = kirkwood_init_irq, | 405 | .init_irq = kirkwood_init_irq, |
406 | .timer = &lacie_v2_timer, | 406 | .timer = &kirkwood_timer, |
407 | MACHINE_END | 407 | MACHINE_END |
408 | #endif | 408 | #endif |
409 | 409 | ||
@@ -413,6 +413,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") | |||
413 | .init_machine = netxbig_v2_init, | 413 | .init_machine = netxbig_v2_init, |
414 | .map_io = kirkwood_map_io, | 414 | .map_io = kirkwood_map_io, |
415 | .init_irq = kirkwood_init_irq, | 415 | .init_irq = kirkwood_init_irq, |
416 | .timer = &lacie_v2_timer, | 416 | .timer = &kirkwood_timer, |
417 | MACHINE_END | 417 | MACHINE_END |
418 | #endif | 418 | #endif |
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c index 8be09a0ce4ac..3587a281d993 100644 --- a/arch/arm/mach-kirkwood/ts41x-setup.c +++ b/arch/arm/mach-kirkwood/ts41x-setup.c | |||
@@ -27,6 +27,10 @@ | |||
27 | #include "mpp.h" | 27 | #include "mpp.h" |
28 | #include "tsx1x-common.h" | 28 | #include "tsx1x-common.h" |
29 | 29 | ||
30 | /* for the PCIe reset workaround */ | ||
31 | #include <plat/pcie.h> | ||
32 | |||
33 | |||
30 | #define QNAP_TS41X_JUMPER_JP1 45 | 34 | #define QNAP_TS41X_JUMPER_JP1 45 |
31 | 35 | ||
32 | static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = { | 36 | static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = { |
@@ -140,8 +144,16 @@ static void __init qnap_ts41x_init(void) | |||
140 | 144 | ||
141 | static int __init ts41x_pci_init(void) | 145 | static int __init ts41x_pci_init(void) |
142 | { | 146 | { |
143 | if (machine_is_ts41x()) | 147 | if (machine_is_ts41x()) { |
148 | /* | ||
149 | * Without this explicit reset, the PCIe SATA controller | ||
150 | * (Marvell 88sx7042/sata_mv) is known to stop working | ||
151 | * after a few minutes. | ||
152 | */ | ||
153 | orion_pcie_reset((void __iomem *)PCIE_VIRT_BASE); | ||
154 | |||
144 | kirkwood_pcie_init(KW_PCIE0); | 155 | kirkwood_pcie_init(KW_PCIE0); |
156 | } | ||
145 | 157 | ||
146 | return 0; | 158 | return 0; |
147 | } | 159 | } |
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h index f43a68b213f1..8a3b56dfd35d 100644 --- a/arch/arm/mach-mmp/include/mach/cputype.h +++ b/arch/arm/mach-mmp/include/mach/cputype.h | |||
@@ -46,7 +46,8 @@ static inline int cpu_is_pxa910(void) | |||
46 | #ifdef CONFIG_CPU_MMP2 | 46 | #ifdef CONFIG_CPU_MMP2 |
47 | static inline int cpu_is_mmp2(void) | 47 | static inline int cpu_is_mmp2(void) |
48 | { | 48 | { |
49 | return (((cpu_readid_id() >> 8) & 0xff) == 0x58); | 49 | return (((read_cpuid_id() >> 8) & 0xff) == 0x58); |
50 | } | ||
50 | #else | 51 | #else |
51 | #define cpu_is_mmp2() (0) | 52 | #define cpu_is_mmp2() (0) |
52 | #endif | 53 | #endif |
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c index 354ac514eb89..84db2dfc475c 100644 --- a/arch/arm/mach-mv78xx0/mpp.c +++ b/arch/arm/mach-mv78xx0/mpp.c | |||
@@ -54,7 +54,7 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list) | |||
54 | } | 54 | } |
55 | printk("\n"); | 55 | printk("\n"); |
56 | 56 | ||
57 | while (*mpp_list) { | 57 | for ( ; *mpp_list; mpp_list++) { |
58 | unsigned int num = MPP_NUM(*mpp_list); | 58 | unsigned int num = MPP_NUM(*mpp_list); |
59 | unsigned int sel = MPP_SEL(*mpp_list); | 59 | unsigned int sel = MPP_SEL(*mpp_list); |
60 | int shift, gpio_mode; | 60 | int shift, gpio_mode; |
@@ -83,8 +83,6 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list) | |||
83 | if (sel != 0) | 83 | if (sel != 0) |
84 | gpio_mode = 0; | 84 | gpio_mode = 0; |
85 | orion_gpio_set_valid(num, gpio_mode); | 85 | orion_gpio_set_valid(num, gpio_mode); |
86 | |||
87 | mpp_list++; | ||
88 | } | 86 | } |
89 | 87 | ||
90 | printk(KERN_DEBUG " final MPP regs:"); | 88 | printk(KERN_DEBUG " final MPP regs:"); |
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c index bc4c3b9aaf83..db485d3b8144 100644 --- a/arch/arm/mach-orion5x/mpp.c +++ b/arch/arm/mach-orion5x/mpp.c | |||
@@ -127,7 +127,7 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) | |||
127 | /* Initialize gpiolib. */ | 127 | /* Initialize gpiolib. */ |
128 | orion_gpio_init(); | 128 | orion_gpio_init(); |
129 | 129 | ||
130 | while (mode->mpp >= 0) { | 130 | for ( ; mode->mpp >= 0; mode++) { |
131 | u32 *reg; | 131 | u32 *reg; |
132 | int num_type; | 132 | int num_type; |
133 | int shift; | 133 | int shift; |
@@ -160,8 +160,6 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) | |||
160 | orion_gpio_set_unused(mode->mpp); | 160 | orion_gpio_set_unused(mode->mpp); |
161 | 161 | ||
162 | orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); | 162 | orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); |
163 | |||
164 | mode++; | ||
165 | } | 163 | } |
166 | 164 | ||
167 | writel(mpp_0_7_ctrl, MPP_0_7_CTRL); | 165 | writel(mpp_0_7_ctrl, MPP_0_7_CTRL); |
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 16f1bd5324be..c1c1cd04bdde 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c | |||
@@ -239,7 +239,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = { | |||
239 | static struct resource ts78xx_ts_nand_resources = { | 239 | static struct resource ts78xx_ts_nand_resources = { |
240 | .start = TS_NAND_DATA, | 240 | .start = TS_NAND_DATA, |
241 | .end = TS_NAND_DATA + 4, | 241 | .end = TS_NAND_DATA + 4, |
242 | .flags = IORESOURCE_IO, | 242 | .flags = IORESOURCE_MEM, |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct platform_device ts78xx_ts_nand_device = { | 245 | static struct platform_device ts78xx_ts_nand_device = { |
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index ac5598ce9724..d34b99febeb9 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c | |||
@@ -476,8 +476,6 @@ static void __init cmx2xx_init(void) | |||
476 | 476 | ||
477 | static void __init cmx2xx_init_irq(void) | 477 | static void __init cmx2xx_init_irq(void) |
478 | { | 478 | { |
479 | pxa27x_init_irq(); | ||
480 | |||
481 | if (cpu_is_pxa25x()) { | 479 | if (cpu_is_pxa25x()) { |
482 | pxa25x_init_irq(); | 480 | pxa25x_init_irq(); |
483 | cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ); | 481 | cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ); |
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index 4b521e045d75..ffa50e633ee6 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c | |||
@@ -116,7 +116,7 @@ static struct platform_device smc91x_device = { | |||
116 | }, | 116 | }, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | #if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULE) | 119 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
120 | static uint16_t lcd_power_on[] = { | 120 | static uint16_t lcd_power_on[] = { |
121 | /* single frame */ | 121 | /* single frame */ |
122 | SMART_CMD_NOOP, | 122 | SMART_CMD_NOOP, |
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 54b479c35ee0..51dcd59eda6a 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -116,4 +116,6 @@ endmenu | |||
116 | config SH_CLK_CPG | 116 | config SH_CLK_CPG |
117 | bool | 117 | bool |
118 | 118 | ||
119 | source "drivers/sh/Kconfig" | ||
120 | |||
119 | endif | 121 | endif |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 46ca4d4abf91..32d9e2816e56 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -565,12 +565,50 @@ static struct platform_device *qhd_devices[] __initdata = { | |||
565 | 565 | ||
566 | /* FSI */ | 566 | /* FSI */ |
567 | #define IRQ_FSI evt2irq(0x1840) | 567 | #define IRQ_FSI evt2irq(0x1840) |
568 | |||
569 | static int fsi_set_rate(int is_porta, int rate) | ||
570 | { | ||
571 | struct clk *fsib_clk; | ||
572 | struct clk *fdiv_clk = &sh7372_fsidivb_clk; | ||
573 | int ret; | ||
574 | |||
575 | /* set_rate is not needed if port A */ | ||
576 | if (is_porta) | ||
577 | return 0; | ||
578 | |||
579 | fsib_clk = clk_get(NULL, "fsib_clk"); | ||
580 | if (IS_ERR(fsib_clk)) | ||
581 | return -EINVAL; | ||
582 | |||
583 | switch (rate) { | ||
584 | case 48000: | ||
585 | clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); | ||
586 | clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); | ||
587 | ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; | ||
588 | break; | ||
589 | default: | ||
590 | pr_err("unsupported rate in FSI2 port B\n"); | ||
591 | ret = -EINVAL; | ||
592 | break; | ||
593 | } | ||
594 | |||
595 | clk_put(fsib_clk); | ||
596 | |||
597 | return ret; | ||
598 | } | ||
599 | |||
568 | static struct sh_fsi_platform_info fsi_info = { | 600 | static struct sh_fsi_platform_info fsi_info = { |
569 | .porta_flags = SH_FSI_BRS_INV | | 601 | .porta_flags = SH_FSI_BRS_INV | |
570 | SH_FSI_OUT_SLAVE_MODE | | 602 | SH_FSI_OUT_SLAVE_MODE | |
571 | SH_FSI_IN_SLAVE_MODE | | 603 | SH_FSI_IN_SLAVE_MODE | |
572 | SH_FSI_OFMT(PCM) | | 604 | SH_FSI_OFMT(PCM) | |
573 | SH_FSI_IFMT(PCM), | 605 | SH_FSI_IFMT(PCM), |
606 | |||
607 | .portb_flags = SH_FSI_BRS_INV | | ||
608 | SH_FSI_BRM_INV | | ||
609 | SH_FSI_LRS_INV | | ||
610 | SH_FSI_OFMT(SPDIF), | ||
611 | .set_rate = fsi_set_rate, | ||
574 | }; | 612 | }; |
575 | 613 | ||
576 | static struct resource fsi_resources[] = { | 614 | static struct resource fsi_resources[] = { |
@@ -634,6 +672,7 @@ static struct platform_device lcdc1_device = { | |||
634 | static struct sh_mobile_hdmi_info hdmi_info = { | 672 | static struct sh_mobile_hdmi_info hdmi_info = { |
635 | .lcd_chan = &sh_mobile_lcdc1_info.ch[0], | 673 | .lcd_chan = &sh_mobile_lcdc1_info.ch[0], |
636 | .lcd_dev = &lcdc1_device.dev, | 674 | .lcd_dev = &lcdc1_device.dev, |
675 | .flags = HDMI_SND_SRC_SPDIF, | ||
637 | }; | 676 | }; |
638 | 677 | ||
639 | static struct resource hdmi_resources[] = { | 678 | static struct resource hdmi_resources[] = { |
@@ -992,6 +1031,7 @@ static void __init ap4evb_map_io(void) | |||
992 | 1031 | ||
993 | #define GPIO_PORT9CR 0xE6051009 | 1032 | #define GPIO_PORT9CR 0xE6051009 |
994 | #define GPIO_PORT10CR 0xE605100A | 1033 | #define GPIO_PORT10CR 0xE605100A |
1034 | #define USCCR1 0xE6058144 | ||
995 | static void __init ap4evb_init(void) | 1035 | static void __init ap4evb_init(void) |
996 | { | 1036 | { |
997 | u32 srcr4; | 1037 | u32 srcr4; |
@@ -1062,7 +1102,7 @@ static void __init ap4evb_init(void) | |||
1062 | /* setup USB phy */ | 1102 | /* setup USB phy */ |
1063 | __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ | 1103 | __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ |
1064 | 1104 | ||
1065 | /* enable FSI2 */ | 1105 | /* enable FSI2 port A (ak4643) */ |
1066 | gpio_request(GPIO_FN_FSIAIBT, NULL); | 1106 | gpio_request(GPIO_FN_FSIAIBT, NULL); |
1067 | gpio_request(GPIO_FN_FSIAILR, NULL); | 1107 | gpio_request(GPIO_FN_FSIAILR, NULL); |
1068 | gpio_request(GPIO_FN_FSIAISLD, NULL); | 1108 | gpio_request(GPIO_FN_FSIAISLD, NULL); |
@@ -1079,6 +1119,10 @@ static void __init ap4evb_init(void) | |||
1079 | gpio_request(GPIO_PORT41, NULL); | 1119 | gpio_request(GPIO_PORT41, NULL); |
1080 | gpio_direction_input(GPIO_PORT41); | 1120 | gpio_direction_input(GPIO_PORT41); |
1081 | 1121 | ||
1122 | /* setup FSI2 port B (HDMI) */ | ||
1123 | gpio_request(GPIO_FN_FSIBCK, NULL); | ||
1124 | __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */ | ||
1125 | |||
1082 | /* set SPU2 clock to 119.6 MHz */ | 1126 | /* set SPU2 clock to 119.6 MHz */ |
1083 | clk = clk_get(NULL, "spu_clk"); | 1127 | clk = clk_get(NULL, "spu_clk"); |
1084 | if (!IS_ERR(clk)) { | 1128 | if (!IS_ERR(clk)) { |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 8565aefa21fd..7db31e6c6bf2 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -50,6 +50,9 @@ | |||
50 | #define SMSTPCR3 0xe615013c | 50 | #define SMSTPCR3 0xe615013c |
51 | #define SMSTPCR4 0xe6150140 | 51 | #define SMSTPCR4 0xe6150140 |
52 | 52 | ||
53 | #define FSIDIVA 0xFE1F8000 | ||
54 | #define FSIDIVB 0xFE1F8008 | ||
55 | |||
53 | /* Platforms must set frequency on their DV_CLKI pin */ | 56 | /* Platforms must set frequency on their DV_CLKI pin */ |
54 | struct clk sh7372_dv_clki_clk = { | 57 | struct clk sh7372_dv_clki_clk = { |
55 | }; | 58 | }; |
@@ -288,6 +291,7 @@ struct clk sh7372_pllc2_clk = { | |||
288 | .ops = &pllc2_clk_ops, | 291 | .ops = &pllc2_clk_ops, |
289 | .parent = &extal1_div2_clk, | 292 | .parent = &extal1_div2_clk, |
290 | .freq_table = pllc2_freq_table, | 293 | .freq_table = pllc2_freq_table, |
294 | .nr_freqs = ARRAY_SIZE(pllc2_freq_table) - 1, | ||
291 | .parent_table = pllc2_parent, | 295 | .parent_table = pllc2_parent, |
292 | .parent_num = ARRAY_SIZE(pllc2_parent), | 296 | .parent_num = ARRAY_SIZE(pllc2_parent), |
293 | }; | 297 | }; |
@@ -417,6 +421,101 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | |||
417 | fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), | 421 | fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), |
418 | }; | 422 | }; |
419 | 423 | ||
424 | /* FSI DIV */ | ||
425 | static unsigned long fsidiv_recalc(struct clk *clk) | ||
426 | { | ||
427 | unsigned long value; | ||
428 | |||
429 | value = __raw_readl(clk->mapping->base); | ||
430 | |||
431 | if ((value & 0x3) != 0x3) | ||
432 | return 0; | ||
433 | |||
434 | value >>= 16; | ||
435 | if (value < 2) | ||
436 | return 0; | ||
437 | |||
438 | return clk->parent->rate / value; | ||
439 | } | ||
440 | |||
441 | static long fsidiv_round_rate(struct clk *clk, unsigned long rate) | ||
442 | { | ||
443 | return clk_rate_div_range_round(clk, 2, 0xffff, rate); | ||
444 | } | ||
445 | |||
446 | static void fsidiv_disable(struct clk *clk) | ||
447 | { | ||
448 | __raw_writel(0, clk->mapping->base); | ||
449 | } | ||
450 | |||
451 | static int fsidiv_enable(struct clk *clk) | ||
452 | { | ||
453 | unsigned long value; | ||
454 | |||
455 | value = __raw_readl(clk->mapping->base) >> 16; | ||
456 | if (value < 2) { | ||
457 | fsidiv_disable(clk); | ||
458 | return -ENOENT; | ||
459 | } | ||
460 | |||
461 | __raw_writel((value << 16) | 0x3, clk->mapping->base); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static int fsidiv_set_rate(struct clk *clk, | ||
467 | unsigned long rate, int algo_id) | ||
468 | { | ||
469 | int idx; | ||
470 | |||
471 | if (clk->parent->rate == rate) { | ||
472 | fsidiv_disable(clk); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | idx = (clk->parent->rate / rate) & 0xffff; | ||
477 | if (idx < 2) | ||
478 | return -ENOENT; | ||
479 | |||
480 | __raw_writel(idx << 16, clk->mapping->base); | ||
481 | return fsidiv_enable(clk); | ||
482 | } | ||
483 | |||
484 | static struct clk_ops fsidiv_clk_ops = { | ||
485 | .recalc = fsidiv_recalc, | ||
486 | .round_rate = fsidiv_round_rate, | ||
487 | .set_rate = fsidiv_set_rate, | ||
488 | .enable = fsidiv_enable, | ||
489 | .disable = fsidiv_disable, | ||
490 | }; | ||
491 | |||
492 | static struct clk_mapping sh7372_fsidiva_clk_mapping = { | ||
493 | .phys = FSIDIVA, | ||
494 | .len = 8, | ||
495 | }; | ||
496 | |||
497 | struct clk sh7372_fsidiva_clk = { | ||
498 | .ops = &fsidiv_clk_ops, | ||
499 | .parent = &div6_reparent_clks[DIV6_FSIA], /* late install */ | ||
500 | .mapping = &sh7372_fsidiva_clk_mapping, | ||
501 | }; | ||
502 | |||
503 | static struct clk_mapping sh7372_fsidivb_clk_mapping = { | ||
504 | .phys = FSIDIVB, | ||
505 | .len = 8, | ||
506 | }; | ||
507 | |||
508 | struct clk sh7372_fsidivb_clk = { | ||
509 | .ops = &fsidiv_clk_ops, | ||
510 | .parent = &div6_reparent_clks[DIV6_FSIB], /* late install */ | ||
511 | .mapping = &sh7372_fsidivb_clk_mapping, | ||
512 | }; | ||
513 | |||
514 | static struct clk *late_main_clks[] = { | ||
515 | &sh7372_fsidiva_clk, | ||
516 | &sh7372_fsidivb_clk, | ||
517 | }; | ||
518 | |||
420 | enum { MSTP001, | 519 | enum { MSTP001, |
421 | MSTP131, MSTP130, | 520 | MSTP131, MSTP130, |
422 | MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, | 521 | MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, |
@@ -585,6 +684,9 @@ void __init sh7372_clock_init(void) | |||
585 | if (!ret) | 684 | if (!ret) |
586 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 685 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); |
587 | 686 | ||
687 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) | ||
688 | ret = clk_register(late_main_clks[k]); | ||
689 | |||
588 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 690 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
589 | 691 | ||
590 | if (!ret) | 692 | if (!ret) |
diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h index 5bc6bd444d72..2b1bb9e43dda 100644 --- a/arch/arm/mach-shmobile/include/mach/gpio.h +++ b/arch/arm/mach-shmobile/include/mach/gpio.h | |||
@@ -35,12 +35,12 @@ static inline int gpio_cansleep(unsigned gpio) | |||
35 | 35 | ||
36 | static inline int gpio_to_irq(unsigned gpio) | 36 | static inline int gpio_to_irq(unsigned gpio) |
37 | { | 37 | { |
38 | return -ENOSYS; | 38 | return __gpio_to_irq(gpio); |
39 | } | 39 | } |
40 | 40 | ||
41 | static inline int irq_to_gpio(unsigned int irq) | 41 | static inline int irq_to_gpio(unsigned int irq) |
42 | { | 42 | { |
43 | return -EINVAL; | 43 | return -ENOSYS; |
44 | } | 44 | } |
45 | 45 | ||
46 | #endif /* CONFIG_GPIOLIB */ | 46 | #endif /* CONFIG_GPIOLIB */ |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 147775a94bce..e4f9004e7103 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -464,5 +464,7 @@ extern struct clk sh7372_dv_clki_div2_clk; | |||
464 | extern struct clk sh7372_pllc2_clk; | 464 | extern struct clk sh7372_pllc2_clk; |
465 | extern struct clk sh7372_fsiack_clk; | 465 | extern struct clk sh7372_fsiack_clk; |
466 | extern struct clk sh7372_fsibck_clk; | 466 | extern struct clk sh7372_fsibck_clk; |
467 | extern struct clk sh7372_fsidiva_clk; | ||
468 | extern struct clk sh7372_fsidivb_clk; | ||
467 | 469 | ||
468 | #endif /* __ASM_SH7372_H__ */ | 470 | #endif /* __ASM_SH7372_H__ */ |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index c2e405a9e025..fd25ccd7272f 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -54,7 +54,9 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = { | |||
54 | 54 | ||
55 | static void __init ct_ca9x4_map_io(void) | 55 | static void __init ct_ca9x4_map_io(void) |
56 | { | 56 | { |
57 | #ifdef CONFIG_LOCAL_TIMERS | ||
57 | twd_base = MMIO_P2V(A9_MPCORE_TWD); | 58 | twd_base = MMIO_P2V(A9_MPCORE_TWD); |
59 | #endif | ||
58 | v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); | 60 | v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); |
59 | } | 61 | } |
60 | 62 | ||
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index e4dd0646e859..ac6a36142fcd 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -198,7 +198,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) | |||
198 | * fragmentation of the DMA space, and also prevents allocations | 198 | * fragmentation of the DMA space, and also prevents allocations |
199 | * smaller than a section from crossing a section boundary. | 199 | * smaller than a section from crossing a section boundary. |
200 | */ | 200 | */ |
201 | bit = fls(size - 1) + 1; | 201 | bit = fls(size - 1); |
202 | if (bit > SECTION_SHIFT) | 202 | if (bit > SECTION_SHIFT) |
203 | bit = SECTION_SHIFT; | 203 | bit = SECTION_SHIFT; |
204 | align = 1 << bit; | 204 | align = 1 << bit; |
diff --git a/arch/arm/plat-orion/include/plat/pcie.h b/arch/arm/plat-orion/include/plat/pcie.h index 3ebfef72b4e7..cc99163e73fd 100644 --- a/arch/arm/plat-orion/include/plat/pcie.h +++ b/arch/arm/plat-orion/include/plat/pcie.h | |||
@@ -11,12 +11,15 @@ | |||
11 | #ifndef __PLAT_PCIE_H | 11 | #ifndef __PLAT_PCIE_H |
12 | #define __PLAT_PCIE_H | 12 | #define __PLAT_PCIE_H |
13 | 13 | ||
14 | struct pci_bus; | ||
15 | |||
14 | u32 orion_pcie_dev_id(void __iomem *base); | 16 | u32 orion_pcie_dev_id(void __iomem *base); |
15 | u32 orion_pcie_rev(void __iomem *base); | 17 | u32 orion_pcie_rev(void __iomem *base); |
16 | int orion_pcie_link_up(void __iomem *base); | 18 | int orion_pcie_link_up(void __iomem *base); |
17 | int orion_pcie_x4_mode(void __iomem *base); | 19 | int orion_pcie_x4_mode(void __iomem *base); |
18 | int orion_pcie_get_local_bus_nr(void __iomem *base); | 20 | int orion_pcie_get_local_bus_nr(void __iomem *base); |
19 | void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); | 21 | void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); |
22 | void orion_pcie_reset(void __iomem *base); | ||
20 | void orion_pcie_setup(void __iomem *base, | 23 | void orion_pcie_setup(void __iomem *base, |
21 | struct mbus_dram_target_info *dram); | 24 | struct mbus_dram_target_info *dram); |
22 | int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, | 25 | int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, |
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index 779553a1595e..af2d733c50b5 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c | |||
@@ -182,11 +182,6 @@ void __init orion_pcie_setup(void __iomem *base, | |||
182 | u32 mask; | 182 | u32 mask; |
183 | 183 | ||
184 | /* | 184 | /* |
185 | * soft reset PCIe unit | ||
186 | */ | ||
187 | orion_pcie_reset(base); | ||
188 | |||
189 | /* | ||
190 | * Point PCIe unit MBUS decode windows to DRAM space. | 185 | * Point PCIe unit MBUS decode windows to DRAM space. |
191 | */ | 186 | */ |
192 | orion_pcie_setup_wins(base, dram); | 187 | orion_pcie_setup_wins(base, dram); |
diff --git a/arch/m68k/include/asm/irqflags.h b/arch/m68k/include/asm/irqflags.h index 4a5b284a1550..7ef4115b8c4a 100644 --- a/arch/m68k/include/asm/irqflags.h +++ b/arch/m68k/include/asm/irqflags.h | |||
@@ -2,7 +2,9 @@ | |||
2 | #define _M68K_IRQFLAGS_H | 2 | #define _M68K_IRQFLAGS_H |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #ifdef CONFIG_MMU | ||
5 | #include <linux/hardirq.h> | 6 | #include <linux/hardirq.h> |
7 | #endif | ||
6 | #include <linux/preempt.h> | 8 | #include <linux/preempt.h> |
7 | #include <asm/thread_info.h> | 9 | #include <asm/thread_info.h> |
8 | #include <asm/entry.h> | 10 | #include <asm/entry.h> |
diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h index 789f3b2de0e9..415d5484916c 100644 --- a/arch/m68k/include/asm/machdep.h +++ b/arch/m68k/include/asm/machdep.h | |||
@@ -40,5 +40,6 @@ extern unsigned long hw_timer_offset(void); | |||
40 | extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); | 40 | extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); |
41 | 41 | ||
42 | extern void config_BSP(char *command, int len); | 42 | extern void config_BSP(char *command, int len); |
43 | extern void do_IRQ(int irq, struct pt_regs *fp); | ||
43 | 44 | ||
44 | #endif /* _M68K_MACHDEP_H */ | 45 | #endif /* _M68K_MACHDEP_H */ |
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 428d0e538aec..b06bdae04064 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c | |||
@@ -127,7 +127,7 @@ static void kvm_patch_ins_nop(u32 *inst) | |||
127 | 127 | ||
128 | static void kvm_patch_ins_b(u32 *inst, int addr) | 128 | static void kvm_patch_ins_b(u32 *inst, int addr) |
129 | { | 129 | { |
130 | #ifdef CONFIG_RELOCATABLE | 130 | #if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC_BOOK3S) |
131 | /* On relocatable kernels interrupts handlers and our code | 131 | /* On relocatable kernels interrupts handlers and our code |
132 | can be in different regions, so we don't patch them */ | 132 | can be in different regions, so we don't patch them */ |
133 | 133 | ||
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 049846911ce4..1cc471faac2d 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -416,7 +416,7 @@ lightweight_exit: | |||
416 | lwz r3, VCPU_PC(r4) | 416 | lwz r3, VCPU_PC(r4) |
417 | mtsrr0 r3 | 417 | mtsrr0 r3 |
418 | lwz r3, VCPU_SHARED(r4) | 418 | lwz r3, VCPU_SHARED(r4) |
419 | lwz r3, VCPU_SHARED_MSR(r3) | 419 | lwz r3, (VCPU_SHARED_MSR + 4)(r3) |
420 | oris r3, r3, KVMPPC_MSR_MASK@h | 420 | oris r3, r3, KVMPPC_MSR_MASK@h |
421 | ori r3, r3, KVMPPC_MSR_MASK@l | 421 | ori r3, r3, KVMPPC_MSR_MASK@l |
422 | mtsrr1 r3 | 422 | mtsrr1 r3 |
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 71750f2dd5d3..e3768ee9b595 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c | |||
@@ -138,8 +138,8 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) | |||
138 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); | 138 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); |
139 | 139 | ||
140 | free_page((unsigned long)vcpu->arch.shared); | 140 | free_page((unsigned long)vcpu->arch.shared); |
141 | kvmppc_e500_tlb_uninit(vcpu_e500); | ||
142 | kvm_vcpu_uninit(vcpu); | 141 | kvm_vcpu_uninit(vcpu); |
142 | kvmppc_e500_tlb_uninit(vcpu_e500); | ||
143 | kmem_cache_free(kvm_vcpu_cache, vcpu_e500); | 143 | kmem_cache_free(kvm_vcpu_cache, vcpu_e500); |
144 | } | 144 | } |
145 | 145 | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2f87a1627f6c..38f756f25053 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -617,6 +617,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
617 | switch (ioctl) { | 617 | switch (ioctl) { |
618 | case KVM_PPC_GET_PVINFO: { | 618 | case KVM_PPC_GET_PVINFO: { |
619 | struct kvm_ppc_pvinfo pvinfo; | 619 | struct kvm_ppc_pvinfo pvinfo; |
620 | memset(&pvinfo, 0, sizeof(pvinfo)); | ||
620 | r = kvm_vm_ioctl_get_pvinfo(&pvinfo); | 621 | r = kvm_vm_ioctl_get_pvinfo(&pvinfo); |
621 | if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) { | 622 | if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) { |
622 | r = -EFAULT; | 623 | r = -EFAULT; |
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index 46fa04f12a9b..a021f5827a33 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c | |||
@@ -35,7 +35,6 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) | |||
35 | int i; | 35 | int i; |
36 | 36 | ||
37 | /* pause guest execution to avoid concurrent updates */ | 37 | /* pause guest execution to avoid concurrent updates */ |
38 | local_irq_disable(); | ||
39 | mutex_lock(&vcpu->mutex); | 38 | mutex_lock(&vcpu->mutex); |
40 | 39 | ||
41 | vcpu->arch.last_exit_type = 0xDEAD; | 40 | vcpu->arch.last_exit_type = 0xDEAD; |
@@ -51,7 +50,6 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) | |||
51 | vcpu->arch.timing_last_enter.tv64 = 0; | 50 | vcpu->arch.timing_last_enter.tv64 = 0; |
52 | 51 | ||
53 | mutex_unlock(&vcpu->mutex); | 52 | mutex_unlock(&vcpu->mutex); |
54 | local_irq_enable(); | ||
55 | } | 53 | } |
56 | 54 | ||
57 | static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) | 55 | static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5c075f562eba..7f217b3a50a8 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -193,6 +193,7 @@ config CPU_SH2 | |||
193 | config CPU_SH2A | 193 | config CPU_SH2A |
194 | bool | 194 | bool |
195 | select CPU_SH2 | 195 | select CPU_SH2 |
196 | select UNCACHED_MAPPING | ||
196 | 197 | ||
197 | config CPU_SH3 | 198 | config CPU_SH3 |
198 | bool | 199 | bool |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 307b3a4a790b..9c8c6e1a2a15 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -133,10 +133,7 @@ machdir-$(CONFIG_SOLUTION_ENGINE) += mach-se | |||
133 | machdir-$(CONFIG_SH_HP6XX) += mach-hp6xx | 133 | machdir-$(CONFIG_SH_HP6XX) += mach-hp6xx |
134 | machdir-$(CONFIG_SH_DREAMCAST) += mach-dreamcast | 134 | machdir-$(CONFIG_SH_DREAMCAST) += mach-dreamcast |
135 | machdir-$(CONFIG_SH_SH03) += mach-sh03 | 135 | machdir-$(CONFIG_SH_SH03) += mach-sh03 |
136 | machdir-$(CONFIG_SH_SECUREEDGE5410) += mach-snapgear | ||
137 | machdir-$(CONFIG_SH_RTS7751R2D) += mach-r2d | 136 | machdir-$(CONFIG_SH_RTS7751R2D) += mach-r2d |
138 | machdir-$(CONFIG_SH_7751_SYSTEMH) += mach-systemh | ||
139 | machdir-$(CONFIG_SH_EDOSK7705) += mach-edosk7705 | ||
140 | machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander | 137 | machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander |
141 | machdir-$(CONFIG_SH_MIGOR) += mach-migor | 138 | machdir-$(CONFIG_SH_MIGOR) += mach-migor |
142 | machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa | 139 | machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa |
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 9c94711aa6ca..2018c7ea4c93 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig | |||
@@ -81,13 +81,6 @@ config SH_7343_SOLUTION_ENGINE | |||
81 | Select 7343 SolutionEngine if configuring for a Hitachi | 81 | Select 7343 SolutionEngine if configuring for a Hitachi |
82 | SH7343 (SH-Mobile 3AS) evaluation board. | 82 | SH7343 (SH-Mobile 3AS) evaluation board. |
83 | 83 | ||
84 | config SH_7751_SYSTEMH | ||
85 | bool "SystemH7751R" | ||
86 | depends on CPU_SUBTYPE_SH7751R | ||
87 | help | ||
88 | Select SystemH if you are configuring for a Renesas SystemH | ||
89 | 7751R evaluation board. | ||
90 | |||
91 | config SH_HP6XX | 84 | config SH_HP6XX |
92 | bool "HP6XX" | 85 | bool "HP6XX" |
93 | select SYS_SUPPORTS_APM_EMULATION | 86 | select SYS_SUPPORTS_APM_EMULATION |
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index 38ef655cc0f0..be7d11d04b26 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile | |||
@@ -2,10 +2,12 @@ | |||
2 | # Specific board support, not covered by a mach group. | 2 | # Specific board support, not covered by a mach group. |
3 | # | 3 | # |
4 | obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o | 4 | obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o |
5 | obj-$(CONFIG_SH_SECUREEDGE5410) += board-secureedge5410.o | ||
5 | obj-$(CONFIG_SH_SH2007) += board-sh2007.o | 6 | obj-$(CONFIG_SH_SH2007) += board-sh2007.o |
6 | obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o | 7 | obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o |
7 | obj-$(CONFIG_SH_URQUELL) += board-urquell.o | 8 | obj-$(CONFIG_SH_URQUELL) += board-urquell.o |
8 | obj-$(CONFIG_SH_SHMIN) += board-shmin.o | 9 | obj-$(CONFIG_SH_SHMIN) += board-shmin.o |
10 | obj-$(CONFIG_SH_EDOSK7705) += board-edosk7705.o | ||
9 | obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o | 11 | obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o |
10 | obj-$(CONFIG_SH_ESPT) += board-espt.o | 12 | obj-$(CONFIG_SH_ESPT) += board-espt.o |
11 | obj-$(CONFIG_SH_POLARIS) += board-polaris.o | 13 | obj-$(CONFIG_SH_POLARIS) += board-polaris.o |
diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c new file mode 100644 index 000000000000..4cb3bb74c36f --- /dev/null +++ b/arch/sh/boards/board-edosk7705.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/renesas/edosk7705/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SolutionEngine Support. | ||
7 | * | ||
8 | * Modified for edosk7705 development | ||
9 | * board by S. Dunn, 2003. | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/smc91x.h> | ||
16 | #include <asm/machvec.h> | ||
17 | #include <asm/sizes.h> | ||
18 | |||
19 | #define SMC_IOBASE 0xA2000000 | ||
20 | #define SMC_IO_OFFSET 0x300 | ||
21 | #define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET) | ||
22 | |||
23 | #define ETHERNET_IRQ 0x09 | ||
24 | |||
25 | static void __init sh_edosk7705_init_irq(void) | ||
26 | { | ||
27 | make_imask_irq(ETHERNET_IRQ); | ||
28 | } | ||
29 | |||
30 | /* eth initialization functions */ | ||
31 | static struct smc91x_platdata smc91x_info = { | ||
32 | .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL, | ||
33 | }; | ||
34 | |||
35 | static struct resource smc91x_res[] = { | ||
36 | [0] = { | ||
37 | .start = SMC_IOADDR, | ||
38 | .end = SMC_IOADDR + SZ_32 - 1, | ||
39 | .flags = IORESOURCE_MEM, | ||
40 | }, | ||
41 | [1] = { | ||
42 | .start = ETHERNET_IRQ, | ||
43 | .end = ETHERNET_IRQ, | ||
44 | .flags = IORESOURCE_IRQ , | ||
45 | } | ||
46 | }; | ||
47 | |||
48 | static struct platform_device smc91x_dev = { | ||
49 | .name = "smc91x", | ||
50 | .id = -1, | ||
51 | .num_resources = ARRAY_SIZE(smc91x_res), | ||
52 | .resource = smc91x_res, | ||
53 | |||
54 | .dev = { | ||
55 | .platform_data = &smc91x_info, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | /* platform init code */ | ||
60 | static struct platform_device *edosk7705_devices[] __initdata = { | ||
61 | &smc91x_dev, | ||
62 | }; | ||
63 | |||
64 | static int __init init_edosk7705_devices(void) | ||
65 | { | ||
66 | return platform_add_devices(edosk7705_devices, | ||
67 | ARRAY_SIZE(edosk7705_devices)); | ||
68 | } | ||
69 | __initcall(init_edosk7705_devices); | ||
70 | |||
71 | /* | ||
72 | * The Machine Vector | ||
73 | */ | ||
74 | static struct sh_machine_vector mv_edosk7705 __initmv = { | ||
75 | .mv_name = "EDOSK7705", | ||
76 | .mv_nr_irqs = 80, | ||
77 | .mv_init_irq = sh_edosk7705_init_irq, | ||
78 | }; | ||
diff --git a/arch/sh/boards/mach-snapgear/setup.c b/arch/sh/boards/board-secureedge5410.c index 331745dee379..32f875e8493d 100644 --- a/arch/sh/boards/mach-snapgear/setup.c +++ b/arch/sh/boards/board-secureedge5410.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/sh/boards/snapgear/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2002 David McCullough <davidm@snapgear.com> | 2 | * Copyright (C) 2002 David McCullough <davidm@snapgear.com> |
5 | * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> | 3 | * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> |
6 | * | 4 | * |
@@ -19,18 +17,19 @@ | |||
19 | #include <linux/module.h> | 17 | #include <linux/module.h> |
20 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
21 | #include <asm/machvec.h> | 19 | #include <asm/machvec.h> |
22 | #include <mach/snapgear.h> | 20 | #include <mach/secureedge5410.h> |
23 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
24 | #include <asm/io.h> | 22 | #include <asm/io.h> |
25 | #include <cpu/timer.h> | 23 | #include <cpu/timer.h> |
26 | 24 | ||
25 | unsigned short secureedge5410_ioport; | ||
26 | |||
27 | /* | 27 | /* |
28 | * EraseConfig handling functions | 28 | * EraseConfig handling functions |
29 | */ | 29 | */ |
30 | |||
31 | static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) | 30 | static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) |
32 | { | 31 | { |
33 | (void)__raw_readb(0xb8000000); /* dummy read */ | 32 | ctrl_delay(); /* dummy read */ |
34 | 33 | ||
35 | printk("SnapGear: erase switch interrupt!\n"); | 34 | printk("SnapGear: erase switch interrupt!\n"); |
36 | 35 | ||
@@ -39,21 +38,22 @@ static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) | |||
39 | 38 | ||
40 | static int __init eraseconfig_init(void) | 39 | static int __init eraseconfig_init(void) |
41 | { | 40 | { |
41 | unsigned int irq = evt2irq(0x240); | ||
42 | |||
42 | printk("SnapGear: EraseConfig init\n"); | 43 | printk("SnapGear: EraseConfig init\n"); |
44 | |||
43 | /* Setup "EraseConfig" switch on external IRQ 0 */ | 45 | /* Setup "EraseConfig" switch on external IRQ 0 */ |
44 | if (request_irq(IRL0_IRQ, eraseconfig_interrupt, IRQF_DISABLED, | 46 | if (request_irq(irq, eraseconfig_interrupt, IRQF_DISABLED, |
45 | "Erase Config", NULL)) | 47 | "Erase Config", NULL)) |
46 | printk("SnapGear: failed to register IRQ%d for Reset witch\n", | 48 | printk("SnapGear: failed to register IRQ%d for Reset witch\n", |
47 | IRL0_IRQ); | 49 | irq); |
48 | else | 50 | else |
49 | printk("SnapGear: registered EraseConfig switch on IRQ%d\n", | 51 | printk("SnapGear: registered EraseConfig switch on IRQ%d\n", |
50 | IRL0_IRQ); | 52 | irq); |
51 | return(0); | 53 | return 0; |
52 | } | 54 | } |
53 | |||
54 | module_init(eraseconfig_init); | 55 | module_init(eraseconfig_init); |
55 | 56 | ||
56 | /****************************************************************************/ | ||
57 | /* | 57 | /* |
58 | * Initialize IRQ setting | 58 | * Initialize IRQ setting |
59 | * | 59 | * |
@@ -62,7 +62,6 @@ module_init(eraseconfig_init); | |||
62 | * IRL2 = eth1 | 62 | * IRL2 = eth1 |
63 | * IRL3 = crypto | 63 | * IRL3 = crypto |
64 | */ | 64 | */ |
65 | |||
66 | static void __init init_snapgear_IRQ(void) | 65 | static void __init init_snapgear_IRQ(void) |
67 | { | 66 | { |
68 | printk("Setup SnapGear IRQ/IPR ...\n"); | 67 | printk("Setup SnapGear IRQ/IPR ...\n"); |
@@ -76,20 +75,5 @@ static void __init init_snapgear_IRQ(void) | |||
76 | static struct sh_machine_vector mv_snapgear __initmv = { | 75 | static struct sh_machine_vector mv_snapgear __initmv = { |
77 | .mv_name = "SnapGear SecureEdge5410", | 76 | .mv_name = "SnapGear SecureEdge5410", |
78 | .mv_nr_irqs = 72, | 77 | .mv_nr_irqs = 72, |
79 | |||
80 | .mv_inb = snapgear_inb, | ||
81 | .mv_inw = snapgear_inw, | ||
82 | .mv_inl = snapgear_inl, | ||
83 | .mv_outb = snapgear_outb, | ||
84 | .mv_outw = snapgear_outw, | ||
85 | .mv_outl = snapgear_outl, | ||
86 | |||
87 | .mv_inb_p = snapgear_inb_p, | ||
88 | .mv_inw_p = snapgear_inw, | ||
89 | .mv_inl_p = snapgear_inl, | ||
90 | .mv_outb_p = snapgear_outb_p, | ||
91 | .mv_outw_p = snapgear_outw, | ||
92 | .mv_outl_p = snapgear_outl, | ||
93 | |||
94 | .mv_init_irq = init_snapgear_IRQ, | 78 | .mv_init_irq = init_snapgear_IRQ, |
95 | }; | 79 | }; |
diff --git a/arch/sh/boards/mach-edosk7705/Makefile b/arch/sh/boards/mach-edosk7705/Makefile deleted file mode 100644 index cd54acb51499..000000000000 --- a/arch/sh/boards/mach-edosk7705/Makefile +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the EDOSK7705 specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := setup.o io.o | ||
diff --git a/arch/sh/boards/mach-edosk7705/io.c b/arch/sh/boards/mach-edosk7705/io.c deleted file mode 100644 index 5b9c57c43241..000000000000 --- a/arch/sh/boards/mach-edosk7705/io.c +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/renesas/edosk7705/io.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel | ||
5 | * Based largely on io_se.c. | ||
6 | * | ||
7 | * I/O routines for Hitachi EDOSK7705 board. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <mach/edosk7705.h> | ||
15 | #include <asm/addrspace.h> | ||
16 | |||
17 | #define SMC_IOADDR 0xA2000000 | ||
18 | |||
19 | /* Map the Ethernet addresses as if it is at 0x300 - 0x320 */ | ||
20 | static unsigned long sh_edosk7705_isa_port2addr(unsigned long port) | ||
21 | { | ||
22 | /* | ||
23 | * SMC91C96 registers are 4 byte aligned rather than the | ||
24 | * usual 2 byte! | ||
25 | */ | ||
26 | if (port >= 0x300 && port < 0x320) | ||
27 | return SMC_IOADDR + ((port - 0x300) * 2); | ||
28 | |||
29 | maybebadio(port); | ||
30 | return port; | ||
31 | } | ||
32 | |||
33 | /* Trying to read / write bytes on odd-byte boundaries to the Ethernet | ||
34 | * registers causes problems. So we bit-shift the value and read / write | ||
35 | * in 2 byte chunks. Setting the low byte to 0 does not cause problems | ||
36 | * now as odd byte writes are only made on the bit mask / interrupt | ||
37 | * register. This may not be the case in future Mar-2003 SJD | ||
38 | */ | ||
39 | unsigned char sh_edosk7705_inb(unsigned long port) | ||
40 | { | ||
41 | if (port >= 0x300 && port < 0x320 && port & 0x01) | ||
42 | return __raw_readw(port - 1) >> 8; | ||
43 | |||
44 | return __raw_readb(sh_edosk7705_isa_port2addr(port)); | ||
45 | } | ||
46 | |||
47 | void sh_edosk7705_outb(unsigned char value, unsigned long port) | ||
48 | { | ||
49 | if (port >= 0x300 && port < 0x320 && port & 0x01) { | ||
50 | __raw_writew(((unsigned short)value << 8), port - 1); | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | __raw_writeb(value, sh_edosk7705_isa_port2addr(port)); | ||
55 | } | ||
56 | |||
57 | void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count) | ||
58 | { | ||
59 | unsigned char *p = addr; | ||
60 | |||
61 | while (count--) | ||
62 | *p++ = sh_edosk7705_inb(port); | ||
63 | } | ||
64 | |||
65 | void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count) | ||
66 | { | ||
67 | unsigned char *p = (unsigned char *)addr; | ||
68 | |||
69 | while (count--) | ||
70 | sh_edosk7705_outb(*p++, port); | ||
71 | } | ||
diff --git a/arch/sh/boards/mach-edosk7705/setup.c b/arch/sh/boards/mach-edosk7705/setup.c deleted file mode 100644 index d59225e26fb9..000000000000 --- a/arch/sh/boards/mach-edosk7705/setup.c +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/renesas/edosk7705/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SolutionEngine Support. | ||
7 | * | ||
8 | * Modified for edosk7705 development | ||
9 | * board by S. Dunn, 2003. | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <asm/machvec.h> | ||
14 | #include <mach/edosk7705.h> | ||
15 | |||
16 | static void __init sh_edosk7705_init_irq(void) | ||
17 | { | ||
18 | /* This is the Ethernet interrupt */ | ||
19 | make_imask_irq(0x09); | ||
20 | } | ||
21 | |||
22 | /* | ||
23 | * The Machine Vector | ||
24 | */ | ||
25 | static struct sh_machine_vector mv_edosk7705 __initmv = { | ||
26 | .mv_name = "EDOSK7705", | ||
27 | .mv_nr_irqs = 80, | ||
28 | |||
29 | .mv_inb = sh_edosk7705_inb, | ||
30 | .mv_outb = sh_edosk7705_outb, | ||
31 | |||
32 | .mv_insb = sh_edosk7705_insb, | ||
33 | .mv_outsb = sh_edosk7705_outsb, | ||
34 | |||
35 | .mv_init_irq = sh_edosk7705_init_irq, | ||
36 | }; | ||
diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c index 2960c659020e..acdafb0c6404 100644 --- a/arch/sh/boards/mach-microdev/io.c +++ b/arch/sh/boards/mach-microdev/io.c | |||
@@ -54,7 +54,7 @@ | |||
54 | /* | 54 | /* |
55 | * map I/O ports to memory-mapped addresses | 55 | * map I/O ports to memory-mapped addresses |
56 | */ | 56 | */ |
57 | static unsigned long microdev_isa_port2addr(unsigned long offset) | 57 | void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) |
58 | { | 58 | { |
59 | unsigned long result; | 59 | unsigned long result; |
60 | 60 | ||
@@ -72,16 +72,6 @@ static unsigned long microdev_isa_port2addr(unsigned long offset) | |||
72 | * Configuration Registers | 72 | * Configuration Registers |
73 | */ | 73 | */ |
74 | result = IO_SUPERIO_PHYS + (offset << 1); | 74 | result = IO_SUPERIO_PHYS + (offset << 1); |
75 | #if 0 | ||
76 | } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG || | ||
77 | offset == KBD_STATUS_REG) { | ||
78 | /* | ||
79 | * SMSC FDC37C93xAPM SuperIO chip | ||
80 | * | ||
81 | * PS/2 Keyboard + Mouse (ports 0x60 and 0x64). | ||
82 | */ | ||
83 | result = IO_SUPERIO_PHYS + (offset << 1); | ||
84 | #endif | ||
85 | } else if (((offset >= IO_IDE1_BASE) && | 75 | } else if (((offset >= IO_IDE1_BASE) && |
86 | (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || | 76 | (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || |
87 | (offset == IO_IDE1_MISC)) { | 77 | (offset == IO_IDE1_MISC)) { |
@@ -131,237 +121,5 @@ static unsigned long microdev_isa_port2addr(unsigned long offset) | |||
131 | result = PVR; | 121 | result = PVR; |
132 | } | 122 | } |
133 | 123 | ||
134 | return result; | 124 | return (void __iomem *)result; |
135 | } | ||
136 | |||
137 | #define PORT2ADDR(x) (microdev_isa_port2addr(x)) | ||
138 | |||
139 | static inline void delay(void) | ||
140 | { | ||
141 | #if defined(CONFIG_PCI) | ||
142 | /* System board present, just make a dummy SRAM access. (CS0 will be | ||
143 | mapped to PCI memory, probably good to avoid it.) */ | ||
144 | __raw_readw(0xa6800000); | ||
145 | #else | ||
146 | /* CS0 will be mapped to flash, ROM etc so safe to access it. */ | ||
147 | __raw_readw(0xa0000000); | ||
148 | #endif | ||
149 | } | ||
150 | |||
151 | unsigned char microdev_inb(unsigned long port) | ||
152 | { | ||
153 | #ifdef CONFIG_PCI | ||
154 | if (port >= PCIBIOS_MIN_IO) | ||
155 | return microdev_pci_inb(port); | ||
156 | #endif | ||
157 | return *(volatile unsigned char*)PORT2ADDR(port); | ||
158 | } | ||
159 | |||
160 | unsigned short microdev_inw(unsigned long port) | ||
161 | { | ||
162 | #ifdef CONFIG_PCI | ||
163 | if (port >= PCIBIOS_MIN_IO) | ||
164 | return microdev_pci_inw(port); | ||
165 | #endif | ||
166 | return *(volatile unsigned short*)PORT2ADDR(port); | ||
167 | } | ||
168 | |||
169 | unsigned int microdev_inl(unsigned long port) | ||
170 | { | ||
171 | #ifdef CONFIG_PCI | ||
172 | if (port >= PCIBIOS_MIN_IO) | ||
173 | return microdev_pci_inl(port); | ||
174 | #endif | ||
175 | return *(volatile unsigned int*)PORT2ADDR(port); | ||
176 | } | ||
177 | |||
178 | void microdev_outw(unsigned short b, unsigned long port) | ||
179 | { | ||
180 | #ifdef CONFIG_PCI | ||
181 | if (port >= PCIBIOS_MIN_IO) { | ||
182 | microdev_pci_outw(b, port); | ||
183 | return; | ||
184 | } | ||
185 | #endif | ||
186 | *(volatile unsigned short*)PORT2ADDR(port) = b; | ||
187 | } | ||
188 | |||
189 | void microdev_outb(unsigned char b, unsigned long port) | ||
190 | { | ||
191 | #ifdef CONFIG_PCI | ||
192 | if (port >= PCIBIOS_MIN_IO) { | ||
193 | microdev_pci_outb(b, port); | ||
194 | return; | ||
195 | } | ||
196 | #endif | ||
197 | |||
198 | /* | ||
199 | * There is a board feature with the current SH4-202 MicroDev in | ||
200 | * that the 2 byte enables (nBE0 and nBE1) are tied together (and | ||
201 | * to the Chip Select Line (Ethernet_CS)). Due to this connectivity, | ||
202 | * it is not possible to safely perform 8-bit writes to the | ||
203 | * Ethernet registers, as 16-bits will be consumed from the Data | ||
204 | * lines (corrupting the other byte). Hence, this function is | ||
205 | * written to implement 16-bit read/modify/write for all byte-wide | ||
206 | * accesses. | ||
207 | * | ||
208 | * Note: there is no problem with byte READS (even or odd). | ||
209 | * | ||
210 | * Sean McGoogan - 16th June 2003. | ||
211 | */ | ||
212 | if ((port >= IO_LAN91C111_BASE) && | ||
213 | (port < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { | ||
214 | /* | ||
215 | * Then are trying to perform a byte-write to the | ||
216 | * LAN91C111. This needs special care. | ||
217 | */ | ||
218 | if (port % 2 == 1) { /* is the port odd ? */ | ||
219 | /* unset bit-0, i.e. make even */ | ||
220 | const unsigned long evenPort = port-1; | ||
221 | unsigned short word; | ||
222 | |||
223 | /* | ||
224 | * do a 16-bit read/write to write to 'port', | ||
225 | * preserving even byte. | ||
226 | * | ||
227 | * Even addresses are bits 0-7 | ||
228 | * Odd addresses are bits 8-15 | ||
229 | */ | ||
230 | word = microdev_inw(evenPort); | ||
231 | word = (word & 0xffu) | (b << 8); | ||
232 | microdev_outw(word, evenPort); | ||
233 | } else { | ||
234 | /* else, we are trying to do an even byte write */ | ||
235 | unsigned short word; | ||
236 | |||
237 | /* | ||
238 | * do a 16-bit read/write to write to 'port', | ||
239 | * preserving odd byte. | ||
240 | * | ||
241 | * Even addresses are bits 0-7 | ||
242 | * Odd addresses are bits 8-15 | ||
243 | */ | ||
244 | word = microdev_inw(port); | ||
245 | word = (word & 0xff00u) | (b); | ||
246 | microdev_outw(word, port); | ||
247 | } | ||
248 | } else { | ||
249 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | void microdev_outl(unsigned int b, unsigned long port) | ||
254 | { | ||
255 | #ifdef CONFIG_PCI | ||
256 | if (port >= PCIBIOS_MIN_IO) { | ||
257 | microdev_pci_outl(b, port); | ||
258 | return; | ||
259 | } | ||
260 | #endif | ||
261 | *(volatile unsigned int*)PORT2ADDR(port) = b; | ||
262 | } | ||
263 | |||
264 | unsigned char microdev_inb_p(unsigned long port) | ||
265 | { | ||
266 | unsigned char v = microdev_inb(port); | ||
267 | delay(); | ||
268 | return v; | ||
269 | } | ||
270 | |||
271 | unsigned short microdev_inw_p(unsigned long port) | ||
272 | { | ||
273 | unsigned short v = microdev_inw(port); | ||
274 | delay(); | ||
275 | return v; | ||
276 | } | ||
277 | |||
278 | unsigned int microdev_inl_p(unsigned long port) | ||
279 | { | ||
280 | unsigned int v = microdev_inl(port); | ||
281 | delay(); | ||
282 | return v; | ||
283 | } | ||
284 | |||
285 | void microdev_outb_p(unsigned char b, unsigned long port) | ||
286 | { | ||
287 | microdev_outb(b, port); | ||
288 | delay(); | ||
289 | } | ||
290 | |||
291 | void microdev_outw_p(unsigned short b, unsigned long port) | ||
292 | { | ||
293 | microdev_outw(b, port); | ||
294 | delay(); | ||
295 | } | ||
296 | |||
297 | void microdev_outl_p(unsigned int b, unsigned long port) | ||
298 | { | ||
299 | microdev_outl(b, port); | ||
300 | delay(); | ||
301 | } | ||
302 | |||
303 | void microdev_insb(unsigned long port, void *buffer, unsigned long count) | ||
304 | { | ||
305 | volatile unsigned char *port_addr; | ||
306 | unsigned char *buf = buffer; | ||
307 | |||
308 | port_addr = (volatile unsigned char *)PORT2ADDR(port); | ||
309 | |||
310 | while (count--) | ||
311 | *buf++ = *port_addr; | ||
312 | } | ||
313 | |||
314 | void microdev_insw(unsigned long port, void *buffer, unsigned long count) | ||
315 | { | ||
316 | volatile unsigned short *port_addr; | ||
317 | unsigned short *buf = buffer; | ||
318 | |||
319 | port_addr = (volatile unsigned short *)PORT2ADDR(port); | ||
320 | |||
321 | while (count--) | ||
322 | *buf++ = *port_addr; | ||
323 | } | ||
324 | |||
325 | void microdev_insl(unsigned long port, void *buffer, unsigned long count) | ||
326 | { | ||
327 | volatile unsigned long *port_addr; | ||
328 | unsigned int *buf = buffer; | ||
329 | |||
330 | port_addr = (volatile unsigned long *)PORT2ADDR(port); | ||
331 | |||
332 | while (count--) | ||
333 | *buf++ = *port_addr; | ||
334 | } | ||
335 | |||
336 | void microdev_outsb(unsigned long port, const void *buffer, unsigned long count) | ||
337 | { | ||
338 | volatile unsigned char *port_addr; | ||
339 | const unsigned char *buf = buffer; | ||
340 | |||
341 | port_addr = (volatile unsigned char *)PORT2ADDR(port); | ||
342 | |||
343 | while (count--) | ||
344 | *port_addr = *buf++; | ||
345 | } | ||
346 | |||
347 | void microdev_outsw(unsigned long port, const void *buffer, unsigned long count) | ||
348 | { | ||
349 | volatile unsigned short *port_addr; | ||
350 | const unsigned short *buf = buffer; | ||
351 | |||
352 | port_addr = (volatile unsigned short *)PORT2ADDR(port); | ||
353 | |||
354 | while (count--) | ||
355 | *port_addr = *buf++; | ||
356 | } | ||
357 | |||
358 | void microdev_outsl(unsigned long port, const void *buffer, unsigned long count) | ||
359 | { | ||
360 | volatile unsigned long *port_addr; | ||
361 | const unsigned int *buf = buffer; | ||
362 | |||
363 | port_addr = (volatile unsigned long *)PORT2ADDR(port); | ||
364 | |||
365 | while (count--) | ||
366 | *port_addr = *buf++; | ||
367 | } | 125 | } |
diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c index d1df2a4fb9b8..d8a747291e03 100644 --- a/arch/sh/boards/mach-microdev/setup.c +++ b/arch/sh/boards/mach-microdev/setup.c | |||
@@ -195,27 +195,6 @@ device_initcall(microdev_devices_setup); | |||
195 | static struct sh_machine_vector mv_sh4202_microdev __initmv = { | 195 | static struct sh_machine_vector mv_sh4202_microdev __initmv = { |
196 | .mv_name = "SH4-202 MicroDev", | 196 | .mv_name = "SH4-202 MicroDev", |
197 | .mv_nr_irqs = 72, | 197 | .mv_nr_irqs = 72, |
198 | 198 | .mv_ioport_map = microdev_ioport_map, | |
199 | .mv_inb = microdev_inb, | ||
200 | .mv_inw = microdev_inw, | ||
201 | .mv_inl = microdev_inl, | ||
202 | .mv_outb = microdev_outb, | ||
203 | .mv_outw = microdev_outw, | ||
204 | .mv_outl = microdev_outl, | ||
205 | |||
206 | .mv_inb_p = microdev_inb_p, | ||
207 | .mv_inw_p = microdev_inw_p, | ||
208 | .mv_inl_p = microdev_inl_p, | ||
209 | .mv_outb_p = microdev_outb_p, | ||
210 | .mv_outw_p = microdev_outw_p, | ||
211 | .mv_outl_p = microdev_outl_p, | ||
212 | |||
213 | .mv_insb = microdev_insb, | ||
214 | .mv_insw = microdev_insw, | ||
215 | .mv_insl = microdev_insl, | ||
216 | .mv_outsb = microdev_outsb, | ||
217 | .mv_outsw = microdev_outsw, | ||
218 | .mv_outsl = microdev_outsl, | ||
219 | |||
220 | .mv_init_irq = init_microdev_irq, | 199 | .mv_init_irq = init_microdev_irq, |
221 | }; | 200 | }; |
diff --git a/arch/sh/boards/mach-se/7206/Makefile b/arch/sh/boards/mach-se/7206/Makefile index 63e7ed699f39..5c9eaa0535b9 100644 --- a/arch/sh/boards/mach-se/7206/Makefile +++ b/arch/sh/boards/mach-se/7206/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for the 7206 SolutionEngine specific parts of the kernel | 2 | # Makefile for the 7206 SolutionEngine specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := setup.o io.o irq.o | 5 | obj-y := setup.o irq.o |
diff --git a/arch/sh/boards/mach-se/7206/io.c b/arch/sh/boards/mach-se/7206/io.c deleted file mode 100644 index adadc77532ee..000000000000 --- a/arch/sh/boards/mach-se/7206/io.c +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | /* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ | ||
2 | * | ||
3 | * linux/arch/sh/boards/se/7206/io.c | ||
4 | * | ||
5 | * Copyright (C) 2006 Yoshinori Sato | ||
6 | * | ||
7 | * I/O routine for Hitachi 7206 SolutionEngine. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <asm/io.h> | ||
14 | #include <mach-se/mach/se7206.h> | ||
15 | |||
16 | |||
17 | static inline void delay(void) | ||
18 | { | ||
19 | __raw_readw(0x20000000); /* P2 ROM Area */ | ||
20 | } | ||
21 | |||
22 | /* MS7750 requires special versions of in*, out* routines, since | ||
23 | PC-like io ports are located at upper half byte of 16-bit word which | ||
24 | can be accessed only with 16-bit wide. */ | ||
25 | |||
26 | static inline volatile __u16 * | ||
27 | port2adr(unsigned int port) | ||
28 | { | ||
29 | if (port >= 0x2000 && port < 0x2020) | ||
30 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | ||
31 | else if (port >= 0x300 && port < 0x310) | ||
32 | return (volatile __u16 *) (PA_SMSC + (port - 0x300)); | ||
33 | |||
34 | return (volatile __u16 *)port; | ||
35 | } | ||
36 | |||
37 | unsigned char se7206_inb(unsigned long port) | ||
38 | { | ||
39 | return (*port2adr(port)) & 0xff; | ||
40 | } | ||
41 | |||
42 | unsigned char se7206_inb_p(unsigned long port) | ||
43 | { | ||
44 | unsigned long v; | ||
45 | |||
46 | v = (*port2adr(port)) & 0xff; | ||
47 | delay(); | ||
48 | return v; | ||
49 | } | ||
50 | |||
51 | unsigned short se7206_inw(unsigned long port) | ||
52 | { | ||
53 | return *port2adr(port); | ||
54 | } | ||
55 | |||
56 | void se7206_outb(unsigned char value, unsigned long port) | ||
57 | { | ||
58 | *(port2adr(port)) = value; | ||
59 | } | ||
60 | |||
61 | void se7206_outb_p(unsigned char value, unsigned long port) | ||
62 | { | ||
63 | *(port2adr(port)) = value; | ||
64 | delay(); | ||
65 | } | ||
66 | |||
67 | void se7206_outw(unsigned short value, unsigned long port) | ||
68 | { | ||
69 | *port2adr(port) = value; | ||
70 | } | ||
71 | |||
72 | void se7206_insb(unsigned long port, void *addr, unsigned long count) | ||
73 | { | ||
74 | volatile __u16 *p = port2adr(port); | ||
75 | __u8 *ap = addr; | ||
76 | |||
77 | while (count--) | ||
78 | *ap++ = *p; | ||
79 | } | ||
80 | |||
81 | void se7206_insw(unsigned long port, void *addr, unsigned long count) | ||
82 | { | ||
83 | volatile __u16 *p = port2adr(port); | ||
84 | __u16 *ap = addr; | ||
85 | while (count--) | ||
86 | *ap++ = *p; | ||
87 | } | ||
88 | |||
89 | void se7206_outsb(unsigned long port, const void *addr, unsigned long count) | ||
90 | { | ||
91 | volatile __u16 *p = port2adr(port); | ||
92 | const __u8 *ap = addr; | ||
93 | |||
94 | while (count--) | ||
95 | *p = *ap++; | ||
96 | } | ||
97 | |||
98 | void se7206_outsw(unsigned long port, const void *addr, unsigned long count) | ||
99 | { | ||
100 | volatile __u16 *p = port2adr(port); | ||
101 | const __u16 *ap = addr; | ||
102 | while (count--) | ||
103 | *p = *ap++; | ||
104 | } | ||
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index 883b21eacaa6..d961949600fd 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c | |||
@@ -139,11 +139,13 @@ void __init init_se7206_IRQ(void) | |||
139 | make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ | 139 | make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ |
140 | make_se7206_irq(IRQ1_IRQ); /* ATA */ | 140 | make_se7206_irq(IRQ1_IRQ); /* ATA */ |
141 | make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ | 141 | make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ |
142 | __raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ | 142 | |
143 | __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */ | ||
143 | 144 | ||
144 | /* FPGA System register setup*/ | 145 | /* FPGA System register setup*/ |
145 | __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ | 146 | __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ |
146 | __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */ | 147 | __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */ |
148 | |||
147 | /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ | 149 | /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ |
148 | __raw_writew(0x0001,INTSEL); | 150 | __raw_writew(0x0001,INTSEL); |
149 | } | 151 | } |
diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c index 8f5c65d43d1d..7f4871c71a01 100644 --- a/arch/sh/boards/mach-se/7206/setup.c +++ b/arch/sh/boards/mach-se/7206/setup.c | |||
@@ -86,20 +86,5 @@ __initcall(se7206_devices_setup); | |||
86 | static struct sh_machine_vector mv_se __initmv = { | 86 | static struct sh_machine_vector mv_se __initmv = { |
87 | .mv_name = "SolutionEngine", | 87 | .mv_name = "SolutionEngine", |
88 | .mv_nr_irqs = 256, | 88 | .mv_nr_irqs = 256, |
89 | .mv_inb = se7206_inb, | ||
90 | .mv_inw = se7206_inw, | ||
91 | .mv_outb = se7206_outb, | ||
92 | .mv_outw = se7206_outw, | ||
93 | |||
94 | .mv_inb_p = se7206_inb_p, | ||
95 | .mv_inw_p = se7206_inw, | ||
96 | .mv_outb_p = se7206_outb_p, | ||
97 | .mv_outw_p = se7206_outw, | ||
98 | |||
99 | .mv_insb = se7206_insb, | ||
100 | .mv_insw = se7206_insw, | ||
101 | .mv_outsb = se7206_outsb, | ||
102 | .mv_outsw = se7206_outsw, | ||
103 | |||
104 | .mv_init_irq = init_se7206_IRQ, | 89 | .mv_init_irq = init_se7206_IRQ, |
105 | }; | 90 | }; |
diff --git a/arch/sh/boards/mach-se/770x/Makefile b/arch/sh/boards/mach-se/770x/Makefile index 8e624b06d5ea..43ea14feef51 100644 --- a/arch/sh/boards/mach-se/770x/Makefile +++ b/arch/sh/boards/mach-se/770x/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for the 770x SolutionEngine specific parts of the kernel | 2 | # Makefile for the 770x SolutionEngine specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := setup.o io.o irq.o | 5 | obj-y := setup.o irq.o |
diff --git a/arch/sh/boards/mach-se/770x/io.c b/arch/sh/boards/mach-se/770x/io.c deleted file mode 100644 index 28833c8786ea..000000000000 --- a/arch/sh/boards/mach-se/770x/io.c +++ /dev/null | |||
@@ -1,156 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Kazumoto Kojima | ||
3 | * | ||
4 | * I/O routine for Hitachi SolutionEngine. | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/types.h> | ||
8 | #include <asm/io.h> | ||
9 | #include <mach-se/mach/se.h> | ||
10 | |||
11 | /* MS7750 requires special versions of in*, out* routines, since | ||
12 | PC-like io ports are located at upper half byte of 16-bit word which | ||
13 | can be accessed only with 16-bit wide. */ | ||
14 | |||
15 | static inline volatile __u16 * | ||
16 | port2adr(unsigned int port) | ||
17 | { | ||
18 | if (port & 0xff000000) | ||
19 | return ( volatile __u16 *) port; | ||
20 | if (port >= 0x2000) | ||
21 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | ||
22 | else if (port >= 0x1000) | ||
23 | return (volatile __u16 *) (PA_83902 + (port << 1)); | ||
24 | else | ||
25 | return (volatile __u16 *) (PA_SUPERIO + (port << 1)); | ||
26 | } | ||
27 | |||
28 | static inline int | ||
29 | shifted_port(unsigned long port) | ||
30 | { | ||
31 | /* For IDE registers, value is not shifted */ | ||
32 | if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) | ||
33 | return 0; | ||
34 | else | ||
35 | return 1; | ||
36 | } | ||
37 | |||
38 | unsigned char se_inb(unsigned long port) | ||
39 | { | ||
40 | if (shifted_port(port)) | ||
41 | return (*port2adr(port) >> 8); | ||
42 | else | ||
43 | return (*port2adr(port))&0xff; | ||
44 | } | ||
45 | |||
46 | unsigned char se_inb_p(unsigned long port) | ||
47 | { | ||
48 | unsigned long v; | ||
49 | |||
50 | if (shifted_port(port)) | ||
51 | v = (*port2adr(port) >> 8); | ||
52 | else | ||
53 | v = (*port2adr(port))&0xff; | ||
54 | ctrl_delay(); | ||
55 | return v; | ||
56 | } | ||
57 | |||
58 | unsigned short se_inw(unsigned long port) | ||
59 | { | ||
60 | if (port >= 0x2000) | ||
61 | return *port2adr(port); | ||
62 | else | ||
63 | maybebadio(port); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | unsigned int se_inl(unsigned long port) | ||
68 | { | ||
69 | maybebadio(port); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | void se_outb(unsigned char value, unsigned long port) | ||
74 | { | ||
75 | if (shifted_port(port)) | ||
76 | *(port2adr(port)) = value << 8; | ||
77 | else | ||
78 | *(port2adr(port)) = value; | ||
79 | } | ||
80 | |||
81 | void se_outb_p(unsigned char value, unsigned long port) | ||
82 | { | ||
83 | if (shifted_port(port)) | ||
84 | *(port2adr(port)) = value << 8; | ||
85 | else | ||
86 | *(port2adr(port)) = value; | ||
87 | ctrl_delay(); | ||
88 | } | ||
89 | |||
90 | void se_outw(unsigned short value, unsigned long port) | ||
91 | { | ||
92 | if (port >= 0x2000) | ||
93 | *port2adr(port) = value; | ||
94 | else | ||
95 | maybebadio(port); | ||
96 | } | ||
97 | |||
98 | void se_outl(unsigned int value, unsigned long port) | ||
99 | { | ||
100 | maybebadio(port); | ||
101 | } | ||
102 | |||
103 | void se_insb(unsigned long port, void *addr, unsigned long count) | ||
104 | { | ||
105 | volatile __u16 *p = port2adr(port); | ||
106 | __u8 *ap = addr; | ||
107 | |||
108 | if (shifted_port(port)) { | ||
109 | while (count--) | ||
110 | *ap++ = *p >> 8; | ||
111 | } else { | ||
112 | while (count--) | ||
113 | *ap++ = *p; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | void se_insw(unsigned long port, void *addr, unsigned long count) | ||
118 | { | ||
119 | volatile __u16 *p = port2adr(port); | ||
120 | __u16 *ap = addr; | ||
121 | while (count--) | ||
122 | *ap++ = *p; | ||
123 | } | ||
124 | |||
125 | void se_insl(unsigned long port, void *addr, unsigned long count) | ||
126 | { | ||
127 | maybebadio(port); | ||
128 | } | ||
129 | |||
130 | void se_outsb(unsigned long port, const void *addr, unsigned long count) | ||
131 | { | ||
132 | volatile __u16 *p = port2adr(port); | ||
133 | const __u8 *ap = addr; | ||
134 | |||
135 | if (shifted_port(port)) { | ||
136 | while (count--) | ||
137 | *p = *ap++ << 8; | ||
138 | } else { | ||
139 | while (count--) | ||
140 | *p = *ap++; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | void se_outsw(unsigned long port, const void *addr, unsigned long count) | ||
145 | { | ||
146 | volatile __u16 *p = port2adr(port); | ||
147 | const __u16 *ap = addr; | ||
148 | |||
149 | while (count--) | ||
150 | *p = *ap++; | ||
151 | } | ||
152 | |||
153 | void se_outsl(unsigned long port, const void *addr, unsigned long count) | ||
154 | { | ||
155 | maybebadio(port); | ||
156 | } | ||
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c index 66d39d1b0901..31330c65c0ce 100644 --- a/arch/sh/boards/mach-se/770x/setup.c +++ b/arch/sh/boards/mach-se/770x/setup.c | |||
@@ -195,27 +195,5 @@ static struct sh_machine_vector mv_se __initmv = { | |||
195 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 195 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
196 | .mv_nr_irqs = 104, | 196 | .mv_nr_irqs = 104, |
197 | #endif | 197 | #endif |
198 | |||
199 | .mv_inb = se_inb, | ||
200 | .mv_inw = se_inw, | ||
201 | .mv_inl = se_inl, | ||
202 | .mv_outb = se_outb, | ||
203 | .mv_outw = se_outw, | ||
204 | .mv_outl = se_outl, | ||
205 | |||
206 | .mv_inb_p = se_inb_p, | ||
207 | .mv_inw_p = se_inw, | ||
208 | .mv_inl_p = se_inl, | ||
209 | .mv_outb_p = se_outb_p, | ||
210 | .mv_outw_p = se_outw, | ||
211 | .mv_outl_p = se_outl, | ||
212 | |||
213 | .mv_insb = se_insb, | ||
214 | .mv_insw = se_insw, | ||
215 | .mv_insl = se_insl, | ||
216 | .mv_outsb = se_outsb, | ||
217 | .mv_outsw = se_outsw, | ||
218 | .mv_outsl = se_outsl, | ||
219 | |||
220 | .mv_init_irq = init_se_IRQ, | 198 | .mv_init_irq = init_se_IRQ, |
221 | }; | 199 | }; |
diff --git a/arch/sh/boards/mach-se/7751/Makefile b/arch/sh/boards/mach-se/7751/Makefile index e6f4341bfe6e..a338fd9d5039 100644 --- a/arch/sh/boards/mach-se/7751/Makefile +++ b/arch/sh/boards/mach-se/7751/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for the 7751 SolutionEngine specific parts of the kernel | 2 | # Makefile for the 7751 SolutionEngine specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := setup.o io.o irq.o | 5 | obj-y := setup.o irq.o |
diff --git a/arch/sh/boards/mach-se/7751/io.c b/arch/sh/boards/mach-se/7751/io.c deleted file mode 100644 index 6e75bd4459e5..000000000000 --- a/arch/sh/boards/mach-se/7751/io.c +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel | ||
3 | * Based largely on io_se.c. | ||
4 | * | ||
5 | * I/O routine for Hitachi 7751 SolutionEngine. | ||
6 | * | ||
7 | * Initial version only to support LAN access; some | ||
8 | * placeholder code from io_se.c left in with the | ||
9 | * expectation of later SuperIO and PCMCIA access. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <mach-se/mach/se7751.h> | ||
16 | #include <asm/addrspace.h> | ||
17 | |||
18 | static inline volatile u16 *port2adr(unsigned int port) | ||
19 | { | ||
20 | if (port >= 0x2000) | ||
21 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | ||
22 | maybebadio((unsigned long)port); | ||
23 | return (volatile __u16*)port; | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * General outline: remap really low stuff [eventually] to SuperIO, | ||
28 | * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) | ||
29 | * is mapped through the PCI IO window. Stuff with high bits (PXSEG) | ||
30 | * should be way beyond the window, and is used w/o translation for | ||
31 | * compatibility. | ||
32 | */ | ||
33 | unsigned char sh7751se_inb(unsigned long port) | ||
34 | { | ||
35 | if (PXSEG(port)) | ||
36 | return *(volatile unsigned char *)port; | ||
37 | else | ||
38 | return (*port2adr(port)) & 0xff; | ||
39 | } | ||
40 | |||
41 | unsigned char sh7751se_inb_p(unsigned long port) | ||
42 | { | ||
43 | unsigned char v; | ||
44 | |||
45 | if (PXSEG(port)) | ||
46 | v = *(volatile unsigned char *)port; | ||
47 | else | ||
48 | v = (*port2adr(port)) & 0xff; | ||
49 | ctrl_delay(); | ||
50 | return v; | ||
51 | } | ||
52 | |||
53 | unsigned short sh7751se_inw(unsigned long port) | ||
54 | { | ||
55 | if (PXSEG(port)) | ||
56 | return *(volatile unsigned short *)port; | ||
57 | else if (port >= 0x2000) | ||
58 | return *port2adr(port); | ||
59 | else | ||
60 | maybebadio(port); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | unsigned int sh7751se_inl(unsigned long port) | ||
65 | { | ||
66 | if (PXSEG(port)) | ||
67 | return *(volatile unsigned long *)port; | ||
68 | else if (port >= 0x2000) | ||
69 | return *port2adr(port); | ||
70 | else | ||
71 | maybebadio(port); | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | void sh7751se_outb(unsigned char value, unsigned long port) | ||
76 | { | ||
77 | |||
78 | if (PXSEG(port)) | ||
79 | *(volatile unsigned char *)port = value; | ||
80 | else | ||
81 | *(port2adr(port)) = value; | ||
82 | } | ||
83 | |||
84 | void sh7751se_outb_p(unsigned char value, unsigned long port) | ||
85 | { | ||
86 | if (PXSEG(port)) | ||
87 | *(volatile unsigned char *)port = value; | ||
88 | else | ||
89 | *(port2adr(port)) = value; | ||
90 | ctrl_delay(); | ||
91 | } | ||
92 | |||
93 | void sh7751se_outw(unsigned short value, unsigned long port) | ||
94 | { | ||
95 | if (PXSEG(port)) | ||
96 | *(volatile unsigned short *)port = value; | ||
97 | else if (port >= 0x2000) | ||
98 | *port2adr(port) = value; | ||
99 | else | ||
100 | maybebadio(port); | ||
101 | } | ||
102 | |||
103 | void sh7751se_outl(unsigned int value, unsigned long port) | ||
104 | { | ||
105 | if (PXSEG(port)) | ||
106 | *(volatile unsigned long *)port = value; | ||
107 | else | ||
108 | maybebadio(port); | ||
109 | } | ||
110 | |||
111 | void sh7751se_insl(unsigned long port, void *addr, unsigned long count) | ||
112 | { | ||
113 | maybebadio(port); | ||
114 | } | ||
115 | |||
116 | void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) | ||
117 | { | ||
118 | maybebadio(port); | ||
119 | } | ||
diff --git a/arch/sh/boards/mach-se/7751/setup.c b/arch/sh/boards/mach-se/7751/setup.c index 50572512e3e8..9fbc51beb181 100644 --- a/arch/sh/boards/mach-se/7751/setup.c +++ b/arch/sh/boards/mach-se/7751/setup.c | |||
@@ -56,23 +56,5 @@ __initcall(se7751_devices_setup); | |||
56 | static struct sh_machine_vector mv_7751se __initmv = { | 56 | static struct sh_machine_vector mv_7751se __initmv = { |
57 | .mv_name = "7751 SolutionEngine", | 57 | .mv_name = "7751 SolutionEngine", |
58 | .mv_nr_irqs = 72, | 58 | .mv_nr_irqs = 72, |
59 | |||
60 | .mv_inb = sh7751se_inb, | ||
61 | .mv_inw = sh7751se_inw, | ||
62 | .mv_inl = sh7751se_inl, | ||
63 | .mv_outb = sh7751se_outb, | ||
64 | .mv_outw = sh7751se_outw, | ||
65 | .mv_outl = sh7751se_outl, | ||
66 | |||
67 | .mv_inb_p = sh7751se_inb_p, | ||
68 | .mv_inw_p = sh7751se_inw, | ||
69 | .mv_inl_p = sh7751se_inl, | ||
70 | .mv_outb_p = sh7751se_outb_p, | ||
71 | .mv_outw_p = sh7751se_outw, | ||
72 | .mv_outl_p = sh7751se_outl, | ||
73 | |||
74 | .mv_insl = sh7751se_insl, | ||
75 | .mv_outsl = sh7751se_outsl, | ||
76 | |||
77 | .mv_init_irq = init_7751se_IRQ, | 59 | .mv_init_irq = init_7751se_IRQ, |
78 | }; | 60 | }; |
diff --git a/arch/sh/boards/mach-snapgear/Makefile b/arch/sh/boards/mach-snapgear/Makefile deleted file mode 100644 index d2d2f4b6a502..000000000000 --- a/arch/sh/boards/mach-snapgear/Makefile +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the SnapGear specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := setup.o io.o | ||
diff --git a/arch/sh/boards/mach-snapgear/io.c b/arch/sh/boards/mach-snapgear/io.c deleted file mode 100644 index 476650e42dbc..000000000000 --- a/arch/sh/boards/mach-snapgear/io.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 David McCullough <davidm@snapgear.com> | ||
3 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel | ||
4 | * Based largely on io_se.c. | ||
5 | * | ||
6 | * I/O routine for Hitachi 7751 SolutionEngine. | ||
7 | * | ||
8 | * Initial version only to support LAN access; some | ||
9 | * placeholder code from io_se.c left in with the | ||
10 | * expectation of later SuperIO and PCMCIA access. | ||
11 | */ | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <asm/io.h> | ||
16 | #include <asm/addrspace.h> | ||
17 | |||
18 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
19 | unsigned short secureedge5410_ioport; | ||
20 | #endif | ||
21 | |||
22 | static inline volatile __u16 *port2adr(unsigned int port) | ||
23 | { | ||
24 | maybebadio((unsigned long)port); | ||
25 | return (volatile __u16*)port; | ||
26 | } | ||
27 | |||
28 | /* | ||
29 | * General outline: remap really low stuff [eventually] to SuperIO, | ||
30 | * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) | ||
31 | * is mapped through the PCI IO window. Stuff with high bits (PXSEG) | ||
32 | * should be way beyond the window, and is used w/o translation for | ||
33 | * compatibility. | ||
34 | */ | ||
35 | unsigned char snapgear_inb(unsigned long port) | ||
36 | { | ||
37 | if (PXSEG(port)) | ||
38 | return *(volatile unsigned char *)port; | ||
39 | else | ||
40 | return (*port2adr(port)) & 0xff; | ||
41 | } | ||
42 | |||
43 | unsigned char snapgear_inb_p(unsigned long port) | ||
44 | { | ||
45 | unsigned char v; | ||
46 | |||
47 | if (PXSEG(port)) | ||
48 | v = *(volatile unsigned char *)port; | ||
49 | else | ||
50 | v = (*port2adr(port))&0xff; | ||
51 | ctrl_delay(); | ||
52 | return v; | ||
53 | } | ||
54 | |||
55 | unsigned short snapgear_inw(unsigned long port) | ||
56 | { | ||
57 | if (PXSEG(port)) | ||
58 | return *(volatile unsigned short *)port; | ||
59 | else if (port >= 0x2000) | ||
60 | return *port2adr(port); | ||
61 | else | ||
62 | maybebadio(port); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | unsigned int snapgear_inl(unsigned long port) | ||
67 | { | ||
68 | if (PXSEG(port)) | ||
69 | return *(volatile unsigned long *)port; | ||
70 | else if (port >= 0x2000) | ||
71 | return *port2adr(port); | ||
72 | else | ||
73 | maybebadio(port); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | void snapgear_outb(unsigned char value, unsigned long port) | ||
78 | { | ||
79 | |||
80 | if (PXSEG(port)) | ||
81 | *(volatile unsigned char *)port = value; | ||
82 | else | ||
83 | *(port2adr(port)) = value; | ||
84 | } | ||
85 | |||
86 | void snapgear_outb_p(unsigned char value, unsigned long port) | ||
87 | { | ||
88 | if (PXSEG(port)) | ||
89 | *(volatile unsigned char *)port = value; | ||
90 | else | ||
91 | *(port2adr(port)) = value; | ||
92 | ctrl_delay(); | ||
93 | } | ||
94 | |||
95 | void snapgear_outw(unsigned short value, unsigned long port) | ||
96 | { | ||
97 | if (PXSEG(port)) | ||
98 | *(volatile unsigned short *)port = value; | ||
99 | else if (port >= 0x2000) | ||
100 | *port2adr(port) = value; | ||
101 | else | ||
102 | maybebadio(port); | ||
103 | } | ||
104 | |||
105 | void snapgear_outl(unsigned int value, unsigned long port) | ||
106 | { | ||
107 | if (PXSEG(port)) | ||
108 | *(volatile unsigned long *)port = value; | ||
109 | else | ||
110 | maybebadio(port); | ||
111 | } | ||
112 | |||
113 | void snapgear_insl(unsigned long port, void *addr, unsigned long count) | ||
114 | { | ||
115 | maybebadio(port); | ||
116 | } | ||
117 | |||
118 | void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) | ||
119 | { | ||
120 | maybebadio(port); | ||
121 | } | ||
diff --git a/arch/sh/boards/mach-systemh/Makefile b/arch/sh/boards/mach-systemh/Makefile deleted file mode 100644 index 2cc6a23d9d39..000000000000 --- a/arch/sh/boards/mach-systemh/Makefile +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the SystemH specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := setup.o irq.o io.o | ||
6 | |||
7 | # XXX: This wants to be consolidated in arch/sh/drivers/pci, and more | ||
8 | # importantly, with the generic sh7751_pcic_init() code. For now, we'll | ||
9 | # just abuse the hell out of kbuild, because we can.. | ||
10 | |||
11 | obj-$(CONFIG_PCI) += pci.o | ||
12 | pci-y := ../../se/7751/pci.o | ||
13 | |||
diff --git a/arch/sh/boards/mach-systemh/io.c b/arch/sh/boards/mach-systemh/io.c deleted file mode 100644 index 15577ff1f715..000000000000 --- a/arch/sh/boards/mach-systemh/io.c +++ /dev/null | |||
@@ -1,158 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/renesas/systemh/io.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel | ||
5 | * Based largely on io_se.c. | ||
6 | * | ||
7 | * I/O routine for Hitachi 7751 Systemh. | ||
8 | */ | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <mach/systemh7751.h> | ||
13 | #include <asm/addrspace.h> | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | #define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area | ||
17 | of smc lan chip*/ | ||
18 | static inline volatile __u16 * | ||
19 | port2adr(unsigned int port) | ||
20 | { | ||
21 | if (port >= 0x2000) | ||
22 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | ||
23 | maybebadio((unsigned long)port); | ||
24 | return (volatile __u16*)port; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | * General outline: remap really low stuff [eventually] to SuperIO, | ||
29 | * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) | ||
30 | * is mapped through the PCI IO window. Stuff with high bits (PXSEG) | ||
31 | * should be way beyond the window, and is used w/o translation for | ||
32 | * compatibility. | ||
33 | */ | ||
34 | unsigned char sh7751systemh_inb(unsigned long port) | ||
35 | { | ||
36 | if (PXSEG(port)) | ||
37 | return *(volatile unsigned char *)port; | ||
38 | else if (port <= 0x3F1) | ||
39 | return *(volatile unsigned char *)ETHER_IOMAP(port); | ||
40 | else | ||
41 | return (*port2adr(port))&0xff; | ||
42 | } | ||
43 | |||
44 | unsigned char sh7751systemh_inb_p(unsigned long port) | ||
45 | { | ||
46 | unsigned char v; | ||
47 | |||
48 | if (PXSEG(port)) | ||
49 | v = *(volatile unsigned char *)port; | ||
50 | else if (port <= 0x3F1) | ||
51 | v = *(volatile unsigned char *)ETHER_IOMAP(port); | ||
52 | else | ||
53 | v = (*port2adr(port))&0xff; | ||
54 | ctrl_delay(); | ||
55 | return v; | ||
56 | } | ||
57 | |||
58 | unsigned short sh7751systemh_inw(unsigned long port) | ||
59 | { | ||
60 | if (PXSEG(port)) | ||
61 | return *(volatile unsigned short *)port; | ||
62 | else if (port >= 0x2000) | ||
63 | return *port2adr(port); | ||
64 | else if (port <= 0x3F1) | ||
65 | return *(volatile unsigned int *)ETHER_IOMAP(port); | ||
66 | else | ||
67 | maybebadio(port); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | unsigned int sh7751systemh_inl(unsigned long port) | ||
72 | { | ||
73 | if (PXSEG(port)) | ||
74 | return *(volatile unsigned long *)port; | ||
75 | else if (port >= 0x2000) | ||
76 | return *port2adr(port); | ||
77 | else if (port <= 0x3F1) | ||
78 | return *(volatile unsigned int *)ETHER_IOMAP(port); | ||
79 | else | ||
80 | maybebadio(port); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | void sh7751systemh_outb(unsigned char value, unsigned long port) | ||
85 | { | ||
86 | |||
87 | if (PXSEG(port)) | ||
88 | *(volatile unsigned char *)port = value; | ||
89 | else if (port <= 0x3F1) | ||
90 | *(volatile unsigned char *)ETHER_IOMAP(port) = value; | ||
91 | else | ||
92 | *(port2adr(port)) = value; | ||
93 | } | ||
94 | |||
95 | void sh7751systemh_outb_p(unsigned char value, unsigned long port) | ||
96 | { | ||
97 | if (PXSEG(port)) | ||
98 | *(volatile unsigned char *)port = value; | ||
99 | else if (port <= 0x3F1) | ||
100 | *(volatile unsigned char *)ETHER_IOMAP(port) = value; | ||
101 | else | ||
102 | *(port2adr(port)) = value; | ||
103 | ctrl_delay(); | ||
104 | } | ||
105 | |||
106 | void sh7751systemh_outw(unsigned short value, unsigned long port) | ||
107 | { | ||
108 | if (PXSEG(port)) | ||
109 | *(volatile unsigned short *)port = value; | ||
110 | else if (port >= 0x2000) | ||
111 | *port2adr(port) = value; | ||
112 | else if (port <= 0x3F1) | ||
113 | *(volatile unsigned short *)ETHER_IOMAP(port) = value; | ||
114 | else | ||
115 | maybebadio(port); | ||
116 | } | ||
117 | |||
118 | void sh7751systemh_outl(unsigned int value, unsigned long port) | ||
119 | { | ||
120 | if (PXSEG(port)) | ||
121 | *(volatile unsigned long *)port = value; | ||
122 | else | ||
123 | maybebadio(port); | ||
124 | } | ||
125 | |||
126 | void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) | ||
127 | { | ||
128 | unsigned char *p = addr; | ||
129 | while (count--) *p++ = sh7751systemh_inb(port); | ||
130 | } | ||
131 | |||
132 | void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) | ||
133 | { | ||
134 | unsigned short *p = addr; | ||
135 | while (count--) *p++ = sh7751systemh_inw(port); | ||
136 | } | ||
137 | |||
138 | void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) | ||
139 | { | ||
140 | maybebadio(port); | ||
141 | } | ||
142 | |||
143 | void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) | ||
144 | { | ||
145 | unsigned char *p = (unsigned char*)addr; | ||
146 | while (count--) sh7751systemh_outb(*p++, port); | ||
147 | } | ||
148 | |||
149 | void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count) | ||
150 | { | ||
151 | unsigned short *p = (unsigned short*)addr; | ||
152 | while (count--) sh7751systemh_outw(*p++, port); | ||
153 | } | ||
154 | |||
155 | void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) | ||
156 | { | ||
157 | maybebadio(port); | ||
158 | } | ||
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c deleted file mode 100644 index e5ee13adeff4..000000000000 --- a/arch/sh/boards/mach-systemh/irq.c +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/renesas/systemh/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SystemH Support. | ||
7 | * | ||
8 | * Modified for 7751 SystemH by | ||
9 | * Jonathan Short. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #include <mach/systemh7751.h> | ||
18 | #include <asm/smc37c93x.h> | ||
19 | |||
20 | /* address of external interrupt mask register | ||
21 | * address must be set prior to use these (maybe in init_XXX_irq()) | ||
22 | * XXX : is it better to use .config than specifying it in code? */ | ||
23 | static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; | ||
24 | static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; | ||
25 | |||
26 | static void disable_systemh_irq(struct irq_data *data) | ||
27 | { | ||
28 | unsigned long val, mask = 0x01 << 1; | ||
29 | |||
30 | /* Clear the "irq"th bit in the mask and set it in the request */ | ||
31 | val = __raw_readl((unsigned long)systemh_irq_mask_register); | ||
32 | val &= ~mask; | ||
33 | __raw_writel(val, (unsigned long)systemh_irq_mask_register); | ||
34 | |||
35 | val = __raw_readl((unsigned long)systemh_irq_request_register); | ||
36 | val |= mask; | ||
37 | __raw_writel(val, (unsigned long)systemh_irq_request_register); | ||
38 | } | ||
39 | |||
40 | static void enable_systemh_irq(struct irq_data *data) | ||
41 | { | ||
42 | unsigned long val, mask = 0x01 << 1; | ||
43 | |||
44 | /* Set "irq"th bit in the mask register */ | ||
45 | val = __raw_readl((unsigned long)systemh_irq_mask_register); | ||
46 | val |= mask; | ||
47 | __raw_writel(val, (unsigned long)systemh_irq_mask_register); | ||
48 | } | ||
49 | |||
50 | static struct irq_chip systemh_irq_type = { | ||
51 | .name = "SystemH Register", | ||
52 | .irq_unmask = enable_systemh_irq, | ||
53 | .irq_mask = disable_systemh_irq, | ||
54 | }; | ||
55 | |||
56 | void make_systemh_irq(unsigned int irq) | ||
57 | { | ||
58 | disable_irq_nosync(irq); | ||
59 | set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq); | ||
60 | disable_systemh_irq(irq_get_irq_data(irq)); | ||
61 | } | ||
diff --git a/arch/sh/boards/mach-systemh/setup.c b/arch/sh/boards/mach-systemh/setup.c deleted file mode 100644 index 219fd800a43f..000000000000 --- a/arch/sh/boards/mach-systemh/setup.c +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/renesas/systemh/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * Copyright (C) 2003 Paul Mundt | ||
6 | * | ||
7 | * Hitachi SystemH Support. | ||
8 | * | ||
9 | * Modified for 7751 SystemH by Jonathan Short. | ||
10 | * | ||
11 | * Rewritten for 2.6 by Paul Mundt. | ||
12 | * | ||
13 | * This file is subject to the terms and conditions of the GNU General Public | ||
14 | * License. See the file "COPYING" in the main directory of this archive | ||
15 | * for more details. | ||
16 | */ | ||
17 | #include <linux/init.h> | ||
18 | #include <asm/machvec.h> | ||
19 | #include <mach/systemh7751.h> | ||
20 | |||
21 | extern void make_systemh_irq(unsigned int irq); | ||
22 | |||
23 | /* | ||
24 | * Initialize IRQ setting | ||
25 | */ | ||
26 | static void __init sh7751systemh_init_irq(void) | ||
27 | { | ||
28 | make_systemh_irq(0xb); /* Ethernet interrupt */ | ||
29 | } | ||
30 | |||
31 | static struct sh_machine_vector mv_7751systemh __initmv = { | ||
32 | .mv_name = "7751 SystemH", | ||
33 | .mv_nr_irqs = 72, | ||
34 | |||
35 | .mv_inb = sh7751systemh_inb, | ||
36 | .mv_inw = sh7751systemh_inw, | ||
37 | .mv_inl = sh7751systemh_inl, | ||
38 | .mv_outb = sh7751systemh_outb, | ||
39 | .mv_outw = sh7751systemh_outw, | ||
40 | .mv_outl = sh7751systemh_outl, | ||
41 | |||
42 | .mv_inb_p = sh7751systemh_inb_p, | ||
43 | .mv_inw_p = sh7751systemh_inw, | ||
44 | .mv_inl_p = sh7751systemh_inl, | ||
45 | .mv_outb_p = sh7751systemh_outb_p, | ||
46 | .mv_outw_p = sh7751systemh_outw, | ||
47 | .mv_outl_p = sh7751systemh_outl, | ||
48 | |||
49 | .mv_insb = sh7751systemh_insb, | ||
50 | .mv_insw = sh7751systemh_insw, | ||
51 | .mv_insl = sh7751systemh_insl, | ||
52 | .mv_outsb = sh7751systemh_outsb, | ||
53 | .mv_outsw = sh7751systemh_outsw, | ||
54 | .mv_outsl = sh7751systemh_outsl, | ||
55 | |||
56 | .mv_init_irq = sh7751systemh_init_irq, | ||
57 | }; | ||
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/secureedge5410_defconfig index 7eae4e59d7f0..7eae4e59d7f0 100644 --- a/arch/sh/configs/snapgear_defconfig +++ b/arch/sh/configs/secureedge5410_defconfig | |||
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig deleted file mode 100644 index b58dfc505efe..000000000000 --- a/arch/sh/configs/systemh_defconfig +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_LOG_BUF_SHIFT=14 | ||
3 | CONFIG_BLK_DEV_INITRD=y | ||
4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
5 | # CONFIG_SYSCTL_SYSCALL is not set | ||
6 | # CONFIG_HOTPLUG is not set | ||
7 | CONFIG_SLAB=y | ||
8 | CONFIG_MODULES=y | ||
9 | CONFIG_MODULE_UNLOAD=y | ||
10 | # CONFIG_BLK_DEV_BSG is not set | ||
11 | CONFIG_CPU_SUBTYPE_SH7751R=y | ||
12 | CONFIG_MEMORY_START=0x0c000000 | ||
13 | CONFIG_MEMORY_SIZE=0x00400000 | ||
14 | CONFIG_FLATMEM_MANUAL=y | ||
15 | CONFIG_SH_7751_SYSTEMH=y | ||
16 | CONFIG_PREEMPT=y | ||
17 | # CONFIG_STANDALONE is not set | ||
18 | CONFIG_BLK_DEV_RAM=y | ||
19 | CONFIG_BLK_DEV_RAM_SIZE=1024 | ||
20 | # CONFIG_INPUT is not set | ||
21 | # CONFIG_SERIO_SERPORT is not set | ||
22 | # CONFIG_VT is not set | ||
23 | CONFIG_HW_RANDOM=y | ||
24 | CONFIG_PROC_KCORE=y | ||
25 | CONFIG_TMPFS=y | ||
26 | CONFIG_CRAMFS=y | ||
27 | CONFIG_ROMFS_FS=y | ||
28 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index 446b3831c214..3d1ae2bfaa6f 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h | |||
@@ -44,10 +44,10 @@ | |||
44 | /* | 44 | /* |
45 | * These will never work in 32-bit, don't even bother. | 45 | * These will never work in 32-bit, don't even bother. |
46 | */ | 46 | */ |
47 | #define P1SEGADDR(a) __futile_remapping_attempt | 47 | #define P1SEGADDR(a) ({ (void)(a); BUG(); NULL; }) |
48 | #define P2SEGADDR(a) __futile_remapping_attempt | 48 | #define P2SEGADDR(a) ({ (void)(a); BUG(); NULL; }) |
49 | #define P3SEGADDR(a) __futile_remapping_attempt | 49 | #define P3SEGADDR(a) ({ (void)(a); BUG(); NULL; }) |
50 | #define P4SEGADDR(a) __futile_remapping_attempt | 50 | #define P4SEGADDR(a) ({ (void)(a); BUG(); NULL; }) |
51 | #endif | 51 | #endif |
52 | #endif /* P1SEG */ | 52 | #endif /* P1SEG */ |
53 | 53 | ||
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index a15f1058bbf4..083ea068e819 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h | |||
@@ -66,7 +66,6 @@ static inline unsigned long long neff_sign_extend(unsigned long val) | |||
66 | #define PHYS_ADDR_MASK29 0x1fffffff | 66 | #define PHYS_ADDR_MASK29 0x1fffffff |
67 | #define PHYS_ADDR_MASK32 0xffffffff | 67 | #define PHYS_ADDR_MASK32 0xffffffff |
68 | 68 | ||
69 | #ifdef CONFIG_PMB | ||
70 | static inline unsigned long phys_addr_mask(void) | 69 | static inline unsigned long phys_addr_mask(void) |
71 | { | 70 | { |
72 | /* Is the MMU in 29bit mode? */ | 71 | /* Is the MMU in 29bit mode? */ |
@@ -75,17 +74,6 @@ static inline unsigned long phys_addr_mask(void) | |||
75 | 74 | ||
76 | return PHYS_ADDR_MASK32; | 75 | return PHYS_ADDR_MASK32; |
77 | } | 76 | } |
78 | #elif defined(CONFIG_32BIT) | ||
79 | static inline unsigned long phys_addr_mask(void) | ||
80 | { | ||
81 | return PHYS_ADDR_MASK32; | ||
82 | } | ||
83 | #else | ||
84 | static inline unsigned long phys_addr_mask(void) | ||
85 | { | ||
86 | return PHYS_ADDR_MASK29; | ||
87 | } | ||
88 | #endif | ||
89 | 77 | ||
90 | #define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK) | 78 | #define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK) |
91 | #define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT) | 79 | #define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT) |
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index 1f1af5afff03..10c8b1823a18 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/compiler.h> | 10 | #include <linux/compiler.h> |
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <asm/types.h> | 12 | #include <asm/types.h> |
13 | #include <asm/uncached.h> | ||
13 | 14 | ||
14 | #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ | 15 | #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ |
15 | 16 | ||
@@ -137,9 +138,6 @@ extern unsigned int instruction_size(unsigned int insn); | |||
137 | #define instruction_size(insn) (4) | 138 | #define instruction_size(insn) (4) |
138 | #endif | 139 | #endif |
139 | 140 | ||
140 | extern unsigned long cached_to_uncached; | ||
141 | extern unsigned long uncached_size; | ||
142 | |||
143 | void per_cpu_trap_init(void); | 141 | void per_cpu_trap_init(void); |
144 | void default_idle(void); | 142 | void default_idle(void); |
145 | void cpu_idle_wait(void); | 143 | void cpu_idle_wait(void); |
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index c941b2739405..a4ad1cd9bc4d 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h | |||
@@ -145,42 +145,6 @@ do { \ | |||
145 | __restore_dsp(prev); \ | 145 | __restore_dsp(prev); \ |
146 | } while (0) | 146 | } while (0) |
147 | 147 | ||
148 | /* | ||
149 | * Jump to uncached area. | ||
150 | * When handling TLB or caches, we need to do it from an uncached area. | ||
151 | */ | ||
152 | #define jump_to_uncached() \ | ||
153 | do { \ | ||
154 | unsigned long __dummy; \ | ||
155 | \ | ||
156 | __asm__ __volatile__( \ | ||
157 | "mova 1f, %0\n\t" \ | ||
158 | "add %1, %0\n\t" \ | ||
159 | "jmp @%0\n\t" \ | ||
160 | " nop\n\t" \ | ||
161 | ".balign 4\n" \ | ||
162 | "1:" \ | ||
163 | : "=&z" (__dummy) \ | ||
164 | : "r" (cached_to_uncached)); \ | ||
165 | } while (0) | ||
166 | |||
167 | /* | ||
168 | * Back to cached area. | ||
169 | */ | ||
170 | #define back_to_cached() \ | ||
171 | do { \ | ||
172 | unsigned long __dummy; \ | ||
173 | ctrl_barrier(); \ | ||
174 | __asm__ __volatile__( \ | ||
175 | "mov.l 1f, %0\n\t" \ | ||
176 | "jmp @%0\n\t" \ | ||
177 | " nop\n\t" \ | ||
178 | ".balign 4\n" \ | ||
179 | "1: .long 2f\n" \ | ||
180 | "2:" \ | ||
181 | : "=&r" (__dummy)); \ | ||
182 | } while (0) | ||
183 | |||
184 | #ifdef CONFIG_CPU_HAS_SR_RB | 148 | #ifdef CONFIG_CPU_HAS_SR_RB |
185 | #define lookup_exception_vector() \ | 149 | #define lookup_exception_vector() \ |
186 | ({ \ | 150 | ({ \ |
diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 36338646dfc8..8593bc8d1a4e 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h | |||
@@ -34,9 +34,6 @@ do { \ | |||
34 | &next->thread); \ | 34 | &next->thread); \ |
35 | } while (0) | 35 | } while (0) |
36 | 36 | ||
37 | #define jump_to_uncached() do { } while (0) | ||
38 | #define back_to_cached() do { } while (0) | ||
39 | |||
40 | #define __icbi(addr) __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr)) | 37 | #define __icbi(addr) __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr)) |
41 | #define __ocbp(addr) __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr)) | 38 | #define __ocbp(addr) __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr)) |
42 | #define __ocbi(addr) __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr)) | 39 | #define __ocbi(addr) __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr)) |
diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h index e3419f96626a..6f8816b79cf1 100644 --- a/arch/sh/include/asm/uncached.h +++ b/arch/sh/include/asm/uncached.h | |||
@@ -4,15 +4,55 @@ | |||
4 | #include <linux/bug.h> | 4 | #include <linux/bug.h> |
5 | 5 | ||
6 | #ifdef CONFIG_UNCACHED_MAPPING | 6 | #ifdef CONFIG_UNCACHED_MAPPING |
7 | extern unsigned long cached_to_uncached; | ||
8 | extern unsigned long uncached_size; | ||
7 | extern unsigned long uncached_start, uncached_end; | 9 | extern unsigned long uncached_start, uncached_end; |
8 | 10 | ||
9 | extern int virt_addr_uncached(unsigned long kaddr); | 11 | extern int virt_addr_uncached(unsigned long kaddr); |
10 | extern void uncached_init(void); | 12 | extern void uncached_init(void); |
11 | extern void uncached_resize(unsigned long size); | 13 | extern void uncached_resize(unsigned long size); |
14 | |||
15 | /* | ||
16 | * Jump to uncached area. | ||
17 | * When handling TLB or caches, we need to do it from an uncached area. | ||
18 | */ | ||
19 | #define jump_to_uncached() \ | ||
20 | do { \ | ||
21 | unsigned long __dummy; \ | ||
22 | \ | ||
23 | __asm__ __volatile__( \ | ||
24 | "mova 1f, %0\n\t" \ | ||
25 | "add %1, %0\n\t" \ | ||
26 | "jmp @%0\n\t" \ | ||
27 | " nop\n\t" \ | ||
28 | ".balign 4\n" \ | ||
29 | "1:" \ | ||
30 | : "=&z" (__dummy) \ | ||
31 | : "r" (cached_to_uncached)); \ | ||
32 | } while (0) | ||
33 | |||
34 | /* | ||
35 | * Back to cached area. | ||
36 | */ | ||
37 | #define back_to_cached() \ | ||
38 | do { \ | ||
39 | unsigned long __dummy; \ | ||
40 | ctrl_barrier(); \ | ||
41 | __asm__ __volatile__( \ | ||
42 | "mov.l 1f, %0\n\t" \ | ||
43 | "jmp @%0\n\t" \ | ||
44 | " nop\n\t" \ | ||
45 | ".balign 4\n" \ | ||
46 | "1: .long 2f\n" \ | ||
47 | "2:" \ | ||
48 | : "=&r" (__dummy)); \ | ||
49 | } while (0) | ||
12 | #else | 50 | #else |
13 | #define virt_addr_uncached(kaddr) (0) | 51 | #define virt_addr_uncached(kaddr) (0) |
14 | #define uncached_init() do { } while (0) | 52 | #define uncached_init() do { } while (0) |
15 | #define uncached_resize(size) BUG() | 53 | #define uncached_resize(size) BUG() |
54 | #define jump_to_uncached() do { } while (0) | ||
55 | #define back_to_cached() do { } while (0) | ||
16 | #endif | 56 | #endif |
17 | 57 | ||
18 | #endif /* __ASM_SH_UNCACHED_H */ | 58 | #endif /* __ASM_SH_UNCACHED_H */ |
diff --git a/arch/sh/include/mach-common/mach/edosk7705.h b/arch/sh/include/mach-common/mach/edosk7705.h deleted file mode 100644 index efc43b323466..000000000000 --- a/arch/sh/include/mach-common/mach/edosk7705.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef __ASM_SH_EDOSK7705_H | ||
2 | #define __ASM_SH_EDOSK7705_H | ||
3 | |||
4 | #define __IO_PREFIX sh_edosk7705 | ||
5 | #include <asm/io_generic.h> | ||
6 | |||
7 | #endif /* __ASM_SH_EDOSK7705_H */ | ||
diff --git a/arch/sh/include/mach-common/mach/microdev.h b/arch/sh/include/mach-common/mach/microdev.h index 1aed15856e11..dcb05fa8c164 100644 --- a/arch/sh/include/mach-common/mach/microdev.h +++ b/arch/sh/include/mach-common/mach/microdev.h | |||
@@ -68,13 +68,4 @@ extern void microdev_print_fpga_intc_status(void); | |||
68 | #define __IO_PREFIX microdev | 68 | #define __IO_PREFIX microdev |
69 | #include <asm/io_generic.h> | 69 | #include <asm/io_generic.h> |
70 | 70 | ||
71 | #if defined(CONFIG_PCI) | ||
72 | unsigned char microdev_pci_inb(unsigned long port); | ||
73 | unsigned short microdev_pci_inw(unsigned long port); | ||
74 | unsigned long microdev_pci_inl(unsigned long port); | ||
75 | void microdev_pci_outb(unsigned char data, unsigned long port); | ||
76 | void microdev_pci_outw(unsigned short data, unsigned long port); | ||
77 | void microdev_pci_outl(unsigned long data, unsigned long port); | ||
78 | #endif | ||
79 | |||
80 | #endif /* __ASM_SH_MICRODEV_H */ | 71 | #endif /* __ASM_SH_MICRODEV_H */ |
diff --git a/arch/sh/include/mach-common/mach/snapgear.h b/arch/sh/include/mach-common/mach/secureedge5410.h index 042d95f51c4d..3653b9a4bacc 100644 --- a/arch/sh/include/mach-common/mach/snapgear.h +++ b/arch/sh/include/mach-common/mach/secureedge5410.h | |||
@@ -12,30 +12,9 @@ | |||
12 | #ifndef _ASM_SH_IO_SNAPGEAR_H | 12 | #ifndef _ASM_SH_IO_SNAPGEAR_H |
13 | #define _ASM_SH_IO_SNAPGEAR_H | 13 | #define _ASM_SH_IO_SNAPGEAR_H |
14 | 14 | ||
15 | #if defined(CONFIG_CPU_SH4) | ||
16 | /* | ||
17 | * The external interrupt lines, these take up ints 0 - 15 inclusive | ||
18 | * depending on the priority for the interrupt. In fact the priority | ||
19 | * is the interrupt :-) | ||
20 | */ | ||
21 | |||
22 | #define IRL0_IRQ 2 | ||
23 | #define IRL0_PRIORITY 13 | ||
24 | |||
25 | #define IRL1_IRQ 5 | ||
26 | #define IRL1_PRIORITY 10 | ||
27 | |||
28 | #define IRL2_IRQ 8 | ||
29 | #define IRL2_PRIORITY 7 | ||
30 | |||
31 | #define IRL3_IRQ 11 | ||
32 | #define IRL3_PRIORITY 4 | ||
33 | #endif | ||
34 | |||
35 | #define __IO_PREFIX snapgear | 15 | #define __IO_PREFIX snapgear |
36 | #include <asm/io_generic.h> | 16 | #include <asm/io_generic.h> |
37 | 17 | ||
38 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
39 | /* | 18 | /* |
40 | * We need to remember what was written to the ioport as some bits | 19 | * We need to remember what was written to the ioport as some bits |
41 | * are shared with other functions and you cannot read back what was | 20 | * are shared with other functions and you cannot read back what was |
@@ -66,6 +45,5 @@ extern unsigned short secureedge5410_ioport; | |||
66 | ((secureedge5410_ioport & ~(mask)) | ((val) & (mask))))) | 45 | ((secureedge5410_ioport & ~(mask)) | ((val) & (mask))))) |
67 | #define SECUREEDGE_READ_IOPORT() \ | 46 | #define SECUREEDGE_READ_IOPORT() \ |
68 | ((*SECUREEDGE_IOPORT_ADDR&0x0817) | (secureedge5410_ioport&~0x0817)) | 47 | ((*SECUREEDGE_IOPORT_ADDR&0x0817) | (secureedge5410_ioport&~0x0817)) |
69 | #endif | ||
70 | 48 | ||
71 | #endif /* _ASM_SH_IO_SNAPGEAR_H */ | 49 | #endif /* _ASM_SH_IO_SNAPGEAR_H */ |
diff --git a/arch/sh/include/mach-common/mach/systemh7751.h b/arch/sh/include/mach-common/mach/systemh7751.h deleted file mode 100644 index 4161122c84ef..000000000000 --- a/arch/sh/include/mach-common/mach/systemh7751.h +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | #ifndef __ASM_SH_SYSTEMH_7751SYSTEMH_H | ||
2 | #define __ASM_SH_SYSTEMH_7751SYSTEMH_H | ||
3 | |||
4 | /* | ||
5 | * linux/include/asm-sh/systemh/7751systemh.h | ||
6 | * | ||
7 | * Copyright (C) 2000 Kazumoto Kojima | ||
8 | * | ||
9 | * Hitachi SystemH support | ||
10 | |||
11 | * Modified for 7751 SystemH by | ||
12 | * Jonathan Short, 2002. | ||
13 | */ | ||
14 | |||
15 | /* Box specific addresses. */ | ||
16 | |||
17 | #define PA_ROM 0x00000000 /* EPROM */ | ||
18 | #define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte */ | ||
19 | #define PA_FROM 0x01000000 /* EPROM */ | ||
20 | #define PA_FROM_SIZE 0x00400000 /* EPROM size 4M byte */ | ||
21 | #define PA_EXT1 0x04000000 | ||
22 | #define PA_EXT1_SIZE 0x04000000 | ||
23 | #define PA_EXT2 0x08000000 | ||
24 | #define PA_EXT2_SIZE 0x04000000 | ||
25 | #define PA_SDRAM 0x0c000000 | ||
26 | #define PA_SDRAM_SIZE 0x04000000 | ||
27 | |||
28 | #define PA_EXT4 0x12000000 | ||
29 | #define PA_EXT4_SIZE 0x02000000 | ||
30 | #define PA_EXT5 0x14000000 | ||
31 | #define PA_EXT5_SIZE 0x04000000 | ||
32 | #define PA_PCIC 0x18000000 /* MR-SHPC-01 PCMCIA */ | ||
33 | |||
34 | #define PA_DIPSW0 0xb9000000 /* Dip switch 5,6 */ | ||
35 | #define PA_DIPSW1 0xb9000002 /* Dip switch 7,8 */ | ||
36 | #define PA_LED 0xba000000 /* LED */ | ||
37 | #define PA_BCR 0xbb000000 /* FPGA on the MS7751SE01 */ | ||
38 | |||
39 | #define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controller */ | ||
40 | #define PA_MRSHPC_MW1 0xb8400000 /* MR-SHPC-01 memory window base */ | ||
41 | #define PA_MRSHPC_MW2 0xb8500000 /* MR-SHPC-01 attribute window base */ | ||
42 | #define PA_MRSHPC_IO 0xb8600000 /* MR-SHPC-01 I/O window base */ | ||
43 | #define MRSHPC_MODE (PA_MRSHPC + 4) | ||
44 | #define MRSHPC_OPTION (PA_MRSHPC + 6) | ||
45 | #define MRSHPC_CSR (PA_MRSHPC + 8) | ||
46 | #define MRSHPC_ISR (PA_MRSHPC + 10) | ||
47 | #define MRSHPC_ICR (PA_MRSHPC + 12) | ||
48 | #define MRSHPC_CPWCR (PA_MRSHPC + 14) | ||
49 | #define MRSHPC_MW0CR1 (PA_MRSHPC + 16) | ||
50 | #define MRSHPC_MW1CR1 (PA_MRSHPC + 18) | ||
51 | #define MRSHPC_IOWCR1 (PA_MRSHPC + 20) | ||
52 | #define MRSHPC_MW0CR2 (PA_MRSHPC + 22) | ||
53 | #define MRSHPC_MW1CR2 (PA_MRSHPC + 24) | ||
54 | #define MRSHPC_IOWCR2 (PA_MRSHPC + 26) | ||
55 | #define MRSHPC_CDCR (PA_MRSHPC + 28) | ||
56 | #define MRSHPC_PCIC_INFO (PA_MRSHPC + 30) | ||
57 | |||
58 | #define BCR_ILCRA (PA_BCR + 0) | ||
59 | #define BCR_ILCRB (PA_BCR + 2) | ||
60 | #define BCR_ILCRC (PA_BCR + 4) | ||
61 | #define BCR_ILCRD (PA_BCR + 6) | ||
62 | #define BCR_ILCRE (PA_BCR + 8) | ||
63 | #define BCR_ILCRF (PA_BCR + 10) | ||
64 | #define BCR_ILCRG (PA_BCR + 12) | ||
65 | |||
66 | #define IRQ_79C973 13 | ||
67 | |||
68 | #define __IO_PREFIX sh7751systemh | ||
69 | #include <asm/io_generic.h> | ||
70 | |||
71 | #endif /* __ASM_SH_SYSTEMH_7751SYSTEMH_H */ | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 2d9700c6b53a..0fe2e9329cb2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c | |||
@@ -48,7 +48,7 @@ static struct clk r_clk = { | |||
48 | * Default rate for the root input clock, reset this with clk_set_rate() | 48 | * Default rate for the root input clock, reset this with clk_set_rate() |
49 | * from the platform code. | 49 | * from the platform code. |
50 | */ | 50 | */ |
51 | struct clk extal_clk = { | 51 | static struct clk extal_clk = { |
52 | .rate = 33333333, | 52 | .rate = 33333333, |
53 | }; | 53 | }; |
54 | 54 | ||
@@ -111,7 +111,7 @@ static struct clk div3_clk = { | |||
111 | .parent = &pll_clk, | 111 | .parent = &pll_clk, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | struct clk *main_clks[] = { | 114 | static struct clk *main_clks[] = { |
115 | &r_clk, | 115 | &r_clk, |
116 | &extal_clk, | 116 | &extal_clk, |
117 | &fll_clk, | 117 | &fll_clk, |
@@ -156,7 +156,7 @@ struct clk div4_clks[DIV4_NR] = { | |||
156 | 156 | ||
157 | enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; | 157 | enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; |
158 | 158 | ||
159 | struct clk div6_clks[DIV6_NR] = { | 159 | static struct clk div6_clks[DIV6_NR] = { |
160 | [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0), | 160 | [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0), |
161 | [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0), | 161 | [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0), |
162 | [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0), | 162 | [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0), |
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 09370392aff1..c3e61b366493 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig | |||
@@ -79,7 +79,7 @@ config 29BIT | |||
79 | 79 | ||
80 | config 32BIT | 80 | config 32BIT |
81 | bool | 81 | bool |
82 | default y if CPU_SH5 | 82 | default y if CPU_SH5 || !MMU |
83 | 83 | ||
84 | config PMB | 84 | config PMB |
85 | bool "Support 32-bit physical addressing through PMB" | 85 | bool "Support 32-bit physical addressing through PMB" |
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 038793286990..40733a952402 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c | |||
@@ -79,21 +79,20 @@ void dma_generic_free_coherent(struct device *dev, size_t size, | |||
79 | void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 79 | void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
80 | enum dma_data_direction direction) | 80 | enum dma_data_direction direction) |
81 | { | 81 | { |
82 | #if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB) | 82 | void *addr; |
83 | void *p1addr = vaddr; | 83 | |
84 | #else | 84 | addr = __in_29bit_mode() ? |
85 | void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr); | 85 | (void *)P1SEGADDR((unsigned long)vaddr) : vaddr; |
86 | #endif | ||
87 | 86 | ||
88 | switch (direction) { | 87 | switch (direction) { |
89 | case DMA_FROM_DEVICE: /* invalidate only */ | 88 | case DMA_FROM_DEVICE: /* invalidate only */ |
90 | __flush_invalidate_region(p1addr, size); | 89 | __flush_invalidate_region(addr, size); |
91 | break; | 90 | break; |
92 | case DMA_TO_DEVICE: /* writeback only */ | 91 | case DMA_TO_DEVICE: /* writeback only */ |
93 | __flush_wback_region(p1addr, size); | 92 | __flush_wback_region(addr, size); |
94 | break; | 93 | break; |
95 | case DMA_BIDIRECTIONAL: /* writeback and invalidate */ | 94 | case DMA_BIDIRECTIONAL: /* writeback and invalidate */ |
96 | __flush_purge_region(p1addr, size); | 95 | __flush_purge_region(addr, size); |
97 | break; | 96 | break; |
98 | default: | 97 | default: |
99 | BUG(); | 98 | BUG(); |
diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c index 8a4eca551fc0..a7767da815e9 100644 --- a/arch/sh/mm/uncached.c +++ b/arch/sh/mm/uncached.c | |||
@@ -28,7 +28,7 @@ EXPORT_SYMBOL(virt_addr_uncached); | |||
28 | 28 | ||
29 | void __init uncached_init(void) | 29 | void __init uncached_init(void) |
30 | { | 30 | { |
31 | #ifdef CONFIG_29BIT | 31 | #if defined(CONFIG_29BIT) || !defined(CONFIG_MMU) |
32 | uncached_start = P2SEG; | 32 | uncached_start = P2SEG; |
33 | #else | 33 | #else |
34 | uncached_start = memory_end; | 34 | uncached_start = memory_end; |
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 9f56eb978024..0e68465e7b50 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types | |||
@@ -26,7 +26,6 @@ HD64461 HD64461 | |||
26 | 7724SE SH_7724_SOLUTION_ENGINE | 26 | 7724SE SH_7724_SOLUTION_ENGINE |
27 | 7751SE SH_7751_SOLUTION_ENGINE | 27 | 7751SE SH_7751_SOLUTION_ENGINE |
28 | 7780SE SH_7780_SOLUTION_ENGINE | 28 | 7780SE SH_7780_SOLUTION_ENGINE |
29 | 7751SYSTEMH SH_7751_SYSTEMH | ||
30 | HP6XX SH_HP6XX | 29 | HP6XX SH_HP6XX |
31 | DREAMCAST SH_DREAMCAST | 30 | DREAMCAST SH_DREAMCAST |
32 | SNAPGEAR SH_SECUREEDGE5410 | 31 | SNAPGEAR SH_SECUREEDGE5410 |
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h index e0f7ee186721..b2a6c5de79ab 100644 --- a/arch/tile/include/asm/highmem.h +++ b/arch/tile/include/asm/highmem.h | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/threads.h> | 25 | #include <linux/threads.h> |
26 | #include <asm/kmap_types.h> | ||
27 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
28 | #include <asm/homecache.h> | 27 | #include <asm/homecache.h> |
29 | 28 | ||
diff --git a/arch/tile/include/asm/kmap_types.h b/arch/tile/include/asm/kmap_types.h index 1480106d1c05..3d0f20246260 100644 --- a/arch/tile/include/asm/kmap_types.h +++ b/arch/tile/include/asm/kmap_types.h | |||
@@ -16,28 +16,42 @@ | |||
16 | #define _ASM_TILE_KMAP_TYPES_H | 16 | #define _ASM_TILE_KMAP_TYPES_H |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * In TILE Linux each set of four of these uses another 16MB chunk of | 19 | * In 32-bit TILE Linux we have to balance the desire to have a lot of |
20 | * address space, given 64 tiles and 64KB pages, so we only enable | 20 | * nested atomic mappings with the fact that large page sizes and many |
21 | * ones that are required by the kernel configuration. | 21 | * processors chew up address space quickly. In a typical |
22 | * 64-processor, 64KB-page layout build, making KM_TYPE_NR one larger | ||
23 | * adds 4MB of required address-space. For now we leave KM_TYPE_NR | ||
24 | * set to depth 8. | ||
22 | */ | 25 | */ |
23 | enum km_type { | 26 | enum km_type { |
27 | KM_TYPE_NR = 8 | ||
28 | }; | ||
29 | |||
30 | /* | ||
31 | * We provide dummy definitions of all the stray values that used to be | ||
32 | * required for kmap_atomic() and no longer are. | ||
33 | */ | ||
34 | enum { | ||
24 | KM_BOUNCE_READ, | 35 | KM_BOUNCE_READ, |
25 | KM_SKB_SUNRPC_DATA, | 36 | KM_SKB_SUNRPC_DATA, |
26 | KM_SKB_DATA_SOFTIRQ, | 37 | KM_SKB_DATA_SOFTIRQ, |
27 | KM_USER0, | 38 | KM_USER0, |
28 | KM_USER1, | 39 | KM_USER1, |
29 | KM_BIO_SRC_IRQ, | 40 | KM_BIO_SRC_IRQ, |
41 | KM_BIO_DST_IRQ, | ||
42 | KM_PTE0, | ||
43 | KM_PTE1, | ||
30 | KM_IRQ0, | 44 | KM_IRQ0, |
31 | KM_IRQ1, | 45 | KM_IRQ1, |
32 | KM_SOFTIRQ0, | 46 | KM_SOFTIRQ0, |
33 | KM_SOFTIRQ1, | 47 | KM_SOFTIRQ1, |
34 | KM_MEMCPY0, | 48 | KM_SYNC_ICACHE, |
35 | KM_MEMCPY1, | 49 | KM_SYNC_DCACHE, |
36 | #if defined(CONFIG_HIGHPTE) | 50 | KM_UML_USERCOPY, |
37 | KM_PTE0, | 51 | KM_IRQ_PTE, |
38 | KM_PTE1, | 52 | KM_NMI, |
39 | #endif | 53 | KM_NMI_PTE, |
40 | KM_TYPE_NR | 54 | KM_KDB |
41 | }; | 55 | }; |
42 | 56 | ||
43 | #endif /* _ASM_TILE_KMAP_TYPES_H */ | 57 | #endif /* _ASM_TILE_KMAP_TYPES_H */ |
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h index dc4ccdd855bc..a6604e9485da 100644 --- a/arch/tile/include/asm/pgtable.h +++ b/arch/tile/include/asm/pgtable.h | |||
@@ -344,10 +344,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
344 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | 344 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) |
345 | 345 | ||
346 | #if defined(CONFIG_HIGHPTE) | 346 | #if defined(CONFIG_HIGHPTE) |
347 | extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type); | 347 | extern pte_t *pte_offset_map(pmd_t *, unsigned long address); |
348 | #define pte_offset_map(dir, address) \ | 348 | #define pte_unmap(pte) kunmap_atomic(pte) |
349 | _pte_offset_map(dir, address, KM_PTE0) | ||
350 | #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) | ||
351 | #else | 349 | #else |
352 | #define pte_offset_map(dir, address) pte_offset_kernel(dir, address) | 350 | #define pte_offset_map(dir, address) pte_offset_kernel(dir, address) |
353 | #define pte_unmap(pte) do { } while (0) | 351 | #define pte_unmap(pte) do { } while (0) |
diff --git a/arch/tile/include/asm/stat.h b/arch/tile/include/asm/stat.h index 3dc90fa92c70..b16e5db8f0e7 100644 --- a/arch/tile/include/asm/stat.h +++ b/arch/tile/include/asm/stat.h | |||
@@ -1 +1,4 @@ | |||
1 | #ifdef CONFIG_COMPAT | ||
2 | #define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */ | ||
3 | #endif | ||
1 | #include <asm-generic/stat.h> | 4 | #include <asm-generic/stat.h> |
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h index f2e3ff485333..b35c2db71199 100644 --- a/arch/tile/include/asm/unistd.h +++ b/arch/tile/include/asm/unistd.h | |||
@@ -41,6 +41,7 @@ __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr) | |||
41 | #ifdef CONFIG_COMPAT | 41 | #ifdef CONFIG_COMPAT |
42 | #define __ARCH_WANT_SYS_LLSEEK | 42 | #define __ARCH_WANT_SYS_LLSEEK |
43 | #endif | 43 | #endif |
44 | #define __ARCH_WANT_SYS_NEWFSTATAT | ||
44 | #endif | 45 | #endif |
45 | 46 | ||
46 | #endif /* _ASM_TILE_UNISTD_H */ | 47 | #endif /* _ASM_TILE_UNISTD_H */ |
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index 77739cdd9462..67617a05e602 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c | |||
@@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid, | |||
148 | #define compat_sys_readahead sys32_readahead | 148 | #define compat_sys_readahead sys32_readahead |
149 | #define compat_sys_sync_file_range compat_sys_sync_file_range2 | 149 | #define compat_sys_sync_file_range compat_sys_sync_file_range2 |
150 | 150 | ||
151 | /* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */ | 151 | /* We leverage the "struct stat64" type for 32-bit time_t/nsec. */ |
152 | #define compat_sys_stat64 sys_newstat | 152 | #define compat_sys_stat64 sys_stat64 |
153 | #define compat_sys_lstat64 sys_newlstat | 153 | #define compat_sys_lstat64 sys_lstat64 |
154 | #define compat_sys_fstat64 sys_newfstat | 154 | #define compat_sys_fstat64 sys_fstat64 |
155 | #define compat_sys_fstatat64 sys_newfstatat | 155 | #define compat_sys_fstatat64 sys_fstatat64 |
156 | 156 | ||
157 | /* The native sys_ptrace dynamically handles compat binaries. */ | 157 | /* The native sys_ptrace dynamically handles compat binaries. */ |
158 | #define compat_sys_ptrace sys_ptrace | 158 | #define compat_sys_ptrace sys_ptrace |
diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c index 2c54fd43a8a0..493a0e66d916 100644 --- a/arch/tile/kernel/early_printk.c +++ b/arch/tile/kernel/early_printk.c | |||
@@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...) | |||
54 | void early_panic(const char *fmt, ...) | 54 | void early_panic(const char *fmt, ...) |
55 | { | 55 | { |
56 | va_list ap; | 56 | va_list ap; |
57 | raw_local_irq_disable_all(); | 57 | arch_local_irq_disable_all(); |
58 | va_start(ap, fmt); | 58 | va_start(ap, fmt); |
59 | early_printk("Kernel panic - not syncing: "); | 59 | early_printk("Kernel panic - not syncing: "); |
60 | early_vprintk(fmt, ap); | 60 | early_vprintk(fmt, ap); |
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 1e54a7843410..e910530436e6 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c | |||
@@ -151,12 +151,12 @@ enum direction_protect { | |||
151 | 151 | ||
152 | static void enable_firewall_interrupts(void) | 152 | static void enable_firewall_interrupts(void) |
153 | { | 153 | { |
154 | raw_local_irq_unmask_now(INT_UDN_FIREWALL); | 154 | arch_local_irq_unmask_now(INT_UDN_FIREWALL); |
155 | } | 155 | } |
156 | 156 | ||
157 | static void disable_firewall_interrupts(void) | 157 | static void disable_firewall_interrupts(void) |
158 | { | 158 | { |
159 | raw_local_irq_mask_now(INT_UDN_FIREWALL); | 159 | arch_local_irq_mask_now(INT_UDN_FIREWALL); |
160 | } | 160 | } |
161 | 161 | ||
162 | /* Set up hardwall on this cpu based on the passed hardwall_info. */ | 162 | /* Set up hardwall on this cpu based on the passed hardwall_info. */ |
@@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file) | |||
768 | } | 768 | } |
769 | 769 | ||
770 | static const struct file_operations dev_hardwall_fops = { | 770 | static const struct file_operations dev_hardwall_fops = { |
771 | .open = nonseekable_open, | ||
771 | .unlocked_ioctl = hardwall_ioctl, | 772 | .unlocked_ioctl = hardwall_ioctl, |
772 | #ifdef CONFIG_COMPAT | 773 | #ifdef CONFIG_COMPAT |
773 | .compat_ioctl = hardwall_compat_ioctl, | 774 | .compat_ioctl = hardwall_compat_ioctl, |
774 | #endif | 775 | #endif |
775 | .flush = hardwall_flush, | 776 | .flush = hardwall_flush, |
776 | .release = hardwall_release, | 777 | .release = hardwall_release, |
777 | .llseek = noop_llseek, | ||
778 | }; | 778 | }; |
779 | 779 | ||
780 | static struct cdev hardwall_dev; | 780 | static struct cdev hardwall_dev; |
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index e63917687e99..128805ef8f2c 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #define IS_HW_CLEARED 1 | 26 | #define IS_HW_CLEARED 1 |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * The set of interrupts we enable for raw_local_irq_enable(). | 29 | * The set of interrupts we enable for arch_local_irq_enable(). |
30 | * This is initialized to have just a single interrupt that the kernel | 30 | * This is initialized to have just a single interrupt that the kernel |
31 | * doesn't actually use as a sentinel. During kernel init, | 31 | * doesn't actually use as a sentinel. During kernel init, |
32 | * interrupts are added as the kernel gets prepared to support them. | 32 | * interrupts are added as the kernel gets prepared to support them. |
@@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void) | |||
225 | /* Enable interrupt delivery. */ | 225 | /* Enable interrupt delivery. */ |
226 | unmask_irqs(~0UL); | 226 | unmask_irqs(~0UL); |
227 | #if CHIP_HAS_IPI() | 227 | #if CHIP_HAS_IPI() |
228 | raw_local_irq_unmask(INT_IPI_K); | 228 | arch_local_irq_unmask(INT_IPI_K); |
229 | #endif | 229 | #endif |
230 | } | 230 | } |
231 | 231 | ||
diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c index ba7a265d6179..0d8b9e933487 100644 --- a/arch/tile/kernel/machine_kexec.c +++ b/arch/tile/kernel/machine_kexec.c | |||
@@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image) | |||
182 | 182 | ||
183 | if ((entry & IND_SOURCE)) { | 183 | if ((entry & IND_SOURCE)) { |
184 | void *va = | 184 | void *va = |
185 | kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0); | 185 | kmap_atomic_pfn(entry >> PAGE_SHIFT); |
186 | r = kexec_bn2cl(va); | 186 | r = kexec_bn2cl(va); |
187 | if (r) { | 187 | if (r) { |
188 | command_line = r; | 188 | command_line = r; |
189 | break; | 189 | break; |
190 | } | 190 | } |
191 | kunmap_atomic(va, KM_USER0); | 191 | kunmap_atomic(va); |
192 | } | 192 | } |
193 | } | 193 | } |
194 | 194 | ||
@@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image) | |||
198 | 198 | ||
199 | hverr = hv_set_command_line( | 199 | hverr = hv_set_command_line( |
200 | (HV_VirtAddr) command_line, strlen(command_line)); | 200 | (HV_VirtAddr) command_line, strlen(command_line)); |
201 | kunmap_atomic(command_line, KM_USER0); | 201 | kunmap_atomic(command_line); |
202 | } else { | 202 | } else { |
203 | pr_info("%s: no command line found; making empty\n", | 203 | pr_info("%s: no command line found; making empty\n", |
204 | __func__); | 204 | __func__); |
diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c index 997e3933f726..0858ee6b520f 100644 --- a/arch/tile/kernel/messaging.c +++ b/arch/tile/kernel/messaging.c | |||
@@ -34,7 +34,7 @@ void __cpuinit init_messaging(void) | |||
34 | panic("hv_register_message_state: error %d", rc); | 34 | panic("hv_register_message_state: error %d", rc); |
35 | 35 | ||
36 | /* Make sure downcall interrupts will be enabled. */ | 36 | /* Make sure downcall interrupts will be enabled. */ |
37 | raw_local_irq_unmask(INT_INTCTRL_K); | 37 | arch_local_irq_unmask(INT_INTCTRL_K); |
38 | } | 38 | } |
39 | 39 | ||
40 | void hv_message_intr(struct pt_regs *regs, int intnum) | 40 | void hv_message_intr(struct pt_regs *regs, int intnum) |
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 9cd29884c09f..e92e40527d6d 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c | |||
@@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request, | |||
50 | { | 50 | { |
51 | unsigned long __user *datap = (long __user __force *)data; | 51 | unsigned long __user *datap = (long __user __force *)data; |
52 | unsigned long tmp; | 52 | unsigned long tmp; |
53 | int i; | ||
54 | long ret = -EIO; | 53 | long ret = -EIO; |
55 | unsigned long *childregs; | ||
56 | char *childreg; | 54 | char *childreg; |
55 | struct pt_regs copyregs; | ||
56 | int ex1_offset; | ||
57 | 57 | ||
58 | switch (request) { | 58 | switch (request) { |
59 | 59 | ||
@@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request, | |||
80 | if (addr >= PTREGS_SIZE) | 80 | if (addr >= PTREGS_SIZE) |
81 | break; | 81 | break; |
82 | childreg = (char *)task_pt_regs(child) + addr; | 82 | childreg = (char *)task_pt_regs(child) + addr; |
83 | |||
84 | /* Guard against overwrites of the privilege level. */ | ||
85 | ex1_offset = PTREGS_OFFSET_EX1; | ||
86 | #if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) | ||
87 | if (is_compat_task()) /* point at low word */ | ||
88 | ex1_offset += sizeof(compat_long_t); | ||
89 | #endif | ||
90 | if (addr == ex1_offset) | ||
91 | data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); | ||
92 | |||
83 | #ifdef CONFIG_COMPAT | 93 | #ifdef CONFIG_COMPAT |
84 | if (is_compat_task()) { | 94 | if (is_compat_task()) { |
85 | if (addr & (sizeof(compat_long_t)-1)) | 95 | if (addr & (sizeof(compat_long_t)-1)) |
@@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request, | |||
96 | break; | 106 | break; |
97 | 107 | ||
98 | case PTRACE_GETREGS: /* Get all registers from the child. */ | 108 | case PTRACE_GETREGS: /* Get all registers from the child. */ |
99 | if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) | 109 | if (copy_to_user(datap, task_pt_regs(child), |
100 | break; | 110 | sizeof(struct pt_regs)) == 0) { |
101 | childregs = (long *)task_pt_regs(child); | 111 | ret = 0; |
102 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); | ||
103 | ++i) { | ||
104 | ret = __put_user(childregs[i], &datap[i]); | ||
105 | if (ret != 0) | ||
106 | break; | ||
107 | } | 112 | } |
108 | break; | 113 | break; |
109 | 114 | ||
110 | case PTRACE_SETREGS: /* Set all registers in the child. */ | 115 | case PTRACE_SETREGS: /* Set all registers in the child. */ |
111 | if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) | 116 | if (copy_from_user(©regs, datap, |
112 | break; | 117 | sizeof(struct pt_regs)) == 0) { |
113 | childregs = (long *)task_pt_regs(child); | 118 | copyregs.ex1 = |
114 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); | 119 | PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); |
115 | ++i) { | 120 | *task_pt_regs(child) = copyregs; |
116 | ret = __get_user(childregs[i], &datap[i]); | 121 | ret = 0; |
117 | if (ret != 0) | ||
118 | break; | ||
119 | } | 122 | } |
120 | break; | 123 | break; |
121 | 124 | ||
diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c index acd86d20beba..baa3d905fee2 100644 --- a/arch/tile/kernel/reboot.c +++ b/arch/tile/kernel/reboot.c | |||
@@ -27,7 +27,7 @@ | |||
27 | void machine_halt(void) | 27 | void machine_halt(void) |
28 | { | 28 | { |
29 | warn_early_printk(); | 29 | warn_early_printk(); |
30 | raw_local_irq_disable_all(); | 30 | arch_local_irq_disable_all(); |
31 | smp_send_stop(); | 31 | smp_send_stop(); |
32 | hv_halt(); | 32 | hv_halt(); |
33 | } | 33 | } |
@@ -35,14 +35,14 @@ void machine_halt(void) | |||
35 | void machine_power_off(void) | 35 | void machine_power_off(void) |
36 | { | 36 | { |
37 | warn_early_printk(); | 37 | warn_early_printk(); |
38 | raw_local_irq_disable_all(); | 38 | arch_local_irq_disable_all(); |
39 | smp_send_stop(); | 39 | smp_send_stop(); |
40 | hv_power_off(); | 40 | hv_power_off(); |
41 | } | 41 | } |
42 | 42 | ||
43 | void machine_restart(char *cmd) | 43 | void machine_restart(char *cmd) |
44 | { | 44 | { |
45 | raw_local_irq_disable_all(); | 45 | arch_local_irq_disable_all(); |
46 | smp_send_stop(); | 46 | smp_send_stop(); |
47 | hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); | 47 | hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); |
48 | } | 48 | } |
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index ae51cad12da0..fb0b3cbeae14 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
@@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot) | |||
868 | 868 | ||
869 | /* Allow asynchronous TLB interrupts. */ | 869 | /* Allow asynchronous TLB interrupts. */ |
870 | #if CHIP_HAS_TILE_DMA() | 870 | #if CHIP_HAS_TILE_DMA() |
871 | raw_local_irq_unmask(INT_DMATLB_MISS); | 871 | arch_local_irq_unmask(INT_DMATLB_MISS); |
872 | raw_local_irq_unmask(INT_DMATLB_ACCESS); | 872 | arch_local_irq_unmask(INT_DMATLB_ACCESS); |
873 | #endif | 873 | #endif |
874 | #if CHIP_HAS_SN_PROC() | 874 | #if CHIP_HAS_SN_PROC() |
875 | raw_local_irq_unmask(INT_SNITLB_MISS); | 875 | arch_local_irq_unmask(INT_SNITLB_MISS); |
876 | #endif | 876 | #endif |
877 | #ifdef __tilegx__ | 877 | #ifdef __tilegx__ |
878 | raw_local_irq_unmask(INT_SINGLE_STEP_K); | 878 | arch_local_irq_unmask(INT_SINGLE_STEP_K); |
879 | #endif | 879 | #endif |
880 | 880 | ||
881 | /* | 881 | /* |
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index fb28e85ae3ae..687719d4abd1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
@@ -71,6 +71,9 @@ int restore_sigcontext(struct pt_regs *regs, | |||
71 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) | 71 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) |
72 | err |= __get_user(regs->regs[i], &sc->gregs[i]); | 72 | err |= __get_user(regs->regs[i], &sc->gregs[i]); |
73 | 73 | ||
74 | /* Ensure that the PL is always set to USER_PL. */ | ||
75 | regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); | ||
76 | |||
74 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 77 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
75 | 78 | ||
76 | err |= __get_user(*pr0, &sc->gregs[0]); | 79 | err |= __get_user(*pr0, &sc->gregs[0]); |
@@ -330,7 +333,7 @@ void do_signal(struct pt_regs *regs) | |||
330 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 333 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
331 | } | 334 | } |
332 | 335 | ||
333 | return; | 336 | goto done; |
334 | } | 337 | } |
335 | 338 | ||
336 | /* Did we come from a system call? */ | 339 | /* Did we come from a system call? */ |
@@ -358,4 +361,8 @@ void do_signal(struct pt_regs *regs) | |||
358 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 361 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
359 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 362 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
360 | } | 363 | } |
364 | |||
365 | done: | ||
366 | /* Avoid double syscall restart if there are nested signals. */ | ||
367 | regs->faultnum = INT_SWINT_1_SIGRETURN; | ||
361 | } | 368 | } |
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index 75255d90aff3..9575b37a8b75 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c | |||
@@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void) | |||
115 | static void smp_stop_cpu_interrupt(void) | 115 | static void smp_stop_cpu_interrupt(void) |
116 | { | 116 | { |
117 | set_cpu_online(smp_processor_id(), 0); | 117 | set_cpu_online(smp_processor_id(), 0); |
118 | raw_local_irq_disable_all(); | 118 | arch_local_irq_disable_all(); |
119 | for (;;) | 119 | for (;;) |
120 | asm("nap"); | 120 | asm("nap"); |
121 | } | 121 | } |
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 6bed820e1421..f2e156e44692 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c | |||
@@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks, | |||
132 | { | 132 | { |
133 | BUG_ON(ticks > MAX_TICK); | 133 | BUG_ON(ticks > MAX_TICK); |
134 | __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); | 134 | __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); |
135 | raw_local_irq_unmask_now(INT_TILE_TIMER); | 135 | arch_local_irq_unmask_now(INT_TILE_TIMER); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
@@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks, | |||
143 | static void tile_timer_set_mode(enum clock_event_mode mode, | 143 | static void tile_timer_set_mode(enum clock_event_mode mode, |
144 | struct clock_event_device *evt) | 144 | struct clock_event_device *evt) |
145 | { | 145 | { |
146 | raw_local_irq_mask_now(INT_TILE_TIMER); | 146 | arch_local_irq_mask_now(INT_TILE_TIMER); |
147 | } | 147 | } |
148 | 148 | ||
149 | /* | 149 | /* |
@@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void) | |||
172 | evt->cpumask = cpumask_of(smp_processor_id()); | 172 | evt->cpumask = cpumask_of(smp_processor_id()); |
173 | 173 | ||
174 | /* Start out with timer not firing. */ | 174 | /* Start out with timer not firing. */ |
175 | raw_local_irq_mask_now(INT_TILE_TIMER); | 175 | arch_local_irq_mask_now(INT_TILE_TIMER); |
176 | 176 | ||
177 | /* Register tile timer. */ | 177 | /* Register tile timer. */ |
178 | clockevents_register_device(evt); | 178 | clockevents_register_device(evt); |
@@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num) | |||
188 | * Mask the timer interrupt here, since we are a oneshot timer | 188 | * Mask the timer interrupt here, since we are a oneshot timer |
189 | * and there are now by definition no events pending. | 189 | * and there are now by definition no events pending. |
190 | */ | 190 | */ |
191 | raw_local_irq_mask(INT_TILE_TIMER); | 191 | arch_local_irq_mask(INT_TILE_TIMER); |
192 | 192 | ||
193 | /* Track time spent here in an interrupt context */ | 193 | /* Track time spent here in an interrupt context */ |
194 | irq_enter(); | 194 | irq_enter(); |
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c index dfedea7b266b..f7d4a6ad61e8 100644 --- a/arch/tile/lib/memcpy_tile64.c +++ b/arch/tile/lib/memcpy_tile64.c | |||
@@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long); | |||
54 | * we must run with interrupts disabled to avoid the risk of some | 54 | * we must run with interrupts disabled to avoid the risk of some |
55 | * other code seeing the incoherent data in our cache. (Recall that | 55 | * other code seeing the incoherent data in our cache. (Recall that |
56 | * our cache is indexed by PA, so even if the other code doesn't use | 56 | * our cache is indexed by PA, so even if the other code doesn't use |
57 | * our KM_MEMCPY virtual addresses, they'll still hit in cache using | 57 | * our kmap_atomic virtual addresses, they'll still hit in cache using |
58 | * the normal VAs that aren't supposed to hit in cache.) | 58 | * the normal VAs that aren't supposed to hit in cache.) |
59 | */ | 59 | */ |
60 | static void memcpy_multicache(void *dest, const void *source, | 60 | static void memcpy_multicache(void *dest, const void *source, |
@@ -64,6 +64,7 @@ static void memcpy_multicache(void *dest, const void *source, | |||
64 | unsigned long flags, newsrc, newdst; | 64 | unsigned long flags, newsrc, newdst; |
65 | pmd_t *pmdp; | 65 | pmd_t *pmdp; |
66 | pte_t *ptep; | 66 | pte_t *ptep; |
67 | int type0, type1; | ||
67 | int cpu = get_cpu(); | 68 | int cpu = get_cpu(); |
68 | 69 | ||
69 | /* | 70 | /* |
@@ -77,7 +78,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
77 | sim_allow_multiple_caching(1); | 78 | sim_allow_multiple_caching(1); |
78 | 79 | ||
79 | /* Set up the new dest mapping */ | 80 | /* Set up the new dest mapping */ |
80 | idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0; | 81 | type0 = kmap_atomic_idx_push(); |
82 | idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0; | ||
81 | newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); | 83 | newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); |
82 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); | 84 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); |
83 | ptep = pte_offset_kernel(pmdp, newdst); | 85 | ptep = pte_offset_kernel(pmdp, newdst); |
@@ -87,7 +89,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
87 | } | 89 | } |
88 | 90 | ||
89 | /* Set up the new source mapping */ | 91 | /* Set up the new source mapping */ |
90 | idx += (KM_MEMCPY0 - KM_MEMCPY1); | 92 | type1 = kmap_atomic_idx_push(); |
93 | idx += (type0 - type1); | ||
91 | src_pte = hv_pte_set_nc(src_pte); | 94 | src_pte = hv_pte_set_nc(src_pte); |
92 | src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ | 95 | src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ |
93 | newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); | 96 | newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); |
@@ -119,6 +122,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
119 | * We're done: notify the simulator that all is back to normal, | 122 | * We're done: notify the simulator that all is back to normal, |
120 | * and re-enable interrupts and pre-emption. | 123 | * and re-enable interrupts and pre-emption. |
121 | */ | 124 | */ |
125 | kmap_atomic_idx_pop(); | ||
126 | kmap_atomic_idx_pop(); | ||
122 | sim_allow_multiple_caching(0); | 127 | sim_allow_multiple_caching(0); |
123 | local_irq_restore(flags); | 128 | local_irq_restore(flags); |
124 | put_cpu(); | 129 | put_cpu(); |
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c index abb57331cf6e..31dbbd9afe47 100644 --- a/arch/tile/mm/highmem.c +++ b/arch/tile/mm/highmem.c | |||
@@ -227,7 +227,7 @@ EXPORT_SYMBOL(kmap_atomic_prot); | |||
227 | void *__kmap_atomic(struct page *page) | 227 | void *__kmap_atomic(struct page *page) |
228 | { | 228 | { |
229 | /* PAGE_NONE is a magic value that tells us to check immutability. */ | 229 | /* PAGE_NONE is a magic value that tells us to check immutability. */ |
230 | return kmap_atomic_prot(page, type, PAGE_NONE); | 230 | return kmap_atomic_prot(page, PAGE_NONE); |
231 | } | 231 | } |
232 | EXPORT_SYMBOL(__kmap_atomic); | 232 | EXPORT_SYMBOL(__kmap_atomic); |
233 | 233 | ||
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 78e1982cb6c9..0b9ce69b0ee5 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c | |||
@@ -988,8 +988,12 @@ static long __write_once initfree = 1; | |||
988 | /* Select whether to free (1) or mark unusable (0) the __init pages. */ | 988 | /* Select whether to free (1) or mark unusable (0) the __init pages. */ |
989 | static int __init set_initfree(char *str) | 989 | static int __init set_initfree(char *str) |
990 | { | 990 | { |
991 | strict_strtol(str, 0, &initfree); | 991 | long val; |
992 | pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't"); | 992 | if (strict_strtol(str, 0, &val)) { |
993 | initfree = val; | ||
994 | pr_info("initfree: %s free init pages\n", | ||
995 | initfree ? "will" : "won't"); | ||
996 | } | ||
993 | return 1; | 997 | return 1; |
994 | } | 998 | } |
995 | __setup("initfree=", set_initfree); | 999 | __setup("initfree=", set_initfree); |
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 335c24621c41..1f5430c53d0d 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c | |||
@@ -134,9 +134,9 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | #if defined(CONFIG_HIGHPTE) | 136 | #if defined(CONFIG_HIGHPTE) |
137 | pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type) | 137 | pte_t *_pte_offset_map(pmd_t *dir, unsigned long address) |
138 | { | 138 | { |
139 | pte_t *pte = kmap_atomic(pmd_page(*dir), type) + | 139 | pte_t *pte = kmap_atomic(pmd_page(*dir)) + |
140 | (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK; | 140 | (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK; |
141 | return &pte[pte_index(address)]; | 141 | return &pte[pte_index(address)]; |
142 | } | 142 | } |
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index 2cd899f75a3c..b7c5bab9bd77 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h | |||
@@ -38,8 +38,8 @@ struct pt_regs { | |||
38 | 38 | ||
39 | struct task_struct; | 39 | struct task_struct; |
40 | 40 | ||
41 | extern long subarch_ptrace(struct task_struct *child, long request, long addr, | 41 | extern long subarch_ptrace(struct task_struct *child, long request, |
42 | long data); | 42 | unsigned long addr, unsigned long data); |
43 | extern unsigned long getreg(struct task_struct *child, int regno); | 43 | extern unsigned long getreg(struct task_struct *child, int regno); |
44 | extern int putreg(struct task_struct *child, int regno, unsigned long value); | 44 | extern int putreg(struct task_struct *child, int regno, unsigned long value); |
45 | extern int get_fpregs(struct user_i387_struct __user *buf, | 45 | extern int get_fpregs(struct user_i387_struct __user *buf, |
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index a5e33f29bbeb..701b672c1122 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -122,7 +122,7 @@ long arch_ptrace(struct task_struct *child, long request, | |||
122 | break; | 122 | break; |
123 | 123 | ||
124 | case PTRACE_SET_THREAD_AREA: | 124 | case PTRACE_SET_THREAD_AREA: |
125 | ret = ptrace_set_thread_area(child, addr, datavp); | 125 | ret = ptrace_set_thread_area(child, addr, vp); |
126 | break; | 126 | break; |
127 | 127 | ||
128 | case PTRACE_FAULTINFO: { | 128 | case PTRACE_FAULTINFO: { |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 286de34b0ed6..f6ce0bda3b98 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -141,13 +141,13 @@ static inline void native_apic_msr_write(u32 reg, u32 v) | |||
141 | 141 | ||
142 | static inline u32 native_apic_msr_read(u32 reg) | 142 | static inline u32 native_apic_msr_read(u32 reg) |
143 | { | 143 | { |
144 | u32 low, high; | 144 | u64 msr; |
145 | 145 | ||
146 | if (reg == APIC_DFR) | 146 | if (reg == APIC_DFR) |
147 | return -1; | 147 | return -1; |
148 | 148 | ||
149 | rdmsr(APIC_BASE_MSR + (reg >> 4), low, high); | 149 | rdmsrl(APIC_BASE_MSR + (reg >> 4), msr); |
150 | return low; | 150 | return (u32)msr; |
151 | } | 151 | } |
152 | 152 | ||
153 | static inline void native_x2apic_wait_icr_idle(void) | 153 | static inline void native_x2apic_wait_icr_idle(void) |
@@ -181,12 +181,12 @@ extern void enable_x2apic(void); | |||
181 | extern void x2apic_icr_write(u32 low, u32 id); | 181 | extern void x2apic_icr_write(u32 low, u32 id); |
182 | static inline int x2apic_enabled(void) | 182 | static inline int x2apic_enabled(void) |
183 | { | 183 | { |
184 | int msr, msr2; | 184 | u64 msr; |
185 | 185 | ||
186 | if (!cpu_has_x2apic) | 186 | if (!cpu_has_x2apic) |
187 | return 0; | 187 | return 0; |
188 | 188 | ||
189 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | 189 | rdmsrl(MSR_IA32_APICBASE, msr); |
190 | if (msr & X2APIC_ENABLE) | 190 | if (msr & X2APIC_ENABLE) |
191 | return 1; | 191 | return 1; |
192 | return 0; | 192 | return 0; |
diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index b2f2d2e05cec..6d90adf4428a 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h | |||
@@ -806,6 +806,78 @@ union uvh_node_present_table_u { | |||
806 | }; | 806 | }; |
807 | 807 | ||
808 | /* ========================================================================= */ | 808 | /* ========================================================================= */ |
809 | /* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR */ | ||
810 | /* ========================================================================= */ | ||
811 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x16000c8UL | ||
812 | |||
813 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 | ||
814 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL | ||
815 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 | ||
816 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL | ||
817 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 | ||
818 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL | ||
819 | |||
820 | union uvh_rh_gam_alias210_overlay_config_0_mmr_u { | ||
821 | unsigned long v; | ||
822 | struct uvh_rh_gam_alias210_overlay_config_0_mmr_s { | ||
823 | unsigned long rsvd_0_23: 24; /* */ | ||
824 | unsigned long base : 8; /* RW */ | ||
825 | unsigned long rsvd_32_47: 16; /* */ | ||
826 | unsigned long m_alias : 5; /* RW */ | ||
827 | unsigned long rsvd_53_62: 10; /* */ | ||
828 | unsigned long enable : 1; /* RW */ | ||
829 | } s; | ||
830 | }; | ||
831 | |||
832 | /* ========================================================================= */ | ||
833 | /* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR */ | ||
834 | /* ========================================================================= */ | ||
835 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x16000d8UL | ||
836 | |||
837 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 | ||
838 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL | ||
839 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 | ||
840 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL | ||
841 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 | ||
842 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL | ||
843 | |||
844 | union uvh_rh_gam_alias210_overlay_config_1_mmr_u { | ||
845 | unsigned long v; | ||
846 | struct uvh_rh_gam_alias210_overlay_config_1_mmr_s { | ||
847 | unsigned long rsvd_0_23: 24; /* */ | ||
848 | unsigned long base : 8; /* RW */ | ||
849 | unsigned long rsvd_32_47: 16; /* */ | ||
850 | unsigned long m_alias : 5; /* RW */ | ||
851 | unsigned long rsvd_53_62: 10; /* */ | ||
852 | unsigned long enable : 1; /* RW */ | ||
853 | } s; | ||
854 | }; | ||
855 | |||
856 | /* ========================================================================= */ | ||
857 | /* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR */ | ||
858 | /* ========================================================================= */ | ||
859 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x16000e8UL | ||
860 | |||
861 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 | ||
862 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL | ||
863 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 | ||
864 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL | ||
865 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 | ||
866 | #define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL | ||
867 | |||
868 | union uvh_rh_gam_alias210_overlay_config_2_mmr_u { | ||
869 | unsigned long v; | ||
870 | struct uvh_rh_gam_alias210_overlay_config_2_mmr_s { | ||
871 | unsigned long rsvd_0_23: 24; /* */ | ||
872 | unsigned long base : 8; /* RW */ | ||
873 | unsigned long rsvd_32_47: 16; /* */ | ||
874 | unsigned long m_alias : 5; /* RW */ | ||
875 | unsigned long rsvd_53_62: 10; /* */ | ||
876 | unsigned long enable : 1; /* RW */ | ||
877 | } s; | ||
878 | }; | ||
879 | |||
880 | /* ========================================================================= */ | ||
809 | /* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */ | 881 | /* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */ |
810 | /* ========================================================================= */ | 882 | /* ========================================================================= */ |
811 | #define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL | 883 | #define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL |
@@ -857,6 +929,29 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { | |||
857 | }; | 929 | }; |
858 | 930 | ||
859 | /* ========================================================================= */ | 931 | /* ========================================================================= */ |
932 | /* UVH_RH_GAM_CONFIG_MMR */ | ||
933 | /* ========================================================================= */ | ||
934 | #define UVH_RH_GAM_CONFIG_MMR 0x1600000UL | ||
935 | |||
936 | #define UVH_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 | ||
937 | #define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | ||
938 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | ||
939 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | ||
940 | #define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 | ||
941 | #define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL | ||
942 | |||
943 | union uvh_rh_gam_config_mmr_u { | ||
944 | unsigned long v; | ||
945 | struct uvh_rh_gam_config_mmr_s { | ||
946 | unsigned long m_skt : 6; /* RW */ | ||
947 | unsigned long n_skt : 4; /* RW */ | ||
948 | unsigned long rsvd_10_11: 2; /* */ | ||
949 | unsigned long mmiol_cfg : 1; /* RW */ | ||
950 | unsigned long rsvd_13_63: 51; /* */ | ||
951 | } s; | ||
952 | }; | ||
953 | |||
954 | /* ========================================================================= */ | ||
860 | /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ | 955 | /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ |
861 | /* ========================================================================= */ | 956 | /* ========================================================================= */ |
862 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL | 957 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL |
@@ -987,97 +1082,5 @@ union uvh_rtc1_int_config_u { | |||
987 | } s; | 1082 | } s; |
988 | }; | 1083 | }; |
989 | 1084 | ||
990 | /* ========================================================================= */ | ||
991 | /* UVH_SI_ADDR_MAP_CONFIG */ | ||
992 | /* ========================================================================= */ | ||
993 | #define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL | ||
994 | |||
995 | #define UVH_SI_ADDR_MAP_CONFIG_M_SKT_SHFT 0 | ||
996 | #define UVH_SI_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL | ||
997 | #define UVH_SI_ADDR_MAP_CONFIG_N_SKT_SHFT 8 | ||
998 | #define UVH_SI_ADDR_MAP_CONFIG_N_SKT_MASK 0x0000000000000f00UL | ||
999 | |||
1000 | union uvh_si_addr_map_config_u { | ||
1001 | unsigned long v; | ||
1002 | struct uvh_si_addr_map_config_s { | ||
1003 | unsigned long m_skt : 6; /* RW */ | ||
1004 | unsigned long rsvd_6_7: 2; /* */ | ||
1005 | unsigned long n_skt : 4; /* RW */ | ||
1006 | unsigned long rsvd_12_63: 52; /* */ | ||
1007 | } s; | ||
1008 | }; | ||
1009 | |||
1010 | /* ========================================================================= */ | ||
1011 | /* UVH_SI_ALIAS0_OVERLAY_CONFIG */ | ||
1012 | /* ========================================================================= */ | ||
1013 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG 0xc80008UL | ||
1014 | |||
1015 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_SHFT 24 | ||
1016 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL | ||
1017 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_SHFT 48 | ||
1018 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL | ||
1019 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_SHFT 63 | ||
1020 | #define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL | ||
1021 | |||
1022 | union uvh_si_alias0_overlay_config_u { | ||
1023 | unsigned long v; | ||
1024 | struct uvh_si_alias0_overlay_config_s { | ||
1025 | unsigned long rsvd_0_23: 24; /* */ | ||
1026 | unsigned long base : 8; /* RW */ | ||
1027 | unsigned long rsvd_32_47: 16; /* */ | ||
1028 | unsigned long m_alias : 5; /* RW */ | ||
1029 | unsigned long rsvd_53_62: 10; /* */ | ||
1030 | unsigned long enable : 1; /* RW */ | ||
1031 | } s; | ||
1032 | }; | ||
1033 | |||
1034 | /* ========================================================================= */ | ||
1035 | /* UVH_SI_ALIAS1_OVERLAY_CONFIG */ | ||
1036 | /* ========================================================================= */ | ||
1037 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG 0xc80010UL | ||
1038 | |||
1039 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_SHFT 24 | ||
1040 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL | ||
1041 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_SHFT 48 | ||
1042 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL | ||
1043 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_SHFT 63 | ||
1044 | #define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL | ||
1045 | |||
1046 | union uvh_si_alias1_overlay_config_u { | ||
1047 | unsigned long v; | ||
1048 | struct uvh_si_alias1_overlay_config_s { | ||
1049 | unsigned long rsvd_0_23: 24; /* */ | ||
1050 | unsigned long base : 8; /* RW */ | ||
1051 | unsigned long rsvd_32_47: 16; /* */ | ||
1052 | unsigned long m_alias : 5; /* RW */ | ||
1053 | unsigned long rsvd_53_62: 10; /* */ | ||
1054 | unsigned long enable : 1; /* RW */ | ||
1055 | } s; | ||
1056 | }; | ||
1057 | |||
1058 | /* ========================================================================= */ | ||
1059 | /* UVH_SI_ALIAS2_OVERLAY_CONFIG */ | ||
1060 | /* ========================================================================= */ | ||
1061 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG 0xc80018UL | ||
1062 | |||
1063 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_SHFT 24 | ||
1064 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL | ||
1065 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_SHFT 48 | ||
1066 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL | ||
1067 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_SHFT 63 | ||
1068 | #define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL | ||
1069 | |||
1070 | union uvh_si_alias2_overlay_config_u { | ||
1071 | unsigned long v; | ||
1072 | struct uvh_si_alias2_overlay_config_s { | ||
1073 | unsigned long rsvd_0_23: 24; /* */ | ||
1074 | unsigned long base : 8; /* RW */ | ||
1075 | unsigned long rsvd_32_47: 16; /* */ | ||
1076 | unsigned long m_alias : 5; /* RW */ | ||
1077 | unsigned long rsvd_53_62: 10; /* */ | ||
1078 | unsigned long enable : 1; /* RW */ | ||
1079 | } s; | ||
1080 | }; | ||
1081 | |||
1082 | 1085 | ||
1083 | #endif /* _ASM_X86_UV_UV_MMRS_H */ | 1086 | #endif /* __ASM_UV_MMRS_X86_H__ */ |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 850657d1b0ed..3f838d537392 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <asm/mce.h> | 52 | #include <asm/mce.h> |
53 | #include <asm/kvm_para.h> | 53 | #include <asm/kvm_para.h> |
54 | #include <asm/tsc.h> | 54 | #include <asm/tsc.h> |
55 | #include <asm/atomic.h> | ||
56 | 55 | ||
57 | unsigned int num_processors; | 56 | unsigned int num_processors; |
58 | 57 | ||
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index ed4118de249e..194539aea175 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -379,14 +379,14 @@ struct redir_addr { | |||
379 | #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT | 379 | #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT |
380 | 380 | ||
381 | static __initdata struct redir_addr redir_addrs[] = { | 381 | static __initdata struct redir_addr redir_addrs[] = { |
382 | {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, | 382 | {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR}, |
383 | {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, | 383 | {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR}, |
384 | {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, | 384 | {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR}, |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) | 387 | static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) |
388 | { | 388 | { |
389 | union uvh_si_alias0_overlay_config_u alias; | 389 | union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias; |
390 | union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; | 390 | union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; |
391 | int i; | 391 | int i; |
392 | 392 | ||
@@ -660,7 +660,7 @@ void uv_nmi_init(void) | |||
660 | 660 | ||
661 | void __init uv_system_init(void) | 661 | void __init uv_system_init(void) |
662 | { | 662 | { |
663 | union uvh_si_addr_map_config_u m_n_config; | 663 | union uvh_rh_gam_config_mmr_u m_n_config; |
664 | union uvh_node_id_u node_id; | 664 | union uvh_node_id_u node_id; |
665 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; | 665 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; |
666 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; | 666 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; |
@@ -670,7 +670,7 @@ void __init uv_system_init(void) | |||
670 | 670 | ||
671 | map_low_mmrs(); | 671 | map_low_mmrs(); |
672 | 672 | ||
673 | m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); | 673 | m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); |
674 | m_val = m_n_config.s.m_skt; | 674 | m_val = m_n_config.s.m_skt; |
675 | n_val = m_n_config.s.n_skt; | 675 | n_val = m_n_config.s.n_skt; |
676 | mmr_base = | 676 | mmr_base = |
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 46d58448c3af..e421b8cd6944 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
@@ -280,11 +280,11 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) | |||
280 | struct amd_nb *nb; | 280 | struct amd_nb *nb; |
281 | int i; | 281 | int i; |
282 | 282 | ||
283 | nb = kmalloc(sizeof(struct amd_nb), GFP_KERNEL); | 283 | nb = kmalloc_node(sizeof(struct amd_nb), GFP_KERNEL | __GFP_ZERO, |
284 | cpu_to_node(cpu)); | ||
284 | if (!nb) | 285 | if (!nb) |
285 | return NULL; | 286 | return NULL; |
286 | 287 | ||
287 | memset(nb, 0, sizeof(*nb)); | ||
288 | nb->nb_id = nb_id; | 288 | nb->nb_id = nb_id; |
289 | 289 | ||
290 | /* | 290 | /* |
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index e1af7c055c7d..ce0cb4721c9a 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -212,7 +212,7 @@ static int install_equiv_cpu_table(const u8 *buf) | |||
212 | return 0; | 212 | return 0; |
213 | } | 213 | } |
214 | 214 | ||
215 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); | 215 | equiv_cpu_table = vmalloc(size); |
216 | if (!equiv_cpu_table) { | 216 | if (!equiv_cpu_table) { |
217 | pr_err("failed to allocate equivalent CPU table\n"); | 217 | pr_err("failed to allocate equivalent CPU table\n"); |
218 | return 0; | 218 | return 0; |
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index 71825806cd44..6da143c2a6b8 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c | |||
@@ -217,13 +217,13 @@ void __cpuinit fam10h_check_enable_mmcfg(void) | |||
217 | wrmsrl(address, val); | 217 | wrmsrl(address, val); |
218 | } | 218 | } |
219 | 219 | ||
220 | static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d) | 220 | static int __init set_check_enable_amd_mmconf(const struct dmi_system_id *d) |
221 | { | 221 | { |
222 | pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; | 222 | pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; |
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = { | 226 | static const struct dmi_system_id __initconst mmconf_dmi_table[] = { |
227 | { | 227 | { |
228 | .callback = set_check_enable_amd_mmconf, | 228 | .callback = set_check_enable_amd_mmconf, |
229 | .ident = "Sun Microsystems Machine", | 229 | .ident = "Sun Microsystems Machine", |
@@ -234,7 +234,8 @@ static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = { | |||
234 | {} | 234 | {} |
235 | }; | 235 | }; |
236 | 236 | ||
237 | void __cpuinit check_enable_amd_mmconf_dmi(void) | 237 | /* Called from a __cpuinit function, but only on the BSP. */ |
238 | void __ref check_enable_amd_mmconf_dmi(void) | ||
238 | { | 239 | { |
239 | dmi_check_system(mmconf_dmi_table); | 240 | dmi_check_system(mmconf_dmi_table); |
240 | } | 241 | } |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index bab3b9e6f66d..008b91eefa18 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -41,44 +41,6 @@ void pvclock_set_flags(u8 flags) | |||
41 | valid_flags = flags; | 41 | valid_flags = flags; |
42 | } | 42 | } |
43 | 43 | ||
44 | /* | ||
45 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, | ||
46 | * yielding a 64-bit result. | ||
47 | */ | ||
48 | static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) | ||
49 | { | ||
50 | u64 product; | ||
51 | #ifdef __i386__ | ||
52 | u32 tmp1, tmp2; | ||
53 | #endif | ||
54 | |||
55 | if (shift < 0) | ||
56 | delta >>= -shift; | ||
57 | else | ||
58 | delta <<= shift; | ||
59 | |||
60 | #ifdef __i386__ | ||
61 | __asm__ ( | ||
62 | "mul %5 ; " | ||
63 | "mov %4,%%eax ; " | ||
64 | "mov %%edx,%4 ; " | ||
65 | "mul %5 ; " | ||
66 | "xor %5,%5 ; " | ||
67 | "add %4,%%eax ; " | ||
68 | "adc %5,%%edx ; " | ||
69 | : "=A" (product), "=r" (tmp1), "=r" (tmp2) | ||
70 | : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); | ||
71 | #elif defined(__x86_64__) | ||
72 | __asm__ ( | ||
73 | "mul %%rdx ; shrd $32,%%rdx,%%rax" | ||
74 | : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); | ||
75 | #else | ||
76 | #error implement me! | ||
77 | #endif | ||
78 | |||
79 | return product; | ||
80 | } | ||
81 | |||
82 | static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow) | 44 | static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow) |
83 | { | 45 | { |
84 | u64 delta = native_read_tsc() - shadow->tsc_timestamp; | 46 | u64 delta = native_read_tsc() - shadow->tsc_timestamp; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 908ea5464a51..fb8b376bf28c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -720,7 +720,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) | |||
720 | } | 720 | } |
721 | } | 721 | } |
722 | 722 | ||
723 | static void set_spte_track_bits(u64 *sptep, u64 new_spte) | 723 | static int set_spte_track_bits(u64 *sptep, u64 new_spte) |
724 | { | 724 | { |
725 | pfn_t pfn; | 725 | pfn_t pfn; |
726 | u64 old_spte = *sptep; | 726 | u64 old_spte = *sptep; |
@@ -731,19 +731,20 @@ static void set_spte_track_bits(u64 *sptep, u64 new_spte) | |||
731 | old_spte = __xchg_spte(sptep, new_spte); | 731 | old_spte = __xchg_spte(sptep, new_spte); |
732 | 732 | ||
733 | if (!is_rmap_spte(old_spte)) | 733 | if (!is_rmap_spte(old_spte)) |
734 | return; | 734 | return 0; |
735 | 735 | ||
736 | pfn = spte_to_pfn(old_spte); | 736 | pfn = spte_to_pfn(old_spte); |
737 | if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) | 737 | if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) |
738 | kvm_set_pfn_accessed(pfn); | 738 | kvm_set_pfn_accessed(pfn); |
739 | if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) | 739 | if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) |
740 | kvm_set_pfn_dirty(pfn); | 740 | kvm_set_pfn_dirty(pfn); |
741 | return 1; | ||
741 | } | 742 | } |
742 | 743 | ||
743 | static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte) | 744 | static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte) |
744 | { | 745 | { |
745 | set_spte_track_bits(sptep, new_spte); | 746 | if (set_spte_track_bits(sptep, new_spte)) |
746 | rmap_remove(kvm, sptep); | 747 | rmap_remove(kvm, sptep); |
747 | } | 748 | } |
748 | 749 | ||
749 | static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) | 750 | static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2288ad829b32..cdac9e592aa5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2560,6 +2560,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
2560 | !kvm_exception_is_soft(vcpu->arch.exception.nr); | 2560 | !kvm_exception_is_soft(vcpu->arch.exception.nr); |
2561 | events->exception.nr = vcpu->arch.exception.nr; | 2561 | events->exception.nr = vcpu->arch.exception.nr; |
2562 | events->exception.has_error_code = vcpu->arch.exception.has_error_code; | 2562 | events->exception.has_error_code = vcpu->arch.exception.has_error_code; |
2563 | events->exception.pad = 0; | ||
2563 | events->exception.error_code = vcpu->arch.exception.error_code; | 2564 | events->exception.error_code = vcpu->arch.exception.error_code; |
2564 | 2565 | ||
2565 | events->interrupt.injected = | 2566 | events->interrupt.injected = |
@@ -2573,12 +2574,14 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
2573 | events->nmi.injected = vcpu->arch.nmi_injected; | 2574 | events->nmi.injected = vcpu->arch.nmi_injected; |
2574 | events->nmi.pending = vcpu->arch.nmi_pending; | 2575 | events->nmi.pending = vcpu->arch.nmi_pending; |
2575 | events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu); | 2576 | events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu); |
2577 | events->nmi.pad = 0; | ||
2576 | 2578 | ||
2577 | events->sipi_vector = vcpu->arch.sipi_vector; | 2579 | events->sipi_vector = vcpu->arch.sipi_vector; |
2578 | 2580 | ||
2579 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING | 2581 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING |
2580 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR | 2582 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR |
2581 | | KVM_VCPUEVENT_VALID_SHADOW); | 2583 | | KVM_VCPUEVENT_VALID_SHADOW); |
2584 | memset(&events->reserved, 0, sizeof(events->reserved)); | ||
2582 | } | 2585 | } |
2583 | 2586 | ||
2584 | static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | 2587 | static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, |
@@ -2623,6 +2626,7 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, | |||
2623 | dbgregs->dr6 = vcpu->arch.dr6; | 2626 | dbgregs->dr6 = vcpu->arch.dr6; |
2624 | dbgregs->dr7 = vcpu->arch.dr7; | 2627 | dbgregs->dr7 = vcpu->arch.dr7; |
2625 | dbgregs->flags = 0; | 2628 | dbgregs->flags = 0; |
2629 | memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved)); | ||
2626 | } | 2630 | } |
2627 | 2631 | ||
2628 | static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, | 2632 | static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, |
@@ -3106,6 +3110,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) | |||
3106 | sizeof(ps->channels)); | 3110 | sizeof(ps->channels)); |
3107 | ps->flags = kvm->arch.vpit->pit_state.flags; | 3111 | ps->flags = kvm->arch.vpit->pit_state.flags; |
3108 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | 3112 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); |
3113 | memset(&ps->reserved, 0, sizeof(ps->reserved)); | ||
3109 | return r; | 3114 | return r; |
3110 | } | 3115 | } |
3111 | 3116 | ||
@@ -3169,10 +3174,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
3169 | struct kvm_memslots *slots, *old_slots; | 3174 | struct kvm_memslots *slots, *old_slots; |
3170 | unsigned long *dirty_bitmap; | 3175 | unsigned long *dirty_bitmap; |
3171 | 3176 | ||
3172 | spin_lock(&kvm->mmu_lock); | ||
3173 | kvm_mmu_slot_remove_write_access(kvm, log->slot); | ||
3174 | spin_unlock(&kvm->mmu_lock); | ||
3175 | |||
3176 | r = -ENOMEM; | 3177 | r = -ENOMEM; |
3177 | dirty_bitmap = vmalloc(n); | 3178 | dirty_bitmap = vmalloc(n); |
3178 | if (!dirty_bitmap) | 3179 | if (!dirty_bitmap) |
@@ -3194,6 +3195,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
3194 | dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap; | 3195 | dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap; |
3195 | kfree(old_slots); | 3196 | kfree(old_slots); |
3196 | 3197 | ||
3198 | spin_lock(&kvm->mmu_lock); | ||
3199 | kvm_mmu_slot_remove_write_access(kvm, log->slot); | ||
3200 | spin_unlock(&kvm->mmu_lock); | ||
3201 | |||
3197 | r = -EFAULT; | 3202 | r = -EFAULT; |
3198 | if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { | 3203 | if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { |
3199 | vfree(dirty_bitmap); | 3204 | vfree(dirty_bitmap); |
@@ -3486,6 +3491,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
3486 | user_ns.clock = kvm->arch.kvmclock_offset + now_ns; | 3491 | user_ns.clock = kvm->arch.kvmclock_offset + now_ns; |
3487 | local_irq_enable(); | 3492 | local_irq_enable(); |
3488 | user_ns.flags = 0; | 3493 | user_ns.flags = 0; |
3494 | memset(&user_ns.pad, 0, sizeof(user_ns.pad)); | ||
3489 | 3495 | ||
3490 | r = -EFAULT; | 3496 | r = -EFAULT; |
3491 | if (copy_to_user(argp, &user_ns, sizeof(user_ns))) | 3497 | if (copy_to_user(argp, &user_ns, sizeof(user_ns))) |
@@ -3972,8 +3978,10 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) | |||
3972 | return X86EMUL_CONTINUE; | 3978 | return X86EMUL_CONTINUE; |
3973 | 3979 | ||
3974 | if (kvm_x86_ops->has_wbinvd_exit()) { | 3980 | if (kvm_x86_ops->has_wbinvd_exit()) { |
3981 | preempt_disable(); | ||
3975 | smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, | 3982 | smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, |
3976 | wbinvd_ipi, NULL, 1); | 3983 | wbinvd_ipi, NULL, 1); |
3984 | preempt_enable(); | ||
3977 | cpumask_clear(vcpu->arch.wbinvd_dirty_mask); | 3985 | cpumask_clear(vcpu->arch.wbinvd_dirty_mask); |
3978 | } | 3986 | } |
3979 | wbinvd(); | 3987 | wbinvd(); |
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 49358481c733..12cdbb17ad18 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
@@ -251,7 +251,7 @@ static void __cpuinit calculate_tlb_offset(void) | |||
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | static int tlb_cpuhp_notify(struct notifier_block *n, | 254 | static int __cpuinit tlb_cpuhp_notify(struct notifier_block *n, |
255 | unsigned long action, void *hcpu) | 255 | unsigned long action, void *hcpu) |
256 | { | 256 | { |
257 | switch (action & 0xf) { | 257 | switch (action & 0xf) { |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 20ea20a39e2a..a318194002b5 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
@@ -1343,8 +1343,8 @@ uv_activation_descriptor_init(int node, int pnode) | |||
1343 | * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) | 1343 | * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) |
1344 | * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub | 1344 | * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub |
1345 | */ | 1345 | */ |
1346 | bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)* | 1346 | bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE |
1347 | UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); | 1347 | * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); |
1348 | BUG_ON(!bau_desc); | 1348 | BUG_ON(!bau_desc); |
1349 | 1349 | ||
1350 | pa = uv_gpa(bau_desc); /* need the real nasid*/ | 1350 | pa = uv_gpa(bau_desc); /* need the real nasid*/ |
@@ -1402,9 +1402,9 @@ uv_payload_queue_init(int node, int pnode) | |||
1402 | struct bau_payload_queue_entry *pqp_malloc; | 1402 | struct bau_payload_queue_entry *pqp_malloc; |
1403 | struct bau_control *bcp; | 1403 | struct bau_control *bcp; |
1404 | 1404 | ||
1405 | pqp = (struct bau_payload_queue_entry *) kmalloc_node( | 1405 | pqp = kmalloc_node((DEST_Q_SIZE + 1) |
1406 | (DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry), | 1406 | * sizeof(struct bau_payload_queue_entry), |
1407 | GFP_KERNEL, node); | 1407 | GFP_KERNEL, node); |
1408 | BUG_ON(!pqp); | 1408 | BUG_ON(!pqp); |
1409 | pqp_malloc = pqp; | 1409 | pqp_malloc = pqp; |
1410 | 1410 | ||
@@ -1520,8 +1520,7 @@ static void __init uv_init_per_cpu(int nuvhubs) | |||
1520 | 1520 | ||
1521 | timeout_us = calculate_destination_timeout(); | 1521 | timeout_us = calculate_destination_timeout(); |
1522 | 1522 | ||
1523 | uvhub_descs = (struct uvhub_desc *) | 1523 | uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); |
1524 | kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); | ||
1525 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); | 1524 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); |
1526 | uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); | 1525 | uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); |
1527 | for_each_present_cpu(cpu) { | 1526 | for_each_present_cpu(cpu) { |
diff --git a/block/blk-core.c b/block/blk-core.c index f0834e2f5727..4ce953f1b390 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1194,13 +1194,6 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
1194 | int where = ELEVATOR_INSERT_SORT; | 1194 | int where = ELEVATOR_INSERT_SORT; |
1195 | int rw_flags; | 1195 | int rw_flags; |
1196 | 1196 | ||
1197 | /* REQ_HARDBARRIER is no more */ | ||
1198 | if (WARN_ONCE(bio->bi_rw & REQ_HARDBARRIER, | ||
1199 | "block: HARDBARRIER is deprecated, use FLUSH/FUA instead\n")) { | ||
1200 | bio_endio(bio, -EOPNOTSUPP); | ||
1201 | return 0; | ||
1202 | } | ||
1203 | |||
1204 | /* | 1197 | /* |
1205 | * low level driver can indicate that it wants pages above a | 1198 | * low level driver can indicate that it wants pages above a |
1206 | * certain limit bounced to low memory (ie for highmem, or even | 1199 | * certain limit bounced to low memory (ie for highmem, or even |
@@ -1351,7 +1344,7 @@ static void handle_bad_sector(struct bio *bio) | |||
1351 | bdevname(bio->bi_bdev, b), | 1344 | bdevname(bio->bi_bdev, b), |
1352 | bio->bi_rw, | 1345 | bio->bi_rw, |
1353 | (unsigned long long)bio->bi_sector + bio_sectors(bio), | 1346 | (unsigned long long)bio->bi_sector + bio_sectors(bio), |
1354 | (long long)(bio->bi_bdev->bd_inode->i_size >> 9)); | 1347 | (long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9)); |
1355 | 1348 | ||
1356 | set_bit(BIO_EOF, &bio->bi_flags); | 1349 | set_bit(BIO_EOF, &bio->bi_flags); |
1357 | } | 1350 | } |
@@ -1404,7 +1397,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors) | |||
1404 | return 0; | 1397 | return 0; |
1405 | 1398 | ||
1406 | /* Test device or partition size, when known. */ | 1399 | /* Test device or partition size, when known. */ |
1407 | maxsector = bio->bi_bdev->bd_inode->i_size >> 9; | 1400 | maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; |
1408 | if (maxsector) { | 1401 | if (maxsector) { |
1409 | sector_t sector = bio->bi_sector; | 1402 | sector_t sector = bio->bi_sector; |
1410 | 1403 | ||
diff --git a/block/blk-ioc.c b/block/blk-ioc.c index d22c4c55c406..3c7a339fe381 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c | |||
@@ -153,20 +153,6 @@ struct io_context *get_io_context(gfp_t gfp_flags, int node) | |||
153 | } | 153 | } |
154 | EXPORT_SYMBOL(get_io_context); | 154 | EXPORT_SYMBOL(get_io_context); |
155 | 155 | ||
156 | void copy_io_context(struct io_context **pdst, struct io_context **psrc) | ||
157 | { | ||
158 | struct io_context *src = *psrc; | ||
159 | struct io_context *dst = *pdst; | ||
160 | |||
161 | if (src) { | ||
162 | BUG_ON(atomic_long_read(&src->refcount) == 0); | ||
163 | atomic_long_inc(&src->refcount); | ||
164 | put_io_context(dst); | ||
165 | *pdst = src; | ||
166 | } | ||
167 | } | ||
168 | EXPORT_SYMBOL(copy_io_context); | ||
169 | |||
170 | static int __init blk_ioc_init(void) | 156 | static int __init blk_ioc_init(void) |
171 | { | 157 | { |
172 | iocontext_cachep = kmem_cache_create("blkdev_ioc", | 158 | iocontext_cachep = kmem_cache_create("blkdev_ioc", |
diff --git a/block/blk-map.c b/block/blk-map.c index d4a586d8691e..5d5dbe47c228 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
@@ -205,6 +205,8 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, | |||
205 | unaligned = 1; | 205 | unaligned = 1; |
206 | break; | 206 | break; |
207 | } | 207 | } |
208 | if (!iov[i].iov_len) | ||
209 | return -EINVAL; | ||
208 | } | 210 | } |
209 | 211 | ||
210 | if (unaligned || (q->dma_pad_mask & len) || map_data) | 212 | if (unaligned || (q->dma_pad_mask & len) || map_data) |
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 119f07b74dc0..58c6ee5b010c 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -744,13 +744,13 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
744 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; | 744 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; |
745 | return 0; | 745 | return 0; |
746 | case BLKGETSIZE: | 746 | case BLKGETSIZE: |
747 | size = bdev->bd_inode->i_size; | 747 | size = i_size_read(bdev->bd_inode); |
748 | if ((size >> 9) > ~0UL) | 748 | if ((size >> 9) > ~0UL) |
749 | return -EFBIG; | 749 | return -EFBIG; |
750 | return compat_put_ulong(arg, size >> 9); | 750 | return compat_put_ulong(arg, size >> 9); |
751 | 751 | ||
752 | case BLKGETSIZE64_32: | 752 | case BLKGETSIZE64_32: |
753 | return compat_put_u64(arg, bdev->bd_inode->i_size); | 753 | return compat_put_u64(arg, i_size_read(bdev->bd_inode)); |
754 | 754 | ||
755 | case BLKTRACESETUP32: | 755 | case BLKTRACESETUP32: |
756 | case BLKTRACESTART: /* compatible */ | 756 | case BLKTRACESTART: /* compatible */ |
diff --git a/block/elevator.c b/block/elevator.c index 282e8308f7e2..2569512830d3 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -429,7 +429,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) | |||
429 | q->nr_sorted--; | 429 | q->nr_sorted--; |
430 | 430 | ||
431 | boundary = q->end_sector; | 431 | boundary = q->end_sector; |
432 | stop_flags = REQ_SOFTBARRIER | REQ_HARDBARRIER | REQ_STARTED; | 432 | stop_flags = REQ_SOFTBARRIER | REQ_STARTED; |
433 | list_for_each_prev(entry, &q->queue_head) { | 433 | list_for_each_prev(entry, &q->queue_head) { |
434 | struct request *pos = list_entry_rq(entry); | 434 | struct request *pos = list_entry_rq(entry); |
435 | 435 | ||
@@ -691,7 +691,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) | |||
691 | void __elv_add_request(struct request_queue *q, struct request *rq, int where, | 691 | void __elv_add_request(struct request_queue *q, struct request *rq, int where, |
692 | int plug) | 692 | int plug) |
693 | { | 693 | { |
694 | if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { | 694 | if (rq->cmd_flags & REQ_SOFTBARRIER) { |
695 | /* barriers are scheduling boundary, update end_sector */ | 695 | /* barriers are scheduling boundary, update end_sector */ |
696 | if (rq->cmd_type == REQ_TYPE_FS || | 696 | if (rq->cmd_type == REQ_TYPE_FS || |
697 | (rq->cmd_flags & REQ_DISCARD)) { | 697 | (rq->cmd_flags & REQ_DISCARD)) { |
diff --git a/block/ioctl.c b/block/ioctl.c index d724ceb1d465..3d866d0037f2 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -125,7 +125,7 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, | |||
125 | start >>= 9; | 125 | start >>= 9; |
126 | len >>= 9; | 126 | len >>= 9; |
127 | 127 | ||
128 | if (start + len > (bdev->bd_inode->i_size >> 9)) | 128 | if (start + len > (i_size_read(bdev->bd_inode) >> 9)) |
129 | return -EINVAL; | 129 | return -EINVAL; |
130 | if (secure) | 130 | if (secure) |
131 | flags |= BLKDEV_DISCARD_SECURE; | 131 | flags |= BLKDEV_DISCARD_SECURE; |
@@ -242,6 +242,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
242 | * We need to set the startsect first, the driver may | 242 | * We need to set the startsect first, the driver may |
243 | * want to override it. | 243 | * want to override it. |
244 | */ | 244 | */ |
245 | memset(&geo, 0, sizeof(geo)); | ||
245 | geo.start = get_start_sect(bdev); | 246 | geo.start = get_start_sect(bdev); |
246 | ret = disk->fops->getgeo(bdev, &geo); | 247 | ret = disk->fops->getgeo(bdev, &geo); |
247 | if (ret) | 248 | if (ret) |
@@ -307,12 +308,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
307 | ret = blkdev_reread_part(bdev); | 308 | ret = blkdev_reread_part(bdev); |
308 | break; | 309 | break; |
309 | case BLKGETSIZE: | 310 | case BLKGETSIZE: |
310 | size = bdev->bd_inode->i_size; | 311 | size = i_size_read(bdev->bd_inode); |
311 | if ((size >> 9) > ~0UL) | 312 | if ((size >> 9) > ~0UL) |
312 | return -EFBIG; | 313 | return -EFBIG; |
313 | return put_ulong(arg, size >> 9); | 314 | return put_ulong(arg, size >> 9); |
314 | case BLKGETSIZE64: | 315 | case BLKGETSIZE64: |
315 | return put_u64(arg, bdev->bd_inode->i_size); | 316 | return put_u64(arg, i_size_read(bdev->bd_inode)); |
316 | case BLKTRACESTART: | 317 | case BLKTRACESTART: |
317 | case BLKTRACESTOP: | 318 | case BLKTRACESTOP: |
318 | case BLKTRACESETUP: | 319 | case BLKTRACESETUP: |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index a8b5a10eb5b0..4f4230b79bb6 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -321,33 +321,47 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
321 | if (hdr->iovec_count) { | 321 | if (hdr->iovec_count) { |
322 | const int size = sizeof(struct sg_iovec) * hdr->iovec_count; | 322 | const int size = sizeof(struct sg_iovec) * hdr->iovec_count; |
323 | size_t iov_data_len; | 323 | size_t iov_data_len; |
324 | struct sg_iovec *iov; | 324 | struct sg_iovec *sg_iov; |
325 | struct iovec *iov; | ||
326 | int i; | ||
325 | 327 | ||
326 | iov = kmalloc(size, GFP_KERNEL); | 328 | sg_iov = kmalloc(size, GFP_KERNEL); |
327 | if (!iov) { | 329 | if (!sg_iov) { |
328 | ret = -ENOMEM; | 330 | ret = -ENOMEM; |
329 | goto out; | 331 | goto out; |
330 | } | 332 | } |
331 | 333 | ||
332 | if (copy_from_user(iov, hdr->dxferp, size)) { | 334 | if (copy_from_user(sg_iov, hdr->dxferp, size)) { |
333 | kfree(iov); | 335 | kfree(sg_iov); |
334 | ret = -EFAULT; | 336 | ret = -EFAULT; |
335 | goto out; | 337 | goto out; |
336 | } | 338 | } |
337 | 339 | ||
340 | /* | ||
341 | * Sum up the vecs, making sure they don't overflow | ||
342 | */ | ||
343 | iov = (struct iovec *) sg_iov; | ||
344 | iov_data_len = 0; | ||
345 | for (i = 0; i < hdr->iovec_count; i++) { | ||
346 | if (iov_data_len + iov[i].iov_len < iov_data_len) { | ||
347 | kfree(sg_iov); | ||
348 | ret = -EINVAL; | ||
349 | goto out; | ||
350 | } | ||
351 | iov_data_len += iov[i].iov_len; | ||
352 | } | ||
353 | |||
338 | /* SG_IO howto says that the shorter of the two wins */ | 354 | /* SG_IO howto says that the shorter of the two wins */ |
339 | iov_data_len = iov_length((struct iovec *)iov, | ||
340 | hdr->iovec_count); | ||
341 | if (hdr->dxfer_len < iov_data_len) { | 355 | if (hdr->dxfer_len < iov_data_len) { |
342 | hdr->iovec_count = iov_shorten((struct iovec *)iov, | 356 | hdr->iovec_count = iov_shorten(iov, |
343 | hdr->iovec_count, | 357 | hdr->iovec_count, |
344 | hdr->dxfer_len); | 358 | hdr->dxfer_len); |
345 | iov_data_len = hdr->dxfer_len; | 359 | iov_data_len = hdr->dxfer_len; |
346 | } | 360 | } |
347 | 361 | ||
348 | ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, | 362 | ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count, |
349 | iov_data_len, GFP_KERNEL); | 363 | iov_data_len, GFP_KERNEL); |
350 | kfree(iov); | 364 | kfree(sg_iov); |
351 | } else if (hdr->dxfer_len) | 365 | } else if (hdr->dxfer_len) |
352 | ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, | 366 | ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, |
353 | GFP_KERNEL); | 367 | GFP_KERNEL); |
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index de3078215fe6..75586f1f86e7 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c | |||
@@ -504,7 +504,6 @@ err: | |||
504 | 504 | ||
505 | static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt) | 505 | static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt) |
506 | { | 506 | { |
507 | kobject_put(&pcrypt->pinst->kobj); | ||
508 | free_cpumask_var(pcrypt->cb_cpumask->mask); | 507 | free_cpumask_var(pcrypt->cb_cpumask->mask); |
509 | kfree(pcrypt->cb_cpumask); | 508 | kfree(pcrypt->cb_cpumask); |
510 | 509 | ||
diff --git a/drivers/Makefile b/drivers/Makefile index 14cf9077bb2b..f3ebb30f1b7f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -26,6 +26,7 @@ obj-$(CONFIG_REGULATOR) += regulator/ | |||
26 | 26 | ||
27 | # char/ comes before serial/ etc so that the VT console is the boot-time | 27 | # char/ comes before serial/ etc so that the VT console is the boot-time |
28 | # default. | 28 | # default. |
29 | obj-y += tty/ | ||
29 | obj-y += char/ | 30 | obj-y += char/ |
30 | 31 | ||
31 | # gpu/ comes after char for AGP vs DRM startup | 32 | # gpu/ comes after char for AGP vs DRM startup |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 541e18879965..528f6318ded1 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -180,9 +180,6 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) | |||
180 | BUG(); | 180 | BUG(); |
181 | bio_endio(bio, -ENXIO); | 181 | bio_endio(bio, -ENXIO); |
182 | return 0; | 182 | return 0; |
183 | } else if (bio->bi_rw & REQ_HARDBARRIER) { | ||
184 | bio_endio(bio, -EOPNOTSUPP); | ||
185 | return 0; | ||
186 | } else if (bio->bi_io_vec == NULL) { | 183 | } else if (bio->bi_io_vec == NULL) { |
187 | printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); | 184 | printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); |
188 | BUG(); | 185 | BUG(); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 2cc4dda46279..a67d0a611a8a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -113,6 +113,8 @@ static struct board_type products[] = { | |||
113 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, | 113 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, |
114 | {0x40910E11, "Smart Array 6i", &SA5_access}, | 114 | {0x40910E11, "Smart Array 6i", &SA5_access}, |
115 | {0x3225103C, "Smart Array P600", &SA5_access}, | 115 | {0x3225103C, "Smart Array P600", &SA5_access}, |
116 | {0x3223103C, "Smart Array P800", &SA5_access}, | ||
117 | {0x3234103C, "Smart Array P400", &SA5_access}, | ||
116 | {0x3235103C, "Smart Array P400i", &SA5_access}, | 118 | {0x3235103C, "Smart Array P400i", &SA5_access}, |
117 | {0x3211103C, "Smart Array E200i", &SA5_access}, | 119 | {0x3211103C, "Smart Array E200i", &SA5_access}, |
118 | {0x3212103C, "Smart Array E200", &SA5_access}, | 120 | {0x3212103C, "Smart Array E200", &SA5_access}, |
@@ -3753,7 +3755,7 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) | |||
3753 | for (i = 0; i < MAX_CONFIG_WAIT; i++) { | 3755 | for (i = 0; i < MAX_CONFIG_WAIT; i++) { |
3754 | if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) | 3756 | if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) |
3755 | break; | 3757 | break; |
3756 | msleep(10); | 3758 | usleep_range(10000, 20000); |
3757 | } | 3759 | } |
3758 | } | 3760 | } |
3759 | 3761 | ||
@@ -3937,10 +3939,9 @@ static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id) | |||
3937 | *board_id = ((subsystem_device_id << 16) & 0xffff0000) | | 3939 | *board_id = ((subsystem_device_id << 16) & 0xffff0000) | |
3938 | subsystem_vendor_id; | 3940 | subsystem_vendor_id; |
3939 | 3941 | ||
3940 | for (i = 0; i < ARRAY_SIZE(products); i++) { | 3942 | for (i = 0; i < ARRAY_SIZE(products); i++) |
3941 | if (*board_id == products[i].board_id) | 3943 | if (*board_id == products[i].board_id) |
3942 | return i; | 3944 | return i; |
3943 | } | ||
3944 | dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n", | 3945 | dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n", |
3945 | *board_id); | 3946 | *board_id); |
3946 | return -ENODEV; | 3947 | return -ENODEV; |
@@ -3971,18 +3972,31 @@ static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, | |||
3971 | return -ENODEV; | 3972 | return -ENODEV; |
3972 | } | 3973 | } |
3973 | 3974 | ||
3974 | static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) | 3975 | static int __devinit cciss_wait_for_board_state(struct pci_dev *pdev, |
3976 | void __iomem *vaddr, int wait_for_ready) | ||
3977 | #define BOARD_READY 1 | ||
3978 | #define BOARD_NOT_READY 0 | ||
3975 | { | 3979 | { |
3976 | int i; | 3980 | int i, iterations; |
3977 | u32 scratchpad; | 3981 | u32 scratchpad; |
3978 | 3982 | ||
3979 | for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) { | 3983 | if (wait_for_ready) |
3980 | scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); | 3984 | iterations = CCISS_BOARD_READY_ITERATIONS; |
3981 | if (scratchpad == CCISS_FIRMWARE_READY) | 3985 | else |
3982 | return 0; | 3986 | iterations = CCISS_BOARD_NOT_READY_ITERATIONS; |
3987 | |||
3988 | for (i = 0; i < iterations; i++) { | ||
3989 | scratchpad = readl(vaddr + SA5_SCRATCHPAD_OFFSET); | ||
3990 | if (wait_for_ready) { | ||
3991 | if (scratchpad == CCISS_FIRMWARE_READY) | ||
3992 | return 0; | ||
3993 | } else { | ||
3994 | if (scratchpad != CCISS_FIRMWARE_READY) | ||
3995 | return 0; | ||
3996 | } | ||
3983 | msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); | 3997 | msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); |
3984 | } | 3998 | } |
3985 | dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); | 3999 | dev_warn(&pdev->dev, "board not ready, timed out.\n"); |
3986 | return -ENODEV; | 4000 | return -ENODEV; |
3987 | } | 4001 | } |
3988 | 4002 | ||
@@ -4031,6 +4045,11 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) | |||
4031 | static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) | 4045 | static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) |
4032 | { | 4046 | { |
4033 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | 4047 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); |
4048 | |||
4049 | /* Limit commands in memory limited kdump scenario. */ | ||
4050 | if (reset_devices && h->max_commands > 32) | ||
4051 | h->max_commands = 32; | ||
4052 | |||
4034 | if (h->max_commands < 16) { | 4053 | if (h->max_commands < 16) { |
4035 | dev_warn(&h->pdev->dev, "Controller reports " | 4054 | dev_warn(&h->pdev->dev, "Controller reports " |
4036 | "max supported commands of %d, an obvious lie. " | 4055 | "max supported commands of %d, an obvious lie. " |
@@ -4148,7 +4167,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h) | |||
4148 | err = -ENOMEM; | 4167 | err = -ENOMEM; |
4149 | goto err_out_free_res; | 4168 | goto err_out_free_res; |
4150 | } | 4169 | } |
4151 | err = cciss_wait_for_board_ready(h); | 4170 | err = cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY); |
4152 | if (err) | 4171 | if (err) |
4153 | goto err_out_free_res; | 4172 | goto err_out_free_res; |
4154 | err = cciss_find_cfgtables(h); | 4173 | err = cciss_find_cfgtables(h); |
@@ -4313,36 +4332,6 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u | |||
4313 | #define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) | 4332 | #define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) |
4314 | #define cciss_noop(p) cciss_message(p, 3, 0) | 4333 | #define cciss_noop(p) cciss_message(p, 3, 0) |
4315 | 4334 | ||
4316 | static __devinit int cciss_reset_msi(struct pci_dev *pdev) | ||
4317 | { | ||
4318 | /* the #defines are stolen from drivers/pci/msi.h. */ | ||
4319 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | ||
4320 | #define PCI_MSIX_FLAGS_ENABLE (1 << 15) | ||
4321 | |||
4322 | int pos; | ||
4323 | u16 control = 0; | ||
4324 | |||
4325 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); | ||
4326 | if (pos) { | ||
4327 | pci_read_config_word(pdev, msi_control_reg(pos), &control); | ||
4328 | if (control & PCI_MSI_FLAGS_ENABLE) { | ||
4329 | dev_info(&pdev->dev, "resetting MSI\n"); | ||
4330 | pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); | ||
4331 | } | ||
4332 | } | ||
4333 | |||
4334 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
4335 | if (pos) { | ||
4336 | pci_read_config_word(pdev, msi_control_reg(pos), &control); | ||
4337 | if (control & PCI_MSIX_FLAGS_ENABLE) { | ||
4338 | dev_info(&pdev->dev, "resetting MSI-X\n"); | ||
4339 | pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); | ||
4340 | } | ||
4341 | } | ||
4342 | |||
4343 | return 0; | ||
4344 | } | ||
4345 | |||
4346 | static int cciss_controller_hard_reset(struct pci_dev *pdev, | 4335 | static int cciss_controller_hard_reset(struct pci_dev *pdev, |
4347 | void * __iomem vaddr, bool use_doorbell) | 4336 | void * __iomem vaddr, bool use_doorbell) |
4348 | { | 4337 | { |
@@ -4397,17 +4386,17 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev, | |||
4397 | * states or using the doorbell register. */ | 4386 | * states or using the doorbell register. */ |
4398 | static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | 4387 | static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) |
4399 | { | 4388 | { |
4400 | u16 saved_config_space[32]; | ||
4401 | u64 cfg_offset; | 4389 | u64 cfg_offset; |
4402 | u32 cfg_base_addr; | 4390 | u32 cfg_base_addr; |
4403 | u64 cfg_base_addr_index; | 4391 | u64 cfg_base_addr_index; |
4404 | void __iomem *vaddr; | 4392 | void __iomem *vaddr; |
4405 | unsigned long paddr; | 4393 | unsigned long paddr; |
4406 | u32 misc_fw_support, active_transport; | 4394 | u32 misc_fw_support, active_transport; |
4407 | int rc, i; | 4395 | int rc; |
4408 | CfgTable_struct __iomem *cfgtable; | 4396 | CfgTable_struct __iomem *cfgtable; |
4409 | bool use_doorbell; | 4397 | bool use_doorbell; |
4410 | u32 board_id; | 4398 | u32 board_id; |
4399 | u16 command_register; | ||
4411 | 4400 | ||
4412 | /* For controllers as old a the p600, this is very nearly | 4401 | /* For controllers as old a the p600, this is very nearly |
4413 | * the same thing as | 4402 | * the same thing as |
@@ -4417,14 +4406,6 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
4417 | * pci_set_power_state(pci_dev, PCI_D0); | 4406 | * pci_set_power_state(pci_dev, PCI_D0); |
4418 | * pci_restore_state(pci_dev); | 4407 | * pci_restore_state(pci_dev); |
4419 | * | 4408 | * |
4420 | * but we can't use these nice canned kernel routines on | ||
4421 | * kexec, because they also check the MSI/MSI-X state in PCI | ||
4422 | * configuration space and do the wrong thing when it is | ||
4423 | * set/cleared. Also, the pci_save/restore_state functions | ||
4424 | * violate the ordering requirements for restoring the | ||
4425 | * configuration space from the CCISS document (see the | ||
4426 | * comment below). So we roll our own .... | ||
4427 | * | ||
4428 | * For controllers newer than the P600, the pci power state | 4409 | * For controllers newer than the P600, the pci power state |
4429 | * method of resetting doesn't work so we have another way | 4410 | * method of resetting doesn't work so we have another way |
4430 | * using the doorbell register. | 4411 | * using the doorbell register. |
@@ -4443,8 +4424,13 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
4443 | return -ENODEV; | 4424 | return -ENODEV; |
4444 | } | 4425 | } |
4445 | 4426 | ||
4446 | for (i = 0; i < 32; i++) | 4427 | /* Save the PCI command register */ |
4447 | pci_read_config_word(pdev, 2*i, &saved_config_space[i]); | 4428 | pci_read_config_word(pdev, 4, &command_register); |
4429 | /* Turn the board off. This is so that later pci_restore_state() | ||
4430 | * won't turn the board on before the rest of config space is ready. | ||
4431 | */ | ||
4432 | pci_disable_device(pdev); | ||
4433 | pci_save_state(pdev); | ||
4448 | 4434 | ||
4449 | /* find the first memory BAR, so we can find the cfg table */ | 4435 | /* find the first memory BAR, so we can find the cfg table */ |
4450 | rc = cciss_pci_find_memory_BAR(pdev, &paddr); | 4436 | rc = cciss_pci_find_memory_BAR(pdev, &paddr); |
@@ -4479,26 +4465,32 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
4479 | rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); | 4465 | rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); |
4480 | if (rc) | 4466 | if (rc) |
4481 | goto unmap_cfgtable; | 4467 | goto unmap_cfgtable; |
4482 | 4468 | pci_restore_state(pdev); | |
4483 | /* Restore the PCI configuration space. The Open CISS | 4469 | rc = pci_enable_device(pdev); |
4484 | * Specification says, "Restore the PCI Configuration | 4470 | if (rc) { |
4485 | * Registers, offsets 00h through 60h. It is important to | 4471 | dev_warn(&pdev->dev, "failed to enable device.\n"); |
4486 | * restore the command register, 16-bits at offset 04h, | 4472 | goto unmap_cfgtable; |
4487 | * last. Do not restore the configuration status register, | ||
4488 | * 16-bits at offset 06h." Note that the offset is 2*i. | ||
4489 | */ | ||
4490 | for (i = 0; i < 32; i++) { | ||
4491 | if (i == 2 || i == 3) | ||
4492 | continue; | ||
4493 | pci_write_config_word(pdev, 2*i, saved_config_space[i]); | ||
4494 | } | 4473 | } |
4495 | wmb(); | 4474 | pci_write_config_word(pdev, 4, command_register); |
4496 | pci_write_config_word(pdev, 4, saved_config_space[2]); | ||
4497 | 4475 | ||
4498 | /* Some devices (notably the HP Smart Array 5i Controller) | 4476 | /* Some devices (notably the HP Smart Array 5i Controller) |
4499 | need a little pause here */ | 4477 | need a little pause here */ |
4500 | msleep(CCISS_POST_RESET_PAUSE_MSECS); | 4478 | msleep(CCISS_POST_RESET_PAUSE_MSECS); |
4501 | 4479 | ||
4480 | /* Wait for board to become not ready, then ready. */ | ||
4481 | dev_info(&pdev->dev, "Waiting for board to become ready.\n"); | ||
4482 | rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY); | ||
4483 | if (rc) /* Don't bail, might be E500, etc. which can't be reset */ | ||
4484 | dev_warn(&pdev->dev, | ||
4485 | "failed waiting for board to become not ready\n"); | ||
4486 | rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_READY); | ||
4487 | if (rc) { | ||
4488 | dev_warn(&pdev->dev, | ||
4489 | "failed waiting for board to become ready\n"); | ||
4490 | goto unmap_cfgtable; | ||
4491 | } | ||
4492 | dev_info(&pdev->dev, "board ready.\n"); | ||
4493 | |||
4502 | /* Controller should be in simple mode at this point. If it's not, | 4494 | /* Controller should be in simple mode at this point. If it's not, |
4503 | * It means we're on one of those controllers which doesn't support | 4495 | * It means we're on one of those controllers which doesn't support |
4504 | * the doorbell reset method and on which the PCI power management reset | 4496 | * the doorbell reset method and on which the PCI power management reset |
@@ -4539,8 +4531,6 @@ static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) | |||
4539 | return 0; /* just try to do the kdump anyhow. */ | 4531 | return 0; /* just try to do the kdump anyhow. */ |
4540 | if (rc) | 4532 | if (rc) |
4541 | return -ENODEV; | 4533 | return -ENODEV; |
4542 | if (cciss_reset_msi(pdev)) | ||
4543 | return -ENODEV; | ||
4544 | 4534 | ||
4545 | /* Now try to get the controller to respond to a no-op */ | 4535 | /* Now try to get the controller to respond to a no-op */ |
4546 | for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { | 4536 | for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { |
@@ -4936,7 +4926,8 @@ static void __exit cciss_cleanup(void) | |||
4936 | } | 4926 | } |
4937 | } | 4927 | } |
4938 | kthread_stop(cciss_scan_thread); | 4928 | kthread_stop(cciss_scan_thread); |
4939 | remove_proc_entry("driver/cciss", NULL); | 4929 | if (proc_cciss) |
4930 | remove_proc_entry("driver/cciss", NULL); | ||
4940 | bus_unregister(&cciss_bus_type); | 4931 | bus_unregister(&cciss_bus_type); |
4941 | } | 4932 | } |
4942 | 4933 | ||
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index ae340ffc8f81..4b8933d778f1 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -200,10 +200,14 @@ struct ctlr_info | |||
200 | * the above. | 200 | * the above. |
201 | */ | 201 | */ |
202 | #define CCISS_BOARD_READY_WAIT_SECS (120) | 202 | #define CCISS_BOARD_READY_WAIT_SECS (120) |
203 | #define CCISS_BOARD_NOT_READY_WAIT_SECS (10) | ||
203 | #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) | 204 | #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) |
204 | #define CCISS_BOARD_READY_ITERATIONS \ | 205 | #define CCISS_BOARD_READY_ITERATIONS \ |
205 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ | 206 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ |
206 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | 207 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) |
208 | #define CCISS_BOARD_NOT_READY_ITERATIONS \ | ||
209 | ((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \ | ||
210 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | ||
207 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) | 211 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) |
208 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) | 212 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) |
209 | #define CCISS_POST_RESET_NOOP_RETRIES (12) | 213 | #define CCISS_POST_RESET_NOOP_RETRIES (12) |
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index ac04ef97eac2..ba95cba192be 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -78,11 +78,10 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
78 | init_completion(&md_io.event); | 78 | init_completion(&md_io.event); |
79 | md_io.error = 0; | 79 | md_io.error = 0; |
80 | 80 | ||
81 | if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags)) | 81 | if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) |
82 | rw |= REQ_HARDBARRIER; | 82 | rw |= REQ_FUA; |
83 | rw |= REQ_UNPLUG | REQ_SYNC; | 83 | rw |= REQ_UNPLUG | REQ_SYNC; |
84 | 84 | ||
85 | retry: | ||
86 | bio = bio_alloc(GFP_NOIO, 1); | 85 | bio = bio_alloc(GFP_NOIO, 1); |
87 | bio->bi_bdev = bdev->md_bdev; | 86 | bio->bi_bdev = bdev->md_bdev; |
88 | bio->bi_sector = sector; | 87 | bio->bi_sector = sector; |
@@ -100,17 +99,6 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
100 | wait_for_completion(&md_io.event); | 99 | wait_for_completion(&md_io.event); |
101 | ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; | 100 | ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; |
102 | 101 | ||
103 | /* check for unsupported barrier op. | ||
104 | * would rather check on EOPNOTSUPP, but that is not reliable. | ||
105 | * don't try again for ANY return value != 0 */ | ||
106 | if (unlikely((bio->bi_rw & REQ_HARDBARRIER) && !ok)) { | ||
107 | /* Try again with no barrier */ | ||
108 | dev_warn(DEV, "Barriers not supported on meta data device - disabling\n"); | ||
109 | set_bit(MD_NO_BARRIER, &mdev->flags); | ||
110 | rw &= ~REQ_HARDBARRIER; | ||
111 | bio_put(bio); | ||
112 | goto retry; | ||
113 | } | ||
114 | out: | 102 | out: |
115 | bio_put(bio); | 103 | bio_put(bio); |
116 | return ok; | 104 | return ok; |
@@ -284,18 +272,32 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) | |||
284 | u32 xor_sum = 0; | 272 | u32 xor_sum = 0; |
285 | 273 | ||
286 | if (!get_ldev(mdev)) { | 274 | if (!get_ldev(mdev)) { |
287 | dev_err(DEV, "get_ldev() failed in w_al_write_transaction\n"); | 275 | dev_err(DEV, |
276 | "disk is %s, cannot start al transaction (-%d +%d)\n", | ||
277 | drbd_disk_str(mdev->state.disk), evicted, new_enr); | ||
288 | complete(&((struct update_al_work *)w)->event); | 278 | complete(&((struct update_al_work *)w)->event); |
289 | return 1; | 279 | return 1; |
290 | } | 280 | } |
291 | /* do we have to do a bitmap write, first? | 281 | /* do we have to do a bitmap write, first? |
292 | * TODO reduce maximum latency: | 282 | * TODO reduce maximum latency: |
293 | * submit both bios, then wait for both, | 283 | * submit both bios, then wait for both, |
294 | * instead of doing two synchronous sector writes. */ | 284 | * instead of doing two synchronous sector writes. |
285 | * For now, we must not write the transaction, | ||
286 | * if we cannot write out the bitmap of the evicted extent. */ | ||
295 | if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) | 287 | if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) |
296 | drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); | 288 | drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); |
297 | 289 | ||
298 | mutex_lock(&mdev->md_io_mutex); /* protects md_io_page, al_tr_cycle, ... */ | 290 | /* The bitmap write may have failed, causing a state change. */ |
291 | if (mdev->state.disk < D_INCONSISTENT) { | ||
292 | dev_err(DEV, | ||
293 | "disk is %s, cannot write al transaction (-%d +%d)\n", | ||
294 | drbd_disk_str(mdev->state.disk), evicted, new_enr); | ||
295 | complete(&((struct update_al_work *)w)->event); | ||
296 | put_ldev(mdev); | ||
297 | return 1; | ||
298 | } | ||
299 | |||
300 | mutex_lock(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ | ||
299 | buffer = (struct al_transaction *)page_address(mdev->md_io_page); | 301 | buffer = (struct al_transaction *)page_address(mdev->md_io_page); |
300 | 302 | ||
301 | buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); | 303 | buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); |
@@ -739,7 +741,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) | |||
739 | unsigned int enr; | 741 | unsigned int enr; |
740 | unsigned long add = 0; | 742 | unsigned long add = 0; |
741 | char ppb[10]; | 743 | char ppb[10]; |
742 | int i; | 744 | int i, tmp; |
743 | 745 | ||
744 | wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); | 746 | wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); |
745 | 747 | ||
@@ -747,7 +749,9 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) | |||
747 | enr = lc_element_by_index(mdev->act_log, i)->lc_number; | 749 | enr = lc_element_by_index(mdev->act_log, i)->lc_number; |
748 | if (enr == LC_FREE) | 750 | if (enr == LC_FREE) |
749 | continue; | 751 | continue; |
750 | add += drbd_bm_ALe_set_all(mdev, enr); | 752 | tmp = drbd_bm_ALe_set_all(mdev, enr); |
753 | dynamic_dev_dbg(DEV, "AL: set %d bits in extent %u\n", tmp, enr); | ||
754 | add += tmp; | ||
751 | } | 755 | } |
752 | 756 | ||
753 | lc_unlock(mdev->act_log); | 757 | lc_unlock(mdev->act_log); |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 9bdcf4393c0a..1ea1a34e78b2 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -114,11 +114,11 @@ struct drbd_conf; | |||
114 | #define D_ASSERT(exp) if (!(exp)) \ | 114 | #define D_ASSERT(exp) if (!(exp)) \ |
115 | dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) | 115 | dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) |
116 | 116 | ||
117 | #define ERR_IF(exp) if (({ \ | 117 | #define ERR_IF(exp) if (({ \ |
118 | int _b = (exp) != 0; \ | 118 | int _b = (exp) != 0; \ |
119 | if (_b) dev_err(DEV, "%s: (%s) in %s:%d\n", \ | 119 | if (_b) dev_err(DEV, "ASSERT FAILED: %s: (%s) in %s:%d\n", \ |
120 | __func__, #exp, __FILE__, __LINE__); \ | 120 | __func__, #exp, __FILE__, __LINE__); \ |
121 | _b; \ | 121 | _b; \ |
122 | })) | 122 | })) |
123 | 123 | ||
124 | /* Defines to control fault insertion */ | 124 | /* Defines to control fault insertion */ |
@@ -749,17 +749,12 @@ struct drbd_epoch { | |||
749 | 749 | ||
750 | /* drbd_epoch flag bits */ | 750 | /* drbd_epoch flag bits */ |
751 | enum { | 751 | enum { |
752 | DE_BARRIER_IN_NEXT_EPOCH_ISSUED, | ||
753 | DE_BARRIER_IN_NEXT_EPOCH_DONE, | ||
754 | DE_CONTAINS_A_BARRIER, | ||
755 | DE_HAVE_BARRIER_NUMBER, | 752 | DE_HAVE_BARRIER_NUMBER, |
756 | DE_IS_FINISHING, | ||
757 | }; | 753 | }; |
758 | 754 | ||
759 | enum epoch_event { | 755 | enum epoch_event { |
760 | EV_PUT, | 756 | EV_PUT, |
761 | EV_GOT_BARRIER_NR, | 757 | EV_GOT_BARRIER_NR, |
762 | EV_BARRIER_DONE, | ||
763 | EV_BECAME_LAST, | 758 | EV_BECAME_LAST, |
764 | EV_CLEANUP = 32, /* used as flag */ | 759 | EV_CLEANUP = 32, /* used as flag */ |
765 | }; | 760 | }; |
@@ -801,11 +796,6 @@ enum { | |||
801 | __EE_CALL_AL_COMPLETE_IO, | 796 | __EE_CALL_AL_COMPLETE_IO, |
802 | __EE_MAY_SET_IN_SYNC, | 797 | __EE_MAY_SET_IN_SYNC, |
803 | 798 | ||
804 | /* This epoch entry closes an epoch using a barrier. | ||
805 | * On sucessful completion, the epoch is released, | ||
806 | * and the P_BARRIER_ACK send. */ | ||
807 | __EE_IS_BARRIER, | ||
808 | |||
809 | /* In case a barrier failed, | 799 | /* In case a barrier failed, |
810 | * we need to resubmit without the barrier flag. */ | 800 | * we need to resubmit without the barrier flag. */ |
811 | __EE_RESUBMITTED, | 801 | __EE_RESUBMITTED, |
@@ -820,7 +810,6 @@ enum { | |||
820 | }; | 810 | }; |
821 | #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) | 811 | #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) |
822 | #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) | 812 | #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) |
823 | #define EE_IS_BARRIER (1<<__EE_IS_BARRIER) | ||
824 | #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) | 813 | #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) |
825 | #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) | 814 | #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) |
826 | #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) | 815 | #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) |
@@ -843,16 +832,15 @@ enum { | |||
843 | * Gets cleared when the state.conn | 832 | * Gets cleared when the state.conn |
844 | * goes into C_CONNECTED state. */ | 833 | * goes into C_CONNECTED state. */ |
845 | WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ | 834 | WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ |
846 | NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ | ||
847 | CONSIDER_RESYNC, | 835 | CONSIDER_RESYNC, |
848 | 836 | ||
849 | MD_NO_BARRIER, /* meta data device does not support barriers, | 837 | MD_NO_FUA, /* Users wants us to not use FUA/FLUSH on meta data dev */ |
850 | so don't even try */ | ||
851 | SUSPEND_IO, /* suspend application io */ | 838 | SUSPEND_IO, /* suspend application io */ |
852 | BITMAP_IO, /* suspend application io; | 839 | BITMAP_IO, /* suspend application io; |
853 | once no more io in flight, start bitmap io */ | 840 | once no more io in flight, start bitmap io */ |
854 | BITMAP_IO_QUEUED, /* Started bitmap IO */ | 841 | BITMAP_IO_QUEUED, /* Started bitmap IO */ |
855 | GO_DISKLESS, /* Disk failed, local_cnt reached zero, we are going diskless */ | 842 | GO_DISKLESS, /* Disk is being detached, on io-error or admin request. */ |
843 | WAS_IO_ERROR, /* Local disk failed returned IO error */ | ||
856 | RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ | 844 | RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ |
857 | NET_CONGESTED, /* The data socket is congested */ | 845 | NET_CONGESTED, /* The data socket is congested */ |
858 | 846 | ||
@@ -947,7 +935,6 @@ enum write_ordering_e { | |||
947 | WO_none, | 935 | WO_none, |
948 | WO_drain_io, | 936 | WO_drain_io, |
949 | WO_bdev_flush, | 937 | WO_bdev_flush, |
950 | WO_bio_barrier | ||
951 | }; | 938 | }; |
952 | 939 | ||
953 | struct fifo_buffer { | 940 | struct fifo_buffer { |
@@ -1281,6 +1268,7 @@ extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); | |||
1281 | extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); | 1268 | extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); |
1282 | extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); | 1269 | extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); |
1283 | extern void drbd_go_diskless(struct drbd_conf *mdev); | 1270 | extern void drbd_go_diskless(struct drbd_conf *mdev); |
1271 | extern void drbd_ldev_destroy(struct drbd_conf *mdev); | ||
1284 | 1272 | ||
1285 | 1273 | ||
1286 | /* Meta data layout | 1274 | /* Meta data layout |
@@ -1798,17 +1786,17 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, | |||
1798 | case EP_PASS_ON: | 1786 | case EP_PASS_ON: |
1799 | if (!forcedetach) { | 1787 | if (!forcedetach) { |
1800 | if (__ratelimit(&drbd_ratelimit_state)) | 1788 | if (__ratelimit(&drbd_ratelimit_state)) |
1801 | dev_err(DEV, "Local IO failed in %s." | 1789 | dev_err(DEV, "Local IO failed in %s.\n", where); |
1802 | "Passing error on...\n", where); | ||
1803 | break; | 1790 | break; |
1804 | } | 1791 | } |
1805 | /* NOTE fall through to detach case if forcedetach set */ | 1792 | /* NOTE fall through to detach case if forcedetach set */ |
1806 | case EP_DETACH: | 1793 | case EP_DETACH: |
1807 | case EP_CALL_HELPER: | 1794 | case EP_CALL_HELPER: |
1795 | set_bit(WAS_IO_ERROR, &mdev->flags); | ||
1808 | if (mdev->state.disk > D_FAILED) { | 1796 | if (mdev->state.disk > D_FAILED) { |
1809 | _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL); | 1797 | _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL); |
1810 | dev_err(DEV, "Local IO failed in %s." | 1798 | dev_err(DEV, |
1811 | "Detaching...\n", where); | 1799 | "Local IO failed in %s. Detaching...\n", where); |
1812 | } | 1800 | } |
1813 | break; | 1801 | break; |
1814 | } | 1802 | } |
@@ -1874,7 +1862,7 @@ static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) | |||
1874 | static inline sector_t drbd_get_capacity(struct block_device *bdev) | 1862 | static inline sector_t drbd_get_capacity(struct block_device *bdev) |
1875 | { | 1863 | { |
1876 | /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ | 1864 | /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ |
1877 | return bdev ? bdev->bd_inode->i_size >> 9 : 0; | 1865 | return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0; |
1878 | } | 1866 | } |
1879 | 1867 | ||
1880 | /** | 1868 | /** |
@@ -2127,7 +2115,11 @@ static inline void put_ldev(struct drbd_conf *mdev) | |||
2127 | __release(local); | 2115 | __release(local); |
2128 | D_ASSERT(i >= 0); | 2116 | D_ASSERT(i >= 0); |
2129 | if (i == 0) { | 2117 | if (i == 0) { |
2118 | if (mdev->state.disk == D_DISKLESS) | ||
2119 | /* even internal references gone, safe to destroy */ | ||
2120 | drbd_ldev_destroy(mdev); | ||
2130 | if (mdev->state.disk == D_FAILED) | 2121 | if (mdev->state.disk == D_FAILED) |
2122 | /* all application IO references gone. */ | ||
2131 | drbd_go_diskless(mdev); | 2123 | drbd_go_diskless(mdev); |
2132 | wake_up(&mdev->misc_wait); | 2124 | wake_up(&mdev->misc_wait); |
2133 | } | 2125 | } |
@@ -2138,6 +2130,10 @@ static inline int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_stat | |||
2138 | { | 2130 | { |
2139 | int io_allowed; | 2131 | int io_allowed; |
2140 | 2132 | ||
2133 | /* never get a reference while D_DISKLESS */ | ||
2134 | if (mdev->state.disk == D_DISKLESS) | ||
2135 | return 0; | ||
2136 | |||
2141 | atomic_inc(&mdev->local_cnt); | 2137 | atomic_inc(&mdev->local_cnt); |
2142 | io_allowed = (mdev->state.disk >= mins); | 2138 | io_allowed = (mdev->state.disk >= mins); |
2143 | if (!io_allowed) | 2139 | if (!io_allowed) |
@@ -2406,12 +2402,12 @@ static inline void drbd_md_flush(struct drbd_conf *mdev) | |||
2406 | { | 2402 | { |
2407 | int r; | 2403 | int r; |
2408 | 2404 | ||
2409 | if (test_bit(MD_NO_BARRIER, &mdev->flags)) | 2405 | if (test_bit(MD_NO_FUA, &mdev->flags)) |
2410 | return; | 2406 | return; |
2411 | 2407 | ||
2412 | r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL); | 2408 | r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL); |
2413 | if (r) { | 2409 | if (r) { |
2414 | set_bit(MD_NO_BARRIER, &mdev->flags); | 2410 | set_bit(MD_NO_FUA, &mdev->flags); |
2415 | dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r); | 2411 | dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r); |
2416 | } | 2412 | } |
2417 | } | 2413 | } |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 25c7a73c5062..6be5401d0e88 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -835,6 +835,15 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
835 | ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) | 835 | ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) |
836 | ns.conn = os.conn; | 836 | ns.conn = os.conn; |
837 | 837 | ||
838 | /* we cannot fail (again) if we already detached */ | ||
839 | if (ns.disk == D_FAILED && os.disk == D_DISKLESS) | ||
840 | ns.disk = D_DISKLESS; | ||
841 | |||
842 | /* if we are only D_ATTACHING yet, | ||
843 | * we can (and should) go directly to D_DISKLESS. */ | ||
844 | if (ns.disk == D_FAILED && os.disk == D_ATTACHING) | ||
845 | ns.disk = D_DISKLESS; | ||
846 | |||
838 | /* After C_DISCONNECTING only C_STANDALONE may follow */ | 847 | /* After C_DISCONNECTING only C_STANDALONE may follow */ |
839 | if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) | 848 | if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) |
840 | ns.conn = os.conn; | 849 | ns.conn = os.conn; |
@@ -1056,7 +1065,15 @@ int __drbd_set_state(struct drbd_conf *mdev, | |||
1056 | !test_and_set_bit(CONFIG_PENDING, &mdev->flags)) | 1065 | !test_and_set_bit(CONFIG_PENDING, &mdev->flags)) |
1057 | set_bit(DEVICE_DYING, &mdev->flags); | 1066 | set_bit(DEVICE_DYING, &mdev->flags); |
1058 | 1067 | ||
1059 | mdev->state.i = ns.i; | 1068 | /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference |
1069 | * on the ldev here, to be sure the transition -> D_DISKLESS resp. | ||
1070 | * drbd_ldev_destroy() won't happen before our corresponding | ||
1071 | * after_state_ch works run, where we put_ldev again. */ | ||
1072 | if ((os.disk != D_FAILED && ns.disk == D_FAILED) || | ||
1073 | (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) | ||
1074 | atomic_inc(&mdev->local_cnt); | ||
1075 | |||
1076 | mdev->state = ns; | ||
1060 | wake_up(&mdev->misc_wait); | 1077 | wake_up(&mdev->misc_wait); |
1061 | wake_up(&mdev->state_wait); | 1078 | wake_up(&mdev->state_wait); |
1062 | 1079 | ||
@@ -1268,7 +1285,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1268 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { | 1285 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { |
1269 | drbd_uuid_new_current(mdev); | 1286 | drbd_uuid_new_current(mdev); |
1270 | clear_bit(NEW_CUR_UUID, &mdev->flags); | 1287 | clear_bit(NEW_CUR_UUID, &mdev->flags); |
1271 | drbd_md_sync(mdev); | ||
1272 | } | 1288 | } |
1273 | spin_lock_irq(&mdev->req_lock); | 1289 | spin_lock_irq(&mdev->req_lock); |
1274 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); | 1290 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); |
@@ -1365,63 +1381,64 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1365 | os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) | 1381 | os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) |
1366 | drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); | 1382 | drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); |
1367 | 1383 | ||
1368 | /* first half of local IO error */ | 1384 | /* first half of local IO error, failure to attach, |
1369 | if (os.disk > D_FAILED && ns.disk == D_FAILED) { | 1385 | * or administrative detach */ |
1370 | enum drbd_io_error_p eh = EP_PASS_ON; | 1386 | if (os.disk != D_FAILED && ns.disk == D_FAILED) { |
1387 | enum drbd_io_error_p eh; | ||
1388 | int was_io_error; | ||
1389 | /* corresponding get_ldev was in __drbd_set_state, to serialize | ||
1390 | * our cleanup here with the transition to D_DISKLESS, | ||
1391 | * so it is safe to dreference ldev here. */ | ||
1392 | eh = mdev->ldev->dc.on_io_error; | ||
1393 | was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags); | ||
1394 | |||
1395 | /* current state still has to be D_FAILED, | ||
1396 | * there is only one way out: to D_DISKLESS, | ||
1397 | * and that may only happen after our put_ldev below. */ | ||
1398 | if (mdev->state.disk != D_FAILED) | ||
1399 | dev_err(DEV, | ||
1400 | "ASSERT FAILED: disk is %s during detach\n", | ||
1401 | drbd_disk_str(mdev->state.disk)); | ||
1371 | 1402 | ||
1372 | if (drbd_send_state(mdev)) | 1403 | if (drbd_send_state(mdev)) |
1373 | dev_warn(DEV, "Notified peer that my disk is broken.\n"); | 1404 | dev_warn(DEV, "Notified peer that I am detaching my disk\n"); |
1374 | else | 1405 | else |
1375 | dev_err(DEV, "Sending state for drbd_io_error() failed\n"); | 1406 | dev_err(DEV, "Sending state for detaching disk failed\n"); |
1376 | 1407 | ||
1377 | drbd_rs_cancel_all(mdev); | 1408 | drbd_rs_cancel_all(mdev); |
1378 | 1409 | ||
1379 | if (get_ldev_if_state(mdev, D_FAILED)) { | 1410 | /* In case we want to get something to stable storage still, |
1380 | eh = mdev->ldev->dc.on_io_error; | 1411 | * this may be the last chance. |
1381 | put_ldev(mdev); | 1412 | * Following put_ldev may transition to D_DISKLESS. */ |
1382 | } | 1413 | drbd_md_sync(mdev); |
1383 | if (eh == EP_CALL_HELPER) | 1414 | put_ldev(mdev); |
1415 | |||
1416 | if (was_io_error && eh == EP_CALL_HELPER) | ||
1384 | drbd_khelper(mdev, "local-io-error"); | 1417 | drbd_khelper(mdev, "local-io-error"); |
1385 | } | 1418 | } |
1386 | 1419 | ||
1420 | /* second half of local IO error, failure to attach, | ||
1421 | * or administrative detach, | ||
1422 | * after local_cnt references have reached zero again */ | ||
1423 | if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) { | ||
1424 | /* We must still be diskless, | ||
1425 | * re-attach has to be serialized with this! */ | ||
1426 | if (mdev->state.disk != D_DISKLESS) | ||
1427 | dev_err(DEV, | ||
1428 | "ASSERT FAILED: disk is %s while going diskless\n", | ||
1429 | drbd_disk_str(mdev->state.disk)); | ||
1387 | 1430 | ||
1388 | /* second half of local IO error handling, | 1431 | mdev->rs_total = 0; |
1389 | * after local_cnt references have reached zero: */ | 1432 | mdev->rs_failed = 0; |
1390 | if (os.disk == D_FAILED && ns.disk == D_DISKLESS) { | 1433 | atomic_set(&mdev->rs_pending_cnt, 0); |
1391 | mdev->rs_total = 0; | ||
1392 | mdev->rs_failed = 0; | ||
1393 | atomic_set(&mdev->rs_pending_cnt, 0); | ||
1394 | } | ||
1395 | |||
1396 | if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) { | ||
1397 | /* We must still be diskless, | ||
1398 | * re-attach has to be serialized with this! */ | ||
1399 | if (mdev->state.disk != D_DISKLESS) | ||
1400 | dev_err(DEV, | ||
1401 | "ASSERT FAILED: disk is %s while going diskless\n", | ||
1402 | drbd_disk_str(mdev->state.disk)); | ||
1403 | 1434 | ||
1404 | /* we cannot assert local_cnt == 0 here, as get_ldev_if_state | ||
1405 | * will inc/dec it frequently. Since we became D_DISKLESS, no | ||
1406 | * one has touched the protected members anymore, though, so we | ||
1407 | * are safe to free them here. */ | ||
1408 | if (drbd_send_state(mdev)) | 1435 | if (drbd_send_state(mdev)) |
1409 | dev_warn(DEV, "Notified peer that I detached my disk.\n"); | 1436 | dev_warn(DEV, "Notified peer that I'm now diskless.\n"); |
1410 | else | 1437 | else |
1411 | dev_err(DEV, "Sending state for detach failed\n"); | 1438 | dev_err(DEV, "Sending state for being diskless failed\n"); |
1412 | 1439 | /* corresponding get_ldev in __drbd_set_state | |
1413 | lc_destroy(mdev->resync); | 1440 | * this may finaly trigger drbd_ldev_destroy. */ |
1414 | mdev->resync = NULL; | 1441 | put_ldev(mdev); |
1415 | lc_destroy(mdev->act_log); | ||
1416 | mdev->act_log = NULL; | ||
1417 | __no_warn(local, | ||
1418 | drbd_free_bc(mdev->ldev); | ||
1419 | mdev->ldev = NULL;); | ||
1420 | |||
1421 | if (mdev->md_io_tmpp) { | ||
1422 | __free_page(mdev->md_io_tmpp); | ||
1423 | mdev->md_io_tmpp = NULL; | ||
1424 | } | ||
1425 | } | 1442 | } |
1426 | 1443 | ||
1427 | /* Disks got bigger while they were detached */ | 1444 | /* Disks got bigger while they were detached */ |
@@ -2772,11 +2789,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2772 | 2789 | ||
2773 | drbd_set_defaults(mdev); | 2790 | drbd_set_defaults(mdev); |
2774 | 2791 | ||
2775 | /* for now, we do NOT yet support it, | ||
2776 | * even though we start some framework | ||
2777 | * to eventually support barriers */ | ||
2778 | set_bit(NO_BARRIER_SUPP, &mdev->flags); | ||
2779 | |||
2780 | atomic_set(&mdev->ap_bio_cnt, 0); | 2792 | atomic_set(&mdev->ap_bio_cnt, 0); |
2781 | atomic_set(&mdev->ap_pending_cnt, 0); | 2793 | atomic_set(&mdev->ap_pending_cnt, 0); |
2782 | atomic_set(&mdev->rs_pending_cnt, 0); | 2794 | atomic_set(&mdev->rs_pending_cnt, 0); |
@@ -2842,7 +2854,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2842 | drbd_thread_init(mdev, &mdev->asender, drbd_asender); | 2854 | drbd_thread_init(mdev, &mdev->asender, drbd_asender); |
2843 | 2855 | ||
2844 | mdev->agreed_pro_version = PRO_VERSION_MAX; | 2856 | mdev->agreed_pro_version = PRO_VERSION_MAX; |
2845 | mdev->write_ordering = WO_bio_barrier; | 2857 | mdev->write_ordering = WO_bdev_flush; |
2846 | mdev->resync_wenr = LC_FREE; | 2858 | mdev->resync_wenr = LC_FREE; |
2847 | } | 2859 | } |
2848 | 2860 | ||
@@ -2899,7 +2911,6 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev) | |||
2899 | D_ASSERT(list_empty(&mdev->resync_work.list)); | 2911 | D_ASSERT(list_empty(&mdev->resync_work.list)); |
2900 | D_ASSERT(list_empty(&mdev->unplug_work.list)); | 2912 | D_ASSERT(list_empty(&mdev->unplug_work.list)); |
2901 | D_ASSERT(list_empty(&mdev->go_diskless.list)); | 2913 | D_ASSERT(list_empty(&mdev->go_diskless.list)); |
2902 | |||
2903 | } | 2914 | } |
2904 | 2915 | ||
2905 | 2916 | ||
@@ -3660,6 +3671,8 @@ void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) | |||
3660 | 3671 | ||
3661 | get_random_bytes(&val, sizeof(u64)); | 3672 | get_random_bytes(&val, sizeof(u64)); |
3662 | _drbd_uuid_set(mdev, UI_CURRENT, val); | 3673 | _drbd_uuid_set(mdev, UI_CURRENT, val); |
3674 | /* get it to stable storage _now_ */ | ||
3675 | drbd_md_sync(mdev); | ||
3663 | } | 3676 | } |
3664 | 3677 | ||
3665 | void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) | 3678 | void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) |
@@ -3756,19 +3769,31 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) | |||
3756 | return 1; | 3769 | return 1; |
3757 | } | 3770 | } |
3758 | 3771 | ||
3772 | void drbd_ldev_destroy(struct drbd_conf *mdev) | ||
3773 | { | ||
3774 | lc_destroy(mdev->resync); | ||
3775 | mdev->resync = NULL; | ||
3776 | lc_destroy(mdev->act_log); | ||
3777 | mdev->act_log = NULL; | ||
3778 | __no_warn(local, | ||
3779 | drbd_free_bc(mdev->ldev); | ||
3780 | mdev->ldev = NULL;); | ||
3781 | |||
3782 | if (mdev->md_io_tmpp) { | ||
3783 | __free_page(mdev->md_io_tmpp); | ||
3784 | mdev->md_io_tmpp = NULL; | ||
3785 | } | ||
3786 | clear_bit(GO_DISKLESS, &mdev->flags); | ||
3787 | } | ||
3788 | |||
3759 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) | 3789 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) |
3760 | { | 3790 | { |
3761 | D_ASSERT(mdev->state.disk == D_FAILED); | 3791 | D_ASSERT(mdev->state.disk == D_FAILED); |
3762 | /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will | 3792 | /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will |
3763 | * inc/dec it frequently. Once we are D_DISKLESS, no one will touch | 3793 | * inc/dec it frequently. Once we are D_DISKLESS, no one will touch |
3764 | * the protected members anymore, though, so in the after_state_ch work | 3794 | * the protected members anymore, though, so once put_ldev reaches zero |
3765 | * it will be safe to free them. */ | 3795 | * again, it will be safe to free them. */ |
3766 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); | 3796 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); |
3767 | /* We need to wait for return of references checked out while we still | ||
3768 | * have been D_FAILED, though (drbd_md_sync, bitmap io). */ | ||
3769 | wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); | ||
3770 | |||
3771 | clear_bit(GO_DISKLESS, &mdev->flags); | ||
3772 | return 1; | 3797 | return 1; |
3773 | } | 3798 | } |
3774 | 3799 | ||
@@ -3777,9 +3802,6 @@ void drbd_go_diskless(struct drbd_conf *mdev) | |||
3777 | D_ASSERT(mdev->state.disk == D_FAILED); | 3802 | D_ASSERT(mdev->state.disk == D_FAILED); |
3778 | if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) | 3803 | if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) |
3779 | drbd_queue_work(&mdev->data.work, &mdev->go_diskless); | 3804 | drbd_queue_work(&mdev->data.work, &mdev->go_diskless); |
3780 | /* don't drbd_queue_work_front, | ||
3781 | * we need to serialize with the after_state_ch work | ||
3782 | * of the -> D_FAILED transition. */ | ||
3783 | } | 3805 | } |
3784 | 3806 | ||
3785 | /** | 3807 | /** |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 87925e97e613..29e5c70e4e26 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -870,6 +870,11 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
870 | retcode = ERR_DISK_CONFIGURED; | 870 | retcode = ERR_DISK_CONFIGURED; |
871 | goto fail; | 871 | goto fail; |
872 | } | 872 | } |
873 | /* It may just now have detached because of IO error. Make sure | ||
874 | * drbd_ldev_destroy is done already, we may end up here very fast, | ||
875 | * e.g. if someone calls attach from the on-io-error handler, | ||
876 | * to realize a "hot spare" feature (not that I'd recommend that) */ | ||
877 | wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); | ||
873 | 878 | ||
874 | /* allocation not in the IO path, cqueue thread context */ | 879 | /* allocation not in the IO path, cqueue thread context */ |
875 | nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); | 880 | nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); |
@@ -1098,9 +1103,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1098 | /* Reset the "barriers don't work" bits here, then force meta data to | 1103 | /* Reset the "barriers don't work" bits here, then force meta data to |
1099 | * be written, to ensure we determine if barriers are supported. */ | 1104 | * be written, to ensure we determine if barriers are supported. */ |
1100 | if (nbc->dc.no_md_flush) | 1105 | if (nbc->dc.no_md_flush) |
1101 | set_bit(MD_NO_BARRIER, &mdev->flags); | 1106 | set_bit(MD_NO_FUA, &mdev->flags); |
1102 | else | 1107 | else |
1103 | clear_bit(MD_NO_BARRIER, &mdev->flags); | 1108 | clear_bit(MD_NO_FUA, &mdev->flags); |
1104 | 1109 | ||
1105 | /* Point of no return reached. | 1110 | /* Point of no return reached. |
1106 | * Devices and memory are no longer released by error cleanup below. | 1111 | * Devices and memory are no longer released by error cleanup below. |
@@ -1112,8 +1117,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1112 | nbc = NULL; | 1117 | nbc = NULL; |
1113 | resync_lru = NULL; | 1118 | resync_lru = NULL; |
1114 | 1119 | ||
1115 | mdev->write_ordering = WO_bio_barrier; | 1120 | mdev->write_ordering = WO_bdev_flush; |
1116 | drbd_bump_write_ordering(mdev, WO_bio_barrier); | 1121 | drbd_bump_write_ordering(mdev, WO_bdev_flush); |
1117 | 1122 | ||
1118 | if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY)) | 1123 | if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY)) |
1119 | set_bit(CRASHED_PRIMARY, &mdev->flags); | 1124 | set_bit(CRASHED_PRIMARY, &mdev->flags); |
@@ -1262,7 +1267,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1262 | force_diskless_dec: | 1267 | force_diskless_dec: |
1263 | put_ldev(mdev); | 1268 | put_ldev(mdev); |
1264 | force_diskless: | 1269 | force_diskless: |
1265 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); | 1270 | drbd_force_state(mdev, NS(disk, D_FAILED)); |
1266 | drbd_md_sync(mdev); | 1271 | drbd_md_sync(mdev); |
1267 | release_bdev2_fail: | 1272 | release_bdev2_fail: |
1268 | if (nbc) | 1273 | if (nbc) |
@@ -1285,10 +1290,19 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1285 | return 0; | 1290 | return 0; |
1286 | } | 1291 | } |
1287 | 1292 | ||
1293 | /* Detaching the disk is a process in multiple stages. First we need to lock | ||
1294 | * out application IO, in-flight IO, IO stuck in drbd_al_begin_io. | ||
1295 | * Then we transition to D_DISKLESS, and wait for put_ldev() to return all | ||
1296 | * internal references as well. | ||
1297 | * Only then we have finally detached. */ | ||
1288 | static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, | 1298 | static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, |
1289 | struct drbd_nl_cfg_reply *reply) | 1299 | struct drbd_nl_cfg_reply *reply) |
1290 | { | 1300 | { |
1301 | drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ | ||
1291 | reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS)); | 1302 | reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS)); |
1303 | if (mdev->state.disk == D_DISKLESS) | ||
1304 | wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); | ||
1305 | drbd_resume_io(mdev); | ||
1292 | return 0; | 1306 | return 0; |
1293 | } | 1307 | } |
1294 | 1308 | ||
@@ -1953,7 +1967,6 @@ static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1953 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { | 1967 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { |
1954 | drbd_uuid_new_current(mdev); | 1968 | drbd_uuid_new_current(mdev); |
1955 | clear_bit(NEW_CUR_UUID, &mdev->flags); | 1969 | clear_bit(NEW_CUR_UUID, &mdev->flags); |
1956 | drbd_md_sync(mdev); | ||
1957 | } | 1970 | } |
1958 | drbd_suspend_io(mdev); | 1971 | drbd_suspend_io(mdev); |
1959 | reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0)); | 1972 | reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0)); |
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index ad325c5d0ce1..7e6ac307e2de 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c | |||
@@ -158,7 +158,6 @@ static int drbd_seq_show(struct seq_file *seq, void *v) | |||
158 | [WO_none] = 'n', | 158 | [WO_none] = 'n', |
159 | [WO_drain_io] = 'd', | 159 | [WO_drain_io] = 'd', |
160 | [WO_bdev_flush] = 'f', | 160 | [WO_bdev_flush] = 'f', |
161 | [WO_bio_barrier] = 'b', | ||
162 | }; | 161 | }; |
163 | 162 | ||
164 | seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", | 163 | seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index efd6169acf2f..d299fe9e78c8 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -49,11 +49,6 @@ | |||
49 | 49 | ||
50 | #include "drbd_vli.h" | 50 | #include "drbd_vli.h" |
51 | 51 | ||
52 | struct flush_work { | ||
53 | struct drbd_work w; | ||
54 | struct drbd_epoch *epoch; | ||
55 | }; | ||
56 | |||
57 | enum finish_epoch { | 52 | enum finish_epoch { |
58 | FE_STILL_LIVE, | 53 | FE_STILL_LIVE, |
59 | FE_DESTROYED, | 54 | FE_DESTROYED, |
@@ -66,16 +61,6 @@ static int drbd_do_auth(struct drbd_conf *mdev); | |||
66 | static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event); | 61 | static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event); |
67 | static int e_end_block(struct drbd_conf *, struct drbd_work *, int); | 62 | static int e_end_block(struct drbd_conf *, struct drbd_work *, int); |
68 | 63 | ||
69 | static struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) | ||
70 | { | ||
71 | struct drbd_epoch *prev; | ||
72 | spin_lock(&mdev->epoch_lock); | ||
73 | prev = list_entry(epoch->list.prev, struct drbd_epoch, list); | ||
74 | if (prev == epoch || prev == mdev->current_epoch) | ||
75 | prev = NULL; | ||
76 | spin_unlock(&mdev->epoch_lock); | ||
77 | return prev; | ||
78 | } | ||
79 | 64 | ||
80 | #define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) | 65 | #define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) |
81 | 66 | ||
@@ -981,7 +966,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi | |||
981 | return TRUE; | 966 | return TRUE; |
982 | } | 967 | } |
983 | 968 | ||
984 | static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) | 969 | static void drbd_flush(struct drbd_conf *mdev) |
985 | { | 970 | { |
986 | int rv; | 971 | int rv; |
987 | 972 | ||
@@ -997,24 +982,6 @@ static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct d | |||
997 | } | 982 | } |
998 | put_ldev(mdev); | 983 | put_ldev(mdev); |
999 | } | 984 | } |
1000 | |||
1001 | return drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE); | ||
1002 | } | ||
1003 | |||
1004 | static int w_flush(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | ||
1005 | { | ||
1006 | struct flush_work *fw = (struct flush_work *)w; | ||
1007 | struct drbd_epoch *epoch = fw->epoch; | ||
1008 | |||
1009 | kfree(w); | ||
1010 | |||
1011 | if (!test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags)) | ||
1012 | drbd_flush_after_epoch(mdev, epoch); | ||
1013 | |||
1014 | drbd_may_finish_epoch(mdev, epoch, EV_PUT | | ||
1015 | (mdev->state.conn < C_CONNECTED ? EV_CLEANUP : 0)); | ||
1016 | |||
1017 | return 1; | ||
1018 | } | 985 | } |
1019 | 986 | ||
1020 | /** | 987 | /** |
@@ -1027,15 +994,13 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, | |||
1027 | struct drbd_epoch *epoch, | 994 | struct drbd_epoch *epoch, |
1028 | enum epoch_event ev) | 995 | enum epoch_event ev) |
1029 | { | 996 | { |
1030 | int finish, epoch_size; | 997 | int epoch_size; |
1031 | struct drbd_epoch *next_epoch; | 998 | struct drbd_epoch *next_epoch; |
1032 | int schedule_flush = 0; | ||
1033 | enum finish_epoch rv = FE_STILL_LIVE; | 999 | enum finish_epoch rv = FE_STILL_LIVE; |
1034 | 1000 | ||
1035 | spin_lock(&mdev->epoch_lock); | 1001 | spin_lock(&mdev->epoch_lock); |
1036 | do { | 1002 | do { |
1037 | next_epoch = NULL; | 1003 | next_epoch = NULL; |
1038 | finish = 0; | ||
1039 | 1004 | ||
1040 | epoch_size = atomic_read(&epoch->epoch_size); | 1005 | epoch_size = atomic_read(&epoch->epoch_size); |
1041 | 1006 | ||
@@ -1045,16 +1010,6 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, | |||
1045 | break; | 1010 | break; |
1046 | case EV_GOT_BARRIER_NR: | 1011 | case EV_GOT_BARRIER_NR: |
1047 | set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags); | 1012 | set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags); |
1048 | |||
1049 | /* Special case: If we just switched from WO_bio_barrier to | ||
1050 | WO_bdev_flush we should not finish the current epoch */ | ||
1051 | if (test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) && epoch_size == 1 && | ||
1052 | mdev->write_ordering != WO_bio_barrier && | ||
1053 | epoch == mdev->current_epoch) | ||
1054 | clear_bit(DE_CONTAINS_A_BARRIER, &epoch->flags); | ||
1055 | break; | ||
1056 | case EV_BARRIER_DONE: | ||
1057 | set_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags); | ||
1058 | break; | 1013 | break; |
1059 | case EV_BECAME_LAST: | 1014 | case EV_BECAME_LAST: |
1060 | /* nothing to do*/ | 1015 | /* nothing to do*/ |
@@ -1063,23 +1018,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, | |||
1063 | 1018 | ||
1064 | if (epoch_size != 0 && | 1019 | if (epoch_size != 0 && |
1065 | atomic_read(&epoch->active) == 0 && | 1020 | atomic_read(&epoch->active) == 0 && |
1066 | test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) && | 1021 | test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags)) { |
1067 | epoch->list.prev == &mdev->current_epoch->list && | ||
1068 | !test_bit(DE_IS_FINISHING, &epoch->flags)) { | ||
1069 | /* Nearly all conditions are met to finish that epoch... */ | ||
1070 | if (test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) || | ||
1071 | mdev->write_ordering == WO_none || | ||
1072 | (epoch_size == 1 && test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) || | ||
1073 | ev & EV_CLEANUP) { | ||
1074 | finish = 1; | ||
1075 | set_bit(DE_IS_FINISHING, &epoch->flags); | ||
1076 | } else if (!test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) && | ||
1077 | mdev->write_ordering == WO_bio_barrier) { | ||
1078 | atomic_inc(&epoch->active); | ||
1079 | schedule_flush = 1; | ||
1080 | } | ||
1081 | } | ||
1082 | if (finish) { | ||
1083 | if (!(ev & EV_CLEANUP)) { | 1022 | if (!(ev & EV_CLEANUP)) { |
1084 | spin_unlock(&mdev->epoch_lock); | 1023 | spin_unlock(&mdev->epoch_lock); |
1085 | drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size); | 1024 | drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size); |
@@ -1102,6 +1041,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, | |||
1102 | /* atomic_set(&epoch->active, 0); is already zero */ | 1041 | /* atomic_set(&epoch->active, 0); is already zero */ |
1103 | if (rv == FE_STILL_LIVE) | 1042 | if (rv == FE_STILL_LIVE) |
1104 | rv = FE_RECYCLED; | 1043 | rv = FE_RECYCLED; |
1044 | wake_up(&mdev->ee_wait); | ||
1105 | } | 1045 | } |
1106 | } | 1046 | } |
1107 | 1047 | ||
@@ -1113,22 +1053,6 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, | |||
1113 | 1053 | ||
1114 | spin_unlock(&mdev->epoch_lock); | 1054 | spin_unlock(&mdev->epoch_lock); |
1115 | 1055 | ||
1116 | if (schedule_flush) { | ||
1117 | struct flush_work *fw; | ||
1118 | fw = kmalloc(sizeof(*fw), GFP_ATOMIC); | ||
1119 | if (fw) { | ||
1120 | fw->w.cb = w_flush; | ||
1121 | fw->epoch = epoch; | ||
1122 | drbd_queue_work(&mdev->data.work, &fw->w); | ||
1123 | } else { | ||
1124 | dev_warn(DEV, "Could not kmalloc a flush_work obj\n"); | ||
1125 | set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); | ||
1126 | /* That is not a recursion, only one level */ | ||
1127 | drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE); | ||
1128 | drbd_may_finish_epoch(mdev, epoch, EV_PUT); | ||
1129 | } | ||
1130 | } | ||
1131 | |||
1132 | return rv; | 1056 | return rv; |
1133 | } | 1057 | } |
1134 | 1058 | ||
@@ -1144,19 +1068,16 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) | |||
1144 | [WO_none] = "none", | 1068 | [WO_none] = "none", |
1145 | [WO_drain_io] = "drain", | 1069 | [WO_drain_io] = "drain", |
1146 | [WO_bdev_flush] = "flush", | 1070 | [WO_bdev_flush] = "flush", |
1147 | [WO_bio_barrier] = "barrier", | ||
1148 | }; | 1071 | }; |
1149 | 1072 | ||
1150 | pwo = mdev->write_ordering; | 1073 | pwo = mdev->write_ordering; |
1151 | wo = min(pwo, wo); | 1074 | wo = min(pwo, wo); |
1152 | if (wo == WO_bio_barrier && mdev->ldev->dc.no_disk_barrier) | ||
1153 | wo = WO_bdev_flush; | ||
1154 | if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush) | 1075 | if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush) |
1155 | wo = WO_drain_io; | 1076 | wo = WO_drain_io; |
1156 | if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain) | 1077 | if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain) |
1157 | wo = WO_none; | 1078 | wo = WO_none; |
1158 | mdev->write_ordering = wo; | 1079 | mdev->write_ordering = wo; |
1159 | if (pwo != mdev->write_ordering || wo == WO_bio_barrier) | 1080 | if (pwo != mdev->write_ordering || wo == WO_bdev_flush) |
1160 | dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); | 1081 | dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); |
1161 | } | 1082 | } |
1162 | 1083 | ||
@@ -1192,7 +1113,7 @@ next_bio: | |||
1192 | bio->bi_sector = sector; | 1113 | bio->bi_sector = sector; |
1193 | bio->bi_bdev = mdev->ldev->backing_bdev; | 1114 | bio->bi_bdev = mdev->ldev->backing_bdev; |
1194 | /* we special case some flags in the multi-bio case, see below | 1115 | /* we special case some flags in the multi-bio case, see below |
1195 | * (REQ_UNPLUG, REQ_HARDBARRIER) */ | 1116 | * (REQ_UNPLUG) */ |
1196 | bio->bi_rw = rw; | 1117 | bio->bi_rw = rw; |
1197 | bio->bi_private = e; | 1118 | bio->bi_private = e; |
1198 | bio->bi_end_io = drbd_endio_sec; | 1119 | bio->bi_end_io = drbd_endio_sec; |
@@ -1226,11 +1147,6 @@ next_bio: | |||
1226 | bio->bi_rw &= ~REQ_UNPLUG; | 1147 | bio->bi_rw &= ~REQ_UNPLUG; |
1227 | 1148 | ||
1228 | drbd_generic_make_request(mdev, fault_type, bio); | 1149 | drbd_generic_make_request(mdev, fault_type, bio); |
1229 | |||
1230 | /* strip off REQ_HARDBARRIER, | ||
1231 | * unless it is the first or last bio */ | ||
1232 | if (bios && bios->bi_next) | ||
1233 | bios->bi_rw &= ~REQ_HARDBARRIER; | ||
1234 | } while (bios); | 1150 | } while (bios); |
1235 | maybe_kick_lo(mdev); | 1151 | maybe_kick_lo(mdev); |
1236 | return 0; | 1152 | return 0; |
@@ -1244,45 +1160,9 @@ fail: | |||
1244 | return -ENOMEM; | 1160 | return -ENOMEM; |
1245 | } | 1161 | } |
1246 | 1162 | ||
1247 | /** | ||
1248 | * w_e_reissue() - Worker callback; Resubmit a bio, without REQ_HARDBARRIER set | ||
1249 | * @mdev: DRBD device. | ||
1250 | * @w: work object. | ||
1251 | * @cancel: The connection will be closed anyways (unused in this callback) | ||
1252 | */ | ||
1253 | int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local) | ||
1254 | { | ||
1255 | struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; | ||
1256 | /* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place, | ||
1257 | (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) | ||
1258 | so that we can finish that epoch in drbd_may_finish_epoch(). | ||
1259 | That is necessary if we already have a long chain of Epochs, before | ||
1260 | we realize that REQ_HARDBARRIER is actually not supported */ | ||
1261 | |||
1262 | /* As long as the -ENOTSUPP on the barrier is reported immediately | ||
1263 | that will never trigger. If it is reported late, we will just | ||
1264 | print that warning and continue correctly for all future requests | ||
1265 | with WO_bdev_flush */ | ||
1266 | if (previous_epoch(mdev, e->epoch)) | ||
1267 | dev_warn(DEV, "Write ordering was not enforced (one time event)\n"); | ||
1268 | |||
1269 | /* we still have a local reference, | ||
1270 | * get_ldev was done in receive_Data. */ | ||
1271 | |||
1272 | e->w.cb = e_end_block; | ||
1273 | if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_DT_WR) != 0) { | ||
1274 | /* drbd_submit_ee fails for one reason only: | ||
1275 | * if was not able to allocate sufficient bios. | ||
1276 | * requeue, try again later. */ | ||
1277 | e->w.cb = w_e_reissue; | ||
1278 | drbd_queue_work(&mdev->data.work, &e->w); | ||
1279 | } | ||
1280 | return 1; | ||
1281 | } | ||
1282 | |||
1283 | static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) | 1163 | static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) |
1284 | { | 1164 | { |
1285 | int rv, issue_flush; | 1165 | int rv; |
1286 | struct p_barrier *p = &mdev->data.rbuf.barrier; | 1166 | struct p_barrier *p = &mdev->data.rbuf.barrier; |
1287 | struct drbd_epoch *epoch; | 1167 | struct drbd_epoch *epoch; |
1288 | 1168 | ||
@@ -1300,44 +1180,40 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign | |||
1300 | * Therefore we must send the barrier_ack after the barrier request was | 1180 | * Therefore we must send the barrier_ack after the barrier request was |
1301 | * completed. */ | 1181 | * completed. */ |
1302 | switch (mdev->write_ordering) { | 1182 | switch (mdev->write_ordering) { |
1303 | case WO_bio_barrier: | ||
1304 | case WO_none: | 1183 | case WO_none: |
1305 | if (rv == FE_RECYCLED) | 1184 | if (rv == FE_RECYCLED) |
1306 | return TRUE; | 1185 | return TRUE; |
1307 | break; | 1186 | |
1187 | /* receiver context, in the writeout path of the other node. | ||
1188 | * avoid potential distributed deadlock */ | ||
1189 | epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); | ||
1190 | if (epoch) | ||
1191 | break; | ||
1192 | else | ||
1193 | dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); | ||
1194 | /* Fall through */ | ||
1308 | 1195 | ||
1309 | case WO_bdev_flush: | 1196 | case WO_bdev_flush: |
1310 | case WO_drain_io: | 1197 | case WO_drain_io: |
1311 | if (rv == FE_STILL_LIVE) { | ||
1312 | set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); | ||
1313 | drbd_wait_ee_list_empty(mdev, &mdev->active_ee); | ||
1314 | rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); | ||
1315 | } | ||
1316 | if (rv == FE_RECYCLED) | ||
1317 | return TRUE; | ||
1318 | |||
1319 | /* The asender will send all the ACKs and barrier ACKs out, since | ||
1320 | all EEs moved from the active_ee to the done_ee. We need to | ||
1321 | provide a new epoch object for the EEs that come in soon */ | ||
1322 | break; | ||
1323 | } | ||
1324 | |||
1325 | /* receiver context, in the writeout path of the other node. | ||
1326 | * avoid potential distributed deadlock */ | ||
1327 | epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); | ||
1328 | if (!epoch) { | ||
1329 | dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); | ||
1330 | issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); | ||
1331 | drbd_wait_ee_list_empty(mdev, &mdev->active_ee); | 1198 | drbd_wait_ee_list_empty(mdev, &mdev->active_ee); |
1332 | if (issue_flush) { | 1199 | drbd_flush(mdev); |
1333 | rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); | 1200 | |
1334 | if (rv == FE_RECYCLED) | 1201 | if (atomic_read(&mdev->current_epoch->epoch_size)) { |
1335 | return TRUE; | 1202 | epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); |
1203 | if (epoch) | ||
1204 | break; | ||
1336 | } | 1205 | } |
1337 | 1206 | ||
1338 | drbd_wait_ee_list_empty(mdev, &mdev->done_ee); | 1207 | epoch = mdev->current_epoch; |
1208 | wait_event(mdev->ee_wait, atomic_read(&epoch->epoch_size) == 0); | ||
1209 | |||
1210 | D_ASSERT(atomic_read(&epoch->active) == 0); | ||
1211 | D_ASSERT(epoch->flags == 0); | ||
1339 | 1212 | ||
1340 | return TRUE; | 1213 | return TRUE; |
1214 | default: | ||
1215 | dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering); | ||
1216 | return FALSE; | ||
1341 | } | 1217 | } |
1342 | 1218 | ||
1343 | epoch->flags = 0; | 1219 | epoch->flags = 0; |
@@ -1652,15 +1528,8 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | |||
1652 | { | 1528 | { |
1653 | struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; | 1529 | struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; |
1654 | sector_t sector = e->sector; | 1530 | sector_t sector = e->sector; |
1655 | struct drbd_epoch *epoch; | ||
1656 | int ok = 1, pcmd; | 1531 | int ok = 1, pcmd; |
1657 | 1532 | ||
1658 | if (e->flags & EE_IS_BARRIER) { | ||
1659 | epoch = previous_epoch(mdev, e->epoch); | ||
1660 | if (epoch) | ||
1661 | drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE + (cancel ? EV_CLEANUP : 0)); | ||
1662 | } | ||
1663 | |||
1664 | if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { | 1533 | if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { |
1665 | if (likely((e->flags & EE_WAS_ERROR) == 0)) { | 1534 | if (likely((e->flags & EE_WAS_ERROR) == 0)) { |
1666 | pcmd = (mdev->state.conn >= C_SYNC_SOURCE && | 1535 | pcmd = (mdev->state.conn >= C_SYNC_SOURCE && |
@@ -1817,27 +1686,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
1817 | e->epoch = mdev->current_epoch; | 1686 | e->epoch = mdev->current_epoch; |
1818 | atomic_inc(&e->epoch->epoch_size); | 1687 | atomic_inc(&e->epoch->epoch_size); |
1819 | atomic_inc(&e->epoch->active); | 1688 | atomic_inc(&e->epoch->active); |
1820 | |||
1821 | if (mdev->write_ordering == WO_bio_barrier && atomic_read(&e->epoch->epoch_size) == 1) { | ||
1822 | struct drbd_epoch *epoch; | ||
1823 | /* Issue a barrier if we start a new epoch, and the previous epoch | ||
1824 | was not a epoch containing a single request which already was | ||
1825 | a Barrier. */ | ||
1826 | epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list); | ||
1827 | if (epoch == e->epoch) { | ||
1828 | set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); | ||
1829 | rw |= REQ_HARDBARRIER; | ||
1830 | e->flags |= EE_IS_BARRIER; | ||
1831 | } else { | ||
1832 | if (atomic_read(&epoch->epoch_size) > 1 || | ||
1833 | !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) { | ||
1834 | set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); | ||
1835 | set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); | ||
1836 | rw |= REQ_HARDBARRIER; | ||
1837 | e->flags |= EE_IS_BARRIER; | ||
1838 | } | ||
1839 | } | ||
1840 | } | ||
1841 | spin_unlock(&mdev->epoch_lock); | 1689 | spin_unlock(&mdev->epoch_lock); |
1842 | 1690 | ||
1843 | dp_flags = be32_to_cpu(p->dp_flags); | 1691 | dp_flags = be32_to_cpu(p->dp_flags); |
@@ -1995,10 +1843,11 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
1995 | break; | 1843 | break; |
1996 | } | 1844 | } |
1997 | 1845 | ||
1998 | if (mdev->state.pdsk == D_DISKLESS) { | 1846 | if (mdev->state.pdsk < D_INCONSISTENT) { |
1999 | /* In case we have the only disk of the cluster, */ | 1847 | /* In case we have the only disk of the cluster, */ |
2000 | drbd_set_out_of_sync(mdev, e->sector, e->size); | 1848 | drbd_set_out_of_sync(mdev, e->sector, e->size); |
2001 | e->flags |= EE_CALL_AL_COMPLETE_IO; | 1849 | e->flags |= EE_CALL_AL_COMPLETE_IO; |
1850 | e->flags &= ~EE_MAY_SET_IN_SYNC; | ||
2002 | drbd_al_begin_io(mdev, e->sector); | 1851 | drbd_al_begin_io(mdev, e->sector); |
2003 | } | 1852 | } |
2004 | 1853 | ||
@@ -3362,7 +3211,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
3362 | if (ns.conn == C_MASK) { | 3211 | if (ns.conn == C_MASK) { |
3363 | ns.conn = C_CONNECTED; | 3212 | ns.conn = C_CONNECTED; |
3364 | if (mdev->state.disk == D_NEGOTIATING) { | 3213 | if (mdev->state.disk == D_NEGOTIATING) { |
3365 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); | 3214 | drbd_force_state(mdev, NS(disk, D_FAILED)); |
3366 | } else if (peer_state.disk == D_NEGOTIATING) { | 3215 | } else if (peer_state.disk == D_NEGOTIATING) { |
3367 | dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); | 3216 | dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); |
3368 | peer_state.disk = D_DISKLESS; | 3217 | peer_state.disk = D_DISKLESS; |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 9e91a2545fc8..11a75d32a2e2 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -258,7 +258,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
258 | if (!hlist_unhashed(&req->colision)) | 258 | if (!hlist_unhashed(&req->colision)) |
259 | hlist_del(&req->colision); | 259 | hlist_del(&req->colision); |
260 | else | 260 | else |
261 | D_ASSERT((s & RQ_NET_MASK) == 0); | 261 | D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); |
262 | 262 | ||
263 | /* for writes we need to do some extra housekeeping */ | 263 | /* for writes we need to do some extra housekeeping */ |
264 | if (rw == WRITE) | 264 | if (rw == WRITE) |
@@ -813,7 +813,8 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) | |||
813 | mdev->state.conn >= C_CONNECTED)); | 813 | mdev->state.conn >= C_CONNECTED)); |
814 | 814 | ||
815 | if (!(local || remote) && !is_susp(mdev->state)) { | 815 | if (!(local || remote) && !is_susp(mdev->state)) { |
816 | dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); | 816 | if (__ratelimit(&drbd_ratelimit_state)) |
817 | dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); | ||
817 | goto fail_free_complete; | 818 | goto fail_free_complete; |
818 | } | 819 | } |
819 | 820 | ||
@@ -942,12 +943,21 @@ allocate_barrier: | |||
942 | if (local) { | 943 | if (local) { |
943 | req->private_bio->bi_bdev = mdev->ldev->backing_bdev; | 944 | req->private_bio->bi_bdev = mdev->ldev->backing_bdev; |
944 | 945 | ||
945 | if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR | 946 | /* State may have changed since we grabbed our reference on the |
946 | : rw == READ ? DRBD_FAULT_DT_RD | 947 | * mdev->ldev member. Double check, and short-circuit to endio. |
947 | : DRBD_FAULT_DT_RA)) | 948 | * In case the last activity log transaction failed to get on |
949 | * stable storage, and this is a WRITE, we may not even submit | ||
950 | * this bio. */ | ||
951 | if (get_ldev(mdev)) { | ||
952 | if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR | ||
953 | : rw == READ ? DRBD_FAULT_DT_RD | ||
954 | : DRBD_FAULT_DT_RA)) | ||
955 | bio_endio(req->private_bio, -EIO); | ||
956 | else | ||
957 | generic_make_request(req->private_bio); | ||
958 | put_ldev(mdev); | ||
959 | } else | ||
948 | bio_endio(req->private_bio, -EIO); | 960 | bio_endio(req->private_bio, -EIO); |
949 | else | ||
950 | generic_make_request(req->private_bio); | ||
951 | } | 961 | } |
952 | 962 | ||
953 | /* we need to plug ALWAYS since we possibly need to kick lo_dev. | 963 | /* we need to plug ALWAYS since we possibly need to kick lo_dev. |
@@ -1022,20 +1032,6 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio) | |||
1022 | return 0; | 1032 | return 0; |
1023 | } | 1033 | } |
1024 | 1034 | ||
1025 | /* Reject barrier requests if we know the underlying device does | ||
1026 | * not support them. | ||
1027 | * XXX: Need to get this info from peer as well some how so we | ||
1028 | * XXX: reject if EITHER side/data/metadata area does not support them. | ||
1029 | * | ||
1030 | * because of those XXX, this is not yet enabled, | ||
1031 | * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. | ||
1032 | */ | ||
1033 | if (unlikely(bio->bi_rw & REQ_HARDBARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags)) { | ||
1034 | /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */ | ||
1035 | bio_endio(bio, -EOPNOTSUPP); | ||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1039 | /* | 1035 | /* |
1040 | * what we "blindly" assume: | 1036 | * what we "blindly" assume: |
1041 | */ | 1037 | */ |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 108d58015cd1..b0551ba7ad0c 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -102,12 +102,6 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local) | |||
102 | put_ldev(mdev); | 102 | put_ldev(mdev); |
103 | } | 103 | } |
104 | 104 | ||
105 | static int is_failed_barrier(int ee_flags) | ||
106 | { | ||
107 | return (ee_flags & (EE_IS_BARRIER|EE_WAS_ERROR|EE_RESUBMITTED)) | ||
108 | == (EE_IS_BARRIER|EE_WAS_ERROR); | ||
109 | } | ||
110 | |||
111 | /* writes on behalf of the partner, or resync writes, | 105 | /* writes on behalf of the partner, or resync writes, |
112 | * "submitted" by the receiver, final stage. */ | 106 | * "submitted" by the receiver, final stage. */ |
113 | static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local) | 107 | static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local) |
@@ -119,21 +113,6 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo | |||
119 | int is_syncer_req; | 113 | int is_syncer_req; |
120 | int do_al_complete_io; | 114 | int do_al_complete_io; |
121 | 115 | ||
122 | /* if this is a failed barrier request, disable use of barriers, | ||
123 | * and schedule for resubmission */ | ||
124 | if (is_failed_barrier(e->flags)) { | ||
125 | drbd_bump_write_ordering(mdev, WO_bdev_flush); | ||
126 | spin_lock_irqsave(&mdev->req_lock, flags); | ||
127 | list_del(&e->w.list); | ||
128 | e->flags = (e->flags & ~EE_WAS_ERROR) | EE_RESUBMITTED; | ||
129 | e->w.cb = w_e_reissue; | ||
130 | /* put_ldev actually happens below, once we come here again. */ | ||
131 | __release(local); | ||
132 | spin_unlock_irqrestore(&mdev->req_lock, flags); | ||
133 | drbd_queue_work(&mdev->data.work, &e->w); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | D_ASSERT(e->block_id != ID_VACANT); | 116 | D_ASSERT(e->block_id != ID_VACANT); |
138 | 117 | ||
139 | /* after we moved e to done_ee, | 118 | /* after we moved e to done_ee, |
@@ -925,7 +904,7 @@ out: | |||
925 | drbd_md_sync(mdev); | 904 | drbd_md_sync(mdev); |
926 | 905 | ||
927 | if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { | 906 | if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { |
928 | dev_warn(DEV, "Writing the whole bitmap, due to failed kmalloc\n"); | 907 | dev_info(DEV, "Writing the whole bitmap\n"); |
929 | drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); | 908 | drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); |
930 | } | 909 | } |
931 | 910 | ||
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 767107cce982..3951020e494a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -4363,9 +4363,9 @@ out_unreg_blkdev: | |||
4363 | out_put_disk: | 4363 | out_put_disk: |
4364 | while (dr--) { | 4364 | while (dr--) { |
4365 | del_timer(&motor_off_timer[dr]); | 4365 | del_timer(&motor_off_timer[dr]); |
4366 | put_disk(disks[dr]); | ||
4367 | if (disks[dr]->queue) | 4366 | if (disks[dr]->queue) |
4368 | blk_cleanup_queue(disks[dr]->queue); | 4367 | blk_cleanup_queue(disks[dr]->queue); |
4368 | put_disk(disks[dr]); | ||
4369 | } | 4369 | } |
4370 | return err; | 4370 | return err; |
4371 | } | 4371 | } |
@@ -4573,8 +4573,8 @@ static void __exit floppy_module_exit(void) | |||
4573 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); | 4573 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); |
4574 | platform_device_unregister(&floppy_device[drive]); | 4574 | platform_device_unregister(&floppy_device[drive]); |
4575 | } | 4575 | } |
4576 | put_disk(disks[drive]); | ||
4577 | blk_cleanup_queue(disks[drive]->queue); | 4576 | blk_cleanup_queue(disks[drive]->queue); |
4577 | put_disk(disks[drive]); | ||
4578 | } | 4578 | } |
4579 | 4579 | ||
4580 | del_timer_sync(&fd_timeout); | 4580 | del_timer_sync(&fd_timeout); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 1e5284ef65fa..7ea0bea2f7e3 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -481,12 +481,6 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
481 | if (bio_rw(bio) == WRITE) { | 481 | if (bio_rw(bio) == WRITE) { |
482 | struct file *file = lo->lo_backing_file; | 482 | struct file *file = lo->lo_backing_file; |
483 | 483 | ||
484 | /* REQ_HARDBARRIER is deprecated */ | ||
485 | if (bio->bi_rw & REQ_HARDBARRIER) { | ||
486 | ret = -EOPNOTSUPP; | ||
487 | goto out; | ||
488 | } | ||
489 | |||
490 | if (bio->bi_rw & REQ_FLUSH) { | 484 | if (bio->bi_rw & REQ_FLUSH) { |
491 | ret = vfs_fsync(file, 0); | 485 | ret = vfs_fsync(file, 0); |
492 | if (unlikely(ret && ret != -EINVAL)) { | 486 | if (unlikely(ret && ret != -EINVAL)) { |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 06e2812ba124..255035cfc88a 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -289,8 +289,6 @@ static int blkif_queue_request(struct request *req) | |||
289 | 289 | ||
290 | ring_req->operation = rq_data_dir(req) ? | 290 | ring_req->operation = rq_data_dir(req) ? |
291 | BLKIF_OP_WRITE : BLKIF_OP_READ; | 291 | BLKIF_OP_WRITE : BLKIF_OP_READ; |
292 | if (req->cmd_flags & REQ_HARDBARRIER) | ||
293 | ring_req->operation = BLKIF_OP_WRITE_BARRIER; | ||
294 | 292 | ||
295 | ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); | 293 | ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); |
296 | BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); | 294 | BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 3a9c01416839..ba53ec956c95 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -2,24 +2,10 @@ | |||
2 | # Makefile for the kernel character device drivers. | 2 | # Makefile for the kernel character device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | # | 5 | obj-y += mem.o random.o |
6 | # This file contains the font map for the default (hardware) font | ||
7 | # | ||
8 | FONTMAPFILE = cp437.uni | ||
9 | |||
10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o | ||
11 | |||
12 | obj-y += tty_mutex.o | ||
13 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | ||
14 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | ||
15 | obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o | 6 | obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o |
16 | obj-y += misc.o | 7 | obj-y += misc.o |
17 | obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o selection.o keyboard.o | ||
18 | obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o | 8 | obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o |
19 | obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o | ||
20 | obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o | ||
21 | obj-$(CONFIG_AUDIT) += tty_audit.o | ||
22 | obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o | ||
23 | obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o | 9 | obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o |
24 | obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o | 10 | obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o |
25 | obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o | 11 | obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o |
@@ -41,8 +27,6 @@ obj-$(CONFIG_ISI) += isicom.o | |||
41 | obj-$(CONFIG_SYNCLINK) += synclink.o | 27 | obj-$(CONFIG_SYNCLINK) += synclink.o |
42 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o | 28 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o |
43 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o | 29 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o |
44 | obj-$(CONFIG_N_HDLC) += n_hdlc.o | ||
45 | obj-$(CONFIG_N_GSM) += n_gsm.o | ||
46 | obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o | 30 | obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o |
47 | obj-$(CONFIG_SX) += sx.o generic_serial.o | 31 | obj-$(CONFIG_SX) += sx.o generic_serial.o |
48 | obj-$(CONFIG_RIO) += rio/ generic_serial.o | 32 | obj-$(CONFIG_RIO) += rio/ generic_serial.o |
@@ -74,7 +58,6 @@ obj-$(CONFIG_PRINTER) += lp.o | |||
74 | obj-$(CONFIG_APM_EMULATION) += apm-emulation.o | 58 | obj-$(CONFIG_APM_EMULATION) += apm-emulation.o |
75 | 59 | ||
76 | obj-$(CONFIG_DTLK) += dtlk.o | 60 | obj-$(CONFIG_DTLK) += dtlk.o |
77 | obj-$(CONFIG_R3964) += n_r3964.o | ||
78 | obj-$(CONFIG_APPLICOM) += applicom.o | 61 | obj-$(CONFIG_APPLICOM) += applicom.o |
79 | obj-$(CONFIG_SONYPI) += sonypi.o | 62 | obj-$(CONFIG_SONYPI) += sonypi.o |
80 | obj-$(CONFIG_RTC) += rtc.o | 63 | obj-$(CONFIG_RTC) += rtc.o |
@@ -115,28 +98,3 @@ obj-$(CONFIG_RAMOOPS) += ramoops.o | |||
115 | 98 | ||
116 | obj-$(CONFIG_JS_RTC) += js-rtc.o | 99 | obj-$(CONFIG_JS_RTC) += js-rtc.o |
117 | js-rtc-y = rtc.o | 100 | js-rtc-y = rtc.o |
118 | |||
119 | # Files generated that shall be removed upon make clean | ||
120 | clean-files := consolemap_deftbl.c defkeymap.c | ||
121 | |||
122 | quiet_cmd_conmk = CONMK $@ | ||
123 | cmd_conmk = scripts/conmakehash $< > $@ | ||
124 | |||
125 | $(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE) | ||
126 | $(call cmd,conmk) | ||
127 | |||
128 | $(obj)/defkeymap.o: $(obj)/defkeymap.c | ||
129 | |||
130 | # Uncomment if you're changing the keymap and have an appropriate | ||
131 | # loadkeys version for the map. By default, we'll use the shipped | ||
132 | # versions. | ||
133 | # GENERATE_KEYMAP := 1 | ||
134 | |||
135 | ifdef GENERATE_KEYMAP | ||
136 | |||
137 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map | ||
138 | loadkeys --mktable $< > $@.tmp | ||
139 | sed -e 's/^static *//' $@.tmp > $@ | ||
140 | rm $@.tmp | ||
141 | |||
142 | endif | ||
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 6b6760ea2435..9272c38dd3c6 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -1210,14 +1210,14 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry, | |||
1210 | unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; | 1210 | unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; |
1211 | u32 pte_flags; | 1211 | u32 pte_flags; |
1212 | 1212 | ||
1213 | if (type_mask == AGP_USER_UNCACHED_MEMORY) | 1213 | if (type_mask == AGP_USER_MEMORY) |
1214 | pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; | 1214 | pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; |
1215 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { | 1215 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { |
1216 | pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; | 1216 | pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; |
1217 | if (gfdt) | 1217 | if (gfdt) |
1218 | pte_flags |= GEN6_PTE_GFDT; | 1218 | pte_flags |= GEN6_PTE_GFDT; |
1219 | } else { /* set 'normal'/'cached' to LLC by default */ | 1219 | } else { /* set 'normal'/'cached' to LLC by default */ |
1220 | pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; | 1220 | pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; |
1221 | if (gfdt) | 1221 | if (gfdt) |
1222 | pte_flags |= GEN6_PTE_GFDT; | 1222 | pte_flags |= GEN6_PTE_GFDT; |
1223 | } | 1223 | } |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index a44611652282..d68d3aa1814b 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -616,13 +616,9 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
616 | /* get hold of clock */ | 616 | /* get hold of clock */ |
617 | p->clk = clk_get(&p->pdev->dev, "cmt_fck"); | 617 | p->clk = clk_get(&p->pdev->dev, "cmt_fck"); |
618 | if (IS_ERR(p->clk)) { | 618 | if (IS_ERR(p->clk)) { |
619 | dev_warn(&p->pdev->dev, "using deprecated clock lookup\n"); | 619 | dev_err(&p->pdev->dev, "cannot get clock\n"); |
620 | p->clk = clk_get(&p->pdev->dev, cfg->clk); | 620 | ret = PTR_ERR(p->clk); |
621 | if (IS_ERR(p->clk)) { | 621 | goto err1; |
622 | dev_err(&p->pdev->dev, "cannot get clock\n"); | ||
623 | ret = PTR_ERR(p->clk); | ||
624 | goto err1; | ||
625 | } | ||
626 | } | 622 | } |
627 | 623 | ||
628 | if (resource_size(res) == 6) { | 624 | if (resource_size(res) == 6) { |
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index ef7a5be8a09f..40630cb98237 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c | |||
@@ -287,13 +287,9 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) | |||
287 | /* get hold of clock */ | 287 | /* get hold of clock */ |
288 | p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); | 288 | p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); |
289 | if (IS_ERR(p->clk)) { | 289 | if (IS_ERR(p->clk)) { |
290 | dev_warn(&p->pdev->dev, "using deprecated clock lookup\n"); | 290 | dev_err(&p->pdev->dev, "cannot get clock\n"); |
291 | p->clk = clk_get(&p->pdev->dev, cfg->clk); | 291 | ret = PTR_ERR(p->clk); |
292 | if (IS_ERR(p->clk)) { | 292 | goto err1; |
293 | dev_err(&p->pdev->dev, "cannot get clock\n"); | ||
294 | ret = PTR_ERR(p->clk); | ||
295 | goto err1; | ||
296 | } | ||
297 | } | 293 | } |
298 | 294 | ||
299 | return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), | 295 | return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), |
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index de715901b82a..36aba9923060 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
@@ -393,13 +393,9 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) | |||
393 | /* get hold of clock */ | 393 | /* get hold of clock */ |
394 | p->clk = clk_get(&p->pdev->dev, "tmu_fck"); | 394 | p->clk = clk_get(&p->pdev->dev, "tmu_fck"); |
395 | if (IS_ERR(p->clk)) { | 395 | if (IS_ERR(p->clk)) { |
396 | dev_warn(&p->pdev->dev, "using deprecated clock lookup\n"); | 396 | dev_err(&p->pdev->dev, "cannot get clock\n"); |
397 | p->clk = clk_get(&p->pdev->dev, cfg->clk); | 397 | ret = PTR_ERR(p->clk); |
398 | if (IS_ERR(p->clk)) { | 398 | goto err1; |
399 | dev_err(&p->pdev->dev, "cannot get clock\n"); | ||
400 | ret = PTR_ERR(p->clk); | ||
401 | goto err1; | ||
402 | } | ||
403 | } | 399 | } |
404 | 400 | ||
405 | return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), | 401 | return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 9dcb17d51aee..84eb607d6c03 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -577,17 +577,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, | |||
577 | return ret; | 577 | return ret; |
578 | } | 578 | } |
579 | 579 | ||
580 | static int ar_context_add_page(struct ar_context *ctx) | 580 | static void ar_context_link_page(struct ar_context *ctx, |
581 | struct ar_buffer *ab, dma_addr_t ab_bus) | ||
581 | { | 582 | { |
582 | struct device *dev = ctx->ohci->card.device; | ||
583 | struct ar_buffer *ab; | ||
584 | dma_addr_t uninitialized_var(ab_bus); | ||
585 | size_t offset; | 583 | size_t offset; |
586 | 584 | ||
587 | ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); | ||
588 | if (ab == NULL) | ||
589 | return -ENOMEM; | ||
590 | |||
591 | ab->next = NULL; | 585 | ab->next = NULL; |
592 | memset(&ab->descriptor, 0, sizeof(ab->descriptor)); | 586 | memset(&ab->descriptor, 0, sizeof(ab->descriptor)); |
593 | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | | 587 | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | |
@@ -606,6 +600,19 @@ static int ar_context_add_page(struct ar_context *ctx) | |||
606 | 600 | ||
607 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); | 601 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); |
608 | flush_writes(ctx->ohci); | 602 | flush_writes(ctx->ohci); |
603 | } | ||
604 | |||
605 | static int ar_context_add_page(struct ar_context *ctx) | ||
606 | { | ||
607 | struct device *dev = ctx->ohci->card.device; | ||
608 | struct ar_buffer *ab; | ||
609 | dma_addr_t uninitialized_var(ab_bus); | ||
610 | |||
611 | ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); | ||
612 | if (ab == NULL) | ||
613 | return -ENOMEM; | ||
614 | |||
615 | ar_context_link_page(ctx, ab, ab_bus); | ||
609 | 616 | ||
610 | return 0; | 617 | return 0; |
611 | } | 618 | } |
@@ -730,16 +737,17 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
730 | static void ar_context_tasklet(unsigned long data) | 737 | static void ar_context_tasklet(unsigned long data) |
731 | { | 738 | { |
732 | struct ar_context *ctx = (struct ar_context *)data; | 739 | struct ar_context *ctx = (struct ar_context *)data; |
733 | struct fw_ohci *ohci = ctx->ohci; | ||
734 | struct ar_buffer *ab; | 740 | struct ar_buffer *ab; |
735 | struct descriptor *d; | 741 | struct descriptor *d; |
736 | void *buffer, *end; | 742 | void *buffer, *end; |
743 | __le16 res_count; | ||
737 | 744 | ||
738 | ab = ctx->current_buffer; | 745 | ab = ctx->current_buffer; |
739 | d = &ab->descriptor; | 746 | d = &ab->descriptor; |
740 | 747 | ||
741 | if (d->res_count == 0) { | 748 | res_count = ACCESS_ONCE(d->res_count); |
742 | size_t size, rest, offset; | 749 | if (res_count == 0) { |
750 | size_t size, size2, rest, pktsize, size3, offset; | ||
743 | dma_addr_t start_bus; | 751 | dma_addr_t start_bus; |
744 | void *start; | 752 | void *start; |
745 | 753 | ||
@@ -750,29 +758,63 @@ static void ar_context_tasklet(unsigned long data) | |||
750 | */ | 758 | */ |
751 | 759 | ||
752 | offset = offsetof(struct ar_buffer, data); | 760 | offset = offsetof(struct ar_buffer, data); |
753 | start = buffer = ab; | 761 | start = ab; |
754 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; | 762 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; |
763 | buffer = ab->data; | ||
755 | 764 | ||
756 | ab = ab->next; | 765 | ab = ab->next; |
757 | d = &ab->descriptor; | 766 | d = &ab->descriptor; |
758 | size = buffer + PAGE_SIZE - ctx->pointer; | 767 | size = start + PAGE_SIZE - ctx->pointer; |
768 | /* valid buffer data in the next page */ | ||
759 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); | 769 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); |
770 | /* what actually fits in this page */ | ||
771 | size2 = min(rest, (size_t)PAGE_SIZE - offset - size); | ||
760 | memmove(buffer, ctx->pointer, size); | 772 | memmove(buffer, ctx->pointer, size); |
761 | memcpy(buffer + size, ab->data, rest); | 773 | memcpy(buffer + size, ab->data, size2); |
762 | ctx->current_buffer = ab; | 774 | |
763 | ctx->pointer = (void *) ab->data + rest; | 775 | while (size > 0) { |
764 | end = buffer + size + rest; | 776 | void *next = handle_ar_packet(ctx, buffer); |
777 | pktsize = next - buffer; | ||
778 | if (pktsize >= size) { | ||
779 | /* | ||
780 | * We have handled all the data that was | ||
781 | * originally in this page, so we can now | ||
782 | * continue in the next page. | ||
783 | */ | ||
784 | buffer = next; | ||
785 | break; | ||
786 | } | ||
787 | /* move the next packet to the start of the buffer */ | ||
788 | memmove(buffer, next, size + size2 - pktsize); | ||
789 | size -= pktsize; | ||
790 | /* fill up this page again */ | ||
791 | size3 = min(rest - size2, | ||
792 | (size_t)PAGE_SIZE - offset - size - size2); | ||
793 | memcpy(buffer + size + size2, | ||
794 | (void *) ab->data + size2, size3); | ||
795 | size2 += size3; | ||
796 | } | ||
765 | 797 | ||
766 | while (buffer < end) | 798 | if (rest > 0) { |
767 | buffer = handle_ar_packet(ctx, buffer); | 799 | /* handle the packets that are fully in the next page */ |
800 | buffer = (void *) ab->data + | ||
801 | (buffer - (start + offset + size)); | ||
802 | end = (void *) ab->data + rest; | ||
803 | |||
804 | while (buffer < end) | ||
805 | buffer = handle_ar_packet(ctx, buffer); | ||
768 | 806 | ||
769 | dma_free_coherent(ohci->card.device, PAGE_SIZE, | 807 | ctx->current_buffer = ab; |
770 | start, start_bus); | 808 | ctx->pointer = end; |
771 | ar_context_add_page(ctx); | 809 | |
810 | ar_context_link_page(ctx, start, start_bus); | ||
811 | } else { | ||
812 | ctx->pointer = start + PAGE_SIZE; | ||
813 | } | ||
772 | } else { | 814 | } else { |
773 | buffer = ctx->pointer; | 815 | buffer = ctx->pointer; |
774 | ctx->pointer = end = | 816 | ctx->pointer = end = |
775 | (void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count); | 817 | (void *) ab + PAGE_SIZE - le16_to_cpu(res_count); |
776 | 818 | ||
777 | while (buffer < end) | 819 | while (buffer < end) |
778 | buffer = handle_ar_packet(ctx, buffer); | 820 | buffer = handle_ar_packet(ctx, buffer); |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index dcbeb98f195a..f7af91cb273d 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -276,7 +276,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, | |||
276 | struct drm_crtc *tmp; | 276 | struct drm_crtc *tmp; |
277 | int crtc_mask = 1; | 277 | int crtc_mask = 1; |
278 | 278 | ||
279 | WARN(!crtc, "checking null crtc?"); | 279 | WARN(!crtc, "checking null crtc?\n"); |
280 | 280 | ||
281 | dev = crtc->dev; | 281 | dev = crtc->dev; |
282 | 282 | ||
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c1a26217a530..a245d17165ae 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -240,7 +240,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, | |||
240 | .addr = DDC_ADDR, | 240 | .addr = DDC_ADDR, |
241 | .flags = I2C_M_RD, | 241 | .flags = I2C_M_RD, |
242 | .len = len, | 242 | .len = len, |
243 | .buf = buf + start, | 243 | .buf = buf, |
244 | } | 244 | } |
245 | }; | 245 | }; |
246 | 246 | ||
@@ -253,7 +253,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, | |||
253 | static u8 * | 253 | static u8 * |
254 | drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | 254 | drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) |
255 | { | 255 | { |
256 | int i, j = 0; | 256 | int i, j = 0, valid_extensions = 0; |
257 | u8 *block, *new; | 257 | u8 *block, *new; |
258 | 258 | ||
259 | if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) | 259 | if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) |
@@ -280,14 +280,28 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | |||
280 | 280 | ||
281 | for (j = 1; j <= block[0x7e]; j++) { | 281 | for (j = 1; j <= block[0x7e]; j++) { |
282 | for (i = 0; i < 4; i++) { | 282 | for (i = 0; i < 4; i++) { |
283 | if (drm_do_probe_ddc_edid(adapter, block, j, | 283 | if (drm_do_probe_ddc_edid(adapter, |
284 | EDID_LENGTH)) | 284 | block + (valid_extensions + 1) * EDID_LENGTH, |
285 | j, EDID_LENGTH)) | ||
285 | goto out; | 286 | goto out; |
286 | if (drm_edid_block_valid(block + j * EDID_LENGTH)) | 287 | if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { |
288 | valid_extensions++; | ||
287 | break; | 289 | break; |
290 | } | ||
288 | } | 291 | } |
289 | if (i == 4) | 292 | if (i == 4) |
290 | goto carp; | 293 | dev_warn(connector->dev->dev, |
294 | "%s: Ignoring invalid EDID block %d.\n", | ||
295 | drm_get_connector_name(connector), j); | ||
296 | } | ||
297 | |||
298 | if (valid_extensions != block[0x7e]) { | ||
299 | block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; | ||
300 | block[0x7e] = valid_extensions; | ||
301 | new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); | ||
302 | if (!new) | ||
303 | goto out; | ||
304 | block = new; | ||
291 | } | 305 | } |
292 | 306 | ||
293 | return block; | 307 | return block; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3467dd420760..80745f85902c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -44,7 +44,7 @@ unsigned int i915_fbpercrtc = 0; | |||
44 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); | 44 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); |
45 | 45 | ||
46 | unsigned int i915_powersave = 1; | 46 | unsigned int i915_powersave = 1; |
47 | module_param_named(powersave, i915_powersave, int, 0400); | 47 | module_param_named(powersave, i915_powersave, int, 0600); |
48 | 48 | ||
49 | unsigned int i915_lvds_downclock = 0; | 49 | unsigned int i915_lvds_downclock = 0; |
50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); | 50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2c2c19b6285e..90414ae86afc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1321,6 +1321,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, | |||
1321 | 1321 | ||
1322 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) | 1322 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) |
1323 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | 1323 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) |
1324 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) | ||
1324 | 1325 | ||
1325 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 1326 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
1326 | 1327 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8eb8453208b5..ef188e391406 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2172,7 +2172,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2172 | static int i915_ring_idle(struct drm_device *dev, | 2172 | static int i915_ring_idle(struct drm_device *dev, |
2173 | struct intel_ring_buffer *ring) | 2173 | struct intel_ring_buffer *ring) |
2174 | { | 2174 | { |
2175 | if (list_empty(&ring->gpu_write_list)) | 2175 | if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) |
2176 | return 0; | 2176 | return 0; |
2177 | 2177 | ||
2178 | i915_gem_flush_ring(dev, NULL, ring, | 2178 | i915_gem_flush_ring(dev, NULL, ring, |
@@ -2190,9 +2190,7 @@ i915_gpu_idle(struct drm_device *dev) | |||
2190 | int ret; | 2190 | int ret; |
2191 | 2191 | ||
2192 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && | 2192 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && |
2193 | list_empty(&dev_priv->render_ring.active_list) && | 2193 | list_empty(&dev_priv->mm.active_list)); |
2194 | list_empty(&dev_priv->bsd_ring.active_list) && | ||
2195 | list_empty(&dev_priv->blt_ring.active_list)); | ||
2196 | if (lists_empty) | 2194 | if (lists_empty) |
2197 | return 0; | 2195 | return 0; |
2198 | 2196 | ||
@@ -3108,7 +3106,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, | |||
3108 | * write domain | 3106 | * write domain |
3109 | */ | 3107 | */ |
3110 | if (obj->write_domain && | 3108 | if (obj->write_domain && |
3111 | obj->write_domain != obj->pending_read_domains) { | 3109 | (obj->write_domain != obj->pending_read_domains || |
3110 | obj_priv->ring != ring)) { | ||
3112 | flush_domains |= obj->write_domain; | 3111 | flush_domains |= obj->write_domain; |
3113 | invalidate_domains |= | 3112 | invalidate_domains |= |
3114 | obj->pending_read_domains & ~obj->write_domain; | 3113 | obj->pending_read_domains & ~obj->write_domain; |
@@ -3497,6 +3496,52 @@ i915_gem_execbuffer_pin(struct drm_device *dev, | |||
3497 | return 0; | 3496 | return 0; |
3498 | } | 3497 | } |
3499 | 3498 | ||
3499 | static int | ||
3500 | i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, | ||
3501 | struct drm_file *file, | ||
3502 | struct intel_ring_buffer *ring, | ||
3503 | struct drm_gem_object **objects, | ||
3504 | int count) | ||
3505 | { | ||
3506 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3507 | int ret, i; | ||
3508 | |||
3509 | /* Zero the global flush/invalidate flags. These | ||
3510 | * will be modified as new domains are computed | ||
3511 | * for each object | ||
3512 | */ | ||
3513 | dev->invalidate_domains = 0; | ||
3514 | dev->flush_domains = 0; | ||
3515 | dev_priv->mm.flush_rings = 0; | ||
3516 | for (i = 0; i < count; i++) | ||
3517 | i915_gem_object_set_to_gpu_domain(objects[i], ring); | ||
3518 | |||
3519 | if (dev->invalidate_domains | dev->flush_domains) { | ||
3520 | #if WATCH_EXEC | ||
3521 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
3522 | __func__, | ||
3523 | dev->invalidate_domains, | ||
3524 | dev->flush_domains); | ||
3525 | #endif | ||
3526 | i915_gem_flush(dev, file, | ||
3527 | dev->invalidate_domains, | ||
3528 | dev->flush_domains, | ||
3529 | dev_priv->mm.flush_rings); | ||
3530 | } | ||
3531 | |||
3532 | for (i = 0; i < count; i++) { | ||
3533 | struct drm_i915_gem_object *obj = to_intel_bo(objects[i]); | ||
3534 | /* XXX replace with semaphores */ | ||
3535 | if (obj->ring && ring != obj->ring) { | ||
3536 | ret = i915_gem_object_wait_rendering(&obj->base, true); | ||
3537 | if (ret) | ||
3538 | return ret; | ||
3539 | } | ||
3540 | } | ||
3541 | |||
3542 | return 0; | ||
3543 | } | ||
3544 | |||
3500 | /* Throttle our rendering by waiting until the ring has completed our requests | 3545 | /* Throttle our rendering by waiting until the ring has completed our requests |
3501 | * emitted over 20 msec ago. | 3546 | * emitted over 20 msec ago. |
3502 | * | 3547 | * |
@@ -3757,33 +3802,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3757 | goto err; | 3802 | goto err; |
3758 | } | 3803 | } |
3759 | 3804 | ||
3760 | /* Zero the global flush/invalidate flags. These | 3805 | ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, |
3761 | * will be modified as new domains are computed | 3806 | object_list, args->buffer_count); |
3762 | * for each object | 3807 | if (ret) |
3763 | */ | 3808 | goto err; |
3764 | dev->invalidate_domains = 0; | ||
3765 | dev->flush_domains = 0; | ||
3766 | dev_priv->mm.flush_rings = 0; | ||
3767 | |||
3768 | for (i = 0; i < args->buffer_count; i++) { | ||
3769 | struct drm_gem_object *obj = object_list[i]; | ||
3770 | |||
3771 | /* Compute new gpu domains and update invalidate/flush */ | ||
3772 | i915_gem_object_set_to_gpu_domain(obj, ring); | ||
3773 | } | ||
3774 | |||
3775 | if (dev->invalidate_domains | dev->flush_domains) { | ||
3776 | #if WATCH_EXEC | ||
3777 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
3778 | __func__, | ||
3779 | dev->invalidate_domains, | ||
3780 | dev->flush_domains); | ||
3781 | #endif | ||
3782 | i915_gem_flush(dev, file, | ||
3783 | dev->invalidate_domains, | ||
3784 | dev->flush_domains, | ||
3785 | dev_priv->mm.flush_rings); | ||
3786 | } | ||
3787 | 3809 | ||
3788 | for (i = 0; i < args->buffer_count; i++) { | 3810 | for (i = 0; i < args->buffer_count; i++) { |
3789 | struct drm_gem_object *obj = object_list[i]; | 3811 | struct drm_gem_object *obj = object_list[i]; |
@@ -4043,8 +4065,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4043 | alignment = i915_gem_get_gtt_alignment(obj); | 4065 | alignment = i915_gem_get_gtt_alignment(obj); |
4044 | if (obj_priv->gtt_offset & (alignment - 1)) { | 4066 | if (obj_priv->gtt_offset & (alignment - 1)) { |
4045 | WARN(obj_priv->pin_count, | 4067 | WARN(obj_priv->pin_count, |
4046 | "bo is already pinned with incorrect alignment:" | 4068 | "bo is already pinned with incorrect alignment: offset=%x, req.alignment=%x\n", |
4047 | " offset=%x, req.alignment=%x\n", | ||
4048 | obj_priv->gtt_offset, alignment); | 4069 | obj_priv->gtt_offset, alignment); |
4049 | ret = i915_gem_object_unbind(obj); | 4070 | ret = i915_gem_object_unbind(obj); |
4050 | if (ret) | 4071 | if (ret) |
@@ -4856,17 +4877,24 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
4856 | struct drm_file *file_priv) | 4877 | struct drm_file *file_priv) |
4857 | { | 4878 | { |
4858 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 4879 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4859 | void *obj_addr; | 4880 | void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset; |
4860 | int ret; | 4881 | char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; |
4861 | char __user *user_data; | ||
4862 | 4882 | ||
4863 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 4883 | DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size); |
4864 | obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; | ||
4865 | 4884 | ||
4866 | DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size); | 4885 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { |
4867 | ret = copy_from_user(obj_addr, user_data, args->size); | 4886 | unsigned long unwritten; |
4868 | if (ret) | 4887 | |
4869 | return -EFAULT; | 4888 | /* The physical object once assigned is fixed for the lifetime |
4889 | * of the obj, so we can safely drop the lock and continue | ||
4890 | * to access vaddr. | ||
4891 | */ | ||
4892 | mutex_unlock(&dev->struct_mutex); | ||
4893 | unwritten = copy_from_user(vaddr, user_data, args->size); | ||
4894 | mutex_lock(&dev->struct_mutex); | ||
4895 | if (unwritten) | ||
4896 | return -EFAULT; | ||
4897 | } | ||
4870 | 4898 | ||
4871 | drm_agp_chipset_flush(dev); | 4899 | drm_agp_chipset_flush(dev); |
4872 | return 0; | 4900 | return 0; |
@@ -4900,9 +4928,7 @@ i915_gpu_is_active(struct drm_device *dev) | |||
4900 | int lists_empty; | 4928 | int lists_empty; |
4901 | 4929 | ||
4902 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && | 4930 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && |
4903 | list_empty(&dev_priv->render_ring.active_list) && | 4931 | list_empty(&dev_priv->mm.active_list); |
4904 | list_empty(&dev_priv->bsd_ring.active_list) && | ||
4905 | list_empty(&dev_priv->blt_ring.active_list); | ||
4906 | 4932 | ||
4907 | return !lists_empty; | 4933 | return !lists_empty; |
4908 | } | 4934 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 43a4013f53fa..d8ae7d1d0cc6 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -165,9 +165,7 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
165 | 165 | ||
166 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | 166 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
167 | list_empty(&dev_priv->mm.flushing_list) && | 167 | list_empty(&dev_priv->mm.flushing_list) && |
168 | list_empty(&dev_priv->render_ring.active_list) && | 168 | list_empty(&dev_priv->mm.active_list)); |
169 | list_empty(&dev_priv->bsd_ring.active_list) && | ||
170 | list_empty(&dev_priv->blt_ring.active_list)); | ||
171 | if (lists_empty) | 169 | if (lists_empty) |
172 | return -ENOSPC; | 170 | return -ENOSPC; |
173 | 171 | ||
@@ -184,9 +182,7 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
184 | 182 | ||
185 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | 183 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
186 | list_empty(&dev_priv->mm.flushing_list) && | 184 | list_empty(&dev_priv->mm.flushing_list) && |
187 | list_empty(&dev_priv->render_ring.active_list) && | 185 | list_empty(&dev_priv->mm.active_list)); |
188 | list_empty(&dev_priv->bsd_ring.active_list) && | ||
189 | list_empty(&dev_priv->blt_ring.active_list)); | ||
190 | BUG_ON(!lists_empty); | 186 | BUG_ON(!lists_empty); |
191 | 187 | ||
192 | return 0; | 188 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 989c19d2d959..454c064f8ef7 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -862,8 +862,10 @@ int i915_restore_state(struct drm_device *dev) | |||
862 | /* Clock gating state */ | 862 | /* Clock gating state */ |
863 | intel_init_clock_gating(dev); | 863 | intel_init_clock_gating(dev); |
864 | 864 | ||
865 | if (HAS_PCH_SPLIT(dev)) | 865 | if (HAS_PCH_SPLIT(dev)) { |
866 | ironlake_enable_drps(dev); | 866 | ironlake_enable_drps(dev); |
867 | intel_init_emon(dev); | ||
868 | } | ||
867 | 869 | ||
868 | /* Cache mode state */ | 870 | /* Cache mode state */ |
869 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | 871 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 990f065374b2..48d8fd686ea9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1681,6 +1681,37 @@ static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) | |||
1681 | udelay(500); | 1681 | udelay(500); |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static void intel_fdi_normal_train(struct drm_crtc *crtc) | ||
1685 | { | ||
1686 | struct drm_device *dev = crtc->dev; | ||
1687 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1688 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1689 | int pipe = intel_crtc->pipe; | ||
1690 | u32 reg, temp; | ||
1691 | |||
1692 | /* enable normal train */ | ||
1693 | reg = FDI_TX_CTL(pipe); | ||
1694 | temp = I915_READ(reg); | ||
1695 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1696 | temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; | ||
1697 | I915_WRITE(reg, temp); | ||
1698 | |||
1699 | reg = FDI_RX_CTL(pipe); | ||
1700 | temp = I915_READ(reg); | ||
1701 | if (HAS_PCH_CPT(dev)) { | ||
1702 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
1703 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; | ||
1704 | } else { | ||
1705 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1706 | temp |= FDI_LINK_TRAIN_NONE; | ||
1707 | } | ||
1708 | I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); | ||
1709 | |||
1710 | /* wait one idle pattern time */ | ||
1711 | POSTING_READ(reg); | ||
1712 | udelay(1000); | ||
1713 | } | ||
1714 | |||
1684 | /* The FDI link training functions for ILK/Ibexpeak. */ | 1715 | /* The FDI link training functions for ILK/Ibexpeak. */ |
1685 | static void ironlake_fdi_link_train(struct drm_crtc *crtc) | 1716 | static void ironlake_fdi_link_train(struct drm_crtc *crtc) |
1686 | { | 1717 | { |
@@ -1767,27 +1798,6 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1767 | 1798 | ||
1768 | DRM_DEBUG_KMS("FDI train done\n"); | 1799 | DRM_DEBUG_KMS("FDI train done\n"); |
1769 | 1800 | ||
1770 | /* enable normal train */ | ||
1771 | reg = FDI_TX_CTL(pipe); | ||
1772 | temp = I915_READ(reg); | ||
1773 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1774 | temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; | ||
1775 | I915_WRITE(reg, temp); | ||
1776 | |||
1777 | reg = FDI_RX_CTL(pipe); | ||
1778 | temp = I915_READ(reg); | ||
1779 | if (HAS_PCH_CPT(dev)) { | ||
1780 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
1781 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; | ||
1782 | } else { | ||
1783 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1784 | temp |= FDI_LINK_TRAIN_NONE; | ||
1785 | } | ||
1786 | I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); | ||
1787 | |||
1788 | /* wait one idle pattern time */ | ||
1789 | POSTING_READ(reg); | ||
1790 | udelay(1000); | ||
1791 | } | 1801 | } |
1792 | 1802 | ||
1793 | static const int const snb_b_fdi_train_param [] = { | 1803 | static const int const snb_b_fdi_train_param [] = { |
@@ -2090,6 +2100,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
2090 | I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); | 2100 | I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); |
2091 | I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); | 2101 | I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); |
2092 | 2102 | ||
2103 | intel_fdi_normal_train(crtc); | ||
2104 | |||
2093 | /* For PCH DP, enable TRANS_DP_CTL */ | 2105 | /* For PCH DP, enable TRANS_DP_CTL */ |
2094 | if (HAS_PCH_CPT(dev) && | 2106 | if (HAS_PCH_CPT(dev) && |
2095 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | 2107 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
@@ -2200,9 +2212,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
2200 | udelay(100); | 2212 | udelay(100); |
2201 | 2213 | ||
2202 | /* Ironlake workaround, disable clock pointer after downing FDI */ | 2214 | /* Ironlake workaround, disable clock pointer after downing FDI */ |
2203 | I915_WRITE(FDI_RX_CHICKEN(pipe), | 2215 | if (HAS_PCH_IBX(dev)) |
2204 | I915_READ(FDI_RX_CHICKEN(pipe) & | 2216 | I915_WRITE(FDI_RX_CHICKEN(pipe), |
2205 | ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); | 2217 | I915_READ(FDI_RX_CHICKEN(pipe) & |
2218 | ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); | ||
2206 | 2219 | ||
2207 | /* still set train pattern 1 */ | 2220 | /* still set train pattern 1 */ |
2208 | reg = FDI_TX_CTL(pipe); | 2221 | reg = FDI_TX_CTL(pipe); |
@@ -5581,20 +5594,19 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5581 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); | 5594 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
5582 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> | 5595 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
5583 | MEMMODE_FSTART_SHIFT; | 5596 | MEMMODE_FSTART_SHIFT; |
5584 | fstart = fmax; | ||
5585 | 5597 | ||
5586 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> | 5598 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> |
5587 | PXVFREQ_PX_SHIFT; | 5599 | PXVFREQ_PX_SHIFT; |
5588 | 5600 | ||
5589 | dev_priv->fmax = fstart; /* IPS callback will increase this */ | 5601 | dev_priv->fmax = fmax; /* IPS callback will increase this */ |
5590 | dev_priv->fstart = fstart; | 5602 | dev_priv->fstart = fstart; |
5591 | 5603 | ||
5592 | dev_priv->max_delay = fmax; | 5604 | dev_priv->max_delay = fstart; |
5593 | dev_priv->min_delay = fmin; | 5605 | dev_priv->min_delay = fmin; |
5594 | dev_priv->cur_delay = fstart; | 5606 | dev_priv->cur_delay = fstart; |
5595 | 5607 | ||
5596 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, | 5608 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", |
5597 | fstart); | 5609 | fmax, fmin, fstart); |
5598 | 5610 | ||
5599 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); | 5611 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); |
5600 | 5612 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 891f4f1d63b1..c8e005553310 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1517,7 +1517,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
1517 | status = connector_status_connected; | 1517 | status = connector_status_connected; |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | return bit; | 1520 | return status; |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | /** | 1523 | /** |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9af9f86a8765..21551fe74541 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -296,6 +296,7 @@ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
296 | extern void intel_init_clock_gating(struct drm_device *dev); | 296 | extern void intel_init_clock_gating(struct drm_device *dev); |
297 | extern void ironlake_enable_drps(struct drm_device *dev); | 297 | extern void ironlake_enable_drps(struct drm_device *dev); |
298 | extern void ironlake_disable_drps(struct drm_device *dev); | 298 | extern void ironlake_disable_drps(struct drm_device *dev); |
299 | extern void intel_init_emon(struct drm_device *dev); | ||
299 | 300 | ||
300 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 301 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
301 | struct drm_gem_object *obj, | 302 | struct drm_gem_object *obj, |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f1a649990ea9..4324a326f98e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -481,11 +481,8 @@ static int intel_lvds_get_modes(struct drm_connector *connector) | |||
481 | struct drm_device *dev = connector->dev; | 481 | struct drm_device *dev = connector->dev; |
482 | struct drm_display_mode *mode; | 482 | struct drm_display_mode *mode; |
483 | 483 | ||
484 | if (intel_lvds->edid) { | 484 | if (intel_lvds->edid) |
485 | drm_mode_connector_update_edid_property(connector, | ||
486 | intel_lvds->edid); | ||
487 | return drm_add_edid_modes(connector, intel_lvds->edid); | 485 | return drm_add_edid_modes(connector, intel_lvds->edid); |
488 | } | ||
489 | 486 | ||
490 | mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); | 487 | mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); |
491 | if (mode == 0) | 488 | if (mode == 0) |
@@ -939,7 +936,16 @@ void intel_lvds_init(struct drm_device *dev) | |||
939 | */ | 936 | */ |
940 | intel_lvds->edid = drm_get_edid(connector, | 937 | intel_lvds->edid = drm_get_edid(connector, |
941 | &dev_priv->gmbus[pin].adapter); | 938 | &dev_priv->gmbus[pin].adapter); |
942 | 939 | if (intel_lvds->edid) { | |
940 | if (drm_add_edid_modes(connector, | ||
941 | intel_lvds->edid)) { | ||
942 | drm_mode_connector_update_edid_property(connector, | ||
943 | intel_lvds->edid); | ||
944 | } else { | ||
945 | kfree(intel_lvds->edid); | ||
946 | intel_lvds->edid = NULL; | ||
947 | } | ||
948 | } | ||
943 | if (!intel_lvds->edid) { | 949 | if (!intel_lvds->edid) { |
944 | /* Didn't get an EDID, so | 950 | /* Didn't get an EDID, so |
945 | * Set wide sync ranges so we get all modes | 951 | * Set wide sync ranges so we get all modes |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 917c7dc3cd6b..9b0d9a867aea 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -512,6 +512,6 @@ int intel_opregion_setup(struct drm_device *dev) | |||
512 | return 0; | 512 | return 0; |
513 | 513 | ||
514 | err_out: | 514 | err_out: |
515 | iounmap(opregion->header); | 515 | iounmap(base); |
516 | return err; | 516 | return err; |
517 | } | 517 | } |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index afb96d25219a..02ff0a481f47 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -946,7 +946,9 @@ static int check_overlay_src(struct drm_device *dev, | |||
946 | { | 946 | { |
947 | int uv_hscale = uv_hsubsampling(rec->flags); | 947 | int uv_hscale = uv_hsubsampling(rec->flags); |
948 | int uv_vscale = uv_vsubsampling(rec->flags); | 948 | int uv_vscale = uv_vsubsampling(rec->flags); |
949 | u32 stride_mask, depth, tmp; | 949 | u32 stride_mask; |
950 | int depth; | ||
951 | u32 tmp; | ||
950 | 952 | ||
951 | /* check src dimensions */ | 953 | /* check src dimensions */ |
952 | if (IS_845G(dev) || IS_I830(dev)) { | 954 | if (IS_845G(dev) || IS_I830(dev)) { |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 09f2dc353ae2..b83306f9244b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -177,7 +177,7 @@ static int init_ring_common(struct drm_device *dev, | |||
177 | 177 | ||
178 | I915_WRITE_CTL(ring, | 178 | I915_WRITE_CTL(ring, |
179 | ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | 179 | ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) |
180 | | RING_NO_REPORT | RING_VALID); | 180 | | RING_REPORT_64K | RING_VALID); |
181 | 181 | ||
182 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 182 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
183 | /* If the head is still not zero, the ring is dead */ | 183 | /* If the head is still not zero, the ring is dead */ |
@@ -654,6 +654,10 @@ void intel_cleanup_ring_buffer(struct drm_device *dev, | |||
654 | i915_gem_object_unpin(ring->gem_object); | 654 | i915_gem_object_unpin(ring->gem_object); |
655 | drm_gem_object_unreference(ring->gem_object); | 655 | drm_gem_object_unreference(ring->gem_object); |
656 | ring->gem_object = NULL; | 656 | ring->gem_object = NULL; |
657 | |||
658 | if (ring->cleanup) | ||
659 | ring->cleanup(ring); | ||
660 | |||
657 | cleanup_status_page(dev, ring); | 661 | cleanup_status_page(dev, ring); |
658 | } | 662 | } |
659 | 663 | ||
@@ -688,6 +692,17 @@ int intel_wait_ring_buffer(struct drm_device *dev, | |||
688 | { | 692 | { |
689 | unsigned long end; | 693 | unsigned long end; |
690 | drm_i915_private_t *dev_priv = dev->dev_private; | 694 | drm_i915_private_t *dev_priv = dev->dev_private; |
695 | u32 head; | ||
696 | |||
697 | head = intel_read_status_page(ring, 4); | ||
698 | if (head) { | ||
699 | ring->head = head & HEAD_ADDR; | ||
700 | ring->space = ring->head - (ring->tail + 8); | ||
701 | if (ring->space < 0) | ||
702 | ring->space += ring->size; | ||
703 | if (ring->space >= n) | ||
704 | return 0; | ||
705 | } | ||
691 | 706 | ||
692 | trace_i915_ring_wait_begin (dev); | 707 | trace_i915_ring_wait_begin (dev); |
693 | end = jiffies + 3 * HZ; | 708 | end = jiffies + 3 * HZ; |
@@ -854,19 +869,125 @@ blt_ring_put_user_irq(struct drm_device *dev, | |||
854 | /* do nothing */ | 869 | /* do nothing */ |
855 | } | 870 | } |
856 | 871 | ||
872 | |||
873 | /* Workaround for some stepping of SNB, | ||
874 | * each time when BLT engine ring tail moved, | ||
875 | * the first command in the ring to be parsed | ||
876 | * should be MI_BATCH_BUFFER_START | ||
877 | */ | ||
878 | #define NEED_BLT_WORKAROUND(dev) \ | ||
879 | (IS_GEN6(dev) && (dev->pdev->revision < 8)) | ||
880 | |||
881 | static inline struct drm_i915_gem_object * | ||
882 | to_blt_workaround(struct intel_ring_buffer *ring) | ||
883 | { | ||
884 | return ring->private; | ||
885 | } | ||
886 | |||
887 | static int blt_ring_init(struct drm_device *dev, | ||
888 | struct intel_ring_buffer *ring) | ||
889 | { | ||
890 | if (NEED_BLT_WORKAROUND(dev)) { | ||
891 | struct drm_i915_gem_object *obj; | ||
892 | u32 __iomem *ptr; | ||
893 | int ret; | ||
894 | |||
895 | obj = to_intel_bo(i915_gem_alloc_object(dev, 4096)); | ||
896 | if (obj == NULL) | ||
897 | return -ENOMEM; | ||
898 | |||
899 | ret = i915_gem_object_pin(&obj->base, 4096); | ||
900 | if (ret) { | ||
901 | drm_gem_object_unreference(&obj->base); | ||
902 | return ret; | ||
903 | } | ||
904 | |||
905 | ptr = kmap(obj->pages[0]); | ||
906 | iowrite32(MI_BATCH_BUFFER_END, ptr); | ||
907 | iowrite32(MI_NOOP, ptr+1); | ||
908 | kunmap(obj->pages[0]); | ||
909 | |||
910 | ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); | ||
911 | if (ret) { | ||
912 | i915_gem_object_unpin(&obj->base); | ||
913 | drm_gem_object_unreference(&obj->base); | ||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | ring->private = obj; | ||
918 | } | ||
919 | |||
920 | return init_ring_common(dev, ring); | ||
921 | } | ||
922 | |||
923 | static void blt_ring_begin(struct drm_device *dev, | ||
924 | struct intel_ring_buffer *ring, | ||
925 | int num_dwords) | ||
926 | { | ||
927 | if (ring->private) { | ||
928 | intel_ring_begin(dev, ring, num_dwords+2); | ||
929 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START); | ||
930 | intel_ring_emit(dev, ring, to_blt_workaround(ring)->gtt_offset); | ||
931 | } else | ||
932 | intel_ring_begin(dev, ring, 4); | ||
933 | } | ||
934 | |||
935 | static void blt_ring_flush(struct drm_device *dev, | ||
936 | struct intel_ring_buffer *ring, | ||
937 | u32 invalidate_domains, | ||
938 | u32 flush_domains) | ||
939 | { | ||
940 | blt_ring_begin(dev, ring, 4); | ||
941 | intel_ring_emit(dev, ring, MI_FLUSH_DW); | ||
942 | intel_ring_emit(dev, ring, 0); | ||
943 | intel_ring_emit(dev, ring, 0); | ||
944 | intel_ring_emit(dev, ring, 0); | ||
945 | intel_ring_advance(dev, ring); | ||
946 | } | ||
947 | |||
948 | static u32 | ||
949 | blt_ring_add_request(struct drm_device *dev, | ||
950 | struct intel_ring_buffer *ring, | ||
951 | u32 flush_domains) | ||
952 | { | ||
953 | u32 seqno = i915_gem_get_seqno(dev); | ||
954 | |||
955 | blt_ring_begin(dev, ring, 4); | ||
956 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | ||
957 | intel_ring_emit(dev, ring, | ||
958 | I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
959 | intel_ring_emit(dev, ring, seqno); | ||
960 | intel_ring_emit(dev, ring, MI_USER_INTERRUPT); | ||
961 | intel_ring_advance(dev, ring); | ||
962 | |||
963 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); | ||
964 | return seqno; | ||
965 | } | ||
966 | |||
967 | static void blt_ring_cleanup(struct intel_ring_buffer *ring) | ||
968 | { | ||
969 | if (!ring->private) | ||
970 | return; | ||
971 | |||
972 | i915_gem_object_unpin(ring->private); | ||
973 | drm_gem_object_unreference(ring->private); | ||
974 | ring->private = NULL; | ||
975 | } | ||
976 | |||
857 | static const struct intel_ring_buffer gen6_blt_ring = { | 977 | static const struct intel_ring_buffer gen6_blt_ring = { |
858 | .name = "blt ring", | 978 | .name = "blt ring", |
859 | .id = RING_BLT, | 979 | .id = RING_BLT, |
860 | .mmio_base = BLT_RING_BASE, | 980 | .mmio_base = BLT_RING_BASE, |
861 | .size = 32 * PAGE_SIZE, | 981 | .size = 32 * PAGE_SIZE, |
862 | .init = init_ring_common, | 982 | .init = blt_ring_init, |
863 | .write_tail = ring_write_tail, | 983 | .write_tail = ring_write_tail, |
864 | .flush = gen6_ring_flush, | 984 | .flush = blt_ring_flush, |
865 | .add_request = ring_add_request, | 985 | .add_request = blt_ring_add_request, |
866 | .get_seqno = ring_status_page_get_seqno, | 986 | .get_seqno = ring_status_page_get_seqno, |
867 | .user_irq_get = blt_ring_get_user_irq, | 987 | .user_irq_get = blt_ring_get_user_irq, |
868 | .user_irq_put = blt_ring_put_user_irq, | 988 | .user_irq_put = blt_ring_put_user_irq, |
869 | .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, | 989 | .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, |
990 | .cleanup = blt_ring_cleanup, | ||
870 | }; | 991 | }; |
871 | 992 | ||
872 | int intel_init_render_ring_buffer(struct drm_device *dev) | 993 | int intel_init_render_ring_buffer(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index a05aff0e5764..3126c2681983 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -63,6 +63,7 @@ struct intel_ring_buffer { | |||
63 | struct drm_i915_gem_execbuffer2 *exec, | 63 | struct drm_i915_gem_execbuffer2 *exec, |
64 | struct drm_clip_rect *cliprects, | 64 | struct drm_clip_rect *cliprects, |
65 | uint64_t exec_offset); | 65 | uint64_t exec_offset); |
66 | void (*cleanup)(struct intel_ring_buffer *ring); | ||
66 | 67 | ||
67 | /** | 68 | /** |
68 | * List of objects currently involved in rendering from the | 69 | * List of objects currently involved in rendering from the |
@@ -98,6 +99,8 @@ struct intel_ring_buffer { | |||
98 | 99 | ||
99 | wait_queue_head_t irq_queue; | 100 | wait_queue_head_t irq_queue; |
100 | drm_local_map_t map; | 101 | drm_local_map_t map; |
102 | |||
103 | void *private; | ||
101 | }; | 104 | }; |
102 | 105 | ||
103 | static inline u32 | 106 | static inline u32 |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f12a5b3ec050..488c36c8f5e6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2033,7 +2033,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2033 | u32 grbm_int_cntl = 0; | 2033 | u32 grbm_int_cntl = 0; |
2034 | 2034 | ||
2035 | if (!rdev->irq.installed) { | 2035 | if (!rdev->irq.installed) { |
2036 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 2036 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
2037 | return -EINVAL; | 2037 | return -EINVAL; |
2038 | } | 2038 | } |
2039 | /* don't enable anything if the ih is disabled */ | 2039 | /* don't enable anything if the ih is disabled */ |
@@ -2295,6 +2295,7 @@ restart_ih: | |||
2295 | case 0: /* D1 vblank */ | 2295 | case 0: /* D1 vblank */ |
2296 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | 2296 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { |
2297 | drm_handle_vblank(rdev->ddev, 0); | 2297 | drm_handle_vblank(rdev->ddev, 0); |
2298 | rdev->pm.vblank_sync = true; | ||
2298 | wake_up(&rdev->irq.vblank_queue); | 2299 | wake_up(&rdev->irq.vblank_queue); |
2299 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 2300 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; |
2300 | DRM_DEBUG("IH: D1 vblank\n"); | 2301 | DRM_DEBUG("IH: D1 vblank\n"); |
@@ -2316,6 +2317,7 @@ restart_ih: | |||
2316 | case 0: /* D2 vblank */ | 2317 | case 0: /* D2 vblank */ |
2317 | if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { | 2318 | if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { |
2318 | drm_handle_vblank(rdev->ddev, 1); | 2319 | drm_handle_vblank(rdev->ddev, 1); |
2320 | rdev->pm.vblank_sync = true; | ||
2319 | wake_up(&rdev->irq.vblank_queue); | 2321 | wake_up(&rdev->irq.vblank_queue); |
2320 | disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | 2322 | disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; |
2321 | DRM_DEBUG("IH: D2 vblank\n"); | 2323 | DRM_DEBUG("IH: D2 vblank\n"); |
@@ -2337,6 +2339,7 @@ restart_ih: | |||
2337 | case 0: /* D3 vblank */ | 2339 | case 0: /* D3 vblank */ |
2338 | if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { | 2340 | if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { |
2339 | drm_handle_vblank(rdev->ddev, 2); | 2341 | drm_handle_vblank(rdev->ddev, 2); |
2342 | rdev->pm.vblank_sync = true; | ||
2340 | wake_up(&rdev->irq.vblank_queue); | 2343 | wake_up(&rdev->irq.vblank_queue); |
2341 | disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | 2344 | disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; |
2342 | DRM_DEBUG("IH: D3 vblank\n"); | 2345 | DRM_DEBUG("IH: D3 vblank\n"); |
@@ -2358,6 +2361,7 @@ restart_ih: | |||
2358 | case 0: /* D4 vblank */ | 2361 | case 0: /* D4 vblank */ |
2359 | if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { | 2362 | if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { |
2360 | drm_handle_vblank(rdev->ddev, 3); | 2363 | drm_handle_vblank(rdev->ddev, 3); |
2364 | rdev->pm.vblank_sync = true; | ||
2361 | wake_up(&rdev->irq.vblank_queue); | 2365 | wake_up(&rdev->irq.vblank_queue); |
2362 | disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | 2366 | disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; |
2363 | DRM_DEBUG("IH: D4 vblank\n"); | 2367 | DRM_DEBUG("IH: D4 vblank\n"); |
@@ -2379,6 +2383,7 @@ restart_ih: | |||
2379 | case 0: /* D5 vblank */ | 2383 | case 0: /* D5 vblank */ |
2380 | if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { | 2384 | if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { |
2381 | drm_handle_vblank(rdev->ddev, 4); | 2385 | drm_handle_vblank(rdev->ddev, 4); |
2386 | rdev->pm.vblank_sync = true; | ||
2382 | wake_up(&rdev->irq.vblank_queue); | 2387 | wake_up(&rdev->irq.vblank_queue); |
2383 | disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | 2388 | disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; |
2384 | DRM_DEBUG("IH: D5 vblank\n"); | 2389 | DRM_DEBUG("IH: D5 vblank\n"); |
@@ -2400,6 +2405,7 @@ restart_ih: | |||
2400 | case 0: /* D6 vblank */ | 2405 | case 0: /* D6 vblank */ |
2401 | if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { | 2406 | if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { |
2402 | drm_handle_vblank(rdev->ddev, 5); | 2407 | drm_handle_vblank(rdev->ddev, 5); |
2408 | rdev->pm.vblank_sync = true; | ||
2403 | wake_up(&rdev->irq.vblank_queue); | 2409 | wake_up(&rdev->irq.vblank_queue); |
2404 | disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | 2410 | disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; |
2405 | DRM_DEBUG("IH: D6 vblank\n"); | 2411 | DRM_DEBUG("IH: D6 vblank\n"); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 0e8f28a68927..8e10aa9f74b0 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -442,7 +442,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) | |||
442 | int r; | 442 | int r; |
443 | 443 | ||
444 | if (rdev->gart.table.ram.ptr) { | 444 | if (rdev->gart.table.ram.ptr) { |
445 | WARN(1, "R100 PCI GART already initialized.\n"); | 445 | WARN(1, "R100 PCI GART already initialized\n"); |
446 | return 0; | 446 | return 0; |
447 | } | 447 | } |
448 | /* Initialize common gart structure */ | 448 | /* Initialize common gart structure */ |
@@ -516,7 +516,7 @@ int r100_irq_set(struct radeon_device *rdev) | |||
516 | uint32_t tmp = 0; | 516 | uint32_t tmp = 0; |
517 | 517 | ||
518 | if (!rdev->irq.installed) { | 518 | if (!rdev->irq.installed) { |
519 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 519 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
520 | WREG32(R_000040_GEN_INT_CNTL, 0); | 520 | WREG32(R_000040_GEN_INT_CNTL, 0); |
521 | return -EINVAL; | 521 | return -EINVAL; |
522 | } | 522 | } |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 34527e600fe9..cde1d3480d93 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -91,7 +91,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) | |||
91 | int r; | 91 | int r; |
92 | 92 | ||
93 | if (rdev->gart.table.vram.robj) { | 93 | if (rdev->gart.table.vram.robj) { |
94 | WARN(1, "RV370 PCIE GART already initialized.\n"); | 94 | WARN(1, "RV370 PCIE GART already initialized\n"); |
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
97 | /* Initialize common gart structure */ | 97 | /* Initialize common gart structure */ |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 33952a12f0a3..0f806cc7dc75 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -97,14 +97,8 @@ u32 rv6xx_get_temp(struct radeon_device *rdev) | |||
97 | { | 97 | { |
98 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> | 98 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> |
99 | ASIC_T_SHIFT; | 99 | ASIC_T_SHIFT; |
100 | u32 actual_temp = 0; | ||
101 | 100 | ||
102 | if ((temp >> 7) & 1) | 101 | return temp * 1000; |
103 | actual_temp = 0; | ||
104 | else | ||
105 | actual_temp = (temp >> 1) & 0xff; | ||
106 | |||
107 | return actual_temp * 1000; | ||
108 | } | 102 | } |
109 | 103 | ||
110 | void r600_pm_get_dynpm_state(struct radeon_device *rdev) | 104 | void r600_pm_get_dynpm_state(struct radeon_device *rdev) |
@@ -919,7 +913,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) | |||
919 | int r; | 913 | int r; |
920 | 914 | ||
921 | if (rdev->gart.table.vram.robj) { | 915 | if (rdev->gart.table.vram.robj) { |
922 | WARN(1, "R600 PCIE GART already initialized.\n"); | 916 | WARN(1, "R600 PCIE GART already initialized\n"); |
923 | return 0; | 917 | return 0; |
924 | } | 918 | } |
925 | /* Initialize common gart structure */ | 919 | /* Initialize common gart structure */ |
@@ -2995,7 +2989,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
2995 | u32 hdmi1, hdmi2; | 2989 | u32 hdmi1, hdmi2; |
2996 | 2990 | ||
2997 | if (!rdev->irq.installed) { | 2991 | if (!rdev->irq.installed) { |
2998 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 2992 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
2999 | return -EINVAL; | 2993 | return -EINVAL; |
3000 | } | 2994 | } |
3001 | /* don't enable anything if the ih is disabled */ | 2995 | /* don't enable anything if the ih is disabled */ |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 04cac7ec9039..87ead090c7d5 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -526,8 +526,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
526 | if (crev < 2) | 526 | if (crev < 2) |
527 | return false; | 527 | return false; |
528 | 528 | ||
529 | router.valid = false; | ||
530 | |||
531 | obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset); | 529 | obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset); |
532 | path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) | 530 | path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) |
533 | (ctx->bios + data_offset + | 531 | (ctx->bios + data_offset + |
@@ -624,6 +622,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
624 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 622 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
625 | continue; | 623 | continue; |
626 | 624 | ||
625 | router.ddc_valid = false; | ||
626 | router.cd_valid = false; | ||
627 | for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { | 627 | for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { |
628 | uint8_t grph_obj_id, grph_obj_num, grph_obj_type; | 628 | uint8_t grph_obj_id, grph_obj_num, grph_obj_type; |
629 | 629 | ||
@@ -647,9 +647,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
647 | usDeviceTag)); | 647 | usDeviceTag)); |
648 | 648 | ||
649 | } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { | 649 | } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { |
650 | router.valid = false; | ||
651 | for (k = 0; k < router_obj->ucNumberOfObjects; k++) { | 650 | for (k = 0; k < router_obj->ucNumberOfObjects; k++) { |
652 | u16 router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID); | 651 | u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); |
653 | if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) { | 652 | if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) { |
654 | ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) | 653 | ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) |
655 | (ctx->bios + data_offset + | 654 | (ctx->bios + data_offset + |
@@ -657,6 +656,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
657 | ATOM_I2C_RECORD *i2c_record; | 656 | ATOM_I2C_RECORD *i2c_record; |
658 | ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; | 657 | ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; |
659 | ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path; | 658 | ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path; |
659 | ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path; | ||
660 | ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = | 660 | ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = |
661 | (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) | 661 | (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) |
662 | (ctx->bios + data_offset + | 662 | (ctx->bios + data_offset + |
@@ -690,10 +690,18 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
690 | case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: | 690 | case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: |
691 | ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *) | 691 | ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *) |
692 | record; | 692 | record; |
693 | router.valid = true; | 693 | router.ddc_valid = true; |
694 | router.mux_type = ddc_path->ucMuxType; | 694 | router.ddc_mux_type = ddc_path->ucMuxType; |
695 | router.mux_control_pin = ddc_path->ucMuxControlPin; | 695 | router.ddc_mux_control_pin = ddc_path->ucMuxControlPin; |
696 | router.mux_state = ddc_path->ucMuxState[enum_id]; | 696 | router.ddc_mux_state = ddc_path->ucMuxState[enum_id]; |
697 | break; | ||
698 | case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE: | ||
699 | cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *) | ||
700 | record; | ||
701 | router.cd_valid = true; | ||
702 | router.cd_mux_type = cd_path->ucMuxType; | ||
703 | router.cd_mux_control_pin = cd_path->ucMuxControlPin; | ||
704 | router.cd_mux_state = cd_path->ucMuxState[enum_id]; | ||
697 | break; | 705 | break; |
698 | } | 706 | } |
699 | record = (ATOM_COMMON_RECORD_HEADER *) | 707 | record = (ATOM_COMMON_RECORD_HEADER *) |
@@ -860,7 +868,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
860 | size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; | 868 | size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; |
861 | struct radeon_router router; | 869 | struct radeon_router router; |
862 | 870 | ||
863 | router.valid = false; | 871 | router.ddc_valid = false; |
872 | router.cd_valid = false; | ||
864 | 873 | ||
865 | bios_connectors = kzalloc(bc_size, GFP_KERNEL); | 874 | bios_connectors = kzalloc(bc_size, GFP_KERNEL); |
866 | if (!bios_connectors) | 875 | if (!bios_connectors) |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 4dac4b0a02ee..fe6c74780f18 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -183,13 +183,13 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, | |||
183 | continue; | 183 | continue; |
184 | 184 | ||
185 | if (priority == true) { | 185 | if (priority == true) { |
186 | DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); | 186 | DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); |
187 | DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); | 187 | DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector)); |
188 | conflict->status = connector_status_disconnected; | 188 | conflict->status = connector_status_disconnected; |
189 | radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); | 189 | radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); |
190 | } else { | 190 | } else { |
191 | DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); | 191 | DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); |
192 | DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict)); | 192 | DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict)); |
193 | current_status = connector_status_disconnected; | 193 | current_status = connector_status_disconnected; |
194 | } | 194 | } |
195 | break; | 195 | break; |
@@ -432,13 +432,13 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | |||
432 | mode->vdisplay == native_mode->vdisplay) { | 432 | mode->vdisplay == native_mode->vdisplay) { |
433 | *native_mode = *mode; | 433 | *native_mode = *mode; |
434 | drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); | 434 | drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); |
435 | DRM_INFO("Determined LVDS native mode details from EDID\n"); | 435 | DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n"); |
436 | break; | 436 | break; |
437 | } | 437 | } |
438 | } | 438 | } |
439 | } | 439 | } |
440 | if (!native_mode->clock) { | 440 | if (!native_mode->clock) { |
441 | DRM_INFO("No LVDS native mode details, disabling RMX\n"); | 441 | DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); |
442 | radeon_encoder->rmx_type = RMX_OFF; | 442 | radeon_encoder->rmx_type = RMX_OFF; |
443 | } | 443 | } |
444 | } | 444 | } |
@@ -1116,7 +1116,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1116 | radeon_connector->shared_ddc = true; | 1116 | radeon_connector->shared_ddc = true; |
1117 | shared_ddc = true; | 1117 | shared_ddc = true; |
1118 | } | 1118 | } |
1119 | if (radeon_connector->router_bus && router->valid && | 1119 | if (radeon_connector->router_bus && router->ddc_valid && |
1120 | (radeon_connector->router.router_id == router->router_id)) { | 1120 | (radeon_connector->router.router_id == router->router_id)) { |
1121 | radeon_connector->shared_ddc = false; | 1121 | radeon_connector->shared_ddc = false; |
1122 | shared_ddc = false; | 1122 | shared_ddc = false; |
@@ -1136,7 +1136,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1136 | radeon_connector->connector_object_id = connector_object_id; | 1136 | radeon_connector->connector_object_id = connector_object_id; |
1137 | radeon_connector->hpd = *hpd; | 1137 | radeon_connector->hpd = *hpd; |
1138 | radeon_connector->router = *router; | 1138 | radeon_connector->router = *router; |
1139 | if (router->valid) { | 1139 | if (router->ddc_valid || router->cd_valid) { |
1140 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); | 1140 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
1141 | if (!radeon_connector->router_bus) | 1141 | if (!radeon_connector->router_bus) |
1142 | goto failed; | 1142 | goto failed; |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0383631da69c..1df4dc6c063c 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -315,10 +315,14 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
315 | radeon_connector->ddc_bus->rec.en_data_reg, | 315 | radeon_connector->ddc_bus->rec.en_data_reg, |
316 | radeon_connector->ddc_bus->rec.y_clk_reg, | 316 | radeon_connector->ddc_bus->rec.y_clk_reg, |
317 | radeon_connector->ddc_bus->rec.y_data_reg); | 317 | radeon_connector->ddc_bus->rec.y_data_reg); |
318 | if (radeon_connector->router_bus) | 318 | if (radeon_connector->router.ddc_valid) |
319 | DRM_INFO(" DDC Router 0x%x/0x%x\n", | 319 | DRM_INFO(" DDC Router 0x%x/0x%x\n", |
320 | radeon_connector->router.mux_control_pin, | 320 | radeon_connector->router.ddc_mux_control_pin, |
321 | radeon_connector->router.mux_state); | 321 | radeon_connector->router.ddc_mux_state); |
322 | if (radeon_connector->router.cd_valid) | ||
323 | DRM_INFO(" Clock/Data Router 0x%x/0x%x\n", | ||
324 | radeon_connector->router.cd_mux_control_pin, | ||
325 | radeon_connector->router.cd_mux_state); | ||
322 | } else { | 326 | } else { |
323 | if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || | 327 | if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || |
324 | connector->connector_type == DRM_MODE_CONNECTOR_DVII || | 328 | connector->connector_type == DRM_MODE_CONNECTOR_DVII || |
@@ -398,8 +402,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
398 | int ret = 0; | 402 | int ret = 0; |
399 | 403 | ||
400 | /* on hw with routers, select right port */ | 404 | /* on hw with routers, select right port */ |
401 | if (radeon_connector->router.valid) | 405 | if (radeon_connector->router.ddc_valid) |
402 | radeon_router_select_port(radeon_connector); | 406 | radeon_router_select_ddc_port(radeon_connector); |
403 | 407 | ||
404 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | 408 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
405 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { | 409 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { |
@@ -432,8 +436,8 @@ static int radeon_ddc_dump(struct drm_connector *connector) | |||
432 | int ret = 0; | 436 | int ret = 0; |
433 | 437 | ||
434 | /* on hw with routers, select right port */ | 438 | /* on hw with routers, select right port */ |
435 | if (radeon_connector->router.valid) | 439 | if (radeon_connector->router.ddc_valid) |
436 | radeon_router_select_port(radeon_connector); | 440 | radeon_router_select_ddc_port(radeon_connector); |
437 | 441 | ||
438 | if (!radeon_connector->ddc_bus) | 442 | if (!radeon_connector->ddc_bus) |
439 | return -1; | 443 | return -1; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index ae58b6849a2e..f678257c42e6 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -1520,6 +1520,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
1520 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | 1520 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) |
1521 | { | 1521 | { |
1522 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1522 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1523 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1523 | 1524 | ||
1524 | if (radeon_encoder->active_device & | 1525 | if (radeon_encoder->active_device & |
1525 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { | 1526 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { |
@@ -1531,6 +1532,13 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
1531 | radeon_atom_output_lock(encoder, true); | 1532 | radeon_atom_output_lock(encoder, true); |
1532 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1533 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1533 | 1534 | ||
1535 | /* select the clock/data port if it uses a router */ | ||
1536 | if (connector) { | ||
1537 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1538 | if (radeon_connector->router.cd_valid) | ||
1539 | radeon_router_select_cd_port(radeon_connector); | ||
1540 | } | ||
1541 | |||
1534 | /* this is needed for the pll/ss setup to work correctly in some cases */ | 1542 | /* this is needed for the pll/ss setup to work correctly in some cases */ |
1535 | atombios_set_encoder_crtc_source(encoder); | 1543 | atombios_set_encoder_crtc_source(encoder); |
1536 | } | 1544 | } |
@@ -1547,6 +1555,23 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
1547 | struct radeon_device *rdev = dev->dev_private; | 1555 | struct radeon_device *rdev = dev->dev_private; |
1548 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1556 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1549 | struct radeon_encoder_atom_dig *dig; | 1557 | struct radeon_encoder_atom_dig *dig; |
1558 | |||
1559 | /* check for pre-DCE3 cards with shared encoders; | ||
1560 | * can't really use the links individually, so don't disable | ||
1561 | * the encoder if it's in use by another connector | ||
1562 | */ | ||
1563 | if (!ASIC_IS_DCE3(rdev)) { | ||
1564 | struct drm_encoder *other_encoder; | ||
1565 | struct radeon_encoder *other_radeon_encoder; | ||
1566 | |||
1567 | list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { | ||
1568 | other_radeon_encoder = to_radeon_encoder(other_encoder); | ||
1569 | if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && | ||
1570 | drm_helper_encoder_in_use(other_encoder)) | ||
1571 | goto disable_done; | ||
1572 | } | ||
1573 | } | ||
1574 | |||
1550 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1575 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1551 | 1576 | ||
1552 | switch (radeon_encoder->encoder_id) { | 1577 | switch (radeon_encoder->encoder_id) { |
@@ -1586,6 +1611,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
1586 | break; | 1611 | break; |
1587 | } | 1612 | } |
1588 | 1613 | ||
1614 | disable_done: | ||
1589 | if (radeon_encoder_is_digital(encoder)) { | 1615 | if (radeon_encoder_is_digital(encoder)) { |
1590 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | 1616 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
1591 | r600_hdmi_disable(encoder); | 1617 | r600_hdmi_disable(encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 216392d0353b..daacb281dfaf 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -240,7 +240,8 @@ retry: | |||
240 | */ | 240 | */ |
241 | if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { | 241 | if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { |
242 | /* good news we believe it's a lockup */ | 242 | /* good news we believe it's a lockup */ |
243 | WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); | 243 | WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", |
244 | fence->seq, seq); | ||
244 | /* FIXME: what should we do ? marking everyone | 245 | /* FIXME: what should we do ? marking everyone |
245 | * as signaled for now | 246 | * as signaled for now |
246 | */ | 247 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 6a13ee38a5b9..0cfbba02c4d0 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -53,8 +53,8 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | |||
53 | }; | 53 | }; |
54 | 54 | ||
55 | /* on hw with routers, select right port */ | 55 | /* on hw with routers, select right port */ |
56 | if (radeon_connector->router.valid) | 56 | if (radeon_connector->router.ddc_valid) |
57 | radeon_router_select_port(radeon_connector); | 57 | radeon_router_select_ddc_port(radeon_connector); |
58 | 58 | ||
59 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); | 59 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); |
60 | if (ret == 2) | 60 | if (ret == 2) |
@@ -1084,26 +1084,51 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, | |||
1084 | addr, val); | 1084 | addr, val); |
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | /* router switching */ | 1087 | /* ddc router switching */ |
1088 | void radeon_router_select_port(struct radeon_connector *radeon_connector) | 1088 | void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) |
1089 | { | 1089 | { |
1090 | u8 val; | 1090 | u8 val; |
1091 | 1091 | ||
1092 | if (!radeon_connector->router.valid) | 1092 | if (!radeon_connector->router.ddc_valid) |
1093 | return; | 1093 | return; |
1094 | 1094 | ||
1095 | radeon_i2c_get_byte(radeon_connector->router_bus, | 1095 | radeon_i2c_get_byte(radeon_connector->router_bus, |
1096 | radeon_connector->router.i2c_addr, | 1096 | radeon_connector->router.i2c_addr, |
1097 | 0x3, &val); | 1097 | 0x3, &val); |
1098 | val &= radeon_connector->router.mux_control_pin; | 1098 | val &= ~radeon_connector->router.ddc_mux_control_pin; |
1099 | radeon_i2c_put_byte(radeon_connector->router_bus, | 1099 | radeon_i2c_put_byte(radeon_connector->router_bus, |
1100 | radeon_connector->router.i2c_addr, | 1100 | radeon_connector->router.i2c_addr, |
1101 | 0x3, val); | 1101 | 0x3, val); |
1102 | radeon_i2c_get_byte(radeon_connector->router_bus, | 1102 | radeon_i2c_get_byte(radeon_connector->router_bus, |
1103 | radeon_connector->router.i2c_addr, | 1103 | radeon_connector->router.i2c_addr, |
1104 | 0x1, &val); | 1104 | 0x1, &val); |
1105 | val &= radeon_connector->router.mux_control_pin; | 1105 | val &= ~radeon_connector->router.ddc_mux_control_pin; |
1106 | val |= radeon_connector->router.mux_state; | 1106 | val |= radeon_connector->router.ddc_mux_state; |
1107 | radeon_i2c_put_byte(radeon_connector->router_bus, | ||
1108 | radeon_connector->router.i2c_addr, | ||
1109 | 0x1, val); | ||
1110 | } | ||
1111 | |||
1112 | /* clock/data router switching */ | ||
1113 | void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) | ||
1114 | { | ||
1115 | u8 val; | ||
1116 | |||
1117 | if (!radeon_connector->router.cd_valid) | ||
1118 | return; | ||
1119 | |||
1120 | radeon_i2c_get_byte(radeon_connector->router_bus, | ||
1121 | radeon_connector->router.i2c_addr, | ||
1122 | 0x3, &val); | ||
1123 | val &= ~radeon_connector->router.cd_mux_control_pin; | ||
1124 | radeon_i2c_put_byte(radeon_connector->router_bus, | ||
1125 | radeon_connector->router.i2c_addr, | ||
1126 | 0x3, val); | ||
1127 | radeon_i2c_get_byte(radeon_connector->router_bus, | ||
1128 | radeon_connector->router.i2c_addr, | ||
1129 | 0x1, &val); | ||
1130 | val &= ~radeon_connector->router.cd_mux_control_pin; | ||
1131 | val |= radeon_connector->router.cd_mux_state; | ||
1107 | radeon_i2c_put_byte(radeon_connector->router_bus, | 1132 | radeon_i2c_put_byte(radeon_connector->router_bus, |
1108 | radeon_connector->router.i2c_addr, | 1133 | radeon_connector->router.i2c_addr, |
1109 | 0x1, val); | 1134 | 0x1, val); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 92457163d070..680f57644e86 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -401,13 +401,19 @@ struct radeon_hpd { | |||
401 | }; | 401 | }; |
402 | 402 | ||
403 | struct radeon_router { | 403 | struct radeon_router { |
404 | bool valid; | ||
405 | u32 router_id; | 404 | u32 router_id; |
406 | struct radeon_i2c_bus_rec i2c_info; | 405 | struct radeon_i2c_bus_rec i2c_info; |
407 | u8 i2c_addr; | 406 | u8 i2c_addr; |
408 | u8 mux_type; | 407 | /* i2c mux */ |
409 | u8 mux_control_pin; | 408 | bool ddc_valid; |
410 | u8 mux_state; | 409 | u8 ddc_mux_type; |
410 | u8 ddc_mux_control_pin; | ||
411 | u8 ddc_mux_state; | ||
412 | /* clock/data mux */ | ||
413 | bool cd_valid; | ||
414 | u8 cd_mux_type; | ||
415 | u8 cd_mux_control_pin; | ||
416 | u8 cd_mux_state; | ||
411 | }; | 417 | }; |
412 | 418 | ||
413 | struct radeon_connector { | 419 | struct radeon_connector { |
@@ -488,7 +494,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, | |||
488 | u8 slave_addr, | 494 | u8 slave_addr, |
489 | u8 addr, | 495 | u8 addr, |
490 | u8 val); | 496 | u8 val); |
491 | extern void radeon_router_select_port(struct radeon_connector *radeon_connector); | 497 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); |
498 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); | ||
492 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); | 499 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); |
493 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); | 500 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
494 | 501 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d7ab91416410..8eb183466015 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -102,6 +102,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
102 | type = ttm_bo_type_device; | 102 | type = ttm_bo_type_device; |
103 | } | 103 | } |
104 | *bo_ptr = NULL; | 104 | *bo_ptr = NULL; |
105 | |||
106 | retry: | ||
105 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 107 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
106 | if (bo == NULL) | 108 | if (bo == NULL) |
107 | return -ENOMEM; | 109 | return -ENOMEM; |
@@ -109,8 +111,6 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
109 | bo->gobj = gobj; | 111 | bo->gobj = gobj; |
110 | bo->surface_reg = -1; | 112 | bo->surface_reg = -1; |
111 | INIT_LIST_HEAD(&bo->list); | 113 | INIT_LIST_HEAD(&bo->list); |
112 | |||
113 | retry: | ||
114 | radeon_ttm_placement_from_domain(bo, domain); | 114 | radeon_ttm_placement_from_domain(bo, domain); |
115 | /* Kernel allocation are uninterruptible */ | 115 | /* Kernel allocation are uninterruptible */ |
116 | mutex_lock(&rdev->vram_mutex); | 116 | mutex_lock(&rdev->vram_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index fe95bb35317e..01c2c736a1da 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -689,7 +689,8 @@ static int radeon_ttm_backend_bind(struct ttm_backend *backend, | |||
689 | gtt = container_of(backend, struct radeon_ttm_backend, backend); | 689 | gtt = container_of(backend, struct radeon_ttm_backend, backend); |
690 | gtt->offset = bo_mem->start << PAGE_SHIFT; | 690 | gtt->offset = bo_mem->start << PAGE_SHIFT; |
691 | if (!gtt->num_pages) { | 691 | if (!gtt->num_pages) { |
692 | WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", gtt->num_pages, bo_mem, backend); | 692 | WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", |
693 | gtt->num_pages, bo_mem, backend); | ||
693 | } | 694 | } |
694 | r = radeon_gart_bind(gtt->rdev, gtt->offset, | 695 | r = radeon_gart_bind(gtt->rdev, gtt->offset, |
695 | gtt->num_pages, gtt->pages); | 696 | gtt->num_pages, gtt->pages); |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index f683e51a2a06..5512e4e5e636 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -78,7 +78,7 @@ int rs400_gart_init(struct radeon_device *rdev) | |||
78 | int r; | 78 | int r; |
79 | 79 | ||
80 | if (rdev->gart.table.ram.ptr) { | 80 | if (rdev->gart.table.ram.ptr) { |
81 | WARN(1, "RS400 GART already initialized.\n"); | 81 | WARN(1, "RS400 GART already initialized\n"); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | /* Check gart size */ | 84 | /* Check gart size */ |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index b091a1f6fa4e..f1c6e02c2e6b 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -375,7 +375,7 @@ int rs600_gart_init(struct radeon_device *rdev) | |||
375 | int r; | 375 | int r; |
376 | 376 | ||
377 | if (rdev->gart.table.vram.robj) { | 377 | if (rdev->gart.table.vram.robj) { |
378 | WARN(1, "RS600 GART already initialized.\n"); | 378 | WARN(1, "RS600 GART already initialized\n"); |
379 | return 0; | 379 | return 0; |
380 | } | 380 | } |
381 | /* Initialize common gart structure */ | 381 | /* Initialize common gart structure */ |
@@ -505,7 +505,7 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
505 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | 505 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); |
506 | 506 | ||
507 | if (!rdev->irq.installed) { | 507 | if (!rdev->irq.installed) { |
508 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 508 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
509 | WREG32(R_000040_GEN_INT_CNTL, 0); | 509 | WREG32(R_000040_GEN_INT_CNTL, 0); |
510 | return -EINVAL; | 510 | return -EINVAL; |
511 | } | 511 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index a1cb783c7131..3ca77dc03915 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -27,14 +27,6 @@ | |||
27 | /* | 27 | /* |
28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> |
29 | */ | 29 | */ |
30 | /* Notes: | ||
31 | * | ||
32 | * We store bo pointer in drm_mm_node struct so we know which bo own a | ||
33 | * specific node. There is no protection on the pointer, thus to make | ||
34 | * sure things don't go berserk you have to access this pointer while | ||
35 | * holding the global lru lock and make sure anytime you free a node you | ||
36 | * reset the pointer to NULL. | ||
37 | */ | ||
38 | 30 | ||
39 | #include "ttm/ttm_module.h" | 31 | #include "ttm/ttm_module.h" |
40 | #include "ttm/ttm_bo_driver.h" | 32 | #include "ttm/ttm_bo_driver.h" |
@@ -45,6 +37,7 @@ | |||
45 | #include <linux/mm.h> | 37 | #include <linux/mm.h> |
46 | #include <linux/file.h> | 38 | #include <linux/file.h> |
47 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <asm/atomic.h> | ||
48 | 41 | ||
49 | #define TTM_ASSERT_LOCKED(param) | 42 | #define TTM_ASSERT_LOCKED(param) |
50 | #define TTM_DEBUG(fmt, arg...) | 43 | #define TTM_DEBUG(fmt, arg...) |
@@ -452,6 +445,11 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) | |||
452 | ttm_bo_mem_put(bo, &bo->mem); | 445 | ttm_bo_mem_put(bo, &bo->mem); |
453 | 446 | ||
454 | atomic_set(&bo->reserved, 0); | 447 | atomic_set(&bo->reserved, 0); |
448 | |||
449 | /* | ||
450 | * Make processes trying to reserve really pick it up. | ||
451 | */ | ||
452 | smp_mb__after_atomic_dec(); | ||
455 | wake_up_all(&bo->event_queue); | 453 | wake_up_all(&bo->event_queue); |
456 | } | 454 | } |
457 | 455 | ||
@@ -460,7 +458,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) | |||
460 | struct ttm_bo_device *bdev = bo->bdev; | 458 | struct ttm_bo_device *bdev = bo->bdev; |
461 | struct ttm_bo_global *glob = bo->glob; | 459 | struct ttm_bo_global *glob = bo->glob; |
462 | struct ttm_bo_driver *driver; | 460 | struct ttm_bo_driver *driver; |
463 | void *sync_obj; | 461 | void *sync_obj = NULL; |
464 | void *sync_obj_arg; | 462 | void *sync_obj_arg; |
465 | int put_count; | 463 | int put_count; |
466 | int ret; | 464 | int ret; |
@@ -495,17 +493,20 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) | |||
495 | spin_lock(&glob->lru_lock); | 493 | spin_lock(&glob->lru_lock); |
496 | } | 494 | } |
497 | queue: | 495 | queue: |
498 | sync_obj = bo->sync_obj; | ||
499 | sync_obj_arg = bo->sync_obj_arg; | ||
500 | driver = bdev->driver; | 496 | driver = bdev->driver; |
497 | if (bo->sync_obj) | ||
498 | sync_obj = driver->sync_obj_ref(bo->sync_obj); | ||
499 | sync_obj_arg = bo->sync_obj_arg; | ||
501 | 500 | ||
502 | kref_get(&bo->list_kref); | 501 | kref_get(&bo->list_kref); |
503 | list_add_tail(&bo->ddestroy, &bdev->ddestroy); | 502 | list_add_tail(&bo->ddestroy, &bdev->ddestroy); |
504 | spin_unlock(&glob->lru_lock); | 503 | spin_unlock(&glob->lru_lock); |
505 | spin_unlock(&bo->lock); | 504 | spin_unlock(&bo->lock); |
506 | 505 | ||
507 | if (sync_obj) | 506 | if (sync_obj) { |
508 | driver->sync_obj_flush(sync_obj, sync_obj_arg); | 507 | driver->sync_obj_flush(sync_obj, sync_obj_arg); |
508 | driver->sync_obj_unref(&sync_obj); | ||
509 | } | ||
509 | schedule_delayed_work(&bdev->wq, | 510 | schedule_delayed_work(&bdev->wq, |
510 | ((HZ / 100) < 1) ? 1 : HZ / 100); | 511 | ((HZ / 100) < 1) ? 1 : HZ / 100); |
511 | } | 512 | } |
@@ -822,7 +823,6 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, | |||
822 | bool no_wait_gpu) | 823 | bool no_wait_gpu) |
823 | { | 824 | { |
824 | struct ttm_bo_device *bdev = bo->bdev; | 825 | struct ttm_bo_device *bdev = bo->bdev; |
825 | struct ttm_bo_global *glob = bdev->glob; | ||
826 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; | 826 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; |
827 | int ret; | 827 | int ret; |
828 | 828 | ||
@@ -832,12 +832,6 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, | |||
832 | return ret; | 832 | return ret; |
833 | if (mem->mm_node) | 833 | if (mem->mm_node) |
834 | break; | 834 | break; |
835 | spin_lock(&glob->lru_lock); | ||
836 | if (list_empty(&man->lru)) { | ||
837 | spin_unlock(&glob->lru_lock); | ||
838 | break; | ||
839 | } | ||
840 | spin_unlock(&glob->lru_lock); | ||
841 | ret = ttm_mem_evict_first(bdev, mem_type, interruptible, | 835 | ret = ttm_mem_evict_first(bdev, mem_type, interruptible, |
842 | no_wait_reserve, no_wait_gpu); | 836 | no_wait_reserve, no_wait_gpu); |
843 | if (unlikely(ret != 0)) | 837 | if (unlikely(ret != 0)) |
@@ -1125,35 +1119,9 @@ EXPORT_SYMBOL(ttm_bo_validate); | |||
1125 | int ttm_bo_check_placement(struct ttm_buffer_object *bo, | 1119 | int ttm_bo_check_placement(struct ttm_buffer_object *bo, |
1126 | struct ttm_placement *placement) | 1120 | struct ttm_placement *placement) |
1127 | { | 1121 | { |
1128 | int i; | 1122 | BUG_ON((placement->fpfn || placement->lpfn) && |
1123 | (bo->mem.num_pages > (placement->lpfn - placement->fpfn))); | ||
1129 | 1124 | ||
1130 | if (placement->fpfn || placement->lpfn) { | ||
1131 | if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) { | ||
1132 | printk(KERN_ERR TTM_PFX "Page number range to small " | ||
1133 | "Need %lu pages, range is [%u, %u]\n", | ||
1134 | bo->mem.num_pages, placement->fpfn, | ||
1135 | placement->lpfn); | ||
1136 | return -EINVAL; | ||
1137 | } | ||
1138 | } | ||
1139 | for (i = 0; i < placement->num_placement; i++) { | ||
1140 | if (!capable(CAP_SYS_ADMIN)) { | ||
1141 | if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { | ||
1142 | printk(KERN_ERR TTM_PFX "Need to be root to " | ||
1143 | "modify NO_EVICT status.\n"); | ||
1144 | return -EINVAL; | ||
1145 | } | ||
1146 | } | ||
1147 | } | ||
1148 | for (i = 0; i < placement->num_busy_placement; i++) { | ||
1149 | if (!capable(CAP_SYS_ADMIN)) { | ||
1150 | if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) { | ||
1151 | printk(KERN_ERR TTM_PFX "Need to be root to " | ||
1152 | "modify NO_EVICT status.\n"); | ||
1153 | return -EINVAL; | ||
1154 | } | ||
1155 | } | ||
1156 | } | ||
1157 | return 0; | 1125 | return 0; |
1158 | } | 1126 | } |
1159 | 1127 | ||
@@ -1176,6 +1144,10 @@ int ttm_bo_init(struct ttm_bo_device *bdev, | |||
1176 | num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1144 | num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1177 | if (num_pages == 0) { | 1145 | if (num_pages == 0) { |
1178 | printk(KERN_ERR TTM_PFX "Illegal buffer object size.\n"); | 1146 | printk(KERN_ERR TTM_PFX "Illegal buffer object size.\n"); |
1147 | if (destroy) | ||
1148 | (*destroy)(bo); | ||
1149 | else | ||
1150 | kfree(bo); | ||
1179 | return -EINVAL; | 1151 | return -EINVAL; |
1180 | } | 1152 | } |
1181 | bo->destroy = destroy; | 1153 | bo->destroy = destroy; |
@@ -1369,18 +1341,9 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, | |||
1369 | int ret = -EINVAL; | 1341 | int ret = -EINVAL; |
1370 | struct ttm_mem_type_manager *man; | 1342 | struct ttm_mem_type_manager *man; |
1371 | 1343 | ||
1372 | if (type >= TTM_NUM_MEM_TYPES) { | 1344 | BUG_ON(type >= TTM_NUM_MEM_TYPES); |
1373 | printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", type); | ||
1374 | return ret; | ||
1375 | } | ||
1376 | |||
1377 | man = &bdev->man[type]; | 1345 | man = &bdev->man[type]; |
1378 | if (man->has_type) { | 1346 | BUG_ON(man->has_type); |
1379 | printk(KERN_ERR TTM_PFX | ||
1380 | "Memory manager already initialized for type %d\n", | ||
1381 | type); | ||
1382 | return ret; | ||
1383 | } | ||
1384 | 1347 | ||
1385 | ret = bdev->driver->init_mem_type(bdev, type, man); | 1348 | ret = bdev->driver->init_mem_type(bdev, type, man); |
1386 | if (ret) | 1349 | if (ret) |
@@ -1389,13 +1352,6 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, | |||
1389 | 1352 | ||
1390 | ret = 0; | 1353 | ret = 0; |
1391 | if (type != TTM_PL_SYSTEM) { | 1354 | if (type != TTM_PL_SYSTEM) { |
1392 | if (!p_size) { | ||
1393 | printk(KERN_ERR TTM_PFX | ||
1394 | "Zero size memory manager type %d\n", | ||
1395 | type); | ||
1396 | return ret; | ||
1397 | } | ||
1398 | |||
1399 | ret = (*man->func->init)(man, p_size); | 1355 | ret = (*man->func->init)(man, p_size); |
1400 | if (ret) | 1356 | if (ret) |
1401 | return ret; | 1357 | return ret; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c index 7410c190c891..038e947d00f9 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_manager.c +++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /************************************************************************** | 1 | /************************************************************************** |
2 | * | 2 | * |
3 | * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA | 3 | * Copyright (c) 2007-2010 VMware, Inc., Palo Alto, CA., USA |
4 | * All Rights Reserved. | 4 | * All Rights Reserved. |
5 | * | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
@@ -31,20 +31,29 @@ | |||
31 | #include "ttm/ttm_module.h" | 31 | #include "ttm/ttm_module.h" |
32 | #include "ttm/ttm_bo_driver.h" | 32 | #include "ttm/ttm_bo_driver.h" |
33 | #include "ttm/ttm_placement.h" | 33 | #include "ttm/ttm_placement.h" |
34 | #include <linux/jiffies.h> | 34 | #include "drm_mm.h" |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/mm.h> | ||
38 | #include <linux/file.h> | ||
39 | #include <linux/module.h> | 37 | #include <linux/module.h> |
40 | 38 | ||
39 | /** | ||
40 | * Currently we use a spinlock for the lock, but a mutex *may* be | ||
41 | * more appropriate to reduce scheduling latency if the range manager | ||
42 | * ends up with very fragmented allocation patterns. | ||
43 | */ | ||
44 | |||
45 | struct ttm_range_manager { | ||
46 | struct drm_mm mm; | ||
47 | spinlock_t lock; | ||
48 | }; | ||
49 | |||
41 | static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, | 50 | static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, |
42 | struct ttm_buffer_object *bo, | 51 | struct ttm_buffer_object *bo, |
43 | struct ttm_placement *placement, | 52 | struct ttm_placement *placement, |
44 | struct ttm_mem_reg *mem) | 53 | struct ttm_mem_reg *mem) |
45 | { | 54 | { |
46 | struct ttm_bo_global *glob = man->bdev->glob; | 55 | struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; |
47 | struct drm_mm *mm = man->priv; | 56 | struct drm_mm *mm = &rman->mm; |
48 | struct drm_mm_node *node = NULL; | 57 | struct drm_mm_node *node = NULL; |
49 | unsigned long lpfn; | 58 | unsigned long lpfn; |
50 | int ret; | 59 | int ret; |
@@ -57,19 +66,19 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, | |||
57 | if (unlikely(ret)) | 66 | if (unlikely(ret)) |
58 | return ret; | 67 | return ret; |
59 | 68 | ||
60 | spin_lock(&glob->lru_lock); | 69 | spin_lock(&rman->lock); |
61 | node = drm_mm_search_free_in_range(mm, | 70 | node = drm_mm_search_free_in_range(mm, |
62 | mem->num_pages, mem->page_alignment, | 71 | mem->num_pages, mem->page_alignment, |
63 | placement->fpfn, lpfn, 1); | 72 | placement->fpfn, lpfn, 1); |
64 | if (unlikely(node == NULL)) { | 73 | if (unlikely(node == NULL)) { |
65 | spin_unlock(&glob->lru_lock); | 74 | spin_unlock(&rman->lock); |
66 | return 0; | 75 | return 0; |
67 | } | 76 | } |
68 | node = drm_mm_get_block_atomic_range(node, mem->num_pages, | 77 | node = drm_mm_get_block_atomic_range(node, mem->num_pages, |
69 | mem->page_alignment, | 78 | mem->page_alignment, |
70 | placement->fpfn, | 79 | placement->fpfn, |
71 | lpfn); | 80 | lpfn); |
72 | spin_unlock(&glob->lru_lock); | 81 | spin_unlock(&rman->lock); |
73 | } while (node == NULL); | 82 | } while (node == NULL); |
74 | 83 | ||
75 | mem->mm_node = node; | 84 | mem->mm_node = node; |
@@ -80,12 +89,12 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, | |||
80 | static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, | 89 | static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, |
81 | struct ttm_mem_reg *mem) | 90 | struct ttm_mem_reg *mem) |
82 | { | 91 | { |
83 | struct ttm_bo_global *glob = man->bdev->glob; | 92 | struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; |
84 | 93 | ||
85 | if (mem->mm_node) { | 94 | if (mem->mm_node) { |
86 | spin_lock(&glob->lru_lock); | 95 | spin_lock(&rman->lock); |
87 | drm_mm_put_block(mem->mm_node); | 96 | drm_mm_put_block(mem->mm_node); |
88 | spin_unlock(&glob->lru_lock); | 97 | spin_unlock(&rman->lock); |
89 | mem->mm_node = NULL; | 98 | mem->mm_node = NULL; |
90 | } | 99 | } |
91 | } | 100 | } |
@@ -93,49 +102,49 @@ static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, | |||
93 | static int ttm_bo_man_init(struct ttm_mem_type_manager *man, | 102 | static int ttm_bo_man_init(struct ttm_mem_type_manager *man, |
94 | unsigned long p_size) | 103 | unsigned long p_size) |
95 | { | 104 | { |
96 | struct drm_mm *mm; | 105 | struct ttm_range_manager *rman; |
97 | int ret; | 106 | int ret; |
98 | 107 | ||
99 | mm = kzalloc(sizeof(*mm), GFP_KERNEL); | 108 | rman = kzalloc(sizeof(*rman), GFP_KERNEL); |
100 | if (!mm) | 109 | if (!rman) |
101 | return -ENOMEM; | 110 | return -ENOMEM; |
102 | 111 | ||
103 | ret = drm_mm_init(mm, 0, p_size); | 112 | ret = drm_mm_init(&rman->mm, 0, p_size); |
104 | if (ret) { | 113 | if (ret) { |
105 | kfree(mm); | 114 | kfree(rman); |
106 | return ret; | 115 | return ret; |
107 | } | 116 | } |
108 | 117 | ||
109 | man->priv = mm; | 118 | spin_lock_init(&rman->lock); |
119 | man->priv = rman; | ||
110 | return 0; | 120 | return 0; |
111 | } | 121 | } |
112 | 122 | ||
113 | static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man) | 123 | static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man) |
114 | { | 124 | { |
115 | struct ttm_bo_global *glob = man->bdev->glob; | 125 | struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; |
116 | struct drm_mm *mm = man->priv; | 126 | struct drm_mm *mm = &rman->mm; |
117 | int ret = 0; | ||
118 | 127 | ||
119 | spin_lock(&glob->lru_lock); | 128 | spin_lock(&rman->lock); |
120 | if (drm_mm_clean(mm)) { | 129 | if (drm_mm_clean(mm)) { |
121 | drm_mm_takedown(mm); | 130 | drm_mm_takedown(mm); |
122 | kfree(mm); | 131 | spin_unlock(&rman->lock); |
132 | kfree(rman); | ||
123 | man->priv = NULL; | 133 | man->priv = NULL; |
124 | } else | 134 | return 0; |
125 | ret = -EBUSY; | 135 | } |
126 | spin_unlock(&glob->lru_lock); | 136 | spin_unlock(&rman->lock); |
127 | return ret; | 137 | return -EBUSY; |
128 | } | 138 | } |
129 | 139 | ||
130 | static void ttm_bo_man_debug(struct ttm_mem_type_manager *man, | 140 | static void ttm_bo_man_debug(struct ttm_mem_type_manager *man, |
131 | const char *prefix) | 141 | const char *prefix) |
132 | { | 142 | { |
133 | struct ttm_bo_global *glob = man->bdev->glob; | 143 | struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; |
134 | struct drm_mm *mm = man->priv; | ||
135 | 144 | ||
136 | spin_lock(&glob->lru_lock); | 145 | spin_lock(&rman->lock); |
137 | drm_mm_debug_table(mm, prefix); | 146 | drm_mm_debug_table(&rman->mm, prefix); |
138 | spin_unlock(&glob->lru_lock); | 147 | spin_unlock(&rman->lock); |
139 | } | 148 | } |
140 | 149 | ||
141 | const struct ttm_mem_type_manager_func ttm_bo_manager_func = { | 150 | const struct ttm_mem_type_manager_func ttm_bo_manager_func = { |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index a7bab87a548b..af789dc869b9 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -440,10 +440,8 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) | |||
440 | return ret; | 440 | return ret; |
441 | 441 | ||
442 | ret = be->func->bind(be, bo_mem); | 442 | ret = be->func->bind(be, bo_mem); |
443 | if (ret) { | 443 | if (unlikely(ret != 0)) |
444 | printk(KERN_ERR TTM_PFX "Couldn't bind backend.\n"); | ||
445 | return ret; | 444 | return ret; |
446 | } | ||
447 | 445 | ||
448 | ttm->state = tt_bound; | 446 | ttm->state = tt_bound; |
449 | 447 | ||
diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 9b5b4d9dd62c..3e038a394c51 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c | |||
@@ -235,9 +235,9 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) | |||
235 | vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - | 235 | vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - |
236 | first_pfn + 1; | 236 | first_pfn + 1; |
237 | 237 | ||
238 | if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) | 238 | vsg->pages = vzalloc(sizeof(struct page *) * vsg->num_pages); |
239 | if (NULL == vsg->pages) | ||
239 | return -ENOMEM; | 240 | return -ENOMEM; |
240 | memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages); | ||
241 | down_read(¤t->mm->mmap_sem); | 241 | down_read(¤t->mm->mmap_sem); |
242 | ret = get_user_pages(current, current->mm, | 242 | ret = get_user_pages(current, current->mm, |
243 | (unsigned long)xfer->mem_addr, | 243 | (unsigned long)xfer->mem_addr, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 51d9f9f1d7f2..76954e3528c1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -691,6 +691,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, | |||
691 | 691 | ||
692 | fence_rep.error = ret; | 692 | fence_rep.error = ret; |
693 | fence_rep.fence_seq = (uint64_t) sequence; | 693 | fence_rep.fence_seq = (uint64_t) sequence; |
694 | fence_rep.pad64 = 0; | ||
694 | 695 | ||
695 | user_fence_rep = (struct drm_vmw_fence_rep __user *) | 696 | user_fence_rep = (struct drm_vmw_fence_rep __user *) |
696 | (unsigned long)arg->fence_rep; | 697 | (unsigned long)arg->fence_rep; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 87c6e6156d7d..cceeb42789b6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -720,6 +720,8 @@ static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb) | |||
720 | &vmw_vram_ne_placement, | 720 | &vmw_vram_ne_placement, |
721 | false, &vmw_dmabuf_bo_free); | 721 | false, &vmw_dmabuf_bo_free); |
722 | vmw_overlay_resume_all(dev_priv); | 722 | vmw_overlay_resume_all(dev_priv); |
723 | if (unlikely(ret != 0)) | ||
724 | vfbs->buffer = NULL; | ||
723 | 725 | ||
724 | return ret; | 726 | return ret; |
725 | } | 727 | } |
@@ -730,6 +732,9 @@ static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb) | |||
730 | struct vmw_framebuffer_surface *vfbs = | 732 | struct vmw_framebuffer_surface *vfbs = |
731 | vmw_framebuffer_to_vfbs(&vfb->base); | 733 | vmw_framebuffer_to_vfbs(&vfb->base); |
732 | 734 | ||
735 | if (unlikely(vfbs->buffer == NULL)) | ||
736 | return 0; | ||
737 | |||
733 | bo = &vfbs->buffer->base; | 738 | bo = &vfbs->buffer->base; |
734 | ttm_bo_unref(&bo); | 739 | ttm_bo_unref(&bo); |
735 | vfbs->buffer = NULL; | 740 | vfbs->buffer = NULL; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index a01c47ddb5bc..29113c9b26a8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -557,7 +557,7 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | |||
557 | return -EINVAL; | 557 | return -EINVAL; |
558 | } | 558 | } |
559 | 559 | ||
560 | dev_priv->ldu_priv = kmalloc(GFP_KERNEL, sizeof(*dev_priv->ldu_priv)); | 560 | dev_priv->ldu_priv = kmalloc(sizeof(*dev_priv->ldu_priv), GFP_KERNEL); |
561 | 561 | ||
562 | if (!dev_priv->ldu_priv) | 562 | if (!dev_priv->ldu_priv) |
563 | return -ENOMEM; | 563 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index df2036ed18d5..f1a52f9e7298 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | |||
@@ -585,7 +585,7 @@ int vmw_overlay_init(struct vmw_private *dev_priv) | |||
585 | return -ENOSYS; | 585 | return -ENOSYS; |
586 | } | 586 | } |
587 | 587 | ||
588 | overlay = kmalloc(GFP_KERNEL, sizeof(*overlay)); | 588 | overlay = kmalloc(sizeof(*overlay), GFP_KERNEL); |
589 | if (!overlay) | 589 | if (!overlay) |
590 | return -ENOMEM; | 590 | return -ENOMEM; |
591 | 591 | ||
diff --git a/drivers/gpu/stub/Kconfig b/drivers/gpu/stub/Kconfig index 742c423567cf..0e1edd7311ff 100644 --- a/drivers/gpu/stub/Kconfig +++ b/drivers/gpu/stub/Kconfig | |||
@@ -3,6 +3,9 @@ config STUB_POULSBO | |||
3 | depends on PCI | 3 | depends on PCI |
4 | # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled | 4 | # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled |
5 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | 5 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick |
6 | select VIDEO_OUTPUT_CONTROL if ACPI | ||
7 | select BACKLIGHT_CLASS_DEVICE if ACPI | ||
8 | select INPUT if ACPI | ||
6 | select ACPI_VIDEO if ACPI | 9 | select ACPI_VIDEO if ACPI |
7 | help | 10 | help |
8 | Choose this option if you have a system that has Intel GMA500 | 11 | Choose this option if you have a system that has Intel GMA500 |
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index 1e4c21fc1a89..86d822aa9bbf 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c | |||
@@ -178,11 +178,13 @@ static int ad7414_probe(struct i2c_client *client, | |||
178 | { | 178 | { |
179 | struct ad7414_data *data; | 179 | struct ad7414_data *data; |
180 | int conf; | 180 | int conf; |
181 | int err = 0; | 181 | int err; |
182 | 182 | ||
183 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 183 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
184 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | 184 | I2C_FUNC_SMBUS_READ_WORD_DATA)) { |
185 | err = -EOPNOTSUPP; | ||
185 | goto exit; | 186 | goto exit; |
187 | } | ||
186 | 188 | ||
187 | data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); | 189 | data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); |
188 | if (!data) { | 190 | if (!data) { |
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 9e775717abb7..87d92a56a939 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
@@ -1286,8 +1286,10 @@ static int adt7470_probe(struct i2c_client *client, | |||
1286 | init_completion(&data->auto_update_stop); | 1286 | init_completion(&data->auto_update_stop); |
1287 | data->auto_update = kthread_run(adt7470_update_thread, client, | 1287 | data->auto_update = kthread_run(adt7470_update_thread, client, |
1288 | dev_name(data->hwmon_dev)); | 1288 | dev_name(data->hwmon_dev)); |
1289 | if (IS_ERR(data->auto_update)) | 1289 | if (IS_ERR(data->auto_update)) { |
1290 | err = PTR_ERR(data->auto_update); | ||
1290 | goto exit_unregister; | 1291 | goto exit_unregister; |
1292 | } | ||
1291 | 1293 | ||
1292 | return 0; | 1294 | return 0; |
1293 | 1295 | ||
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index aa701a183707..f141a1de519c 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -376,10 +376,6 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | ||
380 | if (err) | ||
381 | goto err_free_gpio; | ||
382 | |||
383 | fan_data->num_ctrl = num_ctrl; | 379 | fan_data->num_ctrl = num_ctrl; |
384 | fan_data->ctrl = ctrl; | 380 | fan_data->ctrl = ctrl; |
385 | fan_data->num_speed = pdata->num_speed; | 381 | fan_data->num_speed = pdata->num_speed; |
@@ -391,6 +387,10 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
391 | goto err_free_gpio; | 387 | goto err_free_gpio; |
392 | } | 388 | } |
393 | 389 | ||
390 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | ||
391 | if (err) | ||
392 | goto err_free_gpio; | ||
393 | |||
394 | return 0; | 394 | return 0; |
395 | 395 | ||
396 | err_free_gpio: | 396 | err_free_gpio: |
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 267626178678..4b50601027d3 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c | |||
@@ -82,7 +82,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev) | |||
82 | val = i2c_smbus_read_byte_data(client, i); | 82 | val = i2c_smbus_read_byte_data(client, i); |
83 | if (unlikely(val < 0)) { | 83 | if (unlikely(val < 0)) { |
84 | dev_dbg(dev, | 84 | dev_dbg(dev, |
85 | "Failed to read ADC value: error %d", | 85 | "Failed to read ADC value: error %d\n", |
86 | val); | 86 | val); |
87 | ret = ERR_PTR(val); | 87 | ret = ERR_PTR(val); |
88 | goto abort; | 88 | goto abort; |
@@ -230,8 +230,7 @@ static int ltc4261_probe(struct i2c_client *client, | |||
230 | return -ENODEV; | 230 | return -ENODEV; |
231 | 231 | ||
232 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { | 232 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { |
233 | dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n", | 233 | dev_err(&client->dev, "Failed to read status register\n"); |
234 | adapter->id, client->addr, LTC4261_STATUS); | ||
235 | return -ENODEV; | 234 | return -ENODEV; |
236 | } | 235 | } |
237 | 236 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index d092ef9291da..7f26ca6ecf75 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -74,6 +74,7 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
74 | * dev->event_lock held and interrupts disabled. | 74 | * dev->event_lock held and interrupts disabled. |
75 | */ | 75 | */ |
76 | static void input_pass_event(struct input_dev *dev, | 76 | static void input_pass_event(struct input_dev *dev, |
77 | struct input_handler *src_handler, | ||
77 | unsigned int type, unsigned int code, int value) | 78 | unsigned int type, unsigned int code, int value) |
78 | { | 79 | { |
79 | struct input_handler *handler; | 80 | struct input_handler *handler; |
@@ -92,6 +93,15 @@ static void input_pass_event(struct input_dev *dev, | |||
92 | continue; | 93 | continue; |
93 | 94 | ||
94 | handler = handle->handler; | 95 | handler = handle->handler; |
96 | |||
97 | /* | ||
98 | * If this is the handler that injected this | ||
99 | * particular event we want to skip it to avoid | ||
100 | * filters firing again and again. | ||
101 | */ | ||
102 | if (handler == src_handler) | ||
103 | continue; | ||
104 | |||
95 | if (!handler->filter) { | 105 | if (!handler->filter) { |
96 | if (filtered) | 106 | if (filtered) |
97 | break; | 107 | break; |
@@ -121,7 +131,7 @@ static void input_repeat_key(unsigned long data) | |||
121 | if (test_bit(dev->repeat_key, dev->key) && | 131 | if (test_bit(dev->repeat_key, dev->key) && |
122 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { | 132 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { |
123 | 133 | ||
124 | input_pass_event(dev, EV_KEY, dev->repeat_key, 2); | 134 | input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); |
125 | 135 | ||
126 | if (dev->sync) { | 136 | if (dev->sync) { |
127 | /* | 137 | /* |
@@ -130,7 +140,7 @@ static void input_repeat_key(unsigned long data) | |||
130 | * Otherwise assume that the driver will send | 140 | * Otherwise assume that the driver will send |
131 | * SYN_REPORT once it's done. | 141 | * SYN_REPORT once it's done. |
132 | */ | 142 | */ |
133 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | 143 | input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); |
134 | } | 144 | } |
135 | 145 | ||
136 | if (dev->rep[REP_PERIOD]) | 146 | if (dev->rep[REP_PERIOD]) |
@@ -163,6 +173,7 @@ static void input_stop_autorepeat(struct input_dev *dev) | |||
163 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) | 173 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) |
164 | 174 | ||
165 | static int input_handle_abs_event(struct input_dev *dev, | 175 | static int input_handle_abs_event(struct input_dev *dev, |
176 | struct input_handler *src_handler, | ||
166 | unsigned int code, int *pval) | 177 | unsigned int code, int *pval) |
167 | { | 178 | { |
168 | bool is_mt_event; | 179 | bool is_mt_event; |
@@ -206,13 +217,15 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
206 | /* Flush pending "slot" event */ | 217 | /* Flush pending "slot" event */ |
207 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { | 218 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { |
208 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); | 219 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); |
209 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | 220 | input_pass_event(dev, src_handler, |
221 | EV_ABS, ABS_MT_SLOT, dev->slot); | ||
210 | } | 222 | } |
211 | 223 | ||
212 | return INPUT_PASS_TO_HANDLERS; | 224 | return INPUT_PASS_TO_HANDLERS; |
213 | } | 225 | } |
214 | 226 | ||
215 | static void input_handle_event(struct input_dev *dev, | 227 | static void input_handle_event(struct input_dev *dev, |
228 | struct input_handler *src_handler, | ||
216 | unsigned int type, unsigned int code, int value) | 229 | unsigned int type, unsigned int code, int value) |
217 | { | 230 | { |
218 | int disposition = INPUT_IGNORE_EVENT; | 231 | int disposition = INPUT_IGNORE_EVENT; |
@@ -265,7 +278,8 @@ static void input_handle_event(struct input_dev *dev, | |||
265 | 278 | ||
266 | case EV_ABS: | 279 | case EV_ABS: |
267 | if (is_event_supported(code, dev->absbit, ABS_MAX)) | 280 | if (is_event_supported(code, dev->absbit, ABS_MAX)) |
268 | disposition = input_handle_abs_event(dev, code, &value); | 281 | disposition = input_handle_abs_event(dev, src_handler, |
282 | code, &value); | ||
269 | 283 | ||
270 | break; | 284 | break; |
271 | 285 | ||
@@ -323,7 +337,7 @@ static void input_handle_event(struct input_dev *dev, | |||
323 | dev->event(dev, type, code, value); | 337 | dev->event(dev, type, code, value); |
324 | 338 | ||
325 | if (disposition & INPUT_PASS_TO_HANDLERS) | 339 | if (disposition & INPUT_PASS_TO_HANDLERS) |
326 | input_pass_event(dev, type, code, value); | 340 | input_pass_event(dev, src_handler, type, code, value); |
327 | } | 341 | } |
328 | 342 | ||
329 | /** | 343 | /** |
@@ -352,7 +366,7 @@ void input_event(struct input_dev *dev, | |||
352 | 366 | ||
353 | spin_lock_irqsave(&dev->event_lock, flags); | 367 | spin_lock_irqsave(&dev->event_lock, flags); |
354 | add_input_randomness(type, code, value); | 368 | add_input_randomness(type, code, value); |
355 | input_handle_event(dev, type, code, value); | 369 | input_handle_event(dev, NULL, type, code, value); |
356 | spin_unlock_irqrestore(&dev->event_lock, flags); | 370 | spin_unlock_irqrestore(&dev->event_lock, flags); |
357 | } | 371 | } |
358 | } | 372 | } |
@@ -382,7 +396,8 @@ void input_inject_event(struct input_handle *handle, | |||
382 | rcu_read_lock(); | 396 | rcu_read_lock(); |
383 | grab = rcu_dereference(dev->grab); | 397 | grab = rcu_dereference(dev->grab); |
384 | if (!grab || grab == handle) | 398 | if (!grab || grab == handle) |
385 | input_handle_event(dev, type, code, value); | 399 | input_handle_event(dev, handle->handler, |
400 | type, code, value); | ||
386 | rcu_read_unlock(); | 401 | rcu_read_unlock(); |
387 | 402 | ||
388 | spin_unlock_irqrestore(&dev->event_lock, flags); | 403 | spin_unlock_irqrestore(&dev->event_lock, flags); |
@@ -595,10 +610,10 @@ static void input_dev_release_keys(struct input_dev *dev) | |||
595 | for (code = 0; code <= KEY_MAX; code++) { | 610 | for (code = 0; code <= KEY_MAX; code++) { |
596 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | 611 | if (is_event_supported(code, dev->keybit, KEY_MAX) && |
597 | __test_and_clear_bit(code, dev->key)) { | 612 | __test_and_clear_bit(code, dev->key)) { |
598 | input_pass_event(dev, EV_KEY, code, 0); | 613 | input_pass_event(dev, NULL, EV_KEY, code, 0); |
599 | } | 614 | } |
600 | } | 615 | } |
601 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | 616 | input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); |
602 | } | 617 | } |
603 | } | 618 | } |
604 | 619 | ||
@@ -873,9 +888,9 @@ int input_set_keycode(struct input_dev *dev, | |||
873 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | 888 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && |
874 | __test_and_clear_bit(old_keycode, dev->key)) { | 889 | __test_and_clear_bit(old_keycode, dev->key)) { |
875 | 890 | ||
876 | input_pass_event(dev, EV_KEY, old_keycode, 0); | 891 | input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); |
877 | if (dev->sync) | 892 | if (dev->sync) |
878 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | 893 | input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); |
879 | } | 894 | } |
880 | 895 | ||
881 | out: | 896 | out: |
@@ -1565,8 +1580,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
1565 | } \ | 1580 | } \ |
1566 | } while (0) | 1581 | } while (0) |
1567 | 1582 | ||
1568 | #ifdef CONFIG_PM | 1583 | static void input_dev_toggle(struct input_dev *dev, bool activate) |
1569 | static void input_dev_reset(struct input_dev *dev, bool activate) | ||
1570 | { | 1584 | { |
1571 | if (!dev->event) | 1585 | if (!dev->event) |
1572 | return; | 1586 | return; |
@@ -1580,12 +1594,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate) | |||
1580 | } | 1594 | } |
1581 | } | 1595 | } |
1582 | 1596 | ||
1597 | /** | ||
1598 | * input_reset_device() - reset/restore the state of input device | ||
1599 | * @dev: input device whose state needs to be reset | ||
1600 | * | ||
1601 | * This function tries to reset the state of an opened input device and | ||
1602 | * bring internal state and state if the hardware in sync with each other. | ||
1603 | * We mark all keys as released, restore LED state, repeat rate, etc. | ||
1604 | */ | ||
1605 | void input_reset_device(struct input_dev *dev) | ||
1606 | { | ||
1607 | mutex_lock(&dev->mutex); | ||
1608 | |||
1609 | if (dev->users) { | ||
1610 | input_dev_toggle(dev, true); | ||
1611 | |||
1612 | /* | ||
1613 | * Keys that have been pressed at suspend time are unlikely | ||
1614 | * to be still pressed when we resume. | ||
1615 | */ | ||
1616 | spin_lock_irq(&dev->event_lock); | ||
1617 | input_dev_release_keys(dev); | ||
1618 | spin_unlock_irq(&dev->event_lock); | ||
1619 | } | ||
1620 | |||
1621 | mutex_unlock(&dev->mutex); | ||
1622 | } | ||
1623 | EXPORT_SYMBOL(input_reset_device); | ||
1624 | |||
1625 | #ifdef CONFIG_PM | ||
1583 | static int input_dev_suspend(struct device *dev) | 1626 | static int input_dev_suspend(struct device *dev) |
1584 | { | 1627 | { |
1585 | struct input_dev *input_dev = to_input_dev(dev); | 1628 | struct input_dev *input_dev = to_input_dev(dev); |
1586 | 1629 | ||
1587 | mutex_lock(&input_dev->mutex); | 1630 | mutex_lock(&input_dev->mutex); |
1588 | input_dev_reset(input_dev, false); | 1631 | |
1632 | if (input_dev->users) | ||
1633 | input_dev_toggle(input_dev, false); | ||
1634 | |||
1589 | mutex_unlock(&input_dev->mutex); | 1635 | mutex_unlock(&input_dev->mutex); |
1590 | 1636 | ||
1591 | return 0; | 1637 | return 0; |
@@ -1595,18 +1641,7 @@ static int input_dev_resume(struct device *dev) | |||
1595 | { | 1641 | { |
1596 | struct input_dev *input_dev = to_input_dev(dev); | 1642 | struct input_dev *input_dev = to_input_dev(dev); |
1597 | 1643 | ||
1598 | mutex_lock(&input_dev->mutex); | 1644 | input_reset_device(input_dev); |
1599 | input_dev_reset(input_dev, true); | ||
1600 | |||
1601 | /* | ||
1602 | * Keys that have been pressed at suspend time are unlikely | ||
1603 | * to be still pressed when we resume. | ||
1604 | */ | ||
1605 | spin_lock_irq(&input_dev->event_lock); | ||
1606 | input_dev_release_keys(input_dev); | ||
1607 | spin_unlock_irq(&input_dev->event_lock); | ||
1608 | |||
1609 | mutex_unlock(&input_dev->mutex); | ||
1610 | 1645 | ||
1611 | return 0; | 1646 | return 0; |
1612 | } | 1647 | } |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index b92d1cd5cba1..af45d275f686 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * I2C QWERTY Keypad and IO Expander | 4 | * I2C QWERTY Keypad and IO Expander |
5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
6 | * | 6 | * |
7 | * Copyright (C) 2008-2009 Analog Devices Inc. | 7 | * Copyright (C) 2008-2010 Analog Devices Inc. |
8 | * Licensed under the GPL-2 or later. | 8 | * Licensed under the GPL-2 or later. |
9 | */ | 9 | */ |
10 | 10 | ||
@@ -24,29 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/i2c/adp5588.h> | 25 | #include <linux/i2c/adp5588.h> |
26 | 26 | ||
27 | /* Configuration Register1 */ | ||
28 | #define AUTO_INC (1 << 7) | ||
29 | #define GPIEM_CFG (1 << 6) | ||
30 | #define OVR_FLOW_M (1 << 5) | ||
31 | #define INT_CFG (1 << 4) | ||
32 | #define OVR_FLOW_IEN (1 << 3) | ||
33 | #define K_LCK_IM (1 << 2) | ||
34 | #define GPI_IEN (1 << 1) | ||
35 | #define KE_IEN (1 << 0) | ||
36 | |||
37 | /* Interrupt Status Register */ | ||
38 | #define CMP2_INT (1 << 5) | ||
39 | #define CMP1_INT (1 << 4) | ||
40 | #define OVR_FLOW_INT (1 << 3) | ||
41 | #define K_LCK_INT (1 << 2) | ||
42 | #define GPI_INT (1 << 1) | ||
43 | #define KE_INT (1 << 0) | ||
44 | |||
45 | /* Key Lock and Event Counter Register */ | ||
46 | #define K_LCK_EN (1 << 6) | ||
47 | #define LCK21 0x30 | ||
48 | #define KEC 0xF | ||
49 | |||
50 | /* Key Event Register xy */ | 27 | /* Key Event Register xy */ |
51 | #define KEY_EV_PRESSED (1 << 7) | 28 | #define KEY_EV_PRESSED (1 << 7) |
52 | #define KEY_EV_MASK (0x7F) | 29 | #define KEY_EV_MASK (0x7F) |
@@ -55,10 +32,6 @@ | |||
55 | 32 | ||
56 | #define KEYP_MAX_EVENT 10 | 33 | #define KEYP_MAX_EVENT 10 |
57 | 34 | ||
58 | #define MAXGPIO 18 | ||
59 | #define ADP_BANK(offs) ((offs) >> 3) | ||
60 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | ||
61 | |||
62 | /* | 35 | /* |
63 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, | 36 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, |
64 | * since the Event Counter Register updated 25ms after the interrupt | 37 | * since the Event Counter Register updated 25ms after the interrupt |
@@ -75,7 +48,7 @@ struct adp5588_kpad { | |||
75 | const struct adp5588_gpi_map *gpimap; | 48 | const struct adp5588_gpi_map *gpimap; |
76 | unsigned short gpimapsize; | 49 | unsigned short gpimapsize; |
77 | #ifdef CONFIG_GPIOLIB | 50 | #ifdef CONFIG_GPIOLIB |
78 | unsigned char gpiomap[MAXGPIO]; | 51 | unsigned char gpiomap[ADP5588_MAXGPIO]; |
79 | bool export_gpio; | 52 | bool export_gpio; |
80 | struct gpio_chip gc; | 53 | struct gpio_chip gc; |
81 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | 54 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ |
@@ -103,8 +76,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) | |||
103 | static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) | 76 | static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) |
104 | { | 77 | { |
105 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 78 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
106 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 79 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
107 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 80 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
108 | 81 | ||
109 | return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); | 82 | return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); |
110 | } | 83 | } |
@@ -113,8 +86,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, | |||
113 | unsigned off, int val) | 86 | unsigned off, int val) |
114 | { | 87 | { |
115 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 88 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
116 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 89 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
117 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 90 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
118 | 91 | ||
119 | mutex_lock(&kpad->gpio_lock); | 92 | mutex_lock(&kpad->gpio_lock); |
120 | 93 | ||
@@ -132,8 +105,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, | |||
132 | static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) | 105 | static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) |
133 | { | 106 | { |
134 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 107 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
135 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 108 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
136 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 109 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
137 | int ret; | 110 | int ret; |
138 | 111 | ||
139 | mutex_lock(&kpad->gpio_lock); | 112 | mutex_lock(&kpad->gpio_lock); |
@@ -150,8 +123,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
150 | unsigned off, int val) | 123 | unsigned off, int val) |
151 | { | 124 | { |
152 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 125 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
153 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 126 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
154 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 127 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
155 | int ret; | 128 | int ret; |
156 | 129 | ||
157 | mutex_lock(&kpad->gpio_lock); | 130 | mutex_lock(&kpad->gpio_lock); |
@@ -176,7 +149,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
176 | static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, | 149 | static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, |
177 | const struct adp5588_kpad_platform_data *pdata) | 150 | const struct adp5588_kpad_platform_data *pdata) |
178 | { | 151 | { |
179 | bool pin_used[MAXGPIO]; | 152 | bool pin_used[ADP5588_MAXGPIO]; |
180 | int n_unused = 0; | 153 | int n_unused = 0; |
181 | int i; | 154 | int i; |
182 | 155 | ||
@@ -191,7 +164,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, | |||
191 | for (i = 0; i < kpad->gpimapsize; i++) | 164 | for (i = 0; i < kpad->gpimapsize; i++) |
192 | pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; | 165 | pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; |
193 | 166 | ||
194 | for (i = 0; i < MAXGPIO; i++) | 167 | for (i = 0; i < ADP5588_MAXGPIO; i++) |
195 | if (!pin_used[i]) | 168 | if (!pin_used[i]) |
196 | kpad->gpiomap[n_unused++] = i; | 169 | kpad->gpiomap[n_unused++] = i; |
197 | 170 | ||
@@ -234,7 +207,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) | |||
234 | return error; | 207 | return error; |
235 | } | 208 | } |
236 | 209 | ||
237 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | 210 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { |
238 | kpad->dat_out[i] = adp5588_read(kpad->client, | 211 | kpad->dat_out[i] = adp5588_read(kpad->client, |
239 | GPIO_DAT_OUT1 + i); | 212 | GPIO_DAT_OUT1 + i); |
240 | kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); | 213 | kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); |
@@ -318,11 +291,11 @@ static void adp5588_work(struct work_struct *work) | |||
318 | 291 | ||
319 | status = adp5588_read(client, INT_STAT); | 292 | status = adp5588_read(client, INT_STAT); |
320 | 293 | ||
321 | if (status & OVR_FLOW_INT) /* Unlikely and should never happen */ | 294 | if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */ |
322 | dev_err(&client->dev, "Event Overflow Error\n"); | 295 | dev_err(&client->dev, "Event Overflow Error\n"); |
323 | 296 | ||
324 | if (status & KE_INT) { | 297 | if (status & ADP5588_KE_INT) { |
325 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; | 298 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC; |
326 | if (ev_cnt) { | 299 | if (ev_cnt) { |
327 | adp5588_report_events(kpad, ev_cnt); | 300 | adp5588_report_events(kpad, ev_cnt); |
328 | input_sync(kpad->input); | 301 | input_sync(kpad->input); |
@@ -360,7 +333,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
360 | if (pdata->en_keylock) { | 333 | if (pdata->en_keylock) { |
361 | ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); | 334 | ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); |
362 | ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); | 335 | ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); |
363 | ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN); | 336 | ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); |
364 | } | 337 | } |
365 | 338 | ||
366 | for (i = 0; i < KEYP_MAX_EVENT; i++) | 339 | for (i = 0; i < KEYP_MAX_EVENT; i++) |
@@ -384,7 +357,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
384 | } | 357 | } |
385 | 358 | ||
386 | if (gpio_data) { | 359 | if (gpio_data) { |
387 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | 360 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { |
388 | int pull_mask = gpio_data->pullup_dis_mask; | 361 | int pull_mask = gpio_data->pullup_dis_mask; |
389 | 362 | ||
390 | ret |= adp5588_write(client, GPIO_PULL1 + i, | 363 | ret |= adp5588_write(client, GPIO_PULL1 + i, |
@@ -392,11 +365,14 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
392 | } | 365 | } |
393 | } | 366 | } |
394 | 367 | ||
395 | ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | | 368 | ret |= adp5588_write(client, INT_STAT, |
396 | OVR_FLOW_INT | K_LCK_INT | | 369 | ADP5588_CMP2_INT | ADP5588_CMP1_INT | |
397 | GPI_INT | KE_INT); /* Status is W1C */ | 370 | ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | |
371 | ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ | ||
398 | 372 | ||
399 | ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN); | 373 | ret |= adp5588_write(client, CFG, ADP5588_INT_CFG | |
374 | ADP5588_OVR_FLOW_IEN | | ||
375 | ADP5588_KE_IEN); | ||
400 | 376 | ||
401 | if (ret < 0) { | 377 | if (ret < 0) { |
402 | dev_err(&client->dev, "Write Error\n"); | 378 | dev_err(&client->dev, "Write Error\n"); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index d358ef8623f4..11478eb2c27d 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -63,6 +63,10 @@ static bool atkbd_extra; | |||
63 | module_param_named(extra, atkbd_extra, bool, 0); | 63 | module_param_named(extra, atkbd_extra, bool, 0); |
64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); |
65 | 65 | ||
66 | static bool atkbd_terminal; | ||
67 | module_param_named(terminal, atkbd_terminal, bool, 0); | ||
68 | MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); | ||
69 | |||
66 | /* | 70 | /* |
67 | * Scancode to keycode tables. These are just the default setting, and | 71 | * Scancode to keycode tables. These are just the default setting, and |
68 | * are loadable via a userland utility. | 72 | * are loadable via a userland utility. |
@@ -136,7 +140,8 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
136 | #define ATKBD_CMD_ENABLE 0x00f4 | 140 | #define ATKBD_CMD_ENABLE 0x00f4 |
137 | #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ | 141 | #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ |
138 | #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ | 142 | #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ |
139 | #define ATKBD_CMD_SETALL_MBR 0x00fa | 143 | #define ATKBD_CMD_SETALL_MB 0x00f8 /* Set all keys to give break codes */ |
144 | #define ATKBD_CMD_SETALL_MBR 0x00fa /* ... and repeat */ | ||
140 | #define ATKBD_CMD_RESET_BAT 0x02ff | 145 | #define ATKBD_CMD_RESET_BAT 0x02ff |
141 | #define ATKBD_CMD_RESEND 0x00fe | 146 | #define ATKBD_CMD_RESEND 0x00fe |
142 | #define ATKBD_CMD_EX_ENABLE 0x10ea | 147 | #define ATKBD_CMD_EX_ENABLE 0x10ea |
@@ -764,6 +769,11 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
764 | } | 769 | } |
765 | } | 770 | } |
766 | 771 | ||
772 | if (atkbd_terminal) { | ||
773 | ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB); | ||
774 | return 3; | ||
775 | } | ||
776 | |||
767 | if (target_set != 3) | 777 | if (target_set != 3) |
768 | return 2; | 778 | return 2; |
769 | 779 | ||
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 4b42ffc0532a..d1583aea1721 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c | |||
@@ -127,14 +127,6 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 | |||
127 | idev->id.product = 0x0001; | 127 | idev->id.product = 0x0001; |
128 | idev->id.version = 0x0100; | 128 | idev->id.version = 0x0100; |
129 | 129 | ||
130 | input_set_drvdata(idev, lp); | ||
131 | |||
132 | ret = input_register_device(idev); | ||
133 | if (ret) { | ||
134 | dev_err(&client->dev, "input_register_device() failed\n"); | ||
135 | goto fail_register; | ||
136 | } | ||
137 | |||
138 | lp->laststate = read_state(lp); | 130 | lp->laststate = read_state(lp); |
139 | 131 | ||
140 | ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, | 132 | ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, |
@@ -142,16 +134,21 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 | |||
142 | DRV_NAME, lp); | 134 | DRV_NAME, lp); |
143 | if (ret) { | 135 | if (ret) { |
144 | dev_err(&client->dev, "IRQ %d is not free\n", client->irq); | 136 | dev_err(&client->dev, "IRQ %d is not free\n", client->irq); |
145 | goto fail_irq; | 137 | goto fail_free_device; |
138 | } | ||
139 | |||
140 | ret = input_register_device(idev); | ||
141 | if (ret) { | ||
142 | dev_err(&client->dev, "input_register_device() failed\n"); | ||
143 | goto fail_free_irq; | ||
146 | } | 144 | } |
147 | 145 | ||
148 | i2c_set_clientdata(client, lp); | 146 | i2c_set_clientdata(client, lp); |
149 | return 0; | 147 | return 0; |
150 | 148 | ||
151 | fail_irq: | 149 | fail_free_irq: |
152 | input_unregister_device(idev); | 150 | free_irq(client->irq, lp); |
153 | fail_register: | 151 | fail_free_device: |
154 | input_set_drvdata(idev, NULL); | ||
155 | input_free_device(idev); | 152 | input_free_device(idev); |
156 | fail_allocate: | 153 | fail_allocate: |
157 | kfree(lp); | 154 | kfree(lp); |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index ed7ad7416b24..a5475b577086 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -351,6 +351,17 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
351 | }, | 351 | }, |
352 | }, | 352 | }, |
353 | { | 353 | { |
354 | /* | ||
355 | * Most (all?) VAIOs do not have external PS/2 ports nor | ||
356 | * they implement active multiplexing properly, and | ||
357 | * MUX discovery usually messes up keyboard/touchpad. | ||
358 | */ | ||
359 | .matches = { | ||
360 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
361 | DMI_MATCH(DMI_BOARD_NAME, "VAIO"), | ||
362 | }, | ||
363 | }, | ||
364 | { | ||
354 | /* Amoi M636/A737 */ | 365 | /* Amoi M636/A737 */ |
355 | .matches = { | 366 | .matches = { |
356 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), | 367 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), |
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index aea9a9399a36..d94f7e9aa997 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c | |||
@@ -229,12 +229,13 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
229 | 229 | ||
230 | err = input_register_device(acecad->input); | 230 | err = input_register_device(acecad->input); |
231 | if (err) | 231 | if (err) |
232 | goto fail2; | 232 | goto fail3; |
233 | 233 | ||
234 | usb_set_intfdata(intf, acecad); | 234 | usb_set_intfdata(intf, acecad); |
235 | 235 | ||
236 | return 0; | 236 | return 0; |
237 | 237 | ||
238 | fail3: usb_free_urb(acecad->irq); | ||
238 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); | 239 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); |
239 | fail1: input_free_device(input_dev); | 240 | fail1: input_free_device(input_dev); |
240 | kfree(acecad); | 241 | kfree(acecad); |
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 40b914bded8c..2e72227bd071 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c | |||
@@ -1427,8 +1427,8 @@ modeisar(struct BCState *bcs, int mode, int bc) | |||
1427 | &bcs->hw.isar.reg->Flags)) | 1427 | &bcs->hw.isar.reg->Flags)) |
1428 | bcs->hw.isar.dpath = 1; | 1428 | bcs->hw.isar.dpath = 1; |
1429 | else { | 1429 | else { |
1430 | printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); | 1430 | printk(KERN_WARNING"isar modeisar analog functions only with DP1\n"); |
1431 | debugl1(cs, "isar modeisar analog funktions only with DP1"); | 1431 | debugl1(cs, "isar modeisar analog functions only with DP1"); |
1432 | return(1); | 1432 | return(1); |
1433 | } | 1433 | } |
1434 | break; | 1434 | break; |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index cc2a88d5192f..77b8fd20cd90 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -10,7 +10,7 @@ menuconfig NEW_LEDS | |||
10 | if NEW_LEDS | 10 | if NEW_LEDS |
11 | 11 | ||
12 | config LEDS_CLASS | 12 | config LEDS_CLASS |
13 | tristate "LED Class Support" | 13 | bool "LED Class Support" |
14 | help | 14 | help |
15 | This option enables the led sysfs class in /sys/class/leds. You'll | 15 | This option enables the led sysfs class in /sys/class/leds. You'll |
16 | need this to do anything useful with LEDs. If unsure, say N. | 16 | need this to do anything useful with LEDs. If unsure, say N. |
@@ -176,6 +176,24 @@ config LEDS_LP3944 | |||
176 | To compile this driver as a module, choose M here: the | 176 | To compile this driver as a module, choose M here: the |
177 | module will be called leds-lp3944. | 177 | module will be called leds-lp3944. |
178 | 178 | ||
179 | config LEDS_LP5521 | ||
180 | tristate "LED Support for N.S. LP5521 LED driver chip" | ||
181 | depends on LEDS_CLASS && I2C | ||
182 | help | ||
183 | If you say yes here you get support for the National Semiconductor | ||
184 | LP5521 LED driver. It is 3 channel chip with programmable engines. | ||
185 | Driver provides direct control via LED class and interface for | ||
186 | programming the engines. | ||
187 | |||
188 | config LEDS_LP5523 | ||
189 | tristate "LED Support for N.S. LP5523 LED driver chip" | ||
190 | depends on LEDS_CLASS && I2C | ||
191 | help | ||
192 | If you say yes here you get support for the National Semiconductor | ||
193 | LP5523 LED driver. It is 9 channel chip with programmable engines. | ||
194 | Driver provides direct control via LED class and interface for | ||
195 | programming the engines. | ||
196 | |||
179 | config LEDS_CLEVO_MAIL | 197 | config LEDS_CLEVO_MAIL |
180 | tristate "Mail LED on Clevo notebook" | 198 | tristate "Mail LED on Clevo notebook" |
181 | depends on X86 && SERIO_I8042 && DMI | 199 | depends on X86 && SERIO_I8042 && DMI |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 9c96db40ef6d..aae6989ff6b6 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -23,6 +23,8 @@ obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o | |||
23 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o | 23 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o |
24 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o | 24 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o |
25 | obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o | 25 | obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o |
26 | obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o | ||
27 | obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o | ||
26 | obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o | 28 | obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o |
27 | obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o | 29 | obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o |
28 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o | 30 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 260660076507..211e21f34bd5 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -81,6 +81,79 @@ static struct device_attribute led_class_attrs[] = { | |||
81 | __ATTR_NULL, | 81 | __ATTR_NULL, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static void led_timer_function(unsigned long data) | ||
85 | { | ||
86 | struct led_classdev *led_cdev = (void *)data; | ||
87 | unsigned long brightness; | ||
88 | unsigned long delay; | ||
89 | |||
90 | if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { | ||
91 | led_set_brightness(led_cdev, LED_OFF); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | brightness = led_get_brightness(led_cdev); | ||
96 | if (!brightness) { | ||
97 | /* Time to switch the LED on. */ | ||
98 | brightness = led_cdev->blink_brightness; | ||
99 | delay = led_cdev->blink_delay_on; | ||
100 | } else { | ||
101 | /* Store the current brightness value to be able | ||
102 | * to restore it when the delay_off period is over. | ||
103 | */ | ||
104 | led_cdev->blink_brightness = brightness; | ||
105 | brightness = LED_OFF; | ||
106 | delay = led_cdev->blink_delay_off; | ||
107 | } | ||
108 | |||
109 | led_set_brightness(led_cdev, brightness); | ||
110 | |||
111 | mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); | ||
112 | } | ||
113 | |||
114 | static void led_stop_software_blink(struct led_classdev *led_cdev) | ||
115 | { | ||
116 | /* deactivate previous settings */ | ||
117 | del_timer_sync(&led_cdev->blink_timer); | ||
118 | led_cdev->blink_delay_on = 0; | ||
119 | led_cdev->blink_delay_off = 0; | ||
120 | } | ||
121 | |||
122 | static void led_set_software_blink(struct led_classdev *led_cdev, | ||
123 | unsigned long delay_on, | ||
124 | unsigned long delay_off) | ||
125 | { | ||
126 | int current_brightness; | ||
127 | |||
128 | current_brightness = led_get_brightness(led_cdev); | ||
129 | if (current_brightness) | ||
130 | led_cdev->blink_brightness = current_brightness; | ||
131 | if (!led_cdev->blink_brightness) | ||
132 | led_cdev->blink_brightness = led_cdev->max_brightness; | ||
133 | |||
134 | if (delay_on == led_cdev->blink_delay_on && | ||
135 | delay_off == led_cdev->blink_delay_off) | ||
136 | return; | ||
137 | |||
138 | led_stop_software_blink(led_cdev); | ||
139 | |||
140 | led_cdev->blink_delay_on = delay_on; | ||
141 | led_cdev->blink_delay_off = delay_off; | ||
142 | |||
143 | /* never on - don't blink */ | ||
144 | if (!delay_on) | ||
145 | return; | ||
146 | |||
147 | /* never off - just set to brightness */ | ||
148 | if (!delay_off) { | ||
149 | led_set_brightness(led_cdev, led_cdev->blink_brightness); | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | mod_timer(&led_cdev->blink_timer, jiffies + 1); | ||
154 | } | ||
155 | |||
156 | |||
84 | /** | 157 | /** |
85 | * led_classdev_suspend - suspend an led_classdev. | 158 | * led_classdev_suspend - suspend an led_classdev. |
86 | * @led_cdev: the led_classdev to suspend. | 159 | * @led_cdev: the led_classdev to suspend. |
@@ -148,6 +221,10 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
148 | 221 | ||
149 | led_update_brightness(led_cdev); | 222 | led_update_brightness(led_cdev); |
150 | 223 | ||
224 | init_timer(&led_cdev->blink_timer); | ||
225 | led_cdev->blink_timer.function = led_timer_function; | ||
226 | led_cdev->blink_timer.data = (unsigned long)led_cdev; | ||
227 | |||
151 | #ifdef CONFIG_LEDS_TRIGGERS | 228 | #ifdef CONFIG_LEDS_TRIGGERS |
152 | led_trigger_set_default(led_cdev); | 229 | led_trigger_set_default(led_cdev); |
153 | #endif | 230 | #endif |
@@ -157,7 +234,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
157 | 234 | ||
158 | return 0; | 235 | return 0; |
159 | } | 236 | } |
160 | |||
161 | EXPORT_SYMBOL_GPL(led_classdev_register); | 237 | EXPORT_SYMBOL_GPL(led_classdev_register); |
162 | 238 | ||
163 | /** | 239 | /** |
@@ -175,6 +251,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev) | |||
175 | up_write(&led_cdev->trigger_lock); | 251 | up_write(&led_cdev->trigger_lock); |
176 | #endif | 252 | #endif |
177 | 253 | ||
254 | /* Stop blinking */ | ||
255 | led_brightness_set(led_cdev, LED_OFF); | ||
256 | |||
178 | device_unregister(led_cdev->dev); | 257 | device_unregister(led_cdev->dev); |
179 | 258 | ||
180 | down_write(&leds_list_lock); | 259 | down_write(&leds_list_lock); |
@@ -183,6 +262,30 @@ void led_classdev_unregister(struct led_classdev *led_cdev) | |||
183 | } | 262 | } |
184 | EXPORT_SYMBOL_GPL(led_classdev_unregister); | 263 | EXPORT_SYMBOL_GPL(led_classdev_unregister); |
185 | 264 | ||
265 | void led_blink_set(struct led_classdev *led_cdev, | ||
266 | unsigned long *delay_on, | ||
267 | unsigned long *delay_off) | ||
268 | { | ||
269 | if (led_cdev->blink_set && | ||
270 | led_cdev->blink_set(led_cdev, delay_on, delay_off)) | ||
271 | return; | ||
272 | |||
273 | /* blink with 1 Hz as default if nothing specified */ | ||
274 | if (!*delay_on && !*delay_off) | ||
275 | *delay_on = *delay_off = 500; | ||
276 | |||
277 | led_set_software_blink(led_cdev, *delay_on, *delay_off); | ||
278 | } | ||
279 | EXPORT_SYMBOL(led_blink_set); | ||
280 | |||
281 | void led_brightness_set(struct led_classdev *led_cdev, | ||
282 | enum led_brightness brightness) | ||
283 | { | ||
284 | led_stop_software_blink(led_cdev); | ||
285 | led_cdev->brightness_set(led_cdev, brightness); | ||
286 | } | ||
287 | EXPORT_SYMBOL(led_brightness_set); | ||
288 | |||
186 | static int __init leds_init(void) | 289 | static int __init leds_init(void) |
187 | { | 290 | { |
188 | leds_class = class_create(THIS_MODULE, "leds"); | 291 | leds_class = class_create(THIS_MODULE, "leds"); |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index f1c00db88b5e..c41eb6180c9c 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -113,7 +113,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) | |||
113 | if (led_cdev->trigger->deactivate) | 113 | if (led_cdev->trigger->deactivate) |
114 | led_cdev->trigger->deactivate(led_cdev); | 114 | led_cdev->trigger->deactivate(led_cdev); |
115 | led_cdev->trigger = NULL; | 115 | led_cdev->trigger = NULL; |
116 | led_set_brightness(led_cdev, LED_OFF); | 116 | led_brightness_set(led_cdev, LED_OFF); |
117 | } | 117 | } |
118 | if (trigger) { | 118 | if (trigger) { |
119 | write_lock_irqsave(&trigger->leddev_list_lock, flags); | 119 | write_lock_irqsave(&trigger->leddev_list_lock, flags); |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index ea57e05d08f3..4d9fa38d9ff6 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -316,7 +316,7 @@ static struct of_platform_driver of_gpio_leds_driver = { | |||
316 | 316 | ||
317 | static int __init gpio_led_init(void) | 317 | static int __init gpio_led_init(void) |
318 | { | 318 | { |
319 | int ret; | 319 | int ret = 0; |
320 | 320 | ||
321 | #ifdef CONFIG_LEDS_GPIO_PLATFORM | 321 | #ifdef CONFIG_LEDS_GPIO_PLATFORM |
322 | ret = platform_driver_register(&gpio_led_driver); | 322 | ret = platform_driver_register(&gpio_led_driver); |
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c new file mode 100644 index 000000000000..3782f31f06d2 --- /dev/null +++ b/drivers/leds/leds-lp5521.c | |||
@@ -0,0 +1,821 @@ | |||
1 | /* | ||
2 | * LP5521 LED chip driver. | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/ctype.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/wait.h> | ||
33 | #include <linux/leds.h> | ||
34 | #include <linux/leds-lp5521.h> | ||
35 | #include <linux/workqueue.h> | ||
36 | #include <linux/slab.h> | ||
37 | |||
38 | #define LP5521_PROGRAM_LENGTH 32 /* in bytes */ | ||
39 | |||
40 | #define LP5521_MAX_LEDS 3 /* Maximum number of LEDs */ | ||
41 | #define LP5521_MAX_ENGINES 3 /* Maximum number of engines */ | ||
42 | |||
43 | #define LP5521_ENG_MASK_BASE 0x30 /* 00110000 */ | ||
44 | #define LP5521_ENG_STATUS_MASK 0x07 /* 00000111 */ | ||
45 | |||
46 | #define LP5521_CMD_LOAD 0x15 /* 00010101 */ | ||
47 | #define LP5521_CMD_RUN 0x2a /* 00101010 */ | ||
48 | #define LP5521_CMD_DIRECT 0x3f /* 00111111 */ | ||
49 | #define LP5521_CMD_DISABLED 0x00 /* 00000000 */ | ||
50 | |||
51 | /* Registers */ | ||
52 | #define LP5521_REG_ENABLE 0x00 | ||
53 | #define LP5521_REG_OP_MODE 0x01 | ||
54 | #define LP5521_REG_R_PWM 0x02 | ||
55 | #define LP5521_REG_G_PWM 0x03 | ||
56 | #define LP5521_REG_B_PWM 0x04 | ||
57 | #define LP5521_REG_R_CURRENT 0x05 | ||
58 | #define LP5521_REG_G_CURRENT 0x06 | ||
59 | #define LP5521_REG_B_CURRENT 0x07 | ||
60 | #define LP5521_REG_CONFIG 0x08 | ||
61 | #define LP5521_REG_R_CHANNEL_PC 0x09 | ||
62 | #define LP5521_REG_G_CHANNEL_PC 0x0A | ||
63 | #define LP5521_REG_B_CHANNEL_PC 0x0B | ||
64 | #define LP5521_REG_STATUS 0x0C | ||
65 | #define LP5521_REG_RESET 0x0D | ||
66 | #define LP5521_REG_GPO 0x0E | ||
67 | #define LP5521_REG_R_PROG_MEM 0x10 | ||
68 | #define LP5521_REG_G_PROG_MEM 0x30 | ||
69 | #define LP5521_REG_B_PROG_MEM 0x50 | ||
70 | |||
71 | #define LP5521_PROG_MEM_BASE LP5521_REG_R_PROG_MEM | ||
72 | #define LP5521_PROG_MEM_SIZE 0x20 | ||
73 | |||
74 | /* Base register to set LED current */ | ||
75 | #define LP5521_REG_LED_CURRENT_BASE LP5521_REG_R_CURRENT | ||
76 | |||
77 | /* Base register to set the brightness */ | ||
78 | #define LP5521_REG_LED_PWM_BASE LP5521_REG_R_PWM | ||
79 | |||
80 | /* Bits in ENABLE register */ | ||
81 | #define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */ | ||
82 | #define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */ | ||
83 | #define LP5521_EXEC_RUN 0x2A | ||
84 | |||
85 | /* Bits in CONFIG register */ | ||
86 | #define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */ | ||
87 | #define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */ | ||
88 | #define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */ | ||
89 | #define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */ | ||
90 | #define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */ | ||
91 | #define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */ | ||
92 | #define LP5521_R_TO_BATT 4 /* R out: 0 = CP, 1 = Vbat */ | ||
93 | #define LP5521_CLK_SRC_EXT 0 /* Ext-clk source (CLK_32K) */ | ||
94 | #define LP5521_CLK_INT 1 /* Internal clock */ | ||
95 | #define LP5521_CLK_AUTO 2 /* Automatic clock selection */ | ||
96 | |||
97 | /* Status */ | ||
98 | #define LP5521_EXT_CLK_USED 0x08 | ||
99 | |||
100 | struct lp5521_engine { | ||
101 | const struct attribute_group *attributes; | ||
102 | int id; | ||
103 | u8 mode; | ||
104 | u8 prog_page; | ||
105 | u8 engine_mask; | ||
106 | }; | ||
107 | |||
108 | struct lp5521_led { | ||
109 | int id; | ||
110 | u8 chan_nr; | ||
111 | u8 led_current; | ||
112 | u8 max_current; | ||
113 | struct led_classdev cdev; | ||
114 | struct work_struct brightness_work; | ||
115 | u8 brightness; | ||
116 | }; | ||
117 | |||
118 | struct lp5521_chip { | ||
119 | struct lp5521_platform_data *pdata; | ||
120 | struct mutex lock; /* Serialize control */ | ||
121 | struct i2c_client *client; | ||
122 | struct lp5521_engine engines[LP5521_MAX_ENGINES]; | ||
123 | struct lp5521_led leds[LP5521_MAX_LEDS]; | ||
124 | u8 num_channels; | ||
125 | u8 num_leds; | ||
126 | }; | ||
127 | |||
128 | #define cdev_to_led(c) container_of(c, struct lp5521_led, cdev) | ||
129 | #define engine_to_lp5521(eng) container_of((eng), struct lp5521_chip, \ | ||
130 | engines[(eng)->id - 1]) | ||
131 | #define led_to_lp5521(led) container_of((led), struct lp5521_chip, \ | ||
132 | leds[(led)->id]) | ||
133 | |||
134 | static void lp5521_led_brightness_work(struct work_struct *work); | ||
135 | |||
136 | static inline int lp5521_write(struct i2c_client *client, u8 reg, u8 value) | ||
137 | { | ||
138 | return i2c_smbus_write_byte_data(client, reg, value); | ||
139 | } | ||
140 | |||
141 | static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf) | ||
142 | { | ||
143 | s32 ret; | ||
144 | |||
145 | ret = i2c_smbus_read_byte_data(client, reg); | ||
146 | if (ret < 0) | ||
147 | return -EIO; | ||
148 | |||
149 | *buf = ret; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode) | ||
154 | { | ||
155 | struct lp5521_chip *chip = engine_to_lp5521(engine); | ||
156 | struct i2c_client *client = chip->client; | ||
157 | int ret; | ||
158 | u8 engine_state; | ||
159 | |||
160 | /* Only transition between RUN and DIRECT mode are handled here */ | ||
161 | if (mode == LP5521_CMD_LOAD) | ||
162 | return 0; | ||
163 | |||
164 | if (mode == LP5521_CMD_DISABLED) | ||
165 | mode = LP5521_CMD_DIRECT; | ||
166 | |||
167 | ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); | ||
168 | |||
169 | /* set mode only for this engine */ | ||
170 | engine_state &= ~(engine->engine_mask); | ||
171 | mode &= engine->engine_mask; | ||
172 | engine_state |= mode; | ||
173 | ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state); | ||
174 | |||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) | ||
179 | { | ||
180 | struct lp5521_chip *chip = engine_to_lp5521(eng); | ||
181 | struct i2c_client *client = chip->client; | ||
182 | int ret; | ||
183 | int addr; | ||
184 | u8 mode; | ||
185 | |||
186 | /* move current engine to direct mode and remember the state */ | ||
187 | ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT); | ||
188 | usleep_range(1000, 10000); | ||
189 | ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode); | ||
190 | |||
191 | /* For loading, all the engines to load mode */ | ||
192 | lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); | ||
193 | usleep_range(1000, 10000); | ||
194 | lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD); | ||
195 | usleep_range(1000, 10000); | ||
196 | |||
197 | addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE; | ||
198 | i2c_smbus_write_i2c_block_data(client, | ||
199 | addr, | ||
200 | LP5521_PROG_MEM_SIZE, | ||
201 | pattern); | ||
202 | |||
203 | ret |= lp5521_write(client, LP5521_REG_OP_MODE, mode); | ||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) | ||
208 | { | ||
209 | return lp5521_write(chip->client, | ||
210 | LP5521_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, | ||
211 | curr); | ||
212 | } | ||
213 | |||
214 | static void lp5521_init_engine(struct lp5521_chip *chip, | ||
215 | const struct attribute_group *attr_group) | ||
216 | { | ||
217 | int i; | ||
218 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | ||
219 | chip->engines[i].id = i + 1; | ||
220 | chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); | ||
221 | chip->engines[i].prog_page = i; | ||
222 | chip->engines[i].attributes = &attr_group[i]; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | static int lp5521_configure(struct i2c_client *client, | ||
227 | const struct attribute_group *attr_group) | ||
228 | { | ||
229 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
230 | int ret; | ||
231 | |||
232 | lp5521_init_engine(chip, attr_group); | ||
233 | |||
234 | lp5521_write(client, LP5521_REG_RESET, 0xff); | ||
235 | |||
236 | usleep_range(10000, 20000); | ||
237 | |||
238 | /* Set all PWMs to direct control mode */ | ||
239 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); | ||
240 | |||
241 | /* Enable auto-powersave, set charge pump to auto, red to battery */ | ||
242 | ret |= lp5521_write(client, LP5521_REG_CONFIG, | ||
243 | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); | ||
244 | |||
245 | /* Initialize all channels PWM to zero -> leds off */ | ||
246 | ret |= lp5521_write(client, LP5521_REG_R_PWM, 0); | ||
247 | ret |= lp5521_write(client, LP5521_REG_G_PWM, 0); | ||
248 | ret |= lp5521_write(client, LP5521_REG_B_PWM, 0); | ||
249 | |||
250 | /* Set engines are set to run state when OP_MODE enables engines */ | ||
251 | ret |= lp5521_write(client, LP5521_REG_ENABLE, | ||
252 | LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM | | ||
253 | LP5521_EXEC_RUN); | ||
254 | /* enable takes 500us */ | ||
255 | usleep_range(500, 20000); | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf) | ||
261 | { | ||
262 | int ret; | ||
263 | u8 status; | ||
264 | |||
265 | ret = lp5521_read(chip->client, LP5521_REG_STATUS, &status); | ||
266 | if (ret < 0) | ||
267 | return ret; | ||
268 | |||
269 | /* Check that ext clock is really in use if requested */ | ||
270 | if (chip->pdata && chip->pdata->clock_mode == LP5521_CLOCK_EXT) | ||
271 | if ((status & LP5521_EXT_CLK_USED) == 0) | ||
272 | return -EIO; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static void lp5521_set_brightness(struct led_classdev *cdev, | ||
277 | enum led_brightness brightness) | ||
278 | { | ||
279 | struct lp5521_led *led = cdev_to_led(cdev); | ||
280 | led->brightness = (u8)brightness; | ||
281 | schedule_work(&led->brightness_work); | ||
282 | } | ||
283 | |||
284 | static void lp5521_led_brightness_work(struct work_struct *work) | ||
285 | { | ||
286 | struct lp5521_led *led = container_of(work, | ||
287 | struct lp5521_led, | ||
288 | brightness_work); | ||
289 | struct lp5521_chip *chip = led_to_lp5521(led); | ||
290 | struct i2c_client *client = chip->client; | ||
291 | |||
292 | mutex_lock(&chip->lock); | ||
293 | lp5521_write(client, LP5521_REG_LED_PWM_BASE + led->chan_nr, | ||
294 | led->brightness); | ||
295 | mutex_unlock(&chip->lock); | ||
296 | } | ||
297 | |||
298 | /* Detect the chip by setting its ENABLE register and reading it back. */ | ||
299 | static int lp5521_detect(struct i2c_client *client) | ||
300 | { | ||
301 | int ret; | ||
302 | u8 buf; | ||
303 | |||
304 | ret = lp5521_write(client, LP5521_REG_ENABLE, | ||
305 | LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM); | ||
306 | if (ret) | ||
307 | return ret; | ||
308 | usleep_range(1000, 10000); | ||
309 | ret = lp5521_read(client, LP5521_REG_ENABLE, &buf); | ||
310 | if (ret) | ||
311 | return ret; | ||
312 | if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)) | ||
313 | return -ENODEV; | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | /* Set engine mode and create appropriate sysfs attributes, if required. */ | ||
319 | static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) | ||
320 | { | ||
321 | struct lp5521_chip *chip = engine_to_lp5521(engine); | ||
322 | struct i2c_client *client = chip->client; | ||
323 | struct device *dev = &client->dev; | ||
324 | int ret = 0; | ||
325 | |||
326 | /* if in that mode already do nothing, except for run */ | ||
327 | if (mode == engine->mode && mode != LP5521_CMD_RUN) | ||
328 | return 0; | ||
329 | |||
330 | if (mode == LP5521_CMD_RUN) { | ||
331 | ret = lp5521_set_engine_mode(engine, LP5521_CMD_RUN); | ||
332 | } else if (mode == LP5521_CMD_LOAD) { | ||
333 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); | ||
334 | lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); | ||
335 | |||
336 | ret = sysfs_create_group(&dev->kobj, engine->attributes); | ||
337 | if (ret) | ||
338 | return ret; | ||
339 | } else if (mode == LP5521_CMD_DISABLED) { | ||
340 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); | ||
341 | } | ||
342 | |||
343 | /* remove load attribute from sysfs if not in load mode */ | ||
344 | if (engine->mode == LP5521_CMD_LOAD && mode != LP5521_CMD_LOAD) | ||
345 | sysfs_remove_group(&dev->kobj, engine->attributes); | ||
346 | |||
347 | engine->mode = mode; | ||
348 | |||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | static int lp5521_do_store_load(struct lp5521_engine *engine, | ||
353 | const char *buf, size_t len) | ||
354 | { | ||
355 | struct lp5521_chip *chip = engine_to_lp5521(engine); | ||
356 | struct i2c_client *client = chip->client; | ||
357 | int ret, nrchars, offset = 0, i = 0; | ||
358 | char c[3]; | ||
359 | unsigned cmd; | ||
360 | u8 pattern[LP5521_PROGRAM_LENGTH] = {0}; | ||
361 | |||
362 | while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) { | ||
363 | /* separate sscanfs because length is working only for %s */ | ||
364 | ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); | ||
365 | ret = sscanf(c, "%2x", &cmd); | ||
366 | if (ret != 1) | ||
367 | goto fail; | ||
368 | pattern[i] = (u8)cmd; | ||
369 | |||
370 | offset += nrchars; | ||
371 | i++; | ||
372 | } | ||
373 | |||
374 | /* Each instruction is 16bit long. Check that length is even */ | ||
375 | if (i % 2) | ||
376 | goto fail; | ||
377 | |||
378 | mutex_lock(&chip->lock); | ||
379 | ret = lp5521_load_program(engine, pattern); | ||
380 | mutex_unlock(&chip->lock); | ||
381 | |||
382 | if (ret) { | ||
383 | dev_err(&client->dev, "failed loading pattern\n"); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | return len; | ||
388 | fail: | ||
389 | dev_err(&client->dev, "wrong pattern format\n"); | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | |||
393 | static ssize_t store_engine_load(struct device *dev, | ||
394 | struct device_attribute *attr, | ||
395 | const char *buf, size_t len, int nr) | ||
396 | { | ||
397 | struct i2c_client *client = to_i2c_client(dev); | ||
398 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
399 | return lp5521_do_store_load(&chip->engines[nr - 1], buf, len); | ||
400 | } | ||
401 | |||
402 | #define store_load(nr) \ | ||
403 | static ssize_t store_engine##nr##_load(struct device *dev, \ | ||
404 | struct device_attribute *attr, \ | ||
405 | const char *buf, size_t len) \ | ||
406 | { \ | ||
407 | return store_engine_load(dev, attr, buf, len, nr); \ | ||
408 | } | ||
409 | store_load(1) | ||
410 | store_load(2) | ||
411 | store_load(3) | ||
412 | |||
413 | static ssize_t show_engine_mode(struct device *dev, | ||
414 | struct device_attribute *attr, | ||
415 | char *buf, int nr) | ||
416 | { | ||
417 | struct i2c_client *client = to_i2c_client(dev); | ||
418 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
419 | switch (chip->engines[nr - 1].mode) { | ||
420 | case LP5521_CMD_RUN: | ||
421 | return sprintf(buf, "run\n"); | ||
422 | case LP5521_CMD_LOAD: | ||
423 | return sprintf(buf, "load\n"); | ||
424 | case LP5521_CMD_DISABLED: | ||
425 | return sprintf(buf, "disabled\n"); | ||
426 | default: | ||
427 | return sprintf(buf, "disabled\n"); | ||
428 | } | ||
429 | } | ||
430 | |||
431 | #define show_mode(nr) \ | ||
432 | static ssize_t show_engine##nr##_mode(struct device *dev, \ | ||
433 | struct device_attribute *attr, \ | ||
434 | char *buf) \ | ||
435 | { \ | ||
436 | return show_engine_mode(dev, attr, buf, nr); \ | ||
437 | } | ||
438 | show_mode(1) | ||
439 | show_mode(2) | ||
440 | show_mode(3) | ||
441 | |||
442 | static ssize_t store_engine_mode(struct device *dev, | ||
443 | struct device_attribute *attr, | ||
444 | const char *buf, size_t len, int nr) | ||
445 | { | ||
446 | struct i2c_client *client = to_i2c_client(dev); | ||
447 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
448 | struct lp5521_engine *engine = &chip->engines[nr - 1]; | ||
449 | mutex_lock(&chip->lock); | ||
450 | |||
451 | if (!strncmp(buf, "run", 3)) | ||
452 | lp5521_set_mode(engine, LP5521_CMD_RUN); | ||
453 | else if (!strncmp(buf, "load", 4)) | ||
454 | lp5521_set_mode(engine, LP5521_CMD_LOAD); | ||
455 | else if (!strncmp(buf, "disabled", 8)) | ||
456 | lp5521_set_mode(engine, LP5521_CMD_DISABLED); | ||
457 | |||
458 | mutex_unlock(&chip->lock); | ||
459 | return len; | ||
460 | } | ||
461 | |||
462 | #define store_mode(nr) \ | ||
463 | static ssize_t store_engine##nr##_mode(struct device *dev, \ | ||
464 | struct device_attribute *attr, \ | ||
465 | const char *buf, size_t len) \ | ||
466 | { \ | ||
467 | return store_engine_mode(dev, attr, buf, len, nr); \ | ||
468 | } | ||
469 | store_mode(1) | ||
470 | store_mode(2) | ||
471 | store_mode(3) | ||
472 | |||
473 | static ssize_t show_max_current(struct device *dev, | ||
474 | struct device_attribute *attr, | ||
475 | char *buf) | ||
476 | { | ||
477 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
478 | struct lp5521_led *led = cdev_to_led(led_cdev); | ||
479 | |||
480 | return sprintf(buf, "%d\n", led->max_current); | ||
481 | } | ||
482 | |||
483 | static ssize_t show_current(struct device *dev, | ||
484 | struct device_attribute *attr, | ||
485 | char *buf) | ||
486 | { | ||
487 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
488 | struct lp5521_led *led = cdev_to_led(led_cdev); | ||
489 | |||
490 | return sprintf(buf, "%d\n", led->led_current); | ||
491 | } | ||
492 | |||
493 | static ssize_t store_current(struct device *dev, | ||
494 | struct device_attribute *attr, | ||
495 | const char *buf, size_t len) | ||
496 | { | ||
497 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
498 | struct lp5521_led *led = cdev_to_led(led_cdev); | ||
499 | struct lp5521_chip *chip = led_to_lp5521(led); | ||
500 | ssize_t ret; | ||
501 | unsigned long curr; | ||
502 | |||
503 | if (strict_strtoul(buf, 0, &curr)) | ||
504 | return -EINVAL; | ||
505 | |||
506 | if (curr > led->max_current) | ||
507 | return -EINVAL; | ||
508 | |||
509 | mutex_lock(&chip->lock); | ||
510 | ret = lp5521_set_led_current(chip, led->id, curr); | ||
511 | mutex_unlock(&chip->lock); | ||
512 | |||
513 | if (ret < 0) | ||
514 | return ret; | ||
515 | |||
516 | led->led_current = (u8)curr; | ||
517 | |||
518 | return len; | ||
519 | } | ||
520 | |||
521 | static ssize_t lp5521_selftest(struct device *dev, | ||
522 | struct device_attribute *attr, | ||
523 | char *buf) | ||
524 | { | ||
525 | struct i2c_client *client = to_i2c_client(dev); | ||
526 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
527 | int ret; | ||
528 | |||
529 | mutex_lock(&chip->lock); | ||
530 | ret = lp5521_run_selftest(chip, buf); | ||
531 | mutex_unlock(&chip->lock); | ||
532 | return sprintf(buf, "%s\n", ret ? "FAIL" : "OK"); | ||
533 | } | ||
534 | |||
535 | /* led class device attributes */ | ||
536 | static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); | ||
537 | static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); | ||
538 | |||
539 | static struct attribute *lp5521_led_attributes[] = { | ||
540 | &dev_attr_led_current.attr, | ||
541 | &dev_attr_max_current.attr, | ||
542 | NULL, | ||
543 | }; | ||
544 | |||
545 | static struct attribute_group lp5521_led_attribute_group = { | ||
546 | .attrs = lp5521_led_attributes | ||
547 | }; | ||
548 | |||
549 | /* device attributes */ | ||
550 | static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, | ||
551 | show_engine1_mode, store_engine1_mode); | ||
552 | static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, | ||
553 | show_engine2_mode, store_engine2_mode); | ||
554 | static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, | ||
555 | show_engine3_mode, store_engine3_mode); | ||
556 | static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); | ||
557 | static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); | ||
558 | static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); | ||
559 | static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); | ||
560 | |||
561 | static struct attribute *lp5521_attributes[] = { | ||
562 | &dev_attr_engine1_mode.attr, | ||
563 | &dev_attr_engine2_mode.attr, | ||
564 | &dev_attr_engine3_mode.attr, | ||
565 | &dev_attr_selftest.attr, | ||
566 | NULL | ||
567 | }; | ||
568 | |||
569 | static struct attribute *lp5521_engine1_attributes[] = { | ||
570 | &dev_attr_engine1_load.attr, | ||
571 | NULL | ||
572 | }; | ||
573 | |||
574 | static struct attribute *lp5521_engine2_attributes[] = { | ||
575 | &dev_attr_engine2_load.attr, | ||
576 | NULL | ||
577 | }; | ||
578 | |||
579 | static struct attribute *lp5521_engine3_attributes[] = { | ||
580 | &dev_attr_engine3_load.attr, | ||
581 | NULL | ||
582 | }; | ||
583 | |||
584 | static const struct attribute_group lp5521_group = { | ||
585 | .attrs = lp5521_attributes, | ||
586 | }; | ||
587 | |||
588 | static const struct attribute_group lp5521_engine_group[] = { | ||
589 | {.attrs = lp5521_engine1_attributes }, | ||
590 | {.attrs = lp5521_engine2_attributes }, | ||
591 | {.attrs = lp5521_engine3_attributes }, | ||
592 | }; | ||
593 | |||
594 | static int lp5521_register_sysfs(struct i2c_client *client) | ||
595 | { | ||
596 | struct device *dev = &client->dev; | ||
597 | return sysfs_create_group(&dev->kobj, &lp5521_group); | ||
598 | } | ||
599 | |||
600 | static void lp5521_unregister_sysfs(struct i2c_client *client) | ||
601 | { | ||
602 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
603 | struct device *dev = &client->dev; | ||
604 | int i; | ||
605 | |||
606 | sysfs_remove_group(&dev->kobj, &lp5521_group); | ||
607 | |||
608 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | ||
609 | if (chip->engines[i].mode == LP5521_CMD_LOAD) | ||
610 | sysfs_remove_group(&dev->kobj, | ||
611 | chip->engines[i].attributes); | ||
612 | } | ||
613 | |||
614 | for (i = 0; i < chip->num_leds; i++) | ||
615 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, | ||
616 | &lp5521_led_attribute_group); | ||
617 | } | ||
618 | |||
619 | static int __init lp5521_init_led(struct lp5521_led *led, | ||
620 | struct i2c_client *client, | ||
621 | int chan, struct lp5521_platform_data *pdata) | ||
622 | { | ||
623 | struct device *dev = &client->dev; | ||
624 | char name[32]; | ||
625 | int res; | ||
626 | |||
627 | if (chan >= LP5521_MAX_LEDS) | ||
628 | return -EINVAL; | ||
629 | |||
630 | if (pdata->led_config[chan].led_current == 0) | ||
631 | return 0; | ||
632 | |||
633 | led->led_current = pdata->led_config[chan].led_current; | ||
634 | led->max_current = pdata->led_config[chan].max_current; | ||
635 | led->chan_nr = pdata->led_config[chan].chan_nr; | ||
636 | |||
637 | if (led->chan_nr >= LP5521_MAX_LEDS) { | ||
638 | dev_err(dev, "Use channel numbers between 0 and %d\n", | ||
639 | LP5521_MAX_LEDS - 1); | ||
640 | return -EINVAL; | ||
641 | } | ||
642 | |||
643 | snprintf(name, sizeof(name), "%s:channel%d", client->name, chan); | ||
644 | led->cdev.brightness_set = lp5521_set_brightness; | ||
645 | led->cdev.name = name; | ||
646 | res = led_classdev_register(dev, &led->cdev); | ||
647 | if (res < 0) { | ||
648 | dev_err(dev, "couldn't register led on channel %d\n", chan); | ||
649 | return res; | ||
650 | } | ||
651 | |||
652 | res = sysfs_create_group(&led->cdev.dev->kobj, | ||
653 | &lp5521_led_attribute_group); | ||
654 | if (res < 0) { | ||
655 | dev_err(dev, "couldn't register current attribute\n"); | ||
656 | led_classdev_unregister(&led->cdev); | ||
657 | return res; | ||
658 | } | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static int lp5521_probe(struct i2c_client *client, | ||
663 | const struct i2c_device_id *id) | ||
664 | { | ||
665 | struct lp5521_chip *chip; | ||
666 | struct lp5521_platform_data *pdata; | ||
667 | int ret, i, led; | ||
668 | |||
669 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
670 | if (!chip) | ||
671 | return -ENOMEM; | ||
672 | |||
673 | i2c_set_clientdata(client, chip); | ||
674 | chip->client = client; | ||
675 | |||
676 | pdata = client->dev.platform_data; | ||
677 | |||
678 | if (!pdata) { | ||
679 | dev_err(&client->dev, "no platform data\n"); | ||
680 | ret = -EINVAL; | ||
681 | goto fail1; | ||
682 | } | ||
683 | |||
684 | mutex_init(&chip->lock); | ||
685 | |||
686 | chip->pdata = pdata; | ||
687 | |||
688 | if (pdata->setup_resources) { | ||
689 | ret = pdata->setup_resources(); | ||
690 | if (ret < 0) | ||
691 | goto fail1; | ||
692 | } | ||
693 | |||
694 | if (pdata->enable) { | ||
695 | pdata->enable(0); | ||
696 | usleep_range(1000, 10000); | ||
697 | pdata->enable(1); | ||
698 | usleep_range(1000, 10000); /* Spec says min 500us */ | ||
699 | } | ||
700 | |||
701 | ret = lp5521_detect(client); | ||
702 | |||
703 | if (ret) { | ||
704 | dev_err(&client->dev, "Chip not found\n"); | ||
705 | goto fail2; | ||
706 | } | ||
707 | |||
708 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); | ||
709 | |||
710 | ret = lp5521_configure(client, lp5521_engine_group); | ||
711 | if (ret < 0) { | ||
712 | dev_err(&client->dev, "error configuring chip\n"); | ||
713 | goto fail2; | ||
714 | } | ||
715 | |||
716 | /* Initialize leds */ | ||
717 | chip->num_channels = pdata->num_channels; | ||
718 | chip->num_leds = 0; | ||
719 | led = 0; | ||
720 | for (i = 0; i < pdata->num_channels; i++) { | ||
721 | /* Do not initialize channels that are not connected */ | ||
722 | if (pdata->led_config[i].led_current == 0) | ||
723 | continue; | ||
724 | |||
725 | ret = lp5521_init_led(&chip->leds[led], client, i, pdata); | ||
726 | if (ret) { | ||
727 | dev_err(&client->dev, "error initializing leds\n"); | ||
728 | goto fail3; | ||
729 | } | ||
730 | chip->num_leds++; | ||
731 | |||
732 | chip->leds[led].id = led; | ||
733 | /* Set initial LED current */ | ||
734 | lp5521_set_led_current(chip, led, | ||
735 | chip->leds[led].led_current); | ||
736 | |||
737 | INIT_WORK(&(chip->leds[led].brightness_work), | ||
738 | lp5521_led_brightness_work); | ||
739 | |||
740 | led++; | ||
741 | } | ||
742 | |||
743 | ret = lp5521_register_sysfs(client); | ||
744 | if (ret) { | ||
745 | dev_err(&client->dev, "registering sysfs failed\n"); | ||
746 | goto fail3; | ||
747 | } | ||
748 | return ret; | ||
749 | fail3: | ||
750 | for (i = 0; i < chip->num_leds; i++) { | ||
751 | led_classdev_unregister(&chip->leds[i].cdev); | ||
752 | cancel_work_sync(&chip->leds[i].brightness_work); | ||
753 | } | ||
754 | fail2: | ||
755 | if (pdata->enable) | ||
756 | pdata->enable(0); | ||
757 | if (pdata->release_resources) | ||
758 | pdata->release_resources(); | ||
759 | fail1: | ||
760 | kfree(chip); | ||
761 | return ret; | ||
762 | } | ||
763 | |||
764 | static int lp5521_remove(struct i2c_client *client) | ||
765 | { | ||
766 | struct lp5521_chip *chip = i2c_get_clientdata(client); | ||
767 | int i; | ||
768 | |||
769 | lp5521_unregister_sysfs(client); | ||
770 | |||
771 | for (i = 0; i < chip->num_leds; i++) { | ||
772 | led_classdev_unregister(&chip->leds[i].cdev); | ||
773 | cancel_work_sync(&chip->leds[i].brightness_work); | ||
774 | } | ||
775 | |||
776 | if (chip->pdata->enable) | ||
777 | chip->pdata->enable(0); | ||
778 | if (chip->pdata->release_resources) | ||
779 | chip->pdata->release_resources(); | ||
780 | kfree(chip); | ||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static const struct i2c_device_id lp5521_id[] = { | ||
785 | { "lp5521", 0 }, /* Three channel chip */ | ||
786 | { } | ||
787 | }; | ||
788 | MODULE_DEVICE_TABLE(i2c, lp5521_id); | ||
789 | |||
790 | static struct i2c_driver lp5521_driver = { | ||
791 | .driver = { | ||
792 | .name = "lp5521", | ||
793 | }, | ||
794 | .probe = lp5521_probe, | ||
795 | .remove = lp5521_remove, | ||
796 | .id_table = lp5521_id, | ||
797 | }; | ||
798 | |||
799 | static int __init lp5521_init(void) | ||
800 | { | ||
801 | int ret; | ||
802 | |||
803 | ret = i2c_add_driver(&lp5521_driver); | ||
804 | |||
805 | if (ret < 0) | ||
806 | printk(KERN_ALERT "Adding lp5521 driver failed\n"); | ||
807 | |||
808 | return ret; | ||
809 | } | ||
810 | |||
811 | static void __exit lp5521_exit(void) | ||
812 | { | ||
813 | i2c_del_driver(&lp5521_driver); | ||
814 | } | ||
815 | |||
816 | module_init(lp5521_init); | ||
817 | module_exit(lp5521_exit); | ||
818 | |||
819 | MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo"); | ||
820 | MODULE_DESCRIPTION("LP5521 LED engine"); | ||
821 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c new file mode 100644 index 000000000000..1e11fcc08b28 --- /dev/null +++ b/drivers/leds/leds-lp5523.c | |||
@@ -0,0 +1,1065 @@ | |||
1 | /* | ||
2 | * lp5523.c - LP5523 LED Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/ctype.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/wait.h> | ||
33 | #include <linux/leds.h> | ||
34 | #include <linux/leds-lp5523.h> | ||
35 | #include <linux/workqueue.h> | ||
36 | #include <linux/slab.h> | ||
37 | |||
38 | #define LP5523_REG_ENABLE 0x00 | ||
39 | #define LP5523_REG_OP_MODE 0x01 | ||
40 | #define LP5523_REG_RATIOMETRIC_MSB 0x02 | ||
41 | #define LP5523_REG_RATIOMETRIC_LSB 0x03 | ||
42 | #define LP5523_REG_ENABLE_LEDS_MSB 0x04 | ||
43 | #define LP5523_REG_ENABLE_LEDS_LSB 0x05 | ||
44 | #define LP5523_REG_LED_CNTRL_BASE 0x06 | ||
45 | #define LP5523_REG_LED_PWM_BASE 0x16 | ||
46 | #define LP5523_REG_LED_CURRENT_BASE 0x26 | ||
47 | #define LP5523_REG_CONFIG 0x36 | ||
48 | #define LP5523_REG_CHANNEL1_PC 0x37 | ||
49 | #define LP5523_REG_CHANNEL2_PC 0x38 | ||
50 | #define LP5523_REG_CHANNEL3_PC 0x39 | ||
51 | #define LP5523_REG_STATUS 0x3a | ||
52 | #define LP5523_REG_GPO 0x3b | ||
53 | #define LP5523_REG_VARIABLE 0x3c | ||
54 | #define LP5523_REG_RESET 0x3d | ||
55 | #define LP5523_REG_TEMP_CTRL 0x3e | ||
56 | #define LP5523_REG_TEMP_READ 0x3f | ||
57 | #define LP5523_REG_TEMP_WRITE 0x40 | ||
58 | #define LP5523_REG_LED_TEST_CTRL 0x41 | ||
59 | #define LP5523_REG_LED_TEST_ADC 0x42 | ||
60 | #define LP5523_REG_ENG1_VARIABLE 0x45 | ||
61 | #define LP5523_REG_ENG2_VARIABLE 0x46 | ||
62 | #define LP5523_REG_ENG3_VARIABLE 0x47 | ||
63 | #define LP5523_REG_MASTER_FADER1 0x48 | ||
64 | #define LP5523_REG_MASTER_FADER2 0x49 | ||
65 | #define LP5523_REG_MASTER_FADER3 0x4a | ||
66 | #define LP5523_REG_CH1_PROG_START 0x4c | ||
67 | #define LP5523_REG_CH2_PROG_START 0x4d | ||
68 | #define LP5523_REG_CH3_PROG_START 0x4e | ||
69 | #define LP5523_REG_PROG_PAGE_SEL 0x4f | ||
70 | #define LP5523_REG_PROG_MEM 0x50 | ||
71 | |||
72 | #define LP5523_CMD_LOAD 0x15 /* 00010101 */ | ||
73 | #define LP5523_CMD_RUN 0x2a /* 00101010 */ | ||
74 | #define LP5523_CMD_DISABLED 0x00 /* 00000000 */ | ||
75 | |||
76 | #define LP5523_ENABLE 0x40 | ||
77 | #define LP5523_AUTO_INC 0x40 | ||
78 | #define LP5523_PWR_SAVE 0x20 | ||
79 | #define LP5523_PWM_PWR_SAVE 0x04 | ||
80 | #define LP5523_CP_1 0x08 | ||
81 | #define LP5523_CP_1_5 0x10 | ||
82 | #define LP5523_CP_AUTO 0x18 | ||
83 | #define LP5523_INT_CLK 0x01 | ||
84 | #define LP5523_AUTO_CLK 0x02 | ||
85 | #define LP5523_EN_LEDTEST 0x80 | ||
86 | #define LP5523_LEDTEST_DONE 0x80 | ||
87 | |||
88 | #define LP5523_DEFAULT_CURRENT 50 /* microAmps */ | ||
89 | #define LP5523_PROGRAM_LENGTH 32 /* in bytes */ | ||
90 | #define LP5523_PROGRAM_PAGES 6 | ||
91 | #define LP5523_ADC_SHORTCIRC_LIM 80 | ||
92 | |||
93 | #define LP5523_LEDS 9 | ||
94 | #define LP5523_ENGINES 3 | ||
95 | |||
96 | #define LP5523_ENG_MASK_BASE 0x30 /* 00110000 */ | ||
97 | |||
98 | #define LP5523_ENG_STATUS_MASK 0x07 /* 00000111 */ | ||
99 | |||
100 | #define LP5523_IRQ_FLAGS IRQF_TRIGGER_FALLING | ||
101 | |||
102 | #define LP5523_EXT_CLK_USED 0x08 | ||
103 | |||
104 | #define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) | ||
105 | #define SHIFT_MASK(id) (((id) - 1) * 2) | ||
106 | |||
107 | struct lp5523_engine { | ||
108 | const struct attribute_group *attributes; | ||
109 | int id; | ||
110 | u8 mode; | ||
111 | u8 prog_page; | ||
112 | u8 mux_page; | ||
113 | u16 led_mux; | ||
114 | u8 engine_mask; | ||
115 | }; | ||
116 | |||
117 | struct lp5523_led { | ||
118 | int id; | ||
119 | u8 chan_nr; | ||
120 | u8 led_current; | ||
121 | u8 max_current; | ||
122 | struct led_classdev cdev; | ||
123 | struct work_struct brightness_work; | ||
124 | u8 brightness; | ||
125 | }; | ||
126 | |||
127 | struct lp5523_chip { | ||
128 | struct mutex lock; /* Serialize control */ | ||
129 | struct i2c_client *client; | ||
130 | struct lp5523_engine engines[LP5523_ENGINES]; | ||
131 | struct lp5523_led leds[LP5523_LEDS]; | ||
132 | struct lp5523_platform_data *pdata; | ||
133 | u8 num_channels; | ||
134 | u8 num_leds; | ||
135 | }; | ||
136 | |||
137 | #define cdev_to_led(c) container_of(c, struct lp5523_led, cdev) | ||
138 | |||
139 | static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine) | ||
140 | { | ||
141 | return container_of(engine, struct lp5523_chip, | ||
142 | engines[engine->id - 1]); | ||
143 | } | ||
144 | |||
145 | static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led) | ||
146 | { | ||
147 | return container_of(led, struct lp5523_chip, | ||
148 | leds[led->id]); | ||
149 | } | ||
150 | |||
151 | static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode); | ||
152 | static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode); | ||
153 | static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern); | ||
154 | |||
155 | static void lp5523_led_brightness_work(struct work_struct *work); | ||
156 | |||
157 | static int lp5523_write(struct i2c_client *client, u8 reg, u8 value) | ||
158 | { | ||
159 | return i2c_smbus_write_byte_data(client, reg, value); | ||
160 | } | ||
161 | |||
162 | static int lp5523_read(struct i2c_client *client, u8 reg, u8 *buf) | ||
163 | { | ||
164 | s32 ret = i2c_smbus_read_byte_data(client, reg); | ||
165 | |||
166 | if (ret < 0) | ||
167 | return -EIO; | ||
168 | |||
169 | *buf = ret; | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int lp5523_detect(struct i2c_client *client) | ||
174 | { | ||
175 | int ret; | ||
176 | u8 buf; | ||
177 | |||
178 | ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40); | ||
179 | if (ret) | ||
180 | return ret; | ||
181 | ret = lp5523_read(client, LP5523_REG_ENABLE, &buf); | ||
182 | if (ret) | ||
183 | return ret; | ||
184 | if (buf == 0x40) | ||
185 | return 0; | ||
186 | else | ||
187 | return -ENODEV; | ||
188 | } | ||
189 | |||
190 | static int lp5523_configure(struct i2c_client *client) | ||
191 | { | ||
192 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
193 | int ret = 0; | ||
194 | u8 status; | ||
195 | |||
196 | /* one pattern per engine setting led mux start and stop addresses */ | ||
197 | u8 pattern[][LP5523_PROGRAM_LENGTH] = { | ||
198 | { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0}, | ||
199 | { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0}, | ||
200 | { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, | ||
201 | }; | ||
202 | |||
203 | lp5523_write(client, LP5523_REG_RESET, 0xff); | ||
204 | |||
205 | usleep_range(10000, 100000); | ||
206 | |||
207 | ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE); | ||
208 | /* Chip startup time after reset is 500 us */ | ||
209 | usleep_range(1000, 10000); | ||
210 | |||
211 | ret |= lp5523_write(client, LP5523_REG_CONFIG, | ||
212 | LP5523_AUTO_INC | LP5523_PWR_SAVE | | ||
213 | LP5523_CP_AUTO | LP5523_AUTO_CLK | | ||
214 | LP5523_PWM_PWR_SAVE); | ||
215 | |||
216 | /* turn on all leds */ | ||
217 | ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_MSB, 0x01); | ||
218 | ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_LSB, 0xff); | ||
219 | |||
220 | /* hardcode 32 bytes of memory for each engine from program memory */ | ||
221 | ret |= lp5523_write(client, LP5523_REG_CH1_PROG_START, 0x00); | ||
222 | ret |= lp5523_write(client, LP5523_REG_CH2_PROG_START, 0x10); | ||
223 | ret |= lp5523_write(client, LP5523_REG_CH3_PROG_START, 0x20); | ||
224 | |||
225 | /* write led mux address space for each channel */ | ||
226 | ret |= lp5523_load_program(&chip->engines[0], pattern[0]); | ||
227 | ret |= lp5523_load_program(&chip->engines[1], pattern[1]); | ||
228 | ret |= lp5523_load_program(&chip->engines[2], pattern[2]); | ||
229 | |||
230 | if (ret) { | ||
231 | dev_err(&client->dev, "could not load mux programs\n"); | ||
232 | return -1; | ||
233 | } | ||
234 | |||
235 | /* set all engines exec state and mode to run 00101010 */ | ||
236 | ret |= lp5523_write(client, LP5523_REG_ENABLE, | ||
237 | (LP5523_CMD_RUN | LP5523_ENABLE)); | ||
238 | |||
239 | ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_RUN); | ||
240 | |||
241 | if (ret) { | ||
242 | dev_err(&client->dev, "could not start mux programs\n"); | ||
243 | return -1; | ||
244 | } | ||
245 | |||
246 | /* Wait 3ms and check the engine status */ | ||
247 | usleep_range(3000, 20000); | ||
248 | lp5523_read(client, LP5523_REG_STATUS, &status); | ||
249 | status &= LP5523_ENG_STATUS_MASK; | ||
250 | |||
251 | if (status == LP5523_ENG_STATUS_MASK) { | ||
252 | dev_dbg(&client->dev, "all engines configured\n"); | ||
253 | } else { | ||
254 | dev_info(&client->dev, "status == %x\n", status); | ||
255 | dev_err(&client->dev, "cound not configure LED engine\n"); | ||
256 | return -1; | ||
257 | } | ||
258 | |||
259 | dev_info(&client->dev, "disabling engines\n"); | ||
260 | |||
261 | ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED); | ||
262 | |||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode) | ||
267 | { | ||
268 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
269 | struct i2c_client *client = chip->client; | ||
270 | int ret; | ||
271 | u8 engine_state; | ||
272 | |||
273 | ret = lp5523_read(client, LP5523_REG_OP_MODE, &engine_state); | ||
274 | if (ret) | ||
275 | goto fail; | ||
276 | |||
277 | engine_state &= ~(engine->engine_mask); | ||
278 | |||
279 | /* set mode only for this engine */ | ||
280 | mode &= engine->engine_mask; | ||
281 | |||
282 | engine_state |= mode; | ||
283 | |||
284 | ret |= lp5523_write(client, LP5523_REG_OP_MODE, engine_state); | ||
285 | fail: | ||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux) | ||
290 | { | ||
291 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
292 | struct i2c_client *client = chip->client; | ||
293 | int ret = 0; | ||
294 | |||
295 | ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); | ||
296 | |||
297 | ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, engine->mux_page); | ||
298 | ret |= lp5523_write(client, LP5523_REG_PROG_MEM, | ||
299 | (u8)(mux >> 8)); | ||
300 | ret |= lp5523_write(client, LP5523_REG_PROG_MEM + 1, (u8)(mux)); | ||
301 | engine->led_mux = mux; | ||
302 | |||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern) | ||
307 | { | ||
308 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
309 | struct i2c_client *client = chip->client; | ||
310 | |||
311 | int ret = 0; | ||
312 | |||
313 | ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); | ||
314 | |||
315 | ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, | ||
316 | engine->prog_page); | ||
317 | ret |= i2c_smbus_write_i2c_block_data(client, LP5523_REG_PROG_MEM, | ||
318 | LP5523_PROGRAM_LENGTH, pattern); | ||
319 | |||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | static int lp5523_run_program(struct lp5523_engine *engine) | ||
324 | { | ||
325 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
326 | struct i2c_client *client = chip->client; | ||
327 | int ret; | ||
328 | |||
329 | ret = lp5523_write(client, LP5523_REG_ENABLE, | ||
330 | LP5523_CMD_RUN | LP5523_ENABLE); | ||
331 | if (ret) | ||
332 | goto fail; | ||
333 | |||
334 | ret = lp5523_set_engine_mode(engine, LP5523_CMD_RUN); | ||
335 | fail: | ||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len) | ||
340 | { | ||
341 | int i; | ||
342 | u16 tmp_mux = 0; | ||
343 | len = len < LP5523_LEDS ? len : LP5523_LEDS; | ||
344 | for (i = 0; i < len; i++) { | ||
345 | switch (buf[i]) { | ||
346 | case '1': | ||
347 | tmp_mux |= (1 << i); | ||
348 | break; | ||
349 | case '0': | ||
350 | break; | ||
351 | case '\n': | ||
352 | i = len; | ||
353 | break; | ||
354 | default: | ||
355 | return -1; | ||
356 | } | ||
357 | } | ||
358 | *mux = tmp_mux; | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static void lp5523_mux_to_array(u16 led_mux, char *array) | ||
364 | { | ||
365 | int i, pos = 0; | ||
366 | for (i = 0; i < LP5523_LEDS; i++) | ||
367 | pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i)); | ||
368 | |||
369 | array[pos] = '\0'; | ||
370 | } | ||
371 | |||
372 | /*--------------------------------------------------------------*/ | ||
373 | /* Sysfs interface */ | ||
374 | /*--------------------------------------------------------------*/ | ||
375 | |||
376 | static ssize_t show_engine_leds(struct device *dev, | ||
377 | struct device_attribute *attr, | ||
378 | char *buf, int nr) | ||
379 | { | ||
380 | struct i2c_client *client = to_i2c_client(dev); | ||
381 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
382 | char mux[LP5523_LEDS + 1]; | ||
383 | |||
384 | lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux); | ||
385 | |||
386 | return sprintf(buf, "%s\n", mux); | ||
387 | } | ||
388 | |||
389 | #define show_leds(nr) \ | ||
390 | static ssize_t show_engine##nr##_leds(struct device *dev, \ | ||
391 | struct device_attribute *attr, \ | ||
392 | char *buf) \ | ||
393 | { \ | ||
394 | return show_engine_leds(dev, attr, buf, nr); \ | ||
395 | } | ||
396 | show_leds(1) | ||
397 | show_leds(2) | ||
398 | show_leds(3) | ||
399 | |||
400 | static ssize_t store_engine_leds(struct device *dev, | ||
401 | struct device_attribute *attr, | ||
402 | const char *buf, size_t len, int nr) | ||
403 | { | ||
404 | struct i2c_client *client = to_i2c_client(dev); | ||
405 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
406 | u16 mux = 0; | ||
407 | |||
408 | if (lp5523_mux_parse(buf, &mux, len)) | ||
409 | return -EINVAL; | ||
410 | |||
411 | if (lp5523_load_mux(&chip->engines[nr - 1], mux)) | ||
412 | return -EINVAL; | ||
413 | |||
414 | return len; | ||
415 | } | ||
416 | |||
417 | #define store_leds(nr) \ | ||
418 | static ssize_t store_engine##nr##_leds(struct device *dev, \ | ||
419 | struct device_attribute *attr, \ | ||
420 | const char *buf, size_t len) \ | ||
421 | { \ | ||
422 | return store_engine_leds(dev, attr, buf, len, nr); \ | ||
423 | } | ||
424 | store_leds(1) | ||
425 | store_leds(2) | ||
426 | store_leds(3) | ||
427 | |||
428 | static ssize_t lp5523_selftest(struct device *dev, | ||
429 | struct device_attribute *attr, | ||
430 | char *buf) | ||
431 | { | ||
432 | struct i2c_client *client = to_i2c_client(dev); | ||
433 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
434 | int i, ret, pos = 0; | ||
435 | int led = 0; | ||
436 | u8 status, adc, vdd; | ||
437 | |||
438 | mutex_lock(&chip->lock); | ||
439 | |||
440 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); | ||
441 | if (ret < 0) | ||
442 | goto fail; | ||
443 | |||
444 | /* Check that ext clock is really in use if requested */ | ||
445 | if ((chip->pdata) && (chip->pdata->clock_mode == LP5523_CLOCK_EXT)) | ||
446 | if ((status & LP5523_EXT_CLK_USED) == 0) | ||
447 | goto fail; | ||
448 | |||
449 | /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ | ||
450 | lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL, | ||
451 | LP5523_EN_LEDTEST | 16); | ||
452 | usleep_range(3000, 10000); | ||
453 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); | ||
454 | if (!(status & LP5523_LEDTEST_DONE)) | ||
455 | usleep_range(3000, 10000); | ||
456 | |||
457 | ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd); | ||
458 | vdd--; /* There may be some fluctuation in measurement */ | ||
459 | |||
460 | for (i = 0; i < LP5523_LEDS; i++) { | ||
461 | /* Skip non-existing channels */ | ||
462 | if (chip->pdata->led_config[i].led_current == 0) | ||
463 | continue; | ||
464 | |||
465 | /* Set default current */ | ||
466 | lp5523_write(chip->client, | ||
467 | LP5523_REG_LED_CURRENT_BASE + i, | ||
468 | chip->pdata->led_config[i].led_current); | ||
469 | |||
470 | lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff); | ||
471 | /* let current stabilize 2ms before measurements start */ | ||
472 | usleep_range(2000, 10000); | ||
473 | lp5523_write(chip->client, | ||
474 | LP5523_REG_LED_TEST_CTRL, | ||
475 | LP5523_EN_LEDTEST | i); | ||
476 | /* ledtest takes 2.7ms */ | ||
477 | usleep_range(3000, 10000); | ||
478 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); | ||
479 | if (!(status & LP5523_LEDTEST_DONE)) | ||
480 | usleep_range(3000, 10000); | ||
481 | ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc); | ||
482 | |||
483 | if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) | ||
484 | pos += sprintf(buf + pos, "LED %d FAIL\n", i); | ||
485 | |||
486 | lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0x00); | ||
487 | |||
488 | /* Restore current */ | ||
489 | lp5523_write(chip->client, | ||
490 | LP5523_REG_LED_CURRENT_BASE + i, | ||
491 | chip->leds[led].led_current); | ||
492 | led++; | ||
493 | } | ||
494 | if (pos == 0) | ||
495 | pos = sprintf(buf, "OK\n"); | ||
496 | goto release_lock; | ||
497 | fail: | ||
498 | pos = sprintf(buf, "FAIL\n"); | ||
499 | |||
500 | release_lock: | ||
501 | mutex_unlock(&chip->lock); | ||
502 | |||
503 | return pos; | ||
504 | } | ||
505 | |||
506 | static void lp5523_set_brightness(struct led_classdev *cdev, | ||
507 | enum led_brightness brightness) | ||
508 | { | ||
509 | struct lp5523_led *led = cdev_to_led(cdev); | ||
510 | |||
511 | led->brightness = (u8)brightness; | ||
512 | |||
513 | schedule_work(&led->brightness_work); | ||
514 | } | ||
515 | |||
516 | static void lp5523_led_brightness_work(struct work_struct *work) | ||
517 | { | ||
518 | struct lp5523_led *led = container_of(work, | ||
519 | struct lp5523_led, | ||
520 | brightness_work); | ||
521 | struct lp5523_chip *chip = led_to_lp5523(led); | ||
522 | struct i2c_client *client = chip->client; | ||
523 | |||
524 | mutex_lock(&chip->lock); | ||
525 | |||
526 | lp5523_write(client, LP5523_REG_LED_PWM_BASE + led->chan_nr, | ||
527 | led->brightness); | ||
528 | |||
529 | mutex_unlock(&chip->lock); | ||
530 | } | ||
531 | |||
532 | static int lp5523_do_store_load(struct lp5523_engine *engine, | ||
533 | const char *buf, size_t len) | ||
534 | { | ||
535 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
536 | struct i2c_client *client = chip->client; | ||
537 | int ret, nrchars, offset = 0, i = 0; | ||
538 | char c[3]; | ||
539 | unsigned cmd; | ||
540 | u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; | ||
541 | |||
542 | while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) { | ||
543 | /* separate sscanfs because length is working only for %s */ | ||
544 | ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); | ||
545 | ret = sscanf(c, "%2x", &cmd); | ||
546 | if (ret != 1) | ||
547 | goto fail; | ||
548 | pattern[i] = (u8)cmd; | ||
549 | |||
550 | offset += nrchars; | ||
551 | i++; | ||
552 | } | ||
553 | |||
554 | /* Each instruction is 16bit long. Check that length is even */ | ||
555 | if (i % 2) | ||
556 | goto fail; | ||
557 | |||
558 | mutex_lock(&chip->lock); | ||
559 | |||
560 | ret = lp5523_load_program(engine, pattern); | ||
561 | mutex_unlock(&chip->lock); | ||
562 | |||
563 | if (ret) { | ||
564 | dev_err(&client->dev, "failed loading pattern\n"); | ||
565 | return ret; | ||
566 | } | ||
567 | |||
568 | return len; | ||
569 | fail: | ||
570 | dev_err(&client->dev, "wrong pattern format\n"); | ||
571 | return -EINVAL; | ||
572 | } | ||
573 | |||
574 | static ssize_t store_engine_load(struct device *dev, | ||
575 | struct device_attribute *attr, | ||
576 | const char *buf, size_t len, int nr) | ||
577 | { | ||
578 | struct i2c_client *client = to_i2c_client(dev); | ||
579 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
580 | return lp5523_do_store_load(&chip->engines[nr - 1], buf, len); | ||
581 | } | ||
582 | |||
583 | #define store_load(nr) \ | ||
584 | static ssize_t store_engine##nr##_load(struct device *dev, \ | ||
585 | struct device_attribute *attr, \ | ||
586 | const char *buf, size_t len) \ | ||
587 | { \ | ||
588 | return store_engine_load(dev, attr, buf, len, nr); \ | ||
589 | } | ||
590 | store_load(1) | ||
591 | store_load(2) | ||
592 | store_load(3) | ||
593 | |||
594 | static ssize_t show_engine_mode(struct device *dev, | ||
595 | struct device_attribute *attr, | ||
596 | char *buf, int nr) | ||
597 | { | ||
598 | struct i2c_client *client = to_i2c_client(dev); | ||
599 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
600 | switch (chip->engines[nr - 1].mode) { | ||
601 | case LP5523_CMD_RUN: | ||
602 | return sprintf(buf, "run\n"); | ||
603 | case LP5523_CMD_LOAD: | ||
604 | return sprintf(buf, "load\n"); | ||
605 | case LP5523_CMD_DISABLED: | ||
606 | return sprintf(buf, "disabled\n"); | ||
607 | default: | ||
608 | return sprintf(buf, "disabled\n"); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | #define show_mode(nr) \ | ||
613 | static ssize_t show_engine##nr##_mode(struct device *dev, \ | ||
614 | struct device_attribute *attr, \ | ||
615 | char *buf) \ | ||
616 | { \ | ||
617 | return show_engine_mode(dev, attr, buf, nr); \ | ||
618 | } | ||
619 | show_mode(1) | ||
620 | show_mode(2) | ||
621 | show_mode(3) | ||
622 | |||
623 | static ssize_t store_engine_mode(struct device *dev, | ||
624 | struct device_attribute *attr, | ||
625 | const char *buf, size_t len, int nr) | ||
626 | { | ||
627 | struct i2c_client *client = to_i2c_client(dev); | ||
628 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
629 | struct lp5523_engine *engine = &chip->engines[nr - 1]; | ||
630 | mutex_lock(&chip->lock); | ||
631 | |||
632 | if (!strncmp(buf, "run", 3)) | ||
633 | lp5523_set_mode(engine, LP5523_CMD_RUN); | ||
634 | else if (!strncmp(buf, "load", 4)) | ||
635 | lp5523_set_mode(engine, LP5523_CMD_LOAD); | ||
636 | else if (!strncmp(buf, "disabled", 8)) | ||
637 | lp5523_set_mode(engine, LP5523_CMD_DISABLED); | ||
638 | |||
639 | mutex_unlock(&chip->lock); | ||
640 | return len; | ||
641 | } | ||
642 | |||
643 | #define store_mode(nr) \ | ||
644 | static ssize_t store_engine##nr##_mode(struct device *dev, \ | ||
645 | struct device_attribute *attr, \ | ||
646 | const char *buf, size_t len) \ | ||
647 | { \ | ||
648 | return store_engine_mode(dev, attr, buf, len, nr); \ | ||
649 | } | ||
650 | store_mode(1) | ||
651 | store_mode(2) | ||
652 | store_mode(3) | ||
653 | |||
654 | static ssize_t show_max_current(struct device *dev, | ||
655 | struct device_attribute *attr, | ||
656 | char *buf) | ||
657 | { | ||
658 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
659 | struct lp5523_led *led = cdev_to_led(led_cdev); | ||
660 | |||
661 | return sprintf(buf, "%d\n", led->max_current); | ||
662 | } | ||
663 | |||
664 | static ssize_t show_current(struct device *dev, | ||
665 | struct device_attribute *attr, | ||
666 | char *buf) | ||
667 | { | ||
668 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
669 | struct lp5523_led *led = cdev_to_led(led_cdev); | ||
670 | |||
671 | return sprintf(buf, "%d\n", led->led_current); | ||
672 | } | ||
673 | |||
674 | static ssize_t store_current(struct device *dev, | ||
675 | struct device_attribute *attr, | ||
676 | const char *buf, size_t len) | ||
677 | { | ||
678 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
679 | struct lp5523_led *led = cdev_to_led(led_cdev); | ||
680 | struct lp5523_chip *chip = led_to_lp5523(led); | ||
681 | ssize_t ret; | ||
682 | unsigned long curr; | ||
683 | |||
684 | if (strict_strtoul(buf, 0, &curr)) | ||
685 | return -EINVAL; | ||
686 | |||
687 | if (curr > led->max_current) | ||
688 | return -EINVAL; | ||
689 | |||
690 | mutex_lock(&chip->lock); | ||
691 | ret = lp5523_write(chip->client, | ||
692 | LP5523_REG_LED_CURRENT_BASE + led->chan_nr, | ||
693 | (u8)curr); | ||
694 | mutex_unlock(&chip->lock); | ||
695 | |||
696 | if (ret < 0) | ||
697 | return ret; | ||
698 | |||
699 | led->led_current = (u8)curr; | ||
700 | |||
701 | return len; | ||
702 | } | ||
703 | |||
704 | /* led class device attributes */ | ||
705 | static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); | ||
706 | static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); | ||
707 | |||
708 | static struct attribute *lp5523_led_attributes[] = { | ||
709 | &dev_attr_led_current.attr, | ||
710 | &dev_attr_max_current.attr, | ||
711 | NULL, | ||
712 | }; | ||
713 | |||
714 | static struct attribute_group lp5523_led_attribute_group = { | ||
715 | .attrs = lp5523_led_attributes | ||
716 | }; | ||
717 | |||
718 | /* device attributes */ | ||
719 | static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, | ||
720 | show_engine1_mode, store_engine1_mode); | ||
721 | static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, | ||
722 | show_engine2_mode, store_engine2_mode); | ||
723 | static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, | ||
724 | show_engine3_mode, store_engine3_mode); | ||
725 | static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO, | ||
726 | show_engine1_leds, store_engine1_leds); | ||
727 | static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO, | ||
728 | show_engine2_leds, store_engine2_leds); | ||
729 | static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO, | ||
730 | show_engine3_leds, store_engine3_leds); | ||
731 | static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); | ||
732 | static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); | ||
733 | static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); | ||
734 | static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL); | ||
735 | |||
736 | static struct attribute *lp5523_attributes[] = { | ||
737 | &dev_attr_engine1_mode.attr, | ||
738 | &dev_attr_engine2_mode.attr, | ||
739 | &dev_attr_engine3_mode.attr, | ||
740 | &dev_attr_selftest.attr, | ||
741 | NULL | ||
742 | }; | ||
743 | |||
744 | static struct attribute *lp5523_engine1_attributes[] = { | ||
745 | &dev_attr_engine1_load.attr, | ||
746 | &dev_attr_engine1_leds.attr, | ||
747 | NULL | ||
748 | }; | ||
749 | |||
750 | static struct attribute *lp5523_engine2_attributes[] = { | ||
751 | &dev_attr_engine2_load.attr, | ||
752 | &dev_attr_engine2_leds.attr, | ||
753 | NULL | ||
754 | }; | ||
755 | |||
756 | static struct attribute *lp5523_engine3_attributes[] = { | ||
757 | &dev_attr_engine3_load.attr, | ||
758 | &dev_attr_engine3_leds.attr, | ||
759 | NULL | ||
760 | }; | ||
761 | |||
762 | static const struct attribute_group lp5523_group = { | ||
763 | .attrs = lp5523_attributes, | ||
764 | }; | ||
765 | |||
766 | static const struct attribute_group lp5523_engine_group[] = { | ||
767 | {.attrs = lp5523_engine1_attributes }, | ||
768 | {.attrs = lp5523_engine2_attributes }, | ||
769 | {.attrs = lp5523_engine3_attributes }, | ||
770 | }; | ||
771 | |||
772 | static int lp5523_register_sysfs(struct i2c_client *client) | ||
773 | { | ||
774 | struct device *dev = &client->dev; | ||
775 | int ret; | ||
776 | |||
777 | ret = sysfs_create_group(&dev->kobj, &lp5523_group); | ||
778 | if (ret < 0) | ||
779 | return ret; | ||
780 | |||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static void lp5523_unregister_sysfs(struct i2c_client *client) | ||
785 | { | ||
786 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
787 | struct device *dev = &client->dev; | ||
788 | int i; | ||
789 | |||
790 | sysfs_remove_group(&dev->kobj, &lp5523_group); | ||
791 | |||
792 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) | ||
793 | if (chip->engines[i].mode == LP5523_CMD_LOAD) | ||
794 | sysfs_remove_group(&dev->kobj, &lp5523_engine_group[i]); | ||
795 | |||
796 | for (i = 0; i < chip->num_leds; i++) | ||
797 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, | ||
798 | &lp5523_led_attribute_group); | ||
799 | } | ||
800 | |||
801 | /*--------------------------------------------------------------*/ | ||
802 | /* Set chip operating mode */ | ||
803 | /*--------------------------------------------------------------*/ | ||
804 | static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) | ||
805 | { | ||
806 | /* engine to chip */ | ||
807 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
808 | struct i2c_client *client = chip->client; | ||
809 | struct device *dev = &client->dev; | ||
810 | int ret = 0; | ||
811 | |||
812 | /* if in that mode already do nothing, except for run */ | ||
813 | if (mode == engine->mode && mode != LP5523_CMD_RUN) | ||
814 | return 0; | ||
815 | |||
816 | if (mode == LP5523_CMD_RUN) { | ||
817 | ret = lp5523_run_program(engine); | ||
818 | } else if (mode == LP5523_CMD_LOAD) { | ||
819 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); | ||
820 | lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); | ||
821 | |||
822 | ret = sysfs_create_group(&dev->kobj, engine->attributes); | ||
823 | if (ret) | ||
824 | return ret; | ||
825 | } else if (mode == LP5523_CMD_DISABLED) { | ||
826 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); | ||
827 | } | ||
828 | |||
829 | /* remove load attribute from sysfs if not in load mode */ | ||
830 | if (engine->mode == LP5523_CMD_LOAD && mode != LP5523_CMD_LOAD) | ||
831 | sysfs_remove_group(&dev->kobj, engine->attributes); | ||
832 | |||
833 | engine->mode = mode; | ||
834 | |||
835 | return ret; | ||
836 | } | ||
837 | |||
838 | /*--------------------------------------------------------------*/ | ||
839 | /* Probe, Attach, Remove */ | ||
840 | /*--------------------------------------------------------------*/ | ||
841 | static int __init lp5523_init_engine(struct lp5523_engine *engine, int id) | ||
842 | { | ||
843 | if (id < 1 || id > LP5523_ENGINES) | ||
844 | return -1; | ||
845 | engine->id = id; | ||
846 | engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); | ||
847 | engine->prog_page = id - 1; | ||
848 | engine->mux_page = id + 2; | ||
849 | engine->attributes = &lp5523_engine_group[id - 1]; | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev, | ||
855 | int chan, struct lp5523_platform_data *pdata) | ||
856 | { | ||
857 | char name[32]; | ||
858 | int res; | ||
859 | |||
860 | if (chan >= LP5523_LEDS) | ||
861 | return -EINVAL; | ||
862 | |||
863 | if (pdata->led_config[chan].led_current) { | ||
864 | led->led_current = pdata->led_config[chan].led_current; | ||
865 | led->max_current = pdata->led_config[chan].max_current; | ||
866 | led->chan_nr = pdata->led_config[chan].chan_nr; | ||
867 | |||
868 | if (led->chan_nr >= LP5523_LEDS) { | ||
869 | dev_err(dev, "Use channel numbers between 0 and %d\n", | ||
870 | LP5523_LEDS - 1); | ||
871 | return -EINVAL; | ||
872 | } | ||
873 | |||
874 | snprintf(name, 32, "lp5523:channel%d", chan); | ||
875 | |||
876 | led->cdev.name = name; | ||
877 | led->cdev.brightness_set = lp5523_set_brightness; | ||
878 | res = led_classdev_register(dev, &led->cdev); | ||
879 | if (res < 0) { | ||
880 | dev_err(dev, "couldn't register led on channel %d\n", | ||
881 | chan); | ||
882 | return res; | ||
883 | } | ||
884 | res = sysfs_create_group(&led->cdev.dev->kobj, | ||
885 | &lp5523_led_attribute_group); | ||
886 | if (res < 0) { | ||
887 | dev_err(dev, "couldn't register current attribute\n"); | ||
888 | led_classdev_unregister(&led->cdev); | ||
889 | return res; | ||
890 | } | ||
891 | } else { | ||
892 | led->led_current = 0; | ||
893 | } | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static struct i2c_driver lp5523_driver; | ||
898 | |||
899 | static int lp5523_probe(struct i2c_client *client, | ||
900 | const struct i2c_device_id *id) | ||
901 | { | ||
902 | struct lp5523_chip *chip; | ||
903 | struct lp5523_platform_data *pdata; | ||
904 | int ret, i, led; | ||
905 | |||
906 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
907 | if (!chip) | ||
908 | return -ENOMEM; | ||
909 | |||
910 | i2c_set_clientdata(client, chip); | ||
911 | chip->client = client; | ||
912 | |||
913 | pdata = client->dev.platform_data; | ||
914 | |||
915 | if (!pdata) { | ||
916 | dev_err(&client->dev, "no platform data\n"); | ||
917 | ret = -EINVAL; | ||
918 | goto fail1; | ||
919 | } | ||
920 | |||
921 | mutex_init(&chip->lock); | ||
922 | |||
923 | chip->pdata = pdata; | ||
924 | |||
925 | if (pdata->setup_resources) { | ||
926 | ret = pdata->setup_resources(); | ||
927 | if (ret < 0) | ||
928 | goto fail1; | ||
929 | } | ||
930 | |||
931 | if (pdata->enable) { | ||
932 | pdata->enable(0); | ||
933 | usleep_range(1000, 10000); | ||
934 | pdata->enable(1); | ||
935 | usleep_range(1000, 10000); /* Spec says min 500us */ | ||
936 | } | ||
937 | |||
938 | ret = lp5523_detect(client); | ||
939 | if (ret) | ||
940 | goto fail2; | ||
941 | |||
942 | dev_info(&client->dev, "LP5523 Programmable led chip found\n"); | ||
943 | |||
944 | /* Initialize engines */ | ||
945 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | ||
946 | ret = lp5523_init_engine(&chip->engines[i], i + 1); | ||
947 | if (ret) { | ||
948 | dev_err(&client->dev, "error initializing engine\n"); | ||
949 | goto fail2; | ||
950 | } | ||
951 | } | ||
952 | ret = lp5523_configure(client); | ||
953 | if (ret < 0) { | ||
954 | dev_err(&client->dev, "error configuring chip\n"); | ||
955 | goto fail2; | ||
956 | } | ||
957 | |||
958 | /* Initialize leds */ | ||
959 | chip->num_channels = pdata->num_channels; | ||
960 | chip->num_leds = 0; | ||
961 | led = 0; | ||
962 | for (i = 0; i < pdata->num_channels; i++) { | ||
963 | /* Do not initialize channels that are not connected */ | ||
964 | if (pdata->led_config[i].led_current == 0) | ||
965 | continue; | ||
966 | |||
967 | ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata); | ||
968 | if (ret) { | ||
969 | dev_err(&client->dev, "error initializing leds\n"); | ||
970 | goto fail3; | ||
971 | } | ||
972 | chip->num_leds++; | ||
973 | |||
974 | chip->leds[led].id = led; | ||
975 | /* Set LED current */ | ||
976 | lp5523_write(client, | ||
977 | LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, | ||
978 | chip->leds[led].led_current); | ||
979 | |||
980 | INIT_WORK(&(chip->leds[led].brightness_work), | ||
981 | lp5523_led_brightness_work); | ||
982 | |||
983 | led++; | ||
984 | } | ||
985 | |||
986 | ret = lp5523_register_sysfs(client); | ||
987 | if (ret) { | ||
988 | dev_err(&client->dev, "registering sysfs failed\n"); | ||
989 | goto fail3; | ||
990 | } | ||
991 | return ret; | ||
992 | fail3: | ||
993 | for (i = 0; i < chip->num_leds; i++) { | ||
994 | led_classdev_unregister(&chip->leds[i].cdev); | ||
995 | cancel_work_sync(&chip->leds[i].brightness_work); | ||
996 | } | ||
997 | fail2: | ||
998 | if (pdata->enable) | ||
999 | pdata->enable(0); | ||
1000 | if (pdata->release_resources) | ||
1001 | pdata->release_resources(); | ||
1002 | fail1: | ||
1003 | kfree(chip); | ||
1004 | return ret; | ||
1005 | } | ||
1006 | |||
1007 | static int lp5523_remove(struct i2c_client *client) | ||
1008 | { | ||
1009 | struct lp5523_chip *chip = i2c_get_clientdata(client); | ||
1010 | int i; | ||
1011 | |||
1012 | lp5523_unregister_sysfs(client); | ||
1013 | |||
1014 | for (i = 0; i < chip->num_leds; i++) { | ||
1015 | led_classdev_unregister(&chip->leds[i].cdev); | ||
1016 | cancel_work_sync(&chip->leds[i].brightness_work); | ||
1017 | } | ||
1018 | |||
1019 | if (chip->pdata->enable) | ||
1020 | chip->pdata->enable(0); | ||
1021 | if (chip->pdata->release_resources) | ||
1022 | chip->pdata->release_resources(); | ||
1023 | kfree(chip); | ||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1027 | static const struct i2c_device_id lp5523_id[] = { | ||
1028 | { "lp5523", 0 }, | ||
1029 | { } | ||
1030 | }; | ||
1031 | |||
1032 | MODULE_DEVICE_TABLE(i2c, lp5523_id); | ||
1033 | |||
1034 | static struct i2c_driver lp5523_driver = { | ||
1035 | .driver = { | ||
1036 | .name = "lp5523", | ||
1037 | }, | ||
1038 | .probe = lp5523_probe, | ||
1039 | .remove = lp5523_remove, | ||
1040 | .id_table = lp5523_id, | ||
1041 | }; | ||
1042 | |||
1043 | static int __init lp5523_init(void) | ||
1044 | { | ||
1045 | int ret; | ||
1046 | |||
1047 | ret = i2c_add_driver(&lp5523_driver); | ||
1048 | |||
1049 | if (ret < 0) | ||
1050 | printk(KERN_ALERT "Adding lp5523 driver failed\n"); | ||
1051 | |||
1052 | return ret; | ||
1053 | } | ||
1054 | |||
1055 | static void __exit lp5523_exit(void) | ||
1056 | { | ||
1057 | i2c_del_driver(&lp5523_driver); | ||
1058 | } | ||
1059 | |||
1060 | module_init(lp5523_init); | ||
1061 | module_exit(lp5523_exit); | ||
1062 | |||
1063 | MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>"); | ||
1064 | MODULE_DESCRIPTION("LP5523 LED engine"); | ||
1065 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c index 3063f591f0dc..1739557a9038 100644 --- a/drivers/leds/leds-net5501.c +++ b/drivers/leds/leds-net5501.c | |||
@@ -92,3 +92,5 @@ unmap: | |||
92 | } | 92 | } |
93 | 93 | ||
94 | arch_initcall(soekris_init); | 94 | arch_initcall(soekris_init); |
95 | |||
96 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 82b77bd482ff..b09bcbeade9c 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c | |||
@@ -12,73 +12,25 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/jiffies.h> | ||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/list.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/device.h> | 17 | #include <linux/device.h> |
21 | #include <linux/sysdev.h> | ||
22 | #include <linux/timer.h> | ||
23 | #include <linux/ctype.h> | 18 | #include <linux/ctype.h> |
24 | #include <linux/leds.h> | 19 | #include <linux/leds.h> |
25 | #include <linux/slab.h> | ||
26 | #include "leds.h" | 20 | #include "leds.h" |
27 | 21 | ||
28 | struct timer_trig_data { | ||
29 | int brightness_on; /* LED brightness during "on" period. | ||
30 | * (LED_OFF < brightness_on <= LED_FULL) | ||
31 | */ | ||
32 | unsigned long delay_on; /* milliseconds on */ | ||
33 | unsigned long delay_off; /* milliseconds off */ | ||
34 | struct timer_list timer; | ||
35 | }; | ||
36 | |||
37 | static void led_timer_function(unsigned long data) | ||
38 | { | ||
39 | struct led_classdev *led_cdev = (struct led_classdev *) data; | ||
40 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
41 | unsigned long brightness; | ||
42 | unsigned long delay; | ||
43 | |||
44 | if (!timer_data->delay_on || !timer_data->delay_off) { | ||
45 | led_set_brightness(led_cdev, LED_OFF); | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | brightness = led_get_brightness(led_cdev); | ||
50 | if (!brightness) { | ||
51 | /* Time to switch the LED on. */ | ||
52 | brightness = timer_data->brightness_on; | ||
53 | delay = timer_data->delay_on; | ||
54 | } else { | ||
55 | /* Store the current brightness value to be able | ||
56 | * to restore it when the delay_off period is over. | ||
57 | */ | ||
58 | timer_data->brightness_on = brightness; | ||
59 | brightness = LED_OFF; | ||
60 | delay = timer_data->delay_off; | ||
61 | } | ||
62 | |||
63 | led_set_brightness(led_cdev, brightness); | ||
64 | |||
65 | mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); | ||
66 | } | ||
67 | |||
68 | static ssize_t led_delay_on_show(struct device *dev, | 22 | static ssize_t led_delay_on_show(struct device *dev, |
69 | struct device_attribute *attr, char *buf) | 23 | struct device_attribute *attr, char *buf) |
70 | { | 24 | { |
71 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 25 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
72 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
73 | 26 | ||
74 | return sprintf(buf, "%lu\n", timer_data->delay_on); | 27 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); |
75 | } | 28 | } |
76 | 29 | ||
77 | static ssize_t led_delay_on_store(struct device *dev, | 30 | static ssize_t led_delay_on_store(struct device *dev, |
78 | struct device_attribute *attr, const char *buf, size_t size) | 31 | struct device_attribute *attr, const char *buf, size_t size) |
79 | { | 32 | { |
80 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 33 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
81 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
82 | int ret = -EINVAL; | 34 | int ret = -EINVAL; |
83 | char *after; | 35 | char *after; |
84 | unsigned long state = simple_strtoul(buf, &after, 10); | 36 | unsigned long state = simple_strtoul(buf, &after, 10); |
@@ -88,21 +40,7 @@ static ssize_t led_delay_on_store(struct device *dev, | |||
88 | count++; | 40 | count++; |
89 | 41 | ||
90 | if (count == size) { | 42 | if (count == size) { |
91 | if (timer_data->delay_on != state) { | 43 | led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); |
92 | /* the new value differs from the previous */ | ||
93 | timer_data->delay_on = state; | ||
94 | |||
95 | /* deactivate previous settings */ | ||
96 | del_timer_sync(&timer_data->timer); | ||
97 | |||
98 | /* try to activate hardware acceleration, if any */ | ||
99 | if (!led_cdev->blink_set || | ||
100 | led_cdev->blink_set(led_cdev, | ||
101 | &timer_data->delay_on, &timer_data->delay_off)) { | ||
102 | /* no hardware acceleration, blink via timer */ | ||
103 | mod_timer(&timer_data->timer, jiffies + 1); | ||
104 | } | ||
105 | } | ||
106 | ret = count; | 44 | ret = count; |
107 | } | 45 | } |
108 | 46 | ||
@@ -113,16 +51,14 @@ static ssize_t led_delay_off_show(struct device *dev, | |||
113 | struct device_attribute *attr, char *buf) | 51 | struct device_attribute *attr, char *buf) |
114 | { | 52 | { |
115 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 53 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
116 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
117 | 54 | ||
118 | return sprintf(buf, "%lu\n", timer_data->delay_off); | 55 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); |
119 | } | 56 | } |
120 | 57 | ||
121 | static ssize_t led_delay_off_store(struct device *dev, | 58 | static ssize_t led_delay_off_store(struct device *dev, |
122 | struct device_attribute *attr, const char *buf, size_t size) | 59 | struct device_attribute *attr, const char *buf, size_t size) |
123 | { | 60 | { |
124 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 61 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
125 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
126 | int ret = -EINVAL; | 62 | int ret = -EINVAL; |
127 | char *after; | 63 | char *after; |
128 | unsigned long state = simple_strtoul(buf, &after, 10); | 64 | unsigned long state = simple_strtoul(buf, &after, 10); |
@@ -132,21 +68,7 @@ static ssize_t led_delay_off_store(struct device *dev, | |||
132 | count++; | 68 | count++; |
133 | 69 | ||
134 | if (count == size) { | 70 | if (count == size) { |
135 | if (timer_data->delay_off != state) { | 71 | led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); |
136 | /* the new value differs from the previous */ | ||
137 | timer_data->delay_off = state; | ||
138 | |||
139 | /* deactivate previous settings */ | ||
140 | del_timer_sync(&timer_data->timer); | ||
141 | |||
142 | /* try to activate hardware acceleration, if any */ | ||
143 | if (!led_cdev->blink_set || | ||
144 | led_cdev->blink_set(led_cdev, | ||
145 | &timer_data->delay_on, &timer_data->delay_off)) { | ||
146 | /* no hardware acceleration, blink via timer */ | ||
147 | mod_timer(&timer_data->timer, jiffies + 1); | ||
148 | } | ||
149 | } | ||
150 | ret = count; | 72 | ret = count; |
151 | } | 73 | } |
152 | 74 | ||
@@ -158,60 +80,34 @@ static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); | |||
158 | 80 | ||
159 | static void timer_trig_activate(struct led_classdev *led_cdev) | 81 | static void timer_trig_activate(struct led_classdev *led_cdev) |
160 | { | 82 | { |
161 | struct timer_trig_data *timer_data; | ||
162 | int rc; | 83 | int rc; |
163 | 84 | ||
164 | timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); | 85 | led_cdev->trigger_data = NULL; |
165 | if (!timer_data) | ||
166 | return; | ||
167 | |||
168 | timer_data->brightness_on = led_get_brightness(led_cdev); | ||
169 | if (timer_data->brightness_on == LED_OFF) | ||
170 | timer_data->brightness_on = led_cdev->max_brightness; | ||
171 | led_cdev->trigger_data = timer_data; | ||
172 | |||
173 | init_timer(&timer_data->timer); | ||
174 | timer_data->timer.function = led_timer_function; | ||
175 | timer_data->timer.data = (unsigned long) led_cdev; | ||
176 | 86 | ||
177 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); | 87 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); |
178 | if (rc) | 88 | if (rc) |
179 | goto err_out; | 89 | return; |
180 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); | 90 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); |
181 | if (rc) | 91 | if (rc) |
182 | goto err_out_delayon; | 92 | goto err_out_delayon; |
183 | 93 | ||
184 | /* If there is hardware support for blinking, start one | 94 | led_cdev->trigger_data = (void *)1; |
185 | * user friendly blink rate chosen by the driver. | ||
186 | */ | ||
187 | if (led_cdev->blink_set) | ||
188 | led_cdev->blink_set(led_cdev, | ||
189 | &timer_data->delay_on, &timer_data->delay_off); | ||
190 | 95 | ||
191 | return; | 96 | return; |
192 | 97 | ||
193 | err_out_delayon: | 98 | err_out_delayon: |
194 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | 99 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); |
195 | err_out: | ||
196 | led_cdev->trigger_data = NULL; | ||
197 | kfree(timer_data); | ||
198 | } | 100 | } |
199 | 101 | ||
200 | static void timer_trig_deactivate(struct led_classdev *led_cdev) | 102 | static void timer_trig_deactivate(struct led_classdev *led_cdev) |
201 | { | 103 | { |
202 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 104 | if (led_cdev->trigger_data) { |
203 | unsigned long on = 0, off = 0; | ||
204 | |||
205 | if (timer_data) { | ||
206 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | 105 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); |
207 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); | 106 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); |
208 | del_timer_sync(&timer_data->timer); | ||
209 | kfree(timer_data); | ||
210 | } | 107 | } |
211 | 108 | ||
212 | /* If there is hardware support for blinking, stop it */ | 109 | /* Stop blinking */ |
213 | if (led_cdev->blink_set) | 110 | led_brightness_set(led_cdev, LED_OFF); |
214 | led_cdev->blink_set(led_cdev, &on, &off); | ||
215 | } | 111 | } |
216 | 112 | ||
217 | static struct led_trigger timer_led_trigger = { | 113 | static struct led_trigger timer_led_trigger = { |
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index 444696625171..f5f4da3d0b67 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c | |||
@@ -80,7 +80,7 @@ static void adb_iop_end_req(struct adb_request *req, int state) | |||
80 | static void adb_iop_complete(struct iop_msg *msg) | 80 | static void adb_iop_complete(struct iop_msg *msg) |
81 | { | 81 | { |
82 | struct adb_request *req; | 82 | struct adb_request *req; |
83 | uint flags; | 83 | unsigned long flags; |
84 | 84 | ||
85 | local_irq_save(flags); | 85 | local_irq_save(flags); |
86 | 86 | ||
@@ -103,7 +103,7 @@ static void adb_iop_listen(struct iop_msg *msg) | |||
103 | { | 103 | { |
104 | struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; | 104 | struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; |
105 | struct adb_request *req; | 105 | struct adb_request *req; |
106 | uint flags; | 106 | unsigned long flags; |
107 | #ifdef DEBUG_ADB_IOP | 107 | #ifdef DEBUG_ADB_IOP |
108 | int i; | 108 | int i; |
109 | #endif | 109 | #endif |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4e957f3140a8..324a3663fcda 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -706,7 +706,7 @@ static struct mdk_personality *find_pers(int level, char *clevel) | |||
706 | /* return the offset of the super block in 512byte sectors */ | 706 | /* return the offset of the super block in 512byte sectors */ |
707 | static inline sector_t calc_dev_sboffset(struct block_device *bdev) | 707 | static inline sector_t calc_dev_sboffset(struct block_device *bdev) |
708 | { | 708 | { |
709 | sector_t num_sectors = bdev->bd_inode->i_size / 512; | 709 | sector_t num_sectors = i_size_read(bdev->bd_inode) / 512; |
710 | return MD_NEW_SIZE_SECTORS(num_sectors); | 710 | return MD_NEW_SIZE_SECTORS(num_sectors); |
711 | } | 711 | } |
712 | 712 | ||
@@ -1386,7 +1386,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1386 | */ | 1386 | */ |
1387 | switch(minor_version) { | 1387 | switch(minor_version) { |
1388 | case 0: | 1388 | case 0: |
1389 | sb_start = rdev->bdev->bd_inode->i_size >> 9; | 1389 | sb_start = i_size_read(rdev->bdev->bd_inode) >> 9; |
1390 | sb_start -= 8*2; | 1390 | sb_start -= 8*2; |
1391 | sb_start &= ~(sector_t)(4*2-1); | 1391 | sb_start &= ~(sector_t)(4*2-1); |
1392 | break; | 1392 | break; |
@@ -1472,7 +1472,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1472 | ret = 0; | 1472 | ret = 0; |
1473 | } | 1473 | } |
1474 | if (minor_version) | 1474 | if (minor_version) |
1475 | rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) - | 1475 | rdev->sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - |
1476 | le64_to_cpu(sb->data_offset); | 1476 | le64_to_cpu(sb->data_offset); |
1477 | else | 1477 | else |
1478 | rdev->sectors = rdev->sb_start; | 1478 | rdev->sectors = rdev->sb_start; |
@@ -1680,7 +1680,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1680 | return 0; /* component must fit device */ | 1680 | return 0; /* component must fit device */ |
1681 | if (rdev->sb_start < rdev->data_offset) { | 1681 | if (rdev->sb_start < rdev->data_offset) { |
1682 | /* minor versions 1 and 2; superblock before data */ | 1682 | /* minor versions 1 and 2; superblock before data */ |
1683 | max_sectors = rdev->bdev->bd_inode->i_size >> 9; | 1683 | max_sectors = i_size_read(rdev->bdev->bd_inode) >> 9; |
1684 | max_sectors -= rdev->data_offset; | 1684 | max_sectors -= rdev->data_offset; |
1685 | if (!num_sectors || num_sectors > max_sectors) | 1685 | if (!num_sectors || num_sectors > max_sectors) |
1686 | num_sectors = max_sectors; | 1686 | num_sectors = max_sectors; |
@@ -1690,7 +1690,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1690 | } else { | 1690 | } else { |
1691 | /* minor version 0; superblock after data */ | 1691 | /* minor version 0; superblock after data */ |
1692 | sector_t sb_start; | 1692 | sector_t sb_start; |
1693 | sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2; | 1693 | sb_start = (i_size_read(rdev->bdev->bd_inode) >> 9) - 8*2; |
1694 | sb_start &= ~(sector_t)(4*2 - 1); | 1694 | sb_start &= ~(sector_t)(4*2 - 1); |
1695 | max_sectors = rdev->sectors + sb_start - rdev->sb_start; | 1695 | max_sectors = rdev->sectors + sb_start - rdev->sb_start; |
1696 | if (!num_sectors || num_sectors > max_sectors) | 1696 | if (!num_sectors || num_sectors > max_sectors) |
@@ -2584,7 +2584,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2584 | if (!sectors) | 2584 | if (!sectors) |
2585 | return -EBUSY; | 2585 | return -EBUSY; |
2586 | } else if (!sectors) | 2586 | } else if (!sectors) |
2587 | sectors = (rdev->bdev->bd_inode->i_size >> 9) - | 2587 | sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - |
2588 | rdev->data_offset; | 2588 | rdev->data_offset; |
2589 | } | 2589 | } |
2590 | if (sectors < my_mddev->dev_sectors) | 2590 | if (sectors < my_mddev->dev_sectors) |
@@ -2797,7 +2797,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi | |||
2797 | 2797 | ||
2798 | kobject_init(&rdev->kobj, &rdev_ktype); | 2798 | kobject_init(&rdev->kobj, &rdev_ktype); |
2799 | 2799 | ||
2800 | size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; | 2800 | size = i_size_read(rdev->bdev->bd_inode) >> BLOCK_SIZE_BITS; |
2801 | if (!size) { | 2801 | if (!size) { |
2802 | printk(KERN_WARNING | 2802 | printk(KERN_WARNING |
2803 | "md: %s has zero or unknown size, marking faulty!\n", | 2803 | "md: %s has zero or unknown size, marking faulty!\n", |
@@ -5235,8 +5235,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5235 | 5235 | ||
5236 | if (!mddev->persistent) { | 5236 | if (!mddev->persistent) { |
5237 | printk(KERN_INFO "md: nonpersistent superblock ...\n"); | 5237 | printk(KERN_INFO "md: nonpersistent superblock ...\n"); |
5238 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; | 5238 | rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512; |
5239 | } else | 5239 | } else |
5240 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); | 5240 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); |
5241 | rdev->sectors = rdev->sb_start; | 5241 | rdev->sectors = rdev->sb_start; |
5242 | 5242 | ||
@@ -5306,7 +5306,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
5306 | if (mddev->persistent) | 5306 | if (mddev->persistent) |
5307 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); | 5307 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); |
5308 | else | 5308 | else |
5309 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; | 5309 | rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512; |
5310 | 5310 | ||
5311 | rdev->sectors = rdev->sb_start; | 5311 | rdev->sectors = rdev->sb_start; |
5312 | 5312 | ||
diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index f9b91ba8900c..0ed09358027e 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c | |||
@@ -123,7 +123,7 @@ static ssize_t als_sensing_range_store(struct device *dev, | |||
123 | { | 123 | { |
124 | struct i2c_client *client = to_i2c_client(dev); | 124 | struct i2c_client *client = to_i2c_client(dev); |
125 | struct als_data *data = i2c_get_clientdata(client); | 125 | struct als_data *data = i2c_get_clientdata(client); |
126 | unsigned int ret_val; | 126 | int ret_val; |
127 | unsigned long val; | 127 | unsigned long val; |
128 | 128 | ||
129 | if (strict_strtoul(buf, 10, &val)) | 129 | if (strict_strtoul(buf, 10, &val)) |
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index cee632e645e1..d79a972f2c79 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c | |||
@@ -649,7 +649,7 @@ static ssize_t bh1770_power_state_store(struct device *dev, | |||
649 | { | 649 | { |
650 | struct bh1770_chip *chip = dev_get_drvdata(dev); | 650 | struct bh1770_chip *chip = dev_get_drvdata(dev); |
651 | unsigned long value; | 651 | unsigned long value; |
652 | size_t ret; | 652 | ssize_t ret; |
653 | 653 | ||
654 | if (strict_strtoul(buf, 0, &value)) | 654 | if (strict_strtoul(buf, 0, &value)) |
655 | return -EINVAL; | 655 | return -EINVAL; |
@@ -659,8 +659,12 @@ static ssize_t bh1770_power_state_store(struct device *dev, | |||
659 | pm_runtime_get_sync(dev); | 659 | pm_runtime_get_sync(dev); |
660 | 660 | ||
661 | ret = bh1770_lux_rate(chip, chip->lux_rate_index); | 661 | ret = bh1770_lux_rate(chip, chip->lux_rate_index); |
662 | ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE); | 662 | if (ret < 0) { |
663 | pm_runtime_put(dev); | ||
664 | goto leave; | ||
665 | } | ||
663 | 666 | ||
667 | ret = bh1770_lux_interrupt_control(chip, BH1770_ENABLE); | ||
664 | if (ret < 0) { | 668 | if (ret < 0) { |
665 | pm_runtime_put(dev); | 669 | pm_runtime_put(dev); |
666 | goto leave; | 670 | goto leave; |
diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 34fe835921c4..ca47e6285075 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c | |||
@@ -87,7 +87,7 @@ static ssize_t als_sensing_range_store(struct device *dev, | |||
87 | struct device_attribute *attr, const char *buf, size_t count) | 87 | struct device_attribute *attr, const char *buf, size_t count) |
88 | { | 88 | { |
89 | struct i2c_client *client = to_i2c_client(dev); | 89 | struct i2c_client *client = to_i2c_client(dev); |
90 | unsigned int ret_val; | 90 | int ret_val; |
91 | unsigned long val; | 91 | unsigned long val; |
92 | 92 | ||
93 | if (strict_strtoul(buf, 10, &val)) | 93 | if (strict_strtoul(buf, 10, &val)) |
@@ -106,6 +106,8 @@ static ssize_t als_sensing_range_store(struct device *dev, | |||
106 | val = 4; | 106 | val = 4; |
107 | 107 | ||
108 | ret_val = i2c_smbus_read_byte_data(client, 0x00); | 108 | ret_val = i2c_smbus_read_byte_data(client, 0x00); |
109 | if (ret_val < 0) | ||
110 | return ret_val; | ||
109 | 111 | ||
110 | ret_val &= 0xFC; /*reset the bit before setting them */ | 112 | ret_val &= 0xFC; /*reset the bit before setting them */ |
111 | ret_val |= val - 1; | 113 | ret_val |= val - 1; |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 43579b3b24ac..53363108994e 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -3043,7 +3043,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev, | |||
3043 | atl1_pcie_patch(adapter); | 3043 | atl1_pcie_patch(adapter); |
3044 | /* assume we have no link for now */ | 3044 | /* assume we have no link for now */ |
3045 | netif_carrier_off(netdev); | 3045 | netif_carrier_off(netdev); |
3046 | netif_stop_queue(netdev); | ||
3047 | 3046 | ||
3048 | setup_timer(&adapter->phy_config_timer, atl1_phy_config, | 3047 | setup_timer(&adapter->phy_config_timer, atl1_phy_config, |
3049 | (unsigned long)adapter); | 3048 | (unsigned long)adapter); |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 9eea225decaf..863e73a85fbe 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
22 | 22 | ||
23 | #define DRV_MODULE_VERSION "1.60.00-3" | 23 | #define DRV_MODULE_VERSION "1.60.00-4" |
24 | #define DRV_MODULE_RELDATE "2010/10/19" | 24 | #define DRV_MODULE_RELDATE "2010/11/01" |
25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
26 | 26 | ||
27 | #define BNX2X_MULTI_QUEUE | 27 | #define BNX2X_MULTI_QUEUE |
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 18c8e23a0e82..4cfd4e9b5586 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h | |||
@@ -244,7 +244,14 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ | |||
244 | 244 | ||
245 | u16 xgxs_config_tx[4]; /* 0x1A0 */ | 245 | u16 xgxs_config_tx[4]; /* 0x1A0 */ |
246 | 246 | ||
247 | u32 Reserved1[57]; /* 0x1A8 */ | 247 | u32 Reserved1[56]; /* 0x1A8 */ |
248 | u32 default_cfg; /* 0x288 */ | ||
249 | /* Enable BAM on KR */ | ||
250 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000 | ||
251 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20 | ||
252 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_DISABLED 0x00000000 | ||
253 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED 0x00100000 | ||
254 | |||
248 | u32 speed_capability_mask2; /* 0x28C */ | 255 | u32 speed_capability_mask2; /* 0x28C */ |
249 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF | 256 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF |
250 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 | 257 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 |
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 2326774df843..580919619252 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -610,7 +610,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, | |||
610 | /* reset and unreset the BigMac */ | 610 | /* reset and unreset the BigMac */ |
611 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, | 611 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, |
612 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | 612 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); |
613 | udelay(10); | 613 | msleep(1); |
614 | 614 | ||
615 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, | 615 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, |
616 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | 616 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); |
@@ -3525,13 +3525,19 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, | |||
3525 | DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); | 3525 | DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); |
3526 | 3526 | ||
3527 | /* Enable CL37 BAM */ | 3527 | /* Enable CL37 BAM */ |
3528 | bnx2x_cl45_read(bp, phy, | 3528 | if (REG_RD(bp, params->shmem_base + |
3529 | MDIO_AN_DEVAD, | 3529 | offsetof(struct shmem_region, dev_info. |
3530 | MDIO_AN_REG_8073_BAM, &val); | 3530 | port_hw_config[params->port].default_cfg)) & |
3531 | bnx2x_cl45_write(bp, phy, | 3531 | PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { |
3532 | MDIO_AN_DEVAD, | ||
3533 | MDIO_AN_REG_8073_BAM, val | 1); | ||
3534 | 3532 | ||
3533 | bnx2x_cl45_read(bp, phy, | ||
3534 | MDIO_AN_DEVAD, | ||
3535 | MDIO_AN_REG_8073_BAM, &val); | ||
3536 | bnx2x_cl45_write(bp, phy, | ||
3537 | MDIO_AN_DEVAD, | ||
3538 | MDIO_AN_REG_8073_BAM, val | 1); | ||
3539 | DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); | ||
3540 | } | ||
3535 | if (params->loopback_mode == LOOPBACK_EXT) { | 3541 | if (params->loopback_mode == LOOPBACK_EXT) { |
3536 | bnx2x_807x_force_10G(bp, phy); | 3542 | bnx2x_807x_force_10G(bp, phy); |
3537 | DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); | 3543 | DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); |
@@ -5302,7 +5308,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, | |||
5302 | { | 5308 | { |
5303 | struct bnx2x *bp = params->bp; | 5309 | struct bnx2x *bp = params->bp; |
5304 | u16 autoneg_val, an_1000_val, an_10_100_val; | 5310 | u16 autoneg_val, an_1000_val, an_10_100_val; |
5305 | bnx2x_wait_reset_complete(bp, phy); | 5311 | |
5306 | bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, | 5312 | bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, |
5307 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); | 5313 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); |
5308 | 5314 | ||
@@ -5431,6 +5437,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, | |||
5431 | 5437 | ||
5432 | /* HW reset */ | 5438 | /* HW reset */ |
5433 | bnx2x_ext_phy_hw_reset(bp, params->port); | 5439 | bnx2x_ext_phy_hw_reset(bp, params->port); |
5440 | bnx2x_wait_reset_complete(bp, phy); | ||
5434 | 5441 | ||
5435 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); | 5442 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); |
5436 | return bnx2x_848xx_cmn_config_init(phy, params, vars); | 5443 | return bnx2x_848xx_cmn_config_init(phy, params, vars); |
@@ -5441,7 +5448,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
5441 | struct link_vars *vars) | 5448 | struct link_vars *vars) |
5442 | { | 5449 | { |
5443 | struct bnx2x *bp = params->bp; | 5450 | struct bnx2x *bp = params->bp; |
5444 | u8 port = params->port, initialize = 1; | 5451 | u8 port, initialize = 1; |
5445 | u16 val; | 5452 | u16 val; |
5446 | u16 temp; | 5453 | u16 temp; |
5447 | u32 actual_phy_selection; | 5454 | u32 actual_phy_selection; |
@@ -5450,11 +5457,16 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
5450 | /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ | 5457 | /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ |
5451 | 5458 | ||
5452 | msleep(1); | 5459 | msleep(1); |
5460 | if (CHIP_IS_E2(bp)) | ||
5461 | port = BP_PATH(bp); | ||
5462 | else | ||
5463 | port = params->port; | ||
5453 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, | 5464 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, |
5454 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, | 5465 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
5455 | port); | 5466 | port); |
5456 | msleep(200); /* 100 is not enough */ | 5467 | bnx2x_wait_reset_complete(bp, phy); |
5457 | 5468 | /* Wait for GPHY to come out of reset */ | |
5469 | msleep(50); | ||
5458 | /* BCM84823 requires that XGXS links up first @ 10G for normal | 5470 | /* BCM84823 requires that XGXS links up first @ 10G for normal |
5459 | behavior */ | 5471 | behavior */ |
5460 | temp = vars->line_speed; | 5472 | temp = vars->line_speed; |
@@ -5625,7 +5637,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, | |||
5625 | struct link_params *params) | 5637 | struct link_params *params) |
5626 | { | 5638 | { |
5627 | struct bnx2x *bp = params->bp; | 5639 | struct bnx2x *bp = params->bp; |
5628 | u8 port = params->port; | 5640 | u8 port; |
5641 | if (CHIP_IS_E2(bp)) | ||
5642 | port = BP_PATH(bp); | ||
5643 | else | ||
5644 | port = params->port; | ||
5629 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, | 5645 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, |
5630 | MISC_REGISTERS_GPIO_OUTPUT_LOW, | 5646 | MISC_REGISTERS_GPIO_OUTPUT_LOW, |
5631 | port); | 5647 | port); |
@@ -6928,7 +6944,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
6928 | u8 reset_ext_phy) | 6944 | u8 reset_ext_phy) |
6929 | { | 6945 | { |
6930 | struct bnx2x *bp = params->bp; | 6946 | struct bnx2x *bp = params->bp; |
6931 | u8 phy_index, port = params->port; | 6947 | u8 phy_index, port = params->port, clear_latch_ind = 0; |
6932 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); | 6948 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); |
6933 | /* disable attentions */ | 6949 | /* disable attentions */ |
6934 | vars->link_status = 0; | 6950 | vars->link_status = 0; |
@@ -6966,9 +6982,18 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
6966 | params->phy[phy_index].link_reset( | 6982 | params->phy[phy_index].link_reset( |
6967 | ¶ms->phy[phy_index], | 6983 | ¶ms->phy[phy_index], |
6968 | params); | 6984 | params); |
6985 | if (params->phy[phy_index].flags & | ||
6986 | FLAGS_REARM_LATCH_SIGNAL) | ||
6987 | clear_latch_ind = 1; | ||
6969 | } | 6988 | } |
6970 | } | 6989 | } |
6971 | 6990 | ||
6991 | if (clear_latch_ind) { | ||
6992 | /* Clear latching indication */ | ||
6993 | bnx2x_rearm_latch_signal(bp, port, 0); | ||
6994 | bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4, | ||
6995 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); | ||
6996 | } | ||
6972 | if (params->phy[INT_PHY].link_reset) | 6997 | if (params->phy[INT_PHY].link_reset) |
6973 | params->phy[INT_PHY].link_reset( | 6998 | params->phy[INT_PHY].link_reset( |
6974 | ¶ms->phy[INT_PHY], params); | 6999 | ¶ms->phy[INT_PHY], params); |
@@ -6999,6 +7024,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
6999 | s8 port; | 7024 | s8 port; |
7000 | s8 port_of_path = 0; | 7025 | s8 port_of_path = 0; |
7001 | 7026 | ||
7027 | bnx2x_ext_phy_hw_reset(bp, 0); | ||
7002 | /* PART1 - Reset both phys */ | 7028 | /* PART1 - Reset both phys */ |
7003 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 7029 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
7004 | u32 shmem_base, shmem2_base; | 7030 | u32 shmem_base, shmem2_base; |
@@ -7021,7 +7047,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
7021 | return -EINVAL; | 7047 | return -EINVAL; |
7022 | } | 7048 | } |
7023 | /* disable attentions */ | 7049 | /* disable attentions */ |
7024 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, | 7050 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + |
7051 | port_of_path*4, | ||
7025 | (NIG_MASK_XGXS0_LINK_STATUS | | 7052 | (NIG_MASK_XGXS0_LINK_STATUS | |
7026 | NIG_MASK_XGXS0_LINK10G | | 7053 | NIG_MASK_XGXS0_LINK10G | |
7027 | NIG_MASK_SERDES0_LINK_STATUS | | 7054 | NIG_MASK_SERDES0_LINK_STATUS | |
@@ -7132,7 +7159,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, | |||
7132 | (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); | 7159 | (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); |
7133 | REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); | 7160 | REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); |
7134 | 7161 | ||
7135 | bnx2x_ext_phy_hw_reset(bp, 1); | 7162 | bnx2x_ext_phy_hw_reset(bp, 0); |
7136 | msleep(5); | 7163 | msleep(5); |
7137 | for (port = 0; port < PORT_MAX; port++) { | 7164 | for (port = 0; port < PORT_MAX; port++) { |
7138 | u32 shmem_base, shmem2_base; | 7165 | u32 shmem_base, shmem2_base; |
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 8427533fe313..8b4cea57a6c5 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c | |||
@@ -33,6 +33,9 @@ MODULE_LICENSE("GPL"); | |||
33 | MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>"); | 33 | MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>"); |
34 | MODULE_DESCRIPTION("CAIF SPI driver"); | 34 | MODULE_DESCRIPTION("CAIF SPI driver"); |
35 | 35 | ||
36 | /* Returns the number of padding bytes for alignment. */ | ||
37 | #define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1))))) | ||
38 | |||
36 | static int spi_loop; | 39 | static int spi_loop; |
37 | module_param(spi_loop, bool, S_IRUGO); | 40 | module_param(spi_loop, bool, S_IRUGO); |
38 | MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); | 41 | MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); |
@@ -41,7 +44,10 @@ MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); | |||
41 | module_param(spi_frm_align, int, S_IRUGO); | 44 | module_param(spi_frm_align, int, S_IRUGO); |
42 | MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment."); | 45 | MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment."); |
43 | 46 | ||
44 | /* SPI padding options. */ | 47 | /* |
48 | * SPI padding options. | ||
49 | * Warning: must be a base of 2 (& operation used) and can not be zero ! | ||
50 | */ | ||
45 | module_param(spi_up_head_align, int, S_IRUGO); | 51 | module_param(spi_up_head_align, int, S_IRUGO); |
46 | MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment."); | 52 | MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment."); |
47 | 53 | ||
@@ -240,15 +246,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, | |||
240 | static const struct file_operations dbgfs_state_fops = { | 246 | static const struct file_operations dbgfs_state_fops = { |
241 | .open = dbgfs_open, | 247 | .open = dbgfs_open, |
242 | .read = dbgfs_state, | 248 | .read = dbgfs_state, |
243 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE |
244 | .llseek = default_llseek, | ||
245 | }; | 250 | }; |
246 | 251 | ||
247 | static const struct file_operations dbgfs_frame_fops = { | 252 | static const struct file_operations dbgfs_frame_fops = { |
248 | .open = dbgfs_open, | 253 | .open = dbgfs_open, |
249 | .read = dbgfs_frame, | 254 | .read = dbgfs_frame, |
250 | .owner = THIS_MODULE, | 255 | .owner = THIS_MODULE |
251 | .llseek = default_llseek, | ||
252 | }; | 256 | }; |
253 | 257 | ||
254 | static inline void dev_debugfs_add(struct cfspi *cfspi) | 258 | static inline void dev_debugfs_add(struct cfspi *cfspi) |
@@ -337,6 +341,9 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
337 | u8 *dst = buf; | 341 | u8 *dst = buf; |
338 | caif_assert(buf); | 342 | caif_assert(buf); |
339 | 343 | ||
344 | if (cfspi->slave && !cfspi->slave_talked) | ||
345 | cfspi->slave_talked = true; | ||
346 | |||
340 | do { | 347 | do { |
341 | struct sk_buff *skb; | 348 | struct sk_buff *skb; |
342 | struct caif_payload_info *info; | 349 | struct caif_payload_info *info; |
@@ -357,8 +364,8 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
357 | * Compute head offset i.e. number of bytes to add to | 364 | * Compute head offset i.e. number of bytes to add to |
358 | * get the start of the payload aligned. | 365 | * get the start of the payload aligned. |
359 | */ | 366 | */ |
360 | if (spi_up_head_align) { | 367 | if (spi_up_head_align > 1) { |
361 | spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); | 368 | spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); |
362 | *dst = (u8)(spad - 1); | 369 | *dst = (u8)(spad - 1); |
363 | dst += spad; | 370 | dst += spad; |
364 | } | 371 | } |
@@ -373,7 +380,7 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
373 | * Compute tail offset i.e. number of bytes to add to | 380 | * Compute tail offset i.e. number of bytes to add to |
374 | * get the complete CAIF frame aligned. | 381 | * get the complete CAIF frame aligned. |
375 | */ | 382 | */ |
376 | epad = (skb->len + spad) & spi_up_tail_align; | 383 | epad = PAD_POW2((skb->len + spad), spi_up_tail_align); |
377 | dst += epad; | 384 | dst += epad; |
378 | 385 | ||
379 | dev_kfree_skb(skb); | 386 | dev_kfree_skb(skb); |
@@ -417,14 +424,14 @@ int cfspi_xmitlen(struct cfspi *cfspi) | |||
417 | * Compute head offset i.e. number of bytes to add to | 424 | * Compute head offset i.e. number of bytes to add to |
418 | * get the start of the payload aligned. | 425 | * get the start of the payload aligned. |
419 | */ | 426 | */ |
420 | if (spi_up_head_align) | 427 | if (spi_up_head_align > 1) |
421 | spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); | 428 | spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); |
422 | 429 | ||
423 | /* | 430 | /* |
424 | * Compute tail offset i.e. number of bytes to add to | 431 | * Compute tail offset i.e. number of bytes to add to |
425 | * get the complete CAIF frame aligned. | 432 | * get the complete CAIF frame aligned. |
426 | */ | 433 | */ |
427 | epad = (skb->len + spad) & spi_up_tail_align; | 434 | epad = PAD_POW2((skb->len + spad), spi_up_tail_align); |
428 | 435 | ||
429 | if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) { | 436 | if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) { |
430 | skb_queue_tail(&cfspi->chead, skb); | 437 | skb_queue_tail(&cfspi->chead, skb); |
@@ -433,6 +440,7 @@ int cfspi_xmitlen(struct cfspi *cfspi) | |||
433 | } else { | 440 | } else { |
434 | /* Put back packet. */ | 441 | /* Put back packet. */ |
435 | skb_queue_head(&cfspi->qhead, skb); | 442 | skb_queue_head(&cfspi->qhead, skb); |
443 | break; | ||
436 | } | 444 | } |
437 | } while (pkts <= CAIF_MAX_SPI_PKTS); | 445 | } while (pkts <= CAIF_MAX_SPI_PKTS); |
438 | 446 | ||
@@ -453,6 +461,15 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) | |||
453 | { | 461 | { |
454 | struct cfspi *cfspi = (struct cfspi *)ifc->priv; | 462 | struct cfspi *cfspi = (struct cfspi *)ifc->priv; |
455 | 463 | ||
464 | /* | ||
465 | * The slave device is the master on the link. Interrupts before the | ||
466 | * slave has transmitted are considered spurious. | ||
467 | */ | ||
468 | if (cfspi->slave && !cfspi->slave_talked) { | ||
469 | printk(KERN_WARNING "CFSPI: Spurious SS interrupt.\n"); | ||
470 | return; | ||
471 | } | ||
472 | |||
456 | if (!in_interrupt()) | 473 | if (!in_interrupt()) |
457 | spin_lock(&cfspi->lock); | 474 | spin_lock(&cfspi->lock); |
458 | if (assert) { | 475 | if (assert) { |
@@ -465,7 +482,8 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) | |||
465 | spin_unlock(&cfspi->lock); | 482 | spin_unlock(&cfspi->lock); |
466 | 483 | ||
467 | /* Wake up the xfer thread. */ | 484 | /* Wake up the xfer thread. */ |
468 | wake_up_interruptible(&cfspi->wait); | 485 | if (assert) |
486 | wake_up_interruptible(&cfspi->wait); | ||
469 | } | 487 | } |
470 | 488 | ||
471 | static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc) | 489 | static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc) |
@@ -523,7 +541,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
523 | * Compute head offset i.e. number of bytes added to | 541 | * Compute head offset i.e. number of bytes added to |
524 | * get the start of the payload aligned. | 542 | * get the start of the payload aligned. |
525 | */ | 543 | */ |
526 | if (spi_down_head_align) { | 544 | if (spi_down_head_align > 1) { |
527 | spad = 1 + *src; | 545 | spad = 1 + *src; |
528 | src += spad; | 546 | src += spad; |
529 | } | 547 | } |
@@ -564,7 +582,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
564 | * Compute tail offset i.e. number of bytes added to | 582 | * Compute tail offset i.e. number of bytes added to |
565 | * get the complete CAIF frame aligned. | 583 | * get the complete CAIF frame aligned. |
566 | */ | 584 | */ |
567 | epad = (pkt_len + spad) & spi_down_tail_align; | 585 | epad = PAD_POW2((pkt_len + spad), spi_down_tail_align); |
568 | src += epad; | 586 | src += epad; |
569 | } while ((src - buf) < len); | 587 | } while ((src - buf) < len); |
570 | 588 | ||
@@ -625,11 +643,20 @@ int cfspi_spi_probe(struct platform_device *pdev) | |||
625 | cfspi->ndev = ndev; | 643 | cfspi->ndev = ndev; |
626 | cfspi->pdev = pdev; | 644 | cfspi->pdev = pdev; |
627 | 645 | ||
628 | /* Set flow info */ | 646 | /* Set flow info. */ |
629 | cfspi->flow_off_sent = 0; | 647 | cfspi->flow_off_sent = 0; |
630 | cfspi->qd_low_mark = LOW_WATER_MARK; | 648 | cfspi->qd_low_mark = LOW_WATER_MARK; |
631 | cfspi->qd_high_mark = HIGH_WATER_MARK; | 649 | cfspi->qd_high_mark = HIGH_WATER_MARK; |
632 | 650 | ||
651 | /* Set slave info. */ | ||
652 | if (!strncmp(cfspi_spi_driver.driver.name, "cfspi_sspi", 10)) { | ||
653 | cfspi->slave = true; | ||
654 | cfspi->slave_talked = false; | ||
655 | } else { | ||
656 | cfspi->slave = false; | ||
657 | cfspi->slave_talked = false; | ||
658 | } | ||
659 | |||
633 | /* Assign the SPI device. */ | 660 | /* Assign the SPI device. */ |
634 | cfspi->dev = dev; | 661 | cfspi->dev = dev; |
635 | /* Assign the device ifc to this SPI interface. */ | 662 | /* Assign the device ifc to this SPI interface. */ |
diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c index 2111dbfea6fe..1b9943a4edab 100644 --- a/drivers/net/caif/caif_spi_slave.c +++ b/drivers/net/caif/caif_spi_slave.c | |||
@@ -36,10 +36,15 @@ static inline int forward_to_spi_cmd(struct cfspi *cfspi) | |||
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | int spi_frm_align = 2; | 38 | int spi_frm_align = 2; |
39 | int spi_up_head_align = 1; | 39 | |
40 | int spi_up_tail_align; | 40 | /* |
41 | int spi_down_head_align = 3; | 41 | * SPI padding options. |
42 | int spi_down_tail_align = 1; | 42 | * Warning: must be a base of 2 (& operation used) and can not be zero ! |
43 | */ | ||
44 | int spi_up_head_align = 1 << 1; | ||
45 | int spi_up_tail_align = 1 << 0; | ||
46 | int spi_down_head_align = 1 << 2; | ||
47 | int spi_down_tail_align = 1 << 1; | ||
43 | 48 | ||
44 | #ifdef CONFIG_DEBUG_FS | 49 | #ifdef CONFIG_DEBUG_FS |
45 | static inline void debugfs_store_prev(struct cfspi *cfspi) | 50 | static inline void debugfs_store_prev(struct cfspi *cfspi) |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 407d4e272075..046d846c652d 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -3341,7 +3341,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3341 | adapter->name = adapter->port[i]->name; | 3341 | adapter->name = adapter->port[i]->name; |
3342 | 3342 | ||
3343 | __set_bit(i, &adapter->registered_device_map); | 3343 | __set_bit(i, &adapter->registered_device_map); |
3344 | netif_tx_stop_all_queues(adapter->port[i]); | ||
3345 | } | 3344 | } |
3346 | } | 3345 | } |
3347 | if (!adapter->registered_device_map) { | 3346 | if (!adapter->registered_device_map) { |
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index f17703f410b3..f50bc98310f8 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c | |||
@@ -3736,7 +3736,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3736 | 3736 | ||
3737 | __set_bit(i, &adapter->registered_device_map); | 3737 | __set_bit(i, &adapter->registered_device_map); |
3738 | adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; | 3738 | adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; |
3739 | netif_tx_stop_all_queues(adapter->port[i]); | ||
3740 | } | 3739 | } |
3741 | } | 3740 | } |
3742 | if (!adapter->registered_device_map) { | 3741 | if (!adapter->registered_device_map) { |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 555ecc5a2e93..6de5e2e448a5 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
@@ -2600,7 +2600,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
2600 | pi->xact_addr_filt = -1; | 2600 | pi->xact_addr_filt = -1; |
2601 | pi->rx_offload = RX_CSO; | 2601 | pi->rx_offload = RX_CSO; |
2602 | netif_carrier_off(netdev); | 2602 | netif_carrier_off(netdev); |
2603 | netif_tx_stop_all_queues(netdev); | ||
2604 | netdev->irq = pdev->irq; | 2603 | netdev->irq = pdev->irq; |
2605 | 2604 | ||
2606 | netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | | 2605 | netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 385dc3204cb7..06bb9b799458 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -2871,7 +2871,6 @@ static int __devinit emac_probe(struct platform_device *ofdev, | |||
2871 | SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); | 2871 | SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); |
2872 | 2872 | ||
2873 | netif_carrier_off(ndev); | 2873 | netif_carrier_off(ndev); |
2874 | netif_stop_queue(ndev); | ||
2875 | 2874 | ||
2876 | err = register_netdev(ndev); | 2875 | err = register_netdev(ndev); |
2877 | if (err) { | 2876 | if (err) { |
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d85edf3119c2..c57d9a43ceca 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
@@ -2955,11 +2955,7 @@ jme_init_one(struct pci_dev *pdev, | |||
2955 | * Tell stack that we are not ready to work until open() | 2955 | * Tell stack that we are not ready to work until open() |
2956 | */ | 2956 | */ |
2957 | netif_carrier_off(netdev); | 2957 | netif_carrier_off(netdev); |
2958 | netif_stop_queue(netdev); | ||
2959 | 2958 | ||
2960 | /* | ||
2961 | * Register netdev | ||
2962 | */ | ||
2963 | rc = register_netdev(netdev); | 2959 | rc = register_netdev(netdev); |
2964 | if (rc) { | 2960 | if (rc) { |
2965 | pr_err("Cannot register net device\n"); | 2961 | pr_err("Cannot register net device\n"); |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a75ba9517404..e1d30d7f2071 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -41,9 +41,6 @@ | |||
41 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); | 41 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); |
42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
43 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); | 43 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); |
44 | MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); | ||
45 | MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); | ||
46 | MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); | ||
47 | MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); | 44 | MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); |
48 | 45 | ||
49 | char netxen_nic_driver_name[] = "netxen_nic"; | 46 | char netxen_nic_driver_name[] = "netxen_nic"; |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 7a298cdf9ab3..a3dcd04be22f 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -1450,7 +1450,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, | |||
1450 | netdev->irq = adapter->msix_entries[0].vector; | 1450 | netdev->irq = adapter->msix_entries[0].vector; |
1451 | 1451 | ||
1452 | netif_carrier_off(netdev); | 1452 | netif_carrier_off(netdev); |
1453 | netif_stop_queue(netdev); | ||
1454 | 1453 | ||
1455 | err = register_netdev(netdev); | 1454 | err = register_netdev(netdev); |
1456 | if (err) { | 1455 | if (err) { |
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h index 52f38e12a879..50f712e99e96 100644 --- a/drivers/net/smsc911x.h +++ b/drivers/net/smsc911x.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #define __SMSC911X_H__ | 22 | #define __SMSC911X_H__ |
23 | 23 | ||
24 | #define TX_FIFO_LOW_THRESHOLD ((u32)1600) | 24 | #define TX_FIFO_LOW_THRESHOLD ((u32)1600) |
25 | #define SMSC911X_EEPROM_SIZE ((u32)7) | 25 | #define SMSC911X_EEPROM_SIZE ((u32)128) |
26 | #define USE_DEBUG 0 | 26 | #define USE_DEBUG 0 |
27 | 27 | ||
28 | /* This is the maximum number of packets to be received every | 28 | /* This is the maximum number of packets to be received every |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 28e1ffb13db9..c78a50586c1d 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -2021,7 +2021,6 @@ static int __devinit de_init_one (struct pci_dev *pdev, | |||
2021 | de->media_timer.data = (unsigned long) de; | 2021 | de->media_timer.data = (unsigned long) de; |
2022 | 2022 | ||
2023 | netif_carrier_off(dev); | 2023 | netif_carrier_off(dev); |
2024 | netif_stop_queue(dev); | ||
2025 | 2024 | ||
2026 | /* wake up device, assign resources */ | 2025 | /* wake up device, assign resources */ |
2027 | rc = pci_enable_device(pdev); | 2026 | rc = pci_enable_device(pdev); |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ca7fc9df1ccf..c04d49e31f81 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/usb/usbnet.h> | 45 | #include <linux/usb/usbnet.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/kernel.h> | 47 | #include <linux/kernel.h> |
48 | #include <linux/pm_runtime.h> | ||
48 | 49 | ||
49 | #define DRIVER_VERSION "22-Aug-2005" | 50 | #define DRIVER_VERSION "22-Aug-2005" |
50 | 51 | ||
@@ -1273,6 +1274,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1273 | struct usb_device *xdev; | 1274 | struct usb_device *xdev; |
1274 | int status; | 1275 | int status; |
1275 | const char *name; | 1276 | const char *name; |
1277 | struct usb_driver *driver = to_usb_driver(udev->dev.driver); | ||
1278 | |||
1279 | /* usbnet already took usb runtime pm, so have to enable the feature | ||
1280 | * for usb interface, otherwise usb_autopm_get_interface may return | ||
1281 | * failure if USB_SUSPEND(RUNTIME_PM) is enabled. | ||
1282 | */ | ||
1283 | if (!driver->supports_autosuspend) { | ||
1284 | driver->supports_autosuspend = 1; | ||
1285 | pm_runtime_enable(&udev->dev); | ||
1286 | } | ||
1276 | 1287 | ||
1277 | name = udev->dev.driver->name; | 1288 | name = udev->dev.driver->name; |
1278 | info = (struct driver_info *) prod->driver_info; | 1289 | info = (struct driver_info *) prod->driver_info; |
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 32dee2ce5d31..d5ef696298ee 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | #define DRV_DESCRIPTION "802.11 data/management/control stack" | 55 | #define DRV_DESCRIPTION "802.11 data/management/control stack" |
56 | #define DRV_NAME "libipw" | 56 | #define DRV_NAME "libipw" |
57 | #define DRV_PROCNAME "ieee80211" | ||
57 | #define DRV_VERSION LIBIPW_VERSION | 58 | #define DRV_VERSION LIBIPW_VERSION |
58 | #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" | 59 | #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" |
59 | 60 | ||
@@ -293,16 +294,16 @@ static int __init libipw_init(void) | |||
293 | struct proc_dir_entry *e; | 294 | struct proc_dir_entry *e; |
294 | 295 | ||
295 | libipw_debug_level = debug; | 296 | libipw_debug_level = debug; |
296 | libipw_proc = proc_mkdir("ieee80211", init_net.proc_net); | 297 | libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net); |
297 | if (libipw_proc == NULL) { | 298 | if (libipw_proc == NULL) { |
298 | LIBIPW_ERROR("Unable to create " DRV_NAME | 299 | LIBIPW_ERROR("Unable to create " DRV_PROCNAME |
299 | " proc directory\n"); | 300 | " proc directory\n"); |
300 | return -EIO; | 301 | return -EIO; |
301 | } | 302 | } |
302 | e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, | 303 | e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, |
303 | &debug_level_proc_fops); | 304 | &debug_level_proc_fops); |
304 | if (!e) { | 305 | if (!e) { |
305 | remove_proc_entry(DRV_NAME, init_net.proc_net); | 306 | remove_proc_entry(DRV_PROCNAME, init_net.proc_net); |
306 | libipw_proc = NULL; | 307 | libipw_proc = NULL; |
307 | return -EIO; | 308 | return -EIO; |
308 | } | 309 | } |
@@ -319,7 +320,7 @@ static void __exit libipw_exit(void) | |||
319 | #ifdef CONFIG_LIBIPW_DEBUG | 320 | #ifdef CONFIG_LIBIPW_DEBUG |
320 | if (libipw_proc) { | 321 | if (libipw_proc) { |
321 | remove_proc_entry("debug_level", libipw_proc); | 322 | remove_proc_entry("debug_level", libipw_proc); |
322 | remove_proc_entry(DRV_NAME, init_net.proc_net); | 323 | remove_proc_entry(DRV_PROCNAME, init_net.proc_net); |
323 | libipw_proc = NULL; | 324 | libipw_proc = NULL; |
324 | } | 325 | } |
325 | #endif /* CONFIG_LIBIPW_DEBUG */ | 326 | #endif /* CONFIG_LIBIPW_DEBUG */ |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index eea1ef2f502b..4396d4b9bfb9 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -221,9 +221,6 @@ config RT2X00_LIB_LEDS | |||
221 | boolean | 221 | boolean |
222 | default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) | 222 | default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) |
223 | 223 | ||
224 | comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00" | ||
225 | depends on RT2X00_LIB=y && LEDS_CLASS=m | ||
226 | |||
227 | config RT2X00_LIB_DEBUGFS | 224 | config RT2X00_LIB_DEBUGFS |
228 | bool "Ralink debugfs support" | 225 | bool "Ralink debugfs support" |
229 | depends on RT2X00_LIB && MAC80211_DEBUGFS | 226 | depends on RT2X00_LIB && MAC80211_DEBUGFS |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 68cf0c99138a..7b5080c45569 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -1159,11 +1159,11 @@ int __devinit rio_init_mports(void) | |||
1159 | 1159 | ||
1160 | list_for_each_entry(port, &rio_mports, node) { | 1160 | list_for_each_entry(port, &rio_mports, node) { |
1161 | if (!request_mem_region(port->iores.start, | 1161 | if (!request_mem_region(port->iores.start, |
1162 | port->iores.end - port->iores.start, | 1162 | resource_size(&port->iores), |
1163 | port->name)) { | 1163 | port->name)) { |
1164 | printk(KERN_ERR | 1164 | printk(KERN_ERR |
1165 | "RIO: Error requesting master port region 0x%016llx-0x%016llx\n", | 1165 | "RIO: Error requesting master port region 0x%016llx-0x%016llx\n", |
1166 | (u64)port->iores.start, (u64)port->iores.end - 1); | 1166 | (u64)port->iores.start, (u64)port->iores.end); |
1167 | rc = -ENOMEM; | 1167 | rc = -ENOMEM; |
1168 | goto out; | 1168 | goto out; |
1169 | } | 1169 | } |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 359d1e04626c..f0d638922644 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #ifdef CONFIG_SH_SECUREEDGE5410 | 36 | #ifdef CONFIG_SH_SECUREEDGE5410 |
37 | #include <asm/rtc.h> | 37 | #include <asm/rtc.h> |
38 | #include <mach/snapgear.h> | 38 | #include <mach/secureedge5410.h> |
39 | 39 | ||
40 | #define RTC_RESET 0x1000 | 40 | #define RTC_RESET 0x1000 |
41 | #define RTC_IODATA 0x0800 | 41 | #define RTC_IODATA 0x0800 |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1de30eb83bb0..f3cf924a2cd9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -320,19 +320,11 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
320 | "changed. The Linux SCSI layer does not " | 320 | "changed. The Linux SCSI layer does not " |
321 | "automatically adjust these parameters.\n"); | 321 | "automatically adjust these parameters.\n"); |
322 | 322 | ||
323 | if (scmd->request->cmd_flags & REQ_HARDBARRIER) | 323 | /* |
324 | /* | 324 | * Pass the UA upwards for a determination in the completion |
325 | * barrier requests should always retry on UA | 325 | * functions. |
326 | * otherwise block will get a spurious error | 326 | */ |
327 | */ | 327 | return SUCCESS; |
328 | return NEEDS_RETRY; | ||
329 | else | ||
330 | /* | ||
331 | * for normal (non barrier) commands, pass the | ||
332 | * UA upwards for a determination in the | ||
333 | * completion functions | ||
334 | */ | ||
335 | return SUCCESS; | ||
336 | 328 | ||
337 | /* these three are not supported */ | 329 | /* these three are not supported */ |
338 | case COPY_ABORTED: | 330 | case COPY_ABORTED: |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index d4b711c9a416..3374618300af 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
20 | #include <linux/vt_kern.h> | 20 | #include <linux/vt_kern.h> |
21 | #include <linux/input.h> | ||
21 | 22 | ||
22 | #define MAX_CONFIG_LEN 40 | 23 | #define MAX_CONFIG_LEN 40 |
23 | 24 | ||
@@ -37,6 +38,61 @@ static struct tty_driver *kgdb_tty_driver; | |||
37 | static int kgdb_tty_line; | 38 | static int kgdb_tty_line; |
38 | 39 | ||
39 | #ifdef CONFIG_KDB_KEYBOARD | 40 | #ifdef CONFIG_KDB_KEYBOARD |
41 | static int kgdboc_reset_connect(struct input_handler *handler, | ||
42 | struct input_dev *dev, | ||
43 | const struct input_device_id *id) | ||
44 | { | ||
45 | input_reset_device(dev); | ||
46 | |||
47 | /* Retrun an error - we do not want to bind, just to reset */ | ||
48 | return -ENODEV; | ||
49 | } | ||
50 | |||
51 | static void kgdboc_reset_disconnect(struct input_handle *handle) | ||
52 | { | ||
53 | /* We do not expect anyone to actually bind to us */ | ||
54 | BUG(); | ||
55 | } | ||
56 | |||
57 | static const struct input_device_id kgdboc_reset_ids[] = { | ||
58 | { | ||
59 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | ||
60 | .evbit = { BIT_MASK(EV_KEY) }, | ||
61 | }, | ||
62 | { } | ||
63 | }; | ||
64 | |||
65 | static struct input_handler kgdboc_reset_handler = { | ||
66 | .connect = kgdboc_reset_connect, | ||
67 | .disconnect = kgdboc_reset_disconnect, | ||
68 | .name = "kgdboc_reset", | ||
69 | .id_table = kgdboc_reset_ids, | ||
70 | }; | ||
71 | |||
72 | static DEFINE_MUTEX(kgdboc_reset_mutex); | ||
73 | |||
74 | static void kgdboc_restore_input_helper(struct work_struct *dummy) | ||
75 | { | ||
76 | /* | ||
77 | * We need to take a mutex to prevent several instances of | ||
78 | * this work running on different CPUs so they don't try | ||
79 | * to register again already registered handler. | ||
80 | */ | ||
81 | mutex_lock(&kgdboc_reset_mutex); | ||
82 | |||
83 | if (input_register_handler(&kgdboc_reset_handler) == 0) | ||
84 | input_unregister_handler(&kgdboc_reset_handler); | ||
85 | |||
86 | mutex_unlock(&kgdboc_reset_mutex); | ||
87 | } | ||
88 | |||
89 | static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | ||
90 | |||
91 | static void kgdboc_restore_input(void) | ||
92 | { | ||
93 | schedule_work(&kgdboc_restore_input_work); | ||
94 | } | ||
95 | |||
40 | static int kgdboc_register_kbd(char **cptr) | 96 | static int kgdboc_register_kbd(char **cptr) |
41 | { | 97 | { |
42 | if (strncmp(*cptr, "kbd", 3) == 0) { | 98 | if (strncmp(*cptr, "kbd", 3) == 0) { |
@@ -64,10 +120,12 @@ static void kgdboc_unregister_kbd(void) | |||
64 | i--; | 120 | i--; |
65 | } | 121 | } |
66 | } | 122 | } |
123 | flush_work_sync(&kgdboc_restore_input_work); | ||
67 | } | 124 | } |
68 | #else /* ! CONFIG_KDB_KEYBOARD */ | 125 | #else /* ! CONFIG_KDB_KEYBOARD */ |
69 | #define kgdboc_register_kbd(x) 0 | 126 | #define kgdboc_register_kbd(x) 0 |
70 | #define kgdboc_unregister_kbd() | 127 | #define kgdboc_unregister_kbd() |
128 | #define kgdboc_restore_input() | ||
71 | #endif /* ! CONFIG_KDB_KEYBOARD */ | 129 | #endif /* ! CONFIG_KDB_KEYBOARD */ |
72 | 130 | ||
73 | static int kgdboc_option_setup(char *opt) | 131 | static int kgdboc_option_setup(char *opt) |
@@ -231,6 +289,7 @@ static void kgdboc_post_exp_handler(void) | |||
231 | dbg_restore_graphics = 0; | 289 | dbg_restore_graphics = 0; |
232 | con_debug_leave(); | 290 | con_debug_leave(); |
233 | } | 291 | } |
292 | kgdboc_restore_input(); | ||
234 | } | 293 | } |
235 | 294 | ||
236 | static struct kgdb_io kgdboc_io_ops = { | 295 | static struct kgdb_io kgdboc_io_ops = { |
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index fd0d1b98901c..09615b51d591 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c | |||
@@ -90,8 +90,8 @@ struct clk_rate_round_data { | |||
90 | static long clk_rate_round_helper(struct clk_rate_round_data *rounder) | 90 | static long clk_rate_round_helper(struct clk_rate_round_data *rounder) |
91 | { | 91 | { |
92 | unsigned long rate_error, rate_error_prev = ~0UL; | 92 | unsigned long rate_error, rate_error_prev = ~0UL; |
93 | unsigned long rate_best_fit = rounder->rate; | ||
94 | unsigned long highest, lowest, freq; | 93 | unsigned long highest, lowest, freq; |
94 | long rate_best_fit = -ENOENT; | ||
95 | int i; | 95 | int i; |
96 | 96 | ||
97 | highest = 0; | 97 | highest = 0; |
@@ -146,7 +146,7 @@ long clk_rate_table_round(struct clk *clk, | |||
146 | }; | 146 | }; |
147 | 147 | ||
148 | if (clk->nr_freqs < 1) | 148 | if (clk->nr_freqs < 1) |
149 | return 0; | 149 | return -ENOSYS; |
150 | 150 | ||
151 | return clk_rate_round_helper(&table_round); | 151 | return clk_rate_round_helper(&table_round); |
152 | } | 152 | } |
@@ -541,6 +541,98 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
541 | } | 541 | } |
542 | EXPORT_SYMBOL_GPL(clk_round_rate); | 542 | EXPORT_SYMBOL_GPL(clk_round_rate); |
543 | 543 | ||
544 | long clk_round_parent(struct clk *clk, unsigned long target, | ||
545 | unsigned long *best_freq, unsigned long *parent_freq, | ||
546 | unsigned int div_min, unsigned int div_max) | ||
547 | { | ||
548 | struct cpufreq_frequency_table *freq, *best = NULL; | ||
549 | unsigned long error = ULONG_MAX, freq_high, freq_low, div; | ||
550 | struct clk *parent = clk_get_parent(clk); | ||
551 | |||
552 | if (!parent) { | ||
553 | *parent_freq = 0; | ||
554 | *best_freq = clk_round_rate(clk, target); | ||
555 | return abs(target - *best_freq); | ||
556 | } | ||
557 | |||
558 | for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END; | ||
559 | freq++) { | ||
560 | if (freq->frequency == CPUFREQ_ENTRY_INVALID) | ||
561 | continue; | ||
562 | |||
563 | if (unlikely(freq->frequency / target <= div_min - 1)) { | ||
564 | unsigned long freq_max; | ||
565 | |||
566 | freq_max = (freq->frequency + div_min / 2) / div_min; | ||
567 | if (error > target - freq_max) { | ||
568 | error = target - freq_max; | ||
569 | best = freq; | ||
570 | if (best_freq) | ||
571 | *best_freq = freq_max; | ||
572 | } | ||
573 | |||
574 | pr_debug("too low freq %lu, error %lu\n", freq->frequency, | ||
575 | target - freq_max); | ||
576 | |||
577 | if (!error) | ||
578 | break; | ||
579 | |||
580 | continue; | ||
581 | } | ||
582 | |||
583 | if (unlikely(freq->frequency / target >= div_max)) { | ||
584 | unsigned long freq_min; | ||
585 | |||
586 | freq_min = (freq->frequency + div_max / 2) / div_max; | ||
587 | if (error > freq_min - target) { | ||
588 | error = freq_min - target; | ||
589 | best = freq; | ||
590 | if (best_freq) | ||
591 | *best_freq = freq_min; | ||
592 | } | ||
593 | |||
594 | pr_debug("too high freq %lu, error %lu\n", freq->frequency, | ||
595 | freq_min - target); | ||
596 | |||
597 | if (!error) | ||
598 | break; | ||
599 | |||
600 | continue; | ||
601 | } | ||
602 | |||
603 | div = freq->frequency / target; | ||
604 | freq_high = freq->frequency / div; | ||
605 | freq_low = freq->frequency / (div + 1); | ||
606 | |||
607 | if (freq_high - target < error) { | ||
608 | error = freq_high - target; | ||
609 | best = freq; | ||
610 | if (best_freq) | ||
611 | *best_freq = freq_high; | ||
612 | } | ||
613 | |||
614 | if (target - freq_low < error) { | ||
615 | error = target - freq_low; | ||
616 | best = freq; | ||
617 | if (best_freq) | ||
618 | *best_freq = freq_low; | ||
619 | } | ||
620 | |||
621 | pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n", | ||
622 | freq->frequency, div, freq_high, div + 1, freq_low, | ||
623 | *best_freq, best->frequency); | ||
624 | |||
625 | if (!error) | ||
626 | break; | ||
627 | } | ||
628 | |||
629 | if (parent_freq) | ||
630 | *parent_freq = best->frequency; | ||
631 | |||
632 | return error; | ||
633 | } | ||
634 | EXPORT_SYMBOL_GPL(clk_round_parent); | ||
635 | |||
544 | #ifdef CONFIG_PM | 636 | #ifdef CONFIG_PM |
545 | static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) | 637 | static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) |
546 | { | 638 | { |
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 873a99ff8f64..e5e9e6735f7d 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -79,7 +79,7 @@ static void __init intc_register_irq(struct intc_desc *desc, | |||
79 | * Register the IRQ position with the global IRQ map, then insert | 79 | * Register the IRQ position with the global IRQ map, then insert |
80 | * it in to the radix tree. | 80 | * it in to the radix tree. |
81 | */ | 81 | */ |
82 | irq_reserve_irqs(irq, 1); | 82 | irq_reserve_irq(irq); |
83 | 83 | ||
84 | raw_spin_lock_irqsave(&intc_big_lock, flags); | 84 | raw_spin_lock_irqsave(&intc_big_lock, flags); |
85 | radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); | 85 | radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); |
diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c index 4187cce20ffd..a3677c9dfe36 100644 --- a/drivers/sh/intc/dynamic.c +++ b/drivers/sh/intc/dynamic.c | |||
@@ -60,5 +60,5 @@ void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) | |||
60 | int i; | 60 | int i; |
61 | 61 | ||
62 | for (i = 0; i < nr_vecs; i++) | 62 | for (i = 0; i < nr_vecs; i++) |
63 | irq_reserve_irqs(evt2irq(vectors[i].vect), 1); | 63 | irq_reserve_irq(evt2irq(vectors[i].vect)); |
64 | } | 64 | } |
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 22c6c6659f5b..ee8b47746a15 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | |||
@@ -285,9 +285,9 @@ A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_I | |||
285 | do { | 285 | do { |
286 | 286 | ||
287 | /* check if host supports scatter requests and it meets our requirements */ | 287 | /* check if host supports scatter requests and it meets our requirements */ |
288 | if (device->func->card->host->max_hw_segs < MAX_SCATTER_ENTRIES_PER_REQ) { | 288 | if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { |
289 | AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", | 289 | AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", |
290 | device->func->card->host->max_hw_segs, MAX_SCATTER_ENTRIES_PER_REQ)); | 290 | device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ)); |
291 | status = A_ENOTSUP; | 291 | status = A_ENOTSUP; |
292 | break; | 292 | break; |
293 | } | 293 | } |
diff --git a/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h b/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h +++ /dev/null | |||
diff --git a/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h b/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h +++ /dev/null | |||
diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index bbf3d9c4abb0..097e82bc7a63 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c | |||
@@ -766,7 +766,7 @@ static int solo_enc_open(struct file *file) | |||
766 | &solo_enc->lock, | 766 | &solo_enc->lock, |
767 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 767 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
768 | V4L2_FIELD_INTERLACED, | 768 | V4L2_FIELD_INTERLACED, |
769 | sizeof(struct videobuf_buffer), fh); | 769 | sizeof(struct videobuf_buffer), fh, NULL); |
770 | 770 | ||
771 | spin_unlock(&solo_enc->lock); | 771 | spin_unlock(&solo_enc->lock); |
772 | 772 | ||
diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c index 9731fa02b5e8..6ffd21de837d 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/drivers/staging/solo6x10/solo6010-v4l2.c | |||
@@ -437,7 +437,7 @@ static int solo_v4l2_open(struct file *file) | |||
437 | &solo_dev->pdev->dev, &fh->slock, | 437 | &solo_dev->pdev->dev, &fh->slock, |
438 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 438 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
439 | SOLO_DISP_PIX_FIELD, | 439 | SOLO_DISP_PIX_FIELD, |
440 | sizeof(struct videobuf_buffer), fh); | 440 | sizeof(struct videobuf_buffer), fh, NULL); |
441 | 441 | ||
442 | return 0; | 442 | return 0; |
443 | } | 443 | } |
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile new file mode 100644 index 000000000000..c43ef48b1a0f --- /dev/null +++ b/drivers/tty/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | obj-y += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ | ||
2 | tty_buffer.o tty_port.o tty_mutex.o | ||
3 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | ||
4 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | ||
5 | obj-$(CONFIG_AUDIT) += tty_audit.o | ||
6 | obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o | ||
7 | obj-$(CONFIG_N_HDLC) += n_hdlc.o | ||
8 | obj-$(CONFIG_N_GSM) += n_gsm.o | ||
9 | obj-$(CONFIG_R3964) += n_r3964.o | ||
10 | |||
11 | obj-y += vt/ | ||
diff --git a/drivers/char/n_gsm.c b/drivers/tty/n_gsm.c index 04ef3ef0a422..04ef3ef0a422 100644 --- a/drivers/char/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
diff --git a/drivers/char/n_hdlc.c b/drivers/tty/n_hdlc.c index 47d32281032c..47d32281032c 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
diff --git a/drivers/char/n_r3964.c b/drivers/tty/n_r3964.c index 88dda0c45ee0..88dda0c45ee0 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/tty/n_r3964.c | |||
diff --git a/drivers/char/n_tty.c b/drivers/tty/n_tty.c index 428f4fe0b5f7..428f4fe0b5f7 100644 --- a/drivers/char/n_tty.c +++ b/drivers/tty/n_tty.c | |||
diff --git a/drivers/char/pty.c b/drivers/tty/pty.c index 923a48585501..923a48585501 100644 --- a/drivers/char/pty.c +++ b/drivers/tty/pty.c | |||
diff --git a/drivers/char/sysrq.c b/drivers/tty/sysrq.c index eaa5d3efa79d..eaa5d3efa79d 100644 --- a/drivers/char/sysrq.c +++ b/drivers/tty/sysrq.c | |||
diff --git a/drivers/char/tty_audit.c b/drivers/tty/tty_audit.c index f64582b0f623..f64582b0f623 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/tty/tty_audit.c | |||
diff --git a/drivers/char/tty_buffer.c b/drivers/tty/tty_buffer.c index cc1e9850d655..cc1e9850d655 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
diff --git a/drivers/char/tty_io.c b/drivers/tty/tty_io.c index c05c5af5aa04..c05c5af5aa04 100644 --- a/drivers/char/tty_io.c +++ b/drivers/tty/tty_io.c | |||
diff --git a/drivers/char/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 0c1889971459..0c1889971459 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
diff --git a/drivers/char/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 412f9775d19c..412f9775d19c 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
diff --git a/drivers/char/tty_mutex.c b/drivers/tty/tty_mutex.c index 133697540c73..133697540c73 100644 --- a/drivers/char/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
diff --git a/drivers/char/tty_port.c b/drivers/tty/tty_port.c index 33d37d230f8f..33d37d230f8f 100644 --- a/drivers/char/tty_port.c +++ b/drivers/tty/tty_port.c | |||
diff --git a/drivers/char/.gitignore b/drivers/tty/vt/.gitignore index 83683a2d8e6a..83683a2d8e6a 100644 --- a/drivers/char/.gitignore +++ b/drivers/tty/vt/.gitignore | |||
diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile new file mode 100644 index 000000000000..14a51c9960df --- /dev/null +++ b/drivers/tty/vt/Makefile | |||
@@ -0,0 +1,34 @@ | |||
1 | # | ||
2 | # This file contains the font map for the default (hardware) font | ||
3 | # | ||
4 | FONTMAPFILE = cp437.uni | ||
5 | |||
6 | obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o \ | ||
7 | selection.o keyboard.o | ||
8 | obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o | ||
9 | obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o | ||
10 | |||
11 | # Files generated that shall be removed upon make clean | ||
12 | clean-files := consolemap_deftbl.c defkeymap.c | ||
13 | |||
14 | quiet_cmd_conmk = CONMK $@ | ||
15 | cmd_conmk = scripts/conmakehash $< > $@ | ||
16 | |||
17 | $(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE) | ||
18 | $(call cmd,conmk) | ||
19 | |||
20 | $(obj)/defkeymap.o: $(obj)/defkeymap.c | ||
21 | |||
22 | # Uncomment if you're changing the keymap and have an appropriate | ||
23 | # loadkeys version for the map. By default, we'll use the shipped | ||
24 | # versions. | ||
25 | # GENERATE_KEYMAP := 1 | ||
26 | |||
27 | ifdef GENERATE_KEYMAP | ||
28 | |||
29 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map | ||
30 | loadkeys --mktable $< > $@.tmp | ||
31 | sed -e 's/^static *//' $@.tmp > $@ | ||
32 | rm $@.tmp | ||
33 | |||
34 | endif | ||
diff --git a/drivers/char/consolemap.c b/drivers/tty/vt/consolemap.c index 45d3e80156d4..45d3e80156d4 100644 --- a/drivers/char/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
diff --git a/drivers/char/cp437.uni b/drivers/tty/vt/cp437.uni index bc6163484f62..bc6163484f62 100644 --- a/drivers/char/cp437.uni +++ b/drivers/tty/vt/cp437.uni | |||
diff --git a/drivers/char/defkeymap.c_shipped b/drivers/tty/vt/defkeymap.c_shipped index d2208dfe3f67..d2208dfe3f67 100644 --- a/drivers/char/defkeymap.c_shipped +++ b/drivers/tty/vt/defkeymap.c_shipped | |||
diff --git a/drivers/char/defkeymap.map b/drivers/tty/vt/defkeymap.map index 50b30cace261..50b30cace261 100644 --- a/drivers/char/defkeymap.map +++ b/drivers/tty/vt/defkeymap.map | |||
diff --git a/drivers/char/keyboard.c b/drivers/tty/vt/keyboard.c index e95d7876ca6b..e95d7876ca6b 100644 --- a/drivers/char/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
diff --git a/drivers/char/selection.c b/drivers/tty/vt/selection.c index ebae344ce910..ebae344ce910 100644 --- a/drivers/char/selection.c +++ b/drivers/tty/vt/selection.c | |||
diff --git a/drivers/char/vc_screen.c b/drivers/tty/vt/vc_screen.c index 273ab44cc91d..273ab44cc91d 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c | |||
diff --git a/drivers/char/vt.c b/drivers/tty/vt/vt.c index a8ec48ed14d9..a8ec48ed14d9 100644 --- a/drivers/char/vt.c +++ b/drivers/tty/vt/vt.c | |||
diff --git a/drivers/char/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 6b68a0fb4611..6b68a0fb4611 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index cb23355f52d3..fbe86ca95802 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -811,7 +811,6 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) | |||
811 | INFO(dev, "MAC %pM\n", net->dev_addr); | 811 | INFO(dev, "MAC %pM\n", net->dev_addr); |
812 | INFO(dev, "HOST MAC %pM\n", dev->host_mac); | 812 | INFO(dev, "HOST MAC %pM\n", dev->host_mac); |
813 | 813 | ||
814 | netif_stop_queue(net); | ||
815 | the_dev = dev; | 814 | the_dev = dev; |
816 | } | 815 | } |
817 | 816 | ||
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 2054b1e25a65..d1268191acbd 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -331,10 +331,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
331 | 331 | ||
332 | iu->iu_id = IU_ID_COMMAND; | 332 | iu->iu_id = IU_ID_COMMAND; |
333 | iu->tag = cpu_to_be16(stream_id); | 333 | iu->tag = cpu_to_be16(stream_id); |
334 | if (sdev->ordered_tags && (cmnd->request->cmd_flags & REQ_HARDBARRIER)) | 334 | iu->prio_attr = UAS_SIMPLE_TAG; |
335 | iu->prio_attr = UAS_ORDERED_TAG; | ||
336 | else | ||
337 | iu->prio_attr = UAS_SIMPLE_TAG; | ||
338 | iu->len = len; | 335 | iu->len = len; |
339 | int_to_scsilun(sdev->lun, &iu->lun); | 336 | int_to_scsilun(sdev->lun, &iu->lun); |
340 | memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); | 337 | memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); |
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 3ec24609151e..734c650a47c4 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c | |||
@@ -502,8 +502,10 @@ static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev, | |||
502 | struct device_attribute *attr, const char *buf, size_t count) | 502 | struct device_attribute *attr, const char *buf, size_t count) |
503 | { | 503 | { |
504 | struct adp8860_bl *data = dev_get_drvdata(dev); | 504 | struct adp8860_bl *data = dev_get_drvdata(dev); |
505 | int ret = strict_strtoul(buf, 10, &data->cached_daylight_max); | ||
506 | if (ret) | ||
507 | return ret; | ||
505 | 508 | ||
506 | strict_strtoul(buf, 10, &data->cached_daylight_max); | ||
507 | return adp8860_store(dev, buf, count, ADP8860_BLMX1); | 509 | return adp8860_store(dev, buf, count, ADP8860_BLMX1); |
508 | } | 510 | } |
509 | static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show, | 511 | static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show, |
@@ -614,7 +616,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, | |||
614 | if (val == 0) { | 616 | if (val == 0) { |
615 | /* Enable automatic ambient light sensing */ | 617 | /* Enable automatic ambient light sensing */ |
616 | adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); | 618 | adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); |
617 | } else if ((val > 0) && (val < 6)) { | 619 | } else if ((val > 0) && (val <= 3)) { |
618 | /* Disable automatic ambient light sensing */ | 620 | /* Disable automatic ambient light sensing */ |
619 | adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); | 621 | adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); |
620 | 622 | ||
@@ -622,7 +624,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, | |||
622 | mutex_lock(&data->lock); | 624 | mutex_lock(&data->lock); |
623 | adp8860_read(data->client, ADP8860_CFGR, ®_val); | 625 | adp8860_read(data->client, ADP8860_CFGR, ®_val); |
624 | reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); | 626 | reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); |
625 | reg_val |= val << CFGR_BLV_SHIFT; | 627 | reg_val |= (val - 1) << CFGR_BLV_SHIFT; |
626 | adp8860_write(data->client, ADP8860_CFGR, reg_val); | 628 | adp8860_write(data->client, ADP8860_CFGR, reg_val); |
627 | mutex_unlock(&data->lock); | 629 | mutex_unlock(&data->lock); |
628 | } | 630 | } |
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 9093ef0fa869..c67801e57aaf 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c | |||
@@ -78,7 +78,7 @@ static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) | |||
78 | const u16 slpin = 0x10; | 78 | const u16 slpin = 0x10; |
79 | const u16 disoff = 0x28; | 79 | const u16 disoff = 0x28; |
80 | 80 | ||
81 | if (power) { | 81 | if (power <= FB_BLANK_NORMAL) { |
82 | if (priv->lcd_on) | 82 | if (priv->lcd_on) |
83 | return 0; | 83 | return 0; |
84 | 84 | ||
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index abc43a0eb97d..5d3cf33953ac 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c | |||
@@ -129,7 +129,7 @@ static int lms283gf05_power_set(struct lcd_device *ld, int power) | |||
129 | struct spi_device *spi = st->spi; | 129 | struct spi_device *spi = st->spi; |
130 | struct lms283gf05_pdata *pdata = spi->dev.platform_data; | 130 | struct lms283gf05_pdata *pdata = spi->dev.platform_data; |
131 | 131 | ||
132 | if (power) { | 132 | if (power <= FB_BLANK_NORMAL) { |
133 | if (pdata) | 133 | if (pdata) |
134 | lms283gf05_reset(pdata->reset_gpio, | 134 | lms283gf05_reset(pdata->reset_gpio, |
135 | pdata->reset_inverted); | 135 | pdata->reset_inverted); |
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 9fb533f6373e..1485f7345f49 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c | |||
@@ -335,6 +335,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { | |||
335 | }, | 335 | }, |
336 | .driver_data = (void *)&nvidia_chipset_data, | 336 | .driver_data = (void *)&nvidia_chipset_data, |
337 | }, | 337 | }, |
338 | { | ||
339 | .callback = mbp_dmi_match, | ||
340 | .ident = "MacBookAir 3,1", | ||
341 | .matches = { | ||
342 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
343 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"), | ||
344 | }, | ||
345 | .driver_data = (void *)&nvidia_chipset_data, | ||
346 | }, | ||
347 | { | ||
348 | .callback = mbp_dmi_match, | ||
349 | .ident = "MacBookAir 3,2", | ||
350 | .matches = { | ||
351 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
352 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"), | ||
353 | }, | ||
354 | .driver_data = (void *)&nvidia_chipset_data, | ||
355 | }, | ||
338 | { } | 356 | { } |
339 | }; | 357 | }; |
340 | 358 | ||
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 550443518891..21866ec69656 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
@@ -25,6 +25,7 @@ struct pwm_bl_data { | |||
25 | struct pwm_device *pwm; | 25 | struct pwm_device *pwm; |
26 | struct device *dev; | 26 | struct device *dev; |
27 | unsigned int period; | 27 | unsigned int period; |
28 | unsigned int lth_brightness; | ||
28 | int (*notify)(struct device *, | 29 | int (*notify)(struct device *, |
29 | int brightness); | 30 | int brightness); |
30 | }; | 31 | }; |
@@ -48,7 +49,9 @@ static int pwm_backlight_update_status(struct backlight_device *bl) | |||
48 | pwm_config(pb->pwm, 0, pb->period); | 49 | pwm_config(pb->pwm, 0, pb->period); |
49 | pwm_disable(pb->pwm); | 50 | pwm_disable(pb->pwm); |
50 | } else { | 51 | } else { |
51 | pwm_config(pb->pwm, brightness * pb->period / max, pb->period); | 52 | brightness = pb->lth_brightness + |
53 | (brightness * (pb->period - pb->lth_brightness) / max); | ||
54 | pwm_config(pb->pwm, brightness, pb->period); | ||
52 | pwm_enable(pb->pwm); | 55 | pwm_enable(pb->pwm); |
53 | } | 56 | } |
54 | return 0; | 57 | return 0; |
@@ -92,6 +95,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
92 | 95 | ||
93 | pb->period = data->pwm_period_ns; | 96 | pb->period = data->pwm_period_ns; |
94 | pb->notify = data->notify; | 97 | pb->notify = data->notify; |
98 | pb->lth_brightness = data->lth_brightness * | ||
99 | (data->pwm_period_ns / data->max_brightness); | ||
95 | pb->dev = &pdev->dev; | 100 | pb->dev = &pdev->dev; |
96 | 101 | ||
97 | pb->pwm = pwm_request(data->pwm_id, "backlight"); | 102 | pb->pwm = pwm_request(data->pwm_id, "backlight"); |
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c index a3128c9cb7ad..5927db0da999 100644 --- a/drivers/video/backlight/s6e63m0.c +++ b/drivers/video/backlight/s6e63m0.c | |||
@@ -729,10 +729,10 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev, | |||
729 | 729 | ||
730 | return strlen(buf); | 730 | return strlen(buf); |
731 | } | 731 | } |
732 | static DEVICE_ATTR(gamma_table, 0644, | 732 | static DEVICE_ATTR(gamma_table, 0444, |
733 | s6e63m0_sysfs_show_gamma_table, NULL); | 733 | s6e63m0_sysfs_show_gamma_table, NULL); |
734 | 734 | ||
735 | static int __init s6e63m0_probe(struct spi_device *spi) | 735 | static int __devinit s6e63m0_probe(struct spi_device *spi) |
736 | { | 736 | { |
737 | int ret = 0; | 737 | int ret = 0; |
738 | struct s6e63m0 *lcd = NULL; | 738 | struct s6e63m0 *lcd = NULL; |
@@ -829,6 +829,9 @@ static int __devexit s6e63m0_remove(struct spi_device *spi) | |||
829 | struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); | 829 | struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); |
830 | 830 | ||
831 | s6e63m0_power(lcd, FB_BLANK_POWERDOWN); | 831 | s6e63m0_power(lcd, FB_BLANK_POWERDOWN); |
832 | device_remove_file(&spi->dev, &dev_attr_gamma_table); | ||
833 | device_remove_file(&spi->dev, &dev_attr_gamma_mode); | ||
834 | backlight_device_unregister(lcd->bd); | ||
832 | lcd_device_unregister(lcd->ld); | 835 | lcd_device_unregister(lcd->ld); |
833 | kfree(lcd); | 836 | kfree(lcd); |
834 | 837 | ||
@@ -370,6 +370,9 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) | |||
370 | { | 370 | { |
371 | struct bio *bio; | 371 | struct bio *bio; |
372 | 372 | ||
373 | if (nr_iovecs > UIO_MAXIOV) | ||
374 | return NULL; | ||
375 | |||
373 | bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec), | 376 | bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec), |
374 | gfp_mask); | 377 | gfp_mask); |
375 | if (unlikely(!bio)) | 378 | if (unlikely(!bio)) |
@@ -697,8 +700,12 @@ static void bio_free_map_data(struct bio_map_data *bmd) | |||
697 | static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count, | 700 | static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count, |
698 | gfp_t gfp_mask) | 701 | gfp_t gfp_mask) |
699 | { | 702 | { |
700 | struct bio_map_data *bmd = kmalloc(sizeof(*bmd), gfp_mask); | 703 | struct bio_map_data *bmd; |
701 | 704 | ||
705 | if (iov_count > UIO_MAXIOV) | ||
706 | return NULL; | ||
707 | |||
708 | bmd = kmalloc(sizeof(*bmd), gfp_mask); | ||
702 | if (!bmd) | 709 | if (!bmd) |
703 | return NULL; | 710 | return NULL; |
704 | 711 | ||
@@ -827,6 +834,12 @@ struct bio *bio_copy_user_iov(struct request_queue *q, | |||
827 | end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 834 | end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
828 | start = uaddr >> PAGE_SHIFT; | 835 | start = uaddr >> PAGE_SHIFT; |
829 | 836 | ||
837 | /* | ||
838 | * Overflow, abort | ||
839 | */ | ||
840 | if (end < start) | ||
841 | return ERR_PTR(-EINVAL); | ||
842 | |||
830 | nr_pages += end - start; | 843 | nr_pages += end - start; |
831 | len += iov[i].iov_len; | 844 | len += iov[i].iov_len; |
832 | } | 845 | } |
@@ -955,6 +968,12 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, | |||
955 | unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 968 | unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
956 | unsigned long start = uaddr >> PAGE_SHIFT; | 969 | unsigned long start = uaddr >> PAGE_SHIFT; |
957 | 970 | ||
971 | /* | ||
972 | * Overflow, abort | ||
973 | */ | ||
974 | if (end < start) | ||
975 | return ERR_PTR(-EINVAL); | ||
976 | |||
958 | nr_pages += end - start; | 977 | nr_pages += end - start; |
959 | /* | 978 | /* |
960 | * buffer must be aligned to at least hardsector size for now | 979 | * buffer must be aligned to at least hardsector size for now |
@@ -982,7 +1001,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, | |||
982 | unsigned long start = uaddr >> PAGE_SHIFT; | 1001 | unsigned long start = uaddr >> PAGE_SHIFT; |
983 | const int local_nr_pages = end - start; | 1002 | const int local_nr_pages = end - start; |
984 | const int page_limit = cur_page + local_nr_pages; | 1003 | const int page_limit = cur_page + local_nr_pages; |
985 | 1004 | ||
986 | ret = get_user_pages_fast(uaddr, local_nr_pages, | 1005 | ret = get_user_pages_fast(uaddr, local_nr_pages, |
987 | write_to_vm, &pages[cur_page]); | 1006 | write_to_vm, &pages[cur_page]); |
988 | if (ret < local_nr_pages) { | 1007 | if (ret < local_nr_pages) { |
diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 5aff46c61e52..355abcdcda98 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO | |||
@@ -81,7 +81,7 @@ u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for | |||
81 | 81 | ||
82 | v) mount check for unmatched uids | 82 | v) mount check for unmatched uids |
83 | 83 | ||
84 | w) Add support for new vfs entry points for setlease and fallocate | 84 | w) Add support for new vfs entry point for fallocate |
85 | 85 | ||
86 | x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of | 86 | x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of |
87 | processes can proceed better in parallel (on the server) | 87 | processes can proceed better in parallel (on the server) |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 525ba59a4105..e9a393c9c2ca 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -15,7 +15,7 @@ | |||
15 | * the GNU Lesser General Public License for more details. | 15 | * the GNU Lesser General Public License for more details. |
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | #include <linux/radix-tree.h> | 18 | #include <linux/rbtree.h> |
19 | 19 | ||
20 | #ifndef _CIFS_FS_SB_H | 20 | #ifndef _CIFS_FS_SB_H |
21 | #define _CIFS_FS_SB_H | 21 | #define _CIFS_FS_SB_H |
@@ -42,9 +42,9 @@ | |||
42 | #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ | 42 | #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ |
43 | 43 | ||
44 | struct cifs_sb_info { | 44 | struct cifs_sb_info { |
45 | struct radix_tree_root tlink_tree; | 45 | struct rb_root tlink_tree; |
46 | #define CIFS_TLINK_MASTER_TAG 0 /* is "master" (mount) tcon */ | ||
47 | spinlock_t tlink_tree_lock; | 46 | spinlock_t tlink_tree_lock; |
47 | struct tcon_link *master_tlink; | ||
48 | struct nls_table *local_nls; | 48 | struct nls_table *local_nls; |
49 | unsigned int rsize; | 49 | unsigned int rsize; |
50 | unsigned int wsize; | 50 | unsigned int wsize; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 75c4eaa79588..9c3789762ab7 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -116,7 +116,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
116 | return -ENOMEM; | 116 | return -ENOMEM; |
117 | 117 | ||
118 | spin_lock_init(&cifs_sb->tlink_tree_lock); | 118 | spin_lock_init(&cifs_sb->tlink_tree_lock); |
119 | INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL); | 119 | cifs_sb->tlink_tree = RB_ROOT; |
120 | 120 | ||
121 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 121 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); |
122 | if (rc) { | 122 | if (rc) { |
@@ -321,8 +321,7 @@ cifs_alloc_inode(struct super_block *sb) | |||
321 | /* Until the file is open and we have gotten oplock | 321 | /* Until the file is open and we have gotten oplock |
322 | info back from the server, can not assume caching of | 322 | info back from the server, can not assume caching of |
323 | file data or metadata */ | 323 | file data or metadata */ |
324 | cifs_inode->clientCanCacheRead = false; | 324 | cifs_set_oplock_level(cifs_inode, 0); |
325 | cifs_inode->clientCanCacheAll = false; | ||
326 | cifs_inode->delete_pending = false; | 325 | cifs_inode->delete_pending = false; |
327 | cifs_inode->invalid_mapping = false; | 326 | cifs_inode->invalid_mapping = false; |
328 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ | 327 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f259e4d7612d..b577bf0a1bb3 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -336,7 +336,8 @@ struct cifsTconInfo { | |||
336 | * "get" on the container. | 336 | * "get" on the container. |
337 | */ | 337 | */ |
338 | struct tcon_link { | 338 | struct tcon_link { |
339 | unsigned long tl_index; | 339 | struct rb_node tl_rbnode; |
340 | uid_t tl_uid; | ||
340 | unsigned long tl_flags; | 341 | unsigned long tl_flags; |
341 | #define TCON_LINK_MASTER 0 | 342 | #define TCON_LINK_MASTER 0 |
342 | #define TCON_LINK_PENDING 1 | 343 | #define TCON_LINK_PENDING 1 |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index edb6d90efdf2..7ed69b6b5fe6 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -104,6 +104,7 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); | |||
104 | extern u64 cifs_UnixTimeToNT(struct timespec); | 104 | extern u64 cifs_UnixTimeToNT(struct timespec); |
105 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, | 105 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
106 | int offset); | 106 | int offset); |
107 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); | ||
107 | 108 | ||
108 | extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, | 109 | extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, |
109 | struct file *file, struct tcon_link *tlink, | 110 | struct file *file, struct tcon_link *tlink, |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9eb327defa1d..251a17c03545 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -116,6 +116,7 @@ struct smb_vol { | |||
116 | 116 | ||
117 | static int ipv4_connect(struct TCP_Server_Info *server); | 117 | static int ipv4_connect(struct TCP_Server_Info *server); |
118 | static int ipv6_connect(struct TCP_Server_Info *server); | 118 | static int ipv6_connect(struct TCP_Server_Info *server); |
119 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); | ||
119 | static void cifs_prune_tlinks(struct work_struct *work); | 120 | static void cifs_prune_tlinks(struct work_struct *work); |
120 | 121 | ||
121 | /* | 122 | /* |
@@ -2900,24 +2901,16 @@ remote_path_check: | |||
2900 | goto mount_fail_check; | 2901 | goto mount_fail_check; |
2901 | } | 2902 | } |
2902 | 2903 | ||
2903 | tlink->tl_index = pSesInfo->linux_uid; | 2904 | tlink->tl_uid = pSesInfo->linux_uid; |
2904 | tlink->tl_tcon = tcon; | 2905 | tlink->tl_tcon = tcon; |
2905 | tlink->tl_time = jiffies; | 2906 | tlink->tl_time = jiffies; |
2906 | set_bit(TCON_LINK_MASTER, &tlink->tl_flags); | 2907 | set_bit(TCON_LINK_MASTER, &tlink->tl_flags); |
2907 | set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); | 2908 | set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); |
2908 | 2909 | ||
2909 | rc = radix_tree_preload(GFP_KERNEL); | 2910 | cifs_sb->master_tlink = tlink; |
2910 | if (rc == -ENOMEM) { | ||
2911 | kfree(tlink); | ||
2912 | goto mount_fail_check; | ||
2913 | } | ||
2914 | |||
2915 | spin_lock(&cifs_sb->tlink_tree_lock); | 2911 | spin_lock(&cifs_sb->tlink_tree_lock); |
2916 | radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink); | 2912 | tlink_rb_insert(&cifs_sb->tlink_tree, tlink); |
2917 | radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid, | ||
2918 | CIFS_TLINK_MASTER_TAG); | ||
2919 | spin_unlock(&cifs_sb->tlink_tree_lock); | 2913 | spin_unlock(&cifs_sb->tlink_tree_lock); |
2920 | radix_tree_preload_end(); | ||
2921 | 2914 | ||
2922 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, | 2915 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, |
2923 | TLINK_IDLE_EXPIRE); | 2916 | TLINK_IDLE_EXPIRE); |
@@ -3107,32 +3100,25 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3107 | int | 3100 | int |
3108 | cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | 3101 | cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) |
3109 | { | 3102 | { |
3110 | int i, ret; | 3103 | struct rb_root *root = &cifs_sb->tlink_tree; |
3104 | struct rb_node *node; | ||
3105 | struct tcon_link *tlink; | ||
3111 | char *tmp; | 3106 | char *tmp; |
3112 | struct tcon_link *tlink[8]; | ||
3113 | unsigned long index = 0; | ||
3114 | 3107 | ||
3115 | cancel_delayed_work_sync(&cifs_sb->prune_tlinks); | 3108 | cancel_delayed_work_sync(&cifs_sb->prune_tlinks); |
3116 | 3109 | ||
3117 | do { | 3110 | spin_lock(&cifs_sb->tlink_tree_lock); |
3118 | spin_lock(&cifs_sb->tlink_tree_lock); | 3111 | while ((node = rb_first(root))) { |
3119 | ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, | 3112 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); |
3120 | (void **)tlink, index, | 3113 | cifs_get_tlink(tlink); |
3121 | ARRAY_SIZE(tlink)); | 3114 | clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); |
3122 | /* increment index for next pass */ | 3115 | rb_erase(node, root); |
3123 | if (ret > 0) | ||
3124 | index = tlink[ret - 1]->tl_index + 1; | ||
3125 | for (i = 0; i < ret; i++) { | ||
3126 | cifs_get_tlink(tlink[i]); | ||
3127 | clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); | ||
3128 | radix_tree_delete(&cifs_sb->tlink_tree, | ||
3129 | tlink[i]->tl_index); | ||
3130 | } | ||
3131 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3132 | 3116 | ||
3133 | for (i = 0; i < ret; i++) | 3117 | spin_unlock(&cifs_sb->tlink_tree_lock); |
3134 | cifs_put_tlink(tlink[i]); | 3118 | cifs_put_tlink(tlink); |
3135 | } while (ret != 0); | 3119 | spin_lock(&cifs_sb->tlink_tree_lock); |
3120 | } | ||
3121 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3136 | 3122 | ||
3137 | tmp = cifs_sb->prepath; | 3123 | tmp = cifs_sb->prepath; |
3138 | cifs_sb->prepathlen = 0; | 3124 | cifs_sb->prepathlen = 0; |
@@ -3271,22 +3257,10 @@ out: | |||
3271 | return tcon; | 3257 | return tcon; |
3272 | } | 3258 | } |
3273 | 3259 | ||
3274 | static struct tcon_link * | 3260 | static inline struct tcon_link * |
3275 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) | 3261 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) |
3276 | { | 3262 | { |
3277 | struct tcon_link *tlink; | 3263 | return cifs_sb->master_tlink; |
3278 | unsigned int ret; | ||
3279 | |||
3280 | spin_lock(&cifs_sb->tlink_tree_lock); | ||
3281 | ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink, | ||
3282 | 0, 1, CIFS_TLINK_MASTER_TAG); | ||
3283 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3284 | |||
3285 | /* the master tcon should always be present */ | ||
3286 | if (ret == 0) | ||
3287 | BUG(); | ||
3288 | |||
3289 | return tlink; | ||
3290 | } | 3264 | } |
3291 | 3265 | ||
3292 | struct cifsTconInfo * | 3266 | struct cifsTconInfo * |
@@ -3302,6 +3276,47 @@ cifs_sb_tcon_pending_wait(void *unused) | |||
3302 | return signal_pending(current) ? -ERESTARTSYS : 0; | 3276 | return signal_pending(current) ? -ERESTARTSYS : 0; |
3303 | } | 3277 | } |
3304 | 3278 | ||
3279 | /* find and return a tlink with given uid */ | ||
3280 | static struct tcon_link * | ||
3281 | tlink_rb_search(struct rb_root *root, uid_t uid) | ||
3282 | { | ||
3283 | struct rb_node *node = root->rb_node; | ||
3284 | struct tcon_link *tlink; | ||
3285 | |||
3286 | while (node) { | ||
3287 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); | ||
3288 | |||
3289 | if (tlink->tl_uid > uid) | ||
3290 | node = node->rb_left; | ||
3291 | else if (tlink->tl_uid < uid) | ||
3292 | node = node->rb_right; | ||
3293 | else | ||
3294 | return tlink; | ||
3295 | } | ||
3296 | return NULL; | ||
3297 | } | ||
3298 | |||
3299 | /* insert a tcon_link into the tree */ | ||
3300 | static void | ||
3301 | tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) | ||
3302 | { | ||
3303 | struct rb_node **new = &(root->rb_node), *parent = NULL; | ||
3304 | struct tcon_link *tlink; | ||
3305 | |||
3306 | while (*new) { | ||
3307 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); | ||
3308 | parent = *new; | ||
3309 | |||
3310 | if (tlink->tl_uid > new_tlink->tl_uid) | ||
3311 | new = &((*new)->rb_left); | ||
3312 | else | ||
3313 | new = &((*new)->rb_right); | ||
3314 | } | ||
3315 | |||
3316 | rb_link_node(&new_tlink->tl_rbnode, parent, new); | ||
3317 | rb_insert_color(&new_tlink->tl_rbnode, root); | ||
3318 | } | ||
3319 | |||
3305 | /* | 3320 | /* |
3306 | * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the | 3321 | * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the |
3307 | * current task. | 3322 | * current task. |
@@ -3309,7 +3324,7 @@ cifs_sb_tcon_pending_wait(void *unused) | |||
3309 | * If the superblock doesn't refer to a multiuser mount, then just return | 3324 | * If the superblock doesn't refer to a multiuser mount, then just return |
3310 | * the master tcon for the mount. | 3325 | * the master tcon for the mount. |
3311 | * | 3326 | * |
3312 | * First, search the radix tree for an existing tcon for this fsuid. If one | 3327 | * First, search the rbtree for an existing tcon for this fsuid. If one |
3313 | * exists, then check to see if it's pending construction. If it is then wait | 3328 | * exists, then check to see if it's pending construction. If it is then wait |
3314 | * for construction to complete. Once it's no longer pending, check to see if | 3329 | * for construction to complete. Once it's no longer pending, check to see if |
3315 | * it failed and either return an error or retry construction, depending on | 3330 | * it failed and either return an error or retry construction, depending on |
@@ -3322,14 +3337,14 @@ struct tcon_link * | |||
3322 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) | 3337 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) |
3323 | { | 3338 | { |
3324 | int ret; | 3339 | int ret; |
3325 | unsigned long fsuid = (unsigned long) current_fsuid(); | 3340 | uid_t fsuid = current_fsuid(); |
3326 | struct tcon_link *tlink, *newtlink; | 3341 | struct tcon_link *tlink, *newtlink; |
3327 | 3342 | ||
3328 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 3343 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
3329 | return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); | 3344 | return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); |
3330 | 3345 | ||
3331 | spin_lock(&cifs_sb->tlink_tree_lock); | 3346 | spin_lock(&cifs_sb->tlink_tree_lock); |
3332 | tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); | 3347 | tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); |
3333 | if (tlink) | 3348 | if (tlink) |
3334 | cifs_get_tlink(tlink); | 3349 | cifs_get_tlink(tlink); |
3335 | spin_unlock(&cifs_sb->tlink_tree_lock); | 3350 | spin_unlock(&cifs_sb->tlink_tree_lock); |
@@ -3338,36 +3353,24 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb) | |||
3338 | newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); | 3353 | newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); |
3339 | if (newtlink == NULL) | 3354 | if (newtlink == NULL) |
3340 | return ERR_PTR(-ENOMEM); | 3355 | return ERR_PTR(-ENOMEM); |
3341 | newtlink->tl_index = fsuid; | 3356 | newtlink->tl_uid = fsuid; |
3342 | newtlink->tl_tcon = ERR_PTR(-EACCES); | 3357 | newtlink->tl_tcon = ERR_PTR(-EACCES); |
3343 | set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); | 3358 | set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); |
3344 | set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); | 3359 | set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); |
3345 | cifs_get_tlink(newtlink); | 3360 | cifs_get_tlink(newtlink); |
3346 | 3361 | ||
3347 | ret = radix_tree_preload(GFP_KERNEL); | ||
3348 | if (ret != 0) { | ||
3349 | kfree(newtlink); | ||
3350 | return ERR_PTR(ret); | ||
3351 | } | ||
3352 | |||
3353 | spin_lock(&cifs_sb->tlink_tree_lock); | 3362 | spin_lock(&cifs_sb->tlink_tree_lock); |
3354 | /* was one inserted after previous search? */ | 3363 | /* was one inserted after previous search? */ |
3355 | tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); | 3364 | tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); |
3356 | if (tlink) { | 3365 | if (tlink) { |
3357 | cifs_get_tlink(tlink); | 3366 | cifs_get_tlink(tlink); |
3358 | spin_unlock(&cifs_sb->tlink_tree_lock); | 3367 | spin_unlock(&cifs_sb->tlink_tree_lock); |
3359 | radix_tree_preload_end(); | ||
3360 | kfree(newtlink); | 3368 | kfree(newtlink); |
3361 | goto wait_for_construction; | 3369 | goto wait_for_construction; |
3362 | } | 3370 | } |
3363 | ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink); | ||
3364 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3365 | radix_tree_preload_end(); | ||
3366 | if (ret) { | ||
3367 | kfree(newtlink); | ||
3368 | return ERR_PTR(ret); | ||
3369 | } | ||
3370 | tlink = newtlink; | 3371 | tlink = newtlink; |
3372 | tlink_rb_insert(&cifs_sb->tlink_tree, tlink); | ||
3373 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3371 | } else { | 3374 | } else { |
3372 | wait_for_construction: | 3375 | wait_for_construction: |
3373 | ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, | 3376 | ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, |
@@ -3413,39 +3416,39 @@ cifs_prune_tlinks(struct work_struct *work) | |||
3413 | { | 3416 | { |
3414 | struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, | 3417 | struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, |
3415 | prune_tlinks.work); | 3418 | prune_tlinks.work); |
3416 | struct tcon_link *tlink[8]; | 3419 | struct rb_root *root = &cifs_sb->tlink_tree; |
3417 | unsigned long now = jiffies; | 3420 | struct rb_node *node = rb_first(root); |
3418 | unsigned long index = 0; | 3421 | struct rb_node *tmp; |
3419 | int i, ret; | 3422 | struct tcon_link *tlink; |
3420 | 3423 | ||
3421 | do { | 3424 | /* |
3422 | spin_lock(&cifs_sb->tlink_tree_lock); | 3425 | * Because we drop the spinlock in the loop in order to put the tlink |
3423 | ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, | 3426 | * it's not guarded against removal of links from the tree. The only |
3424 | (void **)tlink, index, | 3427 | * places that remove entries from the tree are this function and |
3425 | ARRAY_SIZE(tlink)); | 3428 | * umounts. Because this function is non-reentrant and is canceled |
3426 | /* increment index for next pass */ | 3429 | * before umount can proceed, this is safe. |
3427 | if (ret > 0) | 3430 | */ |
3428 | index = tlink[ret - 1]->tl_index + 1; | 3431 | spin_lock(&cifs_sb->tlink_tree_lock); |
3429 | for (i = 0; i < ret; i++) { | 3432 | node = rb_first(root); |
3430 | if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) || | 3433 | while (node != NULL) { |
3431 | atomic_read(&tlink[i]->tl_count) != 0 || | 3434 | tmp = node; |
3432 | time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE, | 3435 | node = rb_next(tmp); |
3433 | now)) { | 3436 | tlink = rb_entry(tmp, struct tcon_link, tl_rbnode); |
3434 | tlink[i] = NULL; | 3437 | |
3435 | continue; | 3438 | if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || |
3436 | } | 3439 | atomic_read(&tlink->tl_count) != 0 || |
3437 | cifs_get_tlink(tlink[i]); | 3440 | time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) |
3438 | clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); | 3441 | continue; |
3439 | radix_tree_delete(&cifs_sb->tlink_tree, | ||
3440 | tlink[i]->tl_index); | ||
3441 | } | ||
3442 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3443 | 3442 | ||
3444 | for (i = 0; i < ret; i++) { | 3443 | cifs_get_tlink(tlink); |
3445 | if (tlink[i] != NULL) | 3444 | clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); |
3446 | cifs_put_tlink(tlink[i]); | 3445 | rb_erase(tmp, root); |
3447 | } | 3446 | |
3448 | } while (ret != 0); | 3447 | spin_unlock(&cifs_sb->tlink_tree_lock); |
3448 | cifs_put_tlink(tlink); | ||
3449 | spin_lock(&cifs_sb->tlink_tree_lock); | ||
3450 | } | ||
3451 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
3449 | 3452 | ||
3450 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, | 3453 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, |
3451 | TLINK_IDLE_EXPIRE); | 3454 | TLINK_IDLE_EXPIRE); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ae82159cf7fa..06c3e83fa387 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -146,12 +146,7 @@ client_can_cache: | |||
146 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, | 146 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
147 | xid, NULL); | 147 | xid, NULL); |
148 | 148 | ||
149 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 149 | cifs_set_oplock_level(pCifsInode, oplock); |
150 | pCifsInode->clientCanCacheAll = true; | ||
151 | pCifsInode->clientCanCacheRead = true; | ||
152 | cFYI(1, "Exclusive Oplock granted on inode %p", inode); | ||
153 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
154 | pCifsInode->clientCanCacheRead = true; | ||
155 | 150 | ||
156 | return rc; | 151 | return rc; |
157 | } | 152 | } |
@@ -253,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, | |||
253 | list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); | 248 | list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); |
254 | spin_unlock(&cifs_file_list_lock); | 249 | spin_unlock(&cifs_file_list_lock); |
255 | 250 | ||
256 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 251 | cifs_set_oplock_level(pCifsInode, oplock); |
257 | pCifsInode->clientCanCacheAll = true; | ||
258 | pCifsInode->clientCanCacheRead = true; | ||
259 | cFYI(1, "Exclusive Oplock inode %p", inode); | ||
260 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
261 | pCifsInode->clientCanCacheRead = true; | ||
262 | 252 | ||
263 | file->private_data = pCifsFile; | 253 | file->private_data = pCifsFile; |
264 | return pCifsFile; | 254 | return pCifsFile; |
@@ -271,8 +261,9 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, | |||
271 | */ | 261 | */ |
272 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | 262 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file) |
273 | { | 263 | { |
264 | struct inode *inode = cifs_file->dentry->d_inode; | ||
274 | struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); | 265 | struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); |
275 | struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode); | 266 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
276 | struct cifsLockInfo *li, *tmp; | 267 | struct cifsLockInfo *li, *tmp; |
277 | 268 | ||
278 | spin_lock(&cifs_file_list_lock); | 269 | spin_lock(&cifs_file_list_lock); |
@@ -288,8 +279,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
288 | if (list_empty(&cifsi->openFileList)) { | 279 | if (list_empty(&cifsi->openFileList)) { |
289 | cFYI(1, "closing last open instance for inode %p", | 280 | cFYI(1, "closing last open instance for inode %p", |
290 | cifs_file->dentry->d_inode); | 281 | cifs_file->dentry->d_inode); |
291 | cifsi->clientCanCacheRead = false; | 282 | cifs_set_oplock_level(cifsi, 0); |
292 | cifsi->clientCanCacheAll = false; | ||
293 | } | 283 | } |
294 | spin_unlock(&cifs_file_list_lock); | 284 | spin_unlock(&cifs_file_list_lock); |
295 | 285 | ||
@@ -607,8 +597,6 @@ reopen_success: | |||
607 | rc = filemap_write_and_wait(inode->i_mapping); | 597 | rc = filemap_write_and_wait(inode->i_mapping); |
608 | mapping_set_error(inode->i_mapping, rc); | 598 | mapping_set_error(inode->i_mapping, rc); |
609 | 599 | ||
610 | pCifsInode->clientCanCacheAll = false; | ||
611 | pCifsInode->clientCanCacheRead = false; | ||
612 | if (tcon->unix_ext) | 600 | if (tcon->unix_ext) |
613 | rc = cifs_get_inode_info_unix(&inode, | 601 | rc = cifs_get_inode_info_unix(&inode, |
614 | full_path, inode->i_sb, xid); | 602 | full_path, inode->i_sb, xid); |
@@ -622,18 +610,9 @@ reopen_success: | |||
622 | invalidate the current end of file on the server | 610 | invalidate the current end of file on the server |
623 | we can not go to the server to get the new inod | 611 | we can not go to the server to get the new inod |
624 | info */ | 612 | info */ |
625 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 613 | |
626 | pCifsInode->clientCanCacheAll = true; | 614 | cifs_set_oplock_level(pCifsInode, oplock); |
627 | pCifsInode->clientCanCacheRead = true; | 615 | |
628 | cFYI(1, "Exclusive Oplock granted on inode %p", | ||
629 | pCifsFile->dentry->d_inode); | ||
630 | } else if ((oplock & 0xF) == OPLOCK_READ) { | ||
631 | pCifsInode->clientCanCacheRead = true; | ||
632 | pCifsInode->clientCanCacheAll = false; | ||
633 | } else { | ||
634 | pCifsInode->clientCanCacheRead = false; | ||
635 | pCifsInode->clientCanCacheAll = false; | ||
636 | } | ||
637 | cifs_relock_file(pCifsFile); | 616 | cifs_relock_file(pCifsFile); |
638 | 617 | ||
639 | reopen_error_exit: | 618 | reopen_error_exit: |
@@ -775,12 +754,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
775 | 754 | ||
776 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 755 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
777 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); | 756 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); |
778 | |||
779 | if (file->private_data == NULL) { | ||
780 | rc = -EBADF; | ||
781 | FreeXid(xid); | ||
782 | return rc; | ||
783 | } | ||
784 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 757 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; |
785 | 758 | ||
786 | if ((tcon->ses->capabilities & CAP_UNIX) && | 759 | if ((tcon->ses->capabilities & CAP_UNIX) && |
@@ -956,6 +929,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, | |||
956 | ssize_t cifs_user_write(struct file *file, const char __user *write_data, | 929 | ssize_t cifs_user_write(struct file *file, const char __user *write_data, |
957 | size_t write_size, loff_t *poffset) | 930 | size_t write_size, loff_t *poffset) |
958 | { | 931 | { |
932 | struct inode *inode = file->f_path.dentry->d_inode; | ||
959 | int rc = 0; | 933 | int rc = 0; |
960 | unsigned int bytes_written = 0; | 934 | unsigned int bytes_written = 0; |
961 | unsigned int total_written; | 935 | unsigned int total_written; |
@@ -963,7 +937,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
963 | struct cifsTconInfo *pTcon; | 937 | struct cifsTconInfo *pTcon; |
964 | int xid, long_op; | 938 | int xid, long_op; |
965 | struct cifsFileInfo *open_file; | 939 | struct cifsFileInfo *open_file; |
966 | struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); | 940 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
967 | 941 | ||
968 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 942 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
969 | 943 | ||
@@ -1029,21 +1003,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
1029 | 1003 | ||
1030 | cifs_stats_bytes_written(pTcon, total_written); | 1004 | cifs_stats_bytes_written(pTcon, total_written); |
1031 | 1005 | ||
1032 | /* since the write may have blocked check these pointers again */ | ||
1033 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { | ||
1034 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1035 | /* Do not update local mtime - server will set its actual value on write | 1006 | /* Do not update local mtime - server will set its actual value on write |
1036 | * inode->i_ctime = inode->i_mtime = | 1007 | * inode->i_ctime = inode->i_mtime = |
1037 | * current_fs_time(inode->i_sb);*/ | 1008 | * current_fs_time(inode->i_sb);*/ |
1038 | if (total_written > 0) { | 1009 | if (total_written > 0) { |
1039 | spin_lock(&inode->i_lock); | 1010 | spin_lock(&inode->i_lock); |
1040 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 1011 | if (*poffset > inode->i_size) |
1041 | i_size_write(file->f_path.dentry->d_inode, | 1012 | i_size_write(inode, *poffset); |
1042 | *poffset); | 1013 | spin_unlock(&inode->i_lock); |
1043 | spin_unlock(&inode->i_lock); | ||
1044 | } | ||
1045 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); | ||
1046 | } | 1014 | } |
1015 | mark_inode_dirty_sync(inode); | ||
1016 | |||
1047 | FreeXid(xid); | 1017 | FreeXid(xid); |
1048 | return total_written; | 1018 | return total_written; |
1049 | } | 1019 | } |
@@ -1178,7 +1148,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
1178 | bool fsuid_only) | 1148 | bool fsuid_only) |
1179 | { | 1149 | { |
1180 | struct cifsFileInfo *open_file; | 1150 | struct cifsFileInfo *open_file; |
1181 | struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | 1151 | struct cifs_sb_info *cifs_sb; |
1182 | bool any_available = false; | 1152 | bool any_available = false; |
1183 | int rc; | 1153 | int rc; |
1184 | 1154 | ||
@@ -1192,6 +1162,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
1192 | return NULL; | 1162 | return NULL; |
1193 | } | 1163 | } |
1194 | 1164 | ||
1165 | cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | ||
1166 | |||
1195 | /* only filter by fsuid on multiuser mounts */ | 1167 | /* only filter by fsuid on multiuser mounts */ |
1196 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 1168 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
1197 | fsuid_only = false; | 1169 | fsuid_only = false; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 39869c3c3efb..ef3a55bf86b6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -2177,7 +2177,6 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2177 | 2177 | ||
2178 | setattr_copy(inode, attrs); | 2178 | setattr_copy(inode, attrs); |
2179 | mark_inode_dirty(inode); | 2179 | mark_inode_dirty(inode); |
2180 | return 0; | ||
2181 | 2180 | ||
2182 | cifs_setattr_exit: | 2181 | cifs_setattr_exit: |
2183 | kfree(full_path); | 2182 | kfree(full_path); |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 077bf756f342..0c98672d0122 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -38,10 +38,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
38 | struct cifs_sb_info *cifs_sb; | 38 | struct cifs_sb_info *cifs_sb; |
39 | #ifdef CONFIG_CIFS_POSIX | 39 | #ifdef CONFIG_CIFS_POSIX |
40 | struct cifsFileInfo *pSMBFile = filep->private_data; | 40 | struct cifsFileInfo *pSMBFile = filep->private_data; |
41 | struct cifsTconInfo *tcon = tlink_tcon(pSMBFile->tlink); | 41 | struct cifsTconInfo *tcon; |
42 | __u64 ExtAttrBits = 0; | 42 | __u64 ExtAttrBits = 0; |
43 | __u64 ExtAttrMask = 0; | 43 | __u64 ExtAttrMask = 0; |
44 | __u64 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | 44 | __u64 caps; |
45 | #endif /* CONFIG_CIFS_POSIX */ | 45 | #endif /* CONFIG_CIFS_POSIX */ |
46 | 46 | ||
47 | xid = GetXid(); | 47 | xid = GetXid(); |
@@ -62,9 +62,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
62 | break; | 62 | break; |
63 | #ifdef CONFIG_CIFS_POSIX | 63 | #ifdef CONFIG_CIFS_POSIX |
64 | case FS_IOC_GETFLAGS: | 64 | case FS_IOC_GETFLAGS: |
65 | if (pSMBFile == NULL) | ||
66 | break; | ||
67 | tcon = tlink_tcon(pSMBFile->tlink); | ||
68 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | ||
65 | if (CIFS_UNIX_EXTATTR_CAP & caps) { | 69 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
66 | if (pSMBFile == NULL) | ||
67 | break; | ||
68 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, | 70 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, |
69 | &ExtAttrBits, &ExtAttrMask); | 71 | &ExtAttrBits, &ExtAttrMask); |
70 | if (rc == 0) | 72 | if (rc == 0) |
@@ -75,13 +77,15 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
75 | break; | 77 | break; |
76 | 78 | ||
77 | case FS_IOC_SETFLAGS: | 79 | case FS_IOC_SETFLAGS: |
80 | if (pSMBFile == NULL) | ||
81 | break; | ||
82 | tcon = tlink_tcon(pSMBFile->tlink); | ||
83 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | ||
78 | if (CIFS_UNIX_EXTATTR_CAP & caps) { | 84 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
79 | if (get_user(ExtAttrBits, (int __user *)arg)) { | 85 | if (get_user(ExtAttrBits, (int __user *)arg)) { |
80 | rc = -EFAULT; | 86 | rc = -EFAULT; |
81 | break; | 87 | break; |
82 | } | 88 | } |
83 | if (pSMBFile == NULL) | ||
84 | break; | ||
85 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, | 89 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, |
86 | extAttrBits, &ExtAttrMask);*/ | 90 | extAttrBits, &ExtAttrMask);*/ |
87 | } | 91 | } |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index c4e296fe3518..43f10281bc19 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -569,10 +569,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | |||
569 | 569 | ||
570 | cFYI(1, "file id match, oplock break"); | 570 | cFYI(1, "file id match, oplock break"); |
571 | pCifsInode = CIFS_I(netfile->dentry->d_inode); | 571 | pCifsInode = CIFS_I(netfile->dentry->d_inode); |
572 | pCifsInode->clientCanCacheAll = false; | ||
573 | if (pSMB->OplockLevel == 0) | ||
574 | pCifsInode->clientCanCacheRead = false; | ||
575 | 572 | ||
573 | cifs_set_oplock_level(pCifsInode, | ||
574 | pSMB->OplockLevel); | ||
576 | /* | 575 | /* |
577 | * cifs_oplock_break_put() can't be called | 576 | * cifs_oplock_break_put() can't be called |
578 | * from here. Get reference after queueing | 577 | * from here. Get reference after queueing |
@@ -722,3 +721,23 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) | |||
722 | cifs_sb_master_tcon(cifs_sb)->treeName); | 721 | cifs_sb_master_tcon(cifs_sb)->treeName); |
723 | } | 722 | } |
724 | } | 723 | } |
724 | |||
725 | void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | ||
726 | { | ||
727 | oplock &= 0xF; | ||
728 | |||
729 | if (oplock == OPLOCK_EXCLUSIVE) { | ||
730 | cinode->clientCanCacheAll = true; | ||
731 | cinode->clientCanCacheRead = true; | ||
732 | cFYI(1, "Exclusive Oplock granted on inode %p", | ||
733 | &cinode->vfs_inode); | ||
734 | } else if (oplock == OPLOCK_READ) { | ||
735 | cinode->clientCanCacheAll = false; | ||
736 | cinode->clientCanCacheRead = true; | ||
737 | cFYI(1, "Level II Oplock granted on inode %p", | ||
738 | &cinode->vfs_inode); | ||
739 | } else { | ||
740 | cinode->clientCanCacheAll = false; | ||
741 | cinode->clientCanCacheRead = false; | ||
742 | } | ||
743 | } | ||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8b5dd6369f82..6a5edea2d70b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -177,7 +177,7 @@ struct mpage_da_data { | |||
177 | 177 | ||
178 | struct ext4_io_page { | 178 | struct ext4_io_page { |
179 | struct page *p_page; | 179 | struct page *p_page; |
180 | int p_count; | 180 | atomic_t p_count; |
181 | }; | 181 | }; |
182 | 182 | ||
183 | #define MAX_IO_PAGES 128 | 183 | #define MAX_IO_PAGES 128 |
@@ -858,6 +858,7 @@ struct ext4_inode_info { | |||
858 | spinlock_t i_completed_io_lock; | 858 | spinlock_t i_completed_io_lock; |
859 | /* current io_end structure for async DIO write*/ | 859 | /* current io_end structure for async DIO write*/ |
860 | ext4_io_end_t *cur_aio_dio; | 860 | ext4_io_end_t *cur_aio_dio; |
861 | atomic_t i_ioend_count; /* Number of outstanding io_end structs */ | ||
861 | 862 | ||
862 | /* | 863 | /* |
863 | * Transactions that contain inode's metadata needed to complete | 864 | * Transactions that contain inode's metadata needed to complete |
@@ -2060,6 +2061,7 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, | |||
2060 | /* page-io.c */ | 2061 | /* page-io.c */ |
2061 | extern int __init ext4_init_pageio(void); | 2062 | extern int __init ext4_init_pageio(void); |
2062 | extern void ext4_exit_pageio(void); | 2063 | extern void ext4_exit_pageio(void); |
2064 | extern void ext4_ioend_wait(struct inode *); | ||
2063 | extern void ext4_free_io_end(ext4_io_end_t *io); | 2065 | extern void ext4_free_io_end(ext4_io_end_t *io); |
2064 | extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); | 2066 | extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); |
2065 | extern int ext4_end_io_nolock(ext4_io_end_t *io); | 2067 | extern int ext4_end_io_nolock(ext4_io_end_t *io); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 191616470466..bdbe69902207 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -53,6 +53,7 @@ | |||
53 | static inline int ext4_begin_ordered_truncate(struct inode *inode, | 53 | static inline int ext4_begin_ordered_truncate(struct inode *inode, |
54 | loff_t new_size) | 54 | loff_t new_size) |
55 | { | 55 | { |
56 | trace_ext4_begin_ordered_truncate(inode, new_size); | ||
56 | return jbd2_journal_begin_ordered_truncate( | 57 | return jbd2_journal_begin_ordered_truncate( |
57 | EXT4_SB(inode->i_sb)->s_journal, | 58 | EXT4_SB(inode->i_sb)->s_journal, |
58 | &EXT4_I(inode)->jinode, | 59 | &EXT4_I(inode)->jinode, |
@@ -178,6 +179,7 @@ void ext4_evict_inode(struct inode *inode) | |||
178 | handle_t *handle; | 179 | handle_t *handle; |
179 | int err; | 180 | int err; |
180 | 181 | ||
182 | trace_ext4_evict_inode(inode); | ||
181 | if (inode->i_nlink) { | 183 | if (inode->i_nlink) { |
182 | truncate_inode_pages(&inode->i_data, 0); | 184 | truncate_inode_pages(&inode->i_data, 0); |
183 | goto no_delete; | 185 | goto no_delete; |
@@ -5410,9 +5412,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
5410 | * will return the blocks that include the delayed allocation | 5412 | * will return the blocks that include the delayed allocation |
5411 | * blocks for this file. | 5413 | * blocks for this file. |
5412 | */ | 5414 | */ |
5413 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | ||
5414 | delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; | 5415 | delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; |
5415 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | ||
5416 | 5416 | ||
5417 | stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; | 5417 | stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; |
5418 | return 0; | 5418 | return 0; |
@@ -5649,6 +5649,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
5649 | int err, ret; | 5649 | int err, ret; |
5650 | 5650 | ||
5651 | might_sleep(); | 5651 | might_sleep(); |
5652 | trace_ext4_mark_inode_dirty(inode, _RET_IP_); | ||
5652 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 5653 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
5653 | if (ext4_handle_valid(handle) && | 5654 | if (ext4_handle_valid(handle) && |
5654 | EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && | 5655 | EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index c58eba34724a..5b4d4e3a4d58 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -4640,8 +4640,6 @@ do_more: | |||
4640 | * with group lock held. generate_buddy look at | 4640 | * with group lock held. generate_buddy look at |
4641 | * them with group lock_held | 4641 | * them with group lock_held |
4642 | */ | 4642 | */ |
4643 | if (test_opt(sb, DISCARD)) | ||
4644 | ext4_issue_discard(sb, block_group, bit, count); | ||
4645 | ext4_lock_group(sb, block_group); | 4643 | ext4_lock_group(sb, block_group); |
4646 | mb_clear_bits(bitmap_bh->b_data, bit, count); | 4644 | mb_clear_bits(bitmap_bh->b_data, bit, count); |
4647 | mb_free_blocks(inode, &e4b, bit, count); | 4645 | mb_free_blocks(inode, &e4b, bit, count); |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 46a7d6a9d976..7f5451cd1d38 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -32,8 +32,14 @@ | |||
32 | 32 | ||
33 | static struct kmem_cache *io_page_cachep, *io_end_cachep; | 33 | static struct kmem_cache *io_page_cachep, *io_end_cachep; |
34 | 34 | ||
35 | #define WQ_HASH_SZ 37 | ||
36 | #define to_ioend_wq(v) (&ioend_wq[((unsigned long)v) % WQ_HASH_SZ]) | ||
37 | static wait_queue_head_t ioend_wq[WQ_HASH_SZ]; | ||
38 | |||
35 | int __init ext4_init_pageio(void) | 39 | int __init ext4_init_pageio(void) |
36 | { | 40 | { |
41 | int i; | ||
42 | |||
37 | io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); | 43 | io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); |
38 | if (io_page_cachep == NULL) | 44 | if (io_page_cachep == NULL) |
39 | return -ENOMEM; | 45 | return -ENOMEM; |
@@ -42,6 +48,8 @@ int __init ext4_init_pageio(void) | |||
42 | kmem_cache_destroy(io_page_cachep); | 48 | kmem_cache_destroy(io_page_cachep); |
43 | return -ENOMEM; | 49 | return -ENOMEM; |
44 | } | 50 | } |
51 | for (i = 0; i < WQ_HASH_SZ; i++) | ||
52 | init_waitqueue_head(&ioend_wq[i]); | ||
45 | 53 | ||
46 | return 0; | 54 | return 0; |
47 | } | 55 | } |
@@ -52,24 +60,37 @@ void ext4_exit_pageio(void) | |||
52 | kmem_cache_destroy(io_page_cachep); | 60 | kmem_cache_destroy(io_page_cachep); |
53 | } | 61 | } |
54 | 62 | ||
63 | void ext4_ioend_wait(struct inode *inode) | ||
64 | { | ||
65 | wait_queue_head_t *wq = to_ioend_wq(inode); | ||
66 | |||
67 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); | ||
68 | } | ||
69 | |||
70 | static void put_io_page(struct ext4_io_page *io_page) | ||
71 | { | ||
72 | if (atomic_dec_and_test(&io_page->p_count)) { | ||
73 | end_page_writeback(io_page->p_page); | ||
74 | put_page(io_page->p_page); | ||
75 | kmem_cache_free(io_page_cachep, io_page); | ||
76 | } | ||
77 | } | ||
78 | |||
55 | void ext4_free_io_end(ext4_io_end_t *io) | 79 | void ext4_free_io_end(ext4_io_end_t *io) |
56 | { | 80 | { |
57 | int i; | 81 | int i; |
82 | wait_queue_head_t *wq; | ||
58 | 83 | ||
59 | BUG_ON(!io); | 84 | BUG_ON(!io); |
60 | if (io->page) | 85 | if (io->page) |
61 | put_page(io->page); | 86 | put_page(io->page); |
62 | for (i = 0; i < io->num_io_pages; i++) { | 87 | for (i = 0; i < io->num_io_pages; i++) |
63 | if (--io->pages[i]->p_count == 0) { | 88 | put_io_page(io->pages[i]); |
64 | struct page *page = io->pages[i]->p_page; | ||
65 | |||
66 | end_page_writeback(page); | ||
67 | put_page(page); | ||
68 | kmem_cache_free(io_page_cachep, io->pages[i]); | ||
69 | } | ||
70 | } | ||
71 | io->num_io_pages = 0; | 89 | io->num_io_pages = 0; |
72 | iput(io->inode); | 90 | wq = to_ioend_wq(io->inode); |
91 | if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) && | ||
92 | waitqueue_active(wq)) | ||
93 | wake_up_all(wq); | ||
73 | kmem_cache_free(io_end_cachep, io); | 94 | kmem_cache_free(io_end_cachep, io); |
74 | } | 95 | } |
75 | 96 | ||
@@ -142,8 +163,8 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) | |||
142 | io = kmem_cache_alloc(io_end_cachep, flags); | 163 | io = kmem_cache_alloc(io_end_cachep, flags); |
143 | if (io) { | 164 | if (io) { |
144 | memset(io, 0, sizeof(*io)); | 165 | memset(io, 0, sizeof(*io)); |
145 | io->inode = igrab(inode); | 166 | atomic_inc(&EXT4_I(inode)->i_ioend_count); |
146 | BUG_ON(!io->inode); | 167 | io->inode = inode; |
147 | INIT_WORK(&io->work, ext4_end_io_work); | 168 | INIT_WORK(&io->work, ext4_end_io_work); |
148 | INIT_LIST_HEAD(&io->list); | 169 | INIT_LIST_HEAD(&io->list); |
149 | } | 170 | } |
@@ -171,35 +192,15 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
171 | struct workqueue_struct *wq; | 192 | struct workqueue_struct *wq; |
172 | struct inode *inode; | 193 | struct inode *inode; |
173 | unsigned long flags; | 194 | unsigned long flags; |
174 | ext4_fsblk_t err_block; | ||
175 | int i; | 195 | int i; |
176 | 196 | ||
177 | BUG_ON(!io_end); | 197 | BUG_ON(!io_end); |
178 | inode = io_end->inode; | ||
179 | bio->bi_private = NULL; | 198 | bio->bi_private = NULL; |
180 | bio->bi_end_io = NULL; | 199 | bio->bi_end_io = NULL; |
181 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) | 200 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) |
182 | error = 0; | 201 | error = 0; |
183 | err_block = bio->bi_sector >> (inode->i_blkbits - 9); | ||
184 | bio_put(bio); | 202 | bio_put(bio); |
185 | 203 | ||
186 | if (!(inode->i_sb->s_flags & MS_ACTIVE)) { | ||
187 | pr_err("sb umounted, discard end_io request for inode %lu\n", | ||
188 | io_end->inode->i_ino); | ||
189 | ext4_free_io_end(io_end); | ||
190 | return; | ||
191 | } | ||
192 | |||
193 | if (error) { | ||
194 | io_end->flag |= EXT4_IO_END_ERROR; | ||
195 | ext4_warning(inode->i_sb, "I/O error writing to inode %lu " | ||
196 | "(offset %llu size %ld starting block %llu)", | ||
197 | inode->i_ino, | ||
198 | (unsigned long long) io_end->offset, | ||
199 | (long) io_end->size, | ||
200 | (unsigned long long) err_block); | ||
201 | } | ||
202 | |||
203 | for (i = 0; i < io_end->num_io_pages; i++) { | 204 | for (i = 0; i < io_end->num_io_pages; i++) { |
204 | struct page *page = io_end->pages[i]->p_page; | 205 | struct page *page = io_end->pages[i]->p_page; |
205 | struct buffer_head *bh, *head; | 206 | struct buffer_head *bh, *head; |
@@ -236,13 +237,7 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
236 | } while (bh != head); | 237 | } while (bh != head); |
237 | } | 238 | } |
238 | 239 | ||
239 | if (--io_end->pages[i]->p_count == 0) { | 240 | put_io_page(io_end->pages[i]); |
240 | struct page *page = io_end->pages[i]->p_page; | ||
241 | |||
242 | end_page_writeback(page); | ||
243 | put_page(page); | ||
244 | kmem_cache_free(io_page_cachep, io_end->pages[i]); | ||
245 | } | ||
246 | 241 | ||
247 | /* | 242 | /* |
248 | * If this is a partial write which happened to make | 243 | * If this is a partial write which happened to make |
@@ -254,8 +249,19 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
254 | if (!partial_write) | 249 | if (!partial_write) |
255 | SetPageUptodate(page); | 250 | SetPageUptodate(page); |
256 | } | 251 | } |
257 | |||
258 | io_end->num_io_pages = 0; | 252 | io_end->num_io_pages = 0; |
253 | inode = io_end->inode; | ||
254 | |||
255 | if (error) { | ||
256 | io_end->flag |= EXT4_IO_END_ERROR; | ||
257 | ext4_warning(inode->i_sb, "I/O error writing to inode %lu " | ||
258 | "(offset %llu size %ld starting block %llu)", | ||
259 | inode->i_ino, | ||
260 | (unsigned long long) io_end->offset, | ||
261 | (long) io_end->size, | ||
262 | (unsigned long long) | ||
263 | bio->bi_sector >> (inode->i_blkbits - 9)); | ||
264 | } | ||
259 | 265 | ||
260 | /* Add the io_end to per-inode completed io list*/ | 266 | /* Add the io_end to per-inode completed io list*/ |
261 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); | 267 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); |
@@ -305,7 +311,6 @@ static int io_submit_init(struct ext4_io_submit *io, | |||
305 | bio->bi_private = io->io_end = io_end; | 311 | bio->bi_private = io->io_end = io_end; |
306 | bio->bi_end_io = ext4_end_bio; | 312 | bio->bi_end_io = ext4_end_bio; |
307 | 313 | ||
308 | io_end->inode = inode; | ||
309 | io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); | 314 | io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); |
310 | 315 | ||
311 | io->io_bio = bio; | 316 | io->io_bio = bio; |
@@ -360,7 +365,7 @@ submit_and_retry: | |||
360 | if ((io_end->num_io_pages == 0) || | 365 | if ((io_end->num_io_pages == 0) || |
361 | (io_end->pages[io_end->num_io_pages-1] != io_page)) { | 366 | (io_end->pages[io_end->num_io_pages-1] != io_page)) { |
362 | io_end->pages[io_end->num_io_pages++] = io_page; | 367 | io_end->pages[io_end->num_io_pages++] = io_page; |
363 | io_page->p_count++; | 368 | atomic_inc(&io_page->p_count); |
364 | } | 369 | } |
365 | return 0; | 370 | return 0; |
366 | } | 371 | } |
@@ -389,7 +394,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
389 | return -ENOMEM; | 394 | return -ENOMEM; |
390 | } | 395 | } |
391 | io_page->p_page = page; | 396 | io_page->p_page = page; |
392 | io_page->p_count = 0; | 397 | atomic_set(&io_page->p_count, 1); |
393 | get_page(page); | 398 | get_page(page); |
394 | 399 | ||
395 | for (bh = head = page_buffers(page), block_start = 0; | 400 | for (bh = head = page_buffers(page), block_start = 0; |
@@ -421,10 +426,6 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
421 | * PageWriteback bit from the page to prevent the system from | 426 | * PageWriteback bit from the page to prevent the system from |
422 | * wedging later on. | 427 | * wedging later on. |
423 | */ | 428 | */ |
424 | if (io_page->p_count == 0) { | 429 | put_io_page(io_page); |
425 | put_page(page); | ||
426 | end_page_writeback(page); | ||
427 | kmem_cache_free(io_page_cachep, io_page); | ||
428 | } | ||
429 | return ret; | 430 | return ret; |
430 | } | 431 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 40131b777af6..61182fe6254e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -828,12 +828,22 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
828 | ei->cur_aio_dio = NULL; | 828 | ei->cur_aio_dio = NULL; |
829 | ei->i_sync_tid = 0; | 829 | ei->i_sync_tid = 0; |
830 | ei->i_datasync_tid = 0; | 830 | ei->i_datasync_tid = 0; |
831 | atomic_set(&ei->i_ioend_count, 0); | ||
831 | 832 | ||
832 | return &ei->vfs_inode; | 833 | return &ei->vfs_inode; |
833 | } | 834 | } |
834 | 835 | ||
836 | static int ext4_drop_inode(struct inode *inode) | ||
837 | { | ||
838 | int drop = generic_drop_inode(inode); | ||
839 | |||
840 | trace_ext4_drop_inode(inode, drop); | ||
841 | return drop; | ||
842 | } | ||
843 | |||
835 | static void ext4_destroy_inode(struct inode *inode) | 844 | static void ext4_destroy_inode(struct inode *inode) |
836 | { | 845 | { |
846 | ext4_ioend_wait(inode); | ||
837 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | 847 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
838 | ext4_msg(inode->i_sb, KERN_ERR, | 848 | ext4_msg(inode->i_sb, KERN_ERR, |
839 | "Inode %lu (%p): orphan list check failed!", | 849 | "Inode %lu (%p): orphan list check failed!", |
@@ -1173,6 +1183,7 @@ static const struct super_operations ext4_sops = { | |||
1173 | .destroy_inode = ext4_destroy_inode, | 1183 | .destroy_inode = ext4_destroy_inode, |
1174 | .write_inode = ext4_write_inode, | 1184 | .write_inode = ext4_write_inode, |
1175 | .dirty_inode = ext4_dirty_inode, | 1185 | .dirty_inode = ext4_dirty_inode, |
1186 | .drop_inode = ext4_drop_inode, | ||
1176 | .evict_inode = ext4_evict_inode, | 1187 | .evict_inode = ext4_evict_inode, |
1177 | .put_super = ext4_put_super, | 1188 | .put_super = ext4_put_super, |
1178 | .sync_fs = ext4_sync_fs, | 1189 | .sync_fs = ext4_sync_fs, |
@@ -1194,6 +1205,7 @@ static const struct super_operations ext4_nojournal_sops = { | |||
1194 | .destroy_inode = ext4_destroy_inode, | 1205 | .destroy_inode = ext4_destroy_inode, |
1195 | .write_inode = ext4_write_inode, | 1206 | .write_inode = ext4_write_inode, |
1196 | .dirty_inode = ext4_dirty_inode, | 1207 | .dirty_inode = ext4_dirty_inode, |
1208 | .drop_inode = ext4_drop_inode, | ||
1197 | .evict_inode = ext4_evict_inode, | 1209 | .evict_inode = ext4_evict_inode, |
1198 | .write_super = ext4_write_super, | 1210 | .write_super = ext4_write_super, |
1199 | .put_super = ext4_put_super, | 1211 | .put_super = ext4_put_super, |
@@ -2699,7 +2711,6 @@ static int ext4_lazyinit_thread(void *arg) | |||
2699 | struct ext4_li_request *elr; | 2711 | struct ext4_li_request *elr; |
2700 | unsigned long next_wakeup; | 2712 | unsigned long next_wakeup; |
2701 | DEFINE_WAIT(wait); | 2713 | DEFINE_WAIT(wait); |
2702 | int ret; | ||
2703 | 2714 | ||
2704 | BUG_ON(NULL == eli); | 2715 | BUG_ON(NULL == eli); |
2705 | 2716 | ||
@@ -2723,13 +2734,12 @@ cont_thread: | |||
2723 | elr = list_entry(pos, struct ext4_li_request, | 2734 | elr = list_entry(pos, struct ext4_li_request, |
2724 | lr_request); | 2735 | lr_request); |
2725 | 2736 | ||
2726 | if (time_after_eq(jiffies, elr->lr_next_sched)) | 2737 | if (time_after_eq(jiffies, elr->lr_next_sched)) { |
2727 | ret = ext4_run_li_request(elr); | 2738 | if (ext4_run_li_request(elr) != 0) { |
2728 | 2739 | /* error, remove the lazy_init job */ | |
2729 | if (ret) { | 2740 | ext4_remove_li_request(elr); |
2730 | ret = 0; | 2741 | continue; |
2731 | ext4_remove_li_request(elr); | 2742 | } |
2732 | continue; | ||
2733 | } | 2743 | } |
2734 | 2744 | ||
2735 | if (time_before(elr->lr_next_sched, next_wakeup)) | 2745 | if (time_before(elr->lr_next_sched, next_wakeup)) |
@@ -2740,7 +2750,8 @@ cont_thread: | |||
2740 | if (freezing(current)) | 2750 | if (freezing(current)) |
2741 | refrigerator(); | 2751 | refrigerator(); |
2742 | 2752 | ||
2743 | if (time_after_eq(jiffies, next_wakeup)) { | 2753 | if ((time_after_eq(jiffies, next_wakeup)) || |
2754 | (MAX_JIFFY_OFFSET == next_wakeup)) { | ||
2744 | cond_resched(); | 2755 | cond_resched(); |
2745 | continue; | 2756 | continue; |
2746 | } | 2757 | } |
@@ -3348,6 +3359,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3348 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 3359 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
3349 | spin_lock_init(&sbi->s_next_gen_lock); | 3360 | spin_lock_init(&sbi->s_next_gen_lock); |
3350 | 3361 | ||
3362 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | ||
3363 | ext4_count_free_blocks(sb)); | ||
3364 | if (!err) { | ||
3365 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
3366 | ext4_count_free_inodes(sb)); | ||
3367 | } | ||
3368 | if (!err) { | ||
3369 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
3370 | ext4_count_dirs(sb)); | ||
3371 | } | ||
3372 | if (!err) { | ||
3373 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | ||
3374 | } | ||
3375 | if (err) { | ||
3376 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3377 | goto failed_mount3; | ||
3378 | } | ||
3379 | |||
3351 | sbi->s_stripe = ext4_get_stripe_size(sbi); | 3380 | sbi->s_stripe = ext4_get_stripe_size(sbi); |
3352 | sbi->s_max_writeback_mb_bump = 128; | 3381 | sbi->s_max_writeback_mb_bump = 128; |
3353 | 3382 | ||
@@ -3446,22 +3475,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3446 | } | 3475 | } |
3447 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 3476 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
3448 | 3477 | ||
3449 | no_journal: | 3478 | /* |
3450 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | 3479 | * The journal may have updated the bg summary counts, so we |
3451 | ext4_count_free_blocks(sb)); | 3480 | * need to update the global counters. |
3452 | if (!err) | 3481 | */ |
3453 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | 3482 | percpu_counter_set(&sbi->s_freeblocks_counter, |
3454 | ext4_count_free_inodes(sb)); | 3483 | ext4_count_free_blocks(sb)); |
3455 | if (!err) | 3484 | percpu_counter_set(&sbi->s_freeinodes_counter, |
3456 | err = percpu_counter_init(&sbi->s_dirs_counter, | 3485 | ext4_count_free_inodes(sb)); |
3457 | ext4_count_dirs(sb)); | 3486 | percpu_counter_set(&sbi->s_dirs_counter, |
3458 | if (!err) | 3487 | ext4_count_dirs(sb)); |
3459 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | 3488 | percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); |
3460 | if (err) { | ||
3461 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3462 | goto failed_mount_wq; | ||
3463 | } | ||
3464 | 3489 | ||
3490 | no_journal: | ||
3465 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 3491 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
3466 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 3492 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
3467 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); | 3493 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); |
@@ -3611,10 +3637,6 @@ failed_mount_wq: | |||
3611 | jbd2_journal_destroy(sbi->s_journal); | 3637 | jbd2_journal_destroy(sbi->s_journal); |
3612 | sbi->s_journal = NULL; | 3638 | sbi->s_journal = NULL; |
3613 | } | 3639 | } |
3614 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3615 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3616 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3617 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3618 | failed_mount3: | 3640 | failed_mount3: |
3619 | if (sbi->s_flex_groups) { | 3641 | if (sbi->s_flex_groups) { |
3620 | if (is_vmalloc_addr(sbi->s_flex_groups)) | 3642 | if (is_vmalloc_addr(sbi->s_flex_groups)) |
@@ -3622,6 +3644,10 @@ failed_mount3: | |||
3622 | else | 3644 | else |
3623 | kfree(sbi->s_flex_groups); | 3645 | kfree(sbi->s_flex_groups); |
3624 | } | 3646 | } |
3647 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3648 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3649 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3650 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3625 | failed_mount2: | 3651 | failed_mount2: |
3626 | for (i = 0; i < db_count; i++) | 3652 | for (i = 0; i < db_count; i++) |
3627 | brelse(sbi->s_group_desc[i]); | 3653 | brelse(sbi->s_group_desc[i]); |
@@ -3949,13 +3975,11 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
3949 | else | 3975 | else |
3950 | es->s_kbytes_written = | 3976 | es->s_kbytes_written = |
3951 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); | 3977 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); |
3952 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter)) | 3978 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( |
3953 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( | 3979 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3954 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3980 | es->s_free_inodes_count = |
3955 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) | 3981 | cpu_to_le32(percpu_counter_sum_positive( |
3956 | es->s_free_inodes_count = | 3982 | &EXT4_SB(sb)->s_freeinodes_counter)); |
3957 | cpu_to_le32(percpu_counter_sum_positive( | ||
3958 | &EXT4_SB(sb)->s_freeinodes_counter)); | ||
3959 | sb->s_dirt = 0; | 3983 | sb->s_dirt = 0; |
3960 | BUFFER_TRACE(sbh, "marking dirty"); | 3984 | BUFFER_TRACE(sbh, "marking dirty"); |
3961 | mark_buffer_dirty(sbh); | 3985 | mark_buffer_dirty(sbh); |
@@ -4556,12 +4580,10 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
4556 | 4580 | ||
4557 | static int ext4_quota_off(struct super_block *sb, int type) | 4581 | static int ext4_quota_off(struct super_block *sb, int type) |
4558 | { | 4582 | { |
4559 | /* Force all delayed allocation blocks to be allocated */ | 4583 | /* Force all delayed allocation blocks to be allocated. |
4560 | if (test_opt(sb, DELALLOC)) { | 4584 | * Caller already holds s_umount sem */ |
4561 | down_read(&sb->s_umount); | 4585 | if (test_opt(sb, DELALLOC)) |
4562 | sync_filesystem(sb); | 4586 | sync_filesystem(sb); |
4563 | up_read(&sb->s_umount); | ||
4564 | } | ||
4565 | 4587 | ||
4566 | return dquot_quota_off(sb, type); | 4588 | return dquot_quota_off(sb, type); |
4567 | } | 4589 | } |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index d6cfac1f0a40..a5fe68189eed 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -932,8 +932,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, | |||
932 | if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { | 932 | if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { |
933 | *user = current_user(); | 933 | *user = current_user(); |
934 | if (user_shm_lock(size, *user)) { | 934 | if (user_shm_lock(size, *user)) { |
935 | WARN_ONCE(1, | 935 | printk_once(KERN_WARNING "Using mlock ulimits for SHM_HUGETLB is deprecated\n"); |
936 | "Using mlock ulimits for SHM_HUGETLB deprecated\n"); | ||
937 | } else { | 936 | } else { |
938 | *user = NULL; | 937 | *user = NULL; |
939 | return ERR_PTR(-EPERM); | 938 | return ERR_PTR(-EPERM); |
diff --git a/fs/ioprio.c b/fs/ioprio.c index 748cfb92dcc6..2f7d05c89922 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -111,12 +111,14 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) | |||
111 | read_lock(&tasklist_lock); | 111 | read_lock(&tasklist_lock); |
112 | switch (which) { | 112 | switch (which) { |
113 | case IOPRIO_WHO_PROCESS: | 113 | case IOPRIO_WHO_PROCESS: |
114 | rcu_read_lock(); | ||
114 | if (!who) | 115 | if (!who) |
115 | p = current; | 116 | p = current; |
116 | else | 117 | else |
117 | p = find_task_by_vpid(who); | 118 | p = find_task_by_vpid(who); |
118 | if (p) | 119 | if (p) |
119 | ret = set_task_ioprio(p, ioprio); | 120 | ret = set_task_ioprio(p, ioprio); |
121 | rcu_read_unlock(); | ||
120 | break; | 122 | break; |
121 | case IOPRIO_WHO_PGRP: | 123 | case IOPRIO_WHO_PGRP: |
122 | if (!who) | 124 | if (!who) |
@@ -139,7 +141,12 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) | |||
139 | break; | 141 | break; |
140 | 142 | ||
141 | do_each_thread(g, p) { | 143 | do_each_thread(g, p) { |
142 | if (__task_cred(p)->uid != who) | 144 | int match; |
145 | |||
146 | rcu_read_lock(); | ||
147 | match = __task_cred(p)->uid == who; | ||
148 | rcu_read_unlock(); | ||
149 | if (!match) | ||
143 | continue; | 150 | continue; |
144 | ret = set_task_ioprio(p, ioprio); | 151 | ret = set_task_ioprio(p, ioprio); |
145 | if (ret) | 152 | if (ret) |
@@ -200,12 +207,14 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) | |||
200 | read_lock(&tasklist_lock); | 207 | read_lock(&tasklist_lock); |
201 | switch (which) { | 208 | switch (which) { |
202 | case IOPRIO_WHO_PROCESS: | 209 | case IOPRIO_WHO_PROCESS: |
210 | rcu_read_lock(); | ||
203 | if (!who) | 211 | if (!who) |
204 | p = current; | 212 | p = current; |
205 | else | 213 | else |
206 | p = find_task_by_vpid(who); | 214 | p = find_task_by_vpid(who); |
207 | if (p) | 215 | if (p) |
208 | ret = get_task_ioprio(p); | 216 | ret = get_task_ioprio(p); |
217 | rcu_read_unlock(); | ||
209 | break; | 218 | break; |
210 | case IOPRIO_WHO_PGRP: | 219 | case IOPRIO_WHO_PGRP: |
211 | if (!who) | 220 | if (!who) |
@@ -232,7 +241,12 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) | |||
232 | break; | 241 | break; |
233 | 242 | ||
234 | do_each_thread(g, p) { | 243 | do_each_thread(g, p) { |
235 | if (__task_cred(p)->uid != user->uid) | 244 | int match; |
245 | |||
246 | rcu_read_lock(); | ||
247 | match = __task_cred(p)->uid == user->uid; | ||
248 | rcu_read_unlock(); | ||
249 | if (!match) | ||
236 | continue; | 250 | continue; |
237 | tmpio = get_task_ioprio(p); | 251 | tmpio = get_task_ioprio(p); |
238 | if (tmpio < 0) | 252 | if (tmpio < 0) |
diff --git a/fs/locks.c b/fs/locks.c index 65765cb6afed..0e62dd35d088 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1504,9 +1504,8 @@ static int do_fcntl_delete_lease(struct file *filp) | |||
1504 | 1504 | ||
1505 | static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | 1505 | static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) |
1506 | { | 1506 | { |
1507 | struct file_lock *fl; | 1507 | struct file_lock *fl, *ret; |
1508 | struct fasync_struct *new; | 1508 | struct fasync_struct *new; |
1509 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
1510 | int error; | 1509 | int error; |
1511 | 1510 | ||
1512 | fl = lease_alloc(filp, arg); | 1511 | fl = lease_alloc(filp, arg); |
@@ -1518,13 +1517,16 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1518 | locks_free_lock(fl); | 1517 | locks_free_lock(fl); |
1519 | return -ENOMEM; | 1518 | return -ENOMEM; |
1520 | } | 1519 | } |
1520 | ret = fl; | ||
1521 | lock_flocks(); | 1521 | lock_flocks(); |
1522 | error = __vfs_setlease(filp, arg, &fl); | 1522 | error = __vfs_setlease(filp, arg, &ret); |
1523 | if (error) { | 1523 | if (error) { |
1524 | unlock_flocks(); | 1524 | unlock_flocks(); |
1525 | locks_free_lock(fl); | 1525 | locks_free_lock(fl); |
1526 | goto out_free_fasync; | 1526 | goto out_free_fasync; |
1527 | } | 1527 | } |
1528 | if (ret != fl) | ||
1529 | locks_free_lock(fl); | ||
1528 | 1530 | ||
1529 | /* | 1531 | /* |
1530 | * fasync_insert_entry() returns the old entry if any. | 1532 | * fasync_insert_entry() returns the old entry if any. |
@@ -1532,17 +1534,10 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1532 | * inserted it into the fasync list. Clear new so that | 1534 | * inserted it into the fasync list. Clear new so that |
1533 | * we don't release it here. | 1535 | * we don't release it here. |
1534 | */ | 1536 | */ |
1535 | if (!fasync_insert_entry(fd, filp, &fl->fl_fasync, new)) | 1537 | if (!fasync_insert_entry(fd, filp, &ret->fl_fasync, new)) |
1536 | new = NULL; | 1538 | new = NULL; |
1537 | 1539 | ||
1538 | if (error < 0) { | 1540 | error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); |
1539 | /* remove lease just inserted by setlease */ | ||
1540 | fl->fl_type = F_UNLCK | F_INPROGRESS; | ||
1541 | fl->fl_break_time = jiffies - 10; | ||
1542 | time_out_leases(inode); | ||
1543 | } else { | ||
1544 | error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); | ||
1545 | } | ||
1546 | unlock_flocks(); | 1541 | unlock_flocks(); |
1547 | 1542 | ||
1548 | out_free_fasync: | 1543 | out_free_fasync: |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index cd51a36b37f0..57afd4a6fabb 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -486,7 +486,7 @@ static inline int logfs_get_sb_bdev(struct logfs_super *s, | |||
486 | 486 | ||
487 | /* dev_mtd.c */ | 487 | /* dev_mtd.c */ |
488 | #ifdef CONFIG_MTD | 488 | #ifdef CONFIG_MTD |
489 | int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) | 489 | int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr); |
490 | #else | 490 | #else |
491 | static inline int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) | 491 | static inline int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) |
492 | { | 492 | { |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f1e5ec6b5105..ad2bfa68d534 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -673,16 +673,17 @@ static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) | |||
673 | spin_unlock(&clp->cl_lock); | 673 | spin_unlock(&clp->cl_lock); |
674 | } | 674 | } |
675 | 675 | ||
676 | static void nfsd4_register_conn(struct nfsd4_conn *conn) | 676 | static int nfsd4_register_conn(struct nfsd4_conn *conn) |
677 | { | 677 | { |
678 | conn->cn_xpt_user.callback = nfsd4_conn_lost; | 678 | conn->cn_xpt_user.callback = nfsd4_conn_lost; |
679 | register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); | 679 | return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); |
680 | } | 680 | } |
681 | 681 | ||
682 | static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) | 682 | static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) |
683 | { | 683 | { |
684 | struct nfsd4_conn *conn; | 684 | struct nfsd4_conn *conn; |
685 | u32 flags = NFS4_CDFC4_FORE; | 685 | u32 flags = NFS4_CDFC4_FORE; |
686 | int ret; | ||
686 | 687 | ||
687 | if (ses->se_flags & SESSION4_BACK_CHAN) | 688 | if (ses->se_flags & SESSION4_BACK_CHAN) |
688 | flags |= NFS4_CDFC4_BACK; | 689 | flags |= NFS4_CDFC4_BACK; |
@@ -690,7 +691,10 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) | |||
690 | if (!conn) | 691 | if (!conn) |
691 | return nfserr_jukebox; | 692 | return nfserr_jukebox; |
692 | nfsd4_hash_conn(conn, ses); | 693 | nfsd4_hash_conn(conn, ses); |
693 | nfsd4_register_conn(conn); | 694 | ret = nfsd4_register_conn(conn); |
695 | if (ret) | ||
696 | /* oops; xprt is already down: */ | ||
697 | nfsd4_conn_lost(&conn->cn_xpt_user); | ||
694 | return nfs_ok; | 698 | return nfs_ok; |
695 | } | 699 | } |
696 | 700 | ||
@@ -1644,6 +1648,7 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi | |||
1644 | { | 1648 | { |
1645 | struct nfs4_client *clp = ses->se_client; | 1649 | struct nfs4_client *clp = ses->se_client; |
1646 | struct nfsd4_conn *c; | 1650 | struct nfsd4_conn *c; |
1651 | int ret; | ||
1647 | 1652 | ||
1648 | spin_lock(&clp->cl_lock); | 1653 | spin_lock(&clp->cl_lock); |
1649 | c = __nfsd4_find_conn(new->cn_xprt, ses); | 1654 | c = __nfsd4_find_conn(new->cn_xprt, ses); |
@@ -1654,7 +1659,10 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi | |||
1654 | } | 1659 | } |
1655 | __nfsd4_hash_conn(new, ses); | 1660 | __nfsd4_hash_conn(new, ses); |
1656 | spin_unlock(&clp->cl_lock); | 1661 | spin_unlock(&clp->cl_lock); |
1657 | nfsd4_register_conn(new); | 1662 | ret = nfsd4_register_conn(new); |
1663 | if (ret) | ||
1664 | /* oops; xprt is already down: */ | ||
1665 | nfsd4_conn_lost(&new->cn_xpt_user); | ||
1658 | return; | 1666 | return; |
1659 | } | 1667 | } |
1660 | 1668 | ||
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index ddb1f41376e5..911e61f348fc 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -418,7 +418,7 @@ out_no_root: | |||
418 | static struct dentry *openprom_mount(struct file_system_type *fs_type, | 418 | static struct dentry *openprom_mount(struct file_system_type *fs_type, |
419 | int flags, const char *dev_name, void *data) | 419 | int flags, const char *dev_name, void *data) |
420 | { | 420 | { |
421 | return mount_single(fs_type, flags, data, openprom_fill_super) | 421 | return mount_single(fs_type, flags, data, openprom_fill_super); |
422 | } | 422 | } |
423 | 423 | ||
424 | static struct file_system_type openprom_fs_type = { | 424 | static struct file_system_type openprom_fs_type = { |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index c9af48fffcd7..7d287afccde5 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -1111,11 +1111,12 @@ xfs_vm_writepage( | |||
1111 | uptodate = 0; | 1111 | uptodate = 0; |
1112 | 1112 | ||
1113 | /* | 1113 | /* |
1114 | * A hole may still be marked uptodate because discard_buffer | 1114 | * set_page_dirty dirties all buffers in a page, independent |
1115 | * leaves the flag set. | 1115 | * of their state. The dirty state however is entirely |
1116 | * meaningless for holes (!mapped && uptodate), so skip | ||
1117 | * buffers covering holes here. | ||
1116 | */ | 1118 | */ |
1117 | if (!buffer_mapped(bh) && buffer_uptodate(bh)) { | 1119 | if (!buffer_mapped(bh) && buffer_uptodate(bh)) { |
1118 | ASSERT(!buffer_dirty(bh)); | ||
1119 | imap_valid = 0; | 1120 | imap_valid = 0; |
1120 | continue; | 1121 | continue; |
1121 | } | 1122 | } |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 63fd2c07cb57..aa1d353def29 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1781,7 +1781,6 @@ xfs_buf_delwri_split( | |||
1781 | INIT_LIST_HEAD(list); | 1781 | INIT_LIST_HEAD(list); |
1782 | spin_lock(dwlk); | 1782 | spin_lock(dwlk); |
1783 | list_for_each_entry_safe(bp, n, dwq, b_list) { | 1783 | list_for_each_entry_safe(bp, n, dwq, b_list) { |
1784 | trace_xfs_buf_delwri_split(bp, _RET_IP_); | ||
1785 | ASSERT(bp->b_flags & XBF_DELWRI); | 1784 | ASSERT(bp->b_flags & XBF_DELWRI); |
1786 | 1785 | ||
1787 | if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { | 1786 | if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { |
@@ -1795,6 +1794,7 @@ xfs_buf_delwri_split( | |||
1795 | _XBF_RUN_QUEUES); | 1794 | _XBF_RUN_QUEUES); |
1796 | bp->b_flags |= XBF_WRITE; | 1795 | bp->b_flags |= XBF_WRITE; |
1797 | list_move_tail(&bp->b_list, list); | 1796 | list_move_tail(&bp->b_list, list); |
1797 | trace_xfs_buf_delwri_split(bp, _RET_IP_); | ||
1798 | } else | 1798 | } else |
1799 | skipped++; | 1799 | skipped++; |
1800 | } | 1800 | } |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 2ea238f6d38e..ad442d9e392e 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -416,7 +416,7 @@ xfs_attrlist_by_handle( | |||
416 | if (IS_ERR(dentry)) | 416 | if (IS_ERR(dentry)) |
417 | return PTR_ERR(dentry); | 417 | return PTR_ERR(dentry); |
418 | 418 | ||
419 | kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); | 419 | kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL); |
420 | if (!kbuf) | 420 | if (!kbuf) |
421 | goto out_dput; | 421 | goto out_dput; |
422 | 422 | ||
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 96107efc0c61..94d5fd6a2973 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -762,7 +762,8 @@ xfs_setup_inode( | |||
762 | inode->i_state = I_NEW; | 762 | inode->i_state = I_NEW; |
763 | 763 | ||
764 | inode_sb_list_add(inode); | 764 | inode_sb_list_add(inode); |
765 | insert_inode_hash(inode); | 765 | /* make the inode look hashed for the writeback code */ |
766 | hlist_add_fake(&inode->i_hash); | ||
766 | 767 | ||
767 | inode->i_mode = ip->i_d.di_mode; | 768 | inode->i_mode = ip->i_d.di_mode; |
768 | inode->i_nlink = ip->i_d.di_nlink; | 769 | inode->i_nlink = ip->i_d.di_nlink; |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 9f3a78fe6ae4..064f964d4f3c 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -353,9 +353,6 @@ xfs_parseargs( | |||
353 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 353 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
354 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { | 354 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { |
355 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | 355 | mp->m_flags |= XFS_MOUNT_DELAYLOG; |
356 | cmn_err(CE_WARN, | ||
357 | "Enabling EXPERIMENTAL delayed logging feature " | ||
358 | "- use at your own risk.\n"); | ||
359 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 356 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
360 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; | 357 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; |
361 | } else if (!strcmp(this_char, "ihashsize")) { | 358 | } else if (!strcmp(this_char, "ihashsize")) { |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 37d33254981d..afb0d7cfad1c 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -853,6 +853,7 @@ restart: | |||
853 | if (trylock) { | 853 | if (trylock) { |
854 | if (!mutex_trylock(&pag->pag_ici_reclaim_lock)) { | 854 | if (!mutex_trylock(&pag->pag_ici_reclaim_lock)) { |
855 | skipped++; | 855 | skipped++; |
856 | xfs_perag_put(pag); | ||
856 | continue; | 857 | continue; |
857 | } | 858 | } |
858 | first_index = pag->pag_ici_reclaim_cursor; | 859 | first_index = pag->pag_ici_reclaim_cursor; |
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 9b715dce5699..9124425b7f2f 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c | |||
@@ -744,9 +744,15 @@ xfs_filestream_new_ag( | |||
744 | * If the file's parent directory is known, take its iolock in exclusive | 744 | * If the file's parent directory is known, take its iolock in exclusive |
745 | * mode to prevent two sibling files from racing each other to migrate | 745 | * mode to prevent two sibling files from racing each other to migrate |
746 | * themselves and their parent to different AGs. | 746 | * themselves and their parent to different AGs. |
747 | * | ||
748 | * Note that we lock the parent directory iolock inside the child | ||
749 | * iolock here. That's fine as we never hold both parent and child | ||
750 | * iolock in any other place. This is different from the ilock, | ||
751 | * which requires locking of the child after the parent for namespace | ||
752 | * operations. | ||
747 | */ | 753 | */ |
748 | if (pip) | 754 | if (pip) |
749 | xfs_ilock(pip, XFS_IOLOCK_EXCL); | 755 | xfs_ilock(pip, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT); |
750 | 756 | ||
751 | /* | 757 | /* |
752 | * A new AG needs to be found for the file. If the file's parent | 758 | * A new AG needs to be found for the file. If the file's parent |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b1498ab5a399..19e9dfa1c254 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -275,6 +275,7 @@ xfs_free_perag( | |||
275 | pag = radix_tree_delete(&mp->m_perag_tree, agno); | 275 | pag = radix_tree_delete(&mp->m_perag_tree, agno); |
276 | spin_unlock(&mp->m_perag_lock); | 276 | spin_unlock(&mp->m_perag_lock); |
277 | ASSERT(pag); | 277 | ASSERT(pag); |
278 | ASSERT(atomic_read(&pag->pag_ref) == 0); | ||
278 | call_rcu(&pag->rcu_head, __xfs_free_perag); | 279 | call_rcu(&pag->rcu_head, __xfs_free_perag); |
279 | } | 280 | } |
280 | } | 281 | } |
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index e0e64b113bd6..9bb6eda4cd21 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -346,8 +346,17 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid, | |||
346 | #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta) | 346 | #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta) |
347 | #define xfs_trans_apply_dquot_deltas(tp) | 347 | #define xfs_trans_apply_dquot_deltas(tp) |
348 | #define xfs_trans_unreserve_and_mod_dquots(tp) | 348 | #define xfs_trans_unreserve_and_mod_dquots(tp) |
349 | #define xfs_trans_reserve_quota_nblks(tp, ip, nblks, ninos, flags) (0) | 349 | static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp, |
350 | #define xfs_trans_reserve_quota_bydquots(tp, mp, u, g, nb, ni, fl) (0) | 350 | struct xfs_inode *ip, long nblks, long ninos, uint flags) |
351 | { | ||
352 | return 0; | ||
353 | } | ||
354 | static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp, | ||
355 | struct xfs_mount *mp, struct xfs_dquot *udqp, | ||
356 | struct xfs_dquot *gdqp, long nblks, long nions, uint flags) | ||
357 | { | ||
358 | return 0; | ||
359 | } | ||
351 | #define xfs_qm_vop_create_dqattach(tp, ip, u, g) | 360 | #define xfs_qm_vop_create_dqattach(tp, ip, u, g) |
352 | #define xfs_qm_vop_rename_dqattach(it) (0) | 361 | #define xfs_qm_vop_rename_dqattach(it) (0) |
353 | #define xfs_qm_vop_chown(tp, ip, old, new) (NULL) | 362 | #define xfs_qm_vop_chown(tp, ip, old, new) (NULL) |
@@ -357,11 +366,14 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid, | |||
357 | #define xfs_qm_dqdetach(ip) | 366 | #define xfs_qm_dqdetach(ip) |
358 | #define xfs_qm_dqrele(d) | 367 | #define xfs_qm_dqrele(d) |
359 | #define xfs_qm_statvfs(ip, s) | 368 | #define xfs_qm_statvfs(ip, s) |
360 | #define xfs_qm_sync(mp, fl) (0) | 369 | static inline int xfs_qm_sync(struct xfs_mount *mp, int flags) |
370 | { | ||
371 | return 0; | ||
372 | } | ||
361 | #define xfs_qm_newmount(mp, a, b) (0) | 373 | #define xfs_qm_newmount(mp, a, b) (0) |
362 | #define xfs_qm_mount_quotas(mp) | 374 | #define xfs_qm_mount_quotas(mp) |
363 | #define xfs_qm_unmount(mp) | 375 | #define xfs_qm_unmount(mp) |
364 | #define xfs_qm_unmount_quotas(mp) (0) | 376 | #define xfs_qm_unmount_quotas(mp) |
365 | #endif /* CONFIG_XFS_QUOTA */ | 377 | #endif /* CONFIG_XFS_QUOTA */ |
366 | 378 | ||
367 | #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \ | 379 | #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \ |
diff --git a/include/asm-generic/stat.h b/include/asm-generic/stat.h index 47e64170305d..bd8cad21998e 100644 --- a/include/asm-generic/stat.h +++ b/include/asm-generic/stat.h | |||
@@ -33,18 +33,18 @@ struct stat { | |||
33 | int st_blksize; /* Optimal block size for I/O. */ | 33 | int st_blksize; /* Optimal block size for I/O. */ |
34 | int __pad2; | 34 | int __pad2; |
35 | long st_blocks; /* Number 512-byte blocks allocated. */ | 35 | long st_blocks; /* Number 512-byte blocks allocated. */ |
36 | int st_atime; /* Time of last access. */ | 36 | long st_atime; /* Time of last access. */ |
37 | unsigned int st_atime_nsec; | 37 | unsigned long st_atime_nsec; |
38 | int st_mtime; /* Time of last modification. */ | 38 | long st_mtime; /* Time of last modification. */ |
39 | unsigned int st_mtime_nsec; | 39 | unsigned long st_mtime_nsec; |
40 | int st_ctime; /* Time of last status change. */ | 40 | long st_ctime; /* Time of last status change. */ |
41 | unsigned int st_ctime_nsec; | 41 | unsigned long st_ctime_nsec; |
42 | unsigned int __unused4; | 42 | unsigned int __unused4; |
43 | unsigned int __unused5; | 43 | unsigned int __unused5; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | #if __BITS_PER_LONG != 64 | ||
47 | /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ | 46 | /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ |
47 | #if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64) | ||
48 | struct stat64 { | 48 | struct stat64 { |
49 | unsigned long long st_dev; /* Device. */ | 49 | unsigned long long st_dev; /* Device. */ |
50 | unsigned long long st_ino; /* File serial number. */ | 50 | unsigned long long st_ino; /* File serial number. */ |
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 5afa5b52063e..beafc156a535 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h | |||
@@ -432,6 +432,10 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); | |||
432 | * together with the @destroy function, | 432 | * together with the @destroy function, |
433 | * enables driver-specific objects derived from a ttm_buffer_object. | 433 | * enables driver-specific objects derived from a ttm_buffer_object. |
434 | * On successful return, the object kref and list_kref are set to 1. | 434 | * On successful return, the object kref and list_kref are set to 1. |
435 | * If a failure occurs, the function will call the @destroy function, or | ||
436 | * kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is | ||
437 | * illegal and will likely cause memory corruption. | ||
438 | * | ||
435 | * Returns | 439 | * Returns |
436 | * -ENOMEM: Out of memory. | 440 | * -ENOMEM: Out of memory. |
437 | * -EINVAL: Invalid placement flags. | 441 | * -EINVAL: Invalid placement flags. |
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index d01b4ddbdc56..8e0c848326b6 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
@@ -206,14 +206,84 @@ struct ttm_tt { | |||
206 | struct ttm_mem_type_manager; | 206 | struct ttm_mem_type_manager; |
207 | 207 | ||
208 | struct ttm_mem_type_manager_func { | 208 | struct ttm_mem_type_manager_func { |
209 | /** | ||
210 | * struct ttm_mem_type_manager member init | ||
211 | * | ||
212 | * @man: Pointer to a memory type manager. | ||
213 | * @p_size: Implementation dependent, but typically the size of the | ||
214 | * range to be managed in pages. | ||
215 | * | ||
216 | * Called to initialize a private range manager. The function is | ||
217 | * expected to initialize the man::priv member. | ||
218 | * Returns 0 on success, negative error code on failure. | ||
219 | */ | ||
209 | int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size); | 220 | int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size); |
221 | |||
222 | /** | ||
223 | * struct ttm_mem_type_manager member takedown | ||
224 | * | ||
225 | * @man: Pointer to a memory type manager. | ||
226 | * | ||
227 | * Called to undo the setup done in init. All allocated resources | ||
228 | * should be freed. | ||
229 | */ | ||
210 | int (*takedown)(struct ttm_mem_type_manager *man); | 230 | int (*takedown)(struct ttm_mem_type_manager *man); |
231 | |||
232 | /** | ||
233 | * struct ttm_mem_type_manager member get_node | ||
234 | * | ||
235 | * @man: Pointer to a memory type manager. | ||
236 | * @bo: Pointer to the buffer object we're allocating space for. | ||
237 | * @placement: Placement details. | ||
238 | * @mem: Pointer to a struct ttm_mem_reg to be filled in. | ||
239 | * | ||
240 | * This function should allocate space in the memory type managed | ||
241 | * by @man. Placement details if | ||
242 | * applicable are given by @placement. If successful, | ||
243 | * @mem::mm_node should be set to a non-null value, and | ||
244 | * @mem::start should be set to a value identifying the beginning | ||
245 | * of the range allocated, and the function should return zero. | ||
246 | * If the memory region accomodate the buffer object, @mem::mm_node | ||
247 | * should be set to NULL, and the function should return 0. | ||
248 | * If a system error occured, preventing the request to be fulfilled, | ||
249 | * the function should return a negative error code. | ||
250 | * | ||
251 | * Note that @mem::mm_node will only be dereferenced by | ||
252 | * struct ttm_mem_type_manager functions and optionally by the driver, | ||
253 | * which has knowledge of the underlying type. | ||
254 | * | ||
255 | * This function may not be called from within atomic context, so | ||
256 | * an implementation can and must use either a mutex or a spinlock to | ||
257 | * protect any data structures managing the space. | ||
258 | */ | ||
211 | int (*get_node)(struct ttm_mem_type_manager *man, | 259 | int (*get_node)(struct ttm_mem_type_manager *man, |
212 | struct ttm_buffer_object *bo, | 260 | struct ttm_buffer_object *bo, |
213 | struct ttm_placement *placement, | 261 | struct ttm_placement *placement, |
214 | struct ttm_mem_reg *mem); | 262 | struct ttm_mem_reg *mem); |
263 | |||
264 | /** | ||
265 | * struct ttm_mem_type_manager member put_node | ||
266 | * | ||
267 | * @man: Pointer to a memory type manager. | ||
268 | * @mem: Pointer to a struct ttm_mem_reg to be filled in. | ||
269 | * | ||
270 | * This function frees memory type resources previously allocated | ||
271 | * and that are identified by @mem::mm_node and @mem::start. May not | ||
272 | * be called from within atomic context. | ||
273 | */ | ||
215 | void (*put_node)(struct ttm_mem_type_manager *man, | 274 | void (*put_node)(struct ttm_mem_type_manager *man, |
216 | struct ttm_mem_reg *mem); | 275 | struct ttm_mem_reg *mem); |
276 | |||
277 | /** | ||
278 | * struct ttm_mem_type_manager member debug | ||
279 | * | ||
280 | * @man: Pointer to a memory type manager. | ||
281 | * @prefix: Prefix to be used in printout to identify the caller. | ||
282 | * | ||
283 | * This function is called to print out the state of the memory | ||
284 | * type manager to aid debugging of out-of-memory conditions. | ||
285 | * It may not be called from within atomic context. | ||
286 | */ | ||
217 | void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); | 287 | void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); |
218 | }; | 288 | }; |
219 | 289 | ||
@@ -231,14 +301,13 @@ struct ttm_mem_type_manager { | |||
231 | uint64_t size; | 301 | uint64_t size; |
232 | uint32_t available_caching; | 302 | uint32_t available_caching; |
233 | uint32_t default_caching; | 303 | uint32_t default_caching; |
304 | const struct ttm_mem_type_manager_func *func; | ||
305 | void *priv; | ||
234 | 306 | ||
235 | /* | 307 | /* |
236 | * Protected by the bdev->lru_lock. | 308 | * Protected by the global->lru_lock. |
237 | * TODO: Consider one lru_lock per ttm_mem_type_manager. | ||
238 | * Plays ill with list removal, though. | ||
239 | */ | 309 | */ |
240 | const struct ttm_mem_type_manager_func *func; | 310 | |
241 | void *priv; | ||
242 | struct list_head lru; | 311 | struct list_head lru; |
243 | }; | 312 | }; |
244 | 313 | ||
diff --git a/include/linux/atomic.h b/include/linux/atomic.h new file mode 100644 index 000000000000..96c038e43d66 --- /dev/null +++ b/include/linux/atomic.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef _LINUX_ATOMIC_H | ||
2 | #define _LINUX_ATOMIC_H | ||
3 | #include <asm/atomic.h> | ||
4 | |||
5 | /** | ||
6 | * atomic_inc_not_zero_hint - increment if not null | ||
7 | * @v: pointer of type atomic_t | ||
8 | * @hint: probable value of the atomic before the increment | ||
9 | * | ||
10 | * This version of atomic_inc_not_zero() gives a hint of probable | ||
11 | * value of the atomic. This helps processor to not read the memory | ||
12 | * before doing the atomic read/modify/write cycle, lowering | ||
13 | * number of bus transactions on some arches. | ||
14 | * | ||
15 | * Returns: 0 if increment was not done, 1 otherwise. | ||
16 | */ | ||
17 | #ifndef atomic_inc_not_zero_hint | ||
18 | static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) | ||
19 | { | ||
20 | int val, c = hint; | ||
21 | |||
22 | /* sanity test, should be removed by compiler if hint is a constant */ | ||
23 | if (!hint) | ||
24 | return atomic_inc_not_zero(v); | ||
25 | |||
26 | do { | ||
27 | val = atomic_cmpxchg(v, c, c + 1); | ||
28 | if (val == c) | ||
29 | return 1; | ||
30 | c = val; | ||
31 | } while (c); | ||
32 | |||
33 | return 0; | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | #endif /* _LINUX_ATOMIC_H */ | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index ba679992d39b..35dcdb3589bc 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -66,10 +66,6 @@ | |||
66 | #define bio_offset(bio) bio_iovec((bio))->bv_offset | 66 | #define bio_offset(bio) bio_iovec((bio))->bv_offset |
67 | #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) | 67 | #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) |
68 | #define bio_sectors(bio) ((bio)->bi_size >> 9) | 68 | #define bio_sectors(bio) ((bio)->bi_size >> 9) |
69 | #define bio_empty_barrier(bio) \ | ||
70 | ((bio->bi_rw & REQ_HARDBARRIER) && \ | ||
71 | !bio_has_data(bio) && \ | ||
72 | !(bio->bi_rw & REQ_DISCARD)) | ||
73 | 69 | ||
74 | static inline unsigned int bio_cur_bytes(struct bio *bio) | 70 | static inline unsigned int bio_cur_bytes(struct bio *bio) |
75 | { | 71 | { |
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 0437ab6bb54c..46ad5197537a 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h | |||
@@ -122,7 +122,6 @@ enum rq_flag_bits { | |||
122 | __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ | 122 | __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ |
123 | __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ | 123 | __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ |
124 | 124 | ||
125 | __REQ_HARDBARRIER, /* may not be passed by drive either */ | ||
126 | __REQ_SYNC, /* request is sync (sync write or read) */ | 125 | __REQ_SYNC, /* request is sync (sync write or read) */ |
127 | __REQ_META, /* metadata io request */ | 126 | __REQ_META, /* metadata io request */ |
128 | __REQ_DISCARD, /* request to discard sectors */ | 127 | __REQ_DISCARD, /* request to discard sectors */ |
@@ -159,7 +158,6 @@ enum rq_flag_bits { | |||
159 | #define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV) | 158 | #define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV) |
160 | #define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT) | 159 | #define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT) |
161 | #define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) | 160 | #define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) |
162 | #define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER) | ||
163 | #define REQ_SYNC (1 << __REQ_SYNC) | 161 | #define REQ_SYNC (1 << __REQ_SYNC) |
164 | #define REQ_META (1 << __REQ_META) | 162 | #define REQ_META (1 << __REQ_META) |
165 | #define REQ_DISCARD (1 << __REQ_DISCARD) | 163 | #define REQ_DISCARD (1 << __REQ_DISCARD) |
@@ -168,8 +166,8 @@ enum rq_flag_bits { | |||
168 | #define REQ_FAILFAST_MASK \ | 166 | #define REQ_FAILFAST_MASK \ |
169 | (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) | 167 | (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) |
170 | #define REQ_COMMON_MASK \ | 168 | #define REQ_COMMON_MASK \ |
171 | (REQ_WRITE | REQ_FAILFAST_MASK | REQ_HARDBARRIER | REQ_SYNC | \ | 169 | (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ |
172 | REQ_META | REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA) | 170 | REQ_NOIDLE | REQ_FLUSH | REQ_FUA) |
173 | #define REQ_CLONE_MASK REQ_COMMON_MASK | 171 | #define REQ_CLONE_MASK REQ_COMMON_MASK |
174 | 172 | ||
175 | #define REQ_UNPLUG (1 << __REQ_UNPLUG) | 173 | #define REQ_UNPLUG (1 << __REQ_UNPLUG) |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 5027a599077d..aae86fd10c4f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -552,8 +552,7 @@ static inline void blk_clear_queue_full(struct request_queue *q, int sync) | |||
552 | * it already be started by driver. | 552 | * it already be started by driver. |
553 | */ | 553 | */ |
554 | #define RQ_NOMERGE_FLAGS \ | 554 | #define RQ_NOMERGE_FLAGS \ |
555 | (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER | \ | 555 | (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) |
556 | REQ_FLUSH | REQ_FUA) | ||
557 | #define rq_mergeable(rq) \ | 556 | #define rq_mergeable(rq) \ |
558 | (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ | 557 | (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ |
559 | (((rq)->cmd_flags & REQ_DISCARD) || \ | 558 | (((rq)->cmd_flags & REQ_DISCARD) || \ |
diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 9b2a0158f399..ef44c7a0638c 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h | |||
@@ -53,7 +53,7 @@ | |||
53 | 53 | ||
54 | 54 | ||
55 | extern const char *drbd_buildtag(void); | 55 | extern const char *drbd_buildtag(void); |
56 | #define REL_VERSION "8.3.9rc2" | 56 | #define REL_VERSION "8.3.9" |
57 | #define API_VERSION 88 | 57 | #define API_VERSION 88 |
58 | #define PRO_VERSION_MIN 86 | 58 | #define PRO_VERSION_MIN 86 |
59 | #define PRO_VERSION_MAX 95 | 59 | #define PRO_VERSION_MAX 95 |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 8a389b608ce3..41cb31f14ee3 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -96,11 +96,15 @@ | |||
96 | */ | 96 | */ |
97 | #define in_nmi() (preempt_count() & NMI_MASK) | 97 | #define in_nmi() (preempt_count() & NMI_MASK) |
98 | 98 | ||
99 | #if defined(CONFIG_PREEMPT) | 99 | #if defined(CONFIG_PREEMPT) && defined(CONFIG_BKL) |
100 | # define PREEMPT_INATOMIC_BASE kernel_locked() | 100 | # define PREEMPT_INATOMIC_BASE kernel_locked() |
101 | # define PREEMPT_CHECK_OFFSET 1 | ||
102 | #else | 101 | #else |
103 | # define PREEMPT_INATOMIC_BASE 0 | 102 | # define PREEMPT_INATOMIC_BASE 0 |
103 | #endif | ||
104 | |||
105 | #if defined(CONFIG_PREEMPT) | ||
106 | # define PREEMPT_CHECK_OFFSET 1 | ||
107 | #else | ||
104 | # define PREEMPT_CHECK_OFFSET 0 | 108 | # define PREEMPT_CHECK_OFFSET 0 |
105 | #endif | 109 | #endif |
106 | 110 | ||
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index e9138198e823..b676c585574e 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
7 | #include <linux/uaccess.h> | 7 | #include <linux/uaccess.h> |
8 | #include <linux/hardirq.h> | ||
8 | 9 | ||
9 | #include <asm/cacheflush.h> | 10 | #include <asm/cacheflush.h> |
10 | 11 | ||
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index 3c5d6b6e765c..cec17cf6cac2 100644 --- a/include/linux/i2c/adp5588.h +++ b/include/linux/i2c/adp5588.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller | 2 | * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller |
3 | * | 3 | * |
4 | * Copyright 2009 Analog Devices Inc. | 4 | * Copyright 2009-2010 Analog Devices Inc. |
5 | * | 5 | * |
6 | * Licensed under the GPL-2 or later. | 6 | * Licensed under the GPL-2 or later. |
7 | */ | 7 | */ |
@@ -77,13 +77,26 @@ | |||
77 | /* Configuration Register1 */ | 77 | /* Configuration Register1 */ |
78 | #define ADP5588_AUTO_INC (1 << 7) | 78 | #define ADP5588_AUTO_INC (1 << 7) |
79 | #define ADP5588_GPIEM_CFG (1 << 6) | 79 | #define ADP5588_GPIEM_CFG (1 << 6) |
80 | #define ADP5588_OVR_FLOW_M (1 << 5) | ||
80 | #define ADP5588_INT_CFG (1 << 4) | 81 | #define ADP5588_INT_CFG (1 << 4) |
82 | #define ADP5588_OVR_FLOW_IEN (1 << 3) | ||
83 | #define ADP5588_K_LCK_IM (1 << 2) | ||
81 | #define ADP5588_GPI_IEN (1 << 1) | 84 | #define ADP5588_GPI_IEN (1 << 1) |
85 | #define ADP5588_KE_IEN (1 << 0) | ||
82 | 86 | ||
83 | /* Interrupt Status Register */ | 87 | /* Interrupt Status Register */ |
88 | #define ADP5588_CMP2_INT (1 << 5) | ||
89 | #define ADP5588_CMP1_INT (1 << 4) | ||
90 | #define ADP5588_OVR_FLOW_INT (1 << 3) | ||
91 | #define ADP5588_K_LCK_INT (1 << 2) | ||
84 | #define ADP5588_GPI_INT (1 << 1) | 92 | #define ADP5588_GPI_INT (1 << 1) |
85 | #define ADP5588_KE_INT (1 << 0) | 93 | #define ADP5588_KE_INT (1 << 0) |
86 | 94 | ||
95 | /* Key Lock and Event Counter Register */ | ||
96 | #define ADP5588_K_LCK_EN (1 << 6) | ||
97 | #define ADP5588_LCK21 0x30 | ||
98 | #define ADP5588_KEC 0xF | ||
99 | |||
87 | #define ADP5588_MAXGPIO 18 | 100 | #define ADP5588_MAXGPIO 18 |
88 | #define ADP5588_BANK(offs) ((offs) >> 3) | 101 | #define ADP5588_BANK(offs) ((offs) >> 3) |
89 | #define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) | 102 | #define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) |
diff --git a/include/linux/input.h b/include/linux/input.h index 51af441f3a21..6ef44465db8d 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -1406,6 +1406,8 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data) | |||
1406 | int __must_check input_register_device(struct input_dev *); | 1406 | int __must_check input_register_device(struct input_dev *); |
1407 | void input_unregister_device(struct input_dev *); | 1407 | void input_unregister_device(struct input_dev *); |
1408 | 1408 | ||
1409 | void input_reset_device(struct input_dev *); | ||
1410 | |||
1409 | int __must_check input_register_handler(struct input_handler *); | 1411 | int __must_check input_register_handler(struct input_handler *); |
1410 | void input_unregister_handler(struct input_handler *); | 1412 | void input_unregister_handler(struct input_handler *); |
1411 | 1413 | ||
@@ -1421,7 +1423,7 @@ void input_release_device(struct input_handle *); | |||
1421 | int input_open_device(struct input_handle *); | 1423 | int input_open_device(struct input_handle *); |
1422 | void input_close_device(struct input_handle *); | 1424 | void input_close_device(struct input_handle *); |
1423 | 1425 | ||
1424 | int input_flush_device(struct input_handle* handle, struct file* file); | 1426 | int input_flush_device(struct input_handle *handle, struct file *file); |
1425 | 1427 | ||
1426 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); | 1428 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); |
1427 | void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value); | 1429 | void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value); |
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 3e70b21884a9..b2eee896dcbc 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h | |||
@@ -76,7 +76,6 @@ int put_io_context(struct io_context *ioc); | |||
76 | void exit_io_context(struct task_struct *task); | 76 | void exit_io_context(struct task_struct *task); |
77 | struct io_context *get_io_context(gfp_t gfp_flags, int node); | 77 | struct io_context *get_io_context(gfp_t gfp_flags, int node); |
78 | struct io_context *alloc_io_context(gfp_t gfp_flags, int node); | 78 | struct io_context *alloc_io_context(gfp_t gfp_flags, int node); |
79 | void copy_io_context(struct io_context **pdst, struct io_context **psrc); | ||
80 | #else | 79 | #else |
81 | static inline void exit_io_context(struct task_struct *task) | 80 | static inline void exit_io_context(struct task_struct *task) |
82 | { | 81 | { |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 450092c1e35f..fc3da9e4da19 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -60,7 +60,7 @@ extern const char linux_proc_banner[]; | |||
60 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) | 60 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) |
61 | #define roundup(x, y) ( \ | 61 | #define roundup(x, y) ( \ |
62 | { \ | 62 | { \ |
63 | typeof(y) __y = y; \ | 63 | const typeof(y) __y = y; \ |
64 | (((x) + (__y - 1)) / __y) * __y; \ | 64 | (((x) + (__y - 1)) / __y) * __y; \ |
65 | } \ | 65 | } \ |
66 | ) | 66 | ) |
@@ -293,6 +293,7 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | |||
293 | unsigned int interval_msec); | 293 | unsigned int interval_msec); |
294 | 294 | ||
295 | extern int printk_delay_msec; | 295 | extern int printk_delay_msec; |
296 | extern int dmesg_restrict; | ||
296 | 297 | ||
297 | /* | 298 | /* |
298 | * Print a one-time message (analogous to WARN_ONCE() et al): | 299 | * Print a one-time message (analogous to WARN_ONCE() et al): |
diff --git a/include/linux/leds-lp5521.h b/include/linux/leds-lp5521.h new file mode 100644 index 000000000000..38368d785f08 --- /dev/null +++ b/include/linux/leds-lp5521.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * LP5521 LED chip driver. | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_LP5521_H | ||
24 | #define __LINUX_LP5521_H | ||
25 | |||
26 | /* See Documentation/leds/leds-lp5521.txt */ | ||
27 | |||
28 | struct lp5521_led_config { | ||
29 | u8 chan_nr; | ||
30 | u8 led_current; /* mA x10, 0 if led is not connected */ | ||
31 | u8 max_current; | ||
32 | }; | ||
33 | |||
34 | #define LP5521_CLOCK_AUTO 0 | ||
35 | #define LP5521_CLOCK_INT 1 | ||
36 | #define LP5521_CLOCK_EXT 2 | ||
37 | |||
38 | struct lp5521_platform_data { | ||
39 | struct lp5521_led_config *led_config; | ||
40 | u8 num_channels; | ||
41 | u8 clock_mode; | ||
42 | int (*setup_resources)(void); | ||
43 | void (*release_resources)(void); | ||
44 | void (*enable)(bool state); | ||
45 | }; | ||
46 | |||
47 | #endif /* __LINUX_LP5521_H */ | ||
diff --git a/include/linux/leds-lp5523.h b/include/linux/leds-lp5523.h new file mode 100644 index 000000000000..796747637b80 --- /dev/null +++ b/include/linux/leds-lp5523.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * LP5523 LED Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_LP5523_H | ||
24 | #define __LINUX_LP5523_H | ||
25 | |||
26 | /* See Documentation/leds/leds-lp5523.txt */ | ||
27 | |||
28 | struct lp5523_led_config { | ||
29 | u8 chan_nr; | ||
30 | u8 led_current; /* mA x10, 0 if led is not connected */ | ||
31 | u8 max_current; | ||
32 | }; | ||
33 | |||
34 | #define LP5523_CLOCK_AUTO 0 | ||
35 | #define LP5523_CLOCK_INT 1 | ||
36 | #define LP5523_CLOCK_EXT 2 | ||
37 | |||
38 | struct lp5523_platform_data { | ||
39 | struct lp5523_led_config *led_config; | ||
40 | u8 num_channels; | ||
41 | u8 clock_mode; | ||
42 | int (*setup_resources)(void); | ||
43 | void (*release_resources)(void); | ||
44 | void (*enable)(bool state); | ||
45 | }; | ||
46 | |||
47 | #endif /* __LINUX_LP5523_H */ | ||
diff --git a/include/linux/leds.h b/include/linux/leds.h index ba6986a11663..0f19df9e37b0 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/rwsem.h> | 17 | #include <linux/rwsem.h> |
18 | #include <linux/timer.h> | ||
18 | 19 | ||
19 | struct device; | 20 | struct device; |
20 | /* | 21 | /* |
@@ -45,10 +46,14 @@ struct led_classdev { | |||
45 | /* Get LED brightness level */ | 46 | /* Get LED brightness level */ |
46 | enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); | 47 | enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); |
47 | 48 | ||
48 | /* Activate hardware accelerated blink, delays are in | 49 | /* |
49 | * miliseconds and if none is provided then a sensible default | 50 | * Activate hardware accelerated blink, delays are in milliseconds |
50 | * should be chosen. The call can adjust the timings if it can't | 51 | * and if both are zero then a sensible default should be chosen. |
51 | * match the values specified exactly. */ | 52 | * The call should adjust the timings in that case and if it can't |
53 | * match the values specified exactly. | ||
54 | * Deactivate blinking again when the brightness is set to a fixed | ||
55 | * value via the brightness_set() callback. | ||
56 | */ | ||
52 | int (*blink_set)(struct led_classdev *led_cdev, | 57 | int (*blink_set)(struct led_classdev *led_cdev, |
53 | unsigned long *delay_on, | 58 | unsigned long *delay_on, |
54 | unsigned long *delay_off); | 59 | unsigned long *delay_off); |
@@ -57,6 +62,10 @@ struct led_classdev { | |||
57 | struct list_head node; /* LED Device list */ | 62 | struct list_head node; /* LED Device list */ |
58 | const char *default_trigger; /* Trigger to use */ | 63 | const char *default_trigger; /* Trigger to use */ |
59 | 64 | ||
65 | unsigned long blink_delay_on, blink_delay_off; | ||
66 | struct timer_list blink_timer; | ||
67 | int blink_brightness; | ||
68 | |||
60 | #ifdef CONFIG_LEDS_TRIGGERS | 69 | #ifdef CONFIG_LEDS_TRIGGERS |
61 | /* Protects the trigger data below */ | 70 | /* Protects the trigger data below */ |
62 | struct rw_semaphore trigger_lock; | 71 | struct rw_semaphore trigger_lock; |
@@ -73,6 +82,36 @@ extern void led_classdev_unregister(struct led_classdev *led_cdev); | |||
73 | extern void led_classdev_suspend(struct led_classdev *led_cdev); | 82 | extern void led_classdev_suspend(struct led_classdev *led_cdev); |
74 | extern void led_classdev_resume(struct led_classdev *led_cdev); | 83 | extern void led_classdev_resume(struct led_classdev *led_cdev); |
75 | 84 | ||
85 | /** | ||
86 | * led_blink_set - set blinking with software fallback | ||
87 | * @led_cdev: the LED to start blinking | ||
88 | * @delay_on: the time it should be on (in ms) | ||
89 | * @delay_off: the time it should ble off (in ms) | ||
90 | * | ||
91 | * This function makes the LED blink, attempting to use the | ||
92 | * hardware acceleration if possible, but falling back to | ||
93 | * software blinking if there is no hardware blinking or if | ||
94 | * the LED refuses the passed values. | ||
95 | * | ||
96 | * Note that if software blinking is active, simply calling | ||
97 | * led_cdev->brightness_set() will not stop the blinking, | ||
98 | * use led_classdev_brightness_set() instead. | ||
99 | */ | ||
100 | extern void led_blink_set(struct led_classdev *led_cdev, | ||
101 | unsigned long *delay_on, | ||
102 | unsigned long *delay_off); | ||
103 | /** | ||
104 | * led_brightness_set - set LED brightness | ||
105 | * @led_cdev: the LED to set | ||
106 | * @brightness: the brightness to set it to | ||
107 | * | ||
108 | * Set an LED's brightness, and, if necessary, cancel the | ||
109 | * software blink timer that implements blinking when the | ||
110 | * hardware doesn't. | ||
111 | */ | ||
112 | extern void led_brightness_set(struct led_classdev *led_cdev, | ||
113 | enum led_brightness brightness); | ||
114 | |||
76 | /* | 115 | /* |
77 | * LED Triggers | 116 | * LED Triggers |
78 | */ | 117 | */ |
diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index d19e2114fd86..5c99da1078aa 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h | |||
@@ -59,19 +59,19 @@ struct sh_mmcif_plat_data { | |||
59 | #define MMCIF_CE_HOST_STS2 0x0000004C | 59 | #define MMCIF_CE_HOST_STS2 0x0000004C |
60 | #define MMCIF_CE_VERSION 0x0000007C | 60 | #define MMCIF_CE_VERSION 0x0000007C |
61 | 61 | ||
62 | extern inline u32 sh_mmcif_readl(void __iomem *addr, int reg) | 62 | static inline u32 sh_mmcif_readl(void __iomem *addr, int reg) |
63 | { | 63 | { |
64 | return readl(addr + reg); | 64 | return readl(addr + reg); |
65 | } | 65 | } |
66 | 66 | ||
67 | extern inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val) | 67 | static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val) |
68 | { | 68 | { |
69 | writel(val, addr + reg); | 69 | writel(val, addr + reg); |
70 | } | 70 | } |
71 | 71 | ||
72 | #define SH_MMCIF_BBS 512 /* boot block size */ | 72 | #define SH_MMCIF_BBS 512 /* boot block size */ |
73 | 73 | ||
74 | extern inline void sh_mmcif_boot_cmd_send(void __iomem *base, | 74 | static inline void sh_mmcif_boot_cmd_send(void __iomem *base, |
75 | unsigned long cmd, unsigned long arg) | 75 | unsigned long cmd, unsigned long arg) |
76 | { | 76 | { |
77 | sh_mmcif_writel(base, MMCIF_CE_INT, 0); | 77 | sh_mmcif_writel(base, MMCIF_CE_INT, 0); |
@@ -79,7 +79,7 @@ extern inline void sh_mmcif_boot_cmd_send(void __iomem *base, | |||
79 | sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd); | 79 | sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd); |
80 | } | 80 | } |
81 | 81 | ||
82 | extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) | 82 | static inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) |
83 | { | 83 | { |
84 | unsigned long tmp; | 84 | unsigned long tmp; |
85 | int cnt; | 85 | int cnt; |
@@ -95,14 +95,14 @@ extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) | |||
95 | return -1; | 95 | return -1; |
96 | } | 96 | } |
97 | 97 | ||
98 | extern inline int sh_mmcif_boot_cmd(void __iomem *base, | 98 | static inline int sh_mmcif_boot_cmd(void __iomem *base, |
99 | unsigned long cmd, unsigned long arg) | 99 | unsigned long cmd, unsigned long arg) |
100 | { | 100 | { |
101 | sh_mmcif_boot_cmd_send(base, cmd, arg); | 101 | sh_mmcif_boot_cmd_send(base, cmd, arg); |
102 | return sh_mmcif_boot_cmd_poll(base, 0x00010000); | 102 | return sh_mmcif_boot_cmd_poll(base, 0x00010000); |
103 | } | 103 | } |
104 | 104 | ||
105 | extern inline int sh_mmcif_boot_do_read_single(void __iomem *base, | 105 | static inline int sh_mmcif_boot_do_read_single(void __iomem *base, |
106 | unsigned int block_nr, | 106 | unsigned int block_nr, |
107 | unsigned long *buf) | 107 | unsigned long *buf) |
108 | { | 108 | { |
@@ -125,7 +125,7 @@ extern inline int sh_mmcif_boot_do_read_single(void __iomem *base, | |||
125 | return 0; | 125 | return 0; |
126 | } | 126 | } |
127 | 127 | ||
128 | extern inline int sh_mmcif_boot_do_read(void __iomem *base, | 128 | static inline int sh_mmcif_boot_do_read(void __iomem *base, |
129 | unsigned long first_block, | 129 | unsigned long first_block, |
130 | unsigned long nr_blocks, | 130 | unsigned long nr_blocks, |
131 | void *buf) | 131 | void *buf) |
@@ -143,7 +143,7 @@ extern inline int sh_mmcif_boot_do_read(void __iomem *base, | |||
143 | return ret; | 143 | return ret; |
144 | } | 144 | } |
145 | 145 | ||
146 | extern inline void sh_mmcif_boot_init(void __iomem *base) | 146 | static inline void sh_mmcif_boot_init(void __iomem *base) |
147 | { | 147 | { |
148 | unsigned long tmp; | 148 | unsigned long tmp; |
149 | 149 | ||
@@ -177,7 +177,7 @@ extern inline void sh_mmcif_boot_init(void __iomem *base) | |||
177 | sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000); | 177 | sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000); |
178 | } | 178 | } |
179 | 179 | ||
180 | extern inline void sh_mmcif_boot_slurp(void __iomem *base, | 180 | static inline void sh_mmcif_boot_slurp(void __iomem *base, |
181 | unsigned char *buf, | 181 | unsigned char *buf, |
182 | unsigned long no_bytes) | 182 | unsigned long no_bytes) |
183 | { | 183 | { |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 057bf22a8323..40150f345982 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -747,6 +747,16 @@ struct perf_event { | |||
747 | u64 tstamp_running; | 747 | u64 tstamp_running; |
748 | u64 tstamp_stopped; | 748 | u64 tstamp_stopped; |
749 | 749 | ||
750 | /* | ||
751 | * timestamp shadows the actual context timing but it can | ||
752 | * be safely used in NMI interrupt context. It reflects the | ||
753 | * context time as it was when the event was last scheduled in. | ||
754 | * | ||
755 | * ctx_time already accounts for ctx->timestamp. Therefore to | ||
756 | * compute ctx_time for a sample, simply add perf_clock(). | ||
757 | */ | ||
758 | u64 shadow_ctx_time; | ||
759 | |||
750 | struct perf_event_attr attr; | 760 | struct perf_event_attr attr; |
751 | struct hw_perf_event hw; | 761 | struct hw_perf_event hw; |
752 | 762 | ||
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index 01b3d759f1fc..e031e1a486d9 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h | |||
@@ -8,6 +8,7 @@ struct platform_pwm_backlight_data { | |||
8 | int pwm_id; | 8 | int pwm_id; |
9 | unsigned int max_brightness; | 9 | unsigned int max_brightness; |
10 | unsigned int dft_brightness; | 10 | unsigned int dft_brightness; |
11 | unsigned int lth_brightness; | ||
11 | unsigned int pwm_period_ns; | 12 | unsigned int pwm_period_ns; |
12 | int (*init)(struct device *dev); | 13 | int (*init)(struct device *dev); |
13 | int (*notify)(struct device *dev, int brightness); | 14 | int (*notify)(struct device *dev, int brightness); |
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index a39cbed9ee17..ab2baa5c4884 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -34,19 +34,13 @@ | |||
34 | * needed for RCU lookups (because root->height is unreliable). The only | 34 | * needed for RCU lookups (because root->height is unreliable). The only |
35 | * time callers need worry about this is when doing a lookup_slot under | 35 | * time callers need worry about this is when doing a lookup_slot under |
36 | * RCU. | 36 | * RCU. |
37 | * | ||
38 | * Indirect pointer in fact is also used to tag the last pointer of a node | ||
39 | * when it is shrunk, before we rcu free the node. See shrink code for | ||
40 | * details. | ||
37 | */ | 41 | */ |
38 | #define RADIX_TREE_INDIRECT_PTR 1 | 42 | #define RADIX_TREE_INDIRECT_PTR 1 |
39 | #define RADIX_TREE_RETRY ((void *)-1UL) | ||
40 | |||
41 | static inline void *radix_tree_ptr_to_indirect(void *ptr) | ||
42 | { | ||
43 | return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); | ||
44 | } | ||
45 | 43 | ||
46 | static inline void *radix_tree_indirect_to_ptr(void *ptr) | ||
47 | { | ||
48 | return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); | ||
49 | } | ||
50 | #define radix_tree_indirect_to_ptr(ptr) \ | 44 | #define radix_tree_indirect_to_ptr(ptr) \ |
51 | radix_tree_indirect_to_ptr((void __force *)(ptr)) | 45 | radix_tree_indirect_to_ptr((void __force *)(ptr)) |
52 | 46 | ||
@@ -140,16 +134,29 @@ do { \ | |||
140 | * removed. | 134 | * removed. |
141 | * | 135 | * |
142 | * For use with radix_tree_lookup_slot(). Caller must hold tree at least read | 136 | * For use with radix_tree_lookup_slot(). Caller must hold tree at least read |
143 | * locked across slot lookup and dereference. More likely, will be used with | 137 | * locked across slot lookup and dereference. Not required if write lock is |
144 | * radix_tree_replace_slot(), as well, so caller will hold tree write locked. | 138 | * held (ie. items cannot be concurrently inserted). |
139 | * | ||
140 | * radix_tree_deref_retry must be used to confirm validity of the pointer if | ||
141 | * only the read lock is held. | ||
145 | */ | 142 | */ |
146 | static inline void *radix_tree_deref_slot(void **pslot) | 143 | static inline void *radix_tree_deref_slot(void **pslot) |
147 | { | 144 | { |
148 | void *ret = rcu_dereference(*pslot); | 145 | return rcu_dereference(*pslot); |
149 | if (unlikely(radix_tree_is_indirect_ptr(ret))) | ||
150 | ret = RADIX_TREE_RETRY; | ||
151 | return ret; | ||
152 | } | 146 | } |
147 | |||
148 | /** | ||
149 | * radix_tree_deref_retry - check radix_tree_deref_slot | ||
150 | * @arg: pointer returned by radix_tree_deref_slot | ||
151 | * Returns: 0 if retry is not required, otherwise retry is required | ||
152 | * | ||
153 | * radix_tree_deref_retry must be used with radix_tree_deref_slot. | ||
154 | */ | ||
155 | static inline int radix_tree_deref_retry(void *arg) | ||
156 | { | ||
157 | return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR); | ||
158 | } | ||
159 | |||
153 | /** | 160 | /** |
154 | * radix_tree_replace_slot - replace item in a slot | 161 | * radix_tree_replace_slot - replace item in a slot |
155 | * @pslot: pointer to slot, returned by radix_tree_lookup_slot | 162 | * @pslot: pointer to slot, returned by radix_tree_lookup_slot |
diff --git a/include/linux/resource.h b/include/linux/resource.h index 88d36f9145ba..d01c96c1966e 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _LINUX_RESOURCE_H | 2 | #define _LINUX_RESOURCE_H |
3 | 3 | ||
4 | #include <linux/time.h> | 4 | #include <linux/time.h> |
5 | #include <linux/types.h> | ||
5 | 6 | ||
6 | /* | 7 | /* |
7 | * Resource control/accounting header file for linux | 8 | * Resource control/accounting header file for linux |
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 4dca992f3093..cea0c38e7a63 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h | |||
@@ -122,6 +122,10 @@ int clk_rate_table_find(struct clk *clk, | |||
122 | long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, | 122 | long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, |
123 | unsigned int div_max, unsigned long rate); | 123 | unsigned int div_max, unsigned long rate); |
124 | 124 | ||
125 | long clk_round_parent(struct clk *clk, unsigned long target, | ||
126 | unsigned long *best_freq, unsigned long *parent_freq, | ||
127 | unsigned int div_min, unsigned int div_max); | ||
128 | |||
125 | #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ | 129 | #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ |
126 | { \ | 130 | { \ |
127 | .parent = _parent, \ | 131 | .parent = _parent, \ |
diff --git a/include/linux/sh_timer.h b/include/linux/sh_timer.h index 864bd56bd3b0..4d9dcd138315 100644 --- a/include/linux/sh_timer.h +++ b/include/linux/sh_timer.h | |||
@@ -5,7 +5,6 @@ struct sh_timer_config { | |||
5 | char *name; | 5 | char *name; |
6 | long channel_offset; | 6 | long channel_offset; |
7 | int timer_bit; | 7 | int timer_bit; |
8 | char *clk; | ||
9 | unsigned long clockevent_rating; | 8 | unsigned long clockevent_rating; |
10 | unsigned long clocksource_rating; | 9 | unsigned long clocksource_rating; |
11 | }; | 10 | }; |
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index bbdb680ffbe9..aea0d438e3c7 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h | |||
@@ -82,18 +82,28 @@ struct svc_xprt { | |||
82 | struct net *xpt_net; | 82 | struct net *xpt_net; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static inline void register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) | 85 | static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) |
86 | { | 86 | { |
87 | spin_lock(&xpt->xpt_lock); | 87 | spin_lock(&xpt->xpt_lock); |
88 | list_add(&u->list, &xpt->xpt_users); | 88 | list_del_init(&u->list); |
89 | spin_unlock(&xpt->xpt_lock); | 89 | spin_unlock(&xpt->xpt_lock); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) | 92 | static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) |
93 | { | 93 | { |
94 | spin_lock(&xpt->xpt_lock); | 94 | spin_lock(&xpt->xpt_lock); |
95 | list_del_init(&u->list); | 95 | if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) { |
96 | /* | ||
97 | * The connection is about to be deleted soon (or, | ||
98 | * worse, may already be deleted--in which case we've | ||
99 | * already notified the xpt_users). | ||
100 | */ | ||
101 | spin_unlock(&xpt->xpt_lock); | ||
102 | return -ENOTCONN; | ||
103 | } | ||
104 | list_add(&u->list, &xpt->xpt_users); | ||
96 | spin_unlock(&xpt->xpt_lock); | 105 | spin_unlock(&xpt->xpt_lock); |
106 | return 0; | ||
97 | } | 107 | } |
98 | 108 | ||
99 | int svc_reg_xprt_class(struct svc_xprt_class *); | 109 | int svc_reg_xprt_class(struct svc_xprt_class *); |
diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h index 6da573c75d54..8eff83b95366 100644 --- a/include/net/caif/caif_dev.h +++ b/include/net/caif/caif_dev.h | |||
@@ -28,7 +28,7 @@ struct caif_param { | |||
28 | * @sockaddr: Socket address to connect. | 28 | * @sockaddr: Socket address to connect. |
29 | * @priority: Priority of the connection. | 29 | * @priority: Priority of the connection. |
30 | * @link_selector: Link selector (high bandwidth or low latency) | 30 | * @link_selector: Link selector (high bandwidth or low latency) |
31 | * @link_name: Name of the CAIF Link Layer to use. | 31 | * @ifindex: kernel index of the interface. |
32 | * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). | 32 | * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). |
33 | * | 33 | * |
34 | * This struct is used when connecting a CAIF channel. | 34 | * This struct is used when connecting a CAIF channel. |
@@ -39,7 +39,7 @@ struct caif_connect_request { | |||
39 | struct sockaddr_caif sockaddr; | 39 | struct sockaddr_caif sockaddr; |
40 | enum caif_channel_priority priority; | 40 | enum caif_channel_priority priority; |
41 | enum caif_link_selector link_selector; | 41 | enum caif_link_selector link_selector; |
42 | char link_name[16]; | 42 | int ifindex; |
43 | struct caif_param param; | 43 | struct caif_param param; |
44 | }; | 44 | }; |
45 | 45 | ||
diff --git a/include/net/caif/caif_spi.h b/include/net/caif/caif_spi.h index ce4570dff020..87c3d11b8e55 100644 --- a/include/net/caif/caif_spi.h +++ b/include/net/caif/caif_spi.h | |||
@@ -121,6 +121,8 @@ struct cfspi { | |||
121 | wait_queue_head_t wait; | 121 | wait_queue_head_t wait; |
122 | spinlock_t lock; | 122 | spinlock_t lock; |
123 | bool flow_stop; | 123 | bool flow_stop; |
124 | bool slave; | ||
125 | bool slave_talked; | ||
124 | #ifdef CONFIG_DEBUG_FS | 126 | #ifdef CONFIG_DEBUG_FS |
125 | enum cfspi_state dbg_state; | 127 | enum cfspi_state dbg_state; |
126 | u16 pcmd; | 128 | u16 pcmd; |
diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h index bd646faffa47..f688478bfb84 100644 --- a/include/net/caif/cfcnfg.h +++ b/include/net/caif/cfcnfg.h | |||
@@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, | |||
139 | enum cfcnfg_phy_preference phy_pref); | 139 | enum cfcnfg_phy_preference phy_pref); |
140 | 140 | ||
141 | /** | 141 | /** |
142 | * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer | 142 | * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex, |
143 | * it matches caif physical id with the kernel interface id. | ||
143 | * @cnfg: Configuration object | 144 | * @cnfg: Configuration object |
144 | * @name: Name of the Physical Layer (Caif Link Layer) | 145 | * @ifi: ifindex obtained from socket.c bindtodevice. |
145 | */ | 146 | */ |
146 | int cfcnfg_get_named(struct cfcnfg *cnfg, char *name); | 147 | int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi); |
147 | |||
148 | #endif /* CFCNFG_H_ */ | 148 | #endif /* CFCNFG_H_ */ |
diff --git a/include/net/netlink.h b/include/net/netlink.h index f3b201d335b3..9801c55de5d6 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
@@ -384,7 +384,7 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, | |||
384 | * | 384 | * |
385 | * Returns the first attribute which matches the specified type. | 385 | * Returns the first attribute which matches the specified type. |
386 | */ | 386 | */ |
387 | static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, | 387 | static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, |
388 | int hdrlen, int attrtype) | 388 | int hdrlen, int attrtype) |
389 | { | 389 | { |
390 | return nla_find(nlmsg_attrdata(nlh, hdrlen), | 390 | return nla_find(nlmsg_attrdata(nlh, hdrlen), |
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 289010d3270b..e5e345fb2a5c 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h | |||
@@ -98,6 +98,103 @@ TRACE_EVENT(ext4_allocate_inode, | |||
98 | (unsigned long) __entry->dir, __entry->mode) | 98 | (unsigned long) __entry->dir, __entry->mode) |
99 | ); | 99 | ); |
100 | 100 | ||
101 | TRACE_EVENT(ext4_evict_inode, | ||
102 | TP_PROTO(struct inode *inode), | ||
103 | |||
104 | TP_ARGS(inode), | ||
105 | |||
106 | TP_STRUCT__entry( | ||
107 | __field( int, dev_major ) | ||
108 | __field( int, dev_minor ) | ||
109 | __field( ino_t, ino ) | ||
110 | __field( int, nlink ) | ||
111 | ), | ||
112 | |||
113 | TP_fast_assign( | ||
114 | __entry->dev_major = MAJOR(inode->i_sb->s_dev); | ||
115 | __entry->dev_minor = MINOR(inode->i_sb->s_dev); | ||
116 | __entry->ino = inode->i_ino; | ||
117 | __entry->nlink = inode->i_nlink; | ||
118 | ), | ||
119 | |||
120 | TP_printk("dev %d,%d ino %lu nlink %d", | ||
121 | __entry->dev_major, __entry->dev_minor, | ||
122 | (unsigned long) __entry->ino, __entry->nlink) | ||
123 | ); | ||
124 | |||
125 | TRACE_EVENT(ext4_drop_inode, | ||
126 | TP_PROTO(struct inode *inode, int drop), | ||
127 | |||
128 | TP_ARGS(inode, drop), | ||
129 | |||
130 | TP_STRUCT__entry( | ||
131 | __field( int, dev_major ) | ||
132 | __field( int, dev_minor ) | ||
133 | __field( ino_t, ino ) | ||
134 | __field( int, drop ) | ||
135 | ), | ||
136 | |||
137 | TP_fast_assign( | ||
138 | __entry->dev_major = MAJOR(inode->i_sb->s_dev); | ||
139 | __entry->dev_minor = MINOR(inode->i_sb->s_dev); | ||
140 | __entry->ino = inode->i_ino; | ||
141 | __entry->drop = drop; | ||
142 | ), | ||
143 | |||
144 | TP_printk("dev %d,%d ino %lu drop %d", | ||
145 | __entry->dev_major, __entry->dev_minor, | ||
146 | (unsigned long) __entry->ino, __entry->drop) | ||
147 | ); | ||
148 | |||
149 | TRACE_EVENT(ext4_mark_inode_dirty, | ||
150 | TP_PROTO(struct inode *inode, unsigned long IP), | ||
151 | |||
152 | TP_ARGS(inode, IP), | ||
153 | |||
154 | TP_STRUCT__entry( | ||
155 | __field( int, dev_major ) | ||
156 | __field( int, dev_minor ) | ||
157 | __field( ino_t, ino ) | ||
158 | __field(unsigned long, ip ) | ||
159 | ), | ||
160 | |||
161 | TP_fast_assign( | ||
162 | __entry->dev_major = MAJOR(inode->i_sb->s_dev); | ||
163 | __entry->dev_minor = MINOR(inode->i_sb->s_dev); | ||
164 | __entry->ino = inode->i_ino; | ||
165 | __entry->ip = IP; | ||
166 | ), | ||
167 | |||
168 | TP_printk("dev %d,%d ino %lu caller %pF", | ||
169 | __entry->dev_major, __entry->dev_minor, | ||
170 | (unsigned long) __entry->ino, (void *)__entry->ip) | ||
171 | ); | ||
172 | |||
173 | TRACE_EVENT(ext4_begin_ordered_truncate, | ||
174 | TP_PROTO(struct inode *inode, loff_t new_size), | ||
175 | |||
176 | TP_ARGS(inode, new_size), | ||
177 | |||
178 | TP_STRUCT__entry( | ||
179 | __field( int, dev_major ) | ||
180 | __field( int, dev_minor ) | ||
181 | __field( ino_t, ino ) | ||
182 | __field( loff_t, new_size ) | ||
183 | ), | ||
184 | |||
185 | TP_fast_assign( | ||
186 | __entry->dev_major = MAJOR(inode->i_sb->s_dev); | ||
187 | __entry->dev_minor = MINOR(inode->i_sb->s_dev); | ||
188 | __entry->ino = inode->i_ino; | ||
189 | __entry->new_size = new_size; | ||
190 | ), | ||
191 | |||
192 | TP_printk("dev %d,%d ino %lu new_size %lld", | ||
193 | __entry->dev_major, __entry->dev_minor, | ||
194 | (unsigned long) __entry->ino, | ||
195 | (long long) __entry->new_size) | ||
196 | ); | ||
197 | |||
101 | DECLARE_EVENT_CLASS(ext4__write_begin, | 198 | DECLARE_EVENT_CLASS(ext4__write_begin, |
102 | 199 | ||
103 | TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, | 200 | TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, |
diff --git a/kernel/exit.c b/kernel/exit.c index b194febf5799..21aa7b3001fb 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -96,6 +96,14 @@ static void __exit_signal(struct task_struct *tsk) | |||
96 | sig->tty = NULL; | 96 | sig->tty = NULL; |
97 | } else { | 97 | } else { |
98 | /* | 98 | /* |
99 | * This can only happen if the caller is de_thread(). | ||
100 | * FIXME: this is the temporary hack, we should teach | ||
101 | * posix-cpu-timers to handle this case correctly. | ||
102 | */ | ||
103 | if (unlikely(has_group_leader_pid(tsk))) | ||
104 | posix_cpu_timers_exit_group(tsk); | ||
105 | |||
106 | /* | ||
99 | * If there is any task waiting for the group exit | 107 | * If there is any task waiting for the group exit |
100 | * then notify it: | 108 | * then notify it: |
101 | */ | 109 | */ |
diff --git a/kernel/latencytop.c b/kernel/latencytop.c index 877fb306d415..17110a4a4fc2 100644 --- a/kernel/latencytop.c +++ b/kernel/latencytop.c | |||
@@ -194,14 +194,7 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) | |||
194 | 194 | ||
195 | account_global_scheduler_latency(tsk, &lat); | 195 | account_global_scheduler_latency(tsk, &lat); |
196 | 196 | ||
197 | /* | 197 | for (i = 0; i < tsk->latency_record_count; i++) { |
198 | * short term hack; if we're > 32 we stop; future we recycle: | ||
199 | */ | ||
200 | tsk->latency_record_count++; | ||
201 | if (tsk->latency_record_count >= LT_SAVECOUNT) | ||
202 | goto out_unlock; | ||
203 | |||
204 | for (i = 0; i < LT_SAVECOUNT; i++) { | ||
205 | struct latency_record *mylat; | 198 | struct latency_record *mylat; |
206 | int same = 1; | 199 | int same = 1; |
207 | 200 | ||
@@ -227,8 +220,14 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) | |||
227 | } | 220 | } |
228 | } | 221 | } |
229 | 222 | ||
223 | /* | ||
224 | * short term hack; if we're > 32 we stop; future we recycle: | ||
225 | */ | ||
226 | if (tsk->latency_record_count >= LT_SAVECOUNT) | ||
227 | goto out_unlock; | ||
228 | |||
230 | /* Allocated a new one: */ | 229 | /* Allocated a new one: */ |
231 | i = tsk->latency_record_count; | 230 | i = tsk->latency_record_count++; |
232 | memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record)); | 231 | memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record)); |
233 | 232 | ||
234 | out_unlock: | 233 | out_unlock: |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 517d827f4982..cb6c0d2af68f 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -674,6 +674,8 @@ event_sched_in(struct perf_event *event, | |||
674 | 674 | ||
675 | event->tstamp_running += ctx->time - event->tstamp_stopped; | 675 | event->tstamp_running += ctx->time - event->tstamp_stopped; |
676 | 676 | ||
677 | event->shadow_ctx_time = ctx->time - ctx->timestamp; | ||
678 | |||
677 | if (!is_software_event(event)) | 679 | if (!is_software_event(event)) |
678 | cpuctx->active_oncpu++; | 680 | cpuctx->active_oncpu++; |
679 | ctx->nr_active++; | 681 | ctx->nr_active++; |
@@ -3396,7 +3398,8 @@ static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) | |||
3396 | } | 3398 | } |
3397 | 3399 | ||
3398 | static void perf_output_read_one(struct perf_output_handle *handle, | 3400 | static void perf_output_read_one(struct perf_output_handle *handle, |
3399 | struct perf_event *event) | 3401 | struct perf_event *event, |
3402 | u64 enabled, u64 running) | ||
3400 | { | 3403 | { |
3401 | u64 read_format = event->attr.read_format; | 3404 | u64 read_format = event->attr.read_format; |
3402 | u64 values[4]; | 3405 | u64 values[4]; |
@@ -3404,11 +3407,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, | |||
3404 | 3407 | ||
3405 | values[n++] = perf_event_count(event); | 3408 | values[n++] = perf_event_count(event); |
3406 | if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { | 3409 | if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { |
3407 | values[n++] = event->total_time_enabled + | 3410 | values[n++] = enabled + |
3408 | atomic64_read(&event->child_total_time_enabled); | 3411 | atomic64_read(&event->child_total_time_enabled); |
3409 | } | 3412 | } |
3410 | if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { | 3413 | if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { |
3411 | values[n++] = event->total_time_running + | 3414 | values[n++] = running + |
3412 | atomic64_read(&event->child_total_time_running); | 3415 | atomic64_read(&event->child_total_time_running); |
3413 | } | 3416 | } |
3414 | if (read_format & PERF_FORMAT_ID) | 3417 | if (read_format & PERF_FORMAT_ID) |
@@ -3421,7 +3424,8 @@ static void perf_output_read_one(struct perf_output_handle *handle, | |||
3421 | * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. | 3424 | * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. |
3422 | */ | 3425 | */ |
3423 | static void perf_output_read_group(struct perf_output_handle *handle, | 3426 | static void perf_output_read_group(struct perf_output_handle *handle, |
3424 | struct perf_event *event) | 3427 | struct perf_event *event, |
3428 | u64 enabled, u64 running) | ||
3425 | { | 3429 | { |
3426 | struct perf_event *leader = event->group_leader, *sub; | 3430 | struct perf_event *leader = event->group_leader, *sub; |
3427 | u64 read_format = event->attr.read_format; | 3431 | u64 read_format = event->attr.read_format; |
@@ -3431,10 +3435,10 @@ static void perf_output_read_group(struct perf_output_handle *handle, | |||
3431 | values[n++] = 1 + leader->nr_siblings; | 3435 | values[n++] = 1 + leader->nr_siblings; |
3432 | 3436 | ||
3433 | if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) | 3437 | if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) |
3434 | values[n++] = leader->total_time_enabled; | 3438 | values[n++] = enabled; |
3435 | 3439 | ||
3436 | if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) | 3440 | if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) |
3437 | values[n++] = leader->total_time_running; | 3441 | values[n++] = running; |
3438 | 3442 | ||
3439 | if (leader != event) | 3443 | if (leader != event) |
3440 | leader->pmu->read(leader); | 3444 | leader->pmu->read(leader); |
@@ -3459,13 +3463,35 @@ static void perf_output_read_group(struct perf_output_handle *handle, | |||
3459 | } | 3463 | } |
3460 | } | 3464 | } |
3461 | 3465 | ||
3466 | #define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\ | ||
3467 | PERF_FORMAT_TOTAL_TIME_RUNNING) | ||
3468 | |||
3462 | static void perf_output_read(struct perf_output_handle *handle, | 3469 | static void perf_output_read(struct perf_output_handle *handle, |
3463 | struct perf_event *event) | 3470 | struct perf_event *event) |
3464 | { | 3471 | { |
3472 | u64 enabled = 0, running = 0, now, ctx_time; | ||
3473 | u64 read_format = event->attr.read_format; | ||
3474 | |||
3475 | /* | ||
3476 | * compute total_time_enabled, total_time_running | ||
3477 | * based on snapshot values taken when the event | ||
3478 | * was last scheduled in. | ||
3479 | * | ||
3480 | * we cannot simply called update_context_time() | ||
3481 | * because of locking issue as we are called in | ||
3482 | * NMI context | ||
3483 | */ | ||
3484 | if (read_format & PERF_FORMAT_TOTAL_TIMES) { | ||
3485 | now = perf_clock(); | ||
3486 | ctx_time = event->shadow_ctx_time + now; | ||
3487 | enabled = ctx_time - event->tstamp_enabled; | ||
3488 | running = ctx_time - event->tstamp_running; | ||
3489 | } | ||
3490 | |||
3465 | if (event->attr.read_format & PERF_FORMAT_GROUP) | 3491 | if (event->attr.read_format & PERF_FORMAT_GROUP) |
3466 | perf_output_read_group(handle, event); | 3492 | perf_output_read_group(handle, event, enabled, running); |
3467 | else | 3493 | else |
3468 | perf_output_read_one(handle, event); | 3494 | perf_output_read_one(handle, event, enabled, running); |
3469 | } | 3495 | } |
3470 | 3496 | ||
3471 | void perf_output_sample(struct perf_output_handle *handle, | 3497 | void perf_output_sample(struct perf_output_handle *handle, |
diff --git a/kernel/printk.c b/kernel/printk.c index b2ebaee8c377..38e7d5868d60 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -261,6 +261,12 @@ static inline void boot_delay_msec(void) | |||
261 | } | 261 | } |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | #ifdef CONFIG_SECURITY_DMESG_RESTRICT | ||
265 | int dmesg_restrict = 1; | ||
266 | #else | ||
267 | int dmesg_restrict; | ||
268 | #endif | ||
269 | |||
264 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 270 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
265 | { | 271 | { |
266 | unsigned i, j, limit, count; | 272 | unsigned i, j, limit, count; |
diff --git a/kernel/range.c b/kernel/range.c index 471b66acabb5..37fa9b99ad58 100644 --- a/kernel/range.c +++ b/kernel/range.c | |||
@@ -119,7 +119,7 @@ static int cmp_range(const void *x1, const void *x2) | |||
119 | 119 | ||
120 | int clean_sort_range(struct range *range, int az) | 120 | int clean_sort_range(struct range *range, int az) |
121 | { | 121 | { |
122 | int i, j, k = az - 1, nr_range = 0; | 122 | int i, j, k = az - 1, nr_range = az; |
123 | 123 | ||
124 | for (i = 0; i < k; i++) { | 124 | for (i = 0; i < k; i++) { |
125 | if (range[i].end) | 125 | if (range[i].end) |
diff --git a/kernel/relay.c b/kernel/relay.c index c7cf397fb929..859ea5a9605f 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
@@ -70,17 +70,10 @@ static const struct vm_operations_struct relay_file_mmap_ops = { | |||
70 | */ | 70 | */ |
71 | static struct page **relay_alloc_page_array(unsigned int n_pages) | 71 | static struct page **relay_alloc_page_array(unsigned int n_pages) |
72 | { | 72 | { |
73 | struct page **array; | 73 | const size_t pa_size = n_pages * sizeof(struct page *); |
74 | size_t pa_size = n_pages * sizeof(struct page *); | 74 | if (pa_size > PAGE_SIZE) |
75 | 75 | return vzalloc(pa_size); | |
76 | if (pa_size > PAGE_SIZE) { | 76 | return kzalloc(pa_size, GFP_KERNEL); |
77 | array = vmalloc(pa_size); | ||
78 | if (array) | ||
79 | memset(array, 0, pa_size); | ||
80 | } else { | ||
81 | array = kzalloc(pa_size, GFP_KERNEL); | ||
82 | } | ||
83 | return array; | ||
84 | } | 77 | } |
85 | 78 | ||
86 | /* | 79 | /* |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c33a1edb799f..b65bf634035e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -704,6 +704,15 @@ static struct ctl_table kern_table[] = { | |||
704 | }, | 704 | }, |
705 | #endif | 705 | #endif |
706 | { | 706 | { |
707 | .procname = "dmesg_restrict", | ||
708 | .data = &dmesg_restrict, | ||
709 | .maxlen = sizeof(int), | ||
710 | .mode = 0644, | ||
711 | .proc_handler = proc_dointvec_minmax, | ||
712 | .extra1 = &zero, | ||
713 | .extra2 = &one, | ||
714 | }, | ||
715 | { | ||
707 | .procname = "ngroups_max", | 716 | .procname = "ngroups_max", |
708 | .data = &ngroups_max, | 717 | .data = &ngroups_max, |
709 | .maxlen = sizeof (int), | 718 | .maxlen = sizeof (int), |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index bc251ed66724..7b8ec0281548 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -168,7 +168,6 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, | |||
168 | static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ), | 168 | static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ), |
169 | BLK_TC_ACT(BLK_TC_WRITE) }; | 169 | BLK_TC_ACT(BLK_TC_WRITE) }; |
170 | 170 | ||
171 | #define BLK_TC_HARDBARRIER BLK_TC_BARRIER | ||
172 | #define BLK_TC_RAHEAD BLK_TC_AHEAD | 171 | #define BLK_TC_RAHEAD BLK_TC_AHEAD |
173 | 172 | ||
174 | /* The ilog2() calls fall out because they're constant */ | 173 | /* The ilog2() calls fall out because they're constant */ |
@@ -196,7 +195,6 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
196 | return; | 195 | return; |
197 | 196 | ||
198 | what |= ddir_act[rw & WRITE]; | 197 | what |= ddir_act[rw & WRITE]; |
199 | what |= MASK_TC_BIT(rw, HARDBARRIER); | ||
200 | what |= MASK_TC_BIT(rw, SYNC); | 198 | what |= MASK_TC_BIT(rw, SYNC); |
201 | what |= MASK_TC_BIT(rw, RAHEAD); | 199 | what |= MASK_TC_BIT(rw, RAHEAD); |
202 | what |= MASK_TC_BIT(rw, META); | 200 | what |= MASK_TC_BIT(rw, META); |
@@ -1807,8 +1805,6 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes) | |||
1807 | 1805 | ||
1808 | if (rw & REQ_RAHEAD) | 1806 | if (rw & REQ_RAHEAD) |
1809 | rwbs[i++] = 'A'; | 1807 | rwbs[i++] = 'A'; |
1810 | if (rw & REQ_HARDBARRIER) | ||
1811 | rwbs[i++] = 'B'; | ||
1812 | if (rw & REQ_SYNC) | 1808 | if (rw & REQ_SYNC) |
1813 | rwbs[i++] = 'S'; | 1809 | rwbs[i++] = 'S'; |
1814 | if (rw & REQ_META) | 1810 | if (rw & REQ_META) |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index bafba687a6d8..6e3c41a4024c 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -43,7 +43,7 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); | |||
43 | static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); | 43 | static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | static int __initdata no_watchdog; | 46 | static int no_watchdog; |
47 | 47 | ||
48 | 48 | ||
49 | /* boot commands */ | 49 | /* boot commands */ |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 6f412ab4c24f..5086bb962b4d 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -82,6 +82,16 @@ struct radix_tree_preload { | |||
82 | }; | 82 | }; |
83 | static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; | 83 | static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; |
84 | 84 | ||
85 | static inline void *ptr_to_indirect(void *ptr) | ||
86 | { | ||
87 | return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); | ||
88 | } | ||
89 | |||
90 | static inline void *indirect_to_ptr(void *ptr) | ||
91 | { | ||
92 | return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); | ||
93 | } | ||
94 | |||
85 | static inline gfp_t root_gfp_mask(struct radix_tree_root *root) | 95 | static inline gfp_t root_gfp_mask(struct radix_tree_root *root) |
86 | { | 96 | { |
87 | return root->gfp_mask & __GFP_BITS_MASK; | 97 | return root->gfp_mask & __GFP_BITS_MASK; |
@@ -265,7 +275,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) | |||
265 | return -ENOMEM; | 275 | return -ENOMEM; |
266 | 276 | ||
267 | /* Increase the height. */ | 277 | /* Increase the height. */ |
268 | node->slots[0] = radix_tree_indirect_to_ptr(root->rnode); | 278 | node->slots[0] = indirect_to_ptr(root->rnode); |
269 | 279 | ||
270 | /* Propagate the aggregated tag info into the new root */ | 280 | /* Propagate the aggregated tag info into the new root */ |
271 | for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { | 281 | for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { |
@@ -276,7 +286,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) | |||
276 | newheight = root->height+1; | 286 | newheight = root->height+1; |
277 | node->height = newheight; | 287 | node->height = newheight; |
278 | node->count = 1; | 288 | node->count = 1; |
279 | node = radix_tree_ptr_to_indirect(node); | 289 | node = ptr_to_indirect(node); |
280 | rcu_assign_pointer(root->rnode, node); | 290 | rcu_assign_pointer(root->rnode, node); |
281 | root->height = newheight; | 291 | root->height = newheight; |
282 | } while (height > root->height); | 292 | } while (height > root->height); |
@@ -309,7 +319,7 @@ int radix_tree_insert(struct radix_tree_root *root, | |||
309 | return error; | 319 | return error; |
310 | } | 320 | } |
311 | 321 | ||
312 | slot = radix_tree_indirect_to_ptr(root->rnode); | 322 | slot = indirect_to_ptr(root->rnode); |
313 | 323 | ||
314 | height = root->height; | 324 | height = root->height; |
315 | shift = (height-1) * RADIX_TREE_MAP_SHIFT; | 325 | shift = (height-1) * RADIX_TREE_MAP_SHIFT; |
@@ -325,8 +335,7 @@ int radix_tree_insert(struct radix_tree_root *root, | |||
325 | rcu_assign_pointer(node->slots[offset], slot); | 335 | rcu_assign_pointer(node->slots[offset], slot); |
326 | node->count++; | 336 | node->count++; |
327 | } else | 337 | } else |
328 | rcu_assign_pointer(root->rnode, | 338 | rcu_assign_pointer(root->rnode, ptr_to_indirect(slot)); |
329 | radix_tree_ptr_to_indirect(slot)); | ||
330 | } | 339 | } |
331 | 340 | ||
332 | /* Go a level down */ | 341 | /* Go a level down */ |
@@ -374,7 +383,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, | |||
374 | return NULL; | 383 | return NULL; |
375 | return is_slot ? (void *)&root->rnode : node; | 384 | return is_slot ? (void *)&root->rnode : node; |
376 | } | 385 | } |
377 | node = radix_tree_indirect_to_ptr(node); | 386 | node = indirect_to_ptr(node); |
378 | 387 | ||
379 | height = node->height; | 388 | height = node->height; |
380 | if (index > radix_tree_maxindex(height)) | 389 | if (index > radix_tree_maxindex(height)) |
@@ -393,7 +402,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, | |||
393 | height--; | 402 | height--; |
394 | } while (height > 0); | 403 | } while (height > 0); |
395 | 404 | ||
396 | return is_slot ? (void *)slot:node; | 405 | return is_slot ? (void *)slot : indirect_to_ptr(node); |
397 | } | 406 | } |
398 | 407 | ||
399 | /** | 408 | /** |
@@ -455,7 +464,7 @@ void *radix_tree_tag_set(struct radix_tree_root *root, | |||
455 | height = root->height; | 464 | height = root->height; |
456 | BUG_ON(index > radix_tree_maxindex(height)); | 465 | BUG_ON(index > radix_tree_maxindex(height)); |
457 | 466 | ||
458 | slot = radix_tree_indirect_to_ptr(root->rnode); | 467 | slot = indirect_to_ptr(root->rnode); |
459 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 468 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
460 | 469 | ||
461 | while (height > 0) { | 470 | while (height > 0) { |
@@ -509,7 +518,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root, | |||
509 | 518 | ||
510 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 519 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
511 | pathp->node = NULL; | 520 | pathp->node = NULL; |
512 | slot = radix_tree_indirect_to_ptr(root->rnode); | 521 | slot = indirect_to_ptr(root->rnode); |
513 | 522 | ||
514 | while (height > 0) { | 523 | while (height > 0) { |
515 | int offset; | 524 | int offset; |
@@ -579,7 +588,7 @@ int radix_tree_tag_get(struct radix_tree_root *root, | |||
579 | 588 | ||
580 | if (!radix_tree_is_indirect_ptr(node)) | 589 | if (!radix_tree_is_indirect_ptr(node)) |
581 | return (index == 0); | 590 | return (index == 0); |
582 | node = radix_tree_indirect_to_ptr(node); | 591 | node = indirect_to_ptr(node); |
583 | 592 | ||
584 | height = node->height; | 593 | height = node->height; |
585 | if (index > radix_tree_maxindex(height)) | 594 | if (index > radix_tree_maxindex(height)) |
@@ -666,7 +675,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
666 | } | 675 | } |
667 | 676 | ||
668 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 677 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
669 | slot = radix_tree_indirect_to_ptr(root->rnode); | 678 | slot = indirect_to_ptr(root->rnode); |
670 | 679 | ||
671 | /* | 680 | /* |
672 | * we fill the path from (root->height - 2) to 0, leaving the index at | 681 | * we fill the path from (root->height - 2) to 0, leaving the index at |
@@ -897,7 +906,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, | |||
897 | results[0] = node; | 906 | results[0] = node; |
898 | return 1; | 907 | return 1; |
899 | } | 908 | } |
900 | node = radix_tree_indirect_to_ptr(node); | 909 | node = indirect_to_ptr(node); |
901 | 910 | ||
902 | max_index = radix_tree_maxindex(node->height); | 911 | max_index = radix_tree_maxindex(node->height); |
903 | 912 | ||
@@ -916,7 +925,8 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, | |||
916 | slot = *(((void ***)results)[ret + i]); | 925 | slot = *(((void ***)results)[ret + i]); |
917 | if (!slot) | 926 | if (!slot) |
918 | continue; | 927 | continue; |
919 | results[ret + nr_found] = rcu_dereference_raw(slot); | 928 | results[ret + nr_found] = |
929 | indirect_to_ptr(rcu_dereference_raw(slot)); | ||
920 | nr_found++; | 930 | nr_found++; |
921 | } | 931 | } |
922 | ret += nr_found; | 932 | ret += nr_found; |
@@ -965,7 +975,7 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, | |||
965 | results[0] = (void **)&root->rnode; | 975 | results[0] = (void **)&root->rnode; |
966 | return 1; | 976 | return 1; |
967 | } | 977 | } |
968 | node = radix_tree_indirect_to_ptr(node); | 978 | node = indirect_to_ptr(node); |
969 | 979 | ||
970 | max_index = radix_tree_maxindex(node->height); | 980 | max_index = radix_tree_maxindex(node->height); |
971 | 981 | ||
@@ -1090,7 +1100,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, | |||
1090 | results[0] = node; | 1100 | results[0] = node; |
1091 | return 1; | 1101 | return 1; |
1092 | } | 1102 | } |
1093 | node = radix_tree_indirect_to_ptr(node); | 1103 | node = indirect_to_ptr(node); |
1094 | 1104 | ||
1095 | max_index = radix_tree_maxindex(node->height); | 1105 | max_index = radix_tree_maxindex(node->height); |
1096 | 1106 | ||
@@ -1109,7 +1119,8 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, | |||
1109 | slot = *(((void ***)results)[ret + i]); | 1119 | slot = *(((void ***)results)[ret + i]); |
1110 | if (!slot) | 1120 | if (!slot) |
1111 | continue; | 1121 | continue; |
1112 | results[ret + nr_found] = rcu_dereference_raw(slot); | 1122 | results[ret + nr_found] = |
1123 | indirect_to_ptr(rcu_dereference_raw(slot)); | ||
1113 | nr_found++; | 1124 | nr_found++; |
1114 | } | 1125 | } |
1115 | ret += nr_found; | 1126 | ret += nr_found; |
@@ -1159,7 +1170,7 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, | |||
1159 | results[0] = (void **)&root->rnode; | 1170 | results[0] = (void **)&root->rnode; |
1160 | return 1; | 1171 | return 1; |
1161 | } | 1172 | } |
1162 | node = radix_tree_indirect_to_ptr(node); | 1173 | node = indirect_to_ptr(node); |
1163 | 1174 | ||
1164 | max_index = radix_tree_maxindex(node->height); | 1175 | max_index = radix_tree_maxindex(node->height); |
1165 | 1176 | ||
@@ -1195,7 +1206,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) | |||
1195 | void *newptr; | 1206 | void *newptr; |
1196 | 1207 | ||
1197 | BUG_ON(!radix_tree_is_indirect_ptr(to_free)); | 1208 | BUG_ON(!radix_tree_is_indirect_ptr(to_free)); |
1198 | to_free = radix_tree_indirect_to_ptr(to_free); | 1209 | to_free = indirect_to_ptr(to_free); |
1199 | 1210 | ||
1200 | /* | 1211 | /* |
1201 | * The candidate node has more than one child, or its child | 1212 | * The candidate node has more than one child, or its child |
@@ -1208,16 +1219,39 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) | |||
1208 | 1219 | ||
1209 | /* | 1220 | /* |
1210 | * We don't need rcu_assign_pointer(), since we are simply | 1221 | * We don't need rcu_assign_pointer(), since we are simply |
1211 | * moving the node from one part of the tree to another. If | 1222 | * moving the node from one part of the tree to another: if it |
1212 | * it was safe to dereference the old pointer to it | 1223 | * was safe to dereference the old pointer to it |
1213 | * (to_free->slots[0]), it will be safe to dereference the new | 1224 | * (to_free->slots[0]), it will be safe to dereference the new |
1214 | * one (root->rnode). | 1225 | * one (root->rnode) as far as dependent read barriers go. |
1215 | */ | 1226 | */ |
1216 | newptr = to_free->slots[0]; | 1227 | newptr = to_free->slots[0]; |
1217 | if (root->height > 1) | 1228 | if (root->height > 1) |
1218 | newptr = radix_tree_ptr_to_indirect(newptr); | 1229 | newptr = ptr_to_indirect(newptr); |
1219 | root->rnode = newptr; | 1230 | root->rnode = newptr; |
1220 | root->height--; | 1231 | root->height--; |
1232 | |||
1233 | /* | ||
1234 | * We have a dilemma here. The node's slot[0] must not be | ||
1235 | * NULLed in case there are concurrent lookups expecting to | ||
1236 | * find the item. However if this was a bottom-level node, | ||
1237 | * then it may be subject to the slot pointer being visible | ||
1238 | * to callers dereferencing it. If item corresponding to | ||
1239 | * slot[0] is subsequently deleted, these callers would expect | ||
1240 | * their slot to become empty sooner or later. | ||
1241 | * | ||
1242 | * For example, lockless pagecache will look up a slot, deref | ||
1243 | * the page pointer, and if the page is 0 refcount it means it | ||
1244 | * was concurrently deleted from pagecache so try the deref | ||
1245 | * again. Fortunately there is already a requirement for logic | ||
1246 | * to retry the entire slot lookup -- the indirect pointer | ||
1247 | * problem (replacing direct root node with an indirect pointer | ||
1248 | * also results in a stale slot). So tag the slot as indirect | ||
1249 | * to force callers to retry. | ||
1250 | */ | ||
1251 | if (root->height == 0) | ||
1252 | *((unsigned long *)&to_free->slots[0]) |= | ||
1253 | RADIX_TREE_INDIRECT_PTR; | ||
1254 | |||
1221 | radix_tree_node_free(to_free); | 1255 | radix_tree_node_free(to_free); |
1222 | } | 1256 | } |
1223 | } | 1257 | } |
@@ -1254,7 +1288,7 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) | |||
1254 | root->rnode = NULL; | 1288 | root->rnode = NULL; |
1255 | goto out; | 1289 | goto out; |
1256 | } | 1290 | } |
1257 | slot = radix_tree_indirect_to_ptr(slot); | 1291 | slot = indirect_to_ptr(slot); |
1258 | 1292 | ||
1259 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 1293 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
1260 | pathp->node = NULL; | 1294 | pathp->node = NULL; |
@@ -1296,8 +1330,7 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) | |||
1296 | radix_tree_node_free(to_free); | 1330 | radix_tree_node_free(to_free); |
1297 | 1331 | ||
1298 | if (pathp->node->count) { | 1332 | if (pathp->node->count) { |
1299 | if (pathp->node == | 1333 | if (pathp->node == indirect_to_ptr(root->rnode)) |
1300 | radix_tree_indirect_to_ptr(root->rnode)) | ||
1301 | radix_tree_shrink(root); | 1334 | radix_tree_shrink(root); |
1302 | goto out; | 1335 | goto out; |
1303 | } | 1336 | } |
diff --git a/mm/filemap.c b/mm/filemap.c index 75572b5f2374..ea89840fc65f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -644,7 +644,9 @@ repeat: | |||
644 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); | 644 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); |
645 | if (pagep) { | 645 | if (pagep) { |
646 | page = radix_tree_deref_slot(pagep); | 646 | page = radix_tree_deref_slot(pagep); |
647 | if (unlikely(!page || page == RADIX_TREE_RETRY)) | 647 | if (unlikely(!page)) |
648 | goto out; | ||
649 | if (radix_tree_deref_retry(page)) | ||
648 | goto repeat; | 650 | goto repeat; |
649 | 651 | ||
650 | if (!page_cache_get_speculative(page)) | 652 | if (!page_cache_get_speculative(page)) |
@@ -660,6 +662,7 @@ repeat: | |||
660 | goto repeat; | 662 | goto repeat; |
661 | } | 663 | } |
662 | } | 664 | } |
665 | out: | ||
663 | rcu_read_unlock(); | 666 | rcu_read_unlock(); |
664 | 667 | ||
665 | return page; | 668 | return page; |
@@ -777,12 +780,11 @@ repeat: | |||
777 | page = radix_tree_deref_slot((void **)pages[i]); | 780 | page = radix_tree_deref_slot((void **)pages[i]); |
778 | if (unlikely(!page)) | 781 | if (unlikely(!page)) |
779 | continue; | 782 | continue; |
780 | /* | 783 | if (radix_tree_deref_retry(page)) { |
781 | * this can only trigger if nr_found == 1, making livelock | 784 | if (ret) |
782 | * a non issue. | 785 | start = pages[ret-1]->index; |
783 | */ | ||
784 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
785 | goto restart; | 786 | goto restart; |
787 | } | ||
786 | 788 | ||
787 | if (!page_cache_get_speculative(page)) | 789 | if (!page_cache_get_speculative(page)) |
788 | goto repeat; | 790 | goto repeat; |
@@ -830,11 +832,7 @@ repeat: | |||
830 | page = radix_tree_deref_slot((void **)pages[i]); | 832 | page = radix_tree_deref_slot((void **)pages[i]); |
831 | if (unlikely(!page)) | 833 | if (unlikely(!page)) |
832 | continue; | 834 | continue; |
833 | /* | 835 | if (radix_tree_deref_retry(page)) |
834 | * this can only trigger if nr_found == 1, making livelock | ||
835 | * a non issue. | ||
836 | */ | ||
837 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
838 | goto restart; | 836 | goto restart; |
839 | 837 | ||
840 | if (page->mapping == NULL || page->index != index) | 838 | if (page->mapping == NULL || page->index != index) |
@@ -887,11 +885,7 @@ repeat: | |||
887 | page = radix_tree_deref_slot((void **)pages[i]); | 885 | page = radix_tree_deref_slot((void **)pages[i]); |
888 | if (unlikely(!page)) | 886 | if (unlikely(!page)) |
889 | continue; | 887 | continue; |
890 | /* | 888 | if (radix_tree_deref_retry(page)) |
891 | * this can only trigger if nr_found == 1, making livelock | ||
892 | * a non issue. | ||
893 | */ | ||
894 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
895 | goto restart; | 889 | goto restart; |
896 | 890 | ||
897 | if (!page_cache_get_speculative(page)) | 891 | if (!page_cache_get_speculative(page)) |
@@ -1029,6 +1023,9 @@ find_page: | |||
1029 | goto page_not_up_to_date; | 1023 | goto page_not_up_to_date; |
1030 | if (!trylock_page(page)) | 1024 | if (!trylock_page(page)) |
1031 | goto page_not_up_to_date; | 1025 | goto page_not_up_to_date; |
1026 | /* Did it get truncated before we got the lock? */ | ||
1027 | if (!page->mapping) | ||
1028 | goto page_not_up_to_date_locked; | ||
1032 | if (!mapping->a_ops->is_partially_uptodate(page, | 1029 | if (!mapping->a_ops->is_partially_uptodate(page, |
1033 | desc, offset)) | 1030 | desc, offset)) |
1034 | goto page_not_up_to_date_locked; | 1031 | goto page_not_up_to_date_locked; |
@@ -1563,8 +1560,10 @@ retry_find: | |||
1563 | goto no_cached_page; | 1560 | goto no_cached_page; |
1564 | } | 1561 | } |
1565 | 1562 | ||
1566 | if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) | 1563 | if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) { |
1564 | page_cache_release(page); | ||
1567 | return ret | VM_FAULT_RETRY; | 1565 | return ret | VM_FAULT_RETRY; |
1566 | } | ||
1568 | 1567 | ||
1569 | /* Did it get truncated? */ | 1568 | /* Did it get truncated? */ |
1570 | if (unlikely(page->mapping != mapping)) { | 1569 | if (unlikely(page->mapping != mapping)) { |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 9a99cfaf0a19..2efa8ea07ff7 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -4208,15 +4208,17 @@ static struct mem_cgroup *mem_cgroup_alloc(void) | |||
4208 | 4208 | ||
4209 | memset(mem, 0, size); | 4209 | memset(mem, 0, size); |
4210 | mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu); | 4210 | mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu); |
4211 | if (!mem->stat) { | 4211 | if (!mem->stat) |
4212 | if (size < PAGE_SIZE) | 4212 | goto out_free; |
4213 | kfree(mem); | ||
4214 | else | ||
4215 | vfree(mem); | ||
4216 | mem = NULL; | ||
4217 | } | ||
4218 | spin_lock_init(&mem->pcp_counter_lock); | 4213 | spin_lock_init(&mem->pcp_counter_lock); |
4219 | return mem; | 4214 | return mem; |
4215 | |||
4216 | out_free: | ||
4217 | if (size < PAGE_SIZE) | ||
4218 | kfree(mem); | ||
4219 | else | ||
4220 | vfree(mem); | ||
4221 | return NULL; | ||
4220 | } | 4222 | } |
4221 | 4223 | ||
4222 | /* | 4224 | /* |
diff --git a/mm/mprotect.c b/mm/mprotect.c index 2d1bf7cf8851..4c5133873097 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -211,6 +211,7 @@ success: | |||
211 | mmu_notifier_invalidate_range_end(mm, start, end); | 211 | mmu_notifier_invalidate_range_end(mm, start, end); |
212 | vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); | 212 | vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); |
213 | vm_stat_account(mm, newflags, vma->vm_file, nrpages); | 213 | vm_stat_account(mm, newflags, vma->vm_file, nrpages); |
214 | perf_event_mmap(vma); | ||
214 | return 0; | 215 | return 0; |
215 | 216 | ||
216 | fail: | 217 | fail: |
@@ -299,7 +300,6 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, | |||
299 | error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); | 300 | error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); |
300 | if (error) | 301 | if (error) |
301 | goto out; | 302 | goto out; |
302 | perf_event_mmap(vma); | ||
303 | nstart = tmp; | 303 | nstart = tmp; |
304 | 304 | ||
305 | if (nstart < prev->vm_end) | 305 | if (nstart < prev->vm_end) |
diff --git a/mm/vmscan.c b/mm/vmscan.c index b8a6fdc21312..d31d7ce52c0e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -913,7 +913,7 @@ keep_lumpy: | |||
913 | * back off and wait for congestion to clear because further reclaim | 913 | * back off and wait for congestion to clear because further reclaim |
914 | * will encounter the same problem | 914 | * will encounter the same problem |
915 | */ | 915 | */ |
916 | if (nr_dirty == nr_congested) | 916 | if (nr_dirty == nr_congested && nr_dirty != 0) |
917 | zone_set_flag(zone, ZONE_CONGESTED); | 917 | zone_set_flag(zone, ZONE_CONGESTED); |
918 | 918 | ||
919 | free_page_list(&free_pages); | 919 | free_page_list(&free_pages); |
diff --git a/mm/vmstat.c b/mm/vmstat.c index cd2e42be7b68..42eac4d33216 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -949,7 +949,7 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos) | |||
949 | v[PGPGIN] /= 2; /* sectors -> kbytes */ | 949 | v[PGPGIN] /= 2; /* sectors -> kbytes */ |
950 | v[PGPGOUT] /= 2; | 950 | v[PGPGOUT] /= 2; |
951 | #endif | 951 | #endif |
952 | return m->private + *pos; | 952 | return (unsigned long *)m->private + *pos; |
953 | } | 953 | } |
954 | 954 | ||
955 | static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos) | 955 | static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos) |
diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c index 76ae68303d3a..d522d8c1703e 100644 --- a/net/caif/caif_config_util.c +++ b/net/caif/caif_config_util.c | |||
@@ -16,11 +16,18 @@ int connect_req_to_link_param(struct cfcnfg *cnfg, | |||
16 | { | 16 | { |
17 | struct dev_info *dev_info; | 17 | struct dev_info *dev_info; |
18 | enum cfcnfg_phy_preference pref; | 18 | enum cfcnfg_phy_preference pref; |
19 | int res; | ||
20 | |||
19 | memset(l, 0, sizeof(*l)); | 21 | memset(l, 0, sizeof(*l)); |
20 | l->priority = s->priority; | 22 | /* In caif protocol low value is high priority */ |
23 | l->priority = CAIF_PRIO_MAX - s->priority + 1; | ||
21 | 24 | ||
22 | if (s->link_name[0] != '\0') | 25 | if (s->ifindex != 0){ |
23 | l->phyid = cfcnfg_get_named(cnfg, s->link_name); | 26 | res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex); |
27 | if (res < 0) | ||
28 | return res; | ||
29 | l->phyid = res; | ||
30 | } | ||
24 | else { | 31 | else { |
25 | switch (s->link_selector) { | 32 | switch (s->link_selector) { |
26 | case CAIF_LINK_HIGH_BANDW: | 33 | case CAIF_LINK_HIGH_BANDW: |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index b99369a055d1..a42a408306e4 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
@@ -307,6 +307,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
307 | 307 | ||
308 | case NETDEV_UNREGISTER: | 308 | case NETDEV_UNREGISTER: |
309 | caifd = caif_get(dev); | 309 | caifd = caif_get(dev); |
310 | if (caifd == NULL) | ||
311 | break; | ||
310 | netdev_info(dev, "unregister\n"); | 312 | netdev_info(dev, "unregister\n"); |
311 | atomic_set(&caifd->state, what); | 313 | atomic_set(&caifd->state, what); |
312 | caif_device_destroy(dev); | 314 | caif_device_destroy(dev); |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 2eca2dd0000f..1bf0cf503796 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -716,8 +716,7 @@ static int setsockopt(struct socket *sock, | |||
716 | { | 716 | { |
717 | struct sock *sk = sock->sk; | 717 | struct sock *sk = sock->sk; |
718 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 718 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
719 | int prio, linksel; | 719 | int linksel; |
720 | struct ifreq ifreq; | ||
721 | 720 | ||
722 | if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) | 721 | if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) |
723 | return -ENOPROTOOPT; | 722 | return -ENOPROTOOPT; |
@@ -735,33 +734,6 @@ static int setsockopt(struct socket *sock, | |||
735 | release_sock(&cf_sk->sk); | 734 | release_sock(&cf_sk->sk); |
736 | return 0; | 735 | return 0; |
737 | 736 | ||
738 | case SO_PRIORITY: | ||
739 | if (lvl != SOL_SOCKET) | ||
740 | goto bad_sol; | ||
741 | if (ol < sizeof(int)) | ||
742 | return -EINVAL; | ||
743 | if (copy_from_user(&prio, ov, sizeof(int))) | ||
744 | return -EINVAL; | ||
745 | lock_sock(&(cf_sk->sk)); | ||
746 | cf_sk->conn_req.priority = prio; | ||
747 | release_sock(&cf_sk->sk); | ||
748 | return 0; | ||
749 | |||
750 | case SO_BINDTODEVICE: | ||
751 | if (lvl != SOL_SOCKET) | ||
752 | goto bad_sol; | ||
753 | if (ol < sizeof(struct ifreq)) | ||
754 | return -EINVAL; | ||
755 | if (copy_from_user(&ifreq, ov, sizeof(ifreq))) | ||
756 | return -EFAULT; | ||
757 | lock_sock(&(cf_sk->sk)); | ||
758 | strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name, | ||
759 | sizeof(cf_sk->conn_req.link_name)); | ||
760 | cf_sk->conn_req.link_name | ||
761 | [sizeof(cf_sk->conn_req.link_name)-1] = 0; | ||
762 | release_sock(&cf_sk->sk); | ||
763 | return 0; | ||
764 | |||
765 | case CAIFSO_REQ_PARAM: | 737 | case CAIFSO_REQ_PARAM: |
766 | if (lvl != SOL_CAIF) | 738 | if (lvl != SOL_CAIF) |
767 | goto bad_sol; | 739 | goto bad_sol; |
@@ -880,6 +852,18 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
880 | sock->state = SS_CONNECTING; | 852 | sock->state = SS_CONNECTING; |
881 | sk->sk_state = CAIF_CONNECTING; | 853 | sk->sk_state = CAIF_CONNECTING; |
882 | 854 | ||
855 | /* Check priority value comming from socket */ | ||
856 | /* if priority value is out of range it will be ajusted */ | ||
857 | if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) | ||
858 | cf_sk->conn_req.priority = CAIF_PRIO_MAX; | ||
859 | else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN) | ||
860 | cf_sk->conn_req.priority = CAIF_PRIO_MIN; | ||
861 | else | ||
862 | cf_sk->conn_req.priority = cf_sk->sk.sk_priority; | ||
863 | |||
864 | /*ifindex = id of the interface.*/ | ||
865 | cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if; | ||
866 | |||
883 | dbfs_atomic_inc(&cnt.num_connect_req); | 867 | dbfs_atomic_inc(&cnt.num_connect_req); |
884 | cf_sk->layer.receive = caif_sktrecv_cb; | 868 | cf_sk->layer.receive = caif_sktrecv_cb; |
885 | err = caif_connect_client(&cf_sk->conn_req, | 869 | err = caif_connect_client(&cf_sk->conn_req, |
@@ -905,6 +889,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
905 | cf_sk->maxframe = mtu - (headroom + tailroom); | 889 | cf_sk->maxframe = mtu - (headroom + tailroom); |
906 | if (cf_sk->maxframe < 1) { | 890 | if (cf_sk->maxframe < 1) { |
907 | pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); | 891 | pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); |
892 | err = -ENODEV; | ||
908 | goto out; | 893 | goto out; |
909 | } | 894 | } |
910 | 895 | ||
@@ -1142,7 +1127,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, | |||
1142 | set_rx_flow_on(cf_sk); | 1127 | set_rx_flow_on(cf_sk); |
1143 | 1128 | ||
1144 | /* Set default options on configuration */ | 1129 | /* Set default options on configuration */ |
1145 | cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; | 1130 | cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL; |
1146 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; | 1131 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; |
1147 | cf_sk->conn_req.protocol = protocol; | 1132 | cf_sk->conn_req.protocol = protocol; |
1148 | /* Increase the number of sockets created. */ | 1133 | /* Increase the number of sockets created. */ |
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 41adafd18914..21ede141018a 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
@@ -173,18 +173,15 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg, | |||
173 | return NULL; | 173 | return NULL; |
174 | } | 174 | } |
175 | 175 | ||
176 | int cfcnfg_get_named(struct cfcnfg *cnfg, char *name) | 176 | |
177 | int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) | ||
177 | { | 178 | { |
178 | int i; | 179 | int i; |
179 | 180 | for (i = 0; i < MAX_PHY_LAYERS; i++) | |
180 | /* Try to match with specified name */ | 181 | if (cnfg->phy_layers[i].frm_layer != NULL && |
181 | for (i = 0; i < MAX_PHY_LAYERS; i++) { | 182 | cnfg->phy_layers[i].ifindex == ifi) |
182 | if (cnfg->phy_layers[i].frm_layer != NULL | 183 | return i; |
183 | && strcmp(cnfg->phy_layers[i].phy_layer->name, | 184 | return -ENODEV; |
184 | name) == 0) | ||
185 | return cnfg->phy_layers[i].frm_layer->id; | ||
186 | } | ||
187 | return 0; | ||
188 | } | 185 | } |
189 | 186 | ||
190 | int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) | 187 | int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) |
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 08f267a109aa..3cd8f978e309 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
@@ -361,11 +361,10 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) | |||
361 | struct cfctrl_request_info *p, *tmp; | 361 | struct cfctrl_request_info *p, *tmp; |
362 | struct cfctrl *ctrl = container_obj(layr); | 362 | struct cfctrl *ctrl = container_obj(layr); |
363 | spin_lock(&ctrl->info_list_lock); | 363 | spin_lock(&ctrl->info_list_lock); |
364 | pr_warn("enter\n"); | ||
365 | 364 | ||
366 | list_for_each_entry_safe(p, tmp, &ctrl->list, list) { | 365 | list_for_each_entry_safe(p, tmp, &ctrl->list, list) { |
367 | if (p->client_layer == adap_layer) { | 366 | if (p->client_layer == adap_layer) { |
368 | pr_warn("cancel req :%d\n", p->sequence_no); | 367 | pr_debug("cancel req :%d\n", p->sequence_no); |
369 | list_del(&p->list); | 368 | list_del(&p->list); |
370 | kfree(p); | 369 | kfree(p); |
371 | } | 370 | } |
diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c index 496fda9ac66f..11a2af4c162a 100644 --- a/net/caif/cfdbgl.c +++ b/net/caif/cfdbgl.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <net/caif/cfsrvl.h> | 12 | #include <net/caif/cfsrvl.h> |
13 | #include <net/caif/cfpkt.h> | 13 | #include <net/caif/cfpkt.h> |
14 | 14 | ||
15 | #define container_obj(layr) ((struct cfsrvl *) layr) | ||
16 | |||
15 | static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); | 17 | static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); |
16 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); | 18 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); |
17 | 19 | ||
@@ -38,5 +40,17 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt) | |||
38 | 40 | ||
39 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) | 41 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) |
40 | { | 42 | { |
43 | struct cfsrvl *service = container_obj(layr); | ||
44 | struct caif_payload_info *info; | ||
45 | int ret; | ||
46 | |||
47 | if (!cfsrvl_ready(service, &ret)) | ||
48 | return ret; | ||
49 | |||
50 | /* Add info for MUX-layer to route the packet out */ | ||
51 | info = cfpkt_info(pkt); | ||
52 | info->channel_id = service->layer.id; | ||
53 | info->dev_info = &service->dev_info; | ||
54 | |||
41 | return layr->dn->transmit(layr->dn, pkt); | 55 | return layr->dn->transmit(layr->dn, pkt); |
42 | } | 56 | } |
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index bde8481e8d25..e2fb5fa75795 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c | |||
@@ -193,7 +193,7 @@ out: | |||
193 | 193 | ||
194 | static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) | 194 | static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) |
195 | { | 195 | { |
196 | caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size); | 196 | caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size); |
197 | 197 | ||
198 | /* Add info for MUX-layer to route the packet out. */ | 198 | /* Add info for MUX-layer to route the packet out. */ |
199 | cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; | 199 | cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; |
diff --git a/net/core/dev.c b/net/core/dev.c index 35dfb8318483..0dd54a69dace 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2131,7 +2131,7 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
2131 | } else { | 2131 | } else { |
2132 | struct sock *sk = skb->sk; | 2132 | struct sock *sk = skb->sk; |
2133 | queue_index = sk_tx_queue_get(sk); | 2133 | queue_index = sk_tx_queue_get(sk); |
2134 | if (queue_index < 0) { | 2134 | if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) { |
2135 | 2135 | ||
2136 | queue_index = 0; | 2136 | queue_index = 0; |
2137 | if (dev->real_num_tx_queues > 1) | 2137 | if (dev->real_num_tx_queues > 1) |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index a29edf2219c8..c079cc0ec651 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
@@ -47,11 +47,8 @@ extern int fib_detect_death(struct fib_info *fi, int order, | |||
47 | static inline void fib_result_assign(struct fib_result *res, | 47 | static inline void fib_result_assign(struct fib_result *res, |
48 | struct fib_info *fi) | 48 | struct fib_info *fi) |
49 | { | 49 | { |
50 | if (res->fi != NULL) | 50 | /* we used to play games with refcounts, but we now use RCU */ |
51 | fib_info_put(res->fi); | ||
52 | res->fi = fi; | 51 | res->fi = fi; |
53 | if (fi != NULL) | ||
54 | atomic_inc(&fi->fib_clntref); | ||
55 | } | 52 | } |
56 | 53 | ||
57 | #endif /* _FIB_LOOKUP_H */ | 54 | #endif /* _FIB_LOOKUP_H */ |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index ba8042665849..2ada17129fce 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
490 | { | 490 | { |
491 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 491 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
492 | 492 | ||
493 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 493 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
494 | struct inet_diag_entry entry; | 494 | struct inet_diag_entry entry; |
495 | struct rtattr *bc = (struct rtattr *)(r + 1); | 495 | const struct nlattr *bc = nlmsg_find_attr(cb->nlh, |
496 | sizeof(*r), | ||
497 | INET_DIAG_REQ_BYTECODE); | ||
496 | struct inet_sock *inet = inet_sk(sk); | 498 | struct inet_sock *inet = inet_sk(sk); |
497 | 499 | ||
498 | entry.family = sk->sk_family; | 500 | entry.family = sk->sk_family; |
@@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
512 | entry.dport = ntohs(inet->inet_dport); | 514 | entry.dport = ntohs(inet->inet_dport); |
513 | entry.userlocks = sk->sk_userlocks; | 515 | entry.userlocks = sk->sk_userlocks; |
514 | 516 | ||
515 | if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) | 517 | if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) |
516 | return 0; | 518 | return 0; |
517 | } | 519 | } |
518 | 520 | ||
@@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
527 | { | 529 | { |
528 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 530 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
529 | 531 | ||
530 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 532 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
531 | struct inet_diag_entry entry; | 533 | struct inet_diag_entry entry; |
532 | struct rtattr *bc = (struct rtattr *)(r + 1); | 534 | const struct nlattr *bc = nlmsg_find_attr(cb->nlh, |
535 | sizeof(*r), | ||
536 | INET_DIAG_REQ_BYTECODE); | ||
533 | 537 | ||
534 | entry.family = tw->tw_family; | 538 | entry.family = tw->tw_family; |
535 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 539 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
@@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
548 | entry.dport = ntohs(tw->tw_dport); | 552 | entry.dport = ntohs(tw->tw_dport); |
549 | entry.userlocks = 0; | 553 | entry.userlocks = 0; |
550 | 554 | ||
551 | if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) | 555 | if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) |
552 | return 0; | 556 | return 0; |
553 | } | 557 | } |
554 | 558 | ||
@@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
618 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 622 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
619 | struct inet_connection_sock *icsk = inet_csk(sk); | 623 | struct inet_connection_sock *icsk = inet_csk(sk); |
620 | struct listen_sock *lopt; | 624 | struct listen_sock *lopt; |
621 | struct rtattr *bc = NULL; | 625 | const struct nlattr *bc = NULL; |
622 | struct inet_sock *inet = inet_sk(sk); | 626 | struct inet_sock *inet = inet_sk(sk); |
623 | int j, s_j; | 627 | int j, s_j; |
624 | int reqnum, s_reqnum; | 628 | int reqnum, s_reqnum; |
@@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
638 | if (!lopt || !lopt->qlen) | 642 | if (!lopt || !lopt->qlen) |
639 | goto out; | 643 | goto out; |
640 | 644 | ||
641 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 645 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
642 | bc = (struct rtattr *)(r + 1); | 646 | bc = nlmsg_find_attr(cb->nlh, sizeof(*r), |
647 | INET_DIAG_REQ_BYTECODE); | ||
643 | entry.sport = inet->inet_num; | 648 | entry.sport = inet->inet_num; |
644 | entry.userlocks = sk->sk_userlocks; | 649 | entry.userlocks = sk->sk_userlocks; |
645 | } | 650 | } |
@@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
672 | &ireq->rmt_addr; | 677 | &ireq->rmt_addr; |
673 | entry.dport = ntohs(ireq->rmt_port); | 678 | entry.dport = ntohs(ireq->rmt_port); |
674 | 679 | ||
675 | if (!inet_diag_bc_run(RTA_DATA(bc), | 680 | if (!inet_diag_bc_run(nla_data(bc), |
676 | RTA_PAYLOAD(bc), &entry)) | 681 | nla_len(bc), &entry)) |
677 | continue; | 682 | continue; |
678 | } | 683 | } |
679 | 684 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 3cad2591ace0..3fac340a28d5 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -927,6 +927,7 @@ static int get_info(struct net *net, void __user *user, | |||
927 | private = &tmp; | 927 | private = &tmp; |
928 | } | 928 | } |
929 | #endif | 929 | #endif |
930 | memset(&info, 0, sizeof(info)); | ||
930 | info.valid_hooks = t->valid_hooks; | 931 | info.valid_hooks = t->valid_hooks; |
931 | memcpy(info.hook_entry, private->hook_entry, | 932 | memcpy(info.hook_entry, private->hook_entry, |
932 | sizeof(info.hook_entry)); | 933 | sizeof(info.hook_entry)); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d31b007a6d80..a846d633b3b6 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -1124,6 +1124,7 @@ static int get_info(struct net *net, void __user *user, | |||
1124 | private = &tmp; | 1124 | private = &tmp; |
1125 | } | 1125 | } |
1126 | #endif | 1126 | #endif |
1127 | memset(&info, 0, sizeof(info)); | ||
1127 | info.valid_hooks = t->valid_hooks; | 1128 | info.valid_hooks = t->valid_hooks; |
1128 | memcpy(info.hook_entry, private->hook_entry, | 1129 | memcpy(info.hook_entry, private->hook_entry, |
1129 | sizeof(info.hook_entry)); | 1130 | sizeof(info.hook_entry)); |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 295c97431e43..c04787ce1a71 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -47,26 +47,6 @@ __nf_nat_proto_find(u_int8_t protonum) | |||
47 | return rcu_dereference(nf_nat_protos[protonum]); | 47 | return rcu_dereference(nf_nat_protos[protonum]); |
48 | } | 48 | } |
49 | 49 | ||
50 | static const struct nf_nat_protocol * | ||
51 | nf_nat_proto_find_get(u_int8_t protonum) | ||
52 | { | ||
53 | const struct nf_nat_protocol *p; | ||
54 | |||
55 | rcu_read_lock(); | ||
56 | p = __nf_nat_proto_find(protonum); | ||
57 | if (!try_module_get(p->me)) | ||
58 | p = &nf_nat_unknown_protocol; | ||
59 | rcu_read_unlock(); | ||
60 | |||
61 | return p; | ||
62 | } | ||
63 | |||
64 | static void | ||
65 | nf_nat_proto_put(const struct nf_nat_protocol *p) | ||
66 | { | ||
67 | module_put(p->me); | ||
68 | } | ||
69 | |||
70 | /* We keep an extra hash for each conntrack, for fast searching. */ | 50 | /* We keep an extra hash for each conntrack, for fast searching. */ |
71 | static inline unsigned int | 51 | static inline unsigned int |
72 | hash_by_src(const struct net *net, u16 zone, | 52 | hash_by_src(const struct net *net, u16 zone, |
@@ -588,6 +568,26 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { | |||
588 | #include <linux/netfilter/nfnetlink.h> | 568 | #include <linux/netfilter/nfnetlink.h> |
589 | #include <linux/netfilter/nfnetlink_conntrack.h> | 569 | #include <linux/netfilter/nfnetlink_conntrack.h> |
590 | 570 | ||
571 | static const struct nf_nat_protocol * | ||
572 | nf_nat_proto_find_get(u_int8_t protonum) | ||
573 | { | ||
574 | const struct nf_nat_protocol *p; | ||
575 | |||
576 | rcu_read_lock(); | ||
577 | p = __nf_nat_proto_find(protonum); | ||
578 | if (!try_module_get(p->me)) | ||
579 | p = &nf_nat_unknown_protocol; | ||
580 | rcu_read_unlock(); | ||
581 | |||
582 | return p; | ||
583 | } | ||
584 | |||
585 | static void | ||
586 | nf_nat_proto_put(const struct nf_nat_protocol *p) | ||
587 | { | ||
588 | module_put(p->me); | ||
589 | } | ||
590 | |||
591 | static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = { | 591 | static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = { |
592 | [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 }, | 592 | [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 }, |
593 | [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 }, | 593 | [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 }, |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 51df035897e7..455582384ece 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -1137,6 +1137,7 @@ static int get_info(struct net *net, void __user *user, | |||
1137 | private = &tmp; | 1137 | private = &tmp; |
1138 | } | 1138 | } |
1139 | #endif | 1139 | #endif |
1140 | memset(&info, 0, sizeof(info)); | ||
1140 | info.valid_hooks = t->valid_hooks; | 1141 | info.valid_hooks = t->valid_hooks; |
1141 | memcpy(info.hook_entry, private->hook_entry, | 1142 | memcpy(info.hook_entry, private->hook_entry, |
1142 | sizeof(info.hook_entry)); | 1143 | sizeof(info.hook_entry)); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25661f968f3f..fc328339be99 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2741,6 +2741,7 @@ static void __net_exit ip6_route_net_exit(struct net *net) | |||
2741 | kfree(net->ipv6.ip6_prohibit_entry); | 2741 | kfree(net->ipv6.ip6_prohibit_entry); |
2742 | kfree(net->ipv6.ip6_blk_hole_entry); | 2742 | kfree(net->ipv6.ip6_blk_hole_entry); |
2743 | #endif | 2743 | #endif |
2744 | dst_entries_destroy(&net->ipv6.ip6_dst_ops); | ||
2744 | } | 2745 | } |
2745 | 2746 | ||
2746 | static struct pernet_operations ip6_route_net_ops = { | 2747 | static struct pernet_operations ip6_route_net_ops = { |
@@ -2832,5 +2833,6 @@ void ip6_route_cleanup(void) | |||
2832 | xfrm6_fini(); | 2833 | xfrm6_fini(); |
2833 | fib6_gc_cleanup(); | 2834 | fib6_gc_cleanup(); |
2834 | unregister_pernet_subsys(&ip6_route_net_ops); | 2835 | unregister_pernet_subsys(&ip6_route_net_ops); |
2836 | dst_entries_destroy(&ip6_dst_blackhole_ops); | ||
2835 | kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); | 2837 | kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); |
2836 | } | 2838 | } |
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index 104ec3b283d4..b8dbae82fab8 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c | |||
@@ -249,7 +249,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file) | |||
249 | struct seq_file *seq; | 249 | struct seq_file *seq; |
250 | int rc = -ENOMEM; | 250 | int rc = -ENOMEM; |
251 | 251 | ||
252 | pd = kzalloc(GFP_KERNEL, sizeof(*pd)); | 252 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); |
253 | if (pd == NULL) | 253 | if (pd == NULL) |
254 | goto out; | 254 | goto out; |
255 | 255 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 1eacf8d9966a..27a5ea6b6a0f 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1312,7 +1312,8 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls) | |||
1312 | if (!hash) { | 1312 | if (!hash) { |
1313 | *vmalloced = 1; | 1313 | *vmalloced = 1; |
1314 | printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); | 1314 | printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); |
1315 | hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); | 1315 | hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, |
1316 | PAGE_KERNEL); | ||
1316 | } | 1317 | } |
1317 | 1318 | ||
1318 | if (hash && nulls) | 1319 | if (hash && nulls) |
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index ed6d92958023..dc7bb74110df 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c | |||
@@ -292,6 +292,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) | |||
292 | 292 | ||
293 | for (i = 0; i < MAX_NF_CT_PROTO; i++) | 293 | for (i = 0; i < MAX_NF_CT_PROTO; i++) |
294 | proto_array[i] = &nf_conntrack_l4proto_generic; | 294 | proto_array[i] = &nf_conntrack_l4proto_generic; |
295 | |||
296 | /* Before making proto_array visible to lockless readers, | ||
297 | * we must make sure its content is committed to memory. | ||
298 | */ | ||
299 | smp_wmb(); | ||
300 | |||
295 | nf_ct_protos[l4proto->l3proto] = proto_array; | 301 | nf_ct_protos[l4proto->l3proto] = proto_array; |
296 | } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != | 302 | } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != |
297 | &nf_conntrack_l4proto_generic) { | 303 | &nf_conntrack_l4proto_generic) { |
diff --git a/net/rds/loop.c b/net/rds/loop.c index c390156b426f..aeec1d483b17 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c | |||
@@ -134,8 +134,12 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
134 | static void rds_loop_conn_free(void *arg) | 134 | static void rds_loop_conn_free(void *arg) |
135 | { | 135 | { |
136 | struct rds_loop_connection *lc = arg; | 136 | struct rds_loop_connection *lc = arg; |
137 | unsigned long flags; | ||
138 | |||
137 | rdsdebug("lc %p\n", lc); | 139 | rdsdebug("lc %p\n", lc); |
140 | spin_lock_irqsave(&loop_conns_lock, flags); | ||
138 | list_del(&lc->loop_node); | 141 | list_del(&lc->loop_node); |
142 | spin_unlock_irqrestore(&loop_conns_lock, flags); | ||
139 | kfree(lc); | 143 | kfree(lc); |
140 | } | 144 | } |
141 | 145 | ||
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 08a8c6cf2d10..8e0a32001c90 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -221,7 +221,13 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
221 | static void rds_tcp_conn_free(void *arg) | 221 | static void rds_tcp_conn_free(void *arg) |
222 | { | 222 | { |
223 | struct rds_tcp_connection *tc = arg; | 223 | struct rds_tcp_connection *tc = arg; |
224 | unsigned long flags; | ||
224 | rdsdebug("freeing tc %p\n", tc); | 225 | rdsdebug("freeing tc %p\n", tc); |
226 | |||
227 | spin_lock_irqsave(&rds_tcp_conn_lock, flags); | ||
228 | list_del(&tc->t_tcp_node); | ||
229 | spin_unlock_irqrestore(&rds_tcp_conn_lock, flags); | ||
230 | |||
225 | kmem_cache_free(rds_tcp_conn_slab, tc); | 231 | kmem_cache_free(rds_tcp_conn_slab, tc); |
226 | } | 232 | } |
227 | 233 | ||
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 37dff78e9cb1..d49c40fb7e09 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -34,8 +34,6 @@ struct cgroup_subsys net_cls_subsys = { | |||
34 | .populate = cgrp_populate, | 34 | .populate = cgrp_populate, |
35 | #ifdef CONFIG_NET_CLS_CGROUP | 35 | #ifdef CONFIG_NET_CLS_CGROUP |
36 | .subsys_id = net_cls_subsys_id, | 36 | .subsys_id = net_cls_subsys_id, |
37 | #else | ||
38 | #define net_cls_subsys_id net_cls_subsys.subsys_id | ||
39 | #endif | 37 | #endif |
40 | .module = THIS_MODULE, | 38 | .module = THIS_MODULE, |
41 | }; | 39 | }; |
diff --git a/net/sched/em_text.c b/net/sched/em_text.c index 763253257411..ea8f566e720c 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c | |||
@@ -103,7 +103,8 @@ retry: | |||
103 | 103 | ||
104 | static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) | 104 | static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) |
105 | { | 105 | { |
106 | textsearch_destroy(EM_TEXT_PRIV(m)->config); | 106 | if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) |
107 | textsearch_destroy(EM_TEXT_PRIV(m)->config); | ||
107 | } | 108 | } |
108 | 109 | ||
109 | static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) | 110 | static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 771bab00754b..3a8c4c419cd4 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -134,15 +134,15 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
134 | case X25_FAC_CLASS_D: | 134 | case X25_FAC_CLASS_D: |
135 | switch (*p) { | 135 | switch (*p) { |
136 | case X25_FAC_CALLING_AE: | 136 | case X25_FAC_CALLING_AE: |
137 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | 137 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
138 | break; | 138 | return 0; |
139 | dte_facs->calling_len = p[2]; | 139 | dte_facs->calling_len = p[2]; |
140 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); | 140 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); |
141 | *vc_fac_mask |= X25_MASK_CALLING_AE; | 141 | *vc_fac_mask |= X25_MASK_CALLING_AE; |
142 | break; | 142 | break; |
143 | case X25_FAC_CALLED_AE: | 143 | case X25_FAC_CALLED_AE: |
144 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | 144 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
145 | break; | 145 | return 0; |
146 | dte_facs->called_len = p[2]; | 146 | dte_facs->called_len = p[2]; |
147 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); | 147 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); |
148 | *vc_fac_mask |= X25_MASK_CALLED_AE; | 148 | *vc_fac_mask |= X25_MASK_CALLED_AE; |
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 63178961efac..f729f022be69 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
@@ -119,6 +119,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
119 | &x25->vc_facil_mask); | 119 | &x25->vc_facil_mask); |
120 | if (len > 0) | 120 | if (len > 0) |
121 | skb_pull(skb, len); | 121 | skb_pull(skb, len); |
122 | else | ||
123 | return -1; | ||
122 | /* | 124 | /* |
123 | * Copy any Call User Data. | 125 | * Copy any Call User Data. |
124 | */ | 126 | */ |
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index c0efe102d655..af6e9f3de950 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -875,7 +875,7 @@ const char *sym_expand_string_value(const char *in) | |||
875 | symval = sym_get_string_value(sym); | 875 | symval = sym_get_string_value(sym); |
876 | } | 876 | } |
877 | 877 | ||
878 | newlen = strlen(res) + strlen(symval) + strlen(src); | 878 | newlen = strlen(res) + strlen(symval) + strlen(src) + 1; |
879 | if (newlen > reslen) { | 879 | if (newlen > reslen) { |
880 | reslen = newlen; | 880 | reslen = newlen; |
881 | res = realloc(res, reslen); | 881 | res = realloc(res, reslen); |
diff --git a/security/Kconfig b/security/Kconfig index bd72ae623494..e80da955e687 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -39,6 +39,18 @@ config KEYS_DEBUG_PROC_KEYS | |||
39 | 39 | ||
40 | If you are unsure as to whether this is required, answer N. | 40 | If you are unsure as to whether this is required, answer N. |
41 | 41 | ||
42 | config SECURITY_DMESG_RESTRICT | ||
43 | bool "Restrict unprivileged access to the kernel syslog" | ||
44 | default n | ||
45 | help | ||
46 | This enforces restrictions on unprivileged users reading the kernel | ||
47 | syslog via dmesg(8). | ||
48 | |||
49 | If this option is not selected, no restrictions will be enforced | ||
50 | unless the dmesg_restrict sysctl is explicitly set to (1). | ||
51 | |||
52 | If you are unsure how to answer this question, answer N. | ||
53 | |||
42 | config SECURITY | 54 | config SECURITY |
43 | bool "Enable different security models" | 55 | bool "Enable different security models" |
44 | depends on SYSFS | 56 | depends on SYSFS |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index cf1de4462ccd..b7106f192b75 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -922,7 +922,7 @@ static int __init apparmor_init(void) | |||
922 | error = register_security(&apparmor_ops); | 922 | error = register_security(&apparmor_ops); |
923 | if (error) { | 923 | if (error) { |
924 | AA_ERROR("Unable to register AppArmor\n"); | 924 | AA_ERROR("Unable to register AppArmor\n"); |
925 | goto register_security_out; | 925 | goto set_init_cxt_out; |
926 | } | 926 | } |
927 | 927 | ||
928 | /* Report that AppArmor successfully initialized */ | 928 | /* Report that AppArmor successfully initialized */ |
@@ -936,6 +936,9 @@ static int __init apparmor_init(void) | |||
936 | 936 | ||
937 | return error; | 937 | return error; |
938 | 938 | ||
939 | set_init_cxt_out: | ||
940 | aa_free_task_context(current->real_cred->security); | ||
941 | |||
939 | register_security_out: | 942 | register_security_out: |
940 | aa_free_root_ns(); | 943 | aa_free_root_ns(); |
941 | 944 | ||
@@ -944,7 +947,6 @@ alloc_out: | |||
944 | 947 | ||
945 | apparmor_enabled = 0; | 948 | apparmor_enabled = 0; |
946 | return error; | 949 | return error; |
947 | |||
948 | } | 950 | } |
949 | 951 | ||
950 | security_initcall(apparmor_init); | 952 | security_initcall(apparmor_init); |
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 52cc865f1464..4f0eadee78b8 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
@@ -306,7 +306,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix, | |||
306 | return ns; | 306 | return ns; |
307 | 307 | ||
308 | fail_unconfined: | 308 | fail_unconfined: |
309 | kzfree(ns->base.name); | 309 | kzfree(ns->base.hname); |
310 | fail_ns: | 310 | fail_ns: |
311 | kzfree(ns); | 311 | kzfree(ns); |
312 | return NULL; | 312 | return NULL; |
diff --git a/security/commoncap.c b/security/commoncap.c index 5e632b4857e4..04b80f9912bf 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -895,6 +895,8 @@ int cap_syslog(int type, bool from_file) | |||
895 | { | 895 | { |
896 | if (type != SYSLOG_ACTION_OPEN && from_file) | 896 | if (type != SYSLOG_ACTION_OPEN && from_file) |
897 | return 0; | 897 | return 0; |
898 | if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) | ||
899 | return -EPERM; | ||
898 | if ((type != SYSLOG_ACTION_READ_ALL && | 900 | if ((type != SYSLOG_ACTION_READ_ALL && |
899 | type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) | 901 | type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) |
900 | return -EPERM; | 902 | return -EPERM; |
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index f7e374ec4414..1b9bf9395cfe 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -625,6 +625,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
625 | control_cache_size, (struct hpi_control_cache_info *) | 625 | control_cache_size, (struct hpi_control_cache_info *) |
626 | &phw->control_cache[0] | 626 | &phw->control_cache[0] |
627 | ); | 627 | ); |
628 | if (!phw->p_cache) | ||
629 | pao->has_control_cache = 0; | ||
628 | } else | 630 | } else |
629 | pao->has_control_cache = 0; | 631 | pao->has_control_cache = 0; |
630 | 632 | ||
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 22c5fc625533..2672f6591ceb 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -644,6 +644,8 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
644 | interface->control_cache.size_in_bytes, | 644 | interface->control_cache.size_in_bytes, |
645 | (struct hpi_control_cache_info *) | 645 | (struct hpi_control_cache_info *) |
646 | p_control_cache_virtual); | 646 | p_control_cache_virtual); |
647 | if (!phw->p_cache) | ||
648 | err = HPI_ERROR_MEMORY_ALLOC; | ||
647 | } | 649 | } |
648 | if (!err) { | 650 | if (!err) { |
649 | err = hpios_locked_mem_get_phys_addr(&phw-> | 651 | err = hpios_locked_mem_get_phys_addr(&phw-> |
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index dda4f1c6f658..d67f4d3db911 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -571,14 +571,20 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 | |||
571 | { | 571 | { |
572 | struct hpi_control_cache *p_cache = | 572 | struct hpi_control_cache *p_cache = |
573 | kmalloc(sizeof(*p_cache), GFP_KERNEL); | 573 | kmalloc(sizeof(*p_cache), GFP_KERNEL); |
574 | if (!p_cache) | ||
575 | return NULL; | ||
576 | p_cache->p_info = | ||
577 | kmalloc(sizeof(*p_cache->p_info) * number_of_controls, | ||
578 | GFP_KERNEL); | ||
579 | if (!p_cache->p_info) { | ||
580 | kfree(p_cache); | ||
581 | return NULL; | ||
582 | } | ||
574 | p_cache->cache_size_in_bytes = size_in_bytes; | 583 | p_cache->cache_size_in_bytes = size_in_bytes; |
575 | p_cache->control_count = number_of_controls; | 584 | p_cache->control_count = number_of_controls; |
576 | p_cache->p_cache = | 585 | p_cache->p_cache = |
577 | (struct hpi_control_cache_single *)pDSP_control_buffer; | 586 | (struct hpi_control_cache_single *)pDSP_control_buffer; |
578 | p_cache->init = 0; | 587 | p_cache->init = 0; |
579 | p_cache->p_info = | ||
580 | kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count, | ||
581 | GFP_KERNEL); | ||
582 | return p_cache; | 588 | return p_cache; |
583 | } | 589 | } |
584 | 590 | ||
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 3e5ca8fb519f..e377287192aa 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c | |||
@@ -225,39 +225,25 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
225 | { | 225 | { |
226 | struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL); | 226 | struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL); |
227 | 227 | ||
228 | if (ins == NULL) | 228 | if (ins == NULL) |
229 | return NULL; | 229 | return NULL; |
230 | 230 | ||
231 | /* better to use vmalloc for this big table */ | 231 | /* better to use vmalloc for this big table */ |
232 | ins->symbol_table.nsymbols = 0; | ||
233 | ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) * | 232 | ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) * |
234 | DSP_MAX_SYMBOLS); | 233 | DSP_MAX_SYMBOLS); |
235 | ins->symbol_table.highest_frag_index = 0; | 234 | ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); |
236 | 235 | ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); | |
237 | if (ins->symbol_table.symbols == NULL) { | 236 | if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) { |
238 | cs46xx_dsp_spos_destroy(chip); | 237 | cs46xx_dsp_spos_destroy(chip); |
239 | goto error; | 238 | goto error; |
240 | } | 239 | } |
241 | 240 | ins->symbol_table.nsymbols = 0; | |
241 | ins->symbol_table.highest_frag_index = 0; | ||
242 | ins->code.offset = 0; | 242 | ins->code.offset = 0; |
243 | ins->code.size = 0; | 243 | ins->code.size = 0; |
244 | ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); | ||
245 | |||
246 | if (ins->code.data == NULL) { | ||
247 | cs46xx_dsp_spos_destroy(chip); | ||
248 | goto error; | ||
249 | } | ||
250 | |||
251 | ins->nscb = 0; | 244 | ins->nscb = 0; |
252 | ins->ntask = 0; | 245 | ins->ntask = 0; |
253 | |||
254 | ins->nmodules = 0; | 246 | ins->nmodules = 0; |
255 | ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); | ||
256 | |||
257 | if (ins->modules == NULL) { | ||
258 | cs46xx_dsp_spos_destroy(chip); | ||
259 | goto error; | ||
260 | } | ||
261 | 247 | ||
262 | /* default SPDIF input sample rate | 248 | /* default SPDIF input sample rate |
263 | to 48000 khz */ | 249 | to 48000 khz */ |
@@ -271,8 +257,8 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
271 | 257 | ||
272 | /* set left and right validity bits and | 258 | /* set left and right validity bits and |
273 | default channel status */ | 259 | default channel status */ |
274 | ins->spdif_csuv_default = | 260 | ins->spdif_csuv_default = |
275 | ins->spdif_csuv_stream = | 261 | ins->spdif_csuv_stream = |
276 | /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) | | 262 | /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) | |
277 | /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) | | 263 | /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) | |
278 | /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) | | 264 | /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) | |
@@ -281,6 +267,9 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
281 | return ins; | 267 | return ins; |
282 | 268 | ||
283 | error: | 269 | error: |
270 | kfree(ins->modules); | ||
271 | kfree(ins->code.data); | ||
272 | vfree(ins->symbol_table.symbols); | ||
284 | kfree(ins); | 273 | kfree(ins); |
285 | return NULL; | 274 | return NULL; |
286 | } | 275 | } |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 460fb2ef7e39..18af38ebf757 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -1166,6 +1166,7 @@ static const char *cs420x_models[CS420X_MODELS] = { | |||
1166 | 1166 | ||
1167 | static struct snd_pci_quirk cs420x_cfg_tbl[] = { | 1167 | static struct snd_pci_quirk cs420x_cfg_tbl[] = { |
1168 | SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), | 1168 | SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), |
1169 | SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), | ||
1169 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), | 1170 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), |
1170 | SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), | 1171 | SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), |
1171 | SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), | 1172 | SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index ef9af3f4ace2..1bd7a540fd49 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -425,7 +425,7 @@ exit: | |||
425 | static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) | 425 | static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) |
426 | { | 426 | { |
427 | struct snd_pcm_substream *substream = lx_stream->stream; | 427 | struct snd_pcm_substream *substream = lx_stream->stream; |
428 | const int is_capture = lx_stream->is_capture; | 428 | const unsigned int is_capture = lx_stream->is_capture; |
429 | 429 | ||
430 | int err; | 430 | int err; |
431 | 431 | ||
@@ -473,7 +473,7 @@ static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) | |||
473 | 473 | ||
474 | static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) | 474 | static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) |
475 | { | 475 | { |
476 | const int is_capture = lx_stream->is_capture; | 476 | const unsigned int is_capture = lx_stream->is_capture; |
477 | int err; | 477 | int err; |
478 | 478 | ||
479 | snd_printd(LXP "stopping: stopping stream\n"); | 479 | snd_printd(LXP "stopping: stopping stream\n"); |
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h index 51afc048961d..aea621eafbb5 100644 --- a/sound/pci/lx6464es/lx6464es.h +++ b/sound/pci/lx6464es/lx6464es.h | |||
@@ -60,7 +60,7 @@ struct lx_stream { | |||
60 | snd_pcm_uframes_t frame_pos; | 60 | snd_pcm_uframes_t frame_pos; |
61 | enum lx_stream_status status; /* free, open, running, draining | 61 | enum lx_stream_status status; /* free, open, running, draining |
62 | * pause */ | 62 | * pause */ |
63 | int is_capture:1; | 63 | unsigned int is_capture:1; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | 66 | ||
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 3086b751da4a..617f98b0cbae 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c | |||
@@ -1152,7 +1152,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip, | |||
1152 | struct lx_stream *lx_stream) | 1152 | struct lx_stream *lx_stream) |
1153 | { | 1153 | { |
1154 | struct snd_pcm_substream *substream = lx_stream->stream; | 1154 | struct snd_pcm_substream *substream = lx_stream->stream; |
1155 | int is_capture = lx_stream->is_capture; | 1155 | const unsigned int is_capture = lx_stream->is_capture; |
1156 | int err; | 1156 | int err; |
1157 | unsigned long flags; | 1157 | unsigned long flags; |
1158 | 1158 | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 94a9d06b9027..3b5690d28b8b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -25,8 +25,9 @@ config SND_SOC_ALL_CODECS | |||
25 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC | 25 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC |
26 | select SND_SOC_CS42L51 if I2C | 26 | select SND_SOC_CS42L51 if I2C |
27 | select SND_SOC_CS4270 if I2C | 27 | select SND_SOC_CS4270 if I2C |
28 | select SND_SOC_CX20442 | ||
28 | select SND_SOC_DA7210 if I2C | 29 | select SND_SOC_DA7210 if I2C |
29 | select SND_SOC_JZ4740 if SOC_JZ4740 | 30 | select SND_SOC_JZ4740_CODEC if SOC_JZ4740 |
30 | select SND_SOC_MAX98088 if I2C | 31 | select SND_SOC_MAX98088 if I2C |
31 | select SND_SOC_MAX9877 if I2C | 32 | select SND_SOC_MAX9877 if I2C |
32 | select SND_SOC_PCM3008 | 33 | select SND_SOC_PCM3008 |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index d251ff54a2d3..c5ab8c805771 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -58,7 +58,7 @@ | |||
58 | (1000000000 / ((rate * 1000) / samples)) | 58 | (1000000000 / ((rate * 1000) / samples)) |
59 | 59 | ||
60 | #define US_TO_SAMPLES(rate, us) \ | 60 | #define US_TO_SAMPLES(rate, us) \ |
61 | (rate / (1000000 / us)) | 61 | (rate / (1000000 / (us < 1000000 ? us : 1000000))) |
62 | 62 | ||
63 | #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ | 63 | #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ |
64 | ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) | 64 | ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) |
@@ -200,7 +200,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
200 | u8 *value) | 200 | u8 *value) |
201 | { | 201 | { |
202 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 202 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
203 | int val; | 203 | int val, ret = 0; |
204 | 204 | ||
205 | *value = reg & 0xff; | 205 | *value = reg & 0xff; |
206 | 206 | ||
@@ -210,6 +210,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
210 | if (val < 0) { | 210 | if (val < 0) { |
211 | dev_err(codec->dev, "Read failed (%d)\n", val); | 211 | dev_err(codec->dev, "Read failed (%d)\n", val); |
212 | value[0] = dac33_read_reg_cache(codec, reg); | 212 | value[0] = dac33_read_reg_cache(codec, reg); |
213 | ret = val; | ||
213 | } else { | 214 | } else { |
214 | value[0] = val; | 215 | value[0] = val; |
215 | dac33_write_reg_cache(codec, reg, val); | 216 | dac33_write_reg_cache(codec, reg, val); |
@@ -218,7 +219,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
218 | value[0] = dac33_read_reg_cache(codec, reg); | 219 | value[0] = dac33_read_reg_cache(codec, reg); |
219 | } | 220 | } |
220 | 221 | ||
221 | return 0; | 222 | return ret; |
222 | } | 223 | } |
223 | 224 | ||
224 | static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, | 225 | static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, |
@@ -329,13 +330,18 @@ static void dac33_init_chip(struct snd_soc_codec *codec) | |||
329 | dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); | 330 | dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); |
330 | } | 331 | } |
331 | 332 | ||
332 | static inline void dac33_read_id(struct snd_soc_codec *codec) | 333 | static inline int dac33_read_id(struct snd_soc_codec *codec) |
333 | { | 334 | { |
335 | int i, ret = 0; | ||
334 | u8 reg; | 336 | u8 reg; |
335 | 337 | ||
336 | dac33_read(codec, DAC33_DEVICE_ID_MSB, ®); | 338 | for (i = 0; i < 3; i++) { |
337 | dac33_read(codec, DAC33_DEVICE_ID_LSB, ®); | 339 | ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, ®); |
338 | dac33_read(codec, DAC33_DEVICE_REV_ID, ®); | 340 | if (ret < 0) |
341 | break; | ||
342 | } | ||
343 | |||
344 | return ret; | ||
339 | } | 345 | } |
340 | 346 | ||
341 | static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) | 347 | static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) |
@@ -1076,6 +1082,9 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||
1076 | /* Number of samples under i2c latency */ | 1082 | /* Number of samples under i2c latency */ |
1077 | dac33->alarm_threshold = US_TO_SAMPLES(rate, | 1083 | dac33->alarm_threshold = US_TO_SAMPLES(rate, |
1078 | dac33->mode1_latency); | 1084 | dac33->mode1_latency); |
1085 | nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - | ||
1086 | dac33->alarm_threshold; | ||
1087 | |||
1079 | if (dac33->auto_fifo_config) { | 1088 | if (dac33->auto_fifo_config) { |
1080 | if (period_size <= dac33->alarm_threshold) | 1089 | if (period_size <= dac33->alarm_threshold) |
1081 | /* | 1090 | /* |
@@ -1086,6 +1095,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||
1086 | ((dac33->alarm_threshold / period_size) + | 1095 | ((dac33->alarm_threshold / period_size) + |
1087 | (dac33->alarm_threshold % period_size ? | 1096 | (dac33->alarm_threshold % period_size ? |
1088 | 1 : 0)); | 1097 | 1 : 0)); |
1098 | else if (period_size > nsample_limit) | ||
1099 | dac33->nsample = nsample_limit; | ||
1089 | else | 1100 | else |
1090 | dac33->nsample = period_size; | 1101 | dac33->nsample = period_size; |
1091 | } else { | 1102 | } else { |
@@ -1097,8 +1108,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) | |||
1097 | */ | 1108 | */ |
1098 | dac33->nsample_max = substream->runtime->buffer_size - | 1109 | dac33->nsample_max = substream->runtime->buffer_size - |
1099 | period_size; | 1110 | period_size; |
1100 | nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - | 1111 | |
1101 | dac33->alarm_threshold; | ||
1102 | if (dac33->nsample_max > nsample_limit) | 1112 | if (dac33->nsample_max > nsample_limit) |
1103 | dac33->nsample_max = nsample_limit; | 1113 | dac33->nsample_max = nsample_limit; |
1104 | 1114 | ||
@@ -1414,9 +1424,15 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1414 | dev_err(codec->dev, "Failed to power up codec: %d\n", ret); | 1424 | dev_err(codec->dev, "Failed to power up codec: %d\n", ret); |
1415 | goto err_power; | 1425 | goto err_power; |
1416 | } | 1426 | } |
1417 | dac33_read_id(codec); | 1427 | ret = dac33_read_id(codec); |
1418 | dac33_hard_power(codec, 0); | 1428 | dac33_hard_power(codec, 0); |
1419 | 1429 | ||
1430 | if (ret < 0) { | ||
1431 | dev_err(codec->dev, "Failed to read chip ID: %d\n", ret); | ||
1432 | ret = -ENODEV; | ||
1433 | goto err_power; | ||
1434 | } | ||
1435 | |||
1420 | /* Check if the IRQ number is valid and request it */ | 1436 | /* Check if the IRQ number is valid and request it */ |
1421 | if (dac33->irq >= 0) { | 1437 | if (dac33->irq >= 0) { |
1422 | ret = request_irq(dac33->irq, dac33_interrupt_handler, | 1438 | ret = request_irq(dac33->irq, dac33_interrupt_handler, |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 329acc1a2074..ee4fb201de60 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -119,13 +119,13 @@ static int tpa6130a2_power(int power) | |||
119 | { | 119 | { |
120 | struct tpa6130a2_data *data; | 120 | struct tpa6130a2_data *data; |
121 | u8 val; | 121 | u8 val; |
122 | int ret; | 122 | int ret = 0; |
123 | 123 | ||
124 | BUG_ON(tpa6130a2_client == NULL); | 124 | BUG_ON(tpa6130a2_client == NULL); |
125 | data = i2c_get_clientdata(tpa6130a2_client); | 125 | data = i2c_get_clientdata(tpa6130a2_client); |
126 | 126 | ||
127 | mutex_lock(&data->mutex); | 127 | mutex_lock(&data->mutex); |
128 | if (power) { | 128 | if (power && !data->power_state) { |
129 | /* Power on */ | 129 | /* Power on */ |
130 | if (data->power_gpio >= 0) | 130 | if (data->power_gpio >= 0) |
131 | gpio_set_value(data->power_gpio, 1); | 131 | gpio_set_value(data->power_gpio, 1); |
@@ -153,7 +153,7 @@ static int tpa6130a2_power(int power) | |||
153 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); | 153 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); |
154 | val &= ~TPA6130A2_SWS; | 154 | val &= ~TPA6130A2_SWS; |
155 | tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); | 155 | tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); |
156 | } else { | 156 | } else if (!power && data->power_state) { |
157 | /* set SWS */ | 157 | /* set SWS */ |
158 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); | 158 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); |
159 | val |= TPA6130A2_SWS; | 159 | val |= TPA6130A2_SWS; |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index b4f11724a63f..aca4b1ea10bb 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -186,7 +186,6 @@ static int wm8900_volatile_register(unsigned int reg) | |||
186 | { | 186 | { |
187 | switch (reg) { | 187 | switch (reg) { |
188 | case WM8900_REG_ID: | 188 | case WM8900_REG_ID: |
189 | case WM8900_REG_POWER1: | ||
190 | return 1; | 189 | return 1; |
191 | default: | 190 | default: |
192 | return 0; | 191 | return 0; |
@@ -1200,11 +1199,6 @@ static int wm8900_probe(struct snd_soc_codec *codec) | |||
1200 | return -ENODEV; | 1199 | return -ENODEV; |
1201 | } | 1200 | } |
1202 | 1201 | ||
1203 | /* Read back from the chip */ | ||
1204 | reg = snd_soc_read(codec, WM8900_REG_POWER1); | ||
1205 | reg = (reg >> 12) & 0xf; | ||
1206 | dev_info(codec->dev, "WM8900 revision %d\n", reg); | ||
1207 | |||
1208 | wm8900_reset(codec); | 1202 | wm8900_reset(codec); |
1209 | 1203 | ||
1210 | /* Turn the chip on */ | 1204 | /* Turn the chip on */ |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 2cb81538cd91..19ca782ac970 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -123,7 +123,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
123 | reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | 123 | reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; |
124 | break; | 124 | break; |
125 | default: | 125 | default: |
126 | WARN(1, "Unknown DCS readback method"); | 126 | WARN(1, "Unknown DCS readback method\n"); |
127 | break; | 127 | break; |
128 | } | 128 | } |
129 | 129 | ||
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index a3bfb2e8b70f..73d0edd8ded9 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c | |||
@@ -79,7 +79,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec) | |||
79 | static int tosa_startup(struct snd_pcm_substream *substream) | 79 | static int tosa_startup(struct snd_pcm_substream *substream) |
80 | { | 80 | { |
81 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 81 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
82 | struct snd_soc_codec *codec = rtd->card->codec; | 82 | struct snd_soc_codec *codec = rtd->codec; |
83 | 83 | ||
84 | /* check the jack status at stream startup */ | 84 | /* check the jack status at stream startup */ |
85 | tosa_ext_control(codec); | 85 | tosa_ext_control(codec); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1c8f3f507f54..614a8b30d87b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -165,8 +165,11 @@ static ssize_t pmdown_time_set(struct device *dev, | |||
165 | { | 165 | { |
166 | struct snd_soc_pcm_runtime *rtd = | 166 | struct snd_soc_pcm_runtime *rtd = |
167 | container_of(dev, struct snd_soc_pcm_runtime, dev); | 167 | container_of(dev, struct snd_soc_pcm_runtime, dev); |
168 | int ret; | ||
168 | 169 | ||
169 | strict_strtol(buf, 10, &rtd->pmdown_time); | 170 | ret = strict_strtol(buf, 10, &rtd->pmdown_time); |
171 | if (ret) | ||
172 | return ret; | ||
170 | 173 | ||
171 | return count; | 174 | return count; |
172 | } | 175 | } |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 7dae05d8783e..782f741cd00a 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -60,7 +60,7 @@ static const struct rc_config { | |||
60 | { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */ | 60 | { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */ |
61 | { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ | 61 | { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ |
62 | { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ | 62 | { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ |
63 | { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi */ | 63 | { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ |
64 | { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ | 64 | { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ |
65 | }; | 65 | }; |
66 | 66 | ||
@@ -183,7 +183,13 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
183 | if (value > 1) | 183 | if (value > 1) |
184 | return -EINVAL; | 184 | return -EINVAL; |
185 | changed = value != mixer->audigy2nx_leds[index]; | 185 | changed = value != mixer->audigy2nx_leds[index]; |
186 | err = snd_usb_ctl_msg(mixer->chip->dev, | 186 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) |
187 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
188 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | ||
189 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | ||
190 | !value, 0, NULL, 0, 100); | ||
191 | else | ||
192 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
187 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 193 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
188 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 194 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
189 | value, index + 2, NULL, 0, 100); | 195 | value, index + 2, NULL, 0, 100); |
@@ -225,8 +231,12 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) | |||
225 | int i, err; | 231 | int i, err; |
226 | 232 | ||
227 | for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { | 233 | for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { |
234 | /* USB X-Fi S51 doesn't have a CMSS LED */ | ||
235 | if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) | ||
236 | continue; | ||
228 | if (i > 1 && /* Live24ext has 2 LEDs only */ | 237 | if (i > 1 && /* Live24ext has 2 LEDs only */ |
229 | (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || | 238 | (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || |
239 | mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || | ||
230 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) | 240 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) |
231 | break; | 241 | break; |
232 | err = snd_ctl_add(mixer->chip->card, | 242 | err = snd_ctl_add(mixer->chip->card, |
@@ -365,6 +375,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
365 | 375 | ||
366 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || | 376 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || |
367 | mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || | 377 | mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || |
378 | mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || | ||
368 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { | 379 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { |
369 | if ((err = snd_audigy2nx_controls_create(mixer)) < 0) | 380 | if ((err = snd_audigy2nx_controls_create(mixer)) < 0) |
370 | return err; | 381 | return err; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index cff3a3c465d7..4132522ac90f 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -676,8 +676,10 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
676 | if (!needs_knot) | 676 | if (!needs_knot) |
677 | return 0; | 677 | return 0; |
678 | 678 | ||
679 | subs->rate_list.count = count; | ||
680 | subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); | 679 | subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); |
680 | if (!subs->rate_list.list) | ||
681 | return -ENOMEM; | ||
682 | subs->rate_list.count = count; | ||
681 | subs->rate_list.mask = 0; | 683 | subs->rate_list.mask = 0; |
682 | count = 0; | 684 | count = 0; |
683 | list_for_each_entry(fp, &subs->fmt_list, list) { | 685 | list_for_each_entry(fp, &subs->fmt_list, list) { |
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 122ec9dc4853..26aff6bf9e50 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt | |||
@@ -8,7 +8,11 @@ perf-trace - Read perf.data (created by perf record) and display trace output | |||
8 | SYNOPSIS | 8 | SYNOPSIS |
9 | -------- | 9 | -------- |
10 | [verse] | 10 | [verse] |
11 | 'perf trace' {record <script> | report <script> [args] } | 11 | 'perf trace' [<options>] |
12 | 'perf trace' [<options>] record <script> [<record-options>] <command> | ||
13 | 'perf trace' [<options>] report <script> [script-args] | ||
14 | 'perf trace' [<options>] <script> <required-script-args> [<record-options>] <command> | ||
15 | 'perf trace' [<options>] <top-script> [script-args] | ||
12 | 16 | ||
13 | DESCRIPTION | 17 | DESCRIPTION |
14 | ----------- | 18 | ----------- |
@@ -24,23 +28,53 @@ There are several variants of perf trace: | |||
24 | available via 'perf trace -l'). The following variants allow you to | 28 | available via 'perf trace -l'). The following variants allow you to |
25 | record and run those scripts: | 29 | record and run those scripts: |
26 | 30 | ||
27 | 'perf trace record <script>' to record the events required for 'perf | 31 | 'perf trace record <script> <command>' to record the events required |
28 | trace report'. <script> is the name displayed in the output of | 32 | for 'perf trace report'. <script> is the name displayed in the |
29 | 'perf trace --list' i.e. the actual script name minus any language | 33 | output of 'perf trace --list' i.e. the actual script name minus any |
30 | extension. | 34 | language extension. If <command> is not specified, the events are |
35 | recorded using the -a (system-wide) 'perf record' option. | ||
31 | 36 | ||
32 | 'perf trace report <script>' to run and display the results of | 37 | 'perf trace report <script> [args]' to run and display the results |
33 | <script>. <script> is the name displayed in the output of 'perf | 38 | of <script>. <script> is the name displayed in the output of 'perf |
34 | trace --list' i.e. the actual script name minus any language | 39 | trace --list' i.e. the actual script name minus any language |
35 | extension. The perf.data output from a previous run of 'perf trace | 40 | extension. The perf.data output from a previous run of 'perf trace |
36 | record <script>' is used and should be present for this command to | 41 | record <script>' is used and should be present for this command to |
37 | succeed. | 42 | succeed. [args] refers to the (mainly optional) args expected by |
43 | the script. | ||
44 | |||
45 | 'perf trace <script> <required-script-args> <command>' to both | ||
46 | record the events required for <script> and to run the <script> | ||
47 | using 'live-mode' i.e. without writing anything to disk. <script> | ||
48 | is the name displayed in the output of 'perf trace --list' i.e. the | ||
49 | actual script name minus any language extension. If <command> is | ||
50 | not specified, the events are recorded using the -a (system-wide) | ||
51 | 'perf record' option. If <script> has any required args, they | ||
52 | should be specified before <command>. This mode doesn't allow for | ||
53 | optional script args to be specified; if optional script args are | ||
54 | desired, they can be specified using separate 'perf trace record' | ||
55 | and 'perf trace report' commands, with the stdout of the record step | ||
56 | piped to the stdin of the report script, using the '-o -' and '-i -' | ||
57 | options of the corresponding commands. | ||
58 | |||
59 | 'perf trace <top-script>' to both record the events required for | ||
60 | <top-script> and to run the <top-script> using 'live-mode' | ||
61 | i.e. without writing anything to disk. <top-script> is the name | ||
62 | displayed in the output of 'perf trace --list' i.e. the actual | ||
63 | script name minus any language extension; a <top-script> is defined | ||
64 | as any script name ending with the string 'top'. | ||
65 | |||
66 | [<record-options>] can be passed to the record steps of 'perf trace | ||
67 | record' and 'live-mode' variants; this isn't possible however for | ||
68 | <top-script> 'live-mode' or 'perf trace report' variants. | ||
38 | 69 | ||
39 | See the 'SEE ALSO' section for links to language-specific | 70 | See the 'SEE ALSO' section for links to language-specific |
40 | information on how to write and run your own trace scripts. | 71 | information on how to write and run your own trace scripts. |
41 | 72 | ||
42 | OPTIONS | 73 | OPTIONS |
43 | ------- | 74 | ------- |
75 | <command>...:: | ||
76 | Any command you can specify in a shell. | ||
77 | |||
44 | -D:: | 78 | -D:: |
45 | --dump-raw-trace=:: | 79 | --dump-raw-trace=:: |
46 | Display verbose dump of the trace data. | 80 | Display verbose dump of the trace data. |
@@ -64,6 +98,13 @@ OPTIONS | |||
64 | Generate perf-trace.[ext] starter script for given language, | 98 | Generate perf-trace.[ext] starter script for given language, |
65 | using current perf.data. | 99 | using current perf.data. |
66 | 100 | ||
101 | -a:: | ||
102 | Force system-wide collection. Scripts run without a <command> | ||
103 | normally use -a by default, while scripts run with a <command> | ||
104 | normally don't - this option allows the latter to be run in | ||
105 | system-wide mode. | ||
106 | |||
107 | |||
67 | SEE ALSO | 108 | SEE ALSO |
68 | -------- | 109 | -------- |
69 | linkperf:perf-record[1], linkperf:perf-trace-perl[1], | 110 | linkperf:perf-record[1], linkperf:perf-trace-perl[1], |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4e75583ddd6d..93bd2ff001fb 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -790,7 +790,7 @@ static const char * const record_usage[] = { | |||
790 | 790 | ||
791 | static bool force, append_file; | 791 | static bool force, append_file; |
792 | 792 | ||
793 | static const struct option options[] = { | 793 | const struct option record_options[] = { |
794 | OPT_CALLBACK('e', "event", NULL, "event", | 794 | OPT_CALLBACK('e', "event", NULL, "event", |
795 | "event selector. use 'perf list' to list available events", | 795 | "event selector. use 'perf list' to list available events", |
796 | parse_events), | 796 | parse_events), |
@@ -839,16 +839,16 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
839 | { | 839 | { |
840 | int i, j, err = -ENOMEM; | 840 | int i, j, err = -ENOMEM; |
841 | 841 | ||
842 | argc = parse_options(argc, argv, options, record_usage, | 842 | argc = parse_options(argc, argv, record_options, record_usage, |
843 | PARSE_OPT_STOP_AT_NON_OPTION); | 843 | PARSE_OPT_STOP_AT_NON_OPTION); |
844 | if (!argc && target_pid == -1 && target_tid == -1 && | 844 | if (!argc && target_pid == -1 && target_tid == -1 && |
845 | !system_wide && !cpu_list) | 845 | !system_wide && !cpu_list) |
846 | usage_with_options(record_usage, options); | 846 | usage_with_options(record_usage, record_options); |
847 | 847 | ||
848 | if (force && append_file) { | 848 | if (force && append_file) { |
849 | fprintf(stderr, "Can't overwrite and append at the same time." | 849 | fprintf(stderr, "Can't overwrite and append at the same time." |
850 | " You need to choose between -f and -A"); | 850 | " You need to choose between -f and -A"); |
851 | usage_with_options(record_usage, options); | 851 | usage_with_options(record_usage, record_options); |
852 | } else if (append_file) { | 852 | } else if (append_file) { |
853 | write_mode = WRITE_APPEND; | 853 | write_mode = WRITE_APPEND; |
854 | } else { | 854 | } else { |
@@ -871,7 +871,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
871 | if (thread_num <= 0) { | 871 | if (thread_num <= 0) { |
872 | fprintf(stderr, "Can't find all threads of pid %d\n", | 872 | fprintf(stderr, "Can't find all threads of pid %d\n", |
873 | target_pid); | 873 | target_pid); |
874 | usage_with_options(record_usage, options); | 874 | usage_with_options(record_usage, record_options); |
875 | } | 875 | } |
876 | } else { | 876 | } else { |
877 | all_tids=malloc(sizeof(pid_t)); | 877 | all_tids=malloc(sizeof(pid_t)); |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b513e40974f4..dd625808c2a5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -69,7 +69,6 @@ static int target_tid = -1; | |||
69 | static pid_t *all_tids = NULL; | 69 | static pid_t *all_tids = NULL; |
70 | static int thread_num = 0; | 70 | static int thread_num = 0; |
71 | static bool inherit = false; | 71 | static bool inherit = false; |
72 | static int profile_cpu = -1; | ||
73 | static int nr_cpus = 0; | 72 | static int nr_cpus = 0; |
74 | static int realtime_prio = 0; | 73 | static int realtime_prio = 0; |
75 | static bool group = false; | 74 | static bool group = false; |
@@ -558,13 +557,13 @@ static void print_sym_table(void) | |||
558 | else | 557 | else |
559 | printf(" (all"); | 558 | printf(" (all"); |
560 | 559 | ||
561 | if (profile_cpu != -1) | 560 | if (cpu_list) |
562 | printf(", cpu: %d)\n", profile_cpu); | 561 | printf(", CPU%s: %s)\n", nr_cpus > 1 ? "s" : "", cpu_list); |
563 | else { | 562 | else { |
564 | if (target_tid != -1) | 563 | if (target_tid != -1) |
565 | printf(")\n"); | 564 | printf(")\n"); |
566 | else | 565 | else |
567 | printf(", %d CPUs)\n", nr_cpus); | 566 | printf(", %d CPU%s)\n", nr_cpus, nr_cpus > 1 ? "s" : ""); |
568 | } | 567 | } |
569 | 568 | ||
570 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); | 569 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); |
@@ -1187,11 +1186,10 @@ int group_fd; | |||
1187 | static void start_counter(int i, int counter) | 1186 | static void start_counter(int i, int counter) |
1188 | { | 1187 | { |
1189 | struct perf_event_attr *attr; | 1188 | struct perf_event_attr *attr; |
1190 | int cpu; | 1189 | int cpu = -1; |
1191 | int thread_index; | 1190 | int thread_index; |
1192 | 1191 | ||
1193 | cpu = profile_cpu; | 1192 | if (target_tid == -1) |
1194 | if (target_tid == -1 && profile_cpu == -1) | ||
1195 | cpu = cpumap[i]; | 1193 | cpu = cpumap[i]; |
1196 | 1194 | ||
1197 | attr = attrs + counter; | 1195 | attr = attrs + counter; |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2f8df45c4dcb..86cfe3800e6b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "util/symbol.h" | 10 | #include "util/symbol.h" |
11 | #include "util/thread.h" | 11 | #include "util/thread.h" |
12 | #include "util/trace-event.h" | 12 | #include "util/trace-event.h" |
13 | #include "util/parse-options.h" | ||
13 | #include "util/util.h" | 14 | #include "util/util.h" |
14 | 15 | ||
15 | static char const *script_name; | 16 | static char const *script_name; |
@@ -17,6 +18,7 @@ static char const *generate_script_lang; | |||
17 | static bool debug_mode; | 18 | static bool debug_mode; |
18 | static u64 last_timestamp; | 19 | static u64 last_timestamp; |
19 | static u64 nr_unordered; | 20 | static u64 nr_unordered; |
21 | extern const struct option record_options[]; | ||
20 | 22 | ||
21 | static int default_start_script(const char *script __unused, | 23 | static int default_start_script(const char *script __unused, |
22 | int argc __unused, | 24 | int argc __unused, |
@@ -328,7 +330,7 @@ static struct script_desc *script_desc__new(const char *name) | |||
328 | { | 330 | { |
329 | struct script_desc *s = zalloc(sizeof(*s)); | 331 | struct script_desc *s = zalloc(sizeof(*s)); |
330 | 332 | ||
331 | if (s != NULL) | 333 | if (s != NULL && name) |
332 | s->name = strdup(name); | 334 | s->name = strdup(name); |
333 | 335 | ||
334 | return s; | 336 | return s; |
@@ -337,6 +339,8 @@ static struct script_desc *script_desc__new(const char *name) | |||
337 | static void script_desc__delete(struct script_desc *s) | 339 | static void script_desc__delete(struct script_desc *s) |
338 | { | 340 | { |
339 | free(s->name); | 341 | free(s->name); |
342 | free(s->half_liner); | ||
343 | free(s->args); | ||
340 | free(s); | 344 | free(s); |
341 | } | 345 | } |
342 | 346 | ||
@@ -537,8 +541,40 @@ static char *get_script_path(const char *script_root, const char *suffix) | |||
537 | return path; | 541 | return path; |
538 | } | 542 | } |
539 | 543 | ||
544 | static bool is_top_script(const char *script_path) | ||
545 | { | ||
546 | return ends_with((char *)script_path, "top") == NULL ? false : true; | ||
547 | } | ||
548 | |||
549 | static int has_required_arg(char *script_path) | ||
550 | { | ||
551 | struct script_desc *desc; | ||
552 | int n_args = 0; | ||
553 | char *p; | ||
554 | |||
555 | desc = script_desc__new(NULL); | ||
556 | |||
557 | if (read_script_info(desc, script_path)) | ||
558 | goto out; | ||
559 | |||
560 | if (!desc->args) | ||
561 | goto out; | ||
562 | |||
563 | for (p = desc->args; *p; p++) | ||
564 | if (*p == '<') | ||
565 | n_args++; | ||
566 | out: | ||
567 | script_desc__delete(desc); | ||
568 | |||
569 | return n_args; | ||
570 | } | ||
571 | |||
540 | static const char * const trace_usage[] = { | 572 | static const char * const trace_usage[] = { |
541 | "perf trace [<options>] <command>", | 573 | "perf trace [<options>]", |
574 | "perf trace [<options>] record <script> [<record-options>] <command>", | ||
575 | "perf trace [<options>] report <script> [script-args]", | ||
576 | "perf trace [<options>] <script> [<record-options>] <command>", | ||
577 | "perf trace [<options>] <top-script> [script-args]", | ||
542 | NULL | 578 | NULL |
543 | }; | 579 | }; |
544 | 580 | ||
@@ -564,50 +600,81 @@ static const struct option options[] = { | |||
564 | OPT_END() | 600 | OPT_END() |
565 | }; | 601 | }; |
566 | 602 | ||
603 | static bool have_cmd(int argc, const char **argv) | ||
604 | { | ||
605 | char **__argv = malloc(sizeof(const char *) * argc); | ||
606 | |||
607 | if (!__argv) | ||
608 | die("malloc"); | ||
609 | memcpy(__argv, argv, sizeof(const char *) * argc); | ||
610 | argc = parse_options(argc, (const char **)__argv, record_options, | ||
611 | NULL, PARSE_OPT_STOP_AT_NON_OPTION); | ||
612 | free(__argv); | ||
613 | |||
614 | return argc != 0; | ||
615 | } | ||
616 | |||
567 | int cmd_trace(int argc, const char **argv, const char *prefix __used) | 617 | int cmd_trace(int argc, const char **argv, const char *prefix __used) |
568 | { | 618 | { |
619 | char *rec_script_path = NULL; | ||
620 | char *rep_script_path = NULL; | ||
569 | struct perf_session *session; | 621 | struct perf_session *session; |
570 | const char *suffix = NULL; | 622 | char *script_path = NULL; |
571 | const char **__argv; | 623 | const char **__argv; |
572 | char *script_path; | 624 | bool system_wide; |
573 | int i, err; | 625 | int i, j, err; |
574 | 626 | ||
575 | if (argc >= 2 && strncmp(argv[1], "rec", strlen("rec")) == 0) { | 627 | setup_scripting(); |
576 | if (argc < 3) { | 628 | |
577 | fprintf(stderr, | 629 | argc = parse_options(argc, argv, options, trace_usage, |
578 | "Please specify a record script\n"); | 630 | PARSE_OPT_STOP_AT_NON_OPTION); |
579 | return -1; | 631 | |
580 | } | 632 | if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { |
581 | suffix = RECORD_SUFFIX; | 633 | rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); |
634 | if (!rec_script_path) | ||
635 | return cmd_record(argc, argv, NULL); | ||
582 | } | 636 | } |
583 | 637 | ||
584 | if (argc >= 2 && strncmp(argv[1], "rep", strlen("rep")) == 0) { | 638 | if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { |
585 | if (argc < 3) { | 639 | rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); |
640 | if (!rep_script_path) { | ||
586 | fprintf(stderr, | 641 | fprintf(stderr, |
587 | "Please specify a report script\n"); | 642 | "Please specify a valid report script" |
643 | "(see 'perf trace -l' for listing)\n"); | ||
588 | return -1; | 644 | return -1; |
589 | } | 645 | } |
590 | suffix = REPORT_SUFFIX; | ||
591 | } | 646 | } |
592 | 647 | ||
593 | /* make sure PERF_EXEC_PATH is set for scripts */ | 648 | /* make sure PERF_EXEC_PATH is set for scripts */ |
594 | perf_set_argv_exec_path(perf_exec_path()); | 649 | perf_set_argv_exec_path(perf_exec_path()); |
595 | 650 | ||
596 | if (!suffix && argc >= 2 && strncmp(argv[1], "-", strlen("-")) != 0) { | 651 | if (argc && !script_name && !rec_script_path && !rep_script_path) { |
597 | char *record_script_path, *report_script_path; | ||
598 | int live_pipe[2]; | 652 | int live_pipe[2]; |
653 | int rep_args; | ||
599 | pid_t pid; | 654 | pid_t pid; |
600 | 655 | ||
601 | record_script_path = get_script_path(argv[1], RECORD_SUFFIX); | 656 | rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); |
602 | if (!record_script_path) { | 657 | rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); |
603 | fprintf(stderr, "record script not found\n"); | 658 | |
604 | return -1; | 659 | if (!rec_script_path && !rep_script_path) { |
660 | fprintf(stderr, " Couldn't find script %s\n\n See perf" | ||
661 | " trace -l for available scripts.\n", argv[0]); | ||
662 | usage_with_options(trace_usage, options); | ||
605 | } | 663 | } |
606 | 664 | ||
607 | report_script_path = get_script_path(argv[1], REPORT_SUFFIX); | 665 | if (is_top_script(argv[0])) { |
608 | if (!report_script_path) { | 666 | rep_args = argc - 1; |
609 | fprintf(stderr, "report script not found\n"); | 667 | } else { |
610 | return -1; | 668 | int rec_args; |
669 | |||
670 | rep_args = has_required_arg(rep_script_path); | ||
671 | rec_args = (argc - 1) - rep_args; | ||
672 | if (rec_args < 0) { | ||
673 | fprintf(stderr, " %s script requires options." | ||
674 | "\n\n See perf trace -l for available " | ||
675 | "scripts and options.\n", argv[0]); | ||
676 | usage_with_options(trace_usage, options); | ||
677 | } | ||
611 | } | 678 | } |
612 | 679 | ||
613 | if (pipe(live_pipe) < 0) { | 680 | if (pipe(live_pipe) < 0) { |
@@ -622,60 +689,84 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) | |||
622 | } | 689 | } |
623 | 690 | ||
624 | if (!pid) { | 691 | if (!pid) { |
692 | system_wide = true; | ||
693 | j = 0; | ||
694 | |||
625 | dup2(live_pipe[1], 1); | 695 | dup2(live_pipe[1], 1); |
626 | close(live_pipe[0]); | 696 | close(live_pipe[0]); |
627 | 697 | ||
628 | __argv = malloc(6 * sizeof(const char *)); | 698 | if (!is_top_script(argv[0])) |
629 | __argv[0] = "/bin/sh"; | 699 | system_wide = !have_cmd(argc - rep_args, |
630 | __argv[1] = record_script_path; | 700 | &argv[rep_args]); |
631 | __argv[2] = "-q"; | 701 | |
632 | __argv[3] = "-o"; | 702 | __argv = malloc((argc + 6) * sizeof(const char *)); |
633 | __argv[4] = "-"; | 703 | if (!__argv) |
634 | __argv[5] = NULL; | 704 | die("malloc"); |
705 | |||
706 | __argv[j++] = "/bin/sh"; | ||
707 | __argv[j++] = rec_script_path; | ||
708 | if (system_wide) | ||
709 | __argv[j++] = "-a"; | ||
710 | __argv[j++] = "-q"; | ||
711 | __argv[j++] = "-o"; | ||
712 | __argv[j++] = "-"; | ||
713 | for (i = rep_args + 1; i < argc; i++) | ||
714 | __argv[j++] = argv[i]; | ||
715 | __argv[j++] = NULL; | ||
635 | 716 | ||
636 | execvp("/bin/sh", (char **)__argv); | 717 | execvp("/bin/sh", (char **)__argv); |
718 | free(__argv); | ||
637 | exit(-1); | 719 | exit(-1); |
638 | } | 720 | } |
639 | 721 | ||
640 | dup2(live_pipe[0], 0); | 722 | dup2(live_pipe[0], 0); |
641 | close(live_pipe[1]); | 723 | close(live_pipe[1]); |
642 | 724 | ||
643 | __argv = malloc((argc + 3) * sizeof(const char *)); | 725 | __argv = malloc((argc + 4) * sizeof(const char *)); |
644 | __argv[0] = "/bin/sh"; | 726 | if (!__argv) |
645 | __argv[1] = report_script_path; | 727 | die("malloc"); |
646 | for (i = 2; i < argc; i++) | 728 | j = 0; |
647 | __argv[i] = argv[i]; | 729 | __argv[j++] = "/bin/sh"; |
648 | __argv[i++] = "-i"; | 730 | __argv[j++] = rep_script_path; |
649 | __argv[i++] = "-"; | 731 | for (i = 1; i < rep_args + 1; i++) |
650 | __argv[i++] = NULL; | 732 | __argv[j++] = argv[i]; |
733 | __argv[j++] = "-i"; | ||
734 | __argv[j++] = "-"; | ||
735 | __argv[j++] = NULL; | ||
651 | 736 | ||
652 | execvp("/bin/sh", (char **)__argv); | 737 | execvp("/bin/sh", (char **)__argv); |
738 | free(__argv); | ||
653 | exit(-1); | 739 | exit(-1); |
654 | } | 740 | } |
655 | 741 | ||
656 | if (suffix) { | 742 | if (rec_script_path) |
657 | script_path = get_script_path(argv[2], suffix); | 743 | script_path = rec_script_path; |
658 | if (!script_path) { | 744 | if (rep_script_path) |
659 | fprintf(stderr, "script not found\n"); | 745 | script_path = rep_script_path; |
660 | return -1; | 746 | |
661 | } | 747 | if (script_path) { |
662 | 748 | system_wide = false; | |
663 | __argv = malloc((argc + 1) * sizeof(const char *)); | 749 | j = 0; |
664 | __argv[0] = "/bin/sh"; | 750 | |
665 | __argv[1] = script_path; | 751 | if (rec_script_path) |
666 | for (i = 3; i < argc; i++) | 752 | system_wide = !have_cmd(argc - 1, &argv[1]); |
667 | __argv[i - 1] = argv[i]; | 753 | |
668 | __argv[argc - 1] = NULL; | 754 | __argv = malloc((argc + 2) * sizeof(const char *)); |
755 | if (!__argv) | ||
756 | die("malloc"); | ||
757 | __argv[j++] = "/bin/sh"; | ||
758 | __argv[j++] = script_path; | ||
759 | if (system_wide) | ||
760 | __argv[j++] = "-a"; | ||
761 | for (i = 2; i < argc; i++) | ||
762 | __argv[j++] = argv[i]; | ||
763 | __argv[j++] = NULL; | ||
669 | 764 | ||
670 | execvp("/bin/sh", (char **)__argv); | 765 | execvp("/bin/sh", (char **)__argv); |
766 | free(__argv); | ||
671 | exit(-1); | 767 | exit(-1); |
672 | } | 768 | } |
673 | 769 | ||
674 | setup_scripting(); | ||
675 | |||
676 | argc = parse_options(argc, argv, options, trace_usage, | ||
677 | PARSE_OPT_STOP_AT_NON_OPTION); | ||
678 | |||
679 | if (symbol__init() < 0) | 770 | if (symbol__init() < 0) |
680 | return -1; | 771 | return -1; |
681 | if (!script_name) | 772 | if (!script_name) |
diff --git a/tools/perf/scripts/perl/bin/failed-syscalls-record b/tools/perf/scripts/perl/bin/failed-syscalls-record index eb5846bcb565..8104895a7b67 100644 --- a/tools/perf/scripts/perl/bin/failed-syscalls-record +++ b/tools/perf/scripts/perl/bin/failed-syscalls-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e raw_syscalls:sys_exit $@ | 2 | perf record -e raw_syscalls:sys_exit $@ |
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-record b/tools/perf/scripts/perl/bin/rw-by-file-record index 5bfaae5a6cba..33efc8673aae 100644 --- a/tools/perf/scripts/perl/bin/rw-by-file-record +++ b/tools/perf/scripts/perl/bin/rw-by-file-record | |||
@@ -1,3 +1,3 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@ | 2 | perf record -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@ |
3 | 3 | ||
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-record b/tools/perf/scripts/perl/bin/rw-by-pid-record index 6e0b2f7755ac..7cb9db230448 100644 --- a/tools/perf/scripts/perl/bin/rw-by-pid-record +++ b/tools/perf/scripts/perl/bin/rw-by-pid-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@ | 2 | perf record -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@ |
diff --git a/tools/perf/scripts/perl/bin/rwtop-record b/tools/perf/scripts/perl/bin/rwtop-record index 6e0b2f7755ac..7cb9db230448 100644 --- a/tools/perf/scripts/perl/bin/rwtop-record +++ b/tools/perf/scripts/perl/bin/rwtop-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@ | 2 | perf record -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@ |
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-record b/tools/perf/scripts/perl/bin/wakeup-latency-record index 9f2acaaae9f0..464251a1bd7e 100644 --- a/tools/perf/scripts/perl/bin/wakeup-latency-record +++ b/tools/perf/scripts/perl/bin/wakeup-latency-record | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e sched:sched_switch -e sched:sched_wakeup $@ | 2 | perf record -e sched:sched_switch -e sched:sched_wakeup $@ |
3 | 3 | ||
4 | 4 | ||
5 | 5 | ||
diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-record b/tools/perf/scripts/perl/bin/workqueue-stats-record index 85301f2471ff..8edda9078d5d 100644 --- a/tools/perf/scripts/perl/bin/workqueue-stats-record +++ b/tools/perf/scripts/perl/bin/workqueue-stats-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@ | 2 | perf record -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@ |
diff --git a/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record index eb5846bcb565..8104895a7b67 100644 --- a/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record +++ b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e raw_syscalls:sys_exit $@ | 2 | perf record -e raw_syscalls:sys_exit $@ |
diff --git a/tools/perf/scripts/python/bin/futex-contention-record b/tools/perf/scripts/python/bin/futex-contention-record index 5ecbb433caf4..b1495c9a9b20 100644 --- a/tools/perf/scripts/python/bin/futex-contention-record +++ b/tools/perf/scripts/python/bin/futex-contention-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex $@ | 2 | perf record -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex $@ |
diff --git a/tools/perf/scripts/python/bin/netdev-times-record b/tools/perf/scripts/python/bin/netdev-times-record index d931a828126b..558754b840a9 100644 --- a/tools/perf/scripts/python/bin/netdev-times-record +++ b/tools/perf/scripts/python/bin/netdev-times-record | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e net:net_dev_xmit -e net:net_dev_queue \ | 2 | perf record -e net:net_dev_xmit -e net:net_dev_queue \ |
3 | -e net:netif_receive_skb -e net:netif_rx \ | 3 | -e net:netif_receive_skb -e net:netif_rx \ |
4 | -e skb:consume_skb -e skb:kfree_skb \ | 4 | -e skb:consume_skb -e skb:kfree_skb \ |
5 | -e skb:skb_copy_datagram_iovec -e napi:napi_poll \ | 5 | -e skb:skb_copy_datagram_iovec -e napi:napi_poll \ |
diff --git a/tools/perf/scripts/python/bin/sched-migration-record b/tools/perf/scripts/python/bin/sched-migration-record index 17a3e9bd9e8f..7493fddbe995 100644 --- a/tools/perf/scripts/python/bin/sched-migration-record +++ b/tools/perf/scripts/python/bin/sched-migration-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -m 16384 -a -e sched:sched_wakeup -e sched:sched_wakeup_new -e sched:sched_switch -e sched:sched_migrate_task $@ | 2 | perf record -m 16384 -e sched:sched_wakeup -e sched:sched_wakeup_new -e sched:sched_switch -e sched:sched_migrate_task $@ |
diff --git a/tools/perf/scripts/python/bin/sctop-record b/tools/perf/scripts/python/bin/sctop-record index 1fc5998b721d..4efbfaa7f6a5 100644 --- a/tools/perf/scripts/python/bin/sctop-record +++ b/tools/perf/scripts/python/bin/sctop-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e raw_syscalls:sys_enter $@ | 2 | perf record -e raw_syscalls:sys_enter $@ |
diff --git a/tools/perf/scripts/python/bin/syscall-counts-by-pid-record b/tools/perf/scripts/python/bin/syscall-counts-by-pid-record index 1fc5998b721d..4efbfaa7f6a5 100644 --- a/tools/perf/scripts/python/bin/syscall-counts-by-pid-record +++ b/tools/perf/scripts/python/bin/syscall-counts-by-pid-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e raw_syscalls:sys_enter $@ | 2 | perf record -e raw_syscalls:sys_enter $@ |
diff --git a/tools/perf/scripts/python/bin/syscall-counts-record b/tools/perf/scripts/python/bin/syscall-counts-record index 1fc5998b721d..4efbfaa7f6a5 100644 --- a/tools/perf/scripts/python/bin/syscall-counts-record +++ b/tools/perf/scripts/python/bin/syscall-counts-record | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | perf record -a -e raw_syscalls:sys_enter $@ | 2 | perf record -e raw_syscalls:sys_enter $@ |
diff --git a/tools/perf/util/ui/util.c b/tools/perf/util/ui/util.c index 9706d9d40279..056c69521a38 100644 --- a/tools/perf/util/ui/util.c +++ b/tools/perf/util/ui/util.c | |||
@@ -104,9 +104,10 @@ out_destroy_form: | |||
104 | return rc; | 104 | return rc; |
105 | } | 105 | } |
106 | 106 | ||
107 | static const char yes[] = "Yes", no[] = "No"; | ||
108 | |||
107 | bool ui__dialog_yesno(const char *msg) | 109 | bool ui__dialog_yesno(const char *msg) |
108 | { | 110 | { |
109 | /* newtWinChoice should really be accepting const char pointers... */ | 111 | /* newtWinChoice should really be accepting const char pointers... */ |
110 | char yes[] = "Yes", no[] = "No"; | 112 | return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1; |
111 | return newtWinChoice(NULL, yes, no, (char *)msg) == 1; | ||
112 | } | 113 | } |