From 5939d25ff296bd69fd98ead938cb63e467939040 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 28 Jan 2011 07:07:13 +0000 Subject: sh: sh7750: move machtypes.h to include/generated By commit 3252b11fc4790d046b93f300c898df2f7cd7c176, machtypes.h moved to include/generated. However, this forgot kernel/cpu/sh4/setup-sh7750. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 672944f..84230e9 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { -- cgit v0.10.2 From 0ce08870b8a4895044b6cf2bbdc774a6faaa3656 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 28 Jan 2011 22:04:01 +0000 Subject: sh: sh7750: Fix incompatible pointer type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is necessary to set array of struct platform_device in early_platform_add_devices(). arch/sh/kernel/cpu/sh4/setup-sh7750.c: In function ‘plat_early_device_setup’: arch/sh/kernel/cpu/sh4/setup-sh7750.c:260: warning: passing argument 1 of ‘early_platform_add_devices’ from incompatible pointer type include/linux/platform_device.h:159: note: expected ‘struct platform_device **’ but argument is of type ‘struct platform_device *’ arch/sh/kernel/cpu/sh4/setup-sh7750.c:262: warning: passing argument 1 of ‘early_platform_add_devices’ from incompatible pointer type include/linux/platform_device.h:159: note: expected ‘struct platform_device **’ but argument is of type ‘struct platform_device *’ arch/sh/kernel/cpu/sh4/setup-sh7750.c:263: warning: passing argument 1 of ‘early_platform_add_devices’ from incompatible pointer type include/linux/platform_device.h:159: note: expected ‘struct platform_device **’ but argument is of type ‘struct platform_device *’ Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 84230e9..e53b4b3 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -255,12 +255,17 @@ static struct platform_device *sh7750_early_devices[] __initdata = { void __init plat_early_device_setup(void) { + struct platform_device *dev[1]; + if (mach_is_rts7751r2d()) { scif_platform_data.scscr |= SCSCR_CKE1; - early_platform_add_devices(&scif_device, 1); + dev[0] = &scif_device; + early_platform_add_devices(dev, 1); } else { - early_platform_add_devices(&sci_device, 1); - early_platform_add_devices(&scif_device, 1); + dev[0] = &sci_device; + early_platform_add_devices(dev, 1); + dev[0] = &scif_device; + early_platform_add_devices(dev, 1); } early_platform_add_devices(sh7750_early_devices, -- cgit v0.10.2 From f55398ab9839a4035b97234c9fa0edc11d37ffa4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 28 Jan 2011 09:59:17 +0000 Subject: ARM: mach-shmobile: AG5EVM MIPI-DSI LCD reset delay fix Add a 100 ms delay after the MIPI-DSI panel reset to fix issue related to the LCD panel not starting properly at boot up time. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 2123b96..4303a86 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -454,6 +454,7 @@ static void __init ag5evm_init(void) gpio_direction_output(GPIO_PORT217, 0); mdelay(1); gpio_set_value(GPIO_PORT217, 1); + mdelay(100); /* LCD backlight controller */ gpio_request(GPIO_PORT235, NULL); /* RESET */ -- cgit v0.10.2 From ad054cbd7323a675588c7aa5d714a3663c48ca25 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 28 Jan 2011 10:04:25 +0000 Subject: ARM: mach-shmobile: Add sh73a0 MIPI-CSI and CEU clocks Update the sh73a0 CPGA to support clocks for CEU and MIPI-CSI. This includes MSTP bits for CSI and CEU and div6 clkdev bindings for VCK1-3. Fix the order of the MSTP32 entries in the clkdev table while at it. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index ddd4a1b..7e58904 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -263,7 +263,7 @@ static struct clk div6_clks[DIV6_NR] = { }; enum { MSTP001, - MSTP125, MSTP118, MSTP116, MSTP100, + MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, MSTP219, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, MSTP331, MSTP329, MSTP325, MSTP323, MSTP312, @@ -275,6 +275,10 @@ enum { MSTP001, static struct clk mstp_clks[MSTP_NR] = { [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */ + [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */ + [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */ + [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */ + [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */ [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */ [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */ @@ -306,6 +310,9 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("r_clk", &r_clk), /* DIV6 clocks */ + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), @@ -313,11 +320,15 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ - CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ + CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */ + CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */ + CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */ + CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ - CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ + CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ -- cgit v0.10.2 From a086536858ad0eb51c58074af2fc2c89ba9c1f5e Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Thu, 11 Nov 2010 18:26:31 +0000 Subject: sh: Ensure ST40-300 BogoMIPS value is consistent A strange variation was seen in the BogoMIPS figure for the ST40-300. This was eventually tracked down to sensitivity to the alignment of the loop. So add an align directive to ensure this doesn't occur. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c index faa8f86..0901b2f 100644 --- a/arch/sh/lib/delay.c +++ b/arch/sh/lib/delay.c @@ -10,6 +10,16 @@ void __delay(unsigned long loops) { __asm__ __volatile__( + /* + * ST40-300 appears to have an issue with this code, + * normally taking two cycles each loop, as with all + * other SH variants. If however the branch and the + * delay slot straddle an 8 byte boundary, this increases + * to 3 cycles. + * This align directive ensures this doesn't occur. + */ + ".balign 8\n\t" + "tst %0, %0\n\t" "1:\t" "bf/s 1b\n\t" -- cgit v0.10.2 From a25bbe12224e649fe12cba7a2fa920180a35c8a9 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Mon, 31 Jan 2011 17:50:29 +0000 Subject: sh: Flush executable pages in copy_user_highpage This resolves a problem seen when using the Android dynamic linker. Sometimes the dynamic linker would seg-fault at start up and this was eventually traced to the handling of a COW fault for a page which was being modified by the linker. If there was no cache aliasing between the kernel and the user page, the page was not flushed, leaving the newly copied data in the D-cache. However when executing instructions from that page, the I-cache is filled directly from external memory, rather than the D-cache, and causing garbage to be executed. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 88d3dc3..5a580ea 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -108,7 +108,8 @@ void copy_user_highpage(struct page *to, struct page *from, kunmap_atomic(vfrom, KM_USER0); } - if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) + if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK) || + (vma->vm_flags & VM_EXEC)) __flush_purge_region(vto, PAGE_SIZE); kunmap_atomic(vto, KM_USER1); -- cgit v0.10.2 From 13c12a4e8ecdf3998cd2d89ade69f6f194819c95 Mon Sep 17 00:00:00 2001 From: Francesco Virlinzi Date: Tue, 8 Feb 2011 16:27:12 +0100 Subject: sh: Change __nosave_XXX symbols to long This patch changes the: - __nosave_begin - __nosave_end symbols from 'void' to 'long' as required by the latest Gcc (4.5.2) which raises the compilation error: cc1: warnings being treated as errors arch/sh/kernel/swsusp.c: In function 'pfn_is_nosave': arch/sh/kernel/swsusp.c:24:28: error: taking address of expression of type 'void' arch/sh/kernel/swsusp.c:25:26: error: taking address of expression of type 'void' arch/sh/kernel/swsusp.c:25:26: error: taking address of expression of type 'void' arch/sh/kernel/swsusp.c:25:26: error: taking address of expression of type 'void' Signed-off-by: Francesco Virlinzi Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h index a78701d..4a53500 100644 --- a/arch/sh/include/asm/sections.h +++ b/arch/sh/include/asm/sections.h @@ -3,7 +3,7 @@ #include -extern void __nosave_begin, __nosave_end; +extern long __nosave_begin, __nosave_end; extern long __machvec_start, __machvec_end; extern char __uncached_start, __uncached_end; extern char _ebss[]; -- cgit v0.10.2 From 4ba8a40ea5c93843b0f2b3fd464978c7ad5431c2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 15 Feb 2011 05:03:46 +0000 Subject: ARM: mach-shmobile: ap4evb: fixup memory initialize for zboot Current ap4evb had issue which couldn't boot sometimes. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt index efd3687..3029aba 100644 --- a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt +++ b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt @@ -6,13 +6,10 @@ LIST "RWT Setting" EW 0xE6020004, 0xA500 EW 0xE6030004, 0xA500 -DD 0x01001000, 0x01001000 - LIST "GPIO Setting" EB 0xE6051013, 0xA2 LIST "CPG" -ED 0xE6150080, 0x00000180 ED 0xE61500C0, 0x00000002 WAIT 1, 0xFE40009C @@ -37,6 +34,9 @@ ED 0xE615002C, 0x93000040 WAIT 1, 0xFE40009C +LIST "SUB/USBClk" +ED 0xE6150080, 0x00000180 + LIST "BSC" ED 0xFEC10000, 0x00E0001B @@ -53,7 +53,7 @@ ED 0xFE400048, 0x20C18505 ED 0xFE40004C, 0x00110209 ED 0xFE400010, 0x00000087 -WAIT 10, 0xFE40009C +WAIT 30, 0xFE40009C ED 0xFE400084, 0x0000003F EB 0xFE500000, 0x00 @@ -84,7 +84,7 @@ ED 0xE6150004, 0x80331050 WAIT 1, 0xFE40009C -ED 0xE6150354, 0x00000002 +ED 0xFE400354, 0x01AD8002 LIST "SCIF0 - Serial port for earlyprintk" EB 0xE6053098, 0x11 -- cgit v0.10.2 From 0acb6209a2443797cf2e15b3d978a03efa0765a3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 15 Feb 2011 05:03:53 +0000 Subject: ARM: mach-shmobile: mackerel: fixup memory initialize for zboot Current makerel had issue which couldn't boot sometimes. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt index efd3687..3029aba 100644 --- a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt +++ b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt @@ -6,13 +6,10 @@ LIST "RWT Setting" EW 0xE6020004, 0xA500 EW 0xE6030004, 0xA500 -DD 0x01001000, 0x01001000 - LIST "GPIO Setting" EB 0xE6051013, 0xA2 LIST "CPG" -ED 0xE6150080, 0x00000180 ED 0xE61500C0, 0x00000002 WAIT 1, 0xFE40009C @@ -37,6 +34,9 @@ ED 0xE615002C, 0x93000040 WAIT 1, 0xFE40009C +LIST "SUB/USBClk" +ED 0xE6150080, 0x00000180 + LIST "BSC" ED 0xFEC10000, 0x00E0001B @@ -53,7 +53,7 @@ ED 0xFE400048, 0x20C18505 ED 0xFE40004C, 0x00110209 ED 0xFE400010, 0x00000087 -WAIT 10, 0xFE40009C +WAIT 30, 0xFE40009C ED 0xFE400084, 0x0000003F EB 0xFE500000, 0x00 @@ -84,7 +84,7 @@ ED 0xE6150004, 0x80331050 WAIT 1, 0xFE40009C -ED 0xE6150354, 0x00000002 +ED 0xFE400354, 0x01AD8002 LIST "SCIF0 - Serial port for earlyprintk" EB 0xE6053098, 0x11 -- cgit v0.10.2 From 14796fca2bd22acc73dd0887248d003b0f441d08 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 18 Jan 2011 20:48:27 -0500 Subject: intel_idle: disable NHM/WSM HW C-state auto-demotion Hardware C-state auto-demotion is a mechanism where the HW overrides the OS C-state request, instead demoting to a shallower state, which is less expensive, but saves less power. Modern Linux should generally get exactly the states it requests. In particular, when a CPU is taken off-line, it must not be demoted, else it can prevent the entire package from reaching deep C-states. https://bugzilla.kernel.org/show_bug.cgi?id=25252 Signed-off-by: Len Brown diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 4d0dfa0..b75eeab 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -36,6 +36,10 @@ #define MSR_IA32_PERFCTR1 0x000000c2 #define MSR_FSB_FREQ 0x000000cd +#define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 +#define NHM_C3_AUTO_DEMOTE (1UL << 25) +#define NHM_C1_AUTO_DEMOTE (1UL << 26) + #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 1fa091e..32b25bc 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -62,6 +62,7 @@ #include #include #include +#include #define INTEL_IDLE_VERSION "0.4" #define PREFIX "intel_idle: " @@ -85,6 +86,12 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); static struct cpuidle_state *cpuidle_state_table; /* + * Hardware C-state auto-demotion may not always be optimal. + * Indicate which enable bits to clear here. + */ +static unsigned long long auto_demotion_disable_flags; + +/* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. * If this flag is set, SW flushes the TLB, so even if the @@ -281,6 +288,15 @@ static struct notifier_block setup_broadcast_notifier = { .notifier_call = setup_broadcast_cpuhp_notify, }; +static void auto_demotion_disable(void *dummy) +{ + unsigned long long msr_bits; + + rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); + msr_bits &= ~auto_demotion_disable_flags; + wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); +} + /* * intel_idle_probe() */ @@ -324,6 +340,8 @@ static int intel_idle_probe(void) case 0x25: /* Westmere */ case 0x2C: /* Westmere */ cpuidle_state_table = nehalem_cstates; + auto_demotion_disable_flags = + (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE); break; case 0x1C: /* 28 - Atom Processor */ @@ -436,6 +454,8 @@ static int intel_idle_cpuidle_devices_init(void) return -EIO; } } + if (auto_demotion_disable_flags) + smp_call_function(auto_demotion_disable, NULL, 1); return 0; } -- cgit v0.10.2 From bfb53ccf1c734b1907df7189eef4c08489827951 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 16 Feb 2011 01:32:48 -0500 Subject: intel_idle: disable Atom/Lincroft HW C-state auto-demotion Just as we had to disable auto-demotion for NHM/WSM, we need to do the same for Atom (Lincroft version). In particular, auto-demotion will prevent Lincroft from entering the S0i3 idle power saving state. https://bugzilla.kernel.org/show_bug.cgi?id=25252 Signed-off-by: Len Brown diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b75eeab..43a18c7 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -39,6 +39,7 @@ #define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 #define NHM_C3_AUTO_DEMOTE (1UL << 25) #define NHM_C1_AUTO_DEMOTE (1UL << 26) +#define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 32b25bc..4a5c4a4 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -345,8 +345,12 @@ static int intel_idle_probe(void) break; case 0x1C: /* 28 - Atom Processor */ + cpuidle_state_table = atom_cstates; + break; + case 0x26: /* 38 - Lincroft Atom Processor */ cpuidle_state_table = atom_cstates; + auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE; break; case 0x2A: /* SNB */ -- cgit v0.10.2 From 41504cce240f791f1e16561db95728c5537fbad9 Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Wed, 16 Feb 2011 11:49:34 -0800 Subject: iwlagn: Support new 5000 microcode. New iwlwifi-5000 microcode requires driver support for API version 5. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79ab0a6..537fb8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,7 +51,7 @@ #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ -#define IWL5000_UCODE_API_MAX 2 +#define IWL5000_UCODE_API_MAX 5 #define IWL5150_UCODE_API_MAX 2 /* Lowest firmware API version supported */ -- cgit v0.10.2 From 97594b0f35c0708cb9551c070b9693a52ec24ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 22 Feb 2011 23:29:37 +0100 Subject: ARM: 6757/1: fix tlb.h induced linux/swap.h build failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 06824ba (ARM: tlb: delay page freeing for SMP and ARMv7 CPUs) introduced a build failure for builds with CONFIG_SWAP=n: In file included from arch/arm/mm/init.c:27: arch/arm/include/asm/tlb.h: In function 'tlb_flush_mmu': arch/arm/include/asm/tlb.h:101: error: implicit declaration of function 'release_pages' arch/arm/include/asm/tlb.h: In function 'tlb_remove_page': arch/arm/include/asm/tlb.h:165: error: implicit declaration of function 'page_cache_release' as linux/swap.h doesn't include linux/pagemap.h but actually needs it (see comments in linux/swap.h as to why this is.) Fix that by #including in as it's done by x86. Signed-off-by: Uwe Kleine-König Acked-by: Tony Lindgren Signed-off-by: Russell King diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 9763be0..22de005 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h @@ -10,6 +10,8 @@ #ifndef _ASMARM_PGALLOC_H #define _ASMARM_PGALLOC_H +#include + #include #include #include -- cgit v0.10.2 From 2949ad50711cc161721cf788711722eeeca33764 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sat, 19 Feb 2011 14:18:08 +0100 Subject: ACPI / debugfs: Fix buffer overflows, double free File position is not controlled, it may lead to overwrites of arbitrary kernel memory. Also the code may kfree() the same pointer multiple times. One more flaw is still present: if multiple processes open the file then all 3 static variables are shared, leading to various race conditions. They should be moved to file->private_data. Signed-off-by: Vasiliy Kulikov Reviewed-by: WANG Cong Reviewed-by: Eugene Teo Cc: stable@kernel.org Signed-off-by: Rafael J. Wysocki diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1..384f7ab 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, size_t count, loff_t *ppos) { static char *buf; - static int uncopied_bytes; + static u32 max_size; + static u32 uncopied_bytes; + struct acpi_table_header table; acpi_status status; @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, if (copy_from_user(&table, user_buf, sizeof(struct acpi_table_header))) return -EFAULT; - uncopied_bytes = table.length; - buf = kzalloc(uncopied_bytes, GFP_KERNEL); + uncopied_bytes = max_size = table.length; + buf = kzalloc(max_size, GFP_KERNEL); if (!buf) return -ENOMEM; } - if (uncopied_bytes < count) { - kfree(buf); + if (buf == NULL) + return -EINVAL; + + if ((*ppos > max_size) || + (*ppos + count > max_size) || + (*ppos + count < count) || + (count > uncopied_bytes)) return -EINVAL; - } if (copy_from_user(buf + (*ppos), user_buf, count)) { kfree(buf); + buf = NULL; return -EFAULT; } @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, if (!uncopied_bytes) { status = acpi_install_method(buf); kfree(buf); + buf = NULL; if (ACPI_FAILURE(status)) return -EINVAL; add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); -- cgit v0.10.2 From 981858bd7a401aa9607d9f430d5de920025fc3ea Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 24 Feb 2011 19:59:21 +0100 Subject: ACPI / ACPICA: Implicit notify for multiple devices Commit bba63a2 (ACPICA: Implicit notify support) introduced a mechanism that causes a notify request of type ACPI_NOTIFY_DEVICE_WAKE to be queued automatically by acpi_ev_asynch_execute_gpe_method() for the device whose _PRW points to the GPE being handled if that GPE is not associated with an _Lxx/_Exx method. However, it turns out that on some systems there are multiple devices with _PRW pointing to the same GPE without _Lxx/_Exx and the mechanism introduced by commit bba63a2 needs to be extended so that "implicit" notify requests of type ACPI_NOTIFY_DEVICE_WAKE can be queued automatically for all those devices at the same time. Reported-and-tested-by: Matthew Garrett Signed-off-by: Rafael J. Wysocki diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 54784bb..edc2586 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -416,10 +416,15 @@ struct acpi_gpe_handler_info { u8 originally_enabled; /* True if GPE was originally enabled */ }; +struct acpi_gpe_notify_object { + struct acpi_namespace_node *node; + struct acpi_gpe_notify_object *next; +}; + union acpi_gpe_dispatch_info { struct acpi_namespace_node *method_node; /* Method node for this GPE level */ struct acpi_gpe_handler_info *handler; /* Installed GPE handler */ - struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */ + struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */ }; /* diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 14988a8..f472521 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -457,6 +457,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) acpi_status status; struct acpi_gpe_event_info *local_gpe_event_info; struct acpi_evaluate_info *info; + struct acpi_gpe_notify_object *notify_object; ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); @@ -508,10 +509,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) * from this thread -- because handlers may in turn run other * control methods. */ - status = - acpi_ev_queue_notify_request(local_gpe_event_info->dispatch. - device_node, - ACPI_NOTIFY_DEVICE_WAKE); + status = acpi_ev_queue_notify_request( + local_gpe_event_info->dispatch.device.node, + ACPI_NOTIFY_DEVICE_WAKE); + + notify_object = local_gpe_event_info->dispatch.device.next; + while (ACPI_SUCCESS(status) && notify_object) { + status = acpi_ev_queue_notify_request( + notify_object->node, + ACPI_NOTIFY_DEVICE_WAKE); + notify_object = notify_object->next; + } + break; case ACPI_GPE_DISPATCH_METHOD: diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 3b20a34..52aaff3 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; struct acpi_namespace_node *device_node; + struct acpi_gpe_notify_object *notify_object; acpi_cpu_flags flags; + u8 gpe_dispatch_mask; ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); @@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, goto unlock_and_exit; } + if (wake_device == ACPI_ROOT_OBJECT) { + goto out; + } + /* * If there is no method or handler for this GPE, then the * wake_device will be notified whenever this GPE fires (aka * "implicit notify") Note: The GPE is assumed to be * level-triggered (for windows compatibility). */ - if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { + gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK; + if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE + && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) { + goto out; + } - /* Validate wake_device is of type Device */ + /* Validate wake_device is of type Device */ - device_node = ACPI_CAST_PTR(struct acpi_namespace_node, - wake_device); - if (device_node->type != ACPI_TYPE_DEVICE) { - goto unlock_and_exit; - } + device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); + if (device_node->type != ACPI_TYPE_DEVICE) { + goto unlock_and_exit; + } + + if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) { gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); - gpe_event_info->dispatch.device_node = device_node; + gpe_event_info->dispatch.device.node = device_node; + gpe_event_info->dispatch.device.next = NULL; + } else { + /* There are multiple devices to notify implicitly. */ + + notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object)); + if (!notify_object) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + + notify_object->node = device_node; + notify_object->next = gpe_event_info->dispatch.device.next; + gpe_event_info->dispatch.device.next = notify_object; } + out: gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; status = AE_OK; -- cgit v0.10.2 From cdf64c803e6cfec72259f7bb2654261584bb80a8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 23 Feb 2011 14:52:43 +0000 Subject: skge: don't mark carrier down at start The API for network devices has changed so that setting carrier off at probe is no longer required. This should fix the IPv6 addrconf issue. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=29612 Signed-off-by: Stephen Hemminger Reported-by: George Billios Cc: David Miller Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 42daf98..35b28f4 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3856,9 +3856,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - /* device is off until link detection */ - netif_carrier_off(dev); - return dev; } -- cgit v0.10.2 From c486da34390846b430896a407b47f0cea3a4189c Mon Sep 17 00:00:00 2001 From: Lucian Adrian Grijincu Date: Thu, 24 Feb 2011 19:48:03 +0000 Subject: sysctl: ipv6: use correct net in ipv6_sysctl_rtcache_flush Before this patch issuing these commands: fd = open("/proc/sys/net/ipv6/route/flush") unshare(CLONE_NEWNET) write(fd, "stuff") would flush the newly created net, not the original one. The equivalent ipv4 code is correct (stores the net inside ->extra1). Acked-by: Daniel Lezcano Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a998db6..904312e 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2557,14 +2557,16 @@ static int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - struct net *net = current->nsproxy->net_ns; - int delay = net->ipv6.sysctl.flush_delay; - if (write) { - proc_dointvec(ctl, write, buffer, lenp, ppos); - fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net); - return 0; - } else + struct net *net; + int delay; + if (!write) return -EINVAL; + + net = (struct net *)ctl->extra1; + delay = net->ipv6.sysctl.flush_delay; + proc_dointvec(ctl, write, buffer, lenp, ppos); + fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net); + return 0; } ctl_table ipv6_route_table_template[] = { @@ -2651,6 +2653,7 @@ struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net) if (table) { table[0].data = &net->ipv6.sysctl.flush_delay; + table[0].extra1 = net; table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh; table[2].data = &net->ipv6.sysctl.ip6_rt_max_size; table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; -- cgit v0.10.2 From 385918cc6af74e2b7ae10ec3ccaeea9a83e8e43e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 21 Feb 2011 15:02:41 +0100 Subject: ath9k: correct ath9k_hw_set_interrupts Commit 4df3071ebd92ef7115b409da64d0eb405d24a631 "ath9k_hw: optimize interrupt mask changes", changed ath9k_hw_set_interrupts function to enable interrupts regardless of function argument, what could possibly be wrong. Correct that behaviour and check "ints" arguments before enabling interrupts, also disable interrupts if ints do not have ATH9K_INT_GLOBAL flag set. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 180170d..2915b11 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -885,7 +885,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) struct ath_common *common = ath9k_hw_common(ah); if (!(ints & ATH9K_INT_GLOBAL)) - ath9k_hw_enable_interrupts(ah); + ath9k_hw_disable_interrupts(ah); ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); @@ -963,7 +963,8 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); } - ath9k_hw_enable_interrupts(ah); + if (ints & ATH9K_INT_GLOBAL) + ath9k_hw_enable_interrupts(ah); return; } -- cgit v0.10.2 From c86664e5a285af1afa06416e450e7c4af04daa7c Mon Sep 17 00:00:00 2001 From: Jan Puk Date: Tue, 22 Feb 2011 14:49:43 +0100 Subject: carl9170: add Airlive X.USB a/b/g/n USBID "AirLive X.USB now works perfectly under a Linux environment!" Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 537732e..f82c400 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -118,6 +118,8 @@ static struct usb_device_id carl9170_usb_ids[] = { { USB_DEVICE(0x057c, 0x8402) }, /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ { USB_DEVICE(0x1668, 0x1200) }, + /* Airlive X.USB a/b/g/n */ + { USB_DEVICE(0x1b75, 0x9170) }, /* terminate */ {} -- cgit v0.10.2 From 63453c05da685323d45b7063cc27cf5e44b4134c Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 24 Feb 2011 12:25:42 +0200 Subject: rndis_wlan: use power save only for BCM4320b BCM4320a breaks when enabling power save (bug 29732). So disable power save for anything but BCM4320b that is known to work. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 848cc2c..518542b 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2597,6 +2597,9 @@ static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, __le32 mode; int ret; + if (priv->device_type != RNDIS_BCM4320B) + return -ENOTSUPP; + netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__, enabled ? "enabled" : "disabled", timeout); -- cgit v0.10.2 From 5aca1a9e880e06bb7e5fd553a86a330ae7e218b5 Mon Sep 17 00:00:00 2001 From: Hagen Paul Pfeifer Date: Fri, 25 Feb 2011 13:58:54 -0800 Subject: net: handle addr_type of 0 properly addr_type of 0 means that the type should be adopted from from_dev and not from __hw_addr_del_multiple(). Unfortunately it isn't so and addr_type will always be considered. Fix this by implementing the considered and documented behavior. Signed-off-by: Hagen Paul Pfeifer Signed-off-by: David S. Miller diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 508f9c1..133fd22 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -144,7 +144,7 @@ void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, list_for_each_entry(ha, &from_list->list, list) { type = addr_type ? addr_type : ha->type; - __hw_addr_del(to_list, ha->addr, addr_len, addr_type); + __hw_addr_del(to_list, ha->addr, addr_len, type); } } EXPORT_SYMBOL(__hw_addr_del_multiple); -- cgit v0.10.2 From 8f3112707fabc2f9f932a4ac1c5b92f3266e4662 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 24 Feb 2011 22:57:14 +0100 Subject: ARM: 6765/1: remove obsolete comment from asm/mach/arch.h Since commit 6fc31d54 this comment is no longer true. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 3a0893a..bf13b81 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -15,10 +15,6 @@ struct meminfo; struct sys_timer; struct machine_desc { - /* - * Note! The first two elements are used - * by assembler code in head.S, head-common.S - */ unsigned int nr; /* architecture number */ const char *name; /* architecture name */ unsigned long boot_params; /* tagged list */ -- cgit v0.10.2 From ba55d3db9bb59a52fe45dbc5d62776adbb289e54 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 25 Feb 2011 20:19:32 +0100 Subject: ARM: 6767/1: ptrace: fix register indexing in GETHBPREGS request The GETHBPREGS ptrace request incorrectly maps its index argument onto the thread's saved debug state when the index != 0. This has not yet been seen from userspace because GDB (the only user of this request) only reads from register 0. This patch fixes the indexing. Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 19c6816..b13e70f 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -996,10 +996,10 @@ static int ptrace_gethbpregs(struct task_struct *tsk, long num, while (!(arch_ctrl.len & 0x1)) arch_ctrl.len >>= 1; - if (idx & 0x1) - reg = encode_ctrl_reg(arch_ctrl); - else + if (num & 0x1) reg = bp->attr.bp_addr; + else + reg = encode_ctrl_reg(arch_ctrl); } put: -- cgit v0.10.2 From c09bae709182046ab104757115dfbd74a1ba1a15 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 25 Feb 2011 20:20:42 +0100 Subject: ARM: 6768/1: hw_breakpoint: ensure debug logic is powered up on v7 cores ARMv7 allows the debug core logic to be powered down and provides the DBGPRSR register so that software can power-up and check the status of the logic. This patch ensures that the debug logic is powered up on ARMv7 cores before we attempt to access the extended debug registers. Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index d600bd3..44b84fe 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -836,9 +836,11 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, /* * One-time initialisation. */ -static void reset_ctrl_regs(void *unused) +static void reset_ctrl_regs(void *info) { - int i; + int i, cpu = smp_processor_id(); + u32 dbg_power; + cpumask_t *cpumask = info; /* * v7 debug contains save and restore registers so that debug state @@ -850,6 +852,17 @@ static void reset_ctrl_regs(void *unused) */ if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { /* + * Ensure sticky power-down is clear (i.e. debug logic is + * powered up). + */ + asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); + if ((dbg_power & 0x1) == 0) { + pr_warning("CPU %d debug is powered down!\n", cpu); + cpumask_or(cpumask, cpumask, cpumask_of(cpu)); + return; + } + + /* * Unconditionally clear the lock by writing a value * other than 0xC5ACCE55 to the access register. */ @@ -887,6 +900,7 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { static int __init arch_hw_breakpoint_init(void) { u32 dscr; + cpumask_t cpumask = { CPU_BITS_NONE }; debug_arch = get_debug_arch(); @@ -911,7 +925,13 @@ static int __init arch_hw_breakpoint_init(void) * Reset the breakpoint resources. We assume that a halting * debugger will leave the world in a nice state for us. */ - on_each_cpu(reset_ctrl_regs, NULL, 1); + on_each_cpu(reset_ctrl_regs, &cpumask, 1); + if (!cpumask_empty(&cpumask)) { + core_num_brps = 0; + core_num_reserved_brps = 0; + core_num_wrps = 0; + return 0; + } ARM_DBG_READ(c1, 0, dscr); if (dscr & ARM_DSCR_HDBGEN) { -- cgit v0.10.2 From 6cc6b33ab9644db38579dcb66737311fc20269db Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Thu, 24 Feb 2011 02:12:00 +0100 Subject: ARM: 6761/1: Update number of VIC for S5PV210 The S5PV210 SoC have 4 VICs. It requires for suspend and resume. Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim Signed-off-by: Russell King diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 778655f..9099604 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -6,6 +6,7 @@ config ARM_VIC config ARM_VIC_NR int + default 4 if ARCH_S5PV210 default 2 depends on ARM_VIC help -- cgit v0.10.2 From 59a4f92a3612f3c3ea4c13b43e0e50ae66abfa7b Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Thu, 24 Feb 2011 02:12:44 +0100 Subject: ARM: 6762/1: Update number of VIC for S5P6442 and S5PC100 The S5P6442 and S5PC100 SoCs have 4 VICs. However, default VIC number is defined 2 in arch/arm/common. So can be happened some problem on it. Basically, it requires for suspend and resume. Signed-off-by: Kukjin Kim Signed-off-by: Russell King diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 9099604..ea5ee4d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -7,6 +7,7 @@ config ARM_VIC config ARM_VIC_NR int default 4 if ARCH_S5PV210 + default 3 if ARCH_S5P6442 || ARCH_S5PC100 default 2 depends on ARM_VIC help -- cgit v0.10.2 From a89d030ee46ac016879779f163edf086e1f740a8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 26 Feb 2011 16:28:54 +0000 Subject: dccp: Change maintainer Today was as good as any other day, but I felt I had to do things I love to when paying hommage to somebody I love, so please apply this one, something he would be proud of, even if so geekly. Way past it was/is deserved. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 5dd6c75..1752436 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2026,7 +2026,7 @@ F: Documentation/scsi/dc395x.txt F: drivers/scsi/dc395x.* DCCP PROTOCOL -M: Arnaldo Carvalho de Melo +M: Gerrit Renker L: dccp@vger.kernel.org W: http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp S: Maintained -- cgit v0.10.2 From 6767c5203459ebee1410e87450b32bf9f4488406 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 14 Feb 2011 13:36:42 +0300 Subject: ARM: pxa/tosa: drop setting LED trigger name, as it's unsupported now Since 2e48928d8a0f38c1b5c81eb3f1294de8a6382c68 it's no longer possible to set the name of the LED trigger for RFKILL events. Drop respective code from tosa-bt.c Signed-off-by: Dmitry Eremin-Solenikov Cc: Stephen Hemminger Cc: John W. Linville Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index c31e601..b9b1e5c 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -81,8 +81,6 @@ static int tosa_bt_probe(struct platform_device *dev) goto err_rfk_alloc; } - rfkill_set_led_trigger_name(rfk, "tosa-bt"); - rc = rfkill_register(rfk); if (rc) goto err_rfkill; -- cgit v0.10.2 From 8d9bd9002dc8c3a05e11c5f40d95d06e15e83f71 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 23 Feb 2011 02:30:28 +0300 Subject: ARM: pxa/colibri: don't register pxa2xx-pcmcia nodes on non-colibri platforms PXA supports multi-machine kernels since long ago. However a kernel compiled with support for colibri and any other PXA machine and with PCMCIA enabled will barf at runtime about duplicate registration of pxa2xx-pcmcia device. Fix that. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Eric Miao diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index c3f7219..a520395 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -181,6 +181,9 @@ static int __init colibri_pcmcia_init(void) { int ret; + if (!machine_is_colibri() && !machine_is_colibri320()) + return -ENODEV; + colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); if (!colibri_pcmcia_device) return -ENOMEM; -- cgit v0.10.2 From ea73e75200625439061c41a75d9053407c9ebb74 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 23 Feb 2011 02:29:09 +0300 Subject: ARM: pxa: enable pxa-pcm-audio on pxa210/pxa25x platform pxa25x platforms were left out of major ASoC Update patch. Since f0fba2ad1b a registration of pxa-pcm-audio device is required for ASoC to function on pxa platforms. Register one also for pxa210/pxa25x. Signed-off-by: Dmitry Eremin-Solenikov Cc: Eric Miao Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index fbc5b77..b166b1d 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -347,6 +347,7 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_assp, &pxa25x_device_pwm0, &pxa25x_device_pwm1, + &pxa_device_asoc_platform, }; static struct sys_device pxa25x_sysdev[] = { -- cgit v0.10.2 From fa4704fee22df9c24297305288b53ba8aae527b4 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 23 Feb 2011 02:29:10 +0300 Subject: ARM: pxa/tosa: register wm9712 codec device Since f0fba2ad1b it's required to register platform devices even for AC'97 codecs. Register one on tosa (wm9712-codec). Signed-off-by: Dmitry Eremin-Solenikov Cc: Eric Miao Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index af152e7..f2582ec 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -875,6 +875,11 @@ static struct platform_device sharpsl_rom_device = { .dev.platform_data = &sharpsl_rom_data, }; +static struct platform_device wm9712_device = { + .name = "wm9712-codec", + .id = -1, +}; + static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, @@ -885,6 +890,7 @@ static struct platform_device *devices[] __initdata = { &tosaled_device, &tosa_bt_device, &sharpsl_rom_device, + &wm9712_device, }; static void tosa_poweroff(void) -- cgit v0.10.2 From df213559f029047b4b3d06a25a36f4779de9b989 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 20 Feb 2011 04:27:05 +0000 Subject: bnx2x: Add a missing bit for PXP parity register of 57712. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 5a268e9..fa6dbe3 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -241,7 +241,7 @@ static const struct { /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't * want to handle "system kill" flow at the moment. */ - BLOCK_PRTY_INFO(PXP, 0x3ffffff, 0x3ffffff, 0x3ffffff, 0x3ffffff), + BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff), BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), -- cgit v0.10.2 From f0ce27996217d06207c8bfda1b1bbec2fbab48c6 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 28 Feb 2011 15:58:07 +0100 Subject: ALSA: HDA: Realtek: Fixup jack detection to input subsystem This patch fixes an error in the jack detection reporting, causing the jack detection sometimes not to be reported correctly to the input subsystem. It should apply to several Realtek codecs. Cc: stable@kernel.org Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3328a25..c052fc5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1133,11 +1133,8 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl) nid = spec->autocfg.hp_pins[i]; if (!nid) break; - if (snd_hda_jack_detect(codec, nid)) { - spec->jack_present = 1; - break; - } - alc_report_jack(codec, spec->autocfg.hp_pins[i]); + alc_report_jack(codec, nid); + spec->jack_present |= snd_hda_jack_detect(codec, nid); } mute = spec->jack_present ? HDA_AMP_MUTE : 0; -- cgit v0.10.2 From 2c27392dc4d4f5ee8a3967a520b8f6cac0418031 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 27 Feb 2011 09:23:52 +0530 Subject: ath9k_htc: Fix an endian issue The stream length/tag fields have to be in little endian format. Fixing this makes the driver work on big-endian platforms. Cc: stable@kernel.org Tested-by: raghunathan.kailasanathan@wipro.com Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 5ab3084..07b1633 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -219,8 +219,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) struct tx_buf *tx_buf = NULL; struct sk_buff *nskb = NULL; int ret = 0, i; - u16 *hdr, tx_skb_cnt = 0; + u16 tx_skb_cnt = 0; u8 *buf; + __le16 *hdr; if (hif_dev->tx.tx_skb_cnt == 0) return 0; @@ -245,9 +246,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) buf = tx_buf->buf; buf += tx_buf->offset; - hdr = (u16 *)buf; - *hdr++ = nskb->len; - *hdr++ = ATH_USB_TX_STREAM_MODE_TAG; + hdr = (__le16 *)buf; + *hdr++ = cpu_to_le16(nskb->len); + *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); buf += 4; memcpy(buf, nskb->data, nskb->len); tx_buf->len = nskb->len + 4; -- cgit v0.10.2 From 2b799a6b25bb9f9fbc478782cd9503e8066ab618 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 26 Feb 2011 12:58:06 +0100 Subject: p54usb: add Senao NUB-350 usbid Reported-by: Mark Davis Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 21713a7..9b344a9 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -98,6 +98,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ + {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ -- cgit v0.10.2 From 27aadb615a2d767d629966e88dc7212ceb7c712e Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Sun, 20 Feb 2011 05:07:20 +0000 Subject: fmvj18x_cs: add new id fmvj18x_cs:add new id Toshiba lan&modem multifuction card (model name:IPC5010A) Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9226cda..530ab5a 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -691,6 +691,7 @@ static struct pcmcia_device_id fmvj18x_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), + PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0b05), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101), PCMCIA_DEVICE_NULL, }; diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c index 93760b2..1ef4df9 100644 --- a/drivers/tty/serial/serial_cs.c +++ b/drivers/tty/serial/serial_cs.c @@ -712,6 +712,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), -- cgit v0.10.2 From 19d73f3c6fe86dca01e409f226ec51a0fde9662e Mon Sep 17 00:00:00 2001 From: Justin Mattock Date: Sun, 20 Feb 2011 20:31:21 +0000 Subject: drivers:isdn:istream.c Fix typo pice to piece The below patch changes a typo "pice" to "piece" Signed-off-by: Justin P. Mattock Signed-off-by: David S. Miller diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c index 18f8798..7bd5baa 100644 --- a/drivers/isdn/hardware/eicon/istream.c +++ b/drivers/isdn/hardware/eicon/istream.c @@ -62,7 +62,7 @@ void diva_xdi_provide_istream_info (ADAPTER* a, stream interface. If synchronous service was requested, then function does return amount of data written to stream. - 'final' does indicate that pice of data to be written is + 'final' does indicate that piece of data to be written is final part of frame (necessary only by structured datatransfer) return 0 if zero lengh packet was written return -1 if stream is full -- cgit v0.10.2 From dad3d44dcb054e9d0514fbf65ee4a2d88cf1698f Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Sun, 20 Feb 2011 23:04:22 +0000 Subject: CAN: add controller hardware name for Softing cards I just found that the controller hardware name is not set for the Softing driver. After this patch, "$ ip -d link show" looks nicer. Signed-off-by: Kurt Van Dijck Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 5157e15..aeea9f9 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -633,6 +633,7 @@ static const struct net_device_ops softing_netdev_ops = { }; static const struct can_bittiming_const softing_btr_const = { + .name = "softing", .tseg1_min = 1, .tseg1_max = 16, .tseg2_min = 1, -- cgit v0.10.2 From b44d211e166b4b0dae8ce379f9d2e3ac164b5b60 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Mon, 21 Feb 2011 02:40:47 +0000 Subject: netlink: handle errors from netlink_dump() netlink_dump() may failed, but nobody handle its error. It generates output data, when a previous portion has been returned to user space. This mechanism works when all data isn't go in skb. If we enter in netlink_recvmsg() and skb is absent in the recv queue, the netlink_dump() will not been executed. So if netlink_dump() is failed one time, the new data never appear and the reader will sleep forever. netlink_dump() is called from two places: 1. from netlink_sendmsg->...->netlink_dump_start(). In this place we can report error directly and it will be returned by sendmsg(). 2. from netlink_recvmsg There we can't report error directly, because we have a portion of valid output data and call netlink_dump() for prepare the next portion. If netlink_dump() is failed, the socket will be mark as error and the next recvmsg will be failed. Signed-off-by: Andrey Vagin Signed-off-by: David S. Miller diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 478181d..1f92459 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1407,7 +1407,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, int noblock = flags&MSG_DONTWAIT; size_t copied; struct sk_buff *skb, *data_skb; - int err; + int err, ret; if (flags&MSG_OOB) return -EOPNOTSUPP; @@ -1470,8 +1470,13 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, skb_free_datagram(sk, skb); - if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) - netlink_dump(sk); + if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { + ret = netlink_dump(sk); + if (ret) { + sk->sk_err = ret; + sk->sk_error_report(sk); + } + } scm_recv(sock, msg, siocb->scm, flags); out: @@ -1736,6 +1741,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, struct netlink_callback *cb; struct sock *sk; struct netlink_sock *nlk; + int ret; cb = kzalloc(sizeof(*cb), GFP_KERNEL); if (cb == NULL) @@ -1764,9 +1770,13 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, nlk->cb = cb; mutex_unlock(nlk->cb_mutex); - netlink_dump(sk); + ret = netlink_dump(sk); + sock_put(sk); + if (ret) + return ret; + /* We successfully started a dump, by returning -EINTR we * signal not to send ACK even if it was requested. */ -- cgit v0.10.2 From 915239472a5015c7667025551a73e11d6e2abee0 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 28 Feb 2011 04:05:25 +0000 Subject: macb: don't use platform_set_drvdata() on a net_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 71d6429 (Driver core: convert platform_{get,set}_drvdata to static inline functions) now triggers a warning in the macb network driver: CC drivers/net/macb.o drivers/net/macb.c: In function ‘macb_mii_init’: drivers/net/macb.c:263: warning: passing argument 1 of ‘platform_set_drvdata’ from incompatible pointer type include/linux/platform_device.h:138: note: expected ‘struct platform_device *’ but argument is of type ‘struct net_device *’ Use dev_set_drvdata() on the device embedded in the net_device instead. Cc: Nicolas Ferre Signed-off-by: Jamie Iles Signed-off-by: David S. Miller diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f69e73e..79ccb54 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -260,7 +260,7 @@ static int macb_mii_init(struct macb *bp) for (i = 0; i < PHY_MAX_ADDR; i++) bp->mii_bus->irq[i] = PHY_POLL; - platform_set_drvdata(bp->dev, bp->mii_bus); + dev_set_drvdata(&bp->dev->dev, bp->mii_bus); if (mdiobus_register(bp->mii_bus)) goto err_out_free_mdio_irq; -- cgit v0.10.2 From b093dd96844186cd03318aaf0cd96f91db3970ef Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 21 Feb 2011 10:20:30 +0000 Subject: dnet: fix wrong use of platform_set_drvdata() platform_set_drvdata() was used with argument of incorrect type and could cause memory corruption. Moreover, because of not setting drvdata in the correct place not all resources were freed upon module unload. Signed-off-by: Ilya Yanok Signed-off-by: David S. Miller diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 9d8a20b..8318ea0 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -337,8 +337,6 @@ static int dnet_mii_init(struct dnet *bp) for (i = 0; i < PHY_MAX_ADDR; i++) bp->mii_bus->irq[i] = PHY_POLL; - platform_set_drvdata(bp->dev, bp->mii_bus); - if (mdiobus_register(bp->mii_bus)) { err = -ENXIO; goto err_out_free_mdio_irq; @@ -863,6 +861,7 @@ static int __devinit dnet_probe(struct platform_device *pdev) bp = netdev_priv(dev); bp->dev = dev; + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); spin_lock_init(&bp->lock); -- cgit v0.10.2 From a90e81579de79e1e94b9af6216e4ef54e468ef4a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 22 Feb 2011 12:23:43 +0000 Subject: net: update Documentation/networking/00-INDEX Clean up entries in 00-INDEX: drop files that have been removed. Reported-by: Rob Landley Signed-off-by: Randy Dunlap Acked-by: Rob Landley Signed-off-by: David S. Miller diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index fe5c099..4edd78d 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -40,8 +40,6 @@ decnet.txt - info on using the DECnet networking layer in Linux. depca.txt - the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver -dgrs.txt - - the Digi International RightSwitch SE-X Ethernet driver dmfe.txt - info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver. e100.txt @@ -50,8 +48,6 @@ e1000.txt - info on Intel's E1000 line of gigabit ethernet boards eql.txt - serial IP load balancing -ethertap.txt - - the Ethertap user space packet reception and transmission driver ewrk3.txt - the Digital EtherWORKS 3 DE203/4/5 Ethernet driver filter.txt @@ -104,8 +100,6 @@ tuntap.txt - TUN/TAP device driver, allowing user space Rx/Tx of packets. vortex.txt - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards. -wavelan.txt - - AT&T GIS (nee NCR) WaveLAN card: An Ethernet-like radio transceiver x25.txt - general info on X.25 development. x25-iface.txt -- cgit v0.10.2 From 9eb0e6f26e48ef22cc56a2b81b1572ace999f70f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 22 Feb 2011 23:28:46 +0000 Subject: net/fec: fix unterminated platform_device_id table The platform_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: David S. Miller diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 2a71373..cd0282d 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -74,7 +74,8 @@ static struct platform_device_id fec_devtype[] = { }, { .name = "imx28-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, - } + }, + { } }; static unsigned char macaddr[ETH_ALEN]; -- cgit v0.10.2 From f5a45325284ec10a907b96052ebf2168e7166b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Wed, 23 Feb 2011 02:51:33 +0000 Subject: f_phonet: avoid pskb_pull(), fix OOPS with CONFIG_HIGHMEM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is similar to what we already do in cdc-phonet.c in the same situation. pskb_pull() refuses to work with HIGHMEM, even if it is known that the socket buffer is entirely in "low" memory. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 3c6e1a0..5e14950 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -346,14 +346,19 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) if (unlikely(!skb)) break; - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0, - req->actual); - page = NULL; - if (req->actual < req->length) { /* Last fragment */ + if (skb->len == 0) { /* First fragment */ skb->protocol = htons(ETH_P_PHONET); skb_reset_mac_header(skb); - pskb_pull(skb, 1); + /* Can't use pskb_pull() on page in IRQ */ + memcpy(skb_put(skb, 1), page_address(page), 1); + } + + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + skb->len == 0, req->actual); + page = NULL; + + if (req->actual < req->length) { /* Last fragment */ skb->dev = dev; dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; -- cgit v0.10.2 From e3fa3aff0cb198e7c53d894f52146121d9592872 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Mon, 28 Feb 2011 12:38:25 -0800 Subject: net: fix nla_policy_len to actually _iterate_ over the policy Currently nla_policy_len always returns n * NLA_HDRLEN: It loops, but does not advance it's iterator. NLA_UNSPEC == 0 does not contain a .len in any policy. Trivially fixed by adding p++. Signed-off-by: Lars Ellenberg Signed-off-by: David S. Miller diff --git a/lib/nlattr.c b/lib/nlattr.c index 5021cbc..ac09f22 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -148,7 +148,7 @@ nla_policy_len(const struct nla_policy *p, int n) { int i, len = 0; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++, p++) { if (p->len) len += nla_total_size(p->len); else if (nla_attr_minlen[p->type]) -- cgit v0.10.2 From faa6fcbbba110c7c4bc299bc90f59d9f7b51ac6e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:20 +0000 Subject: bnx2x: (NPAR mode) Fix FW initialization Fix FW initialization according to max BW stored in percents for NPAR mode. Protect HW from being configured to speed 0. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 710ce5d..a58baf3 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -703,19 +703,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp) { u16 line_speed = bp->link_vars.line_speed; if (IS_MF(bp)) { - u16 maxCfg = (bp->mf_config[BP_VN(bp)] & - FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT; - /* Calculate the current MAX line speed limit for the DCC - * capable devices + u16 maxCfg = bnx2x_extract_max_cfg(bp, + bp->mf_config[BP_VN(bp)]); + + /* Calculate the current MAX line speed limit for the MF + * devices */ - if (IS_MF_SD(bp)) { + if (IS_MF_SI(bp)) + line_speed = (line_speed * maxCfg) / 100; + else { /* SD mode */ u16 vn_max_rate = maxCfg * 100; if (vn_max_rate < line_speed) line_speed = vn_max_rate; - } else /* IS_MF_SI(bp)) */ - line_speed = (line_speed * maxCfg) / 100; + } } return line_speed; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 03eb4d6..326ba44 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1044,4 +1044,24 @@ static inline void storm_memset_cmng(struct bnx2x *bp, void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); +/** + * Extracts MAX BW part from MF configuration. + * + * @param bp + * @param mf_cfg + * + * @return u16 + */ +static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg) +{ + u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT; + if (!max_cfg) { + BNX2X_ERR("Illegal configuration detected for Max BW - " + "using 100 instead\n"); + max_cfg = 100; + } + return max_cfg; +} + #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b44a8b..b3da295 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) speed |= (cmd->speed_hi << 16); if (IS_MF_SI(bp)) { - u32 param = 0; + u32 param = 0, part; u32 line_speed = bp->link_vars.line_speed; /* use 10G if no link detected */ @@ -251,9 +251,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) REQ_BC_VER_4_SET_MF_BW); return -EINVAL; } - if (line_speed < speed) { - BNX2X_DEV_INFO("New speed should be less or equal " - "to actual line speed\n"); + part = (speed * 100) / line_speed; + if (line_speed < speed || !part) { + BNX2X_DEV_INFO("Speed setting should be in a range " + "from 1%% to 100%% " + "of actual line speed\n"); return -EINVAL; } /* load old values */ @@ -263,8 +265,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) param &= FUNC_MF_CFG_MIN_BW_MASK; /* set new MAX value */ - param |= (((speed * 100) / line_speed) - << FUNC_MF_CFG_MAX_BW_SHIFT) + param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) & FUNC_MF_CFG_MAX_BW_MASK; bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index d584d32..203e9bf 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1974,13 +1974,22 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) vn_max_rate = 0; } else { + u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg); + vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; - /* If min rate is zero - set it to 1 */ + /* If fairness is enabled (not all min rates are zeroes) and + if current min rate is zero - set it to 1. + This is a requirement of the algorithm. */ if (bp->vn_weight_sum && (vn_min_rate == 0)) vn_min_rate = DEF_MIN_RATE; - vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + + if (IS_MF_SI(bp)) + /* maxCfg in percents of linkspeed */ + vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100; + else + /* maxCfg is absolute in 100Mb units */ + vn_max_rate = maxCfg * 100; } DP(NETIF_MSG_IFUP, -- cgit v0.10.2 From d4215ef71f4ec21c236a1f255f1808af2cfa6aa0 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:13 +0000 Subject: bnx2x: Fix nvram test for single port devices. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index b3da295..5b0fe7a 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1782,9 +1782,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp) { 0x100, 0x350 }, /* manuf_info */ { 0x450, 0xf0 }, /* feature_info */ { 0x640, 0x64 }, /* upgrade_key_info */ - { 0x6a4, 0x64 }, { 0x708, 0x70 }, /* manuf_key_info */ - { 0x778, 0x70 }, { 0, 0 } }; __be32 buf[0x350 / 4]; -- cgit v0.10.2 From 633ac3637a1ff84eb85d5659380a41d96c4fdbae Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:12 +0000 Subject: bnx2x: Fix ethtool -t link test for MF (non-pmf) devices. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b0fe7a..ef29199 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1932,11 +1932,11 @@ static void bnx2x_self_test(struct net_device *dev, buf[4] = 1; etest->flags |= ETH_TEST_FL_FAILED; } - if (bp->port.pmf) - if (bnx2x_link_test(bp, is_serdes) != 0) { - buf[5] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } + + if (bnx2x_link_test(bp, is_serdes) != 0) { + buf[5] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } #ifdef BNX2X_EXTRA_DEBUG bnx2x_panic_dump(bp); -- cgit v0.10.2 From ff80ee029b562c21ca40724dfe9a63e0e0e0ce3d Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:11 +0000 Subject: bnx2x: properly configure coefficients for MinBW algorithm (NPAR mode). Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 653c624..368cfcd 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1613,19 +1613,23 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_BTR 4 #define MAX_SPQ_PENDING 8 - -/* CMNG constants - derived from lab experiments, and not from system spec calculations !!! */ -#define DEF_MIN_RATE 100 +/* CMNG constants, as derived from system spec calculations */ +/* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ +#define DEF_MIN_RATE 100 /* resolution of the rate shaping timer - 100 usec */ -#define RS_PERIODIC_TIMEOUT_USEC 100 -/* resolution of fairness algorithm in usecs - - coefficient for calculating the actual t fair */ -#define T_FAIR_COEF 10000000 +#define RS_PERIODIC_TIMEOUT_USEC 100 /* number of bytes in single QM arbitration cycle - - coefficient for calculating the fairness timer */ -#define QM_ARB_BYTES 40000 -#define FAIR_MEM 2 + * coefficient for calculating the fairness timer */ +#define QM_ARB_BYTES 160000 +/* resolution of Min algorithm 1:100 */ +#define MIN_RES 100 +/* how many bytes above threshold for the minimal credit of Min algorithm*/ +#define MIN_ABOVE_THRESH 32768 +/* Fairness algorithm integration time coefficient - + * for calculating the actual Tfair */ +#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES) +/* Memory of fairness algorithm . 2 cycles */ +#define FAIR_MEM 2 #define ATTN_NIG_FOR_FUNC (1L << 8) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 203e9bf..032ae18 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2015,7 +2015,8 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) m_fair_vn.vn_credit_delta = max_t(u32, (vn_min_rate * (T_FAIR_COEF / (8 * bp->vn_weight_sum))), - (bp->cmng.fair_vars.fair_threshold * 2)); + (bp->cmng.fair_vars.fair_threshold + + MIN_ABOVE_THRESH)); DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n", m_fair_vn.vn_credit_delta); } -- cgit v0.10.2 From 63135281af8c7fb2b7c84b63f5f974238b7d843e Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 28 Feb 2011 03:37:10 +0000 Subject: bnx2x: perform statistics "action" before state transition. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index bda60d5..3445ded 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -1239,14 +1239,14 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) if (unlikely(bp->panic)) return; + bnx2x_stats_stm[bp->stats_state][event].action(bp); + /* Protect a state change flow */ spin_lock_bh(&bp->stats_lock); state = bp->stats_state; bp->stats_state = bnx2x_stats_stm[state][event].next_state; spin_unlock_bh(&bp->stats_lock); - bnx2x_stats_stm[state][event].action(bp); - if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", state, event, bp->stats_state); -- cgit v0.10.2 From e4e3c02a1a90b12d1b31e5fd9826ad84866ee526 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 28 Feb 2011 03:37:10 +0000 Subject: bnx2x: properly calculate lro_mss Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index a58baf3..9379812 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -259,10 +259,44 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, #endif } +/* Timestamp option length allowed for TPA aggregation: + * + * nop nop kind length echo val + */ +#define TPA_TSTAMP_OPT_LEN 12 +/** + * Calculate the approximate value of the MSS for this + * aggregation using the first packet of it. + * + * @param bp + * @param parsing_flags Parsing flags from the START CQE + * @param len_on_bd Total length of the first packet for the + * aggregation. + */ +static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, + u16 len_on_bd) +{ + /* TPA arrgregation won't have an IP options and TCP options + * other than timestamp. + */ + u16 hdrs_len = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr); + + + /* Check if there was a TCP timestamp, if there is it's will + * always be 12 bytes length: nop nop kind length echo val. + * + * Otherwise FW would close the aggregation. + */ + if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG) + hdrs_len += TPA_TSTAMP_OPT_LEN; + + return len_on_bd - hdrs_len; +} + static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct sk_buff *skb, struct eth_fast_path_rx_cqe *fp_cqe, - u16 cqe_idx) + u16 cqe_idx, u16 parsing_flags) { struct sw_rx_page *rx_pg, old_rx_pg; u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); @@ -275,8 +309,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* This is needed in order to enable forwarding support */ if (frag_size) - skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, - max(frag_size, (u32)len_on_bd)); + skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, parsing_flags, + len_on_bd); #ifdef BNX2X_STOP_ON_ERROR if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { @@ -344,6 +378,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ /* (no need to map the new skb) */ + u16 parsing_flags = + le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags); prefetch(skb); prefetch(((char *)(skb)) + L1_CACHE_BYTES); @@ -373,9 +409,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, } if (!bnx2x_fill_frag_skb(bp, fp, skb, - &cqe->fast_path_cqe, cqe_idx)) { - if ((le16_to_cpu(cqe->fast_path_cqe. - pars_flags.flags) & PARSING_FLAGS_VLAN)) + &cqe->fast_path_cqe, cqe_idx, + parsing_flags)) { + if (parsing_flags & PARSING_FLAGS_VLAN) __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe. vlan_tag)); -- cgit v0.10.2 From b746f7e52fe33ce66ea0cf6127838eff507839ff Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:09 +0000 Subject: bnx2x: update driver version to 1.62.00-6 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 368cfcd..7897d11 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,7 +22,7 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.62.00-5" +#define DRV_MODULE_VERSION "1.62.00-6" #define DRV_MODULE_RELDATE "2011/01/30" #define BNX2X_BC_VER 0x040200 -- cgit v0.10.2 From 0a5f38467765ee15478db90d81e40c269c8dda20 Mon Sep 17 00:00:00 2001 From: "Hegde, Vinay" Date: Thu, 24 Feb 2011 23:56:28 +0000 Subject: davinci_emac: Add Carrier Link OK check in Davinci RX Handler This patch adds an additional check in the Davinci EMAC RX Handler, which tests the __LINK_STATE_NOCARRIER flag along with the __LINK_STATE_START flag as part EMAC shutting down procedure. This avoids WARNING: at drivers/net/davinci_emac.c:1040 emac_rx_handler+0xf8/0x120() during rtcwake used to suspend the target for a specified duration. Signed-off-by: Hegde, Vinay Acked-by: Cyril Chemparathy Signed-off-by: David S. Miller diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 2a628d1..7018bfe 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1008,7 +1008,7 @@ static void emac_rx_handler(void *token, int len, int status) int ret; /* free and bail if we are shutting down */ - if (unlikely(!netif_running(ndev))) { + if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { dev_kfree_skb_any(skb); return; } -- cgit v0.10.2 From b3d1ffb2a5294c74fcf1579499115e1e33b8f487 Mon Sep 17 00:00:00 2001 From: "Rajashekhara, Sudhakar" Date: Fri, 21 Jan 2011 21:13:06 +0530 Subject: davinci: da8xx/omap-l1x: add platform device for davinci-pcm-audio After the multi-component commit f0fba2ad (ASoC: multi-component - ASoC Multi-Component Support) for ASoC, we need to register the platform device for davinci-pcm-audio. This patch and patch at [1] are required for audio to work on DA850/OMAP-L138. [1] https://patchwork.kernel.org/patch/495211/ Signed-off-by: Rajashekhara, Sudhakar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 9eec630..beda8a4 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -480,8 +480,15 @@ static struct platform_device da850_mcasp_device = { .resource = da850_mcasp_resources, }; +struct platform_device davinci_pcm_device = { + .name = "davinci-pcm-audio", + .id = -1, +}; + void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata) { + platform_device_register(&davinci_pcm_device); + /* DA830/OMAP-L137 has 3 instances of McASP */ if (cpu_is_davinci_da830() && id == 1) { da830_mcasp1_device.dev.platform_data = pdata; -- cgit v0.10.2 From c284d9fa48e1ad17bda142cfbb683c29a3b005a6 Mon Sep 17 00:00:00 2001 From: Hirosh Dabui Date: Tue, 25 Jan 2011 23:05:26 +0100 Subject: davinci: tnetv107x: fix register indexing for GPIOs numbers > 31 This patch fix a bug in the register indexing for GPIOs numbers > 31 to get the relevant hardware registers of tnetv107x to control the GPIOs. In the structure tnetv107x_gpio_regs: struct tnetv107x_gpio_regs { u32 idver; u32 data_in[3]; u32 data_out[3]; u32 direction[3]; u32 enable[3]; }; The GPIO hardware register addresses of tnetv107x are stored. The chip implements 3 registers of each entity to serve 96 GPIOs, each register provides a subset of 32 GPIOs. The driver provides these macros: gpio_reg_set_bit, gpio_reg_get_bit and gpio_reg_clear_bit. The bug implied the use of macros to access the relevant hardware register e.g. the driver code used the macro like this: 'gpio_reg_clear_bit(®->data_out, gpio)' But it has to be used like this: 'gpio_reg_clear_bit(reg->data_out, gpio)'. The different results are shown here: - ®->data_out + 1 (it will add the full array size of data_out i.e. 12 bytes) - reg->data_out + 1 (it will increment only the size of data_out i.e. only 4 bytes) Acked-by: Cyril Chemparathy Signed-off-by: Hirosh Dabui Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/gpio-tnetv107x.c b/arch/arm/mach-davinci/gpio-tnetv107x.c index d102986..3fa3e28 100644 --- a/arch/arm/mach-davinci/gpio-tnetv107x.c +++ b/arch/arm/mach-davinci/gpio-tnetv107x.c @@ -58,7 +58,7 @@ static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&ctlr->lock, flags); - gpio_reg_set_bit(®s->enable, gpio); + gpio_reg_set_bit(regs->enable, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); @@ -74,7 +74,7 @@ static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&ctlr->lock, flags); - gpio_reg_clear_bit(®s->enable, gpio); + gpio_reg_clear_bit(regs->enable, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); } @@ -88,7 +88,7 @@ static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&ctlr->lock, flags); - gpio_reg_set_bit(®s->direction, gpio); + gpio_reg_set_bit(regs->direction, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); @@ -106,11 +106,11 @@ static int tnetv107x_gpio_dir_out(struct gpio_chip *chip, spin_lock_irqsave(&ctlr->lock, flags); if (value) - gpio_reg_set_bit(®s->data_out, gpio); + gpio_reg_set_bit(regs->data_out, gpio); else - gpio_reg_clear_bit(®s->data_out, gpio); + gpio_reg_clear_bit(regs->data_out, gpio); - gpio_reg_clear_bit(®s->direction, gpio); + gpio_reg_clear_bit(regs->direction, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); @@ -124,7 +124,7 @@ static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset) unsigned gpio = chip->base + offset; int ret; - ret = gpio_reg_get_bit(®s->data_in, gpio); + ret = gpio_reg_get_bit(regs->data_in, gpio); return ret ? 1 : 0; } @@ -140,9 +140,9 @@ static void tnetv107x_gpio_set(struct gpio_chip *chip, spin_lock_irqsave(&ctlr->lock, flags); if (value) - gpio_reg_set_bit(®s->data_out, gpio); + gpio_reg_set_bit(regs->data_out, gpio); else - gpio_reg_clear_bit(®s->data_out, gpio); + gpio_reg_clear_bit(regs->data_out, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); } -- cgit v0.10.2 From 3113307a37c731a8caa608d086f8506905e08b30 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 9 Feb 2011 18:33:23 +0000 Subject: DaVinci: fix compilation warnings in Commit 6d803ba736abb5e122dede70a4720e4843dd6df4 (ARM: 6483/1: arm & sh: factorised duplicated clkdev.c) caused the following warnings: In file included from /home/headless/src/kernel.org/linux-davinci/arch/arm/ include/asm/clkdev.h:17, from include/linux/clkdev.h:15, from arch/arm/mach-davinci/clock.h:71, from arch/arm/mach-davinci/common.c:22: arch/arm/mach-davinci/include/mach/clkdev.h:4: warning: `struct clk' declared inside parameter list arch/arm/mach-davinci/include/mach/clkdev.h:4: warning: its scope is only this definition or declaration, which is probably not what you want arch/arm/mach-davinci/include/mach/clkdev.h:9: warning: `struct clk' declared inside parameter list Signed-off-by: Sergei Shtylyov Acked-by: Sekhar Nori Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/include/mach/clkdev.h b/arch/arm/mach-davinci/include/mach/clkdev.h index 730c49d..14a5048 100644 --- a/arch/arm/mach-davinci/include/mach/clkdev.h +++ b/arch/arm/mach-davinci/include/mach/clkdev.h @@ -1,6 +1,8 @@ #ifndef __MACH_CLKDEV_H #define __MACH_CLKDEV_H +struct clk; + static inline int __clk_get(struct clk *clk) { return 1; -- cgit v0.10.2 From 079db590f954baa03804a6fc66b201e1347dc1c1 Mon Sep 17 00:00:00 2001 From: Axel Lin <[axel.lin@gmail.com]> Date: Mon, 28 Feb 2011 15:51:33 +0530 Subject: davinci: cpufreq: fix section mismatch warning Fix below section mismatch warning: WARNING: vmlinux.o(.data+0x673c): Section mismatch in reference from the variable davinci_driver to the function .init.text:davinci_cpu_init() The variable davinci_driver references the function __init davinci_cpu_init() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Signed-off-by: Axel Lin Acked-by: Sekhar Nori Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c index 343de73..4a68c2b 100644 --- a/arch/arm/mach-davinci/cpufreq.c +++ b/arch/arm/mach-davinci/cpufreq.c @@ -132,7 +132,7 @@ out: return ret; } -static int __init davinci_cpu_init(struct cpufreq_policy *policy) +static int davinci_cpu_init(struct cpufreq_policy *policy) { int result = 0; struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; -- cgit v0.10.2 From c790ad31a28671b9b478f5d4db2f8b05dabaae4e Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Fri, 25 Feb 2011 11:14:31 +0800 Subject: ALSA: hda - Fix unable to record issue on ASUS N82JV The codec of N82JV is ALC269VB. Signed-off-by: Chih-Wei Huang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c052fc5..4261bb8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15012,7 +15012,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), - SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), + SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), -- cgit v0.10.2 From 450adcbe518ab3a3953d8475309525d22de77cba Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 1 Mar 2011 13:40:54 -0500 Subject: blk-throttle: Do not use kblockd workqueue for throtl work o Dominik Klein reported a system hang issue while doing some blkio throttling testing. https://lkml.org/lkml/2011/2/24/173 o Some tracing revealed that CFQ was not dispatching any more jobs as queue unplug was not happening. And queue unplug was not happening because unplug work was not being called as there was one throttling work on same cpu which as not finished yet. And throttling work had not finished as it was tyring to dispatch a bio to CFQ but all the request descriptors were consume to it was put to sleep. o So basically it is a cyclic dependecny between CFQ unplug work and throtl dispatch work. Tejun suggested that use separate workqueue for such cases. o This patch uses a separate workqueue for throttle related work and does not rely on kblockd workqueue anymore. Cc: stable@kernel.org Reported-by: Dominik Klein Signed-off-by: Vivek Goyal Acked-by: Tejun Heo Signed-off-by: Jens Axboe diff --git a/block/blk-core.c b/block/blk-core.c index 2f4002f..792ece2 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2610,13 +2610,6 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work) } EXPORT_SYMBOL(kblockd_schedule_work); -int kblockd_schedule_delayed_work(struct request_queue *q, - struct delayed_work *dwork, unsigned long delay) -{ - return queue_delayed_work(kblockd_workqueue, dwork, delay); -} -EXPORT_SYMBOL(kblockd_schedule_delayed_work); - int __init blk_dev_init(void) { BUILD_BUG_ON(__REQ_NR_BITS > 8 * diff --git a/block/blk-throttle.c b/block/blk-throttle.c index a89043a..e36cc10 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -20,6 +20,11 @@ static int throtl_quantum = 32; /* Throttling is performed over 100ms slice and after that slice is renewed */ static unsigned long throtl_slice = HZ/10; /* 100 ms */ +/* A workqueue to queue throttle related work */ +static struct workqueue_struct *kthrotld_workqueue; +static void throtl_schedule_delayed_work(struct throtl_data *td, + unsigned long delay); + struct throtl_rb_root { struct rb_root rb; struct rb_node *left; @@ -345,10 +350,9 @@ static void throtl_schedule_next_dispatch(struct throtl_data *td) update_min_dispatch_time(st); if (time_before_eq(st->min_disptime, jiffies)) - throtl_schedule_delayed_work(td->queue, 0); + throtl_schedule_delayed_work(td, 0); else - throtl_schedule_delayed_work(td->queue, - (st->min_disptime - jiffies)); + throtl_schedule_delayed_work(td, (st->min_disptime - jiffies)); } static inline void @@ -815,10 +819,10 @@ void blk_throtl_work(struct work_struct *work) } /* Call with queue lock held */ -void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) +static void +throtl_schedule_delayed_work(struct throtl_data *td, unsigned long delay) { - struct throtl_data *td = q->td; struct delayed_work *dwork = &td->throtl_work; if (total_nr_queued(td) > 0) { @@ -827,12 +831,11 @@ void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) * Cancel that and schedule a new one. */ __cancel_delayed_work(dwork); - kblockd_schedule_delayed_work(q, dwork, delay); + queue_delayed_work(kthrotld_workqueue, dwork, delay); throtl_log(td, "schedule work. delay=%lu jiffies=%lu", delay, jiffies); } } -EXPORT_SYMBOL(throtl_schedule_delayed_work); static void throtl_destroy_tg(struct throtl_data *td, struct throtl_grp *tg) @@ -920,7 +923,7 @@ static void throtl_update_blkio_group_read_bps(void *key, smp_mb__after_atomic_inc(); /* Schedule a work now to process the limit change */ - throtl_schedule_delayed_work(td->queue, 0); + throtl_schedule_delayed_work(td, 0); } static void throtl_update_blkio_group_write_bps(void *key, @@ -934,7 +937,7 @@ static void throtl_update_blkio_group_write_bps(void *key, smp_mb__before_atomic_inc(); atomic_inc(&td->limits_changed); smp_mb__after_atomic_inc(); - throtl_schedule_delayed_work(td->queue, 0); + throtl_schedule_delayed_work(td, 0); } static void throtl_update_blkio_group_read_iops(void *key, @@ -948,7 +951,7 @@ static void throtl_update_blkio_group_read_iops(void *key, smp_mb__before_atomic_inc(); atomic_inc(&td->limits_changed); smp_mb__after_atomic_inc(); - throtl_schedule_delayed_work(td->queue, 0); + throtl_schedule_delayed_work(td, 0); } static void throtl_update_blkio_group_write_iops(void *key, @@ -962,7 +965,7 @@ static void throtl_update_blkio_group_write_iops(void *key, smp_mb__before_atomic_inc(); atomic_inc(&td->limits_changed); smp_mb__after_atomic_inc(); - throtl_schedule_delayed_work(td->queue, 0); + throtl_schedule_delayed_work(td, 0); } void throtl_shutdown_timer_wq(struct request_queue *q) @@ -1135,6 +1138,10 @@ void blk_throtl_exit(struct request_queue *q) static int __init throtl_init(void) { + kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM, 0); + if (!kthrotld_workqueue) + panic("Failed to create kthrotld\n"); + blkio_policy_register(&blkio_policy_throtl); return 0; } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 4d18ff3..dd8cd0f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1088,7 +1088,6 @@ static inline void put_dev_sector(Sector p) struct work_struct; int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); -int kblockd_schedule_delayed_work(struct request_queue *q, struct delayed_work *dwork, unsigned long delay); #ifdef CONFIG_BLK_CGROUP /* @@ -1136,7 +1135,6 @@ static inline uint64_t rq_io_start_time_ns(struct request *req) extern int blk_throtl_init(struct request_queue *q); extern void blk_throtl_exit(struct request_queue *q); extern int blk_throtl_bio(struct request_queue *q, struct bio **bio); -extern void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay); extern void throtl_shutdown_timer_wq(struct request_queue *q); #else /* CONFIG_BLK_DEV_THROTTLING */ static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) @@ -1146,7 +1144,6 @@ static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) static inline int blk_throtl_init(struct request_queue *q) { return 0; } static inline int blk_throtl_exit(struct request_queue *q) { return 0; } -static inline void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) {} static inline void throtl_shutdown_timer_wq(struct request_queue *q) {} #endif /* CONFIG_BLK_DEV_THROTTLING */ -- cgit v0.10.2 From 291d24f6d9e7bbef81454fade8a44720665c7302 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 1 Mar 2011 13:45:24 -0500 Subject: block: fix kernel-doc format for blkdev_issue_zeroout Signed-off-by: Ben Hutchings Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/block/blk-lib.c b/block/blk-lib.c index 1a320d2..eec78be 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -132,7 +132,7 @@ static void bio_batch_end_io(struct bio *bio, int err) } /** - * blkdev_issue_zeroout generate number of zero filed write bios + * blkdev_issue_zeroout - generate number of zero filed write bios * @bdev: blockdev to issue * @sector: start sector * @nr_sects: number of sectors to write -- cgit v0.10.2 From ff75f40f44ae9b79d520bf32a05d35af74a805c0 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Tue, 22 Feb 2011 10:40:25 +0200 Subject: ipvs: fix dst_lock locking on dest update Fix dst_lock usage in __ip_vs_update_dest. We need _bh locking because destination is updated in user context. Can cause lockups on frequent destination updates. Problem reported by Simon Kirby. Bug was introduced in 2.6.37 from the "ipvs: changes for local real server" change. Signed-off-by: Julian Anastasov Signed-off-by: Hans Schillstrom Signed-off-by: Simon Horman diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 22f7ad5..ba98e13 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -808,9 +808,9 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, dest->u_threshold = udest->u_threshold; dest->l_threshold = udest->l_threshold; - spin_lock(&dest->dst_lock); + spin_lock_bh(&dest->dst_lock); ip_vs_dst_reset(dest); - spin_unlock(&dest->dst_lock); + spin_unlock_bh(&dest->dst_lock); if (add) ip_vs_new_estimator(&dest->stats); -- cgit v0.10.2 From 3ee845acba58549578d03a46ed307c0a56c7f777 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 1 Mar 2011 20:05:23 +0000 Subject: ASoC: Fix WM9081 platform data initialisation It went AWOL in the multi-component conversion. Signed-off-by: Mark Brown Acked-by: Liam Girdwood Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 43825b2..cce704c 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1341,6 +1342,10 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, wm9081->control_type = SND_SOC_I2C; wm9081->control_data = i2c; + if (dev_get_platdata(&i2c->dev)) + memcpy(&wm9081->retune, dev_get_platdata(&i2c->dev), + sizeof(wm9081->retune)); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9081, &wm9081_dai, 1); if (ret < 0) -- cgit v0.10.2 From 6927faf30920b8c03dfa007e732642a1f1f20089 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Tue, 1 Mar 2011 23:24:16 +0100 Subject: drm/i915: fix memory corruption with GM965 and >4GB RAM On a Thinkpad x61s, I noticed some memory corruption when plugging/unplugging the external VGA connection. The symptoms are that 4 bytes at the beginning of a page get overwritten by zeroes. The address of the corruption varies when rebooting the machine, but stays constant while it's running (so it's possible to repeatedly write some data and then corrupt it again by plugging the cable). Further investigation revealed that the corrupted address is (dev_priv->status_page_dmah->busaddr & 0xffffffff), ie. the beginning of the hardware status page of the i965 graphics card, cut to 32 bits. So it seems that for some memory access, the hardware uses only 32 bit addressing. If the hardware status page is located >4GB, this corrupts unrelated memory. Signed-off-by: Jan Niehusmann Acked-by: Daniel Vetter Signed-off-by: Chris Wilson Cc: stable@kernel.org diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 17bd766..e33d9be 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1895,6 +1895,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); + /* 965GM sometimes incorrectly writes to hardware status page (HWS) + * using 32bit addressing, overwriting memory if HWS is located + * above 4GB. + * + * The documentation also mentions an issue with undefined + * behaviour if any general state is accessed within a page above 4GB, + * which also needs to be handled carefully. + */ + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); + mmio_bar = IS_GEN2(dev) ? 1 : 0; dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); if (!dev_priv->regs) { -- cgit v0.10.2 From a3cff81ac19ace1ce5ba3fc88e46aea2cb4ebe1a Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 28 Feb 2011 17:24:11 +0000 Subject: ASoC: WM8994: Don't disable the AIF[1|2]CLK_ENA unconditionaly Since we began using the late clock disable functionality, ensure that we don't disable the clock if any of the ADC or DAC paths are still enabled. This happens when we have simultaneous playback and recording. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index ebaee5c..9e91525 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -110,6 +110,9 @@ struct wm8994_priv { unsigned int aif1clk_enable:1; unsigned int aif2clk_enable:1; + + unsigned int aif1clk_disable:1; + unsigned int aif2clk_disable:1; }; static int wm8994_readable(unsigned int reg) @@ -1015,14 +1018,18 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (wm8994->aif1clk_enable) + if (wm8994->aif1clk_enable) { snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, WM8994_AIF1CLK_ENA_MASK, WM8994_AIF1CLK_ENA); - if (wm8994->aif2clk_enable) + wm8994->aif1clk_enable = 0; + } + if (wm8994->aif2clk_enable) { snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, WM8994_AIF2CLK_ENA_MASK, WM8994_AIF2CLK_ENA); + wm8994->aif2clk_enable = 0; + } break; } @@ -1037,15 +1044,15 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMD: - if (wm8994->aif1clk_enable) { + if (wm8994->aif1clk_disable) { snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, WM8994_AIF1CLK_ENA_MASK, 0); - wm8994->aif1clk_enable = 0; + wm8994->aif1clk_disable = 0; } - if (wm8994->aif2clk_enable) { + if (wm8994->aif2clk_disable) { snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, WM8994_AIF2CLK_ENA_MASK, 0); - wm8994->aif2clk_enable = 0; + wm8994->aif2clk_disable = 0; } break; } @@ -1063,6 +1070,9 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: wm8994->aif1clk_enable = 1; break; + case SND_SOC_DAPM_POST_PMD: + wm8994->aif1clk_disable = 1; + break; } return 0; @@ -1078,6 +1088,9 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: wm8994->aif2clk_enable = 1; break; + case SND_SOC_DAPM_POST_PMD: + wm8994->aif2clk_disable = 1; + break; } return 0; -- cgit v0.10.2 From 04d286819ba499839d04cbf847f2ea28d5cf4296 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 1 Mar 2011 11:47:10 +0000 Subject: ASoC: WM8994: Ensure late enable events are processed for the ADCs Ensure that the ADCs are provided with a clock as the previous patch "ASoC: WM8994: Improve playback robustness" did not handle this case properly. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9e91525..4afbe3b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1096,6 +1096,13 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, return 0; } +static int adc_mux_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + late_enable_ev(w, kcontrol, event); + return 0; +} + static int dac_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1416,6 +1423,18 @@ SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0), SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), }; +static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { +SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +}; + +static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { +SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), +}; + static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { SND_SOC_DAPM_INPUT("DMIC1DAT"), SND_SOC_DAPM_INPUT("DMIC2DAT"), @@ -1510,9 +1529,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0), SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), -SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), - SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), @@ -3293,11 +3309,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) if (wm8994->revision < 4) { snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, ARRAY_SIZE(wm8994_lateclk_revd_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, + ARRAY_SIZE(wm8994_adc_revd_widgets)); snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets, ARRAY_SIZE(wm8994_dac_revd_widgets)); } else { snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, ARRAY_SIZE(wm8994_lateclk_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, + ARRAY_SIZE(wm8994_adc_widgets)); snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, ARRAY_SIZE(wm8994_dac_widgets)); } -- cgit v0.10.2 From ac818314499b707a97690d5ee835e6ba40a407c1 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Wed, 24 Nov 2010 11:28:01 +1100 Subject: [CPUFREQ] Missing "unregister_cpu_notifier" in powernow-k8.c It appears that when powernow-k8 finds that No compatible ACPI _PSS objects found. and suggests Try again with latest BIOS. it fails the module load, but does not unregister the cpu_notifier that was registered in powernowk8_init This ends up leaving freed memory on the cpu notifier list for some other poor module (e.g. md/raid5) to come along and trip over. The following might be a partial fix, but I suspect there is probably other clean-up that is needed. ( https://bugzilla.novell.com/show_bug.cgi?id=655215 has full dmesg traces). Signed-off-by: Dave Jones Signed-off-by: Neil Brown diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 35c7e65..302963f 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -1537,6 +1537,7 @@ static struct notifier_block cpb_nb = { static int __cpuinit powernowk8_init(void) { unsigned int i, supported_cpus = 0, cpu; + int rv; for_each_online_cpu(i) { int rc; @@ -1574,7 +1575,13 @@ static int __cpuinit powernowk8_init(void) (cpb_enabled ? "on" : "off")); } - return cpufreq_register_driver(&cpufreq_amd64_driver); + rv = cpufreq_register_driver(&cpufreq_amd64_driver); + if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) { + unregister_cpu_notifier(&cpb_nb); + msrs_free(msrs); + msrs = NULL; + } + return rv; } /* driver entry point for term */ -- cgit v0.10.2 From a536b126f211bdf9a0eecce0d403a26900d2106c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 23 Nov 2010 21:29:31 -0500 Subject: [CPUFREQ] Fix another notifier leak in powernow-k8. Do the notifier registration later, so we don't have to worry about freeing it if we fail the msr allocation. Signed-off-by: Dave Jones diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 302963f..c567dec 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -1556,14 +1556,14 @@ static int __cpuinit powernowk8_init(void) cpb_capable = true; - register_cpu_notifier(&cpb_nb); - msrs = msrs_alloc(); if (!msrs) { printk(KERN_ERR "%s: Error allocating msrs!\n", __func__); return -ENOMEM; } + register_cpu_notifier(&cpb_nb); + rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); for_each_cpu(cpu, cpu_online_mask) { -- cgit v0.10.2 From 8f5bc2abfd4240b1f55425a3d36b6e6c391bc148 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 1 Mar 2011 17:41:10 +0100 Subject: [CPUFREQ] fix BUG on cpufreq policy init failure cpufreq_register_driver sets cpufreq_driver to a structure owned (and placed) in the caller's memory. If cpufreq policy fails in its ->init function, sysdev_driver_register returns nonzero in cpufreq_register_driver. Now, cpufreq_register_driver returns an error without setting cpufreq_driver back to NULL. Usually cpufreq policy modules are unloaded because they propagate the error to the module init function and return that. So a later access to any member of cpufreq_driver causes bugs like: BUG: unable to handle kernel paging request at ffffffffa00270a0 IP: [] cpufreq_cpu_get+0x53/0xe0 PGD 1805067 PUD 1809063 PMD 1c3f90067 PTE 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/virtual/net/tun0/statistics/collisions CPU 0 Modules linked in: ... Pid: 5677, comm: thunderbird-bin Tainted: G W 2.6.38-rc4-mm1_64+ #1389 To be filled by O.E.M./To Be Filled By O.E.M. RIP: 0010:[] [] cpufreq_cpu_get+0x53/0xe0 RSP: 0018:ffff8801aec37d98 EFLAGS: 00010086 RAX: 0000000000000202 RBX: 0000000000000000 RCX: 0000000000000001 RDX: ffffffffa00270a0 RSI: 0000000000001000 RDI: ffffffff8199ece8 ... Call Trace: [] cpufreq_quick_get+0x10/0x30 [] show_cpuinfo+0x2ab/0x300 [] seq_read+0xf2/0x3f0 [] ? __strncpy_from_user+0x33/0x60 [] proc_reg_read+0x6d/0xa0 [] vfs_read+0xc3/0x180 [] sys_read+0x4c/0x90 [] system_call_fastpath+0x16/0x1b ... It's all cause by weird fail path handling in cpufreq_register_driver. To fix that, shuffle the code to do proper handling with gotos. Signed-off-by: Jiri Slaby Signed-off-by: Dave Jones diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1109f68..5cb4d09 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1919,8 +1919,10 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) ret = sysdev_driver_register(&cpu_sysdev_class, &cpufreq_sysdev_driver); + if (ret) + goto err_null_driver; - if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) { + if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { int i; ret = -ENODEV; @@ -1935,21 +1937,22 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) if (ret) { dprintk("no CPU initialized for driver %s\n", driver_data->name); - sysdev_driver_unregister(&cpu_sysdev_class, - &cpufreq_sysdev_driver); - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_driver = NULL; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); + goto err_sysdev_unreg; } } - if (!ret) { - register_hotcpu_notifier(&cpufreq_cpu_notifier); - dprintk("driver %s up and running\n", driver_data->name); - cpufreq_debug_enable_ratelimit(); - } + register_hotcpu_notifier(&cpufreq_cpu_notifier); + dprintk("driver %s up and running\n", driver_data->name); + cpufreq_debug_enable_ratelimit(); + return 0; +err_sysdev_unreg: + sysdev_driver_unregister(&cpu_sysdev_class, + &cpufreq_sysdev_driver); +err_null_driver: + spin_lock_irqsave(&cpufreq_driver_lock, flags); + cpufreq_driver = NULL; + spin_unlock_irqrestore(&cpufreq_driver_lock, flags); return ret; } EXPORT_SYMBOL_GPL(cpufreq_register_driver); -- cgit v0.10.2 From 853cee26e2a0c5f97386beca4c67b11c3cd85b8e Mon Sep 17 00:00:00 2001 From: Naga Chumbalkar Date: Tue, 15 Feb 2011 17:44:11 +0000 Subject: [CPUFREQ] p4-clockmod: print EST-capable warning message only once Print the message only once. I see it 16 times on a 2P box with 16 logical CPUs. Signed-off-by: Naga Chumbalkar diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index bd1cac7..52c9364 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c @@ -158,9 +158,9 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) { if (c->x86 == 0x06) { if (cpu_has(c, X86_FEATURE_EST)) - printk(KERN_WARNING PFX "Warning: EST-capable CPU " - "detected. The acpi-cpufreq module offers " - "voltage scaling in addition of frequency " + printk_once(KERN_WARNING PFX "Warning: EST-capable " + "CPU detected. The acpi-cpufreq module offers " + "voltage scaling in addition to frequency " "scaling. You should use that instead of " "p4-clockmod, if possible.\n"); switch (c->x86_model) { -- cgit v0.10.2 From 72746ac643928f6c3113b5aa783d8ea1b13949d2 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 28 Feb 2011 13:41:11 +0900 Subject: nilfs2: fix regression that i-flag is not set on changeless checkpoints According to the report from Jiro SEKIBA titled "regression in 2.6.37?" (Message-Id: <8739n8vs1f.wl%jir@sekiba.com>), on 2.6.37 and later kernels, lscp command no longer displays "i" flag on checkpoints that snapshot operations or garbage collection created. This is a regression of nilfs2 checkpointing function, and it's critical since it broke behavior of a part of nilfs2 applications. For instance, snapshot manager of TimeBrowse gets to create meaningless snapshots continuously; snapshot creation triggers another checkpoint, but applications cannot distinguish whether the new checkpoint contains meaningful changes or not without the i-flag. This patch fixes the regression and brings that application behavior back to normal. Reported-by: Jiro SEKIBA Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi Tested-by: Jiro SEKIBA Cc: stable [2.6.37] diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 55ebae5..2de9f63 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -430,7 +430,8 @@ static void nilfs_segctor_begin_finfo(struct nilfs_sc_info *sci, nilfs_segctor_map_segsum_entry( sci, &sci->sc_binfo_ptr, sizeof(struct nilfs_finfo)); - if (inode->i_sb && !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags)) + if (NILFS_I(inode)->i_root && + !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags)) set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); /* skip finfo */ } -- cgit v0.10.2 From af24ee9ea8d532e16883251a6684dfa1be8eec29 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Tue, 1 Mar 2011 17:50:00 +0000 Subject: xfs: zero proper structure size for geometry calls Commit 493f3358cb289ccf716c5a14fa5bb52ab75943e5 added this call to xfs_fs_geometry() in order to avoid passing kernel stack data back to user space: + memset(geo, 0, sizeof(*geo)); Unfortunately, one of the callers of that function passes the address of a smaller data type, cast to fit the type that xfs_fs_geometry() requires. As a result, this can happen: Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: f87aca93 Pid: 262, comm: xfs_fsr Not tainted 2.6.38-rc6-493f3358cb2+ #1 Call Trace: [] ? panic+0x50/0x150 [] ? __stack_chk_fail+0x10/0x18 [] ? xfs_ioc_fsgeometry_v1+0x56/0x5d [xfs] Fix this by fixing that one caller to pass the right type and then copy out the subset it is interested in. Note: This patch is an alternative to one originally proposed by Eric Sandeen. Reported-by: Jeffrey Hundstad Signed-off-by: Alex Elder Reviewed-by: Eric Sandeen Tested-by: Jeffrey Hundstad diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index f5e2a19..0ca0e3c 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -695,14 +695,19 @@ xfs_ioc_fsgeometry_v1( xfs_mount_t *mp, void __user *arg) { - xfs_fsop_geom_v1_t fsgeo; + xfs_fsop_geom_t fsgeo; int error; - error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3); + error = xfs_fs_geometry(mp, &fsgeo, 3); if (error) return -error; - if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) + /* + * Caller should have passed an argument of type + * xfs_fsop_geom_v1_t. This is a proper subset of the + * xfs_fsop_geom_t that xfs_fs_geometry() fills in. + */ + if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t))) return -XFS_ERROR(EFAULT); return 0; } -- cgit v0.10.2 From f342552b917a18a7a1fa2c10625df85fac828c36 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 24 Feb 2011 10:47:32 +0000 Subject: powerpc/mm: Make hpte_need_flush() safe for preemption hpte_need_flush() might be called outside of a preempt section when manipulating the kernel page tables, so we need to use the appopriate variants of per-cpu variable accesses. There should be no risk of being in the middle of a batch and a context switch will flush any pending batch. [Patch extracted from a larger patch in Peter's preemptible mmu_gather series] Signed-off-by: Peter Zijlstra Signed-off-by: Hugh Dickins Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c index 1ec0657..c14d09f 100644 --- a/arch/powerpc/mm/tlb_hash64.c +++ b/arch/powerpc/mm/tlb_hash64.c @@ -38,13 +38,11 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); * neesd to be flushed. This function will either perform the flush * immediately or will batch it up if the current CPU has an active * batch on it. - * - * Must be called from within some kind of spinlock/non-preempt region... */ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long pte, int huge) { - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch); unsigned long vsid, vaddr; unsigned int psize; int ssize; @@ -99,6 +97,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, */ if (!batch->active) { flush_hash_page(vaddr, rpte, psize, ssize, 0); + put_cpu_var(ppc64_tlb_batch); return; } @@ -127,6 +126,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, batch->index = ++i; if (i >= PPC64_TLB_BATCH_NR) __flush_tlb_pending(batch); + put_cpu_var(ppc64_tlb_batch); } /* -- cgit v0.10.2 From 357574c48260c9177803a23b881d0af535670ec0 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 23 Feb 2011 12:46:16 +0000 Subject: powerpc/kexec: Restore ppc_md.machine_kexec Kyle Moffett points out that mpc85xx has started using the ppc_md.machine_kexec hook. As such, revert patch c94868788cf2 (powerpc/kexec: Remove ppc_md.machine_kexec). Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 991d599..fe56a23 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -240,6 +240,12 @@ struct machdep_calls { * claims to support kexec. */ int (*machine_kexec_prepare)(struct kimage *image); + + /* Called to perform the _real_ kexec. + * Do NOT allocate memory or fail here. We are past the point of + * no return. + */ + void (*machine_kexec)(struct kimage *image); #endif /* CONFIG_KEXEC */ #ifdef CONFIG_SUSPEND diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index 49a170a..a5f8672 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -87,7 +87,10 @@ void machine_kexec(struct kimage *image) save_ftrace_enabled = __ftrace_enabled_save(); - default_machine_kexec(image); + if (ppc_md.machine_kexec) + ppc_md.machine_kexec(image); + else + default_machine_kexec(image); __ftrace_enabled_restore(save_ftrace_enabled); -- cgit v0.10.2 From e0780b720f75487911e0174ec3dec2da49f7bbfa Mon Sep 17 00:00:00 2001 From: "K.Prasad" Date: Thu, 10 Feb 2011 04:44:35 +0000 Subject: powerpc: Fix call to flush_ptrace_hw_breakpoint() Fix the error in spelling the config option for hw-breakpoints and fix the build issue that follows. Signed-off by: K.Prasad Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 7a1d5cb..8303a6c 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -353,6 +353,7 @@ static void switch_booke_debug_regs(struct thread_struct *new_thread) prime_debug_regs(new_thread); } #else /* !CONFIG_PPC_ADV_DEBUG_REGS */ +#ifndef CONFIG_HAVE_HW_BREAKPOINT static void set_debug_reg_defaults(struct thread_struct *thread) { if (thread->dabr) { @@ -360,6 +361,7 @@ static void set_debug_reg_defaults(struct thread_struct *thread) set_dabr(0); } } +#endif /* !CONFIG_HAVE_HW_BREAKPOINT */ #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ int set_dabr(unsigned long dabr) @@ -670,11 +672,11 @@ void flush_thread(void) { discard_lazy_cpu_state(); -#ifdef CONFIG_HAVE_HW_BREAKPOINTS +#ifdef CONFIG_HAVE_HW_BREAKPOINT flush_ptrace_hw_breakpoint(current); -#else /* CONFIG_HAVE_HW_BREAKPOINTS */ +#else /* CONFIG_HAVE_HW_BREAKPOINT */ set_debug_reg_defaults(¤t->thread); -#endif /* CONFIG_HAVE_HW_BREAKPOINTS */ +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ } void -- cgit v0.10.2 From 720dc34bbbe9493c7bd48b2243058b4e447a929d Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 1 Mar 2011 23:02:07 -0800 Subject: dccp: fix oops on Reset after close This fixes a bug in the order of dccp_rcv_state_process() that still permitted reception even after closing the socket. A Reset after close thus causes a NULL pointer dereference by not preventing operations on an already torn-down socket. dccp_v4_do_rcv() | | state other than OPEN v dccp_rcv_state_process() | | DCCP_PKT_RESET v dccp_rcv_reset() | v dccp_time_wait() WARNING: at net/ipv4/inet_timewait_sock.c:141 __inet_twsk_hashdance+0x48/0x128() Modules linked in: arc4 ecb carl9170 rt2870sta(C) mac80211 r8712u(C) crc_ccitt ah [] (unwind_backtrace+0x0/0xec) from [] (warn_slowpath_common) [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_n) [] (warn_slowpath_null+0x1c/0x24) from [] (__inet_twsk_hashd) [] (__inet_twsk_hashdance+0x48/0x128) from [] (dccp_time_wai) [] (dccp_time_wait+0x40/0xc8) from [] (dccp_rcv_state_proces) [] (dccp_rcv_state_process+0x120/0x538) from [] (dccp_v4_do_) [] (dccp_v4_do_rcv+0x11c/0x14c) from [] (release_sock+0xac/0) [] (release_sock+0xac/0x110) from [] (dccp_close+0x28c/0x380) [] (dccp_close+0x28c/0x380) from [] (inet_release+0x64/0x70) The fix is by testing the socket state first. Receiving a packet in Closed state now also produces the required "No connection" Reset reply of RFC 4340, 8.3.1. Reported-and-tested-by: Johan Hovold Cc: stable@kernel.org Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller diff --git a/net/dccp/input.c b/net/dccp/input.c index 8cde009..4222e7a 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -614,6 +614,9 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* Caller (dccp_v4_do_rcv) will send Reset */ dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; return 1; + } else if (sk->sk_state == DCCP_CLOSED) { + dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; + return 1; } if (sk->sk_state != DCCP_REQUESTING && sk->sk_state != DCCP_RESPOND) { @@ -668,10 +671,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } switch (sk->sk_state) { - case DCCP_CLOSED: - dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; - return 1; - case DCCP_REQUESTING: queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); if (queued >= 0) -- cgit v0.10.2 From 0a85b4827e9960295fbf4ca0f32bb357693cc5f7 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 22 Jan 2011 02:08:30 +0100 Subject: mfd: Fix ASIC3 build with GENERIC_HARDIRQS_NO_DEPRECATED Signed-off-by: Lennert Buytenhek Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 6a1f940..c45e630 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -143,9 +143,9 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) unsigned long flags; struct asic3 *asic; - desc->chip->ack(irq); + desc->irq_data.chip->irq_ack(&desc->irq_data); - asic = desc->handler_data; + asic = get_irq_data(irq); for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { u32 status; -- cgit v0.10.2 From 9063f1f15eec35e5fd608879cef8be5728f2d12a Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Wed, 26 Jan 2011 11:30:01 +0100 Subject: mfd: Fix NULL pointer due to non-initialized ucb1x00-ts absinfo Call input_set_abs_params instead of manually setting absbit only. This fixes this oops: Unable to handle kernel NULL pointer dereference at virtual address 00000024 Internal error: Oops: 41b67017 [#1] CPU: 0 Not tainted (2.6.37 #4) pc : [] lr : [<00000000>] psr: 20000093 sp : c19e5f30 ip : c19e5e6c fp : c19e5f58 r10: 00000000 r9 : c19e4000 r8 : 00000003 r7 : 000001e4 r6 : 00000001 r5 : c1854400 r4 : 00000003 r3 : 00000018 r2 : 00000018 r1 : 00000018 r0 : c185447c Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: c1b6717f Table: c1b6717f DAC: 00000017 Stack: (0xc19e5f30 to 0xc19e6000) 5f20: 00000003 00000003 c1854400 00000013 5f40: 00000001 000001e4 000001c5 c19e5f80 c19e5f5c c016d5e8 c016cf5c 000001e4 5f60: c1854400 c18b5860 00000000 00000171 000001e4 c19e5fc4 c19e5f84 c01559a4 5f80: c016d584 c18b5868 00000000 c1bb5c40 c0035afc c18b5868 c18b5868 c1a55d54 5fa0: c18b5860 c0155750 00000013 00000000 00000000 00000000 c19e5ff4 c19e5fc8 5fc0: c0050174 c015575c 00000000 c18b5860 00000000 c19e5fd4 c19e5fd4 c1a55d54 5fe0: c00500f0 c003b464 00000000 c19e5ff8 c003b464 c00500fc 04000400 04000400 Backtrace: Function entered at [] from [] Function entered at [] from [] r8:000001e4 r7:00000171 r6:00000000 r5:c18b5860 r4:c1854400 Function entered at [] from [] Function entered at [] from [] r6:c003b464 r5:c00500f0 r4:c1a55d54 Code: e59520fc e1a03286 e0433186 e0822003 (e592000c) >>PC; c016d1fc <===== Trace; c016cf50 Trace; c016d5e8 Trace; c016d578 Trace; c01559a4 Trace; c0155750 Trace; c0050174 Trace; c00500f0 Trace; c003b464 Signed-off-by: Jochen Friedrich CC: stable@kernel.org Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 000cb41..92b85e2 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -385,12 +385,18 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) idev->close = ucb1x00_ts_close; __set_bit(EV_ABS, idev->evbit); - __set_bit(ABS_X, idev->absbit); - __set_bit(ABS_Y, idev->absbit); - __set_bit(ABS_PRESSURE, idev->absbit); input_set_drvdata(idev, ts); + ucb1x00_adc_enable(ts->ucb); + ts->x_res = ucb1x00_ts_read_xres(ts); + ts->y_res = ucb1x00_ts_read_yres(ts); + ucb1x00_adc_disable(ts->ucb); + + input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0); + input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0); + input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); + err = input_register_device(idev); if (err) goto fail; -- cgit v0.10.2 From 73ee6524d55444dc80c691ff8602e08940df3d47 Mon Sep 17 00:00:00 2001 From: "Manjunathappa, Prakash" Date: Thu, 27 Jan 2011 18:58:36 +0530 Subject: mfd: Fix DaVinci voice codec device name Fix the device name in DaVinci Voice Codec MFD driver to load davinci-vcif and cq93vc codec client drivers. Signed-off-by: Manjunathappa, Prakash Acked-by: Liam Girdwood Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 33c923d..fdd8a1b 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -118,12 +118,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev) /* Voice codec interface client */ cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; - cell->name = "davinci_vcif"; + cell->name = "davinci-vcif"; cell->driver_data = davinci_vc; /* Voice codec CQ93VC client */ cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; - cell->name = "cq93vc"; + cell->name = "cq93vc-codec"; cell->driver_data = davinci_vc; ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, -- cgit v0.10.2 From 77bd70e9009eab6dbdef3ee08afe87ab26df8dac Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Feb 2011 14:57:43 +0000 Subject: mfd: Don't suspend WM8994 if the CODEC is not suspended ASoC supports keeping the audio subsysetm active over suspend in order to support use cases such as audio passthrough from a cellular modem with the main CPU suspended. Ensure that we don't power down the CODEC when this is happening by checking to see if VMID is up and skipping suspend and resume when it is. If the CODEC has suspended then it'll turn VMID off before the core suspend() gets called. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 41233c7..f4016a0 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -246,6 +246,16 @@ static int wm8994_suspend(struct device *dev) struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; + /* Don't actually go through with the suspend if the CODEC is + * still active (eg, for audio passthrough from CP. */ + ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); + if (ret < 0) { + dev_err(dev, "Failed to read power status: %d\n", ret); + } else if (ret & WM8994_VMID_SEL_MASK) { + dev_dbg(dev, "CODEC still active, ignoring suspend\n"); + return 0; + } + /* GPIO configuration state is saved here since we may be configuring * the GPIO alternate functions even if we're not using the gpiolib * driver for them. @@ -261,6 +271,8 @@ static int wm8994_suspend(struct device *dev) if (ret < 0) dev_err(dev, "Failed to save LDO registers: %d\n", ret); + wm8994->suspended = true; + ret = regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { @@ -276,6 +288,10 @@ static int wm8994_resume(struct device *dev) struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; + /* We may have lied to the PM core about suspending */ + if (!wm8994->suspended) + return 0; + ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { @@ -298,6 +314,8 @@ static int wm8994_resume(struct device *dev) if (ret < 0) dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); + wm8994->suspended = false; + return 0; } #endif diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 3fd3684..ef4f0b6 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -71,6 +71,7 @@ struct wm8994 { u16 irq_masks_cache[WM8994_NUM_IRQ_REGS]; /* Used over suspend/resume */ + bool suspended; u16 ldo_regs[WM8994_NUM_LDO_REGS]; u16 gpio_regs[WM8994_NUM_GPIO_REGS]; -- cgit v0.10.2 From 4b57018dcd6418e18c08088c89f123da8a7bfc45 Mon Sep 17 00:00:00 2001 From: "vwadekar@nvidia.com" Date: Thu, 24 Feb 2011 10:18:13 +0530 Subject: mfd: Avoid tps6586x burst writes tps6586 does not support burst writes. i2c writes have to be 1 byte at a time. Cc: stable@kernel.org Signed-off-by: Varun Wadekar Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 627cf57..e9018d1 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -150,12 +150,12 @@ static inline int __tps6586x_write(struct i2c_client *client, static inline int __tps6586x_writes(struct i2c_client *client, int reg, int len, uint8_t *val) { - int ret; + int ret, i; - ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); - if (ret < 0) { - dev_err(&client->dev, "failed writings to 0x%02x\n", reg); - return ret; + for (i = 0; i < len; i++) { + ret = __tps6586x_write(client, reg + i, *(val + i)); + if (ret < 0) + return ret; } return 0; -- cgit v0.10.2 From e8a80c6f769dd4622d8b211b398452158ee60c0b Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Thu, 24 Feb 2011 11:48:22 +0100 Subject: ext2: Fix link count corruption under heavy link+rename load vfs_rename_other() does not lock renamed inode with i_mutex. Thus changing i_nlink in a non-atomic manner (which happens in ext2_rename()) can corrupt it as reported and analyzed by Josh. In fact, there is no good reason to mess with i_nlink of the moved file. We did it presumably to simulate linking into the new directory and unlinking from an old one. But the practical effect of this is disputable because fsck can possibly treat file as being properly linked into both directories without writing any error which is confusing. So we just stop increment-decrement games with i_nlink which also fixes the corruption. CC: stable@kernel.org CC: Al Viro Signed-off-by: Josh Hunt Signed-off-by: Jan Kara diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 2e1d834..adb9185 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -344,7 +344,6 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page); if (!new_de) goto out_dir; - inode_inc_link_count(old_inode); ext2_set_link(new_dir, new_de, new_page, old_inode, 1); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) @@ -356,12 +355,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, if (new_dir->i_nlink >= EXT2_LINK_MAX) goto out_dir; } - inode_inc_link_count(old_inode); err = ext2_add_link(new_dentry, old_inode); - if (err) { - inode_dec_link_count(old_inode); + if (err) goto out_dir; - } if (dir_de) inode_inc_link_count(new_dir); } @@ -369,12 +365,11 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, /* * Like most other Unix systems, set the ctime for inodes on a * rename. - * inode_dec_link_count() will mark the inode dirty. */ old_inode->i_ctime = CURRENT_TIME_SEC; + mark_inode_dirty(old_inode); ext2_delete_entry (old_de, old_page); - inode_dec_link_count(old_inode); if (dir_de) { if (old_dir != new_dir) -- cgit v0.10.2 From 9ef0298a8e5730d9a46d640014c727f3b4152870 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 2 Mar 2011 12:10:13 +0100 Subject: netfilter: nf_log: avoid oops in (un)bind with invalid nfproto values Like many other places, we have to check that the array index is within allowed limits, or otherwise, a kernel oops and other nastiness can ensue when we access memory beyond the end of the array. [ 5954.115381] BUG: unable to handle kernel paging request at 0000004000000000 [ 5954.120014] IP: __find_logger+0x6f/0xa0 [ 5954.123979] nf_log_bind_pf+0x2b/0x70 [ 5954.123979] nfulnl_recv_config+0xc0/0x4a0 [nfnetlink_log] [ 5954.123979] nfnetlink_rcv_msg+0x12c/0x1b0 [nfnetlink] ... The problem goes back to v2.6.30-rc1~1372~1342~31 where nf_log_bind was decoupled from nf_log_register. Reported-by: Miguel Di Ciurcio Filho , via irc.freenode.net/#netfilter Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index b07393e..9181699 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -85,6 +85,8 @@ EXPORT_SYMBOL(nf_log_unregister); int nf_log_bind_pf(u_int8_t pf, const struct nf_logger *logger) { + if (pf >= ARRAY_SIZE(nf_loggers)) + return -EINVAL; mutex_lock(&nf_log_mutex); if (__find_logger(pf, logger->name) == NULL) { mutex_unlock(&nf_log_mutex); @@ -98,6 +100,8 @@ EXPORT_SYMBOL(nf_log_bind_pf); void nf_log_unbind_pf(u_int8_t pf) { + if (pf >= ARRAY_SIZE(nf_loggers)) + return; mutex_lock(&nf_log_mutex); rcu_assign_pointer(nf_loggers[pf], NULL); mutex_unlock(&nf_log_mutex); -- cgit v0.10.2 From 2db1badfa5d100dd9f7c7a716911250a735cf2e8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 24 Feb 2011 16:11:42 +0000 Subject: e1000: fix sparse warning Sparse complains because the e1000 driver is calling ioread on a pointer not tagged as __iomem. Signed-off-by: Stephen Hemminger Reviewed-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 55c1711..33e7c45a 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -42,7 +42,8 @@ #define GBE_CONFIG_RAM_BASE \ ((unsigned int)(CONFIG_RAM_BASE + GBE_CONFIG_OFFSET)) -#define GBE_CONFIG_BASE_VIRT phys_to_virt(GBE_CONFIG_RAM_BASE) +#define GBE_CONFIG_BASE_VIRT \ + ((void __iomem *)phys_to_virt(GBE_CONFIG_RAM_BASE)) #define GBE_CONFIG_FLASH_WRITE(base, offset, count, data) \ (iowrite16_rep(base + offset, data, count)) -- cgit v0.10.2 From 9dc441f3c5a9ea1b9888ce15b1ccb3f30a79e323 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 17 Feb 2011 18:47:48 +0000 Subject: igb: fix sparse warning Reported-by: Stephen Hemminger Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index 74486a8..af3822f 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c @@ -220,7 +220,7 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr) * The parameter rar_count will usually be hw->mac.rar_entry_count * unless there are workarounds that change this. **/ -void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, +static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count) { -- cgit v0.10.2 From 4def99bbfd46e05c5e03b5b282cb4ee30e27ff19 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 2 Feb 2011 09:30:36 +0000 Subject: e1000e: disable broken PHY wakeup for ICH10 LOMs, use MAC wakeup instead When support for 82577/82578 was added[1] in 2.6.31, PHY wakeup was in- advertently enabled (even though it does not function properly) on ICH10 LOMs. This patch makes it so that the ICH10 LOMs use MAC wakeup instead as was done with the initial support for those devices (i.e. 82567LM-3, 82567LF-3 and 82567V-4). [1] commit a4f58f5455ba0efda36fb33c37074922d1527a10 Reported-by: Aurelien Jarno Cc: Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3fa110d..2e50228 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5967,7 +5967,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* APME bit in EEPROM is mapped to WUC.APME */ eeprom_data = er32(WUC); eeprom_apme_mask = E1000_WUC_APME; - if (eeprom_data & E1000_WUC_PHY_WAKE) + if ((hw->mac.type > e1000_ich10lan) && + (eeprom_data & E1000_WUC_PHY_WAKE)) adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP; } else if (adapter->flags & FLAG_APME_IN_CTRL3) { if (adapter->flags & FLAG_APME_CHECK_PORT_B && -- cgit v0.10.2 From 1654e7411a1ad4999fe7890ef51d2a2bbb1fcf76 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Mar 2011 08:48:05 -0500 Subject: block: add @force_kblockd to __blk_run_queue() __blk_run_queue() automatically either calls q->request_fn() directly or schedules kblockd depending on whether the function is recursed. blk-flush implementation needs to be able to explicitly choose kblockd. Add @force_kblockd. All the current users are converted to specify %false for the parameter and this patch doesn't introduce any behavior change. stable: This is prerequisite for fixing ide oops caused by the new blk-flush implementation. Signed-off-by: Tejun Heo Cc: Jan Beulich Cc: James Bottomley Cc: stable@kernel.org Signed-off-by: Jens Axboe diff --git a/block/blk-core.c b/block/blk-core.c index 792ece2..518dd42 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -352,7 +352,7 @@ void blk_start_queue(struct request_queue *q) WARN_ON(!irqs_disabled()); queue_flag_clear(QUEUE_FLAG_STOPPED, q); - __blk_run_queue(q); + __blk_run_queue(q, false); } EXPORT_SYMBOL(blk_start_queue); @@ -403,13 +403,14 @@ EXPORT_SYMBOL(blk_sync_queue); /** * __blk_run_queue - run a single device queue * @q: The queue to run + * @force_kblockd: Don't run @q->request_fn directly. Use kblockd. * * Description: * See @blk_run_queue. This variant must be called with the queue lock * held and interrupts disabled. * */ -void __blk_run_queue(struct request_queue *q) +void __blk_run_queue(struct request_queue *q, bool force_kblockd) { blk_remove_plug(q); @@ -423,7 +424,7 @@ void __blk_run_queue(struct request_queue *q) * Only recurse once to avoid overrunning the stack, let the unplug * handling reinvoke the handler shortly if we already got there. */ - if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { + if (!force_kblockd && !queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { q->request_fn(q); queue_flag_clear(QUEUE_FLAG_REENTER, q); } else { @@ -446,7 +447,7 @@ void blk_run_queue(struct request_queue *q) unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - __blk_run_queue(q); + __blk_run_queue(q, false); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_run_queue); @@ -1053,7 +1054,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq, drive_stat_acct(rq, 1); __elv_add_request(q, rq, where, 0); - __blk_run_queue(q); + __blk_run_queue(q, false); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_insert_request); diff --git a/block/blk-flush.c b/block/blk-flush.c index 54b123d..56adaa8 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -69,7 +69,7 @@ static void blk_flush_complete_seq_end_io(struct request_queue *q, * queue. Kick the queue in those cases. */ if (was_empty && next_rq) - __blk_run_queue(q); + __blk_run_queue(q, false); } static void pre_flush_end_io(struct request *rq, int error) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7be4c79..ea83a4f 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3355,7 +3355,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfqd->busy_queues > 1) { cfq_del_timer(cfqd, cfqq); cfq_clear_cfqq_wait_request(cfqq); - __blk_run_queue(cfqd->queue); + __blk_run_queue(cfqd->queue, false); } else { cfq_blkiocg_update_idle_time_stats( &cfqq->cfqg->blkg); @@ -3370,7 +3370,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, * this new queue is RT and the current one is BE */ cfq_preempt_queue(cfqd, cfqq); - __blk_run_queue(cfqd->queue); + __blk_run_queue(cfqd->queue, false); } } @@ -3731,7 +3731,7 @@ static void cfq_kick_queue(struct work_struct *work) struct request_queue *q = cfqd->queue; spin_lock_irq(q->queue_lock); - __blk_run_queue(cfqd->queue); + __blk_run_queue(cfqd->queue, false); spin_unlock_irq(q->queue_lock); } diff --git a/block/elevator.c b/block/elevator.c index 2569512..236e93c 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -602,7 +602,7 @@ void elv_quiesce_start(struct request_queue *q) */ elv_drain_elevator(q); while (q->rq.elvpriv) { - __blk_run_queue(q); + __blk_run_queue(q, false); spin_unlock_irq(q->queue_lock); msleep(10); spin_lock_irq(q->queue_lock); @@ -651,7 +651,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) * with anything. There's no point in delaying queue * processing. */ - __blk_run_queue(q); + __blk_run_queue(q, false); break; case ELEVATOR_INSERT_SORT: diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9045c52..fb2bb35 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -443,7 +443,7 @@ static void scsi_run_queue(struct request_queue *q) &sdev->request_queue->queue_flags); if (flagset) queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); - __blk_run_queue(sdev->request_queue); + __blk_run_queue(sdev->request_queue, false); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); spin_unlock(sdev->request_queue->queue_lock); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 998c01b..5c3ccfc 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3829,7 +3829,7 @@ fc_bsg_goose_queue(struct fc_rport *rport) !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); if (flagset) queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); - __blk_run_queue(rport->rqst_q); + __blk_run_queue(rport->rqst_q, false); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index dd8cd0f..d5063e1 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -699,7 +699,7 @@ extern void blk_start_queue(struct request_queue *q); extern void blk_stop_queue(struct request_queue *q); extern void blk_sync_queue(struct request_queue *q); extern void __blk_stop_queue(struct request_queue *q); -extern void __blk_run_queue(struct request_queue *); +extern void __blk_run_queue(struct request_queue *q, bool force_kblockd); extern void blk_run_queue(struct request_queue *); extern int blk_rq_map_user(struct request_queue *, struct request *, struct rq_map_data *, void __user *, unsigned long, -- cgit v0.10.2 From 255bb490c8c27eed484d538efe6ef6a7473bd3f6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Mar 2011 08:48:06 -0500 Subject: block: blk-flush shouldn't call directly into q->request_fn() __blk_run_queue() blk-flush decomposes a flush into sequence of multiple requests. On completion of a request, the next one is queued; however, block layer must not implicitly call into q->request_fn() directly from completion path. This makes the queue behave unexpectedly when seen from the drivers and violates the assumption that q->request_fn() is called with process context + queue_lock. This patch makes blk-flush the following two changes to make sure q->request_fn() is not called directly from request completion path. - blk_flush_complete_seq_end_io() now asks __blk_run_queue() to always use kblockd instead of calling directly into q->request_fn(). - queue_next_fseq() uses ELEVATOR_INSERT_REQUEUE instead of ELEVATOR_INSERT_FRONT so that elv_insert() doesn't try to unplug the request queue directly. Reported by Jan in the following threads. http://thread.gmane.org/gmane.linux.ide/48778 http://thread.gmane.org/gmane.linux.ide/48786 stable: applicable to v2.6.37. Signed-off-by: Tejun Heo Reported-by: Jan Beulich Cc: "David S. Miller" Cc: stable@kernel.org Signed-off-by: Jens Axboe diff --git a/block/blk-flush.c b/block/blk-flush.c index 56adaa8..b27d020 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -66,10 +66,12 @@ static void blk_flush_complete_seq_end_io(struct request_queue *q, /* * Moving a request silently to empty queue_head may stall the - * queue. Kick the queue in those cases. + * queue. Kick the queue in those cases. This function is called + * from request completion path and calling directly into + * request_fn may confuse the driver. Always use kblockd. */ if (was_empty && next_rq) - __blk_run_queue(q, false); + __blk_run_queue(q, true); } static void pre_flush_end_io(struct request *rq, int error) @@ -130,7 +132,7 @@ static struct request *queue_next_fseq(struct request_queue *q) BUG(); } - elv_insert(q, rq, ELEVATOR_INSERT_FRONT); + elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); return rq; } -- cgit v0.10.2 From 865212abb5268d56ab5e1035426bbeebba01138e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 7 Feb 2011 16:08:04 +0200 Subject: arm: mach-omap2: smartreflex: fix another memory leak Temporary strings with volt_* file names should be released after the debugfs entries are created. While at it, also simplify the string allocation, and use just snprintf() to create the name. The patch eliminates kmemleak reports with the following stack trace (multiple objects depending on HW): unreferenced object 0xcedbc5a0 (size 64): comm "swapper", pid 1, jiffies 4294929375 (age 423.734s) hex dump (first 32 bytes): 76 6f 6c 74 5f 39 37 35 30 30 30 00 00 00 00 00 volt_975000..... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] create_object+0x104/0x208 [] kmem_cache_alloc_trace+0xf0/0x17c [] omap_sr_probe+0x314/0x420 [] platform_drv_probe+0x18/0x1c [] driver_probe_device+0xc8/0x188 [] __driver_attach+0x68/0x8c [] bus_for_each_dev+0x44/0x74 [] bus_add_driver+0xa0/0x228 [] driver_register+0xa8/0x130 [] platform_driver_probe+0x18/0x8c [] sr_init+0x40/0x74 [] do_one_initcall+0xc8/0x1a0 [] kernel_init+0x150/0x218 [] kernel_thread_exit+0x0/0x8 [] 0xffffffff Signed-off-by: Aaro Koskinen Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 95ac336..5a849c9 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -926,19 +926,10 @@ static int __init omap_sr_probe(struct platform_device *pdev) } for (i = 0; i < sr_info->nvalue_count; i++) { - char *name; - char volt_name[32]; - - name = kzalloc(NVALUE_NAME_LEN + 1, GFP_KERNEL); - if (!name) { - dev_err(&pdev->dev, "%s: Unable to allocate memory" - " for n-value directory name\n", __func__); - return -ENOMEM; - } + char name[NVALUE_NAME_LEN + 1]; - strcpy(name, "volt_"); - sprintf(volt_name, "%d", volt_data[i].volt_nominal); - strcat(name, volt_name); + snprintf(name, sizeof(name), "volt_%d", + volt_data[i].volt_nominal); (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, &(sr_info->nvalue_table[i].nvalue)); } -- cgit v0.10.2 From b3329a33b5a3902e65c5517f41c374f5adb060e1 Mon Sep 17 00:00:00 2001 From: Shweta Gulati Date: Tue, 15 Feb 2011 13:40:30 +0530 Subject: OMAP2+: PM: SmartReflex: fix memory leaks in Smartreflex driver This Patch frees all the dynamically allocated memory which couldn't have been released in some error hitting cases. Signed-off-by: Shweta Gulati Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 5a849c9..1a777e3 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -282,6 +282,7 @@ error: dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" "interrupt handler. Smartreflex will" "not function as desired\n", __func__); + kfree(name); kfree(sr_info); return ret; } @@ -879,7 +880,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) ret = sr_late_init(sr_info); if (ret) { pr_warning("%s: Error in SR late init\n", __func__); - return ret; + goto err_release_region; } } @@ -890,14 +891,17 @@ static int __init omap_sr_probe(struct platform_device *pdev) * not try to create rest of the debugfs entries. */ vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm); - if (!vdd_dbg_dir) - return -EINVAL; + if (!vdd_dbg_dir) { + ret = -EINVAL; + goto err_release_region; + } dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); if (IS_ERR(dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); - return PTR_ERR(dbg_dir); + ret = PTR_ERR(dbg_dir); + goto err_release_region; } (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, dbg_dir, @@ -913,7 +917,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) if (IS_ERR(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); - return PTR_ERR(nvalue_dir); + ret = PTR_ERR(nvalue_dir); + goto err_release_region; } omap_voltage_get_volttable(sr_info->voltdm, &volt_data); @@ -922,7 +927,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) " corresponding vdd vdd_%s. Cannot create debugfs" "entries for n-values\n", __func__, sr_info->voltdm->name); - return -ENODATA; + ret = -ENODATA; + goto err_release_region; } for (i = 0; i < sr_info->nvalue_count; i++) { -- cgit v0.10.2 From 0c7a720bd1c9059fe7b869bc5feeba738d6ce799 Mon Sep 17 00:00:00 2001 From: Morten Holst Larsen Date: Sun, 23 Jan 2011 13:40:47 +0100 Subject: Fix typo in call to irq_to_desc() Fix typo in call to irq_to_desc() Signed-off-by: Morten H. Larsen Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 9ab234f..d3e20c7 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -44,7 +44,7 @@ static char irq_user_affinity[NR_IRQS]; int irq_select_affinity(unsigned int irq) { - struct irq_desc *desc = irq_to_desc[irq]; + struct irq_desc *desc = irq_to_desc(irq); static int last_cpu; int cpu = last_cpu + 1; -- cgit v0.10.2 From 592924c7741377790866ee4bd7e6f214b1aeaade Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:23 +0000 Subject: alpha: Pyxis convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c index 2863458..b30227f 100644 --- a/arch/alpha/kernel/irq_pyxis.c +++ b/arch/alpha/kernel/irq_pyxis.c @@ -29,21 +29,21 @@ pyxis_update_irq_hw(unsigned long mask) } static inline void -pyxis_enable_irq(unsigned int irq) +pyxis_enable_irq(struct irq_data *d) { - pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); + pyxis_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16)); } static void -pyxis_disable_irq(unsigned int irq) +pyxis_disable_irq(struct irq_data *d) { - pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); + pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16))); } static void -pyxis_mask_and_ack_irq(unsigned int irq) +pyxis_mask_and_ack_irq(struct irq_data *d) { - unsigned long bit = 1UL << (irq - 16); + unsigned long bit = 1UL << (d->irq - 16); unsigned long mask = cached_irq_mask &= ~bit; /* Disable the interrupt. */ @@ -58,9 +58,9 @@ pyxis_mask_and_ack_irq(unsigned int irq) static struct irq_chip pyxis_irq_type = { .name = "PYXIS", - .mask_ack = pyxis_mask_and_ack_irq, - .mask = pyxis_disable_irq, - .unmask = pyxis_enable_irq, + .irq_mask_ack = pyxis_mask_and_ack_irq, + .irq_mask = pyxis_disable_irq, + .irq_unmask = pyxis_enable_irq, }; void @@ -103,7 +103,7 @@ init_pyxis_irqs(unsigned long ignore_mask) if ((ignore_mask >> i) & 1) continue; set_irq_chip_and_handler(i, &pyxis_irq_type, handle_level_irq); - irq_to_desc(i)->status |= IRQ_LEVEL; + irq_set_status_flags(i, IRQ_LEVEL); } setup_irq(16+7, &isa_cascade_irqaction); -- cgit v0.10.2 From 35252254cbd89191f381bb5454b3bdfb939e9d31 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:26 +0000 Subject: alpha: srm: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index 0e57e82..82a47bb 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -18,27 +18,27 @@ DEFINE_SPINLOCK(srm_irq_lock); static inline void -srm_enable_irq(unsigned int irq) +srm_enable_irq(struct irq_data *d) { spin_lock(&srm_irq_lock); - cserve_ena(irq - 16); + cserve_ena(d->irq - 16); spin_unlock(&srm_irq_lock); } static void -srm_disable_irq(unsigned int irq) +srm_disable_irq(struct irq_data *d) { spin_lock(&srm_irq_lock); - cserve_dis(irq - 16); + cserve_dis(d->irq - 16); spin_unlock(&srm_irq_lock); } /* Handle interrupts from the SRM, assuming no additional weirdness. */ static struct irq_chip srm_irq_type = { .name = "SRM", - .unmask = srm_enable_irq, - .mask = srm_disable_irq, - .mask_ack = srm_disable_irq, + .irq_unmask = srm_enable_irq, + .irq_mask = srm_disable_irq, + .irq_mask_ack = srm_disable_irq, }; void __init @@ -52,7 +52,7 @@ init_srm_irqs(long max, unsigned long ignore_mask) if (i < 64 && ((ignore_mask >> i) & 1)) continue; set_irq_chip_and_handler(i, &srm_irq_type, handle_level_irq); - irq_to_desc(i)->status |= IRQ_LEVEL; + irq_set_status_flags(i, IRQ_LEVEL); } } -- cgit v0.10.2 From ff53afe66a3ab5614309a4193df72c82ec3bb984 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:28 +0000 Subject: alpha: i8259, alcor, jensen wildfire: Convert irq_chip Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c index 956ea0e..c7cc981 100644 --- a/arch/alpha/kernel/irq_i8259.c +++ b/arch/alpha/kernel/irq_i8259.c @@ -33,10 +33,10 @@ i8259_update_irq_hw(unsigned int irq, unsigned long mask) } inline void -i8259a_enable_irq(unsigned int irq) +i8259a_enable_irq(struct irq_data *d) { spin_lock(&i8259_irq_lock); - i8259_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); + i8259_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq)); spin_unlock(&i8259_irq_lock); } @@ -47,16 +47,18 @@ __i8259a_disable_irq(unsigned int irq) } void -i8259a_disable_irq(unsigned int irq) +i8259a_disable_irq(struct irq_data *d) { spin_lock(&i8259_irq_lock); - __i8259a_disable_irq(irq); + __i8259a_disable_irq(d->irq); spin_unlock(&i8259_irq_lock); } void -i8259a_mask_and_ack_irq(unsigned int irq) +i8259a_mask_and_ack_irq(struct irq_data *d) { + unsigned int irq = d->irq; + spin_lock(&i8259_irq_lock); __i8259a_disable_irq(irq); @@ -71,9 +73,9 @@ i8259a_mask_and_ack_irq(unsigned int irq) struct irq_chip i8259a_irq_type = { .name = "XT-PIC", - .unmask = i8259a_enable_irq, - .mask = i8259a_disable_irq, - .mask_ack = i8259a_mask_and_ack_irq, + .irq_unmask = i8259a_enable_irq, + .irq_mask = i8259a_disable_irq, + .irq_mask_ack = i8259a_mask_and_ack_irq, }; void __init diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h index b63ccd7..d507a23 100644 --- a/arch/alpha/kernel/irq_impl.h +++ b/arch/alpha/kernel/irq_impl.h @@ -31,11 +31,9 @@ extern void init_rtc_irq(void); extern void common_init_isa_dma(void); -extern void i8259a_enable_irq(unsigned int); -extern void i8259a_disable_irq(unsigned int); -extern void i8259a_mask_and_ack_irq(unsigned int); -extern unsigned int i8259a_startup_irq(unsigned int); -extern void i8259a_end_irq(unsigned int); +extern void i8259a_enable_irq(struct irq_data *d); +extern void i8259a_disable_irq(struct irq_data *d); +extern void i8259a_mask_and_ack_irq(struct irq_data *d); extern struct irq_chip i8259a_irq_type; extern void init_i8259a_irqs(void); diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 7bef617..88d95e8 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -44,31 +44,31 @@ alcor_update_irq_hw(unsigned long mask) } static inline void -alcor_enable_irq(unsigned int irq) +alcor_enable_irq(struct irq_data *d) { - alcor_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); + alcor_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16)); } static void -alcor_disable_irq(unsigned int irq) +alcor_disable_irq(struct irq_data *d) { - alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); + alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16))); } static void -alcor_mask_and_ack_irq(unsigned int irq) +alcor_mask_and_ack_irq(struct irq_data *d) { - alcor_disable_irq(irq); + alcor_disable_irq(d); /* On ALCOR/XLT, need to dismiss interrupt via GRU. */ - *(vuip)GRU_INT_CLEAR = 1 << (irq - 16); mb(); + *(vuip)GRU_INT_CLEAR = 1 << (d->irq - 16); mb(); *(vuip)GRU_INT_CLEAR = 0; mb(); } static void -alcor_isa_mask_and_ack_irq(unsigned int irq) +alcor_isa_mask_and_ack_irq(struct irq_data *d) { - i8259a_mask_and_ack_irq(irq); + i8259a_mask_and_ack_irq(d); /* On ALCOR/XLT, need to dismiss interrupt via GRU. */ *(vuip)GRU_INT_CLEAR = 0x80000000; mb(); @@ -77,9 +77,9 @@ alcor_isa_mask_and_ack_irq(unsigned int irq) static struct irq_chip alcor_irq_type = { .name = "ALCOR", - .unmask = alcor_enable_irq, - .mask = alcor_disable_irq, - .mask_ack = alcor_mask_and_ack_irq, + .irq_unmask = alcor_enable_irq, + .irq_mask = alcor_disable_irq, + .irq_mask_ack = alcor_mask_and_ack_irq, }; static void @@ -126,9 +126,9 @@ alcor_init_irq(void) if (i >= 16+20 && i <= 16+30) continue; set_irq_chip_and_handler(i, &alcor_irq_type, handle_level_irq); - irq_to_desc(i)->status |= IRQ_LEVEL; + irq_set_status_flags(i, IRQ_LEVEL); } - i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; + i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq; init_i8259a_irqs(); common_init_isa_dma(); diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 34f55e0..00341b7 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -63,34 +63,34 @@ */ static void -jensen_local_enable(unsigned int irq) +jensen_local_enable(struct irq_data *d) { /* the parport is really hw IRQ 1, silly Jensen. */ - if (irq == 7) - i8259a_enable_irq(1); + if (d->irq == 7) + i8259a_enable_irq(d); } static void -jensen_local_disable(unsigned int irq) +jensen_local_disable(struct irq_data *d) { /* the parport is really hw IRQ 1, silly Jensen. */ - if (irq == 7) - i8259a_disable_irq(1); + if (d->irq == 7) + i8259a_disable_irq(d); } static void -jensen_local_mask_ack(unsigned int irq) +jensen_local_mask_ack(struct irq_data *d) { /* the parport is really hw IRQ 1, silly Jensen. */ - if (irq == 7) - i8259a_mask_and_ack_irq(1); + if (d->irq == 7) + i8259a_mask_and_ack_irq(d); } static struct irq_chip jensen_local_irq_type = { .name = "LOCAL", - .unmask = jensen_local_enable, - .mask = jensen_local_disable, - .mask_ack = jensen_local_mask_ack, + .irq_unmask = jensen_local_enable, + .irq_mask = jensen_local_disable, + .irq_mask_ack = jensen_local_mask_ack, }; static void diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index eec5259..ca60a38 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -104,10 +104,12 @@ wildfire_init_irq_hw(void) } static void -wildfire_enable_irq(unsigned int irq) +wildfire_enable_irq(struct irq_data *d) { + unsigned int irq = d->irq; + if (irq < 16) - i8259a_enable_irq(irq); + i8259a_enable_irq(d); spin_lock(&wildfire_irq_lock); set_bit(irq, &cached_irq_mask); @@ -116,10 +118,12 @@ wildfire_enable_irq(unsigned int irq) } static void -wildfire_disable_irq(unsigned int irq) +wildfire_disable_irq(struct irq_data *d) { + unsigned int irq = d->irq; + if (irq < 16) - i8259a_disable_irq(irq); + i8259a_disable_irq(d); spin_lock(&wildfire_irq_lock); clear_bit(irq, &cached_irq_mask); @@ -128,10 +132,12 @@ wildfire_disable_irq(unsigned int irq) } static void -wildfire_mask_and_ack_irq(unsigned int irq) +wildfire_mask_and_ack_irq(struct irq_data *d) { + unsigned int irq = d->irq; + if (irq < 16) - i8259a_mask_and_ack_irq(irq); + i8259a_mask_and_ack_irq(d); spin_lock(&wildfire_irq_lock); clear_bit(irq, &cached_irq_mask); @@ -141,9 +147,9 @@ wildfire_mask_and_ack_irq(unsigned int irq) static struct irq_chip wildfire_irq_type = { .name = "WILDFIRE", - .unmask = wildfire_enable_irq, - .mask = wildfire_disable_irq, - .mask_ack = wildfire_mask_and_ack_irq, + .irq_unmask = wildfire_enable_irq, + .irq_mask = wildfire_disable_irq, + .irq_mask_ack = wildfire_mask_and_ack_irq, }; static void __init @@ -177,21 +183,21 @@ wildfire_init_irq_per_pca(int qbbno, int pcano) for (i = 0; i < 16; ++i) { if (i == 2) continue; - irq_to_desc(i+irq_bias)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type, handle_level_irq); + irq_set_status_flags(i + irq_bias, IRQ_LEVEL); } - irq_to_desc(36+irq_bias)->status |= IRQ_LEVEL; set_irq_chip_and_handler(36+irq_bias, &wildfire_irq_type, handle_level_irq); + irq_set_status_flags(36 + irq_bias, IRQ_LEVEL); for (i = 40; i < 64; ++i) { - irq_to_desc(i+irq_bias)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type, handle_level_irq); + irq_set_status_flags(i + irq_bias, IRQ_LEVEL); } - setup_irq(32+irq_bias, &isa_enable); + setup_irq(32+irq_bias, &isa_enable); } static void __init -- cgit v0.10.2 From 118b4691da32be471d91edfad0edd555933be769 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:30 +0000 Subject: alpha: cabriolet: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index b0c9164..57eb630 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -46,22 +46,22 @@ cabriolet_update_irq_hw(unsigned int irq, unsigned long mask) } static inline void -cabriolet_enable_irq(unsigned int irq) +cabriolet_enable_irq(struct irq_data *d) { - cabriolet_update_irq_hw(irq, cached_irq_mask &= ~(1UL << irq)); + cabriolet_update_irq_hw(d->irq, cached_irq_mask &= ~(1UL << d->irq)); } static void -cabriolet_disable_irq(unsigned int irq) +cabriolet_disable_irq(struct irq_data *d) { - cabriolet_update_irq_hw(irq, cached_irq_mask |= 1UL << irq); + cabriolet_update_irq_hw(d->irq, cached_irq_mask |= 1UL << d->irq); } static struct irq_chip cabriolet_irq_type = { .name = "CABRIOLET", - .unmask = cabriolet_enable_irq, - .mask = cabriolet_disable_irq, - .mask_ack = cabriolet_disable_irq, + .irq_unmask = cabriolet_enable_irq, + .irq_mask = cabriolet_disable_irq, + .irq_mask_ack = cabriolet_disable_irq, }; static void @@ -107,7 +107,7 @@ common_init_irq(void (*srm_dev_int)(unsigned long v)) for (i = 16; i < 35; ++i) { set_irq_chip_and_handler(i, &cabriolet_irq_type, handle_level_irq); - irq_to_desc(i)->status |= IRQ_LEVEL; + irq_set_status_flags(i, IRQ_LEVEL); } } -- cgit v0.10.2 From d677f4508accb92126e7b2827de525e48ea73cdf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:33 +0000 Subject: alpha: dp264: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index edad5f7..481df4e 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -98,37 +98,37 @@ tsunami_update_irq_hw(unsigned long mask) } static void -dp264_enable_irq(unsigned int irq) +dp264_enable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); - cached_irq_mask |= 1UL << irq; + cached_irq_mask |= 1UL << d->irq; tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } static void -dp264_disable_irq(unsigned int irq) +dp264_disable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); - cached_irq_mask &= ~(1UL << irq); + cached_irq_mask &= ~(1UL << d->irq); tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } static void -clipper_enable_irq(unsigned int irq) +clipper_enable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); - cached_irq_mask |= 1UL << (irq - 16); + cached_irq_mask |= 1UL << (d->irq - 16); tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } static void -clipper_disable_irq(unsigned int irq) +clipper_disable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); - cached_irq_mask &= ~(1UL << (irq - 16)); + cached_irq_mask &= ~(1UL << (d->irq - 16)); tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } @@ -149,10 +149,11 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) } static int -dp264_set_affinity(unsigned int irq, const struct cpumask *affinity) -{ +dp264_set_affinity(struct irq_data *d, const struct cpumask *affinity, + bool force) +{ spin_lock(&dp264_irq_lock); - cpu_set_irq_affinity(irq, *affinity); + cpu_set_irq_affinity(d->irq, *affinity); tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); @@ -160,10 +161,11 @@ dp264_set_affinity(unsigned int irq, const struct cpumask *affinity) } static int -clipper_set_affinity(unsigned int irq, const struct cpumask *affinity) -{ +clipper_set_affinity(struct irq_data *d, const struct cpumask *affinity, + bool force) +{ spin_lock(&dp264_irq_lock); - cpu_set_irq_affinity(irq - 16, *affinity); + cpu_set_irq_affinity(d->irq - 16, *affinity); tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); @@ -171,19 +173,19 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity) } static struct irq_chip dp264_irq_type = { - .name = "DP264", - .unmask = dp264_enable_irq, - .mask = dp264_disable_irq, - .mask_ack = dp264_disable_irq, - .set_affinity = dp264_set_affinity, + .name = "DP264", + .irq_unmask = dp264_enable_irq, + .irq_mask = dp264_disable_irq, + .irq_mask_ack = dp264_disable_irq, + .irq_set_affinity = dp264_set_affinity, }; static struct irq_chip clipper_irq_type = { - .name = "CLIPPER", - .unmask = clipper_enable_irq, - .mask = clipper_disable_irq, - .mask_ack = clipper_disable_irq, - .set_affinity = clipper_set_affinity, + .name = "CLIPPER", + .irq_unmask = clipper_enable_irq, + .irq_mask = clipper_disable_irq, + .irq_mask_ack = clipper_disable_irq, + .irq_set_affinity = clipper_set_affinity, }; static void @@ -268,8 +270,8 @@ init_tsunami_irqs(struct irq_chip * ops, int imin, int imax) { long i; for (i = imin; i <= imax; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, ops, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } } -- cgit v0.10.2 From 02e5d87be229763e0f07a196c08dad35bf870329 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:35 +0000 Subject: alpha: eb64p: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index ae5f29d..402e908 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -44,22 +44,22 @@ eb64p_update_irq_hw(unsigned int irq, unsigned long mask) } static inline void -eb64p_enable_irq(unsigned int irq) +eb64p_enable_irq(struct irq_data *d) { - eb64p_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); + eb64p_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq)); } static void -eb64p_disable_irq(unsigned int irq) +eb64p_disable_irq(struct irq_data *d) { - eb64p_update_irq_hw(irq, cached_irq_mask |= 1 << irq); + eb64p_update_irq_hw(d->irq, cached_irq_mask |= 1 << d->irq); } static struct irq_chip eb64p_irq_type = { .name = "EB64P", - .unmask = eb64p_enable_irq, - .mask = eb64p_disable_irq, - .mask_ack = eb64p_disable_irq, + .irq_unmask = eb64p_enable_irq, + .irq_mask = eb64p_disable_irq, + .irq_mask_ack = eb64p_disable_irq, }; static void @@ -118,9 +118,9 @@ eb64p_init_irq(void) init_i8259a_irqs(); for (i = 16; i < 32; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &eb64p_irq_type, handle_level_irq); - } + irq_set_status_flags(i, IRQ_LEVEL); + } common_init_isa_dma(); setup_irq(16+5, &isa_cascade_irqaction); -- cgit v0.10.2 From c049766445b8791ab683c765674de86588d9ae14 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:37 +0000 Subject: alpha: eiger: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index 1121bc5..0b44a54 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -51,16 +51,18 @@ eiger_update_irq_hw(unsigned long irq, unsigned long mask) } static inline void -eiger_enable_irq(unsigned int irq) +eiger_enable_irq(struct irq_data *d) { + unsigned int irq = d->irq; unsigned long mask; mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63))); eiger_update_irq_hw(irq, mask); } static void -eiger_disable_irq(unsigned int irq) +eiger_disable_irq(struct irq_data *d) { + unsigned int irq = d->irq; unsigned long mask; mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63)); eiger_update_irq_hw(irq, mask); @@ -68,9 +70,9 @@ eiger_disable_irq(unsigned int irq) static struct irq_chip eiger_irq_type = { .name = "EIGER", - .unmask = eiger_enable_irq, - .mask = eiger_disable_irq, - .mask_ack = eiger_disable_irq, + .irq_unmask = eiger_enable_irq, + .irq_mask = eiger_disable_irq, + .irq_mask_ack = eiger_disable_irq, }; static void @@ -136,8 +138,8 @@ eiger_init_irq(void) init_i8259a_irqs(); for (i = 16; i < 128; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &eiger_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } } -- cgit v0.10.2 From 08876fe8519c4f7625efba8aa3d51b1d24cd8a13 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:39 +0000 Subject: alpha: marvel: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 2bfc9f1..e619107 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -104,9 +104,10 @@ io7_get_irq_ctl(unsigned int irq, struct io7 **pio7) } static void -io7_enable_irq(unsigned int irq) +io7_enable_irq(struct irq_data *d) { volatile unsigned long *ctl; + unsigned int irq = d->irq; struct io7 *io7; ctl = io7_get_irq_ctl(irq, &io7); @@ -115,7 +116,7 @@ io7_enable_irq(unsigned int irq) __func__, irq); return; } - + spin_lock(&io7->irq_lock); *ctl |= 1UL << 24; mb(); @@ -124,9 +125,10 @@ io7_enable_irq(unsigned int irq) } static void -io7_disable_irq(unsigned int irq) +io7_disable_irq(struct irq_data *d) { volatile unsigned long *ctl; + unsigned int irq = d->irq; struct io7 *io7; ctl = io7_get_irq_ctl(irq, &io7); @@ -135,7 +137,7 @@ io7_disable_irq(unsigned int irq) __func__, irq); return; } - + spin_lock(&io7->irq_lock); *ctl &= ~(1UL << 24); mb(); @@ -144,35 +146,29 @@ io7_disable_irq(unsigned int irq) } static void -marvel_irq_noop(unsigned int irq) -{ - return; -} - -static unsigned int -marvel_irq_noop_return(unsigned int irq) -{ - return 0; +marvel_irq_noop(struct irq_data *d) +{ + return; } static struct irq_chip marvel_legacy_irq_type = { .name = "LEGACY", - .mask = marvel_irq_noop, - .unmask = marvel_irq_noop, + .irq_mask = marvel_irq_noop, + .irq_unmask = marvel_irq_noop, }; static struct irq_chip io7_lsi_irq_type = { .name = "LSI", - .unmask = io7_enable_irq, - .mask = io7_disable_irq, - .mask_ack = io7_disable_irq, + .irq_unmask = io7_enable_irq, + .irq_mask = io7_disable_irq, + .irq_mask_ack = io7_disable_irq, }; static struct irq_chip io7_msi_irq_type = { .name = "MSI", - .unmask = io7_enable_irq, - .mask = io7_disable_irq, - .ack = marvel_irq_noop, + .irq_unmask = io7_enable_irq, + .irq_mask = io7_disable_irq, + .irq_ack = marvel_irq_noop, }; static void @@ -280,8 +276,8 @@ init_io7_irqs(struct io7 *io7, /* Set up the lsi irqs. */ for (i = 0; i < 128; ++i) { - irq_to_desc(base + i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(base + i, lsi_ops, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } /* Disable the implemented irqs in hardware. */ @@ -294,8 +290,8 @@ init_io7_irqs(struct io7 *io7, /* Set up the msi irqs. */ for (i = 128; i < (128 + 512); ++i) { - irq_to_desc(base + i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(base + i, msi_ops, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } for (i = 0; i < 16; ++i) -- cgit v0.10.2 From a326526360622825fd98c05a0eae3087efb0df81 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:42 +0000 Subject: alpha: mikasa: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index bcc1639..cf7f43d 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -43,22 +43,22 @@ mikasa_update_irq_hw(int mask) } static inline void -mikasa_enable_irq(unsigned int irq) +mikasa_enable_irq(struct irq_data *d) { - mikasa_update_irq_hw(cached_irq_mask |= 1 << (irq - 16)); + mikasa_update_irq_hw(cached_irq_mask |= 1 << (d->irq - 16)); } static void -mikasa_disable_irq(unsigned int irq) +mikasa_disable_irq(struct irq_data *d) { - mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16))); + mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (d->irq - 16))); } static struct irq_chip mikasa_irq_type = { .name = "MIKASA", - .unmask = mikasa_enable_irq, - .mask = mikasa_disable_irq, - .mask_ack = mikasa_disable_irq, + .irq_unmask = mikasa_enable_irq, + .irq_mask = mikasa_disable_irq, + .irq_mask_ack = mikasa_disable_irq, }; static void @@ -98,8 +98,8 @@ mikasa_init_irq(void) mikasa_update_irq_hw(0); for (i = 16; i < 32; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &mikasa_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } init_i8259a_irqs(); -- cgit v0.10.2 From 67436cef1926cbb2f0b4dabed5aa7fcba8a70891 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:44 +0000 Subject: alpha: rawhide: Convert irq_chip functions Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 6a51364..936d414 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -56,9 +56,10 @@ rawhide_update_irq_hw(int hose, int mask) (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0)) static inline void -rawhide_enable_irq(unsigned int irq) +rawhide_enable_irq(struct irq_data *d) { unsigned int mask, hose; + unsigned int irq = d->irq; irq -= 16; hose = irq / 24; @@ -76,9 +77,10 @@ rawhide_enable_irq(unsigned int irq) } static void -rawhide_disable_irq(unsigned int irq) +rawhide_disable_irq(struct irq_data *d) { unsigned int mask, hose; + unsigned int irq = d->irq; irq -= 16; hose = irq / 24; @@ -96,9 +98,10 @@ rawhide_disable_irq(unsigned int irq) } static void -rawhide_mask_and_ack_irq(unsigned int irq) +rawhide_mask_and_ack_irq(struct irq_data *d) { unsigned int mask, mask1, hose; + unsigned int irq = d->irq; irq -= 16; hose = irq / 24; @@ -123,9 +126,9 @@ rawhide_mask_and_ack_irq(unsigned int irq) static struct irq_chip rawhide_irq_type = { .name = "RAWHIDE", - .unmask = rawhide_enable_irq, - .mask = rawhide_disable_irq, - .mask_ack = rawhide_mask_and_ack_irq, + .irq_unmask = rawhide_enable_irq, + .irq_mask = rawhide_disable_irq, + .irq_mask_ack = rawhide_mask_and_ack_irq, }; static void @@ -177,8 +180,8 @@ rawhide_init_irq(void) } for (i = 16; i < 128; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &rawhide_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } init_i8259a_irqs(); -- cgit v0.10.2 From 76f4645fc2011cc4bd8952befed3e74bcd77a929 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:46 +0000 Subject: alpha: noritake: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index e88f4ae..92bc188 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -48,22 +48,22 @@ noritake_update_irq_hw(int irq, int mask) } static void -noritake_enable_irq(unsigned int irq) +noritake_enable_irq(struct irq_data *d) { - noritake_update_irq_hw(irq, cached_irq_mask |= 1 << (irq - 16)); + noritake_update_irq_hw(d->irq, cached_irq_mask |= 1 << (d->irq - 16)); } static void -noritake_disable_irq(unsigned int irq) +noritake_disable_irq(struct irq_data *d) { - noritake_update_irq_hw(irq, cached_irq_mask &= ~(1 << (irq - 16))); + noritake_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << (d->irq - 16))); } static struct irq_chip noritake_irq_type = { .name = "NORITAKE", - .unmask = noritake_enable_irq, - .mask = noritake_disable_irq, - .mask_ack = noritake_disable_irq, + .irq_unmask = noritake_enable_irq, + .irq_mask = noritake_disable_irq, + .irq_mask_ack = noritake_disable_irq, }; static void @@ -127,8 +127,8 @@ noritake_init_irq(void) outw(0, 0x54c); for (i = 16; i < 48; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &noritake_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } init_i8259a_irqs(); -- cgit v0.10.2 From 2758a8af18ca4ea7148927f3a58ddcb1bf163d76 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:49 +0000 Subject: alpha: rx164: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index 89e7e37e..cea22a6 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -47,22 +47,22 @@ rx164_update_irq_hw(unsigned long mask) } static inline void -rx164_enable_irq(unsigned int irq) +rx164_enable_irq(struct irq_data *d) { - rx164_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); + rx164_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16)); } static void -rx164_disable_irq(unsigned int irq) +rx164_disable_irq(struct irq_data *d) { - rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); + rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16))); } static struct irq_chip rx164_irq_type = { .name = "RX164", - .unmask = rx164_enable_irq, - .mask = rx164_disable_irq, - .mask_ack = rx164_disable_irq, + .irq_unmask = rx164_enable_irq, + .irq_mask = rx164_disable_irq, + .irq_mask_ack = rx164_disable_irq, }; static void @@ -99,8 +99,8 @@ rx164_init_irq(void) rx164_update_irq_hw(0); for (i = 16; i < 40; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &rx164_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } init_i8259a_irqs(); -- cgit v0.10.2 From c90c10c8bf9624c95ba02228fb58e7bebe68fb1b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:51 +0000 Subject: alpha: sable: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index 5c4423d..a349538 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -443,11 +443,11 @@ lynx_swizzle(struct pci_dev *dev, u8 *pinp) /* GENERIC irq routines */ static inline void -sable_lynx_enable_irq(unsigned int irq) +sable_lynx_enable_irq(struct irq_data *d) { unsigned long bit, mask; - bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; + bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq]; spin_lock(&sable_lynx_irq_lock); mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit); sable_lynx_irq_swizzle->update_irq_hw(bit, mask); @@ -459,11 +459,11 @@ sable_lynx_enable_irq(unsigned int irq) } static void -sable_lynx_disable_irq(unsigned int irq) +sable_lynx_disable_irq(struct irq_data *d) { unsigned long bit, mask; - bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; + bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq]; spin_lock(&sable_lynx_irq_lock); mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit; sable_lynx_irq_swizzle->update_irq_hw(bit, mask); @@ -475,11 +475,11 @@ sable_lynx_disable_irq(unsigned int irq) } static void -sable_lynx_mask_and_ack_irq(unsigned int irq) +sable_lynx_mask_and_ack_irq(struct irq_data *d) { unsigned long bit, mask; - bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; + bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq]; spin_lock(&sable_lynx_irq_lock); mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit; sable_lynx_irq_swizzle->update_irq_hw(bit, mask); @@ -489,9 +489,9 @@ sable_lynx_mask_and_ack_irq(unsigned int irq) static struct irq_chip sable_lynx_irq_type = { .name = "SABLE/LYNX", - .unmask = sable_lynx_enable_irq, - .mask = sable_lynx_disable_irq, - .mask_ack = sable_lynx_mask_and_ack_irq, + .irq_unmask = sable_lynx_enable_irq, + .irq_mask = sable_lynx_disable_irq, + .irq_mask_ack = sable_lynx_mask_and_ack_irq, }; static void @@ -518,9 +518,9 @@ sable_lynx_init_irq(int nr_of_irqs) long i; for (i = 0; i < nr_of_irqs; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &sable_lynx_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } common_init_isa_dma(); -- cgit v0.10.2 From b148c6146147ad9985e08ce518f032d8b01d8b30 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:53 +0000 Subject: alpha: takara: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index f8a1e8a..42a5331 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -45,16 +45,18 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask) } static inline void -takara_enable_irq(unsigned int irq) +takara_enable_irq(struct irq_data *d) { + unsigned int irq = d->irq; unsigned long mask; mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63))); takara_update_irq_hw(irq, mask); } static void -takara_disable_irq(unsigned int irq) +takara_disable_irq(struct irq_data *d) { + unsigned int irq = d->irq; unsigned long mask; mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63)); takara_update_irq_hw(irq, mask); @@ -62,9 +64,9 @@ takara_disable_irq(unsigned int irq) static struct irq_chip takara_irq_type = { .name = "TAKARA", - .unmask = takara_enable_irq, - .mask = takara_disable_irq, - .mask_ack = takara_disable_irq, + .irq_unmask = takara_enable_irq, + .irq_mask = takara_disable_irq, + .irq_mask_ack = takara_disable_irq, }; static void @@ -136,8 +138,8 @@ takara_init_irq(void) takara_update_irq_hw(i, -1); for (i = 16; i < 128; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, &takara_irq_type, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } common_init_isa_dma(); -- cgit v0.10.2 From 628150cae3d83136416a384b939d8a6fad52499e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:56 +0000 Subject: alpha: titan: Convert irq_chip functions Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index e02494b..f6c108a 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -112,8 +112,9 @@ titan_update_irq_hw(unsigned long mask) } static inline void -titan_enable_irq(unsigned int irq) +titan_enable_irq(struct irq_data *d) { + unsigned int irq = d->irq; spin_lock(&titan_irq_lock); titan_cached_irq_mask |= 1UL << (irq - 16); titan_update_irq_hw(titan_cached_irq_mask); @@ -121,8 +122,9 @@ titan_enable_irq(unsigned int irq) } static inline void -titan_disable_irq(unsigned int irq) +titan_disable_irq(struct irq_data *d) { + unsigned int irq = d->irq; spin_lock(&titan_irq_lock); titan_cached_irq_mask &= ~(1UL << (irq - 16)); titan_update_irq_hw(titan_cached_irq_mask); @@ -144,7 +146,8 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) } static int -titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) +titan_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, + bool force) { spin_lock(&titan_irq_lock); titan_cpu_set_irq_affinity(irq - 16, *affinity); @@ -175,17 +178,17 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax) { long i; for (i = imin; i <= imax; ++i) { - irq_to_desc(i)->status |= IRQ_LEVEL; set_irq_chip_and_handler(i, ops, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); } } static struct irq_chip titan_irq_type = { - .name = "TITAN", - .unmask = titan_enable_irq, - .mask = titan_disable_irq, - .mask_ack = titan_disable_irq, - .set_affinity = titan_set_irq_affinity, + .name = "TITAN", + .irq_unmask = titan_enable_irq, + .irq_mask = titan_disable_irq, + .irq_mask_ack = titan_disable_irq, + .irq_set_affinity = titan_set_irq_affinity, }; static irqreturn_t -- cgit v0.10.2 From eb1e17fb9956eb3156f33cdcd880306102212661 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:32:58 +0000 Subject: alpha: irq: Remove pointless irq status manipulation The irq descriptors are initialized IRQ_DISABLED in the generic code. No need to fiddle with them. Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 2d0679b..411ca11 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -228,14 +228,9 @@ struct irqaction timer_irqaction = { void __init init_rtc_irq(void) { - struct irq_desc *desc = irq_to_desc(RTC_IRQ); - - if (desc) { - desc->status |= IRQ_DISABLED; - set_irq_chip_and_handler_name(RTC_IRQ, &no_irq_chip, - handle_simple_irq, "RTC"); - setup_irq(RTC_IRQ, &timer_irqaction); - } + set_irq_chip_and_handler_name(RTC_IRQ, &no_irq_chip, + handle_simple_irq, "RTC"); + setup_irq(RTC_IRQ, &timer_irqaction); } /* Dummy irqactions. */ -- cgit v0.10.2 From 0b534cf3e86c3fec7703173f45fcb9290b77667b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:33:00 +0000 Subject: alpha: irq: Convert affinity to use irq_data affinity is moving to irq_data. Fix it up. Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index d3e20c7..a19d600 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -44,11 +44,16 @@ static char irq_user_affinity[NR_IRQS]; int irq_select_affinity(unsigned int irq) { - struct irq_desc *desc = irq_to_desc(irq); + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip; static int last_cpu; int cpu = last_cpu + 1; - if (!desc || !get_irq_desc_chip(desc)->set_affinity || irq_user_affinity[irq]) + if (!data) + return 1; + chip = irq_data_get_irq_chip(data); + + if (!chip->irq_set_affinity || irq_user_affinity[irq]) return 1; while (!cpu_possible(cpu) || @@ -56,8 +61,8 @@ int irq_select_affinity(unsigned int irq) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - cpumask_copy(desc->affinity, cpumask_of(cpu)); - get_irq_desc_chip(desc)->set_affinity(irq, cpumask_of(cpu)); + cpumask_copy(data->affinity, cpumask_of(cpu)); + chip->irq_set_affinity(data, cpumask_of(cpu), false); return 0; } #endif /* CONFIG_SMP */ -- cgit v0.10.2 From 10e53f5834cd3b9a14e1c944a3e7ad34ee368834 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 6 Feb 2011 14:33:02 +0000 Subject: alpha: Enable GENERIC_HARDIRQS_NO_DEPRECATED All interrupt chips are converted. Mark it clean. Signed-off-by: Thomas Gleixner Signed-off-by: Matt Turner diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 47f63d4..cc31bec 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -11,6 +11,7 @@ config ALPHA select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select AUTO_IRQ_AFFINITY if SMP + select GENERIC_HARDIRQS_NO_DEPRECATED help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, -- cgit v0.10.2 From 337fc720d85b98a71b1ff6e3a5449a24a7c33cfe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 14 Feb 2011 11:40:09 +0100 Subject: of: Add missing of_address.h to xilinx ehci driver Build log: In file included from drivers/usb/host/ehci-hcd.c:1208: drivers/usb/host/ehci-xilinx-of.c: In function 'ehci_hcd_xilinx_of_probe': drivers/usb/host/ehci-xilinx-of.c:168: error: implicit declaration of function 'of_address_to_resource' Signed-off-by: John Williams Signed-off-by: Michal Simek Acked-by: Greg Kroah-Hartman Signed-off-by: Grant Likely diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index e8f4f36..a6f21b8 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -29,6 +29,7 @@ #include #include +#include /** * ehci_xilinx_of_setup - Initialize the device for ehci_reset() -- cgit v0.10.2 From 8aaccf7fa2a2f148db1edbe7b09e3119c3f910cf Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 14 Feb 2011 22:34:22 +0100 Subject: of/flattree: Drop an uninteresting message to pr_debug level This message looks like an error (which it isn't) when booting with a flattened device tree. Remove the message from normal kernel builds. Signed-off-by: Paul Bolle Signed-off-by: Grant Likely diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index d9396a4..927cbd1 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c @@ -233,7 +233,7 @@ void __init proc_device_tree_init(void) return; root = of_find_node_by_path("/"); if (root == NULL) { - printk(KERN_ERR "/proc/device-tree: can't find root\n"); + pr_debug("/proc/device-tree: can't find root\n"); return; } proc_device_tree_add_node(root, proc_device_tree); -- cgit v0.10.2 From 60cba5a57b8affe98ea9f2bac147be0fb253d5f4 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 24 Feb 2011 20:06:31 -0800 Subject: x86: OLPC: have prom_early_alloc BUG rather than return NULL ..similar to what sparc's prom_early_alloc does. Signed-off-by: Andres Salomon Signed-off-by: Grant Likely diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c index dab8746..044bda5 100644 --- a/arch/x86/platform/olpc/olpc_dt.c +++ b/arch/x86/platform/olpc/olpc_dt.c @@ -140,8 +140,7 @@ void * __init prom_early_alloc(unsigned long size) * wasted bootmem) and hand off chunks of it to callers. */ res = alloc_bootmem(chunk_size); - if (!res) - return NULL; + BUG_ON(!res); prom_early_allocated += chunk_size; memset(res, 0, chunk_size); free_mem = chunk_size; -- cgit v0.10.2 From a74ea43df1afc68f265c0ac2cb64031d855ae97b Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Wed, 23 Feb 2011 22:38:22 -0800 Subject: of/promtree: allow DT device matching by fixing 'name' brokenness (v5) Commit e2f2a93b, "of/promtree: add package-to-path support to pdt" changed dp->name from using the 'name' property to using package-to-path. This fixed /proc/device-tree creation by eliminating conflicts between names (the 'name' property provides names like 'battery', whereas package-to-path provides names like '/foo/bar/battery@0', which we stripped to 'battery@0'). However, it also breaks of_device_id table matching. The fix that we _really_ wanted was to keep dp->name based upon the name property ('battery'), but based dp->full_name upon package-to-path ('battery@0'). This patch does just that. This changes all users (except SPARC) of promtree to use the full result from package-to-path for full_name, rather than stripping the directory out. In practice, the strings end up being exactly the same; this change saves time, code, and memory. SPARC continues to use the existing build_path_component() code. v2: combine two patches and revert of_pdt_node_name to original version v3: use dp->phandle instead of passing around node v4: warn/bail out for non-sparc archs if pkg2path is not set v5: split of_pdt_build_full_name into sparc & non-sparc versions v6: Pass NULL to pkg2path before buf gets assigned. Drop check for pkg2path hook on each and every node. v7: Don't BUG() when unable to get the full_path; create a known-unique name instead. Signed-off-by: Andres Salomon Signed-off-by: Grant Likely diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 28295d0..4d87b5d 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -36,19 +36,55 @@ unsigned int of_pdt_unique_id __initdata; (p)->unique_id = of_pdt_unique_id++; \ } while (0) -static inline const char *of_pdt_node_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp) { - return dp->path_component_name; + int len, ourlen, plen; + char *n; + + dp->path_component_name = build_path_component(dp); + + plen = strlen(dp->parent->full_name); + ourlen = strlen(dp->path_component_name); + len = ourlen + plen + 2; + + n = prom_early_alloc(len); + strcpy(n, dp->parent->full_name); + if (!of_node_is_root(dp->parent)) { + strcpy(n + plen, "/"); + plen++; + } + strcpy(n + plen, dp->path_component_name); + + return n; } -#else +#else /* CONFIG_SPARC */ static inline void of_pdt_incr_unique_id(void *p) { } static inline void irq_trans_init(struct device_node *dp) { } -static inline const char *of_pdt_node_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp) { - return dp->name; + static int failsafe_id = 0; /* for generating unique names on failure */ + char *buf; + int len; + + if (of_pdt_prom_ops->pkg2path(dp->phandle, NULL, 0, &len)) + goto failsafe; + + buf = prom_early_alloc(len + 1); + if (of_pdt_prom_ops->pkg2path(dp->phandle, buf, len, &len)) + goto failsafe; + return buf; + + failsafe: + buf = prom_early_alloc(strlen(dp->parent->full_name) + + strlen(dp->name) + 16); + sprintf(buf, "%s/%s@unknown%i", + of_node_is_root(dp->parent) ? "" : dp->parent->full_name, + dp->name, failsafe_id++); + pr_err("%s: pkg2path failed; assigning %s\n", __func__, buf); + return buf; } #endif /* !CONFIG_SPARC */ @@ -132,47 +168,6 @@ static char * __init of_pdt_get_one_property(phandle node, const char *name) return buf; } -static char * __init of_pdt_try_pkg2path(phandle node) -{ - char *res, *buf = NULL; - int len; - - if (!of_pdt_prom_ops->pkg2path) - return NULL; - - if (of_pdt_prom_ops->pkg2path(node, buf, 0, &len)) - return NULL; - buf = prom_early_alloc(len + 1); - if (of_pdt_prom_ops->pkg2path(node, buf, len, &len)) { - pr_err("%s: package-to-path failed\n", __func__); - return NULL; - } - - res = strrchr(buf, '/'); - if (!res) { - pr_err("%s: couldn't find / in %s\n", __func__, buf); - return NULL; - } - return res+1; -} - -/* - * When fetching the node's name, first try using package-to-path; if - * that fails (either because the arch hasn't supplied a PROM callback, - * or some other random failure), fall back to just looking at the node's - * 'name' property. - */ -static char * __init of_pdt_build_name(phandle node) -{ - char *buf; - - buf = of_pdt_try_pkg2path(node); - if (!buf) - buf = of_pdt_get_one_property(node, "name"); - - return buf; -} - static struct device_node * __init of_pdt_create_node(phandle node, struct device_node *parent) { @@ -187,7 +182,7 @@ static struct device_node * __init of_pdt_create_node(phandle node, kref_init(&dp->kref); - dp->name = of_pdt_build_name(node); + dp->name = of_pdt_get_one_property(node, "name"); dp->type = of_pdt_get_one_property(node, "device_type"); dp->phandle = node; @@ -198,26 +193,6 @@ static struct device_node * __init of_pdt_create_node(phandle node, return dp; } -static char * __init of_pdt_build_full_name(struct device_node *dp) -{ - int len, ourlen, plen; - char *n; - - plen = strlen(dp->parent->full_name); - ourlen = strlen(of_pdt_node_name(dp)); - len = ourlen + plen + 2; - - n = prom_early_alloc(len); - strcpy(n, dp->parent->full_name); - if (!of_node_is_root(dp->parent)) { - strcpy(n + plen, "/"); - plen++; - } - strcpy(n + plen, of_pdt_node_name(dp)); - - return n; -} - static struct device_node * __init of_pdt_build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) @@ -240,9 +215,6 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, *(*nextp) = dp; *nextp = &dp->allnext; -#if defined(CONFIG_SPARC) - dp->path_component_name = build_path_component(dp); -#endif dp->full_name = of_pdt_build_full_name(dp); dp->child = of_pdt_build_tree(dp, -- cgit v0.10.2 From f3d7bc57c71eba3f279785111bb473b1ef68dcb6 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 2 Mar 2011 10:35:33 +0000 Subject: net: dcbnl: check correct ops in dcbnl_ieee_set() The incorrect ops routine was being tested for in DCB_ATTR_IEEE_PFC attributes. This patch corrects it. Currently, every driver implementing ieee_setets also implements ieee_setpfc so this bug is not actualized yet. Signed-off-by: John Fastabend Signed-off-by: David S. Miller diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index d5074a5..c44348a 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1193,7 +1193,7 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, goto err; } - if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) { + if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); err = ops->ieee_setpfc(netdev, pfc); if (err) -- cgit v0.10.2 From 107c3f4d42adc9af393019b795dd2177fbe9e465 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 2 Mar 2011 13:00:49 +0000 Subject: cnic: Prevent status block race conditions with hardware The status block index is used to acknowledge interrupt events and must be read before checking for the interrupt events, so we need to add rmb() to guarantee that. Signed-off-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 7ff170c..b0d9e4a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2760,6 +2760,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) u32 status_idx = (u16) *cp->kcq1.status_idx_ptr; int kcqe_cnt; + /* status block index must be read before reading other fields */ + rmb(); cp->kwq_con_idx = *cp->kwq_con_idx_ptr; while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { @@ -2770,6 +2772,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) barrier(); if (status_idx != *cp->kcq1.status_idx_ptr) { status_idx = (u16) *cp->kcq1.status_idx_ptr; + /* status block index must be read first */ + rmb(); cp->kwq_con_idx = *cp->kwq_con_idx_ptr; } else break; @@ -2888,6 +2892,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) u32 last_status = *info->status_idx_ptr; int kcqe_cnt; + /* status block index must be read before reading the KCQ */ + rmb(); while ((kcqe_cnt = cnic_get_kcqes(dev, info))) { service_kcqes(dev, kcqe_cnt); @@ -2898,6 +2904,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) break; last_status = *info->status_idx_ptr; + /* status block index must be read before reading the KCQ */ + rmb(); } return last_status; } -- cgit v0.10.2 From 0197b087ed6384760656f1e4a620a3e92d8dc0b0 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 2 Mar 2011 13:00:50 +0000 Subject: cnic: Fix lost interrupt on bnx2x We service 2 queues (kcq1 and kcq2) in cnic_service_bnx2x_bh(). If the status block index has changed when servicing the kcq2, we must go back and check kcq1. The latest status block index will be used to acknowledge the interrupt, and without looping back to check kcq1, we may miss events on kcq1. Signed-off-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index b0d9e4a..302be4a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2914,26 +2914,35 @@ static void cnic_service_bnx2x_bh(unsigned long data) { struct cnic_dev *dev = (struct cnic_dev *) data; struct cnic_local *cp = dev->cnic_priv; - u32 status_idx; + u32 status_idx, new_status_idx; if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) return; - status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); + while (1) { + status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); - CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); + CNIC_WR16(dev, cp->kcq1.io_addr, + cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { - status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); + if (!BNX2X_CHIP_IS_E2(cp->chip_id)) { + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, + status_idx, IGU_INT_ENABLE, 1); + break; + } + + new_status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); + + if (new_status_idx != status_idx) + continue; CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx + MAX_KCQ_IDX); cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, status_idx, IGU_INT_ENABLE, 1); - } else { - cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, - status_idx, IGU_INT_ENABLE, 1); + + break; } } -- cgit v0.10.2 From 10003453479ef287a73f8a39593f8f42687ea565 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 28 Feb 2011 03:27:43 +0000 Subject: AF_RXRPC: Handle receiving ACKALL packets The OpenAFS server is now sending ACKALL packets, so we need to handle them. Otherwise we report a protocol error and abort. Signed-off-by: David Howells Signed-off-by: David S. Miller diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c index 8931500..1a2b0633 100644 --- a/net/rxrpc/ar-input.c +++ b/net/rxrpc/ar-input.c @@ -423,6 +423,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb) goto protocol_error; } + case RXRPC_PACKET_TYPE_ACKALL: case RXRPC_PACKET_TYPE_ACK: /* ACK processing is done in process context */ read_lock_bh(&call->state_lock); -- cgit v0.10.2 From f009918a1c1bbf8607b8aab3959876913a30193a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 28 Feb 2011 03:27:53 +0000 Subject: RxRPC: Fix v1 keys commit 339412841d7 (RxRPC: Allow key payloads to be passed in XDR form) broke klog for me. I notice the v1 key struct had a kif_version field added: -struct rxkad_key { - u16 security_index; /* RxRPC header security index */ - u16 ticket_len; /* length of ticket[] */ - u32 expiry; /* time at which expires */ - u32 kvno; /* key version number */ - u8 session_key[8]; /* DES session key */ - u8 ticket[0]; /* the encrypted ticket */ -}; +struct rxrpc_key_data_v1 { + u32 kif_version; /* 1 */ + u16 security_index; + u16 ticket_length; + u32 expiry; /* time_t */ + u32 kvno; + u8 session_key[8]; + u8 ticket[0]; +}; However the code in rxrpc_instantiate strips it away: data += sizeof(kver); datalen -= sizeof(kver); Removing kif_version fixes my problem. Signed-off-by: Anton Blanchard Signed-off-by: David Howells Signed-off-by: David S. Miller diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h index 5cb86c3..fc48754 100644 --- a/include/keys/rxrpc-type.h +++ b/include/keys/rxrpc-type.h @@ -99,7 +99,6 @@ struct rxrpc_key_token { * structure of raw payloads passed to add_key() or instantiate key */ struct rxrpc_key_data_v1 { - u32 kif_version; /* 1 */ u16 security_index; u16 ticket_length; u32 expiry; /* time_t */ -- cgit v0.10.2 From 4787d45fa76b97e224a8299086bb5fb496275796 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 09:38:45 -0500 Subject: sysv: i_nlink races in rename() Signed-off-by: Al Viro diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index b427b12..e474fbc 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -245,7 +245,6 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, new_de = sysv_find_entry(new_dentry, &new_page); if (!new_de) goto out_dir; - inode_inc_link_count(old_inode); sysv_set_link(new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) @@ -257,18 +256,15 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, if (new_dir->i_nlink >= SYSV_SB(new_dir->i_sb)->s_link_max) goto out_dir; } - inode_inc_link_count(old_inode); err = sysv_add_link(new_dentry, old_inode); - if (err) { - inode_dec_link_count(old_inode); + if (err) goto out_dir; - } if (dir_de) inode_inc_link_count(new_dir); } sysv_delete_entry(old_de, old_page); - inode_dec_link_count(old_inode); + mark_inode_dirty(old_inode); if (dir_de) { sysv_set_link(dir_de, dir_page, new_dir); -- cgit v0.10.2 From 37750cdda36721fa7fa816f5f58258d2c013b248 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 09:40:21 -0500 Subject: ufs: i_nlink races in rename() Signed-off-by: Al Viro diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 12f39b9..d6f6815 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -306,7 +306,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); if (!new_de) goto out_dir; - inode_inc_link_count(old_inode); ufs_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) @@ -318,12 +317,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dir->i_nlink >= UFS_LINK_MAX) goto out_dir; } - inode_inc_link_count(old_inode); err = ufs_add_link(new_dentry, old_inode); - if (err) { - inode_dec_link_count(old_inode); + if (err) goto out_dir; - } if (dir_de) inode_inc_link_count(new_dir); } @@ -331,12 +327,11 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, /* * Like most other Unix systems, set the ctime for inodes on a * rename. - * inode_dec_link_count() will mark the inode dirty. */ old_inode->i_ctime = CURRENT_TIME_SEC; ufs_delete_entry(old_dir, old_de, old_page); - inode_dec_link_count(old_inode); + mark_inode_dirty(old_inode); if (dir_de) { ufs_set_link(old_inode, dir_de, dir_page, new_dir); -- cgit v0.10.2 From 6f88049caf56022c773272e03ddfa8cf79867059 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 09:41:38 -0500 Subject: minix: i_nlink races in rename() Signed-off-by: Al Viro diff --git a/fs/minix/namei.c b/fs/minix/namei.c index ce7337d..6e6777f 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -213,7 +213,6 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, new_de = minix_find_entry(new_dentry, &new_page); if (!new_de) goto out_dir; - inode_inc_link_count(old_inode); minix_set_link(new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) @@ -225,18 +224,15 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, if (new_dir->i_nlink >= info->s_link_max) goto out_dir; } - inode_inc_link_count(old_inode); err = minix_add_link(new_dentry, old_inode); - if (err) { - inode_dec_link_count(old_inode); + if (err) goto out_dir; - } if (dir_de) inode_inc_link_count(new_dir); } minix_delete_entry(old_de, old_page); - inode_dec_link_count(old_inode); + mark_inode_dirty(old_inode); if (dir_de) { minix_set_link(dir_de, dir_page, new_dir); -- cgit v0.10.2 From 30eb43d31478f0fca28423623f3ec6af13f845fa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 12:01:13 -0500 Subject: nilfs2: i_nlink races in rename() Signed-off-by: Al Viro diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 9803427..161791d 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c @@ -397,7 +397,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page); if (!new_de) goto out_dir; - inc_nlink(old_inode); nilfs_set_link(new_dir, new_de, new_page, old_inode); nilfs_mark_inode_dirty(new_dir); new_inode->i_ctime = CURRENT_TIME; @@ -411,13 +410,9 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dir->i_nlink >= NILFS_LINK_MAX) goto out_dir; } - inc_nlink(old_inode); err = nilfs_add_link(new_dentry, old_inode); - if (err) { - drop_nlink(old_inode); - nilfs_mark_inode_dirty(old_inode); + if (err) goto out_dir; - } if (dir_de) { inc_nlink(new_dir); nilfs_mark_inode_dirty(new_dir); @@ -431,7 +426,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_inode->i_ctime = CURRENT_TIME; nilfs_delete_entry(old_de, old_page); - drop_nlink(old_inode); if (dir_de) { nilfs_set_link(old_inode, dir_de, dir_page, new_dir); -- cgit v0.10.2 From babfe56046885749b6a90a3c4409219a1f16cf48 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 16:42:38 -0500 Subject: exofs: i_nlink races in rename() Signed-off-by: Al Viro diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 264e95d..4d70db1 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c @@ -272,7 +272,6 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry, new_de = exofs_find_entry(new_dir, new_dentry, &new_page); if (!new_de) goto out_dir; - inode_inc_link_count(old_inode); err = exofs_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME; if (dir_de) @@ -286,12 +285,9 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dir->i_nlink >= EXOFS_LINK_MAX) goto out_dir; } - inode_inc_link_count(old_inode); err = exofs_add_link(new_dentry, old_inode); - if (err) { - inode_dec_link_count(old_inode); + if (err) goto out_dir; - } if (dir_de) inode_inc_link_count(new_dir); } @@ -299,7 +295,7 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry, old_inode->i_ctime = CURRENT_TIME; exofs_delete_entry(old_de, old_page); - inode_dec_link_count(old_inode); + mark_inode_dirty(old_inode); if (dir_de) { err = exofs_set_link(old_inode, dir_de, dir_page, new_dir); -- cgit v0.10.2 From 99890a3be1ee67346300f1e0a873006588760f2a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 09:35:13 -0500 Subject: fix reiserfs mkdir() breakage if directory has so many subdirectories that its link count is set to 1 (i.e. "can't tell accurately") and reiserfs_new_inode() fails, we shouldn't decrement the parent's link count in cleanup path; that's what DEC_DIR_INODE_NLINK() is for. As it is, we end up with parent suddenly getting zero i_nlink, with very unpleasant effects. Signed-off-by: Al Viro diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index ba5f51e..68fdf45 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -771,7 +771,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE, dentry, inode, &security); if (retval) { - dir->i_nlink--; + DEC_DIR_INODE_NLINK(dir) goto out_failed; } -- cgit v0.10.2 From 810c1b2e48d32a8605928c3609262d94853c3a76 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 10:15:26 -0500 Subject: udf: fix i_nlink limit (256 << sizeof(x)) - 1 is not the maximal possible value of x... In reality, the maximal allowed value for UDF FileLinkCount is 65535. Signed-off-by: Al Viro diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 2be0f9e..b7c338d 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -32,6 +32,8 @@ #include #include +enum { UDF_MAX_LINKS = 0xffff }; + static inline int udf_match(int len1, const unsigned char *name1, int len2, const unsigned char *name2) { @@ -650,7 +652,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) struct udf_inode_info *iinfo; err = -EMLINK; - if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) + if (dir->i_nlink >= UDF_MAX_LINKS) goto out; err = -EIO; @@ -1034,9 +1036,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, struct fileIdentDesc cfi, *fi; int err; - if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { + if (inode->i_nlink >= UDF_MAX_LINKS) return -EMLINK; - } fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); if (!fi) { @@ -1131,9 +1132,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, goto end_rename; retval = -EMLINK; - if (!new_inode && - new_dir->i_nlink >= - (256 << sizeof(new_dir->i_nlink)) - 1) + if (!new_inode && new_dir->i_nlink >= UDF_MAX_LINKS) goto end_rename; } if (!nfi) { -- cgit v0.10.2 From 69102e9b4b61f56a26717659ec2e572a6b18458d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Mar 2011 23:46:51 -0500 Subject: hfs: fix rename() over non-empty directory merge hfs_unlink() and hfs_rmdir(), while we are at it. Signed-off-by: Al Viro diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index afa66aa..b4d70b1 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -238,46 +238,22 @@ static int hfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) } /* - * hfs_unlink() + * hfs_remove() * - * This is the unlink() entry in the inode_operations structure for - * regular HFS directories. The purpose is to delete an existing - * file, given the inode for the parent directory and the name - * (and its length) of the existing file. - */ -static int hfs_unlink(struct inode *dir, struct dentry *dentry) -{ - struct inode *inode; - int res; - - inode = dentry->d_inode; - res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); - if (res) - return res; - - drop_nlink(inode); - hfs_delete_inode(inode); - inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(inode); - - return res; -} - -/* - * hfs_rmdir() + * This serves as both unlink() and rmdir() in the inode_operations + * structure for regular HFS directories. The purpose is to delete + * an existing child, given the inode for the parent directory and + * the name (and its length) of the existing directory. * - * This is the rmdir() entry in the inode_operations structure for - * regular HFS directories. The purpose is to delete an existing - * directory, given the inode for the parent directory and the name - * (and its length) of the existing directory. + * HFS does not have hardlinks, so both rmdir and unlink set the + * link count to 0. The only difference is the emptiness check. */ -static int hfs_rmdir(struct inode *dir, struct dentry *dentry) +static int hfs_remove(struct inode *dir, struct dentry *dentry) { - struct inode *inode; + struct inode *inode = dentry->d_inode; int res; - inode = dentry->d_inode; - if (inode->i_size != 2) + if (S_ISDIR(inode->i_mode) && inode->i_size != 2) return -ENOTEMPTY; res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); if (res) @@ -307,7 +283,7 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, /* Unlink destination if it already exists */ if (new_dentry->d_inode) { - res = hfs_unlink(new_dir, new_dentry); + res = hfs_remove(new_dir, new_dentry); if (res) return res; } @@ -332,9 +308,9 @@ const struct file_operations hfs_dir_operations = { const struct inode_operations hfs_dir_inode_operations = { .create = hfs_create, .lookup = hfs_lookup, - .unlink = hfs_unlink, + .unlink = hfs_remove, .mkdir = hfs_mkdir, - .rmdir = hfs_rmdir, + .rmdir = hfs_remove, .rename = hfs_rename, .setattr = hfs_inode_setattr, }; -- cgit v0.10.2 From c8900a0fad5ae9f4823451de17ba5dec6653ac74 Mon Sep 17 00:00:00 2001 From: Richard Samson Date: Thu, 3 Mar 2011 12:46:13 +0100 Subject: ALSA: hda - add new Fermi 5xx codec IDs to snd-hda Added the missing HDMI codec IDs for new Nvidia stuff. Note that ID 0x17 isn't assigned to anything so far, as suggested by Stephen. [Modified to get rid of 0x17 by tiwai] Signed-off-by: Richard Samson Acked-by: Acked-By: Stephen Warren Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index a587677..ec0fa2d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1634,6 +1634,9 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +/* 17 is known to be absent */ { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, @@ -1676,6 +1679,8 @@ MODULE_ALIAS("snd-hda-codec-id:10de0011"); MODULE_ALIAS("snd-hda-codec-id:10de0012"); MODULE_ALIAS("snd-hda-codec-id:10de0013"); MODULE_ALIAS("snd-hda-codec-id:10de0014"); +MODULE_ALIAS("snd-hda-codec-id:10de0015"); +MODULE_ALIAS("snd-hda-codec-id:10de0016"); MODULE_ALIAS("snd-hda-codec-id:10de0018"); MODULE_ALIAS("snd-hda-codec-id:10de0019"); MODULE_ALIAS("snd-hda-codec-id:10de001a"); -- cgit v0.10.2 From 38c07641905c0db58e800ea974cd9158717c6610 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 3 Mar 2011 14:54:19 +0100 Subject: ALSA: hda - Don't set to D3 in Cirrus errata init verbs The errata init verbs for CS42xx codecs contain the verbs to set the power-state of SPDIF nodes to D3, which seem to break the SPDIF output on some MacBooks. Since this is executed during the power-up initialization, we shouldn't turn them down there. Reported-by: Arun Raghavan Cc: Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index a07b031..067982f4 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -1039,9 +1039,11 @@ static struct hda_verb cs_errata_init_verbs[] = { {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, {0x11, AC_VERB_SET_PROC_STATE, 0x00}, +#if 0 /* Don't to set to D3 as we are in power-up sequence */ {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ +#endif {} /* terminator */ }; -- cgit v0.10.2 From 2d3a8497f8cc5aca14b722cd37d51f6c15ff9f74 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Thu, 3 Mar 2011 10:53:20 -0500 Subject: blktrace: Remove blk_fill_rwbs_rq. If we enable trace events to trace block actions, We use blk_fill_rwbs_rq to analyze the corresponding actions in request's cmd_flags, but we only choose the minor 2 bits from it, so most of other flags(e.g, REQ_SYNC) are missing. For example, with a sync write we get: write_test-2409 [001] 160.013869: block_rq_insert: 3,64 W 0 () 258135 + = 8 [write_test] Since now we have integrated the flags of both bio and request, it is safe to pass rq->cmd_flags directly to blk_fill_rwbs and blk_fill_rwbs_rq isn't needed any more. With this patch, after a sync write we get: write_test-2417 [000] 226.603878: block_rq_insert: 3,64 WS 0 () 258135 += 8 [write_test] Signed-off-by: Tao Ma Acked-by: Jeff Moyer Signed-off-by: Jens Axboe diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 3395cf7..b22fb0d 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -245,7 +245,6 @@ static inline int blk_cmd_buf_len(struct request *rq) extern void blk_dump_cmd(char *buf, struct request *rq); extern void blk_fill_rwbs(char *rwbs, u32 rw, int bytes); -extern void blk_fill_rwbs_rq(char *rwbs, struct request *rq); #endif /* CONFIG_EVENT_TRACING && CONFIG_BLOCK */ diff --git a/include/trace/events/block.h b/include/trace/events/block.h index aba421d..78f18ad 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h @@ -31,7 +31,7 @@ DECLARE_EVENT_CLASS(block_rq_with_error, 0 : blk_rq_sectors(rq); __entry->errors = rq->errors; - blk_fill_rwbs_rq(__entry->rwbs, rq); + blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq)); blk_dump_cmd(__get_str(cmd), rq); ), @@ -118,7 +118,7 @@ DECLARE_EVENT_CLASS(block_rq, __entry->bytes = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? blk_rq_bytes(rq) : 0; - blk_fill_rwbs_rq(__entry->rwbs, rq); + blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq)); blk_dump_cmd(__get_str(cmd), rq); memcpy(__entry->comm, current->comm, TASK_COMM_LEN); ), @@ -563,7 +563,7 @@ TRACE_EVENT(block_rq_remap, __entry->nr_sector = blk_rq_sectors(rq); __entry->old_dev = dev; __entry->old_sector = from; - blk_fill_rwbs_rq(__entry->rwbs, rq); + blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq)); ), TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index d95721f..cbafed7 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -1827,21 +1827,5 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes) rwbs[i] = '\0'; } -void blk_fill_rwbs_rq(char *rwbs, struct request *rq) -{ - int rw = rq->cmd_flags & 0x03; - int bytes; - - if (rq->cmd_flags & REQ_DISCARD) - rw |= REQ_DISCARD; - - if (rq->cmd_flags & REQ_SECURE) - rw |= REQ_SECURE; - - bytes = blk_rq_bytes(rq); - - blk_fill_rwbs(rwbs, rw, bytes); -} - #endif /* CONFIG_EVENT_TRACING */ -- cgit v0.10.2 From fd51469fb68b987032e46297e0a4fe9020063c20 Mon Sep 17 00:00:00 2001 From: Petr Uzel Date: Thu, 3 Mar 2011 11:48:50 -0500 Subject: block: kill loop_mutex Following steps lead to deadlock in kernel: dd if=/dev/zero of=img bs=512 count=1000 losetup -f img mkfs.ext2 /dev/loop0 mount -t ext2 -o loop /dev/loop0 mnt umount mnt/ Stacktrace: [] irq_exit+0x36/0x59 [] smp_apic_timer_interrupt+0x6b/0x75 [] apic_timer_interrupt+0x31/0x38 [] mutex_spin_on_owner+0x54/0x5b [] lo_release+0x12/0x67 [loop] [] __blkdev_put+0x7c/0x10c [] fput+0xd5/0x1aa [] loop_clr_fd+0x1a9/0x1b1 [loop] [] lo_release+0x39/0x67 [loop] [] __blkdev_put+0x7c/0x10c [] deactivate_locked_super+0x17/0x36 [] sys_umount+0x27e/0x2a5 [] sys_oldumount+0xb/0xe [] sysenter_do_call+0x12/0x26 [] 0xffffffff Regression since 2a48fc0ab24241755dc9, which introduced the private loop_mutex as part of the BKL removal process. As per [1], the mutex can be safely removed. [1] http://www.gossamer-threads.com/lists/linux/kernel/1341930 Addresses: https://bugzilla.novell.com/show_bug.cgi?id=669394 Addresses: https://bugzilla.kernel.org/show_bug.cgi?id=29172 Signed-off-by: Petr Uzel Cc: stable@kernel.org Reviewed-by: Nikanth Karthikesan Acked-by: Arnd Bergmann Signed-off-by: Jens Axboe diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 49e6a54..dbf31ec 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -78,7 +78,6 @@ #include -static DEFINE_MUTEX(loop_mutex); static LIST_HEAD(loop_devices); static DEFINE_MUTEX(loop_devices_mutex); @@ -1501,11 +1500,9 @@ static int lo_open(struct block_device *bdev, fmode_t mode) { struct loop_device *lo = bdev->bd_disk->private_data; - mutex_lock(&loop_mutex); mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; mutex_unlock(&lo->lo_ctl_mutex); - mutex_unlock(&loop_mutex); return 0; } @@ -1515,7 +1512,6 @@ static int lo_release(struct gendisk *disk, fmode_t mode) struct loop_device *lo = disk->private_data; int err; - mutex_lock(&loop_mutex); mutex_lock(&lo->lo_ctl_mutex); if (--lo->lo_refcnt) @@ -1540,7 +1536,6 @@ static int lo_release(struct gendisk *disk, fmode_t mode) out: mutex_unlock(&lo->lo_ctl_mutex); out_unlocked: - mutex_unlock(&loop_mutex); return 0; } -- cgit v0.10.2 From 0c0db0355bc070b4c623622248d3f577642536b9 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 3 Mar 2011 17:56:05 +0100 Subject: [S390] xpram: remove __initdata attribute from module parameters The module parameter 'devs' and 'sizes' are marked as __initdata. The memory for the parameters are freed after module_init completed. This can lead to kernel crashes in param_free_charp. Remove the __initdata attribute to fix the problem. Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index c881a14..1f6a4d8 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -62,8 +62,8 @@ static int xpram_devs; /* * Parameter parsing functions. */ -static int __initdata devs = XPRAM_DEVS; -static char __initdata *sizes[XPRAM_MAX_DEVS]; +static int devs = XPRAM_DEVS; +static char *sizes[XPRAM_MAX_DEVS]; module_param(devs, int, 0); module_param_array(sizes, charp, NULL, 0); -- cgit v0.10.2 From b652277b09d3d030cb074cc6a98ba80b34244c03 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Mar 2011 17:56:06 +0100 Subject: [S390] keyboard: integer underflow bug The "ct" variable should be an unsigned int. Both struct kbdiacrs ->kb_cnt and struct kbd_data ->accent_table_size are unsigned ints. Making it signed causes a problem in KBDIACRUC because the user could set the signed bit and cause a buffer overflow. Cc: Signed-off-by: Dan Carpenter Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 8cd58e4..5ad44da 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -460,7 +460,8 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp; - int ct, perm; + unsigned int ct; + int perm; argp = (void __user *)arg; -- cgit v0.10.2 From 0c2bd9b24e73287aa4ee87844c847205e0da8a9b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 3 Mar 2011 17:56:07 +0100 Subject: [S390] tape: deadlock on system work queue The 34xx and 3590 tape driver uses the system work queue to defer work from the interrupt function to process context, e.g. a medium sense after an unsolicited interrupt. The tape commands started by the work handler need to be asynchronous, otherwise a deadlock on the system work queue can occur. Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 7a242f0..267b54e 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -280,6 +280,14 @@ tape_do_io_free(struct tape_device *device, struct tape_request *request) return rc; } +static inline void +tape_do_io_async_free(struct tape_device *device, struct tape_request *request) +{ + request->callback = (void *) tape_free_request; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + extern int tape_oper_handler(int irq, int status); extern void tape_noper_handler(int irq, int status); extern int tape_open(struct tape_device *); diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index c17f35b..c265111 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -53,23 +53,11 @@ static void tape_34xx_delete_sbid_from(struct tape_device *, int); * Medium sense for 34xx tapes. There is no 'real' medium sense call. * So we just do a normal sense. */ -static int -tape_34xx_medium_sense(struct tape_device *device) +static void __tape_34xx_medium_sense(struct tape_request *request) { - struct tape_request *request; - unsigned char *sense; - int rc; - - request = tape_alloc_request(1, 32); - if (IS_ERR(request)) { - DBF_EXCEPTION(6, "MSEN fail\n"); - return PTR_ERR(request); - } - - request->op = TO_MSEN; - tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + struct tape_device *device = request->device; + unsigned char *sense; - rc = tape_do_io_interruptible(device, request); if (request->rc == 0) { sense = request->cpdata; @@ -88,15 +76,47 @@ tape_34xx_medium_sense(struct tape_device *device) device->tape_generic_status |= GMT_WR_PROT(~0); else device->tape_generic_status &= ~GMT_WR_PROT(~0); - } else { + } else DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n", request->rc); - } tape_free_request(request); +} + +static int tape_34xx_medium_sense(struct tape_device *device) +{ + struct tape_request *request; + int rc; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return PTR_ERR(request); + } + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + rc = tape_do_io_interruptible(device, request); + __tape_34xx_medium_sense(request); return rc; } +static void tape_34xx_medium_sense_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return; + } + + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + request->callback = (void *) __tape_34xx_medium_sense; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + struct tape_34xx_work { struct tape_device *device; enum tape_op op; @@ -109,6 +129,9 @@ struct tape_34xx_work { * is inserted but cannot call tape_do_io* from an interrupt context. * Maybe that's useful for other actions we want to start from the * interrupt handler. + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ static void tape_34xx_work_handler(struct work_struct *work) @@ -119,7 +142,7 @@ tape_34xx_work_handler(struct work_struct *work) switch(p->op) { case TO_MSEN: - tape_34xx_medium_sense(device); + tape_34xx_medium_sense_async(device); break; default: DBF_EVENT(3, "T34XX: internal error: unknown work\n"); diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index fbe361f..de2e99e 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -329,17 +329,17 @@ out: /* * Enable encryption */ -static int tape_3592_enable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_enable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -354,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device) request->op = TO_CRYPT_ON; tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_enable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_enable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * Disable encryption */ -static int tape_3592_disable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_disable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -383,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device) tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_disable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_disable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * IOCTL: Set encryption status */ @@ -457,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg) /* * SENSE Medium: Get Sense data about medium state */ -static int -tape_3590_sense_medium(struct tape_device *device) +static int tape_3590_sense_medium(struct tape_device *device) { struct tape_request *request; @@ -470,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device) return tape_do_io_free(device, request); } +static void tape_3590_sense_medium_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 128); + if (IS_ERR(request)) + return; + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata); + tape_do_io_async_free(device, request); +} + /* * MTTELL: Tell block. Return the number of block relative to current file. */ @@ -546,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device, * 2. The attention msg is written to the "read subsystem data" buffer. * In this case we probably should print it to the console. */ -static int -tape_3590_read_attmsg(struct tape_device *device) +static void tape_3590_read_attmsg_async(struct tape_device *device) { struct tape_request *request; char *buf; request = tape_alloc_request(3, 4096); if (IS_ERR(request)) - return PTR_ERR(request); + return; request->op = TO_READ_ATTMSG; buf = request->cpdata; buf[0] = PREP_RD_SS_DATA; @@ -562,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device) tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); - return tape_do_io_free(device, request); + tape_do_io_async_free(device, request); } /* * These functions are used to schedule follow-up actions from within an * interrupt context (like unsolicited interrupts). + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ struct work_handler_data { struct tape_device *device; @@ -583,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work) switch (p->op) { case TO_MSEN: - tape_3590_sense_medium(p->device); + tape_3590_sense_medium_async(p->device); break; case TO_READ_ATTMSG: - tape_3590_read_attmsg(p->device); + tape_3590_read_attmsg_async(p->device); break; case TO_CRYPT_ON: - tape_3592_enable_crypt(p->device); + tape_3592_enable_crypt_async(p->device); break; case TO_CRYPT_OFF: - tape_3592_disable_crypt(p->device); + tape_3592_disable_crypt_async(p->device); break; default: DBF_EVENT(3, "T3590: work handler undefined for " -- cgit v0.10.2 From 9bde178d052418af0b8e0f12932cf02ab4764c9d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 28 Feb 2011 09:47:37 -0800 Subject: Revert "ceph: keep reference to parent inode on ceph_dentry" This reverts commit 97d79b403ef03f729883246208ef5d8a2ebc4d68. This fails to account for d_parent changes due to rename or disconnected dentries due to submounts or NFS reexports. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index f0aef78..0bc68de 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -60,7 +60,6 @@ int ceph_init_dentry(struct dentry *dentry) } di->dentry = dentry; di->lease_session = NULL; - di->parent_inode = igrab(dentry->d_parent->d_inode); dentry->d_fsdata = di; dentry->d_time = jiffies; ceph_dentry_lru_add(dentry); @@ -1034,7 +1033,7 @@ static void ceph_dentry_release(struct dentry *dentry) u64 snapid = CEPH_NOSNAP; if (!IS_ROOT(dentry)) { - parent_inode = di->parent_inode; + parent_inode = dentry->d_parent->d_inode; if (parent_inode) snapid = ceph_snap(parent_inode); } @@ -1059,8 +1058,6 @@ static void ceph_dentry_release(struct dentry *dentry) kmem_cache_free(ceph_dentry_cachep, di); dentry->d_fsdata = NULL; } - if (parent_inode) - iput(parent_inode); } static int ceph_snapdir_d_revalidate(struct dentry *dentry, diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 88fcaa2..20b907d 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -207,7 +207,6 @@ struct ceph_dentry_info { struct dentry *dentry; u64 time; u64 offset; - struct inode *parent_inode; }; struct ceph_inode_xattrs_info { -- cgit v0.10.2 From b545cc1505eb49247071ce9f4092665de788ca00 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 28 Feb 2011 12:46:46 -0800 Subject: ceph: do not set I_COMPLETE Do not set the I_COMPLETE flag on directories until we resolve races with dcache pruning. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 0bc68de..9b4f9d9 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -409,7 +409,7 @@ more: spin_lock(&inode->i_lock); if (ci->i_release_count == fi->dir_release_count) { dout(" marking %p complete\n", inode); - ci->i_ceph_flags |= CEPH_I_COMPLETE; + /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */ ci->i_max_offset = filp->f_pos; } spin_unlock(&inode->i_lock); diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 5625463..193bfa5 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -707,7 +707,7 @@ static int fill_inode(struct inode *inode, (issued & CEPH_CAP_FILE_EXCL) == 0 && (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) { dout(" marking %p complete (empty)\n", inode); - ci->i_ceph_flags |= CEPH_I_COMPLETE; + /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */ ci->i_max_offset = 2; } break; -- cgit v0.10.2 From 16a8b70a5a757db513f036bbcc73309f6c507d81 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 28 Feb 2011 12:49:15 -0800 Subject: ceph: do not clear I_COMPLETE from d_release First, this was racy anyway: d_release isn't called until well after the dentry is unhashed. Second, this runs afoul of the recent dcache change that clears d_parent prior to calling d_release (949854d0), causing a NULL pointer dereference. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 9b4f9d9..196fd4c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1029,28 +1029,8 @@ out_touch: static void ceph_dentry_release(struct dentry *dentry) { struct ceph_dentry_info *di = ceph_dentry(dentry); - struct inode *parent_inode = NULL; - u64 snapid = CEPH_NOSNAP; - if (!IS_ROOT(dentry)) { - parent_inode = dentry->d_parent->d_inode; - if (parent_inode) - snapid = ceph_snap(parent_inode); - } - dout("dentry_release %p parent %p\n", dentry, parent_inode); - if (parent_inode && snapid != CEPH_SNAPDIR) { - struct ceph_inode_info *ci = ceph_inode(parent_inode); - - spin_lock(&parent_inode->i_lock); - if (ci->i_shared_gen == di->lease_shared_gen || - snapid <= CEPH_MAXSNAP) { - dout(" clearing %p complete (d_release)\n", - parent_inode); - ci->i_ceph_flags &= ~CEPH_I_COMPLETE; - ci->i_release_count++; - } - spin_unlock(&parent_inode->i_lock); - } + dout("dentry_release %p\n", dentry); if (di) { ceph_dentry_lru_del(dentry); if (di->lease_session) -- cgit v0.10.2 From 525a11381bcad9a7f55d0bac9c8676fe71819002 Mon Sep 17 00:00:00 2001 From: Hari Kanigeri Date: Wed, 2 Mar 2011 22:14:18 +0000 Subject: omap: mailbox: resolve hang issue omap4 interrupt disable bits is different. On rx kfifo full, the mbox rx interrupts wasn't getting disabled, and this is causing the rcm stress tests to hang. Signed-off-by: Hari Kanigeri Signed-off-by: Armando Uribe Signed-off-by: Fernando Guzman Lugo Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 0a585df..24b8850 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -193,10 +193,12 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) { struct omap_mbox2_priv *p = mbox->priv; - u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - l = mbox_read_reg(p->irqdisable); - l &= ~bit; - mbox_write_reg(l, p->irqdisable); + u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; + + if (!cpu_is_omap44xx()) + bit = mbox_read_reg(p->irqdisable) & ~bit; + + mbox_write_reg(bit, p->irqdisable); } static void omap2_mbox_ack_irq(struct omap_mbox *mbox, -- cgit v0.10.2 From ba04c7c93bbcb48ce880cf75b6e9dffcd79d4c7b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 22 Feb 2011 02:00:11 +0000 Subject: r8169: disable ASPM For some time is known that ASPM is causing troubles on r8169, i.e. make device randomly stop working without any errors in dmesg. Currently Tomi Leppikangas reports that system with r8169 device hangs with MCE errors when ASPM is enabled: https://bugzilla.redhat.com/show_bug.cgi?id=642861#c4 Lets disable ASPM for r8169 devices at all, to avoid problems with r8169 PCIe devices at least for some users. Reported-by: Tomi Leppikangas Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ef2133b..7ffdb80 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -3020,6 +3021,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) mii->reg_num_mask = 0x1f; mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); + /* disable ASPM completely as that cause random device stop working + * problems as well as full system hangs for some PCIe devices users */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + /* enable device (incl. PCI PM wakeup and hotplug setup) */ rc = pci_enable_device(pdev); if (rc < 0) { -- cgit v0.10.2 From 4cd72c6e72e8a36a975decb53d70086008f386db Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 3 Mar 2011 10:43:10 +0000 Subject: MAINTAINERS: Add Andy Gospodarek as co-maintainer. Acked-by: Andy Gospodarek Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 1752436..a9784a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1467,6 +1467,7 @@ F: include/net/bluetooth/ BONDING DRIVER M: Jay Vosburgh +M: Andy Gospodarek L: netdev@vger.kernel.org W: http://sourceforge.net/projects/bonding/ S: Supported -- cgit v0.10.2 From 38815b780285a4957852c5c9dbe94991c0b26c56 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 2 Mar 2011 16:55:21 -0800 Subject: libceph: fix handling of short returns from get_user_pages get_user_pages() can return fewer pages than we ask for. We were returning a bogus pointer/error code in that case. Instead, loop until we get all the pages we want or get an error we can return to the caller. Signed-off-by: Sage Weil diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index 1a040e6..cd9c21d 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c @@ -16,22 +16,30 @@ struct page **ceph_get_direct_page_vector(const char __user *data, int num_pages, bool write_page) { struct page **pages; - int rc; + int got = 0; + int rc = 0; pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS); if (!pages) return ERR_PTR(-ENOMEM); down_read(¤t->mm->mmap_sem); - rc = get_user_pages(current, current->mm, (unsigned long)data, - num_pages, write_page, 0, pages, NULL); + while (got < num_pages) { + rc = get_user_pages(current, current->mm, + (unsigned long)data + ((unsigned long)got * PAGE_SIZE), + num_pages - got, write_page, 0, pages + got, NULL); + if (rc < 0) + break; + BUG_ON(rc == 0); + got += rc; + } up_read(¤t->mm->mmap_sem); - if (rc < num_pages) + if (rc < 0) goto fail; return pages; fail: - ceph_put_page_vector(pages, rc > 0 ? rc : 0, false); + ceph_put_page_vector(pages, got, false); return ERR_PTR(rc); } EXPORT_SYMBOL(ceph_get_direct_page_vector); -- cgit v0.10.2 From 692d20f576fb26f62c83f80dbf3ea899998391b7 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 3 Mar 2011 12:14:53 -0800 Subject: libceph: retry after authorization failure If we mark the connection CLOSED we will give up trying to reconnect to this server instance. That is appropriate for things like a protocol version mismatch that won't change until the server is restarted, at which point we'll get a new addr and reconnect. An authorization failure like this is probably due to the server not properly rotating it's secret keys, however, and should be treated as transient so that the normal backoff and retry behavior kicks in. Signed-off-by: Sage Weil diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 35b36b8..6bd5025 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1248,8 +1248,6 @@ static int process_connect(struct ceph_connection *con) con->auth_retry); if (con->auth_retry == 2) { con->error_msg = "connect authorization failure"; - reset_connection(con); - set_bit(CLOSED, &con->state); return -1; } con->auth_retry = 1; -- cgit v0.10.2 From 1362fa078dae16776cd439791c6605b224ea6171 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 Mar 2011 11:28:58 +0000 Subject: DNS: Fix a NULL pointer deref when trying to read an error key [CVE-2011-1076] When a DNS resolver key is instantiated with an error indication, attempts to read that key will result in an oops because user_read() is expecting there to be a payload - and there isn't one [CVE-2011-1076]. Give the DNS resolver key its own read handler that returns the error cached in key->type_data.x[0] as an error rather than crashing. Also make the kenter() at the beginning of dns_resolver_instantiate() limit the amount of data it prints, since the data is not necessarily NUL-terminated. The buggy code was added in: commit 4a2d789267e00b5a1175ecd2ddefcc78b83fbf09 Author: Wang Lei Date: Wed Aug 11 09:37:58 2010 +0100 Subject: DNS: If the DNS server returns an error, allow that to be cached [ver #2] This can trivially be reproduced by any user with the following program compiled with -lkeyutils: #include #include #include static char payload[] = "#dnserror=6"; int main() { key_serial_t key; key = add_key("dns_resolver", "a", payload, sizeof(payload), KEY_SPEC_SESSION_KEYRING); if (key == -1) err(1, "add_key"); if (keyctl_read(key, NULL, 0) == -1) err(1, "read_key"); return 0; } What should happen is that keyctl_read() reports error 6 (ENXIO) to the user: dns-break: read_key: No such device or address but instead the kernel oopses. This cannot be reproduced with the 'keyutils add' or 'keyutils padd' commands as both of those cut the data down below the NUL termination that must be included in the data. Without this dns_resolver_instantiate() will return -EINVAL and the key will not be instantiated such that it can be read. The oops looks like: BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 IP: [] user_read+0x4f/0x8f PGD 3bdf8067 PUD 385b9067 PMD 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/pci0000:00/0000:00:19.0/irq CPU 0 Modules linked in: Pid: 2150, comm: dns-break Not tainted 2.6.38-rc7-cachefs+ #468 /DG965RY RIP: 0010:[] [] user_read+0x4f/0x8f RSP: 0018:ffff88003bf47f08 EFLAGS: 00010246 RAX: 0000000000000001 RBX: ffff88003b5ea378 RCX: ffffffff81972368 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88003b5ea378 RBP: ffff88003bf47f28 R08: ffff88003be56620 R09: 0000000000000000 R10: 0000000000000395 R11: 0000000000000002 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: ffffffffffffffa1 FS: 00007feab5751700(0000) GS:ffff88003e000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000010 CR3: 000000003de40000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process dns-break (pid: 2150, threadinfo ffff88003bf46000, task ffff88003be56090) Stack: ffff88003b5ea378 ffff88003b5ea3a0 0000000000000000 0000000000000000 ffff88003bf47f68 ffffffff811b708e ffff88003c442bc8 0000000000000000 00000000004005a0 00007fffba368060 0000000000000000 0000000000000000 Call Trace: [] keyctl_read_key+0xac/0xcf [] sys_keyctl+0x75/0xb6 [] system_call_fastpath+0x16/0x1b Code: 75 1f 48 83 7b 28 00 75 18 c6 05 58 2b fb 00 01 be bb 00 00 00 48 c7 c7 76 1c 75 81 e8 13 c2 e9 ff 4c 8b b3 e0 00 00 00 4d 85 ed <41> 0f b7 5e 10 74 2d 4d 85 e4 74 28 e8 98 79 ee ff 49 39 dd 48 RIP [] user_read+0x4f/0x8f RSP CR2: 0000000000000010 Signed-off-by: David Howells Acked-by: Jeff Layton cc: Wang Lei Signed-off-by: James Morris diff --git a/Documentation/networking/dns_resolver.txt b/Documentation/networking/dns_resolver.txt index aefd1e6..04ca0632 100644 --- a/Documentation/networking/dns_resolver.txt +++ b/Documentation/networking/dns_resolver.txt @@ -61,7 +61,6 @@ before the more general line given above as the first match is the one taken. create dns_resolver foo:* * /usr/sbin/dns.foo %k - ===== USAGE ===== @@ -104,6 +103,14 @@ implemented in the module can be called after doing: returned also. +=============================== +READING DNS KEYS FROM USERSPACE +=============================== + +Keys of dns_resolver type can be read from userspace using keyctl_read() or +"keyctl read/print/pipe". + + ========= MECHANISM ========= diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index 739435a..cfa7a5e 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c @@ -67,8 +67,9 @@ dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen) size_t result_len = 0; const char *data = _data, *end, *opt; - kenter("%%%d,%s,'%s',%zu", - key->serial, key->description, data, datalen); + kenter("%%%d,%s,'%*.*s',%zu", + key->serial, key->description, + (int)datalen, (int)datalen, data, datalen); if (datalen <= 1 || !data || data[datalen - 1] != '\0') return -EINVAL; @@ -217,6 +218,19 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m) seq_printf(m, ": %u", key->datalen); } +/* + * read the DNS data + * - the key's semaphore is read-locked + */ +static long dns_resolver_read(const struct key *key, + char __user *buffer, size_t buflen) +{ + if (key->type_data.x[0]) + return key->type_data.x[0]; + + return user_read(key, buffer, buflen); +} + struct key_type key_type_dns_resolver = { .name = "dns_resolver", .instantiate = dns_resolver_instantiate, @@ -224,7 +238,7 @@ struct key_type key_type_dns_resolver = { .revoke = user_revoke, .destroy = user_destroy, .describe = dns_resolver_describe, - .read = user_read, + .read = dns_resolver_read, }; static int __init init_dns_resolver(void) -- cgit v0.10.2 From 73412c3854c877e5f37ad944ee8977addde4d35a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Mar 2011 09:58:36 +1000 Subject: drm/nouveau: allocate kernel's notifier object at end of block The nv30/nv40 3d driver is about to start using DMA_FENCE from the 3D object which, it turns out, doesn't like its DMA object to not be aligned to a 4KiB boundary. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 65699bf..b368ed7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -83,7 +83,8 @@ nouveau_dma_init(struct nouveau_channel *chan) return ret; /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ - ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); + ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, + &chan->m2mf_ntfy); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9821fca..982d70b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -852,7 +852,8 @@ extern const struct ttm_mem_type_manager_func nouveau_vram_manager; extern int nouveau_notifier_init_channel(struct nouveau_channel *); extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, - int cout, uint32_t *offset); + int cout, uint32_t start, uint32_t end, + uint32_t *offset); extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *); extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, struct drm_file *); diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index fe29d60..5ea1676 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -96,7 +96,8 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, int nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int size, uint32_t *b_offset) + int size, uint32_t start, uint32_t end, + uint32_t *b_offset) { struct drm_device *dev = chan->dev; struct nouveau_gpuobj *nobj = NULL; @@ -104,9 +105,10 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, uint32_t offset; int target, ret; - mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); + mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0, + start, end, 0); if (mem) - mem = drm_mm_get_block(mem, size, 0); + mem = drm_mm_get_block_range(mem, size, 0, start, end); if (!mem) { NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); return -ENOMEM; @@ -177,7 +179,8 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, if (IS_ERR(chan)) return PTR_ERR(chan); - ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); + ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, + &na->offset); nouveau_channel_put(&chan); return ret; } -- cgit v0.10.2 From f60cb470eab2f06e0facb8d86a769e9c0a220e28 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 2 Mar 2011 09:05:44 +0000 Subject: ARM: mach-shmobile: ap4evb: modify LCDC clock divider value ap4evb WVGA LCDC panel expect 33.3MHz for dot-clock, but current dot-clock was 50.0MHz. This patch modify clock divider value. Signed-off-by: Makoto Ueda Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 3cf0951..81d6536 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -1303,7 +1303,7 @@ static void __init ap4evb_init(void) lcdc_info.clock_source = LCDC_CLK_BUS; lcdc_info.ch[0].interface_type = RGB18; - lcdc_info.ch[0].clock_divider = 2; + lcdc_info.ch[0].clock_divider = 3; lcdc_info.ch[0].flags = 0; lcdc_info.ch[0].lcd_size_cfg.width = 152; lcdc_info.ch[0].lcd_size_cfg.height = 91; -- cgit v0.10.2 From 2c34e939f9e98bb678a2b0d35e7a318bf2947024 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 2 Mar 2011 09:05:21 +0000 Subject: ARM: mach-shmobile: mackerel: modify LCDC clock divider value mackerel WVGA LCDC panel expect 33.3MHz for dot-clock, but current dot-clock was 50.0MHz. This patch modify clock divider value. Signed-off-by: Makoto Ueda Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index fb4213a..1657eac 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -303,7 +303,7 @@ static struct sh_mobile_lcdc_info lcdc_info = { .lcd_cfg = mackerel_lcdc_modes, .num_cfg = ARRAY_SIZE(mackerel_lcdc_modes), .interface_type = RGB24, - .clock_divider = 2, + .clock_divider = 3, .flags = 0, .lcd_size_cfg.width = 152, .lcd_size_cfg.height = 91, -- cgit v0.10.2 From bb7b11290afd2a192d33c357a2a62cb8eaf29eab Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 26 Jan 2011 18:10:44 +0000 Subject: Blackfin: outs[lwb]: make sure count is greater than 0 Some devices will use the outs* funcs with a length of zero, so make sure we do not write any data in that case. Reported-by: Gilbert Inho Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S index 250f4d4..06a5e67 100644 --- a/arch/blackfin/lib/outs.S +++ b/arch/blackfin/lib/outs.S @@ -13,6 +13,8 @@ .align 2 ENTRY(_outsl) + CC = R2 == 0; + IF CC JUMP 1f; P0 = R0; /* P0 = port */ P1 = R1; /* P1 = address */ P2 = R2; /* P2 = count */ @@ -20,10 +22,12 @@ ENTRY(_outsl) LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; .Llong_loop_s: R0 = [P1++]; .Llong_loop_e: [P0] = R0; - RTS; +1: RTS; ENDPROC(_outsl) ENTRY(_outsw) + CC = R2 == 0; + IF CC JUMP 1f; P0 = R0; /* P0 = port */ P1 = R1; /* P1 = address */ P2 = R2; /* P2 = count */ @@ -31,10 +35,12 @@ ENTRY(_outsw) LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; .Lword_loop_s: R0 = W[P1++]; .Lword_loop_e: W[P0] = R0; - RTS; +1: RTS; ENDPROC(_outsw) ENTRY(_outsb) + CC = R2 == 0; + IF CC JUMP 1f; P0 = R0; /* P0 = port */ P1 = R1; /* P1 = address */ P2 = R2; /* P2 = count */ @@ -42,10 +48,12 @@ ENTRY(_outsb) LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; .Lbyte_loop_s: R0 = B[P1++]; .Lbyte_loop_e: B[P0] = R0; - RTS; +1: RTS; ENDPROC(_outsb) ENTRY(_outsw_8) + CC = R2 == 0; + IF CC JUMP 1f; P0 = R0; /* P0 = port */ P1 = R1; /* P1 = address */ P2 = R2; /* P2 = count */ @@ -56,5 +64,5 @@ ENTRY(_outsw_8) R0 = R0 << 8; R0 = R0 + R1; .Lword8_loop_e: W[P0] = R0; - RTS; +1: RTS; ENDPROC(_outsw_8) -- cgit v0.10.2 From be1229b4c52202033ba857e96e592777f08e8046 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 2 Feb 2011 01:55:22 +0000 Subject: Blackfin: iflush: update anomaly 05000491 workaround Recent feedback from design says we need three NOPs in the hardware loop. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S index 790c767..ab4a925 100644 --- a/arch/blackfin/mach-common/cache.S +++ b/arch/blackfin/mach-common/cache.S @@ -58,6 +58,8 @@ 1: .ifeqs "\flushins", BROK_FLUSH_INST \flushins [P0++]; + nop; + nop; 2: nop; .else 2: \flushins [P0++]; -- cgit v0.10.2 From 8c00ae98d12613bf283543da200c4ab311362c35 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 28 Feb 2011 15:03:46 +0900 Subject: ARM: S3C2440: Select missing S3C_DEV_USB_HOST on GTA02 The gta02 mach file references the ohci device. So we need to select S3C_DEV_USB_HOST to have the device available. This fixes the following linker errors: arch/arm/mach-s3c2440/built-in.o: In function 'gta02_machine_init': mach-gta02.c:(.init.text+0x370): undefined reference to 's3c_ohci_set_platdata' arch/arm/mach-s3c2440/built-in.o:(.init.data+0xac): undefined reference to 's3c_device_ohci' Signed-off-by: Lars-Peter Clausen Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index a0cb258..50825a3 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -99,6 +99,7 @@ config MACH_NEO1973_GTA02 select POWER_SUPPLY select MACH_NEO1973 select S3C2410_PWM + select S3C_DEV_USB_HOST help Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone -- cgit v0.10.2 From f33f314961575d00ca397cf08889e973c85a1fd3 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Mon, 28 Feb 2011 16:53:36 +0900 Subject: ARM: S5P64X0: Fix number of GPIO lines in Bank F This patch modifies the number of total GPIO lines for Bank F for Samsung S5P6440 and S5P6450 SoCs from 2 to 16. This is necessary as the GPIO lines from 0 to 13 are reserved and only lines 14 and 15 are used. As during initialization, the line number starts at 0, putting 2 does not solve the intended purpose. Signed-off-by: Banajit Goswami Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5p64x0/include/mach/gpio.h b/arch/arm/mach-s5p64x0/include/mach/gpio.h index 5486c8f..adb5f29 100644 --- a/arch/arm/mach-s5p64x0/include/mach/gpio.h +++ b/arch/arm/mach-s5p64x0/include/mach/gpio.h @@ -23,7 +23,7 @@ #define S5P6440_GPIO_A_NR (6) #define S5P6440_GPIO_B_NR (7) #define S5P6440_GPIO_C_NR (8) -#define S5P6440_GPIO_F_NR (2) +#define S5P6440_GPIO_F_NR (16) #define S5P6440_GPIO_G_NR (7) #define S5P6440_GPIO_H_NR (10) #define S5P6440_GPIO_I_NR (16) @@ -36,7 +36,7 @@ #define S5P6450_GPIO_B_NR (7) #define S5P6450_GPIO_C_NR (8) #define S5P6450_GPIO_D_NR (8) -#define S5P6450_GPIO_F_NR (2) +#define S5P6450_GPIO_F_NR (16) #define S5P6450_GPIO_G_NR (14) #define S5P6450_GPIO_H_NR (10) #define S5P6450_GPIO_I_NR (16) -- cgit v0.10.2 From 6a53048dde1c85fe03b197352d637e1e4a7380fb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 28 Feb 2011 20:20:53 +0900 Subject: ARM: S3C2440: Fix usage gpio bank j pin definitions on GTA02 The gta02 header file still uses the old S3C2410_GPJx defines instead of the S3C2410_GPJ(x) macro. Since the S3C2410_GPJx defines have already been removed this causes the following build failure: sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_set_spk': sound/soc/samsung/neo1973_wm8753.c:259: error: 'S3C2440_GPJ2' undeclared (first use in this function) sound/soc/samsung/neo1973_wm8753.c:259: error: (Each undeclared identifier is reported only once sound/soc/samsung/neo1973_wm8753.c:259: error: for each function it appears in.) sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_get_spk': sound/soc/samsung/neo1973_wm8753.c:267: error: 'S3C2440_GPJ2' undeclared (first use in this function) sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_event': sound/soc/samsung/neo1973_wm8753.c:276: error: 'S3C2440_GPJ1' undeclared (first use in this function) sound/soc/samsung/neo1973_wm8753.c: At top level: sound/soc/samsung/neo1973_wm8753.c:439: error: 'S3C2440_GPJ2' undeclared here (not in a function) sound/soc/samsung/neo1973_wm8753.c:440: error: 'S3C2440_GPJ1' undeclared here (not in a function) This patches fixes the issue by doing a s,S3C2410_GPJ([\d]+),S3C2410_GPJ(\1),g on the file. Signed-off-by: Lars-Peter Clausen Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-s3c2440/include/mach/gta02.h index 953331d..3a56a22 100644 --- a/arch/arm/mach-s3c2440/include/mach/gta02.h +++ b/arch/arm/mach-s3c2440/include/mach/gta02.h @@ -44,19 +44,19 @@ #define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG(10) /* v3 + v4 only */ #define GTA02v3_GPIO_nGSM_OC S3C2410_GPG(11) /* v3 + v4 only */ -#define GTA02_GPIO_AMP_SHUT S3C2440_GPJ1 /* v2 + v3 + v4 only */ -#define GTA02v1_GPIO_WLAN_GPIO10 S3C2440_GPJ2 -#define GTA02_GPIO_HP_IN S3C2440_GPJ2 /* v2 + v3 + v4 only */ -#define GTA02_GPIO_INT0 S3C2440_GPJ3 /* v2 + v3 + v4 only */ -#define GTA02_GPIO_nGSM_EN S3C2440_GPJ4 -#define GTA02_GPIO_3D_RESET S3C2440_GPJ5 -#define GTA02_GPIO_nDL_GSM S3C2440_GPJ6 /* v4 + v5 only */ -#define GTA02_GPIO_WLAN_GPIO0 S3C2440_GPJ7 -#define GTA02v1_GPIO_BAT_ID S3C2440_GPJ8 -#define GTA02_GPIO_KEEPACT S3C2440_GPJ8 -#define GTA02v1_GPIO_HP_IN S3C2440_GPJ10 -#define GTA02_CHIP_PWD S3C2440_GPJ11 /* v2 + v3 + v4 only */ -#define GTA02_GPIO_nWLAN_RESET S3C2440_GPJ12 /* v2 + v3 + v4 only */ +#define GTA02_GPIO_AMP_SHUT S3C2410_GPJ(1) /* v2 + v3 + v4 only */ +#define GTA02v1_GPIO_WLAN_GPIO10 S3C2410_GPJ(2) +#define GTA02_GPIO_HP_IN S3C2410_GPJ(2) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_INT0 S3C2410_GPJ(3) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_nGSM_EN S3C2410_GPJ(4) +#define GTA02_GPIO_3D_RESET S3C2410_GPJ(5) +#define GTA02_GPIO_nDL_GSM S3C2410_GPJ(6) /* v4 + v5 only */ +#define GTA02_GPIO_WLAN_GPIO0 S3C2410_GPJ(7) +#define GTA02v1_GPIO_BAT_ID S3C2410_GPJ(8) +#define GTA02_GPIO_KEEPACT S3C2410_GPJ(8) +#define GTA02v1_GPIO_HP_IN S3C2410_GPJ(10) +#define GTA02_CHIP_PWD S3C2410_GPJ(11) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_nWLAN_RESET S3C2410_GPJ(12) /* v2 + v3 + v4 only */ #define GTA02_IRQ_GSENSOR_1 IRQ_EINT0 #define GTA02_IRQ_MODEM IRQ_EINT1 -- cgit v0.10.2 From b3f639c4fe54ce750debe343acbd237f3a75e07c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 2 Mar 2011 15:19:15 +0900 Subject: ARM: S3C64XX: Fix keypad setup to configure correct number of rows The call to s3c_gpio_cfgrange_nopull() takes a size and base but this looks like it is trying to do base and end. This means it is configuring too many GPIOs and on the case of the Cragganmore means we're seeing an overflow of the ROW pins causing problems with the keyboard driver. Signed-off-by: Ben Dooks Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c index f8ed0d2..1d4d0ee 100644 --- a/arch/arm/mach-s3c64xx/setup-keypad.c +++ b/arch/arm/mach-s3c64xx/setup-keypad.c @@ -17,7 +17,7 @@ void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) { /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */ - s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3)); + s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), rows, S3C_GPIO_SFN(3)); /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */ s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3)); -- cgit v0.10.2 From 13c608d244600be1d324067dff1a1a1192fc0730 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Mar 2011 07:55:44 +0900 Subject: ARM: SAMSUNG: Include devs.h in dev-uart.c to prototype devices Ensures that the declaration agrees with the definition and makes sparse happy. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c index 3776cd9..5928105 100644 --- a/arch/arm/plat-samsung/dev-uart.c +++ b/arch/arm/plat-samsung/dev-uart.c @@ -15,6 +15,8 @@ #include #include +#include + /* uart devices */ static struct platform_device s3c24xx_uart_device0 = { -- cgit v0.10.2 From 82e985eb69c61f1d4f609fbc29a26b35e869b17b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Mar 2011 07:55:44 +0900 Subject: ARM: S3C64XX: Staticise non-exported GPIO to interrupt functions No need to put these in the global namespace and sparse gets upset. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c index fd99a82..92b0908 100644 --- a/arch/arm/mach-s3c64xx/gpiolib.c +++ b/arch/arm/mach-s3c64xx/gpiolib.c @@ -72,7 +72,7 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = { .get_pull = s3c_gpio_getpull_updown, }; -int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin) +static int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin) { return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO; } @@ -138,7 +138,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }; -int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin) +static int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin) { return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO; } -- cgit v0.10.2 From 400b11a784b0202307b8596b0c393ca9966fd8b4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 4 Mar 2011 07:55:44 +0900 Subject: ARM: S3C64XX: Add clock for i2c1 The clock for i2c1 has been missing for a while, add it to the list of clocks for the system and ensure it is initialised at startup. Signed-off-by: Ben Dooks Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index dd37820..fdfc4d5 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -151,6 +151,12 @@ static struct clk init_clocks_off[] = { .enable = s3c64xx_pclk_ctrl, .ctrlbit = S3C_CLKCON_PCLK_IIC, }, { + .name = "i2c", + .id = 1, + .parent = &clk_p, + .enable = s3c64xx_pclk_ctrl, + .ctrlbit = S3C6410_CLKCON_PCLK_I2C1, + }, { .name = "iis", .id = 0, .parent = &clk_p, -- cgit v0.10.2 From ac1e10bed11c1ad1a2488e896022491a1167b9ff Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Mar 2011 07:55:44 +0900 Subject: ARM: S3C64XX: Tone down SDHCI debugging The MMC core calls s3c6400_setup_sdhcp_cfg_card() very frequently, causing the log message in there at KERN_INFO to be displayed a lot which is slow and overly chatty. Convert the message into a pr_debug() to tone this down. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/setup-sdhci.c b/arch/arm/mach-s3c64xx/setup-sdhci.c index 1a94203..f344a22 100644 --- a/arch/arm/mach-s3c64xx/setup-sdhci.c +++ b/arch/arm/mach-s3c64xx/setup-sdhci.c @@ -56,7 +56,7 @@ void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev, else ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0); - printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3); + pr_debug("%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3); writel(ctrl2, r + S3C_SDHCI_CONTROL2); writel(ctrl3, r + S3C_SDHCI_CONTROL3); } -- cgit v0.10.2 From 00252830322c1e213acd05f8bc21aaac8df07b9e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 4 Mar 2011 07:55:44 +0900 Subject: ARM: S3C64XX: Reduce output of s3c64xx_dma_init1() Reduce the logging output of s3c64xx_dma_init1() as it is not useful for normal bootup (and we get an overall indication of the registration of the PL180 DMA block). This removes the following output from the log: s3c64xx_dma_init1: registering DMA 0 (e0808100) s3c64xx_dma_init1: registering DMA 1 (e0808120) s3c64xx_dma_init1: registering DMA 2 (e0808140) s3c64xx_dma_init1: registering DMA 3 (e0808160) s3c64xx_dma_init1: registering DMA 4 (e0808180) s3c64xx_dma_init1: registering DMA 5 (e08081a0) s3c64xx_dma_init1: registering DMA 6 (e08081c0) s3c64xx_dma_init1: registering DMA 7 (e08081e0) Signed-off-by: Ben Dooks Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 135db1b..c35585c 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -690,12 +690,12 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, regptr = regs + PL080_Cx_BASE(0); - for (ch = 0; ch < 8; ch++, chno++, chptr++) { - printk(KERN_INFO "%s: registering DMA %d (%p)\n", - __func__, chno, regptr); + for (ch = 0; ch < 8; ch++, chptr++) { + pr_debug("%s: registering DMA %d (%p)\n", + __func__, chno + ch, regptr); chptr->bit = 1 << ch; - chptr->number = chno; + chptr->number = chno + ch; chptr->dmac = dmac; chptr->regs = regptr; regptr += PL080_Cx_STRIDE; @@ -704,7 +704,8 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, /* for the moment, permanently enable the controller */ writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG); - printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs); + printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n", + irq, regs, chno, chno+8); return 0; -- cgit v0.10.2 From 628e7eb5a74b4ea78db97609a8dcbdf41b4b0b90 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Mar 2011 07:59:20 +0900 Subject: ARM: S3C64XX: Fix build with WM1190 disabled and WM1192 enabled on SMDK6410 Avoid relying on implicit inclusion of machine.h Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index e85192a..a74f2c9 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef CONFIG_SMDK6410_WM1190_EV1 #include -- cgit v0.10.2 From 18b52ca5d0ea7f7d1933ebe8d277a1b499c940f2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Mar 2011 08:24:15 +0900 Subject: ARM: S3C64XX: Update regulator names for debugfs compatiblity on SMDK6410 The debugfs support added to the regulator API (which has been merged in during this merge window) creates directories for regulators named after the display names for the regulators so replace / as a separator for multiple supplies with + in the SMDK6410 machine. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index a74f2c9..a80a316 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -352,7 +352,7 @@ static struct regulator_init_data smdk6410_vddpll = { /* VDD_UH_MMC, LDO5 on J5 */ static struct regulator_init_data smdk6410_vdduh_mmc = { .constraints = { - .name = "PVDD_UH/PVDD_MMC", + .name = "PVDD_UH+PVDD_MMC", .always_on = 1, }, }; @@ -418,7 +418,7 @@ static struct regulator_init_data smdk6410_vddaudio = { /* S3C64xx internal logic & PLL */ static struct regulator_init_data wm8350_dcdc1_data = { .constraints = { - .name = "PVDD_INT/PVDD_PLL", + .name = "PVDD_INT+PVDD_PLL", .min_uV = 1200000, .max_uV = 1200000, .always_on = 1, @@ -453,7 +453,7 @@ static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = { static struct regulator_init_data wm8350_dcdc4_data = { .constraints = { - .name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV", + .name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV", .min_uV = 3000000, .max_uV = 3000000, .always_on = 1, @@ -465,7 +465,7 @@ static struct regulator_init_data wm8350_dcdc4_data = { /* OTGi/1190-EV1 HPVDD & AVDD */ static struct regulator_init_data wm8350_ldo4_data = { .constraints = { - .name = "PVDD_OTGI/HPVDD/AVDD", + .name = "PVDD_OTGI+HPVDD+AVDD", .min_uV = 1200000, .max_uV = 1200000, .apply_uV = 1, @@ -553,7 +553,7 @@ static struct wm831x_backlight_pdata wm1192_backlight_pdata = { static struct regulator_init_data wm1192_dcdc3 = { .constraints = { - .name = "PVDD_MEM/PVDD_GPS", + .name = "PVDD_MEM+PVDD_GPS", .always_on = 1, }, }; @@ -564,7 +564,7 @@ static struct regulator_consumer_supply wm1192_ldo1_consumers[] = { static struct regulator_init_data wm1192_ldo1 = { .constraints = { - .name = "PVDD_LCD/PVDD_EXT", + .name = "PVDD_LCD+PVDD_EXT", .always_on = 1, }, .consumer_supplies = wm1192_ldo1_consumers, -- cgit v0.10.2 From e3e89cc535223433a619d0969db3fa05cdd946b8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 4 Mar 2011 09:23:30 -0800 Subject: Mark ptrace_{traceme,attach,detach} static They are only used inside kernel/ptrace.c, and have been for a long time. We don't want to go back to the bad-old-days when architectures did things on their own, so make them static and private. Signed-off-by: Linus Torvalds diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 092a04f..a1147e5 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -102,11 +102,8 @@ extern long arch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data); -extern int ptrace_traceme(void); extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); -extern int ptrace_attach(struct task_struct *tsk); -extern int ptrace_detach(struct task_struct *, unsigned int); extern void ptrace_disable(struct task_struct *); extern int ptrace_check_attach(struct task_struct *task, int kill); extern int ptrace_request(struct task_struct *child, long request, diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 1708b1e..e2302e4 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -163,7 +163,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) return !err; } -int ptrace_attach(struct task_struct *task) +static int ptrace_attach(struct task_struct *task) { int retval; @@ -219,7 +219,7 @@ out: * Performs checks and sets PT_PTRACED. * Should be used by all ptrace implementations for PTRACE_TRACEME. */ -int ptrace_traceme(void) +static int ptrace_traceme(void) { int ret = -EPERM; @@ -293,7 +293,7 @@ static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) return false; } -int ptrace_detach(struct task_struct *child, unsigned int data) +static int ptrace_detach(struct task_struct *child, unsigned int data) { bool dead = false; -- cgit v0.10.2 From 3256f80fbbc25bd2504bd564844c615227621e56 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 4 Mar 2011 10:13:47 -0600 Subject: MAINTAINERS: Update shaggy's email address Signed-off-by: Dave Kleikamp Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 6d18148..297a052 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3520,7 +3520,7 @@ F: drivers/hwmon/jc42.c F: Documentation/hwmon/jc42 JFS FILESYSTEM -M: Dave Kleikamp +M: Dave Kleikamp L: jfs-discussion@lists.sourceforge.net W: http://jfs.sourceforge.net/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git -- cgit v0.10.2 From 60bf8bf8815e6adea4c1d0423578c3b8000e2ec8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 4 Mar 2011 12:24:28 -0800 Subject: libceph: fix msgr backoff With commit f363e45f we replaced a bunch of hacky workqueue mutual exclusion logic with the WQ_NON_REENTRANT flag. One pieces of fallout is that the exponential backoff breaks in certain cases: * con_work attempts to connect. * we get an immediate failure, and the socket state change handler queues immediate work. * con_work calls con_fault, we decide to back off, but can't queue delayed work. In this case, we add a BACKOFF bit to make con_work reschedule delayed work next time it runs (which should be immediately). Signed-off-by: Sage Weil diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index c3011be..eb31e10 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h @@ -123,6 +123,7 @@ struct ceph_msg_pos { #define SOCK_CLOSED 11 /* socket state changed to closed */ #define OPENING 13 /* open connection w/ (possibly new) peer */ #define DEAD 14 /* dead, about to kfree */ +#define BACKOFF 15 /* * A single connection with another host. diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 6bd5025..46fbc42 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1949,6 +1949,19 @@ static void con_work(struct work_struct *work) work.work); mutex_lock(&con->mutex); + if (test_and_clear_bit(BACKOFF, &con->state)) { + dout("con_work %p backing off\n", con); + if (queue_delayed_work(ceph_msgr_wq, &con->work, + round_jiffies_relative(con->delay))) { + dout("con_work %p backoff %lu\n", con, con->delay); + mutex_unlock(&con->mutex); + return; + } else { + con->ops->put(con); + dout("con_work %p FAILED to back off %lu\n", con, + con->delay); + } + } if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */ dout("con_work CLOSED\n"); @@ -2017,11 +2030,24 @@ static void ceph_fault(struct ceph_connection *con) con->delay = BASE_DELAY_INTERVAL; else if (con->delay < MAX_DELAY_INTERVAL) con->delay *= 2; - dout("fault queueing %p delay %lu\n", con, con->delay); con->ops->get(con); if (queue_delayed_work(ceph_msgr_wq, &con->work, - round_jiffies_relative(con->delay)) == 0) + round_jiffies_relative(con->delay))) { + dout("fault queued %p delay %lu\n", con, con->delay); + } else { con->ops->put(con); + dout("fault failed to queue %p delay %lu, backoff\n", + con, con->delay); + /* + * In many cases we see a socket state change + * while con_work is running and end up + * queuing (non-delayed) work, such that we + * can't backoff with a delay. Set a flag so + * that when con_work restarts we schedule the + * delay then. + */ + set_bit(BACKOFF, &con->state); + } } out_unlock: -- cgit v0.10.2 From e76661d0a59e53e5cc4dccbe4b755d1dc8a968ec Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 3 Mar 2011 10:10:15 -0800 Subject: libceph: fix msgr keepalive flag There was some broken keepalive code using a dead variable. Shift to using the proper bit flag. Signed-off-by: Sage Weil diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index eb31e10..31d91a6 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h @@ -161,7 +161,6 @@ struct ceph_connection { struct list_head out_queue; struct list_head out_sent; /* sending or sent but unacked */ u64 out_seq; /* last message queued for send */ - bool out_keepalive_pending; u64 in_seq, in_seq_acked; /* last message received, acked */ diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 46fbc42..3252ea9 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -336,7 +336,6 @@ static void reset_connection(struct ceph_connection *con) ceph_msg_put(con->out_msg); con->out_msg = NULL; } - con->out_keepalive_pending = false; con->in_seq = 0; con->in_seq_acked = 0; } @@ -2019,10 +2018,10 @@ static void ceph_fault(struct ceph_connection *con) /* Requeue anything that hasn't been acked */ list_splice_init(&con->out_sent, &con->out_queue); - /* If there are no messages in the queue, place the connection - * in a STANDBY state (i.e., don't try to reconnect just yet). */ - if (list_empty(&con->out_queue) && !con->out_keepalive_pending) { - dout("fault setting STANDBY\n"); + /* If there are no messages queued or keepalive pending, place + * the connection in a STANDBY state */ + if (list_empty(&con->out_queue) && + !test_bit(KEEPALIVE_PENDING, &con->state)) { set_bit(STANDBY, &con->state); } else { /* retry after a delay. */ -- cgit v0.10.2 From e00de341fdb76c955703b4438100f9933c452b7f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 4 Mar 2011 12:25:05 -0800 Subject: libceph: fix msgr standby handling The standby logic used to be pretty dependent on the work requeueing behavior that changed when we switched to WQ_NON_REENTRANT. It was also very fragile. Restructure things so that: - We clear WRITE_PENDING when we set STANDBY. This ensures we will requeue work when we wake up later. - con_work backs off if STANDBY is set. There is nothing to do if we are in standby. - clear_standby() helper is called by both con_send() and con_keepalive(), the two actions that can wake us up again. Move the connect_seq++ logic here. Signed-off-by: Sage Weil diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 3252ea9..05f3578 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1712,14 +1712,6 @@ more: /* open the socket first? */ if (con->sock == NULL) { - /* - * if we were STANDBY and are reconnecting _this_ - * connection, bump connect_seq now. Always bump - * global_seq. - */ - if (test_and_clear_bit(STANDBY, &con->state)) - con->connect_seq++; - prepare_write_banner(msgr, con); prepare_write_connect(msgr, con, 1); prepare_read_banner(con); @@ -1962,6 +1954,10 @@ static void con_work(struct work_struct *work) } } + if (test_bit(STANDBY, &con->state)) { + dout("con_work %p STANDBY\n", con); + goto done; + } if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */ dout("con_work CLOSED\n"); con_close_socket(con); @@ -2022,6 +2018,8 @@ static void ceph_fault(struct ceph_connection *con) * the connection in a STANDBY state */ if (list_empty(&con->out_queue) && !test_bit(KEEPALIVE_PENDING, &con->state)) { + dout("fault %p setting STANDBY clearing WRITE_PENDING\n", con); + clear_bit(WRITE_PENDING, &con->state); set_bit(STANDBY, &con->state); } else { /* retry after a delay. */ @@ -2117,6 +2115,19 @@ void ceph_messenger_destroy(struct ceph_messenger *msgr) } EXPORT_SYMBOL(ceph_messenger_destroy); +static void clear_standby(struct ceph_connection *con) +{ + /* come back from STANDBY? */ + if (test_and_clear_bit(STANDBY, &con->state)) { + mutex_lock(&con->mutex); + dout("clear_standby %p and ++connect_seq\n", con); + con->connect_seq++; + WARN_ON(test_bit(WRITE_PENDING, &con->state)); + WARN_ON(test_bit(KEEPALIVE_PENDING, &con->state)); + mutex_unlock(&con->mutex); + } +} + /* * Queue up an outgoing message on the given connection. */ @@ -2149,6 +2160,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) /* if there wasn't anything waiting to send before, queue * new work */ + clear_standby(con); if (test_and_set_bit(WRITE_PENDING, &con->state) == 0) queue_con(con); } @@ -2214,6 +2226,8 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg) */ void ceph_con_keepalive(struct ceph_connection *con) { + dout("con_keepalive %p\n", con); + clear_standby(con); if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 && test_and_set_bit(WRITE_PENDING, &con->state) == 0) queue_con(con); -- cgit v0.10.2 From 455cec0abff563574cca432ced49f734117ca113 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 3 Mar 2011 13:44:35 -0800 Subject: ceph: no .snap inside of snapped namespace Otherwise you can do things like # mkdir .snap/foo # cd .snap/foo/.snap # ls Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 196fd4c..099a586 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -496,6 +496,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, /* .snap dir? */ if (err == -ENOENT && + ceph_snap(parent) == CEPH_NOSNAP && strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) { struct inode *inode = ceph_get_snapdir(parent); -- cgit v0.10.2 From e9e3d724e2145f5039b423c290ce2b2c3d8f94bc Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 4 Mar 2011 19:26:03 -0500 Subject: nfs4: Ensure that ACL pages sent over NFS were not allocated from the slab (v3) The "bad_page()" page allocator sanity check was reported recently (call chain as follows): bad_page+0x69/0x91 free_hot_cold_page+0x81/0x144 skb_release_data+0x5f/0x98 __kfree_skb+0x11/0x1a tcp_ack+0x6a3/0x1868 tcp_rcv_established+0x7a6/0x8b9 tcp_v4_do_rcv+0x2a/0x2fa tcp_v4_rcv+0x9a2/0x9f6 do_timer+0x2df/0x52c ip_local_deliver+0x19d/0x263 ip_rcv+0x539/0x57c netif_receive_skb+0x470/0x49f :virtio_net:virtnet_poll+0x46b/0x5c5 net_rx_action+0xac/0x1b3 __do_softirq+0x89/0x133 call_softirq+0x1c/0x28 do_softirq+0x2c/0x7d do_IRQ+0xec/0xf5 default_idle+0x0/0x50 ret_from_intr+0x0/0xa default_idle+0x29/0x50 cpu_idle+0x95/0xb8 start_kernel+0x220/0x225 _sinittext+0x22f/0x236 It occurs because an skb with a fraglist was freed from the tcp retransmit queue when it was acked, but a page on that fraglist had PG_Slab set (indicating it was allocated from the Slab allocator (which means the free path above can't safely free it via put_page. We tracked this back to an nfsv4 setacl operation, in which the nfs code attempted to fill convert the passed in buffer to an array of pages in __nfs4_proc_set_acl, which gets used by the skb->frags list in xs_sendpages. __nfs4_proc_set_acl just converts each page in the buffer to a page struct via virt_to_page, but the vfs allocates the buffer via kmalloc, meaning the PG_slab bit is set. We can't create a buffer with kmalloc and free it later in the tcp ack path with put_page, so we need to either: 1) ensure that when we create the list of pages, no page struct has PG_Slab set or 2) not use a page list to send this data Given that these buffers can be multiple pages and arbitrarily sized, I think (1) is the right way to go. I've written the below patch to allocate a page from the buddy allocator directly and copy the data over to it. This ensures that we have a put_page free-able page for every entry that winds up on an skb frag list, so it can be safely freed when the frame is acked. We do a put page on each entry after the rpc_call_sync call so as to drop our own reference count to the page, leaving only the ref count taken by tcp_sendpages. This way the data will be properly freed when the ack comes in Successfully tested by myself to solve the above oops. Note, as this is the result of a setacl operation that exceeded a page of data, I think this amounts to a local DOS triggerable by an uprivlidged user, so I'm CCing security on this as well. Signed-off-by: Neil Horman CC: Trond Myklebust CC: security@kernel.org CC: Jeff Layton Signed-off-by: Linus Torvalds diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 78936a8..1ff76ac 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "nfs4_fs.h" #include "delegation.h" @@ -3252,6 +3253,35 @@ static void buf_to_pages(const void *buf, size_t buflen, } } +static int buf_to_pages_noslab(const void *buf, size_t buflen, + struct page **pages, unsigned int *pgbase) +{ + struct page *newpage, **spages; + int rc = 0; + size_t len; + spages = pages; + + do { + len = min(PAGE_CACHE_SIZE, buflen); + newpage = alloc_page(GFP_KERNEL); + + if (newpage == NULL) + goto unwind; + memcpy(page_address(newpage), buf, len); + buf += len; + buflen -= len; + *pages++ = newpage; + rc++; + } while (buflen != 0); + + return rc; + +unwind: + for(; rc > 0; rc--) + __free_page(spages[rc-1]); + return -ENOMEM; +} + struct nfs4_cached_acl { int cached; size_t len; @@ -3420,13 +3450,23 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .rpc_argp = &arg, .rpc_resp = &res, }; - int ret; + int ret, i; if (!nfs4_server_supports_acls(server)) return -EOPNOTSUPP; + i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); + if (i < 0) + return i; nfs_inode_return_delegation(inode); - buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); ret = nfs4_call_sync(server, &msg, &arg, &res, 1); + + /* + * Free each page after tx, so the only ref left is + * held by the network stack + */ + for (; i > 0; i--) + put_page(pages[i-1]); + /* * Acl update can result in inode attribute update. * so mark the attribute cache invalid. -- cgit v0.10.2 From 2ec38a0359e227c01080dcd670a0368c61ccd9ce Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:19 -0800 Subject: drivers/rtc/rtc-s3c.c: fix prototype for s3c_rtc_setaie() Fix s3c_rtc_setaie() prototype to eliminate the following compile warning: drivers/rtc/rtc-s3c.c:383: warning: initialization from incompatible pointer type (akpm: the rtc_class_ops.alarm_irq_enable() handler is being passed two arguments where it expects just one, presumably with undesired effects) Signed-off-by: Axel Lin Cc: Alessandro Zummo Cc: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index cf953ec..b80fa28 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -77,18 +77,20 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) } /* Update control registers */ -static void s3c_rtc_setaie(int to) +static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) { unsigned int tmp; - pr_debug("%s: aie=%d\n", __func__, to); + pr_debug("%s: aie=%d\n", __func__, enabled); tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; - if (to) + if (enabled) tmp |= S3C2410_RTCALM_ALMEN; writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); + + return 0; } static int s3c_rtc_setpie(struct device *dev, int enabled) @@ -308,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) writeb(alrm_en, base + S3C2410_RTCALM); - s3c_rtc_setaie(alrm->enabled); + s3c_rtc_setaie(dev, alrm->enabled); return 0; } @@ -440,7 +442,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) rtc_device_unregister(rtc); s3c_rtc_setpie(&dev->dev, 0); - s3c_rtc_setaie(0); + s3c_rtc_setaie(&dev->dev, 0); clk_disable(rtc_clk); clk_put(rtc_clk); -- cgit v0.10.2 From b75f38d659e6fc747eda64cb72f3920e29dd44a4 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 4 Mar 2011 17:36:21 -0800 Subject: cpuset: add a missing unlock in cpuset_write_resmask() Don't forget to release cgroup_mutex if alloc_trial_cpuset() fails. [akpm@linux-foundation.org: avoid multiple return points] Signed-off-by: Li Zefan Cc: Paul Menage Acked-by: David Rientjes Cc: Miao Xie Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 4349935..e92e981 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1575,8 +1575,10 @@ static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft, return -ENODEV; trialcs = alloc_trial_cpuset(cs); - if (!trialcs) - return -ENOMEM; + if (!trialcs) { + retval = -ENOMEM; + goto out; + } switch (cft->private) { case FILE_CPULIST: @@ -1591,6 +1593,7 @@ static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft, } free_trial_cpuset(trialcs); +out: cgroup_unlock(); return retval; } -- cgit v0.10.2 From 97e419a082461f8a3a0818834eb88ad41219a1da Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:22 -0800 Subject: drivers/misc/bmp085.c: add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. Signed-off-by: Axel Lin Cc: Shubhrajyoti D Cc: Christoph Mair Cc: Jonathan Cameron Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 63ee4c1..b6e1c9a 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -449,6 +449,7 @@ static const struct i2c_device_id bmp085_id[] = { { "bmp085", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, bmp085_id); static struct i2c_driver bmp085_driver = { .driver = { -- cgit v0.10.2 From 95b90afec301f050f72740e8696f7cce8a37db5a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 4 Mar 2011 17:36:23 -0800 Subject: pps: make pps_gen_parport depend on BROKEN This driver causes hard lockups, when the active clock soure is jiffies. The reason is that it loops with interrupts disabled waiting for a timestamp to be reached by polling getnstimeofday(). Though with a jiffies clocksource, when that code runs on the same CPU which is responsible for updating jiffies, then we loop in circles for ever simply because the timer interrupt cannot update jiffies. So both UP and SMP can be affected. There is no easy fix for that problem so make it depend on BROKEN for now. Signed-off-by: Thomas Gleixner Cc: Alexander Gordeev Cc: Rodolfo Giometti Cc: john stultz Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index f3a73dd..e4c4f3d 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -6,7 +6,7 @@ comment "PPS generators support" config PPS_GENERATOR_PARPORT tristate "Parallel port PPS signal generator" - depends on PARPORT + depends on PARPORT && BROKEN help If you say yes here you get support for a PPS signal generator which utilizes STROBE pin of a parallel port to send PPS signals. It uses -- cgit v0.10.2 From 10ffa96407b230ea7fc72abd32c6795183f38fa1 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 4 Mar 2011 17:36:26 -0800 Subject: MAINTAINERS: add maintainer of Samsung Mobile Machine support Add maintainer of Samsung Mobile machine support. Currently, Aquila, Goni, Universal (C210), and Nuri board are supported. Signed-off-by: Kyungmin Park Cc: Joe Perches Cc: "David S. Miller" Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 297a052..44757a0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1010,6 +1010,15 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-s5p*/ +ARM/SAMSUNG MOBILE MACHINE SUPPORT +M: Kyungmin Park +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-s5pv210/mach-aquila.c +F: arch/arm/mach-s5pv210/mach-goni.c +F: arch/arm/mach-exynos4/mach-universal_c210.c +F: arch/arm/mach-exynos4/mach-nuri.c + ARM/SAMSUNG S5P SERIES FIMC SUPPORT M: Kyungmin Park M: Sylwester Nawrocki -- cgit v0.10.2 From 9dab51daef2e4a0d18d7824e23fcb64a2a86481d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:27 -0800 Subject: drivers/video/backlight/ltv350qv.c: fix a memory leak Signed-off-by: Axel Lin Cc: Haavard Skinnemoen Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 8010aae..dd0e84a 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -239,11 +239,15 @@ static int __devinit ltv350qv_probe(struct spi_device *spi) lcd->spi = spi; lcd->power = FB_BLANK_POWERDOWN; lcd->buffer = kzalloc(8, GFP_KERNEL); + if (!lcd->buffer) { + ret = -ENOMEM; + goto out_free_lcd; + } ld = lcd_device_register("ltv350qv", &spi->dev, lcd, <v_ops); if (IS_ERR(ld)) { ret = PTR_ERR(ld); - goto out_free_lcd; + goto out_free_buffer; } lcd->ld = ld; @@ -257,6 +261,8 @@ static int __devinit ltv350qv_probe(struct spi_device *spi) out_unregister: lcd_device_unregister(ld); +out_free_buffer: + kfree(lcd->buffer); out_free_lcd: kfree(lcd); return ret; @@ -268,6 +274,7 @@ static int __devexit ltv350qv_remove(struct spi_device *spi) ltv350qv_power(lcd, FB_BLANK_POWERDOWN); lcd_device_unregister(lcd->ld); + kfree(lcd->buffer); kfree(lcd); return 0; -- cgit v0.10.2 From b8bc1dd39722f7c306435d0682e9bf81abf52105 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Fri, 4 Mar 2011 17:36:28 -0800 Subject: RapidIO: Update MAINTAINERS Signed-off-by: Alexandre Bounine Cc: Matt Porter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 44757a0..560ecce 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5181,6 +5181,7 @@ F: drivers/char/random.c RAPIDIO SUBSYSTEM M: Matt Porter +M: Alexandre Bounine S: Maintained F: drivers/rapidio/ -- cgit v0.10.2 From 2f5f9486f8c12e3aa40fe3775a18cb14efc5cea2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 4 Mar 2011 17:36:29 -0800 Subject: mm: change alloc_pages_vma to pass down the policy node for local policy Currently alloc_pages_vma() always uses the local node as policy node for the LOCAL policy. Pass this node down as an argument instead. No behaviour change from this patch, but will be needed for followons. Acked-by: Andrea Arcangeli Signed-off-by: Andi Kleen Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0b84c61..37b8af5 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -332,16 +332,17 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) return alloc_pages_current(gfp_mask, order); } extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, - struct vm_area_struct *vma, unsigned long addr); + struct vm_area_struct *vma, unsigned long addr, + int node); #else #define alloc_pages(gfp_mask, order) \ alloc_pages_node(numa_node_id(), gfp_mask, order) -#define alloc_pages_vma(gfp_mask, order, vma, addr) \ +#define alloc_pages_vma(gfp_mask, order, vma, addr, node) \ alloc_pages(gfp_mask, order) #endif #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) -#define alloc_page_vma(gfp_mask, vma, addr) \ - alloc_pages_vma(gfp_mask, 0, vma, addr) +#define alloc_page_vma(gfp_mask, vma, addr) \ + alloc_pages_vma(gfp_mask, 0, vma, addr, numa_node_id()) extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order); extern unsigned long get_zeroed_page(gfp_t gfp_mask); diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 3e29781..c7c2cd9 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -653,7 +653,7 @@ static inline struct page *alloc_hugepage_vma(int defrag, unsigned long haddr) { return alloc_pages_vma(alloc_hugepage_gfpmask(defrag), - HPAGE_PMD_ORDER, vma, haddr); + HPAGE_PMD_ORDER, vma, haddr, numa_node_id()); } #ifndef CONFIG_NUMA diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 49355a9..25a5a91 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1524,10 +1524,9 @@ static nodemask_t *policy_nodemask(gfp_t gfp, struct mempolicy *policy) } /* Return a zonelist indicated by gfp for node representing a mempolicy */ -static struct zonelist *policy_zonelist(gfp_t gfp, struct mempolicy *policy) +static struct zonelist *policy_zonelist(gfp_t gfp, struct mempolicy *policy, + int nd) { - int nd = numa_node_id(); - switch (policy->mode) { case MPOL_PREFERRED: if (!(policy->flags & MPOL_F_LOCAL)) @@ -1679,7 +1678,7 @@ struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr, zl = node_zonelist(interleave_nid(*mpol, vma, addr, huge_page_shift(hstate_vma(vma))), gfp_flags); } else { - zl = policy_zonelist(gfp_flags, *mpol); + zl = policy_zonelist(gfp_flags, *mpol, numa_node_id()); if ((*mpol)->mode == MPOL_BIND) *nodemask = &(*mpol)->v.nodes; } @@ -1820,7 +1819,7 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, */ struct page * alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, - unsigned long addr) + unsigned long addr, int node) { struct mempolicy *pol = get_vma_policy(current, vma, addr); struct zonelist *zl; @@ -1836,7 +1835,7 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, put_mems_allowed(); return page; } - zl = policy_zonelist(gfp, pol); + zl = policy_zonelist(gfp, pol, node); if (unlikely(mpol_needs_cond_ref(pol))) { /* * slow path: ref counted shared policy -- cgit v0.10.2 From 236344d6b417d05a3080477639234fd9ca97568d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 4 Mar 2011 17:36:30 -0800 Subject: mm: add alloc_page_vma_node() Add a alloc_page_vma_node that allows passing the "local" node in. Used in a followon patch. Acked-by: Andrea Arcangeli Signed-off-by: Andi Kleen Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 37b8af5..dca3176 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -343,6 +343,8 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) #define alloc_page_vma(gfp_mask, vma, addr) \ alloc_pages_vma(gfp_mask, 0, vma, addr, numa_node_id()) +#define alloc_page_vma_node(gfp_mask, vma, addr, node) \ + alloc_pages_vma(gfp_mask, 0, vma, addr, node) extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order); extern unsigned long get_zeroed_page(gfp_t gfp_mask); -- cgit v0.10.2 From 19ee151e140daa5183c4984981801e542e0544fb Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 4 Mar 2011 17:36:31 -0800 Subject: mm: preserve original node for transparent huge page copies This makes a difference for LOCAL policy, where the node cannot be determined from the policy itself, but has to be gotten from the original page. Acked-by: Andrea Arcangeli Signed-off-by: Andi Kleen Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/huge_memory.c b/mm/huge_memory.c index c7c2cd9..1802db8 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -799,8 +799,8 @@ static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm, } for (i = 0; i < HPAGE_PMD_NR; i++) { - pages[i] = alloc_page_vma(GFP_HIGHUSER_MOVABLE, - vma, address); + pages[i] = alloc_page_vma_node(GFP_HIGHUSER_MOVABLE, + vma, address, page_to_nid(page)); if (unlikely(!pages[i] || mem_cgroup_newpage_charge(pages[i], mm, GFP_KERNEL))) { -- cgit v0.10.2 From 5c4b4be3b6b937256103a5ae49177e0c3a17cb8f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 4 Mar 2011 17:36:32 -0800 Subject: mm: use correct numa policy node for transparent hugepages Pass down the correct node for a transparent hugepage allocation. Most callers continue to use the current node, however the hugepaged daemon now uses the previous node of the first to be collapsed page instead. This ensures that khugepaged does not mess up local memory for an existing process which uses local policy. The choice of node is somewhat primitive currently: it just uses the node of the first page in the pmd range. An alternative would be to look at multiple pages and use the most popular node. I used the simplest variant for now which should work well enough for the case of all pages being on the same node. [akpm@linux-foundation.org: coding-style fixes] Acked-by: Andrea Arcangeli Signed-off-by: Andi Kleen Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 1802db8..dbe99a5 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -650,10 +650,10 @@ static inline gfp_t alloc_hugepage_gfpmask(int defrag) static inline struct page *alloc_hugepage_vma(int defrag, struct vm_area_struct *vma, - unsigned long haddr) + unsigned long haddr, int nd) { return alloc_pages_vma(alloc_hugepage_gfpmask(defrag), - HPAGE_PMD_ORDER, vma, haddr, numa_node_id()); + HPAGE_PMD_ORDER, vma, haddr, nd); } #ifndef CONFIG_NUMA @@ -678,7 +678,7 @@ int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(khugepaged_enter(vma))) return VM_FAULT_OOM; page = alloc_hugepage_vma(transparent_hugepage_defrag(vma), - vma, haddr); + vma, haddr, numa_node_id()); if (unlikely(!page)) goto out; if (unlikely(mem_cgroup_newpage_charge(page, mm, GFP_KERNEL))) { @@ -902,7 +902,7 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, if (transparent_hugepage_enabled(vma) && !transparent_hugepage_debug_cow()) new_page = alloc_hugepage_vma(transparent_hugepage_defrag(vma), - vma, haddr); + vma, haddr, numa_node_id()); else new_page = NULL; @@ -1745,7 +1745,8 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page, static void collapse_huge_page(struct mm_struct *mm, unsigned long address, struct page **hpage, - struct vm_area_struct *vma) + struct vm_area_struct *vma, + int node) { pgd_t *pgd; pud_t *pud; @@ -1773,7 +1774,8 @@ static void collapse_huge_page(struct mm_struct *mm, * mmap_sem in read mode is good idea also to allow greater * scalability. */ - new_page = alloc_hugepage_vma(khugepaged_defrag(), vma, address); + new_page = alloc_hugepage_vma(khugepaged_defrag(), vma, address, + node); if (unlikely(!new_page)) { up_read(&mm->mmap_sem); *hpage = ERR_PTR(-ENOMEM); @@ -1919,6 +1921,7 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, struct page *page; unsigned long _address; spinlock_t *ptl; + int node = -1; VM_BUG_ON(address & ~HPAGE_PMD_MASK); @@ -1949,6 +1952,13 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, page = vm_normal_page(vma, _address, pteval); if (unlikely(!page)) goto out_unmap; + /* + * Chose the node of the first page. This could + * be more sophisticated and look at more pages, + * but isn't for now. + */ + if (node == -1) + node = page_to_nid(page); VM_BUG_ON(PageCompound(page)); if (!PageLRU(page) || PageLocked(page) || !PageAnon(page)) goto out_unmap; @@ -1965,7 +1975,7 @@ out_unmap: pte_unmap_unlock(pte, ptl); if (ret) /* collapse_huge_page will return with the mmap_sem released */ - collapse_huge_page(mm, address, hpage, vma); + collapse_huge_page(mm, address, hpage, vma, node); out: return ret; } diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 25a5a91..b53ec99 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1891,7 +1891,8 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order) page = alloc_page_interleave(gfp, order, interleave_nodes(pol)); else page = __alloc_pages_nodemask(gfp, order, - policy_zonelist(gfp, pol), policy_nodemask(gfp, pol)); + policy_zonelist(gfp, pol, numa_node_id()), + policy_nodemask(gfp, pol)); put_mems_allowed(); return page; } -- cgit v0.10.2 From 0ee537abbd10a9abf11e1c22ee32a68e8c12ed4a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Mar 2011 09:03:16 +0000 Subject: Revert "drm/i915: fix corruptions on i8xx due to relaxed fencing" This reverts commit c2e0eb167070a6e9dcb49c84c13c79a30d672431. As it turns out, userspace already depends upon being able to enable tiling on existing bo which it promises to be large enough for its purposes i.e. it will not access beyond the end of the last full-tile row. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=35016 Reported-and-tested-by: Kamal Mostafa Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 79a04fd..22a32b9 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { - int tile_width, tile_height; + int tile_width; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) @@ -215,20 +215,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) } } - if (IS_GEN2(dev) || - (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) - tile_height = 32; - else - tile_height = 8; - /* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even - * number of tile rows. */ - if (IS_GEN2(dev)) - tile_height *= 2; - - /* Size needs to be aligned to a full tile row */ - if (size & (tile_height * stride - 1)) - return false; - /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) -- cgit v0.10.2 From 91355834646328e7edc6bd25176ae44bcd7386c7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Mar 2011 19:22:40 +0000 Subject: drm/i915: Do not overflow the MMADDR write FIFO Whilst the GT is powered down (rc6), writes to MMADDR are placed in a FIFO by the System Agent. This is a limited resource, only 64 entries, of which 20 are reserved for Display and PCH writes, and so we must take care not to queue up too many writes. To avoid this, there is counter which we can poll to ensure there are sufficient free entries in the fifo. "Issuing a write to a full FIFO is not supported; at worst it could result in corruption or a system hang." Reported-and-Tested-by: Matt Turner Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34056 Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3601466..4ff9b6c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -865,7 +865,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) int max_freq; /* RPSTAT1 is in the GT power well */ - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "RPSTAT1: 0x%08x\n", I915_READ(GEN6_RPSTAT1)); @@ -888,7 +888,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", max_freq * 100); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } else { seq_printf(m, "no P-state info available\n"); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0ad533f..37d672a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -254,7 +254,7 @@ void intel_detect_pch (struct drm_device *dev) } } -void __gen6_force_wake_get(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { int count; @@ -270,12 +270,22 @@ void __gen6_force_wake_get(struct drm_i915_private *dev_priv) udelay(10); } -void __gen6_force_wake_put(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); POSTING_READ(FORCEWAKE); } +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +{ + int loop = 500; + u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + while (fifo < 20 && loop--) { + udelay(10); + fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + } +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65dfe81..549c046 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1353,22 +1353,32 @@ __i915_write(64, q) * must be set to prevent GT core from power down and stale values being * returned. */ -void __gen6_force_wake_get(struct drm_i915_private *dev_priv); -void __gen6_force_wake_put (struct drm_i915_private *dev_priv); -static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + +static inline u32 i915_gt_read(struct drm_i915_private *dev_priv, u32 reg) { u32 val; if (dev_priv->info->gen >= 6) { - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); val = I915_READ(reg); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } else val = I915_READ(reg); return val; } +static inline void i915_gt_write(struct drm_i915_private *dev_priv, + u32 reg, u32 val) +{ + if (dev_priv->info->gen >= 6) + __gen6_gt_wait_for_fifo(dev_priv); + I915_WRITE(reg, val); +} + static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 729d423..3e6f486 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3261,6 +3261,8 @@ #define FORCEWAKE 0xA18C #define FORCEWAKE_ACK 0x130090 +#define GT_FIFO_FREE_ENTRIES 0x120008 + #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e79b25b..49fb54f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1219,7 +1219,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) u32 blt_ecoskpd; /* Make sure blitter notifies FBC of writes */ - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << GEN6_BLITTER_LOCK_SHIFT; @@ -1230,7 +1230,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) GEN6_BLITTER_LOCK_SHIFT); I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); POSTING_READ(GEN6_BLITTER_ECOSKPD); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) @@ -6282,7 +6282,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) * userspace... */ I915_WRITE(GEN6_RC_STATE, 0); - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); @@ -6380,7 +6380,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) /* enable all PM interrupts */ I915_WRITE(GEN6_PMINTRMSK, 0); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } void intel_enable_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 6d6fde8..3430686 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -14,22 +14,23 @@ struct intel_hw_status_page { struct drm_i915_gem_object *obj; }; -#define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) +#define I915_RING_READ(reg) i915_gt_read(dev_priv, reg) +#define I915_RING_WRITE(reg, val) i915_gt_write(dev_priv, reg, val) #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base)) -#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) +#define I915_WRITE_TAIL(ring, val) I915_RING_WRITE(RING_TAIL((ring)->mmio_base), val) #define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base)) -#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) +#define I915_WRITE_START(ring, val) I915_RING_WRITE(RING_START((ring)->mmio_base), val) #define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD((ring)->mmio_base)) -#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) +#define I915_WRITE_HEAD(ring, val) I915_RING_WRITE(RING_HEAD((ring)->mmio_base), val) #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base)) -#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) +#define I915_WRITE_CTL(ring, val) I915_RING_WRITE(RING_CTL((ring)->mmio_base), val) -#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base)) +#define I915_WRITE_IMR(ring, val) I915_RING_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base)) #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base)) -- cgit v0.10.2 From d7a62cd0332115d4c7c4689abea0d889a30d8349 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 4 Mar 2011 14:04:33 +1030 Subject: virtio: console: Don't access vqs if device was unplugged If a virtio-console device gets unplugged while a port is open, a subsequent close() call on the port accesses vqs to free up buffers. This can lead to a crash. The buffers are already freed up as a result of the call to unplug_ports() from virtcons_remove(). The fix is to simply not access vq information if port->portdev is NULL. Reported-by: juzhang CC: stable@kernel.org Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 4903931..84b164d 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -388,6 +388,10 @@ static void discard_port_data(struct port *port) unsigned int len; int ret; + if (!port->portdev) { + /* Device has been unplugged. vqs are already gone. */ + return; + } vq = port->in_vq; if (port->inbuf) buf = port->inbuf; @@ -470,6 +474,10 @@ static void reclaim_consumed_buffers(struct port *port) void *buf; unsigned int len; + if (!port->portdev) { + /* Device has been unplugged. vqs are already gone. */ + return; + } while ((buf = virtqueue_get_buf(port->out_vq, &len))) { kfree(buf); port->outvq_full = false; -- cgit v0.10.2 From a1656b9090f7008d2941c314f5a64724bea2ae37 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Mar 2011 18:48:03 +0000 Subject: drm/i915: Disable GPU semaphores by default Andi Kleen narrowed his GPU hangs on his Sugar Bay (SNB desktop) rev 09 down to the use of GPU semaphores, and we already know that they appear broken up to Huron River (mobile) rev 08. (I'm optimistic that disabling GPU semaphores is simply hiding another bug by the latency and side-effects of the additional device interaction it introduces...) However, use of semaphores is a massive performance improvement... Only as long as the system remains stable. Enable at your peril. Reported-by: Andi Kleen Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33921 Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 37d672a..22ec066 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; module_param_named(powersave, i915_powersave, int, 0600); +unsigned int i915_semaphores = 0; +module_param_named(semaphores, i915_semaphores, int, 0600); + unsigned int i915_enable_rc6 = 0; module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 549c046..d023b9b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -956,6 +956,7 @@ extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; +extern unsigned int i915_semaphores; extern unsigned int i915_lvds_downclock; extern unsigned int i915_panel_use_ssc; extern unsigned int i915_enable_rc6; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d2f445e..50ab161 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -772,8 +772,8 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, if (from == NULL || to == from) return 0; - /* XXX gpu semaphores are currently causing hard hangs on SNB mobile */ - if (INTEL_INFO(obj->base.dev)->gen < 6 || IS_MOBILE(obj->base.dev)) + /* XXX gpu semaphores are implicated in various hard hangs on SNB */ + if (INTEL_INFO(obj->base.dev)->gen < 6 || !i915_semaphores) return i915_gem_object_wait_rendering(obj, true); idx = intel_ring_sync_index(from, to); -- cgit v0.10.2 From 467cffba85791cdfce38c124d75bd578f4bb8625 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Mar 2011 10:42:03 +0000 Subject: drm/i915: Rebind the buffer if its alignment constraints changes with tiling Early gen3 and gen2 chipset do not have the relaxed per-surface tiling constraints of the later chipsets, so we need to check that the GTT alignment is correct for the new tiling. If it is not, we need to rebind. Reported-by: Daniel Vetter Reviewed-by: Daniel Vetter Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d023b9b..456f404 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1178,6 +1178,9 @@ void i915_gem_detach_phys_object(struct drm_device *dev, void i915_gem_free_all_phys_object(struct drm_device *dev); void i915_gem_release(struct drm_device *dev, struct drm_file *file); +uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); + /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4f74c..36e66cc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1398,7 +1398,7 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) * Return the required GTT alignment for an object, only taking into account * unfenced tiled surface requirements. */ -static uint32_t +uint32_t i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 22a32b9..d64843e 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -349,14 +349,27 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && i915_gem_object_fence_ok(obj, args->tiling_mode)); - obj->tiling_changed = true; - obj->tiling_mode = args->tiling_mode; - obj->stride = args->stride; + /* Rebind if we need a change of alignment */ + if (!obj->map_and_fenceable) { + u32 unfenced_alignment = + i915_gem_get_unfenced_gtt_alignment(obj); + if (obj->gtt_offset & (unfenced_alignment - 1)) + ret = i915_gem_object_unbind(obj); + } + + if (ret == 0) { + obj->tiling_changed = true; + obj->tiling_mode = args->tiling_mode; + obj->stride = args->stride; + } } + /* we have to maintain this existing ABI... */ + args->stride = obj->stride; + args->tiling_mode = obj->tiling_mode; drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); - return 0; + return ret; } /** -- cgit v0.10.2 From ef1b287169cd3d1e428c8ed8222e0bbf733d5dbb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Mar 2011 17:18:03 +1000 Subject: drm/nouveau: fix regression causing ttm to not be able to evict vram TTM assumes an error condition from man->func->get_node() means that something went horribly wrong, and causes it to bail. The driver is supposed to return 0, and leave mm_node == NULL to signal that it couldn't allocate any memory. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 26347b7..b0fb9bd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -725,8 +725,10 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, mem->page_alignment << PAGE_SHIFT, size_nc, (nvbo->tile_flags >> 8) & 0xff, &node); - if (ret) - return ret; + if (ret) { + mem->mm_node = NULL; + return (ret == -ENOSPC) ? 0 : ret; + } node->page_shift = 12; if (nvbo->vma.node) diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c index 8844b50..7609756 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mm.c @@ -123,7 +123,7 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, return 0; } - return -ENOMEM; + return -ENOSPC; } int -- cgit v0.10.2 From 6f70a4c3d19e8e8e1047a4dbf0ca910fed39f619 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Mar 2011 17:18:04 +1000 Subject: drm/nv50-nvc0: prevent multiple vm/bar flushes occuring simultanenously The per-vm mutex doesn't prevent this completely, a flush coming from the BAR VM could potentially happen at the same time as one for the channel VM. Not to mention that if/when we get per-client/channel VM, this will happen far more frequently. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index ea00418..e57caa2 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -403,16 +403,24 @@ nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) void nv50_instmem_flush(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x00330c, 0x00000001); if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); + spin_unlock(&dev_priv->ramin_lock); } void nv84_instmem_flush(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x070000, 0x00000001); if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); + spin_unlock(&dev_priv->ramin_lock); } diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 459ff08..6144156 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -169,7 +169,11 @@ nv50_vm_flush(struct nouveau_vm *vm) void nv50_vm_flush_engine(struct drm_device *dev, int engine) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x100c80, (engine << 16) | 1); if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); + spin_unlock(&dev_priv->ramin_lock); } -- cgit v0.10.2 From 34497913f2936fd43c86b007da7224bb8e77fd15 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 3 Mar 2011 17:40:10 -0500 Subject: mmc: sdio: Allow sdio operations in other threads during sdio_add_func() This fixes a bug introduced by 807e8e40673d ("mmc: Fix sd/sdio/mmc initialization frequency retries") that prevented SDIO drivers from performing SDIO commands in their probe routines -- the above patch called mmc_claim_host() before sdio_add_func(), which causes a deadlock if an external SDIO driver calls sdio_claim_host(). Fix tested on an OLPC XO-1.75 with libertas on SDIO. Signed-off-by: Dmitry Shmidt Reviewed-and-Tested-by: Chris Ball Signed-off-by: Chris Ball diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 5c4a54d..ebc62ad 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -792,7 +792,6 @@ int mmc_attach_sdio(struct mmc_host *host) */ mmc_release_host(host); err = mmc_add_card(host->card); - mmc_claim_host(host); if (err) goto remove_added; @@ -805,12 +804,12 @@ int mmc_attach_sdio(struct mmc_host *host) goto remove_added; } + mmc_claim_host(host); return 0; remove_added: /* Remove without lock if the device has been added. */ - mmc_release_host(host); mmc_sdio_remove(host); mmc_claim_host(host); remove: -- cgit v0.10.2 From 062ac622e03a8be5f894555ece540d63a54ae8bd Mon Sep 17 00:00:00 2001 From: roel Date: Mon, 7 Mar 2011 18:00:34 +0100 Subject: drm: index i shadowed in 2nd loop Index i was already used in thhe first loop Signed-off-by: Roel Kluin Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6977a1c..f73ef43 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -672,7 +672,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) struct drm_crtc_helper_funcs *crtc_funcs; u16 *red, *green, *blue, *transp; struct drm_crtc *crtc; - int i, rc = 0; + int i, j, rc = 0; int start; for (i = 0; i < fb_helper->crtc_count; i++) { @@ -685,7 +685,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) transp = cmap->transp; start = cmap->start; - for (i = 0; i < cmap->len; i++) { + for (j = 0; j < cmap->len; j++) { u16 hred, hgreen, hblue, htransp = 0xffff; hred = *red++; -- cgit v0.10.2 From a5abba989deceb731047425812d268daf7536575 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 7 Mar 2011 21:09:37 -0800 Subject: Linux 2.6.38-rc8 diff --git a/Makefile b/Makefile index 2f7d922..504f788 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 38 -EXTRAVERSION = -rc7 +EXTRAVERSION = -rc8 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* -- cgit v0.10.2 From 126f7e2992760028005ce94509ce54d331c6714d Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 4 Jan 2011 15:33:08 -0800 Subject: MAINTAINERS: update Kevin's email for OMAP PM section Change my email to TI email address for OMAP PM maintenance. Signed-off-by: Kevin Hilman diff --git a/MAINTAINERS b/MAINTAINERS index 560ecce..939e852 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4501,7 +4501,7 @@ S: Maintained F: arch/arm/*omap*/*clock* OMAP POWER MANAGEMENT SUPPORT -M: Kevin Hilman +M: Kevin Hilman L: linux-omap@vger.kernel.org S: Maintained F: arch/arm/*omap*/*pm* -- cgit v0.10.2 From e16b41bfd5efaa1f9521449f1f0e341ebec73398 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Mon, 31 Jan 2011 11:35:25 -0200 Subject: OMAP3630: PM: don't warn the user with a trace in case of PM34XX_ERRATUM In case in user has a OMAP3630 < ES1.2 the kernel should warn the user about the ERRATUM, but using pr_warn instead of WARN_ON is already enough, as there is nothing else the user can do besides changing the board. Signed-off-by: Ricardo Salveti de Araujo Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f7b22a1..876eeca 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -464,7 +464,7 @@ void omap_init_power_states(void) if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) { omap3_power_states[OMAP3_STATE_C7].valid = 0; cpuidle_params_table[OMAP3_STATE_C7].valid = 0; - WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n", + pr_warn("%s: core off state C7 disabled due to i583\n", __func__); } } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 2f864e4..6ade4ea 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -928,8 +928,7 @@ void omap3_pm_off_mode_enable(int enable) pwrst->pwrdm == core_pwrdm && state == PWRDM_POWER_OFF) { pwrst->next_state = PWRDM_POWER_RET; - WARN_ONCE(1, - "%s: Core OFF disabled due to errata i583\n", + pr_warn("%s: Core OFF disabled due to errata i583\n", __func__); } else { pwrst->next_state = state; -- cgit v0.10.2 From eb05ead90ddb2a4e51d34f6c25f01c2e0653da59 Mon Sep 17 00:00:00 2001 From: "Menon, Nishanth" Date: Wed, 5 Jan 2011 20:49:35 +0000 Subject: OMAP3|4: OPP: make omapx_opp_init non-static omap3 and omap4 opp_init should be made non-static to allow for platform specific opp table tweaking. making these static conflicts with the definition in pm.h(global) as well. we include pm.h as well to ensure that there are no such prototype conflicts with actual implementation in the future. Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c index 0486fce..fd3a1af 100644 --- a/arch/arm/mach-omap2/opp3xxx_data.c +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -21,6 +21,7 @@ #include #include "omap_opp_data.h" +#include "pm.h" static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { /* MPU OPP1 */ @@ -88,7 +89,7 @@ static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { /** * omap3_opp_init() - initialize omap3 opp table */ -static int __init omap3_opp_init(void) +int __init omap3_opp_init(void) { int r = -ENODEV; diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index a11fa56..f0e9939 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -22,6 +22,7 @@ #include #include "omap_opp_data.h" +#include "pm.h" static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { /* MPU OPP1 - OPP50 */ @@ -42,7 +43,7 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { /** * omap4_opp_init() - initialize omap4 opp table */ -static int __init omap4_opp_init(void) +int __init omap4_opp_init(void) { int r = -ENODEV; -- cgit v0.10.2 From 8743410d4971c5510a7d09293f5f3f89d8081059 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 7 Jan 2011 09:41:13 -0600 Subject: OMAP3: beagle xm: enable up to 800MHz OPP OMP3630 silicon can enable higher frequencies only depending on the board characteristics meeting the recommended standards, and has to be selectively toggled. Beagle XM uses 3730 variant and the board design allows enabling 800MHz and 1GHz OPPs. However, We need Smart reflex class 1.5 and ABB to enable 1GHz safely. For the moment, we tweak the default table to allow for 800Mhz OPP usage. Reported-by: Koen Kooi Tested-by: Koen Kooi Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 46d814a..91b4e14 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -45,10 +46,12 @@ #include #include #include +#include #include "mux.h" #include "hsmmc.h" #include "timer-gp.h" +#include "pm.h" #define NAND_BLOCK_SIZE SZ_128K @@ -610,6 +613,52 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; +static void __init beagle_opp_init(void) +{ + int r = 0; + + /* Initialize the omap3 opp table */ + if (omap3_opp_init()) { + pr_err("%s: opp default init failed\n", __func__); + return; + } + + /* Custom OPP enabled for XM */ + if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { + struct omap_hwmod *mh = omap_hwmod_lookup("mpu"); + struct omap_hwmod *dh = omap_hwmod_lookup("iva"); + struct device *dev; + + if (!mh || !dh) { + pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", + __func__, mh, dh); + return; + } + /* Enable MPU 1GHz and lower opps */ + dev = &mh->od->pdev.dev; + r = opp_enable(dev, 800000000); + /* TODO: MPU 1GHz needs SR and ABB */ + + /* Enable IVA 800MHz and lower opps */ + dev = &dh->od->pdev.dev; + r |= opp_enable(dev, 660000000); + /* TODO: DSP 800MHz needs SR and ABB */ + if (r) { + pr_err("%s: failed to enable higher opp %d\n", + __func__, r); + /* + * Cleanup - disable the higher freqs - we dont care + * about the results + */ + dev = &mh->od->pdev.dev; + opp_disable(dev, 800000000); + dev = &dh->od->pdev.dev; + opp_disable(dev, 660000000); + } + } + return; +} + static void __init omap3_beagle_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -633,6 +682,7 @@ static void __init omap3_beagle_init(void) omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); beagle_display_init(); + beagle_opp_init(); } MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") -- cgit v0.10.2 From 5c56f32e80ac8ea9878a0a5eb9ca99c703e953ab Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Wed, 19 Jan 2011 15:57:22 +0300 Subject: OMAP: PM: SmartReflex: fix potential NULL dereference kzalloc() may fail, if so return -ENOMEM. Also Walter Harms suggested to use kasprintf() instead of kzalloc+strcpy+strcat. Signed-off-by: Vasiliy Kulikov Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 1a777e3..b57ae50 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -260,9 +260,11 @@ static int sr_late_init(struct omap_sr *sr_info) if (sr_class->class_type == SR_CLASS2 && sr_class->notify_flags && sr_info->irq) { - name = kzalloc(SMARTREFLEX_NAME_LEN + 1, GFP_KERNEL); - strcpy(name, "sr_"); - strcat(name, sr_info->voltdm->name); + name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); + if (name == NULL) { + ret = -ENOMEM; + goto error; + } ret = request_irq(sr_info->irq, sr_interrupt, 0, name, (void *)sr_info); if (ret) -- cgit v0.10.2 From df93bd76b61639fe9093ccbfc5d1a4bfb744ec47 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 21 Jan 2011 14:30:15 -0800 Subject: OMAP2+: remove unused UART base addresses from omap_globals Now that omap_hwmod + omap_device is used for OMAP UART device and driver code, we no longer need the UART physical addresses in omap_globals. Note that the #defines for the base addresses are still left in since they are used by DEBUG_LL and uncompress code. Build tested for OMAP1 (omap1_defconfig) and OMAP2+ (omap2plus_defconfig) Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 778929f..994f0f0 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -50,9 +50,6 @@ static struct omap_globals omap242x_globals = { .ctrl = OMAP242X_CTRL_BASE, .prm = OMAP2420_PRM_BASE, .cm = OMAP2420_CM_BASE, - .uart1_phys = OMAP2_UART1_BASE, - .uart2_phys = OMAP2_UART2_BASE, - .uart3_phys = OMAP2_UART3_BASE, }; void __init omap2_set_globals_242x(void) @@ -71,9 +68,6 @@ static struct omap_globals omap243x_globals = { .ctrl = OMAP243X_CTRL_BASE, .prm = OMAP2430_PRM_BASE, .cm = OMAP2430_CM_BASE, - .uart1_phys = OMAP2_UART1_BASE, - .uart2_phys = OMAP2_UART2_BASE, - .uart3_phys = OMAP2_UART3_BASE, }; void __init omap2_set_globals_243x(void) @@ -92,10 +86,6 @@ static struct omap_globals omap3_globals = { .ctrl = OMAP343X_CTRL_BASE, .prm = OMAP3430_PRM_BASE, .cm = OMAP3430_CM_BASE, - .uart1_phys = OMAP3_UART1_BASE, - .uart2_phys = OMAP3_UART2_BASE, - .uart3_phys = OMAP3_UART3_BASE, - .uart4_phys = OMAP3_UART4_BASE, /* Only on 3630 */ }; void __init omap2_set_globals_3xxx(void) @@ -119,10 +109,6 @@ static struct omap_globals omap4_globals = { .prm = OMAP4430_PRM_BASE, .cm = OMAP4430_CM_BASE, .cm2 = OMAP4430_CM2_BASE, - .uart1_phys = OMAP4_UART1_BASE, - .uart2_phys = OMAP4_UART2_BASE, - .uart3_phys = OMAP4_UART3_BASE, - .uart4_phys = OMAP4_UART4_BASE, }; void __init omap2_set_globals_443x(void) diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 29b2afb..1b8095b 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -56,10 +56,6 @@ struct omap_globals { unsigned long prm; /* Power and Reset Management */ unsigned long cm; /* Clock Management */ unsigned long cm2; - unsigned long uart1_phys; - unsigned long uart2_phys; - unsigned long uart3_phys; - unsigned long uart4_phys; }; void omap2_set_globals_242x(void); -- cgit v0.10.2 From 51d070afd6f927752c76a0cc537c73737578bb93 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 27 Jan 2011 02:52:55 -0700 Subject: OMAP2/3: PM: remove unnecessary wakeup/sleep dependency clear The OMAP2 and OMAP3 PM code clears clockdomain wakeup and sleep dependencies. This is unnecessary after commit 6f7f63cc9adf3192e6fcac4e8bed5cc10fd924aa ("OMAP clockdomain: initialize clockdomain registers when the clockdomain layer starts") which clears these dependencies during clockdomain init. Signed-off-by: Paul Walmsley Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 97feb3a..10f8747 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -363,9 +363,6 @@ static const struct platform_suspend_ops __initdata omap_pm_ops; /* XXX This function should be shareable between OMAP2xxx and OMAP3 */ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) { - clkdm_clear_all_wkdeps(clkdm); - clkdm_clear_all_sleepdeps(clkdm); - if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) omap2_clkdm_allow_idle(clkdm); else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && @@ -411,10 +408,7 @@ static void __init prcm_setup_regs(void) pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); omap2_clkdm_sleep(gfx_clkdm); - /* - * Clear clockdomain wakeup dependencies and enable - * hardware-supervised idle for all clkdms - */ + /* Enable hardware-supervised idle for all clkdms */ clkdm_for_each(clkdms_setup, NULL); clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 6ade4ea..b9427c7 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -695,21 +695,6 @@ static void __init prcm_setup_regs(void) u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ? OMAP3630_GRPSEL_UART4_MASK : 0; - - /* XXX Reset all wkdeps. This should be done when initializing - * powerdomains */ - omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, MPU_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP); - if (omap_rev() > OMAP3430_REV_ES1_0) { - omap2_prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP); - omap2_prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP); - } else - omap2_prm_write_mod_reg(0, GFX_MOD, PM_WKDEP); - /* * Enable interface clock autoidle for all modules. * Note that in the long run this should be done by clockfw -- cgit v0.10.2 From 261bfb286eab32aa6129f48d2b2d24f20825757b Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 11 Feb 2011 20:42:11 +0530 Subject: omap3: pm: Use exported set_cr() instead of a custom one. Remove the custom restore_control_register() and use the exported set_cr() instead to set the system control register(SCTRL) value. No functional change. Signed-off-by: Santosh Shilimkar Cc: Kevin Hilman Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index b9427c7..1883a46 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -311,11 +311,6 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) return IRQ_HANDLED; } -static void restore_control_register(u32 val) -{ - __asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0" : : "r" (val)); -} - /* Function to restore the table entry that was modified for enabling MMU */ static void restore_table_entry(void) { @@ -337,7 +332,7 @@ static void restore_table_entry(void) control_reg_value = __raw_readl(scratchpad_address + OMAP343X_CONTROL_REG_VALUE_OFFSET); /* This will enable caches and prediction */ - restore_control_register(control_reg_value); + set_cr(control_reg_value); } void omap_sram_idle(void) -- cgit v0.10.2 From 8c5ca4d29bf44eb4eb004683ca745742040c7486 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 11 Feb 2011 20:42:12 +0530 Subject: omap3: cpuidle: Add description field to each C-state. Add a description field to each idle C-state. This helps to give better data with PowerTop and one don't have to refer to the code to link what Cx means from system point of view while analysing PowerTop data. No functional change. Signed-off-by: Santosh Shilimkar Cc: Kevin Hilman Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 876eeca..cba437d 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -58,6 +58,7 @@ struct omap3_processor_cx { u32 core_state; u32 threshold; u32 flags; + const char *desc; }; struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; @@ -365,6 +366,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[OMAP3_STATE_C1].desc = "MPU ON + CORE ON"; /* C2 . MPU WFI + Core inactive */ omap3_power_states[OMAP3_STATE_C2].valid = @@ -380,6 +382,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C2].desc = "MPU ON + CORE ON"; /* C3 . MPU CSWR + Core inactive */ omap3_power_states[OMAP3_STATE_C3].valid = @@ -395,6 +398,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C3].desc = "MPU RET + CORE ON"; /* C4 . MPU OFF + Core inactive */ omap3_power_states[OMAP3_STATE_C4].valid = @@ -410,6 +414,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C4].desc = "MPU OFF + CORE ON"; /* C5 . MPU CSWR + Core CSWR*/ omap3_power_states[OMAP3_STATE_C5].valid = @@ -425,6 +430,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET; omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C5].desc = "MPU RET + CORE RET"; /* C6 . MPU OFF + Core CSWR */ omap3_power_states[OMAP3_STATE_C6].valid = @@ -440,6 +446,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET; omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C6].desc = "MPU OFF + CORE RET"; /* C7 . MPU OFF + Core OFF */ omap3_power_states[OMAP3_STATE_C7].valid = @@ -455,6 +462,7 @@ void omap_init_power_states(void) omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF; omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C7].desc = "MPU OFF + CORE OFF"; /* * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot @@ -512,6 +520,7 @@ int __init omap3_idle_init(void) if (cx->type == OMAP3_STATE_C1) dev->safe_state = state; sprintf(state->name, "C%d", count+1); + strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); count++; } -- cgit v0.10.2 From 4071318983ff2dead7fd2caf85498bcd8956d93e Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Tue, 15 Feb 2011 13:28:58 +0530 Subject: OMAP3: PM: Set/clear T2 bit for Smartreflex on TWL Voltage control on TWL can be done using VMODE/I2C1/I2C_SR. Since almost all platforms use I2C_SR on omap3, omap3_twl_init by default expects that OMAP's I2C_SR is plugged in to TWL's I2C and calls omap3_twl_set_sr_bit. On platforms where I2C_SR is not connected, the board files are expected to call omap3_twl_set_sr_bit(false) to ensure that I2C_SR path is not set for voltage control and prevent the default behavior of omap3_twl_init. Signed-off-by: Nishanth Menon Signed-off-by: Thara Gopinath Signed-off-by: Shweta Gulati Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 00e1d2b..b341c36 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -59,8 +59,15 @@ static bool is_offset_valid; static u8 smps_offset; +/* + * Flag to ensure Smartreflex bit in TWL + * being cleared in board file is not overwritten. + */ +static bool __initdata twl_sr_enable_autoinit; +#define TWL4030_DCDC_GLOBAL_CFG 0x06 #define REG_SMPS_OFFSET 0xE0 +#define SMARTREFLEX_ENABLE BIT(3) static unsigned long twl4030_vsel_to_uv(const u8 vsel) { @@ -269,6 +276,18 @@ int __init omap3_twl_init(void) omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX; } + /* + * The smartreflex bit on twl4030 specifies if the setting of voltage + * is done over the I2C_SR path. Since this setting is independent of + * the actual usage of smartreflex AVS module, we enable TWL SR bit + * by default irrespective of whether smartreflex AVS module is enabled + * on the OMAP side or not. This is because without this bit enabled, + * the voltage scaling through vp forceupdate/bypass mechanism of + * voltage scaling will not function on TWL over I2C_SR. + */ + if (!twl_sr_enable_autoinit) + omap3_twl_set_sr_bit(true); + voltdm = omap_voltage_domain_lookup("mpu"); omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info); @@ -277,3 +296,44 @@ int __init omap3_twl_init(void) return 0; } + +/** + * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL + * @enable: enable SR mode in twl or not + * + * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure + * voltage scaling through OMAP SR works. Else, the smartreflex bit + * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but + * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct + * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages, + * in those scenarios this bit is to be cleared (enable = false). + * + * Returns 0 on sucess, error is returned if I2C read/write fails. + */ +int __init omap3_twl_set_sr_bit(bool enable) +{ + u8 temp; + int ret; + if (twl_sr_enable_autoinit) + pr_warning("%s: unexpected multiple calls\n", __func__); + + ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp, + TWL4030_DCDC_GLOBAL_CFG); + if (ret) + goto err; + + if (enable) + temp |= SMARTREFLEX_ENABLE; + else + temp &= ~SMARTREFLEX_ENABLE; + + ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp, + TWL4030_DCDC_GLOBAL_CFG); + if (!ret) { + twl_sr_enable_autoinit = true; + return 0; + } +err: + pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret); + return ret; +} diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 1c1b0ab..f4a5f71 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -127,6 +127,7 @@ static inline void omap_enable_smartreflex_on_init(void) {} #ifdef CONFIG_TWL4030_CORE extern int omap3_twl_init(void); extern int omap4_twl_init(void); +extern int omap3_twl_set_sr_bit(bool enable); #else static inline int omap3_twl_init(void) { -- cgit v0.10.2 From 2de0baefaa7f2fad221bba6049e389e39990e2f0 Mon Sep 17 00:00:00 2001 From: Sanjeev Premi Date: Fri, 25 Feb 2011 18:57:20 +0530 Subject: OMAP3: PM: Initialize IVA only if available IVA device is not present in many OMAP3 variants. This patch ensures that initialization is tied to the presence of IVA on the device. Signed-off-by: Sanjeev Premi Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index d5a102c..6e4eb7f 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -83,7 +83,9 @@ static int _init_omap_device(char *name, struct device **new_dev) static void omap2_init_processor_devices(void) { _init_omap_device("mpu", &mpu_dev); - _init_omap_device("iva", &iva_dev); + if (omap3_has_iva()) + _init_omap_device("iva", &iva_dev); + if (cpu_is_omap44xx()) { _init_omap_device("l3_main_1", &l3_dev); _init_omap_device("dsp", &dsp_dev); -- cgit v0.10.2 From 85243a762457f7891ae525df39ad44323b3eeea6 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:53 +0000 Subject: ARM: omap4: Provide do_wfi() for Thumb-2 For CONFIG_THUMB2_KERNEL, the existing definition of do_wfi() will insert invalid code into the instruction stream. Any assembler which can assemble Thumb-2 is guaranteed to accept the "wfi" mnemonic, so for the Thumb-2 case, just use the mnemonic. The ARM case is left as-is. Signed-off-by: Dave Martin Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h index 5b0270b..de441c0 100644 --- a/arch/arm/mach-omap2/include/mach/omap4-common.h +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h @@ -17,8 +17,12 @@ * wfi used in low power code. Directly opcode is used instead * of instruction to avoid mulit-omap build break */ +#ifdef CONFIG_THUMB2_KERNEL +#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#else #define do_wfi() \ __asm__ __volatile__ (".word 0xe320f003" : : : "memory") +#endif #ifdef CONFIG_CACHE_L2X0 extern void __iomem *l2cache_base; -- cgit v0.10.2 From f96bdfa0d036393741fce303ea98abb44452d042 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:54 +0000 Subject: ARM: omap4: Convert END() to ENDPROC() for correct linkage with CONFIG_THUMB2_KERNEL Code marked with ENTRY() also needs a matching ENDPROC() directive, in order to ensure that the type and instruction set of the symbol are correctly annotated. ENDPROC() tags the affected symbol as a function symbol, which will ensure that link-time fixups don't accidentally switch to the wrong instruction set. Signed-off-by: Dave Martin Tested-by: Santosh Shilimkar Acked-by: Santosh Shilimkar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 6ae937a..4ee6aec 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -45,5 +45,5 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -END(omap_secondary_startup) +ENDPROC(omap_secondary_startup) diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S index 1980dc3..e69d37d 100644 --- a/arch/arm/mach-omap2/omap44xx-smc.S +++ b/arch/arm/mach-omap2/omap44xx-smc.S @@ -29,7 +29,7 @@ ENTRY(omap_smc1) dsb smc #0 ldmfd sp!, {r2-r12, pc} -END(omap_smc1) +ENDPROC(omap_smc1) ENTRY(omap_modify_auxcoreboot0) stmfd sp!, {r1-r12, lr} @@ -37,7 +37,7 @@ ENTRY(omap_modify_auxcoreboot0) dsb smc #0 ldmfd sp!, {r1-r12, pc} -END(omap_modify_auxcoreboot0) +ENDPROC(omap_modify_auxcoreboot0) ENTRY(omap_auxcoreboot_addr) stmfd sp!, {r2-r12, lr} @@ -45,7 +45,7 @@ ENTRY(omap_auxcoreboot_addr) dsb smc #0 ldmfd sp!, {r2-r12, pc} -END(omap_auxcoreboot_addr) +ENDPROC(omap_auxcoreboot_addr) ENTRY(omap_read_auxcoreboot0) stmfd sp!, {r2-r12, lr} @@ -54,4 +54,4 @@ ENTRY(omap_read_auxcoreboot0) smc #0 mov r0, r0, lsr #9 ldmfd sp!, {r2-r12, pc} -END(omap_read_auxcoreboot0) +ENDPROC(omap_read_auxcoreboot0) -- cgit v0.10.2 From 76d500182061dcc7508e6b829af097348fa7d804 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:55 +0000 Subject: ARM: omap3: Remove hand-encoded SMC instructions For various reasons, Linux now only officially supports being built with tools which are new enough to understand the SMC instruction. Replacing the hand-encoded instructions when the mnemonic also allows for correct assembly in Thumb-2 (otherwise, the result is random data in the middle of the code). The Makefile already ensures that this file is built with a high enough gcc -march= flag (armv7-a). Signed-off-by: Dave Martin Tested-by: Santosh Shilimkar Tested-by: Jean Pihet Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 98d8232..a05c348 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -133,7 +133,7 @@ ENTRY(save_secure_ram_context) mov r6, #0xff mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) nop nop nop @@ -408,7 +408,7 @@ skipl2dis: adr r3, l2_inv_api_params @ r3 points to dummy parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) /* Write to Aux control register to set some bits */ mov r0, #42 @ set service ID for PPA mov r12, r0 @ copy secure Service ID in r12 @@ -419,7 +419,7 @@ skipl2dis: ldr r3, [r4, #0xBC] @ r3 points to parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE /* Restore L2 aux control register */ @@ -434,7 +434,7 @@ skipl2dis: adds r3, r3, #8 @ r3 points to parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) #endif b logic_l1_restore @@ -443,18 +443,18 @@ l2_inv_api_params: l2_inv_gp: /* Execute smi to invalidate L2 cache */ mov r12, #0x1 @ set up to invalidate L2 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) /* Write to Aux control register to set some bits */ ldr r4, scratchpad_base ldr r3, [r4,#0xBC] ldr r0, [r3,#4] mov r12, #0x3 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) ldr r4, scratchpad_base ldr r3, [r4,#0xBC] ldr r0, [r3,#12] mov r12, #0x2 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) logic_l1_restore: ldr r1, l2dis_3630 cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 -- cgit v0.10.2 From ef7a87d34064eb87866d02547ee67060e5e49eb9 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:56 +0000 Subject: ARM: omap3: Thumb-2 compatibility for sram34xx.S * Build unconditionally as ARM for correct interoperation with OMAP firmware. * Remove deprecated PC-relative stores * Add the required ENDPROC() directive for each ENTRY(). * .align before data words Signed-off-by: Dave Martin Tested-by: Jean Pihet Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 7f893a2..1078bfb 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -34,6 +34,12 @@ #include "sdrc.h" #include "cm2xxx_3xxx.h" +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm + .text /* r1 parameters */ @@ -116,24 +122,36 @@ ENTRY(omap3_sram_configure_core_dpll) @ pull the extra args off the stack @ and store them in SRAM + +/* + * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour + * in Thumb-2: use a r7 as a base instead. + * Be careful not to clobber r7 when maintaing this file. + */ + THUMB( adr r7, omap3_sram_configure_core_dpll ) + .macro strtext Rt:req, label:req + ARM( str \Rt, \label ) + THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] ) + .endm + ldr r4, [sp, #52] - str r4, omap_sdrc_rfr_ctrl_0_val + strtext r4, omap_sdrc_rfr_ctrl_0_val ldr r4, [sp, #56] - str r4, omap_sdrc_actim_ctrl_a_0_val + strtext r4, omap_sdrc_actim_ctrl_a_0_val ldr r4, [sp, #60] - str r4, omap_sdrc_actim_ctrl_b_0_val + strtext r4, omap_sdrc_actim_ctrl_b_0_val ldr r4, [sp, #64] - str r4, omap_sdrc_mr_0_val + strtext r4, omap_sdrc_mr_0_val ldr r4, [sp, #68] - str r4, omap_sdrc_rfr_ctrl_1_val + strtext r4, omap_sdrc_rfr_ctrl_1_val cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, beq skip_cs1_params @ do not use cs1 params ldr r4, [sp, #72] - str r4, omap_sdrc_actim_ctrl_a_1_val + strtext r4, omap_sdrc_actim_ctrl_a_1_val ldr r4, [sp, #76] - str r4, omap_sdrc_actim_ctrl_b_1_val + strtext r4, omap_sdrc_actim_ctrl_b_1_val ldr r4, [sp, #80] - str r4, omap_sdrc_mr_1_val + strtext r4, omap_sdrc_mr_1_val skip_cs1_params: mrc p15, 0, r8, c1, c0, 0 @ read ctrl register bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction @@ -271,6 +289,7 @@ skip_cs1_prog: ldr r12, [r11] @ posted-write barrier for SDRC bx lr + .align omap3_sdrc_power: .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) omap3_cm_clksel1_pll: @@ -319,6 +338,7 @@ omap3_sdrc_dlla_ctrl: .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) core_m2_mask_val: .word 0x07FFFFFF +ENDPROC(omap3_sram_configure_core_dpll) ENTRY(omap3_sram_configure_core_dpll_sz) .word . - omap3_sram_configure_core_dpll -- cgit v0.10.2 From dd31394779aa288eb6b9c42672ffcb6d05d6c414 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Fri, 4 Mar 2011 15:33:57 +0000 Subject: ARM: omap3: Thumb-2 compatibility for sleep34xx.S * Build unconditionally as ARM for correct interoperation with OMAP firmware. * Fix an out-of-range ADR when building for ARM. * Remove deprecated PC-relative stores. * Add the required ENDPROC() directive for each ENTRY(). * .align before data words. * Handle non-interworking return from v7_flush_dcache_all. Signed-off-by: Dave Martin Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index a05c348..0c1b335 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -64,6 +64,11 @@ #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm /* * API functions @@ -82,6 +87,8 @@ ENTRY(get_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_restore_pointer) + .align ENTRY(get_restore_pointer_sz) .word . - get_restore_pointer @@ -91,6 +98,8 @@ ENTRY(get_omap3630_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore_3630 ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_omap3630_restore_pointer) + .align ENTRY(get_omap3630_restore_pointer_sz) .word . - get_omap3630_restore_pointer @@ -100,6 +109,8 @@ ENTRY(get_es3_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore_es3 ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_es3_restore_pointer) + .align ENTRY(get_es3_restore_pointer_sz) .word . - get_es3_restore_pointer @@ -113,8 +124,10 @@ ENTRY(enable_omap3630_toggle_l2_on_restore) stmfd sp!, {lr} @ save registers on stack /* Setup so that we will disable and enable l2 */ mov r1, #0x1 - str r1, l2dis_3630 + adrl r2, l2dis_3630 @ may be too distant for plain adr + str r1, [r2] ldmfd sp!, {pc} @ restore regs and return +ENDPROC(enable_omap3630_toggle_l2_on_restore) .text /* Function to call rom code to save secure ram context */ @@ -139,12 +152,14 @@ ENTRY(save_secure_ram_context) nop nop ldmfd sp!, {r1-r12, pc} + .align sram_phy_addr_mask: .word SRAM_BASE_P high_mask: .word 0xffff api_params: .word 0x4, 0x0, 0x0, 0x1, 0x1 +ENDPROC(save_secure_ram_context) ENTRY(save_secure_ram_context_sz) .word . - save_secure_ram_context @@ -279,8 +294,18 @@ clean_l2: * - 'might' have to copy address, load and jump to it */ ldr r1, kernel_flush - mov lr, pc - bx r1 + blx r1 + /* + * The kernel doesn't interwork: v7_flush_dcache_all in particluar will + * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. + * This sequence switches back to ARM. Note that .align may insert a + * nop: bx pc needs to be word-aligned in order to work. + */ + THUMB( .thumb ) + THUMB( .align ) + THUMB( bx pc ) + THUMB( nop ) + .arm omap3_do_wfi: ldr r4, sdrc_power @ read the SDRC_POWER register @@ -438,6 +463,7 @@ skipl2dis: #endif b logic_l1_restore + .align l2_inv_api_params: .word 0x1, 0x00 l2_inv_gp: @@ -607,6 +633,7 @@ usettbr0: /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ .text + .align 3 ENTRY(es3_sdrc_fix) ldr r4, sdrc_syscfg @ get config addr ldr r5, [r4] @ get value @@ -634,6 +661,7 @@ ENTRY(es3_sdrc_fix) str r5, [r4] @ kick off refreshes bx lr + .align sdrc_syscfg: .word SDRC_SYSCONFIG_P sdrc_mr_0: @@ -648,6 +676,7 @@ sdrc_emr2_1: .word SDRC_EMR2_1_P sdrc_manual_1: .word SDRC_MANUAL_1_P +ENDPROC(es3_sdrc_fix) ENTRY(es3_sdrc_fix_sz) .word . - es3_sdrc_fix @@ -682,6 +711,12 @@ wait_sdrc_ready: bic r5, r5, #0x40 str r5, [r4] +/* + * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a + * base instead. + * Be careful not to clobber r7 when maintaing this code. + */ + is_dll_in_lock_mode: /* Is dll in lock mode? */ ldr r4, sdrc_dlla_ctrl @@ -689,10 +724,11 @@ is_dll_in_lock_mode: tst r5, #0x4 bxne lr @ Return if locked /* wait till dll locks */ + adr r7, kick_counter wait_dll_lock_timed: ldr r4, wait_dll_lock_counter add r4, r4, #1 - str r4, wait_dll_lock_counter + str r4, [r7, #wait_dll_lock_counter - kick_counter] ldr r4, sdrc_dlla_status /* Wait 20uS for lock */ mov r6, #8 @@ -718,9 +754,10 @@ kick_dll: dsb ldr r4, kick_counter add r4, r4, #1 - str r4, kick_counter + str r4, [r7] @ kick_counter b wait_dll_lock_timed + .align cm_idlest1_core: .word CM_IDLEST1_CORE_V cm_idlest_ckgen: @@ -763,6 +800,7 @@ kick_counter: .word 0 wait_dll_lock_counter: .word 0 +ENDPROC(omap34xx_cpu_suspend) ENTRY(omap34xx_cpu_suspend_sz) .word . - omap34xx_cpu_suspend -- cgit v0.10.2 From b1ace38094c4926255343a81faba8fb4faf59a45 Mon Sep 17 00:00:00 2001 From: Anand S Sawant Date: Thu, 17 Feb 2011 21:27:30 +0530 Subject: OMAP2+: smartreflex: remove SR debug directory in omap_sr_remove() omap_sr_probe() creates the smartreflex debug directory and its underlying nvalue debug directory. These directories are removed in omap_sr_remove(). Basic smartreflex functionality tested on OMAP3630 Zoom3 & OMAP4430 SDP Signed-off-by: Anand S Sawant Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index b57ae50..0ab4dd5 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -54,6 +54,7 @@ struct omap_sr { struct list_head node; struct omap_sr_nvalue_table *nvalue_table; struct voltagedomain *voltdm; + struct dentry *dbg_dir; }; /* sr_list contains all the instances of smartreflex module */ @@ -823,7 +824,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; - struct dentry *vdd_dbg_dir, *dbg_dir, *nvalue_dir; + struct dentry *vdd_dbg_dir, *nvalue_dir; struct omap_volt_data *volt_data; int i, ret = 0; @@ -898,24 +899,24 @@ static int __init omap_sr_probe(struct platform_device *pdev) goto err_release_region; } - dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); - if (IS_ERR(dbg_dir)) { + sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); + if (IS_ERR(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); - ret = PTR_ERR(dbg_dir); + ret = PTR_ERR(sr_info->dbg_dir); goto err_release_region; } - (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, dbg_dir, - (void *)sr_info, &pm_sr_fops); - (void) debugfs_create_x32("errweight", S_IRUGO, dbg_dir, + (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, + sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops); + (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, &sr_info->err_weight); - (void) debugfs_create_x32("errmaxlimit", S_IRUGO, dbg_dir, + (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, &sr_info->err_maxlimit); - (void) debugfs_create_x32("errminlimit", S_IRUGO, dbg_dir, + (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir, &sr_info->err_minlimit); - nvalue_dir = debugfs_create_dir("nvalue", dbg_dir); + nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); if (IS_ERR(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); @@ -972,6 +973,8 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) if (sr_info->autocomp_active) sr_stop_vddautocomp(sr_info); + if (sr_info->dbg_dir) + debugfs_remove_recursive(sr_info->dbg_dir); list_del(&sr_info->node); iounmap(sr_info->base); -- cgit v0.10.2 From 4444d712fd5b31f2348b57eaa2bbdc5e68c4e1b6 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 19:00:34 +0530 Subject: OMAP3: PM: Use ARMv7 supported instructions instead of legacy CP15 ones On ARMv7 dsb, dmb instructions are supported and can be used directly instead of their cp15 equivalnet. Also remove the opcodes for smc and use the available instruction directly in OMAP3 low power asm code Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 0c1b335..1c17ee81 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -144,8 +144,8 @@ ENTRY(save_secure_ram_context) mov r1, #0 @ set task id for ROM code in r1 mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) nop nop @@ -314,9 +314,8 @@ omap3_do_wfi: str r5, [r4] @ write back to SDRC_POWER register /* Data memory barrier and Data sync barrier */ - mov r1, #0 - mcr p15, 0, r1, c7, c10, 4 - mcr p15, 0, r1, c7, c10, 5 + dsb + dmb /* * =================================== @@ -431,8 +430,8 @@ skipl2dis: mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff adr r3, l2_inv_api_params @ r3 points to dummy parameters - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) /* Write to Aux control register to set some bits */ mov r0, #42 @ set service ID for PPA @@ -442,8 +441,8 @@ skipl2dis: mov r6, #0xff ldr r4, scratchpad_base ldr r3, [r4, #0xBC] @ r3 points to parameters - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE @@ -457,8 +456,8 @@ skipl2dis: ldr r4, scratchpad_base ldr r3, [r4, #0xBC] adds r3, r3, #8 @ r3 points to parameters - mcr p15, 0, r0, c7, c10, 4 @ data write barrier - mcr p15, 0, r0, c7, c10, 5 @ data memory barrier + dsb @ data write barrier + dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) #endif b logic_l1_restore -- cgit v0.10.2 From 8409d57bc342536ffe96acc7cd6c7575d98d3edb Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 16:04:39 +0530 Subject: OMAP3: PM: Fix the MMU on sequence in the asm code Add necessary barriers after enabling MMU. Also use the sane way to load pc and jump to it instead of executing ldma first up. Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 1c17ee81..a31845a 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -617,12 +617,17 @@ usettbr0: ldr r2, cache_pred_disable_mask and r4, r2 mcr p15, 0, r4, c1, c0, 0 + dsb + isb + ldr r0, =restoremmu_on + bx r0 /* * ============================== * == Exit point from OFF mode == * ============================== */ +restoremmu_on: ldmfd sp!, {r0-r12, pc} @ restore regs and return -- cgit v0.10.2 From c9749a352383d4d2d25eb28062afd1a7eee115b7 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 19:33:53 +0530 Subject: OMAP3: PM: Allow the cache clean when L1 is lost. When L1 cache is suppose to be lost, it needs to be cleaned before entrering to the low power mode. While at this, also fix few comments and remove un-necessary clean_l2 lable. Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index a31845a..f75a166 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -188,12 +188,12 @@ ENTRY(omap34xx_cpu_suspend) stmfd sp!, {r0-r12, lr} @ save registers on stack /* - * r0 contains restore pointer in sdram + * r0 contains CPU context save/restore pointer in sdram * r1 contains information about saving context: * 0 - No context lost * 1 - Only L1 and logic lost - * 2 - Only L2 lost - * 3 - Both L1 and L2 lost + * 2 - Only L2 lost (Even L1 is retained we clean it along with L2) + * 3 - Both L1 and L2 lost and logic lost */ /* Directly jump to WFI is the context save is not required */ @@ -278,15 +278,6 @@ l1_logic_lost: clean_caches: /* - * Clean Data or unified cache to POU - * How to invalidate only L1 cache???? - #FIX_ME# - * mcr p15, 0, r11, c7, c11, 1 - */ - cmp r1, #0x1 @ Check whether L2 inval is required - beq omap3_do_wfi - -clean_l2: - /* * jump out to kernel flush routine * - reuse that code is better * - it executes in a cached space so is faster than refetch per-block -- cgit v0.10.2 From 46f557cb453b9f3b6dc36b8179c2c36932a2ea64 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 21:37:03 +0530 Subject: OMAP3: PM: Remove un-necessary cp15 registers form low power cpu context The current code saves few un-necessary registers which are read-only or write-only, unused CP15 registers. Remove them and keep only necessary CP15 registers part of low power context save/restore. Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index f75a166..99e43cc 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -214,66 +214,29 @@ save_context_wfi: beq clean_caches l1_logic_lost: - /* Store sp and spsr to SDRAM */ - mov r4, sp - mrs r5, spsr - mov r6, lr + mov r4, sp @ Store sp + mrs r5, spsr @ Store spsr + mov r6, lr @ Store lr stmia r8!, {r4-r6} - /* Save all ARM registers */ - /* Coprocessor access control register */ - mrc p15, 0, r6, c1, c0, 2 - stmia r8!, {r6} - /* TTBR0, TTBR1 and Translation table base control */ - mrc p15, 0, r4, c2, c0, 0 - mrc p15, 0, r5, c2, c0, 1 - mrc p15, 0, r6, c2, c0, 2 - stmia r8!, {r4-r6} - /* - * Domain access control register, data fault status register, - * and instruction fault status register - */ - mrc p15, 0, r4, c3, c0, 0 - mrc p15, 0, r5, c5, c0, 0 - mrc p15, 0, r6, c5, c0, 1 - stmia r8!, {r4-r6} - /* - * Data aux fault status register, instruction aux fault status, - * data fault address register and instruction fault address register - */ - mrc p15, 0, r4, c5, c1, 0 - mrc p15, 0, r5, c5, c1, 1 - mrc p15, 0, r6, c6, c0, 0 - mrc p15, 0, r7, c6, c0, 2 - stmia r8!, {r4-r7} - /* - * user r/w thread and process ID, user r/o thread and process ID, - * priv only thread and process ID, cache size selection - */ - mrc p15, 0, r4, c13, c0, 2 - mrc p15, 0, r5, c13, c0, 3 - mrc p15, 0, r6, c13, c0, 4 - mrc p15, 2, r7, c0, c0, 0 + + mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register + mrc p15, 0, r5, c2, c0, 0 @ TTBR0 + mrc p15, 0, r6, c2, c0, 1 @ TTBR1 + mrc p15, 0, r7, c2, c0, 2 @ TTBCR stmia r8!, {r4-r7} - /* Data TLB lockdown, instruction TLB lockdown registers */ - mrc p15, 0, r5, c10, c0, 0 - mrc p15, 0, r6, c10, c0, 1 - stmia r8!, {r5-r6} - /* Secure or non secure vector base address, FCSE PID, Context PID*/ - mrc p15, 0, r4, c12, c0, 0 - mrc p15, 0, r5, c13, c0, 0 - mrc p15, 0, r6, c13, c0, 1 - stmia r8!, {r4-r6} - /* Primary remap, normal remap registers */ - mrc p15, 0, r4, c10, c2, 0 - mrc p15, 0, r5, c10, c2, 1 - stmia r8!,{r4-r5} - /* Store current cpsr*/ - mrs r2, cpsr - stmia r8!, {r2} + mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register + mrc p15, 0, r5, c10, c2, 0 @ PRRR + mrc p15, 0, r6, c10, c2, 1 @ NMRR + stmia r8!,{r4-r6} + + mrc p15, 0, r4, c13, c0, 1 @ Context ID + mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID + mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address + mrs r7, cpsr @ Store current cpsr + stmia r8!, {r4-r7} - mrc p15, 0, r4, c1, c0, 0 - /* save control register */ + mrc p15, 0, r4, c1, c0, 0 @ save control register stmia r8!, {r4} clean_caches: @@ -489,68 +452,29 @@ skipl2reen: ldr r4, scratchpad_base ldr r3, [r4,#0xBC] adds r3, r3, #16 + ldmia r3!, {r4-r6} - mov sp, r4 - msr spsr_cxsf, r5 - mov lr, r6 - - ldmia r3!, {r4-r9} - /* Coprocessor access Control Register */ - mcr p15, 0, r4, c1, c0, 2 - - /* TTBR0 */ - MCR p15, 0, r5, c2, c0, 0 - /* TTBR1 */ - MCR p15, 0, r6, c2, c0, 1 - /* Translation table base control register */ - MCR p15, 0, r7, c2, c0, 2 - /* Domain access Control Register */ - MCR p15, 0, r8, c3, c0, 0 - /* Data fault status Register */ - MCR p15, 0, r9, c5, c0, 0 - - ldmia r3!,{r4-r8} - /* Instruction fault status Register */ - MCR p15, 0, r4, c5, c0, 1 - /* Data Auxiliary Fault Status Register */ - MCR p15, 0, r5, c5, c1, 0 - /* Instruction Auxiliary Fault Status Register*/ - MCR p15, 0, r6, c5, c1, 1 - /* Data Fault Address Register */ - MCR p15, 0, r7, c6, c0, 0 - /* Instruction Fault Address Register*/ - MCR p15, 0, r8, c6, c0, 2 - ldmia r3!,{r4-r7} + mov sp, r4 @ Restore sp + msr spsr_cxsf, r5 @ Restore spsr + mov lr, r6 @ Restore lr - /* User r/w thread and process ID */ - MCR p15, 0, r4, c13, c0, 2 - /* User ro thread and process ID */ - MCR p15, 0, r5, c13, c0, 3 - /* Privileged only thread and process ID */ - MCR p15, 0, r6, c13, c0, 4 - /* Cache size selection */ - MCR p15, 2, r7, c0, c0, 0 - ldmia r3!,{r4-r8} - /* Data TLB lockdown registers */ - MCR p15, 0, r4, c10, c0, 0 - /* Instruction TLB lockdown registers */ - MCR p15, 0, r5, c10, c0, 1 - /* Secure or Nonsecure Vector Base Address */ - MCR p15, 0, r6, c12, c0, 0 - /* FCSE PID */ - MCR p15, 0, r7, c13, c0, 0 - /* Context PID */ - MCR p15, 0, r8, c13, c0, 1 - - ldmia r3!,{r4-r5} - /* Primary memory remap register */ - MCR p15, 0, r4, c10, c2, 0 - /* Normal memory remap register */ - MCR p15, 0, r5, c10, c2, 1 - - /* Restore cpsr */ - ldmia r3!,{r4} @ load CPSR from SDRAM - msr cpsr, r4 @ store cpsr + ldmia r3!, {r4-r7} + mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register + mcr p15, 0, r5, c2, c0, 0 @ TTBR0 + mcr p15, 0, r6, c2, c0, 1 @ TTBR1 + mcr p15, 0, r7, c2, c0, 2 @ TTBCR + + ldmia r3!,{r4-r6} + mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register + mcr p15, 0, r5, c10, c2, 0 @ PRRR + mcr p15, 0, r6, c10, c2, 1 @ NMRR + + + ldmia r3!,{r4-r7} + mcr p15, 0, r4, c13, c0, 1 @ Context ID + mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID + mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address + msr cpsr, r7 @ store cpsr /* Enabling MMU here */ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl -- cgit v0.10.2 From 9062511097683b4422f023d181b4a8b2db1a7a72 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 23 Jan 2011 22:51:09 +0530 Subject: OMAP3: PM: Clear the SCTLR C bit in asm code to prevent data cache allocation On the newer ARM processors like CortexA8, CortexA9, the caches can be speculatively loaded while they are getting flushed. Clear the SCTLR C bit to prevent further data cache allocation as part of cache clean routine Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 99e43cc..e60ac1f 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -246,6 +246,27 @@ clean_caches: * - it executes in a cached space so is faster than refetch per-block * - should be faster and will change with kernel * - 'might' have to copy address, load and jump to it + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + ldr r1, kernel_flush + mov lr, pc + bx r1 + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* + * Invalidate L1 data cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. */ ldr r1, kernel_flush blx r1 @@ -295,6 +316,12 @@ omap3_do_wfi: nop bl wait_sdrc_ok + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared + mcreq p15, 0, r0, c1, c0, 0 + isb + /* * =================================== * == Exit point from non-OFF modes == -- cgit v0.10.2