diff options
237 files changed, 4363 insertions, 2474 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/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/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/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/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/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/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/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/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/floppy.c b/drivers/block/floppy.c index 8f19b380ca83..3951020e494a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -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/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/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/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/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/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/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/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/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 | ||
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 2fa22f20cfc5..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,6 +62,10 @@ 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 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, | 70 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, |
67 | &ExtAttrBits, &ExtAttrMask); | 71 | &ExtAttrBits, &ExtAttrMask); |
@@ -73,6 +77,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
73 | break; | 77 | break; |
74 | 78 | ||
75 | 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); | ||
76 | if (CIFS_UNIX_EXTATTR_CAP & caps) { | 84 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
77 | if (get_user(ExtAttrBits, (int __user *)arg)) { | 85 | if (get_user(ExtAttrBits, (int __user *)arg)) { |
78 | rc = -EFAULT; | 86 | rc = -EFAULT; |
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 4d78342f3bf0..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; |
@@ -5647,6 +5649,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
5647 | int err, ret; | 5649 | int err, ret; |
5648 | 5650 | ||
5649 | might_sleep(); | 5651 | might_sleep(); |
5652 | trace_ext4_mark_inode_dirty(inode, _RET_IP_); | ||
5650 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 5653 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
5651 | if (ext4_handle_valid(handle) && | 5654 | if (ext4_handle_valid(handle) && |
5652 | 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/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/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/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/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/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/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/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/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/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 61ba5e405791..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; |
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/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/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 | } |