From afe48049ab1d0ca83afe45f9d5116bf4507741eb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 17 Jun 2011 08:21:10 +0000 Subject: [PATCH 001/249] ARM: mach-shmobile: sh7372: Add USB-DMAC support Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/clock-sh7372.c | 5 +- arch/arm/mach-shmobile/include/mach/sh7372.h | 4 + arch/arm/mach-shmobile/setup-sh7372.c | 146 +++++++++++++++++++ 3 files changed, 154 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index c0800d83971e..c239ab10c95b 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -509,7 +509,7 @@ enum { MSTP001, MSTP118, MSTP117, MSTP116, MSTP113, MSTP106, MSTP101, MSTP100, MSTP223, - MSTP218, MSTP217, MSTP216, + MSTP214, MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, @@ -538,6 +538,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ + [MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ @@ -633,6 +634,8 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */ + CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */ + CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP214]), /* USB-DMAC1 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index df20d7670172..51db9d3a2cac 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -458,6 +458,10 @@ enum { SHDMA_SLAVE_SDHI2_TX, SHDMA_SLAVE_MMCIF_RX, SHDMA_SLAVE_MMCIF_TX, + SHDMA_SLAVE_USB0_TX, + SHDMA_SLAVE_USB0_RX, + SHDMA_SLAVE_USB1_TX, + SHDMA_SLAVE_USB1_RX, }; extern struct clk sh7372_extal1_clk; diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index cd807eea69e2..f2a58d48bfb4 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -602,6 +602,150 @@ static struct platform_device dma2_device = { }, }; +/* + * USB-DMAC + */ + +unsigned int usbts_shift[] = {3, 4, 5}; + +enum { + XMIT_SZ_8BYTE = 0, + XMIT_SZ_16BYTE = 1, + XMIT_SZ_32BYTE = 2, +}; + +#define USBTS_INDEX2VAL(i) (((i) & 3) << 6) + +static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = { + { + .offset = 0, + }, { + .offset = 0x20, + }, +}; + +/* USB DMAC0 */ +static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = { + { + .slave_id = SHDMA_SLAVE_USB0_TX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, { + .slave_id = SHDMA_SLAVE_USB0_RX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, +}; + +static struct sh_dmae_pdata usb_dma0_platform_data = { + .slave = sh7372_usb_dmae0_slaves, + .slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves), + .channel = sh7372_usb_dmae_channels, + .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), + .ts_low_shift = 6, + .ts_low_mask = 0xc0, + .ts_high_shift = 0, + .ts_high_mask = 0, + .ts_shift = usbts_shift, + .ts_shift_num = ARRAY_SIZE(usbts_shift), + .dmaor_init = DMAOR_DME, + .chcr_offset = 0x14, + .chcr_ie_bit = 1 << 5, + .dmaor_is_32bit = 1, + .needs_tend_set = 1, + .no_dmars = 1, +}; + +static struct resource sh7372_usb_dmae0_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xe68a0020, + .end = 0xe68a0064 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* VCR/SWR/DMICR */ + .start = 0xe68a0000, + .end = 0xe68a0014 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* IRQ for channels */ + .start = evt2irq(0x0a00), + .end = evt2irq(0x0a00), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb_dma0_device = { + .name = "sh-dma-engine", + .id = 3, + .resource = sh7372_usb_dmae0_resources, + .num_resources = ARRAY_SIZE(sh7372_usb_dmae0_resources), + .dev = { + .platform_data = &usb_dma0_platform_data, + }, +}; + +/* USB DMAC1 */ +static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = { + { + .slave_id = SHDMA_SLAVE_USB1_TX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, { + .slave_id = SHDMA_SLAVE_USB1_RX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, +}; + +static struct sh_dmae_pdata usb_dma1_platform_data = { + .slave = sh7372_usb_dmae1_slaves, + .slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves), + .channel = sh7372_usb_dmae_channels, + .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), + .ts_low_shift = 6, + .ts_low_mask = 0xc0, + .ts_high_shift = 0, + .ts_high_mask = 0, + .ts_shift = usbts_shift, + .ts_shift_num = ARRAY_SIZE(usbts_shift), + .dmaor_init = DMAOR_DME, + .chcr_offset = 0x14, + .chcr_ie_bit = 1 << 5, + .dmaor_is_32bit = 1, + .needs_tend_set = 1, + .no_dmars = 1, +}; + +static struct resource sh7372_usb_dmae1_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xe68c0020, + .end = 0xe68c0064 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* VCR/SWR/DMICR */ + .start = 0xe68c0000, + .end = 0xe68c0014 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* IRQ for channels */ + .start = evt2irq(0x1d00), + .end = evt2irq(0x1d00), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb_dma1_device = { + .name = "sh-dma-engine", + .id = 4, + .resource = sh7372_usb_dmae1_resources, + .num_resources = ARRAY_SIZE(sh7372_usb_dmae1_resources), + .dev = { + .platform_data = &usb_dma1_platform_data, + }, +}; + /* VPU */ static struct uio_info vpu_platform_data = { .name = "VPU5HG", @@ -829,6 +973,8 @@ static struct platform_device *sh7372_late_devices[] __initdata = { &dma0_device, &dma1_device, &dma2_device, + &usb_dma0_device, + &usb_dma1_device, &vpu_device, &veu0_device, &veu1_device, From 0ed61fc9da59ea45d56a6928653691cef14bab9b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 30 Jun 2011 09:22:50 +0000 Subject: [PATCH 002/249] ARM: mach-shmobile: Use CMT2 for timer on sh7372 Switch the sh7372 CPU support to use CMT2 instead of CMT1 for system timer. CMT1 is located in the A3SP power domain while CMT2 is located in the always-on power domain C5. This improves our PM situation - with CMT2 as timer we can power down A3SP and still access the timer. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/clock-sh7372.c | 8 +++---- arch/arm/mach-shmobile/setup-sh7372.c | 30 +++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index c0800d83971e..7fb1d2e52540 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -511,8 +511,8 @@ enum { MSTP001, MSTP223, MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, - MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, - MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, + MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, + MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, MSTP400, MSTP_NR }; #define MSTP(_parent, _reg, _bit, _flags) \ @@ -545,7 +545,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ - [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ @@ -559,6 +558,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ + [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */ }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } @@ -640,7 +640,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ - CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ @@ -658,6 +657,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ + CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */ CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index cd807eea69e2..cb8ac7845245 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -169,35 +169,35 @@ static struct platform_device scif6_device = { }; /* CMT */ -static struct sh_timer_config cmt10_platform_data = { - .name = "CMT10", - .channel_offset = 0x10, - .timer_bit = 0, +static struct sh_timer_config cmt2_platform_data = { + .name = "CMT2", + .channel_offset = 0x40, + .timer_bit = 5, .clockevent_rating = 125, .clocksource_rating = 125, }; -static struct resource cmt10_resources[] = { +static struct resource cmt2_resources[] = { [0] = { - .name = "CMT10", - .start = 0xe6138010, - .end = 0xe613801b, + .name = "CMT2", + .start = 0xe6130040, + .end = 0xe613004b, .flags = IORESOURCE_MEM, }, [1] = { - .start = evt2irq(0x0b00), /* CMT1_CMT10 */ + .start = evt2irq(0x0b80), /* CMT2 */ .flags = IORESOURCE_IRQ, }, }; -static struct platform_device cmt10_device = { +static struct platform_device cmt2_device = { .name = "sh_cmt", - .id = 10, + .id = 2, .dev = { - .platform_data = &cmt10_platform_data, + .platform_data = &cmt2_platform_data, }, - .resource = cmt10_resources, - .num_resources = ARRAY_SIZE(cmt10_resources), + .resource = cmt2_resources, + .num_resources = ARRAY_SIZE(cmt2_resources), }; /* TMU */ @@ -818,7 +818,7 @@ static struct platform_device *sh7372_early_devices[] __initdata = { &scif4_device, &scif5_device, &scif6_device, - &cmt10_device, + &cmt2_device, &tmu00_device, &tmu01_device, }; From b8e513a2ecafb5bb068c00be98d584871afcd4c3 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 9 Jul 2011 21:11:14 +0000 Subject: [PATCH 003/249] ARM: static should be at beginning of declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the 'static' keywork is at the beginning of declaration for arch/arm/mach-shmobile/board-ap4evb.c This gets rid of warnings like warning: ‘static’ is not at beginning of declaration when building with -Wold-style-declaration (and/or -Wextra which also enables it). Signed-off-by: Jesper Juhl Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/board-ap4evb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 803bc6edfca4..bb4e084920b8 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -443,7 +443,7 @@ static struct platform_device usb1_host_device = { .resource = usb1_host_resources, }; -const static struct fb_videomode ap4evb_lcdc_modes[] = { +static const struct fb_videomode ap4evb_lcdc_modes[] = { { #ifdef CONFIG_AP4EVB_QHD .name = "R63302(QHD)", From 3f7e5e2423f6233f7665d54061ba7761ca90cf52 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 13 Jul 2011 07:59:48 +0000 Subject: [PATCH 004/249] clocksource: sh_cmt: wait for CMCNT on init V2 Add code to the CMT driver to wait for CMCNT V2. This to let the register value settle before starting the timer channel. Makes the driver more robust. Needed for CMT2 on sh7372 and certain CMT channels on sh73a0. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index dc7c033ef587..32a77becc098 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -150,13 +151,13 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) { - int ret; + int k, ret; /* enable clock */ ret = clk_enable(p->clk); if (ret) { dev_err(&p->pdev->dev, "cannot enable clock\n"); - return ret; + goto err0; } /* make sure channel is disabled */ @@ -174,9 +175,38 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) sh_cmt_write(p, CMCOR, 0xffffffff); sh_cmt_write(p, CMCNT, 0); + /* + * According to the sh73a0 user's manual, as CMCNT can be operated + * only by the RCLK (Pseudo 32 KHz), there's one restriction on + * modifying CMCNT register; two RCLK cycles are necessary before + * this register is either read or any modification of the value + * it holds is reflected in the LSI's actual operation. + * + * While at it, we're supposed to clear out the CMCNT as of this + * moment, so make sure it's processed properly here. This will + * take RCLKx2 at maximum. + */ + for (k = 0; k < 100; k++) { + if (!sh_cmt_read(p, CMCNT)) + break; + udelay(1); + } + + if (sh_cmt_read(p, CMCNT)) { + dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); + ret = -ETIMEDOUT; + goto err1; + } + /* enable channel */ sh_cmt_start_stop_ch(p, 1); return 0; + err1: + /* stop clock */ + clk_disable(p->clk); + + err0: + return ret; } static void sh_cmt_disable(struct sh_cmt_priv *p) From b4300b72cfc01ea75b8aaede574bdfb04545d691 Mon Sep 17 00:00:00 2001 From: David Engraf Date: Wed, 20 Jul 2011 13:03:39 +0000 Subject: [PATCH 005/249] shwdt: fix usage of mod_timer This patch fixes the usage of mod_timer and makes the driver usable. mod_timer must be called with an absolute timeout in jiffies, the old implementation used a relative timeout thus the hardware watchdog was never triggered. Signed-off-by: David Engraf Signed-off-by: Paul Mundt --- drivers/watchdog/shwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index db84f2322d1a..a267dc078daf 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -64,7 +64,7 @@ * misses its deadline, the kernel timer will allow the WDT to overflow. */ static int clock_division_ratio = WTCSR_CKS_4096; -#define next_ping_period(cks) msecs_to_jiffies(cks - 4) +#define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) static const struct watchdog_info sh_wdt_info; static struct platform_device *sh_wdt_dev; From 9a14a92c939aea1aaf27f5ad37b26b235acc2a65 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 15 Jul 2011 10:58:55 +0000 Subject: [PATCH 006/249] sh: intc: enable both edges GPIO interrupts on sh7372 IRQ-capable GPIOs on sh7372 can be configured to produce interrupts on both edges. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/sh/intc/chip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index f33e2dd97934..33b2ed451e09 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -186,6 +186,9 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { !defined(CONFIG_CPU_SUBTYPE_SH7709) [IRQ_TYPE_LEVEL_HIGH] = VALID(3), #endif +#if defined(CONFIG_ARCH_SH7372) + [IRQ_TYPE_EDGE_BOTH] = VALID(4), +#endif }; static int intc_set_type(struct irq_data *data, unsigned int type) From c5ad48f3117c4aae379b536f3270fc1efae945c0 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 20 Jun 2011 23:00:12 +0000 Subject: [PATCH 007/249] ARM: mach-shmobile: ag5evm: SDHI requires waiting for idle The SDHI block on the ag5evm requires waiting for idle before writing to some registers. Cc: Guennadi Liakhovetski Cc: Magnus Damm Signed-off-by: Simon Horman Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/board-ag5evm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index ce5c2513c6ce..cdfdd624d21d 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -341,6 +341,7 @@ static struct platform_device mipidsi0_device = { static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, }; @@ -382,7 +383,7 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) } static struct sh_mobile_sdhi_info sh_sdhi1_info = { - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, + .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .set_pwr = ag5evm_sdhi1_set_pwr, From ad75b88ac3792ae6a541d9b9fa84e379bd0b29dd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 3 Aug 2011 12:33:20 +0900 Subject: [PATCH 008/249] serial: sh-sci: Fix up default regtype probing. Presently the default regtype probing inadvertently bails out due to an inverted error check. This fixes it up, and gets platforms without explicit regtype specifications working again. Reported-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d0a56235c50e..522f69d3c8ae 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1889,7 +1889,7 @@ static int __devinit sci_init_single(struct platform_device *dev, if (p->regtype == SCIx_PROBE_REGTYPE) { ret = sci_probe_regmap(p); - if (unlikely(!ret)) + if (unlikely(ret != 0)) return ret; } From 5beabc7fcd99856084e232b37d3280ce353eaf41 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 2 Aug 2011 09:42:54 +0000 Subject: [PATCH 009/249] serial: sh-sci: fix DMA build by including dma-mapping.h Include dma-mapping.h to fix build of the sh-sci driver on SH-Mobile ARM (sh73a0) when CONFIG_SERIAL_SH_SCI_DMA=y: drivers/tty/serial/sh-sci.c: In function 'sci_rx_dma_release': drivers/tty/serial/sh-sci.c:1182:3: error: implicit declaration of function 'dma_free_coherent' drivers/tty/serial/sh-sci.c: In function 'work_fn_tx': drivers/tty/serial/sh-sci.c:1333:2: error: implicit declaration of function 'dma_sync_sg_for_device' drivers/tty/serial/sh-sci.c: In function 'sci_request_dma': drivers/tty/serial/sh-sci.c:1498:3: error: implicit declaration of function 'dma_map_sg' drivers/tty/serial/sh-sci.c:1527:3: error: implicit declaration of function 'dma_alloc_coherent' drivers/tty/serial/sh-sci.c:1527:10: warning: assignment makes pointer from integer without a cast make[3]: *** [drivers/tty/serial/sh-sci.o] Error 1 make[2]: *** [drivers/tty/serial] Error 2 make[1]: *** [drivers/tty] Error 2 make: *** [drivers] Error 2 Signed-off-by: Magnus Damm Tested-by: Simon Horman Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 522f69d3c8ae..38a81ae9b7df 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include From c84b51e65ea2f256353c339bd87e991b7e64630f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 31 Jul 2011 21:36:35 +0000 Subject: [PATCH 010/249] sh: Fix conflicting definitions of ptrace_triggered The extra nmi argument is causing this compile fail: CC arch/sh/kernel/ptrace_32.o arch/sh/kernel/ptrace_32.c:66:6: error: conflicting types for 'ptrace_triggered' arch/sh/include/asm/ptrace.h:126:13: note: previous declaration of 'ptrace_triggered' was here make[3]: *** [arch/sh/kernel/ptrace_32.o] Error 1 Signed-off-by: Paul Gortmaker Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index b97baf81a87b..2d3679b2447f 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -123,7 +123,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, struct perf_event; struct perf_sample_data; -extern void ptrace_triggered(struct perf_event *bp, int nmi, +extern void ptrace_triggered(struct perf_event *bp, struct perf_sample_data *data, struct pt_regs *regs); #define task_pt_regs(task) \ From 1ba762209491e2496e58baffa3fd65d661f54404 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 3 Aug 2011 03:47:36 +0000 Subject: [PATCH 011/249] serial: sh-sci: console Runtime PM support Add Runtime PM context save/restore support to the SCIF driver. Tested on the AP4EVB console. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 68 +++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 38a81ae9b7df..ffcaceee0215 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -96,6 +96,12 @@ struct sci_port { #endif struct notifier_block freq_transition; + +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE + unsigned short saved_smr; + unsigned short saved_fcr; + unsigned char saved_brr; +#endif }; /* Function prototypes */ @@ -1634,11 +1640,25 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +static void sci_reset(struct uart_port *port) +{ + unsigned int status; + + do { + status = sci_in(port, SCxSR); + } while (!(status & SCxSR_TEND(port))); + + sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ + + if (port->type != PORT_SCI) + sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); +} + static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sci_port *s = to_sci_port(port); - unsigned int status, baud, smr_val, max_baud; + unsigned int baud, smr_val, max_baud; int t = -1; u16 scfcr = 0; @@ -1658,14 +1678,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_port_enable(s); - do { - status = sci_in(port, SCxSR); - } while (!(status & SCxSR_TEND(port))); - - sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ - - if (port->type != PORT_SCI) - sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); + sci_reset(port); smr_val = sci_in(port, SCSMR) & 3; @@ -2037,7 +2050,8 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - /* TODO: disable clock */ + sci_port_disable(sci_port); + return uart_set_options(port, co, baud, parity, bits, flow); } @@ -2080,6 +2094,36 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) return 0; } +#define uart_console(port) ((port)->cons->index == (port)->line) + +static int sci_runtime_suspend(struct device *dev) +{ + struct sci_port *sci_port = dev_get_drvdata(dev); + struct uart_port *port = &sci_port->port; + + if (uart_console(port)) { + sci_port->saved_smr = sci_in(port, SCSMR); + sci_port->saved_brr = sci_in(port, SCBRR); + sci_port->saved_fcr = sci_in(port, SCFCR); + } + return 0; +} + +static int sci_runtime_resume(struct device *dev) +{ + struct sci_port *sci_port = dev_get_drvdata(dev); + struct uart_port *port = &sci_port->port; + + if (uart_console(port)) { + sci_reset(port); + sci_out(port, SCSMR, sci_port->saved_smr); + sci_out(port, SCBRR, sci_port->saved_brr); + sci_out(port, SCFCR, sci_port->saved_fcr); + sci_out(port, SCSCR, sci_port->cfg->scscr); + } + return 0; +} + #define SCI_CONSOLE (&serial_console) #else @@ -2089,6 +2133,8 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) } #define SCI_CONSOLE NULL +#define sci_runtime_suspend NULL +#define sci_runtime_resume NULL #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ @@ -2204,6 +2250,8 @@ static int sci_resume(struct device *dev) } static const struct dev_pm_ops sci_dev_pm_ops = { + .runtime_suspend = sci_runtime_suspend, + .runtime_resume = sci_runtime_resume, .suspend = sci_suspend, .resume = sci_resume, }; From c66d3fcbf306af3c0c4b6f4e0d81467f89c67702 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 8 Aug 2011 16:30:11 +0900 Subject: [PATCH 012/249] sh: Fix up fallout from cpuidle changes. Fixes up the pm_idle redefinition that was introduced with the earlier cpuidle changes. Signed-off-by: Paul Mundt --- arch/sh/kernel/idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 32114e0941ae..db4ecd731a00 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -22,7 +22,7 @@ #include #include -static void (*pm_idle)(void); +void (*pm_idle)(void); static int hlt_counter; From b3623080ff6974e696710b6c6eb4cdbf2bbab347 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 3 Aug 2011 06:08:54 +0000 Subject: [PATCH 013/249] mmc: sdhi, mmcif: zboot: Correct clock disable logic This corrects a logic-error that I made in the original implementation. An alternate patch would be to just remove these lines and leave the clock running as it is reconfigured later on during boot anyway. Signed-off-by: Simon Horman Signed-off-by: Paul Mundt --- arch/arm/boot/compressed/mmcif-sh7372.c | 2 +- arch/arm/boot/compressed/sdhi-sh7372.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c index b6f61d9a5a1b..672ae95db5c3 100644 --- a/arch/arm/boot/compressed/mmcif-sh7372.c +++ b/arch/arm/boot/compressed/mmcif-sh7372.c @@ -82,7 +82,7 @@ asmlinkage void mmc_loader(unsigned char *buf, unsigned long len) /* Disable clock to MMC hardware block */ - __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3); + __raw_writel(__raw_readl(SMSTPCR3) | (1 << 12), SMSTPCR3); mmc_update_progress(MMC_PROGRESS_DONE); } diff --git a/arch/arm/boot/compressed/sdhi-sh7372.c b/arch/arm/boot/compressed/sdhi-sh7372.c index d403a8b24d7f..d279294f2381 100644 --- a/arch/arm/boot/compressed/sdhi-sh7372.c +++ b/arch/arm/boot/compressed/sdhi-sh7372.c @@ -85,7 +85,7 @@ asmlinkage void mmc_loader(unsigned short *buf, unsigned long len) goto err; /* Disable clock to SDHI1 hardware block */ - __raw_writel(__raw_readl(SMSTPCR3) & (1 << 13), SMSTPCR3); + __raw_writel(__raw_readl(SMSTPCR3) | (1 << 13), SMSTPCR3); mmc_update_progress(MMC_PROGRESS_DONE); From fe43756143c4efa6f8fdef07aa3ca4dc0be24ada Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 17 Jun 2011 08:21:21 +0000 Subject: [PATCH 014/249] ARM: mach-shmobile: mackerel: Add USB-DMA ID This patch use channel0 as Tx, and channel1 as Rx Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/board-mackerel.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index d41c01f83f15..e1d9b6af3f94 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -641,6 +641,8 @@ static struct usbhs_private usbhs0_private = { }, .driver_param = { .buswait_bwait = 4, + .d0_tx_id = SHDMA_SLAVE_USB0_TX, + .d1_rx_id = SHDMA_SLAVE_USB0_RX, }, }, }; @@ -810,6 +812,8 @@ static struct usbhs_private usbhs1_private = { .buswait_bwait = 4, .pipe_type = usbhs1_pipe_cfg, .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg), + .d0_tx_id = SHDMA_SLAVE_USB1_TX, + .d1_rx_id = SHDMA_SLAVE_USB1_RX, }, }, }; From 5185352c163a72cf969b2fbbfb89801b398896fd Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Aug 2011 14:48:11 -0700 Subject: [PATCH 015/249] libceph: fix msgpool There were several problems here: 1- we weren't tagging allocations with the pool, so they were never returned to the pool. 2- msgpool_put didn't add back to the mempool, even it were called. 3- msgpool_release didn't clear the pool pointer, so it would have looped had #1 not been broken. These may or may not have been responsible for #1136 or #1381 (BUG due to non-empty mempool on umount). I can't seem to trigger the crash now using the method I was using before. Signed-off-by: Sage Weil --- net/ceph/msgpool.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/net/ceph/msgpool.c b/net/ceph/msgpool.c index d5f2d97ac05c..1f4cb30a42c5 100644 --- a/net/ceph/msgpool.c +++ b/net/ceph/msgpool.c @@ -7,27 +7,37 @@ #include -static void *alloc_fn(gfp_t gfp_mask, void *arg) +static void *msgpool_alloc(gfp_t gfp_mask, void *arg) { struct ceph_msgpool *pool = arg; - void *p; + struct ceph_msg *msg; - p = ceph_msg_new(0, pool->front_len, gfp_mask); - if (!p) - pr_err("msgpool %s alloc failed\n", pool->name); - return p; + msg = ceph_msg_new(0, pool->front_len, gfp_mask); + if (!msg) { + dout("msgpool_alloc %s failed\n", pool->name); + } else { + dout("msgpool_alloc %s %p\n", pool->name, msg); + msg->pool = pool; + } + return msg; } -static void free_fn(void *element, void *arg) +static void msgpool_free(void *element, void *arg) { - ceph_msg_put(element); + struct ceph_msgpool *pool = arg; + struct ceph_msg *msg = element; + + dout("msgpool_release %s %p\n", pool->name, msg); + msg->pool = NULL; + ceph_msg_put(msg); } int ceph_msgpool_init(struct ceph_msgpool *pool, int front_len, int size, bool blocking, const char *name) { + dout("msgpool %s init\n", name); pool->front_len = front_len; - pool->pool = mempool_create(size, alloc_fn, free_fn, pool); + pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool); if (!pool->pool) return -ENOMEM; pool->name = name; @@ -36,14 +46,17 @@ int ceph_msgpool_init(struct ceph_msgpool *pool, void ceph_msgpool_destroy(struct ceph_msgpool *pool) { + dout("msgpool %s destroy\n", pool->name); mempool_destroy(pool->pool); } struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len) { + struct ceph_msg *msg; + if (front_len > pool->front_len) { - pr_err("msgpool_get pool %s need front %d, pool size is %d\n", + dout("msgpool_get %s need front %d, pool size is %d\n", pool->name, front_len, pool->front_len); WARN_ON(1); @@ -51,14 +64,19 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, return ceph_msg_new(0, front_len, GFP_NOFS); } - return mempool_alloc(pool->pool, GFP_NOFS); + msg = mempool_alloc(pool->pool, GFP_NOFS); + dout("msgpool_get %s %p\n", pool->name, msg); + return msg; } void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) { + dout("msgpool_put %s %p\n", pool->name, msg); + /* reset msg front_len; user may have changed it */ msg->front.iov_len = pool->front_len; msg->hdr.front_len = cpu_to_le32(pool->front_len); kref_init(&msg->kref); /* retake single ref */ + mempool_free(msg, pool->pool); } From 4f6fdf08681cecd9f38499de7a02eb4f05f399a7 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Fri, 5 Aug 2011 09:16:57 -0700 Subject: [PATCH 016/249] HID: magicmouse: Set resolution of touch surfaces Add touch surface resolution information. The size of the touch surfaces has been determined to the hundredth of a mm. Cc: Jiri Kosina Cc: Michael Poole Cc: linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Chase Douglas [jkosina@suse.cz: update comments and commit message] Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 56 +++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0ec91c18a421..b5bdab3299bc 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -81,6 +81,28 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie #define NO_TOUCHES -1 #define SINGLE_TOUCH_UP -2 +/* Touch surface information. Dimension is in hundredths of a mm, min and max + * are in units. */ +#define MOUSE_DIMENSION_X (float)9056 +#define MOUSE_MIN_X -1100 +#define MOUSE_MAX_X 1258 +#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100)) +#define MOUSE_DIMENSION_Y (float)5152 +#define MOUSE_MIN_Y -1589 +#define MOUSE_MAX_Y 2047 +#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100)) + +#define TRACKPAD_DIMENSION_X (float)13000 +#define TRACKPAD_MIN_X -2909 +#define TRACKPAD_MAX_X 3167 +#define TRACKPAD_RES_X \ + ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100)) +#define TRACKPAD_DIMENSION_Y (float)11000 +#define TRACKPAD_MIN_Y -2456 +#define TRACKPAD_MAX_Y 2565 +#define TRACKPAD_RES_Y \ + ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100)) + /** * struct magicmouse_sc - Tracks Magic Mouse-specific data. * @input: Input device through which we report events. @@ -406,17 +428,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h * inverse of the reported Y. */ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, - 1358, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, - 2047, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_X, + MOUSE_MIN_X, MOUSE_MAX_X, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, + MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0); + + input_abs_set_res(input, ABS_MT_POSITION_X, + MOUSE_RES_X); + input_abs_set_res(input, ABS_MT_POSITION_Y, + MOUSE_RES_Y); } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); - input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_X, -2909, - 3167, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, - 2565, 4, 0); + input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X, + TRACKPAD_MAX_X, 4, 0); + input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y, + TRACKPAD_MAX_Y, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_X, + TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, + TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0); + + input_abs_set_res(input, ABS_X, TRACKPAD_RES_X); + input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y); + input_abs_set_res(input, ABS_MT_POSITION_X, + TRACKPAD_RES_X); + input_abs_set_res(input, ABS_MT_POSITION_Y, + TRACKPAD_RES_Y); } input_set_events_per_packet(input, 60); From 971c90bfa2f0b4fe52d6d9002178d547706f1343 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 4 Aug 2011 07:25:35 -0700 Subject: [PATCH 017/249] alarmtimers: Avoid possible null pointer traversal We don't check if old_setting is non null before assigning it, so correct this. CC: Thomas Gleixner CC: stable@kernel.org Signed-off-by: John Stultz --- kernel/time/alarmtimer.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 59f369f98a04..1dee3f62a6a7 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -479,11 +479,8 @@ static int alarm_timer_set(struct k_itimer *timr, int flags, if (!rtcdev) return -ENOTSUPP; - /* Save old values */ - old_setting->it_interval = - ktime_to_timespec(timr->it.alarmtimer.period); - old_setting->it_value = - ktime_to_timespec(timr->it.alarmtimer.node.expires); + if (old_setting) + alarm_timer_get(timr, old_setting); /* If the timer was already set, cancel it */ alarm_cancel(&timr->it.alarmtimer); From ea7802f630d356acaf66b3c0b28c00a945fc35dc Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 4 Aug 2011 07:51:56 -0700 Subject: [PATCH 018/249] alarmtimers: Memset itimerspec passed into alarm_timer_get Following common_timer_get, zero out the itimerspec passed in. CC: Thomas Gleixner CC: stable@kernel.org Signed-off-by: John Stultz --- kernel/time/alarmtimer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 1dee3f62a6a7..0e9263f6fd09 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -441,6 +441,8 @@ static int alarm_timer_create(struct k_itimer *new_timer) static void alarm_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) { + memset(cur_setting, 0, sizeof(struct itimerspec)); + cur_setting->it_interval = ktime_to_timespec(timr->it.alarmtimer.period); cur_setting->it_value = From 6af7e471e5a7746b8024d70b4363d3dfe41d36b8 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 10 Aug 2011 10:26:09 -0700 Subject: [PATCH 019/249] alarmtimers: Avoid possible denial of service with high freq periodic timers Its possible to jam up the alarm timers by setting very small interval timers, which will cause the alarmtimer subsystem to spend all of its time firing and restarting timers. This can effectivly lock up a box. A deeper fix is needed, closely mimicking the hrtimer code, but for now just cap the interval to 100us to avoid userland hanging the system. CC: Thomas Gleixner CC: stable@kernel.org Signed-off-by: John Stultz --- kernel/time/alarmtimer.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 0e9263f6fd09..ea5e1a928d5b 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -481,6 +481,15 @@ static int alarm_timer_set(struct k_itimer *timr, int flags, if (!rtcdev) return -ENOTSUPP; + /* + * XXX HACK! Currently we can DOS a system if the interval + * period on alarmtimers is too small. Cap the interval here + * to 100us and solve this properly in a future patch! -jstultz + */ + if ((new_setting->it_interval.tv_sec == 0) && + (new_setting->it_interval.tv_nsec < 100000)) + new_setting->it_interval.tv_nsec = 100000; + if (old_setting) alarm_timer_get(timr, old_setting); From bf6ed027bcc93f8d54d321fe87f0434b25699eb1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 10 Aug 2011 21:11:26 +0800 Subject: [PATCH 020/249] rtc: ep93xx: Fix 'rtc' may be used uninitialized warning commit 92d921c5d "rtc: ep93xx: Initialize drvdata before registering device" ensures the drvdata is initialized prior to registering the rtc device. But it set the drvdata to an uninitialized pointer. Thus calling platform_get_drvdata in ep93xx_rtc_remove does not get correct address. This patch fixes below warning by adding struct rtc_device *rtc to struct ep93xx_rtc. Then set platform drvdata to ep93xx_rtc instead of rtc. CC drivers/rtc/rtc-ep93xx.o drivers/rtc/rtc-ep93xx.c: In function 'ep93xx_rtc_probe': drivers/rtc/rtc-ep93xx.c:154: warning: 'rtc' may be used uninitialized in this function Signed-off-by: Axel Lin Signed-off-by: John Stultz --- drivers/rtc/rtc-ep93xx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 335551d333b2..14a42a1edc66 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -36,6 +36,7 @@ */ struct ep93xx_rtc { void __iomem *mmio_base; + struct rtc_device *rtc; }; static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, @@ -130,7 +131,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) { struct ep93xx_rtc *ep93xx_rtc; struct resource *res; - struct rtc_device *rtc; int err; ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL); @@ -151,12 +151,12 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return -ENXIO; pdev->dev.platform_data = ep93xx_rtc; - platform_set_drvdata(pdev, rtc); + platform_set_drvdata(pdev, ep93xx_rtc); - rtc = rtc_device_register(pdev->name, + ep93xx_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); + if (IS_ERR(ep93xx_rtc->rtc)) { + err = PTR_ERR(ep93xx_rtc->rtc); goto exit; } @@ -167,7 +167,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return 0; fail: - rtc_device_unregister(rtc); + rtc_device_unregister(ep93xx_rtc->rtc); exit: platform_set_drvdata(pdev, NULL); pdev->dev.platform_data = NULL; @@ -176,11 +176,11 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) static int __exit ep93xx_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); + struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev); sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); platform_set_drvdata(pdev, NULL); - rtc_device_unregister(rtc); + rtc_device_unregister(ep93xx_rtc->rtc); pdev->dev.platform_data = NULL; return 0; From dec35d19c4ec65b94df3b27b6e373f0d48c9cd32 Mon Sep 17 00:00:00 2001 From: Ilkka Koskinen Date: Wed, 16 Mar 2011 06:07:14 +0000 Subject: [PATCH 021/249] rtc: rtc-twl: Switch to using threaded irq The driver is accessing to i2c bus in interrupt handler. Therefore, it should use threaded irq. Signed-off-by: Ilkka Koskinen Acked-by: Balaji T K Signed-off-by: John Stultz --- drivers/rtc/rtc-twl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 9a81f778d6b2..1963cddbf214 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -462,7 +462,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) if (ret < 0) goto out1; - ret = request_irq(irq, twl_rtc_interrupt, + ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, IRQF_TRIGGER_RISING, dev_name(&rtc->dev), rtc); if (ret < 0) { From 34d623d11316cb69f9e8cc5eb50d3792b5c302b6 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 31 May 2011 08:51:39 +0000 Subject: [PATCH 022/249] rtc: rtc-twl: Remove lockdep related local_irq_enable() Now that the irq is properly threaded (due to it needing i2c access) we should also remove the local_irq_enable() call in twl_rtc_interrupt. Testing this with Pandaboard, the RTC is still working. [Reworked commit message -jstultz] Signed-off-by: John Stultz --- drivers/rtc/rtc-twl.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 1963cddbf214..9677bbc433f9 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -362,14 +362,6 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) int res; u8 rd_reg; -#ifdef CONFIG_LOCKDEP - /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which - * we don't want and can't tolerate. Although it might be - * friendlier not to borrow this thread context... - */ - local_irq_enable(); -#endif - res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; From 938f97bcf1bdd1b681d5d14d1d7117a2e22d4434 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 22 Jul 2011 09:12:51 +0000 Subject: [PATCH 023/249] rtc: Fix RTC PIE frequency limit Thomas earlier submitted a fix to limit the RTC PIE freq, but picked 5000Hz out of the air. Willy noticed that we should instead use the 8192Hz max from the rtc man documentation. Cc: Willy Tarreau Cc: stable@kernel.org Cc: Thomas Gleixner Signed-off-by: John Stultz --- drivers/rtc/interface.c | 2 +- include/linux/rtc.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 3195dbd3ec34..eb4c88316a15 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -708,7 +708,7 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) int err = 0; unsigned long flags; - if (freq <= 0 || freq > 5000) + if (freq <= 0 || freq > RTC_MAX_FREQ) return -EINVAL; retry: spin_lock_irqsave(&rtc->irq_task_lock, flags); diff --git a/include/linux/rtc.h b/include/linux/rtc.h index b27ebea25660..93f4d035076b 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -97,6 +97,9 @@ struct rtc_pll_info { #define RTC_AF 0x20 /* Alarm interrupt */ #define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ + +#define RTC_MAX_FREQ 8192 + #ifdef __KERNEL__ #include From 8475e2336cf80ba6e7b27715b4b3214d73c211ab Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 3 Aug 2011 17:22:45 +0300 Subject: [PATCH 024/249] Bluetooth: unlock if allocation fails in hci_blacklist_add() There was a small typo here so we never actually hit the goto which would call hci_dev_unlock_bh(). Signed-off-by: Dan Carpenter Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ec0bc3f60f2e..fca62dcd7f1b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1327,7 +1327,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); if (!entry) { - return -ENOMEM; + err = -ENOMEM; goto err; } From 4935f1c164ac528dff3538f97953b385ba500710 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 9 Aug 2011 17:16:28 +0200 Subject: [PATCH 025/249] Bluetooth: btusb: be quiet on device disconnect Disabling the bluetooth usb device embedded in (some) ThinkPads tends to lead to errors like these: btusb_bulk_complete: hci0 urb ffff88011b9bfd68 failed to resubmit (19) btusb_intr_complete: hci0 urb ffff88011b46a318 failed to resubmit (19) btusb_bulk_complete: hci0 urb ffff88011b46a000 failed to resubmit (19) That is because usb_disconnect() doesn't "quiesces" pending urbs. Disconnecting a device is a normal thing to happen so it's no big deal that usb_submit_urb() returns -ENODEV. The simplest way to get rid of these errors is to stop treating that return as an error. Trivial, actually. While we're at it, add comments to be explicit about the reasons we're not complaining about -EPERM and -ENODEV. Signed-off-by: Paul Bolle Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 91d13a9e8c65..9e4448efb104 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -256,7 +256,9 @@ static void btusb_intr_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); @@ -341,7 +343,9 @@ static void btusb_bulk_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); @@ -431,7 +435,9 @@ static void btusb_isoc_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); From 8e7c3d2e4ba18ee4cdcc1f89aec944fbff4ce735 Mon Sep 17 00:00:00 2001 From: Ricardo Mendoza Date: Wed, 13 Jul 2011 16:04:29 +0100 Subject: [PATCH 026/249] Bluetooth: Add Toshiba laptops AR30XX device ID Blacklist Toshiba-branded AR3011 based AR5B195 [0930:0215] and add to ath3k.c for firmware loading. Signed-off-by: Ricardo Mendoza Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 1 + drivers/bluetooth/btusb.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a5854735bb2e..db7cb8111fbe 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x13d3, 0x3304) }, + { USB_DEVICE(0x0930, 0x0215) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9e4448efb104..3ef476070baf 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, From e5842cdb0f4f2c68f6acd39e286e5d10d8c073e8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:35 -0400 Subject: [PATCH 027/249] Bluetooth: rfcomm: Remove unnecessary krfcommd event Removed superfluous event handling which was used to signal that the rfcomm kthread had been woken. This appears to have been used to prevent lost wakeups. Correctly ordering when the task state is set to TASK_INTERRUPTIBLE is sufficient to prevent lost wakeups. To prevent wakeups which occurred prior to initially setting TASK_INTERRUPTIBLE from being lost, the main work of the thread loop - rfcomm_process_sessions() - is performed prior to sleeping. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/core.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5759bb7054f7..5ba3f6df665c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); #define rfcomm_lock() mutex_lock(&rfcomm_mutex) #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) -static unsigned long rfcomm_event; static LIST_HEAD(session_list); @@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) { if (!rfcomm_thread) return; - set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); wake_up_process(rfcomm_thread); } @@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused) rfcomm_add_listener(BDADDR_ANY); - while (!kthread_should_stop()) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { - /* No pending events. Let's sleep. - * Incoming connections and data will wake us up. */ - schedule(); - } - set_current_state(TASK_RUNNING); + + if (kthread_should_stop()) + break; /* Process stuff */ - clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); rfcomm_process_sessions(); + + schedule(); } + __set_current_state(TASK_RUNNING); rfcomm_kill_listener(); From 950e2d51e866623e4c360280aa63b85ab66d3403 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:41 -0400 Subject: [PATCH 028/249] Bluetooth: rfcomm: Fix lost wakeups waiting to accept socket Fix race conditions which can cause lost wakeups (or missed signals) while waiting to accept an rfcomm socket connection. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/sock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8f01e6b11a70..482722bbc7a0 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f lock_sock(sk); - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; - goto done; - } - if (sk->sk_type != SOCK_STREAM) { err = -EINVAL; goto done; @@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); - while (!(nsk = bt_accept_dequeue(sk, newsock))) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; break; } - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); + nsk = bt_accept_dequeue(sk, newsock); + if (nsk) + break; - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; + if (!timeo) { + err = -EAGAIN; break; } @@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f err = sock_intr_errno(timeo); break; } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); if (err) From 9be4e3fbf2d3603e7a7010ede0697166738a788b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:46 -0400 Subject: [PATCH 029/249] Bluetooth: Fix lost wakeups waiting for sock state change Fix race conditions which can cause lost wakeups while waiting for sock state to change. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/af_bluetooth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8add9b499912..117e0d161780 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) BT_DBG("sk %p", sk); add_wait_queue(sk_sleep(sk), &wait); + set_current_state(TASK_INTERRUPTIBLE); while (sk->sk_state != state) { - set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { err = -EINPROGRESS; break; @@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); + set_current_state(TASK_INTERRUPTIBLE); err = sock_error(sk); if (err) break; } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); return err; } From f9a3c20aa07462108fc6fd759dea956053f020bb Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:52 -0400 Subject: [PATCH 030/249] Bluetooth: l2cap: Fix lost wakeups waiting to accept socket Fix race conditions which can cause lost wakeups (or misssed signals) while waiting to accept an l2cap socket connection. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_sock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c36b3e8739c..7d713b1c4cbd 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl lock_sock_nested(sk, SINGLE_DEPTH_NESTING); - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; - goto done; - } - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); BT_DBG("sk %p timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); - while (!(nsk = bt_accept_dequeue(sk, newsock))) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; break; } - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + nsk = bt_accept_dequeue(sk, newsock); + if (nsk) + break; - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; + if (!timeo) { + err = -EAGAIN; break; } @@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl err = sock_intr_errno(timeo); break; } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); if (err) From 552b0d3cb9ff648aa503011ef50ca24019cd0f5f Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:11:01 -0400 Subject: [PATCH 031/249] Bluetooth: sco: Fix lost wakeups waiting to accept socket Fix race conditions which can cause lost wakeups (or missed signals) while waiting to accept a sco socket connection. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/sco.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 4c3621b5e0aa..8270f05e3f1f 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag lock_sock(sk); - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; - goto done; - } - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); BT_DBG("sk %p timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); - while (!(ch = bt_accept_dequeue(sk, newsock))) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; break; } - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); + ch = bt_accept_dequeue(sk, newsock); + if (ch) + break; - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; + if (!timeo) { + err = -EAGAIN; break; } @@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag err = sock_intr_errno(timeo); break; } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); if (err) From 38d57555616afcdad7381b02b523d494327494cd Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:11:07 -0400 Subject: [PATCH 032/249] Bluetooth: bnep: Fix lost wakeup of session thread Fix race condition which can result in missing the wakeup intended to stop the session thread. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ca39fcf010ce..7e8ff3c24942 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,9 +484,11 @@ static int bnep_session(void *arg) init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); - while (!kthread_should_stop()) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; /* RX */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { skb_orphan(skb); @@ -504,7 +506,7 @@ static int bnep_session(void *arg) schedule(); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ From 3a3f5c7df55a1294c9e6e2d0b8cea604b137438f Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:11:10 -0400 Subject: [PATCH 033/249] Bluetooth: cmtp: Fix lost wakeup of session thread Fix race condition which can result in missing the wakeup intended to stop the session thread. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index c5b11af908be..2eb854ab10f6 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -292,9 +292,11 @@ static int cmtp_session(void *arg) init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); - while (!kthread_should_stop()) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; if (sk->sk_state != BT_CONNECTED) break; @@ -307,7 +309,7 @@ static int cmtp_session(void *arg) schedule(); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); From a71a0cf4e9cdb1c43843977a1efc43f96f6efc21 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 25 Jul 2011 18:36:26 -0400 Subject: [PATCH 034/249] Bluetooth: l2cap: Fix lost wakeup waiting for ERTM acks Fix race condition which can result in missing wakeup during l2cap socket shutdown. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3204ba8a701c..b3bdb482bbe6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk) int timeo = HZ/5; add_wait_queue(sk_sleep(sk), &wait); - while ((chan->unacked_frames > 0 && chan->conn)) { - set_current_state(TASK_INTERRUPTIBLE); - + set_current_state(TASK_INTERRUPTIBLE); + while (chan->unacked_frames > 0 && chan->conn) { if (!timeo) timeo = HZ/5; @@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk) release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); + set_current_state(TASK_INTERRUPTIBLE); err = sock_error(sk); if (err) From 6be6b11f006840ba7d8d4b959b3fa0c522f8468a Mon Sep 17 00:00:00 2001 From: Chen Ganir Date: Thu, 28 Jul 2011 15:42:09 +0300 Subject: [PATCH 035/249] Bluetooth: Fixed wrong L2CAP Sock timer value L2CAP connection timeout needs to be assigned as miliseconds and not as jiffies. Signed-off-by: Chen Ganir Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 7d713b1c4cbd..61f1f623091d 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p INIT_LIST_HEAD(&bt_sk(sk)->accept_q); sk->sk_destruct = l2cap_sock_destruct; - sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); + sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; sock_reset_flag(sk, SOCK_ZAPPED); From 7bdb8a5cf17f66614a9897645efcd4ccc27535ee Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Jul 2011 22:46:54 +0200 Subject: [PATCH 036/249] Bluetooth: Don't use cmd_timer to timeout HCI reset command No command should be send before Command Complete event for HCI reset is received. This fix regression introduced by commit 6bd32326cda(Bluetooth: Use proper timer for hci command timout) for chips whose reset command takes longer to complete (e.g. CSR) resulting in next command being send before HCI reset completed. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index fca62dcd7f1b..56943add45cc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg) BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); - clear_bit(HCI_RESET, &hdev->flags); tasklet_schedule(&hdev->cmd_task); } @@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg) if (hdev->sent_cmd) { atomic_dec(&hdev->cmd_cnt); hci_send_frame(skb); - mod_timer(&hdev->cmd_timer, + if (test_bit(HCI_RESET, &hdev->flags)) + del_timer(&hdev->cmd_timer); + else + mod_timer(&hdev->cmd_timer, jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); } else { skb_queue_head(&hdev->cmd_q, skb); From 751c10a56802513a6b057c8cf1552cecc1c9afde Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:41:35 -0400 Subject: [PATCH 037/249] Bluetooth: bnep: Fix deadlock in session deletion Commit f4d7cd4a4c introduced the usage of kthread API. kthread_stop is a blocking function which returns only when the thread exits. In this case, the thread can't exit because it's waiting for the write lock, which is being held by bnep_del_connection() which is waiting for the thread to exit -- deadlock. Use atomic_t/wake_up_process instead to signal to the thread to exit. Signed-off-by: Jaikumar Ganesh Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/bnep.h | 1 + net/bluetooth/bnep/core.c | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 8e6c06158f8e..e7ee5314f39a 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h @@ -155,6 +155,7 @@ struct bnep_session { unsigned int role; unsigned long state; unsigned long flags; + atomic_t terminate; struct task_struct *task; struct ethhdr eh; diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 7e8ff3c24942..d9edfe8bf9d6 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -487,7 +487,7 @@ static int bnep_session(void *arg) while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) + if (atomic_read(&s->terminate)) break; /* RX */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { @@ -642,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req) down_read(&bnep_session_sem); s = __bnep_get_session(req->dst); - if (s) - kthread_stop(s->task); - else + if (s) { + atomic_inc(&s->terminate); + wake_up_process(s->task); + } else err = -ENOENT; up_read(&bnep_session_sem); From 7176522cdca1f0b78a1434b41761f0334511822a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:44:21 -0400 Subject: [PATCH 038/249] Bluetooth: cmtp: Fix deadlock in session deletion Commit fada4ac339 introduced the usage of kthread API. kthread_stop is a blocking function which returns only when the thread exits. In this case, the thread can't exit because it's waiting for the write lock, which is being held by cmtp_del_connection() which is waiting for the thread to exit -- deadlock. Revert cmtp_reset_ctr to its original behavior: non-blocking signalling for the session to terminate. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/capi.c | 3 ++- net/bluetooth/cmtp/cmtp.h | 1 + net/bluetooth/cmtp/core.c | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 040f67b12978..50f0d135eb8f 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) capi_ctr_down(ctrl); - kthread_stop(session->task); + atomic_inc(&session->terminate); + wake_up_process(session->task); } static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index db43b54ac9af..c32638dddbf9 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h @@ -81,6 +81,7 @@ struct cmtp_session { char name[BTNAMSIZ]; + atomic_t terminate; struct task_struct *task; wait_queue_head_t wait; diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 2eb854ab10f6..42cb2f4c0db1 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -295,7 +295,7 @@ static int cmtp_session(void *arg) while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) + if (atomic_read(&session->terminate)) break; if (sk->sk_state != BT_CONNECTED) break; @@ -416,7 +416,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) skb_queue_purge(&session->transmit); /* Stop session thread */ - kthread_stop(session->task); + atomic_inc(&session->terminate); + wake_up_process(session->task); } else err = -ENOENT; From e9d5cb541b22aa651edc29990092ec5f8174cd39 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:51:26 -0400 Subject: [PATCH 039/249] Bluetooth: hidp: Fix session cleanup on failed conn add Once the session thread is running, cleanup must be handled by the session thread only. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 43b4c2deb7cc..7e19a012970e 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1044,8 +1044,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, } err = hid_add_device(session->hid); - if (err < 0) - goto err_add_device; + if (err < 0) { + atomic_inc(&session->terminate); + wake_up_process(session->task); + up_write(&hidp_session_sem); + return err; + } if (session->input) { hidp_send_ctrl_message(session, @@ -1059,12 +1063,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, up_write(&hidp_session_sem); return 0; -err_add_device: - hid_destroy_device(session->hid); - session->hid = NULL; - atomic_inc(&session->terminate); - wake_up_process(session->task); - unlink: hidp_del_timer(session); From 1c97e94c0b7c56319754ee6f9ccd2e93fe1ee2b3 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:51:34 -0400 Subject: [PATCH 040/249] Bluetooth: hidp: Fix memory leak of cached report descriptor Free the cached HID report descriptor on thread terminate. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 7e19a012970e..26f0d109ff41 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -764,6 +764,7 @@ static int hidp_session(void *arg) up_write(&hidp_session_sem); + kfree(session->rd_data); kfree(session); return 0; } From 615aedd6e5add8104f031b0d547285652d04d330 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:51:50 -0400 Subject: [PATCH 041/249] Bluetooth: hidp: Only free input device if failed register When an hidp connection is added for a boot protocol input device, only free the allocated device if device registration fails. Subsequent failures should only unregister the device (the input device api documents that unregister will also free the allocated device). Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 26f0d109ff41..a859f9078df6 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -842,6 +842,8 @@ static int hidp_setup_input(struct hidp_session *session, err = input_register_device(input); if (err < 0) { + input_free_device(input); + session->input = NULL; hci_conn_put_device(session->conn); return err; } @@ -1089,7 +1091,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, failed: up_write(&hidp_session_sem); - input_free_device(session->input); kfree(session); return err; } From ff062ea109217329b88693bc9081da893eb8b71b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:52:01 -0400 Subject: [PATCH 042/249] Bluetooth: hidp: Don't release device ref if never held When an hidp connection is added for a boot protocol input device, don't release a device reference that was never acquired. The device reference is acquired when the session is linked to the session list (which hasn't happened yet when hidp_setup_input is called). Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index a859f9078df6..fb68f344c34a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -844,7 +844,6 @@ static int hidp_setup_input(struct hidp_session *session, if (err < 0) { input_free_device(input); session->input = NULL; - hci_conn_put_device(session->conn); return err; } From 687beaa0d1d937c327e2f97b4b4fa6c23ca70624 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:53:52 -0400 Subject: [PATCH 043/249] Bluetooth: cmtp: Fix session cleanup on failed conn add Once the session thread is running, cleanup must be handled by the session thread only. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 42cb2f4c0db1..521baa4fe835 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -382,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) if (!(session->flags & (1 << CMTP_LOOPBACK))) { err = cmtp_attach_device(session); - if (err < 0) - goto detach; + if (err < 0) { + atomic_inc(&session->terminate); + wake_up_process(session->task); + up_write(&cmtp_session_sem); + return err; + } } up_write(&cmtp_session_sem); return 0; -detach: - cmtp_detach_device(session); - unlink: __cmtp_unlink_session(session); From 0ac8e58f3818795d02ac309bd57b4d93ec283a77 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 9 Aug 2011 12:24:17 +0100 Subject: [PATCH 044/249] ARM: fix perf build with uclibc toolchains libio.h is not provided by uClibc, in order to be able to test the definition of __UCLIBC__ we need to include stdlib.h, which also includes stddef.h, providing the definition of 'NULL'. Signed-off-by: Florian Fainelli Signed-off-by: Will Deacon --- tools/perf/arch/arm/util/dwarf-regs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/arch/arm/util/dwarf-regs.c b/tools/perf/arch/arm/util/dwarf-regs.c index fff6450c8c99..e8d5c551c69c 100644 --- a/tools/perf/arch/arm/util/dwarf-regs.c +++ b/tools/perf/arch/arm/util/dwarf-regs.c @@ -8,7 +8,10 @@ * published by the Free Software Foundation. */ +#include +#ifndef __UCLIBC__ #include +#endif #include struct pt_regs_dwarfnum { From 49bef8331afefa4dd75f7124c50bde47168f5492 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 10 Aug 2011 10:20:17 +0100 Subject: [PATCH 045/249] ARM: perf: fix prototype of release_pmu Commit f12482c9 ("ARM: 6974/1: pmu: refactor reservation") changed the prototype of release_pmu, but missed the stub for when CONFIG_CPU_HAS_PMU is not selected by the platform. This patch changes the prototype of the stub, preventing possible build failures when CONFIG_CPU_HAS_PMU is not selected. Signed-off-by: Mark Rutland Signed-off-by: Will Deacon --- arch/arm/include/asm/pmu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 67c70a31a1be..8ae32ba092c2 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -75,7 +75,7 @@ reserve_pmu(enum arm_pmu_type device) } static inline int -release_pmu(struct platform_device *pdev) +release_pmu(enum arm_pmu_type device) { return -ENODEV; } From 7fdd3c49629e8aab48dbd1b2f800854b0f93cba0 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Fri, 12 Aug 2011 10:42:48 +0100 Subject: [PATCH 046/249] ARM: perf: make name of arm_pmu_type consistent Commit f12482c9 ("ARM: 6974/1: pmu: refactor reservation") changed {release,reserve}_pmu to take an enum arm_pmu_type as a parameter, but inconsistently named the parameter `type' or `device'. It would be nice if these were consistent. This patch makes use of enum arm_pmu_type consistent, always using `type'. Related printks are updated, explicitly mentioning `type' also. Signed-off-by: Mark Rutland Signed-off-by: Will Deacon --- arch/arm/include/asm/pmu.h | 10 +++++----- arch/arm/kernel/pmu.c | 26 +++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 8ae32ba092c2..b7e82c4aced6 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -41,7 +41,7 @@ struct arm_pmu_platdata { * encoded error on failure. */ extern struct platform_device * -reserve_pmu(enum arm_pmu_type device); +reserve_pmu(enum arm_pmu_type type); /** * release_pmu() - Relinquish control of the performance counters @@ -62,26 +62,26 @@ release_pmu(enum arm_pmu_type type); * the actual hardware initialisation. */ extern int -init_pmu(enum arm_pmu_type device); +init_pmu(enum arm_pmu_type type); #else /* CONFIG_CPU_HAS_PMU */ #include static inline struct platform_device * -reserve_pmu(enum arm_pmu_type device) +reserve_pmu(enum arm_pmu_type type) { return ERR_PTR(-ENODEV); } static inline int -release_pmu(enum arm_pmu_type device) +release_pmu(enum arm_pmu_type type) { return -ENODEV; } static inline int -init_pmu(enum arm_pmu_type device) +init_pmu(enum arm_pmu_type type) { return -ENODEV; } diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index 2b70709376c3..c53474fe84df 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c @@ -31,7 +31,7 @@ static int __devinit pmu_register(struct platform_device *pdev, { if (type < 0 || type >= ARM_NUM_PMU_DEVICES) { pr_warning("received registration request for unknown " - "device %d\n", type); + "PMU device type %d\n", type); return -EINVAL; } @@ -112,17 +112,17 @@ static int __init register_pmu_driver(void) device_initcall(register_pmu_driver); struct platform_device * -reserve_pmu(enum arm_pmu_type device) +reserve_pmu(enum arm_pmu_type type) { struct platform_device *pdev; - if (test_and_set_bit_lock(device, &pmu_lock)) { + if (test_and_set_bit_lock(type, &pmu_lock)) { pdev = ERR_PTR(-EBUSY); - } else if (pmu_devices[device] == NULL) { - clear_bit_unlock(device, &pmu_lock); + } else if (pmu_devices[type] == NULL) { + clear_bit_unlock(type, &pmu_lock); pdev = ERR_PTR(-ENODEV); } else { - pdev = pmu_devices[device]; + pdev = pmu_devices[type]; } return pdev; @@ -130,11 +130,11 @@ reserve_pmu(enum arm_pmu_type device) EXPORT_SYMBOL_GPL(reserve_pmu); int -release_pmu(enum arm_pmu_type device) +release_pmu(enum arm_pmu_type type) { - if (WARN_ON(!pmu_devices[device])) + if (WARN_ON(!pmu_devices[type])) return -EINVAL; - clear_bit_unlock(device, &pmu_lock); + clear_bit_unlock(type, &pmu_lock); return 0; } EXPORT_SYMBOL_GPL(release_pmu); @@ -182,17 +182,17 @@ init_cpu_pmu(void) } int -init_pmu(enum arm_pmu_type device) +init_pmu(enum arm_pmu_type type) { int err = 0; - switch (device) { + switch (type) { case ARM_PMU_DEVICE_CPU: err = init_cpu_pmu(); break; default: - pr_warning("attempt to initialise unknown device %d\n", - device); + pr_warning("attempt to initialise PMU of unknown " + "type %d\n", type); err = -EINVAL; } From 5cb843ca0f781b62dc9793b26926d0b8efef5576 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 20 Jul 2011 11:57:03 +0100 Subject: [PATCH 047/249] ARM: realview: ensure visibility of writes during reset The various reset routines in mach-realview rely on an FPGA to power-cycle the board after writing some magic runes to memory-mapped registers. This patch adds a dsb() following the writes, so that they become visible before we mdelay(1000) in the arch_reset code. Without this patch, the timeout would expire sporadically, causing the reset to fail. Signed-off-by: Will Deacon --- arch/arm/mach-realview/include/mach/system.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h index a30f2e3ec178..6657ff231161 100644 --- a/arch/arm/mach-realview/include/mach/system.h +++ b/arch/arm/mach-realview/include/mach/system.h @@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd) */ if (realview_reset) realview_reset(mode); + dsb(); } #endif From dfc40b24c0a37593724f3317cd485c73ee878c18 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 20 Jul 2011 14:18:46 +0100 Subject: [PATCH 048/249] ARM: twd: register clockevents device before enabling PPI The smp_twd clockevents driver currently enables the local timer PPI before the clockevents device is registered. This can lead to a kernel panic if a spurious timer interrupt is generated before registration has completed since the kernel will treat it as an IPI timer. This patch moves the clockevents device registration before the IRQ unmasking so that we can always handle timer interrupts once they can occur. Acked-by: Marc Zyngier Signed-off-by: Will Deacon --- arch/arm/kernel/smp_twd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 2c277d40cee6..01c186222f3b 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -137,8 +137,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); clk->min_delta_ns = clockevent_delta2ns(0xf, clk); + clockevents_register_device(clk); + /* Make sure our local interrupt controller has this enabled */ gic_enable_ppi(clk->irq); - - clockevents_register_device(clk); } From 72dc53acd50db066a5a5ebe1f39fae73d7e62aa8 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 3 Aug 2011 12:37:04 +0100 Subject: [PATCH 049/249] ARM: cache: detect VIPT aliasing I-cache on ARMv6 The current cache detection code does not check for an aliasing I-cache if the D-cache is found to be VIPT aliasing. This patch fixes the problem by always checking for an aliasing I-cache on v6 and later. Signed-off-by: Will Deacon --- arch/arm/kernel/setup.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 70bca649e925..e514c76043b4 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -280,18 +280,19 @@ static void __init cacheid_init(void) if (arch >= CPU_ARCH_ARMv6) { if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ + arch = CPU_ARCH_ARMv7; cacheid = CACHEID_VIPT_NONALIASING; if ((cachetype & (3 << 14)) == 1 << 14) cacheid |= CACHEID_ASID_TAGGED; - else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7)) - cacheid |= CACHEID_VIPT_I_ALIASING; - } else if (cachetype & (1 << 23)) { - cacheid = CACHEID_VIPT_ALIASING; } else { - cacheid = CACHEID_VIPT_NONALIASING; - if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6)) - cacheid |= CACHEID_VIPT_I_ALIASING; + arch = CPU_ARCH_ARMv6; + if (cachetype & (1 << 23)) + cacheid = CACHEID_VIPT_ALIASING; + else + cacheid = CACHEID_VIPT_NONALIASING; } + if (cpu_has_aliasing_icache(arch)) + cacheid |= CACHEID_VIPT_I_ALIASING; } else { cacheid = CACHEID_VIVT; } From 2a004c686e7997ddb795dbce10b263e241f9bdaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Fri, 17 Jun 2011 11:09:07 +0100 Subject: [PATCH 050/249] ARM: 6965/1: ep93xx: add model detection for ts-7300 and ts-7400 boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Ryan Mallon Acked-by: H Hartley Sweeten Signed-off-by: Petr Štetiar Signed-off-by: Russell King --- arch/arm/mach-ep93xx/include/mach/ts72xx.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 0eabec62cd9d..ee7f87589efa 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h @@ -20,6 +20,8 @@ #define TS72XX_MODEL_TS7200 0x00 #define TS72XX_MODEL_TS7250 0x01 #define TS72XX_MODEL_TS7260 0x02 +#define TS72XX_MODEL_TS7300 0x03 +#define TS72XX_MODEL_TS7400 0x04 #define TS72XX_OPTIONS_PHYS_BASE 0x22400000 @@ -66,6 +68,16 @@ static inline int board_is_ts7260(void) return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260; } +static inline int board_is_ts7300(void) +{ + return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7300; +} + +static inline int board_is_ts7400(void) +{ + return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7400; +} + static inline int is_max197_installed(void) { return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) & From 505ed6fd82608bd4f26d487220ec40a3c5d0dded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Fri, 17 Jun 2011 11:11:59 +0100 Subject: [PATCH 051/249] ARM: 6967/1: ep93xx: ts72xx: fix board model detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the obvious error in board detection logic, because according to the TS's manual, the model is stored in the least three significant bits. For example the byte read on my ts-7300 is 0x23 and the detection then fails. Cc: Ryan Mallon Acked-by: H Hartley Sweeten Signed-off-by: Petr Štetiar Signed-off-by: Russell King --- arch/arm/mach-ep93xx/include/mach/ts72xx.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index ee7f87589efa..f1397a13e76b 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h @@ -6,7 +6,7 @@ * TS72xx memory map: * * virt phys size - * febff000 22000000 4K model number register + * febff000 22000000 4K model number register (bits 0-2) * febfe000 22400000 4K options register * febfd000 22800000 4K options register #2 * febf9000 10800000 4K TS-5620 RTC index register @@ -22,6 +22,7 @@ #define TS72XX_MODEL_TS7260 0x02 #define TS72XX_MODEL_TS7300 0x03 #define TS72XX_MODEL_TS7400 0x04 +#define TS72XX_MODEL_MASK 0x07 #define TS72XX_OPTIONS_PHYS_BASE 0x22400000 @@ -53,29 +54,34 @@ #ifndef __ASSEMBLY__ +static inline int ts72xx_model(void) +{ + return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK; +} + static inline int board_is_ts7200(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200; + return ts72xx_model() == TS72XX_MODEL_TS7200; } static inline int board_is_ts7250(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250; + return ts72xx_model() == TS72XX_MODEL_TS7250; } static inline int board_is_ts7260(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260; + return ts72xx_model() == TS72XX_MODEL_TS7260; } static inline int board_is_ts7300(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7300; + return ts72xx_model() == TS72XX_MODEL_TS7300; } static inline int board_is_ts7400(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7400; + return ts72xx_model() == TS72XX_MODEL_TS7400; } static inline int is_max197_installed(void) From 43c734be5571a4daad9f0a3e0b3229a1c0049917 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 15 Aug 2011 10:43:44 +0100 Subject: [PATCH 052/249] ARM: 7014/1: cache-l2x0: Fix L2 Cache size calculation. This patch fixes L2 Cache size calculations for L2C-210, L2C-310 and PL310, by changing the L2X0_AUX_CTRL_WAY_SIZE_MASK from 2 bits to 3 bits. The Auxiliary Control Register for L2C-210, L2C-310 and PL310 has 3bits [19:17] for Way size, however the existing code only uses 2 bits to get this value. This results in incorrect cachesize calculations. It also results in performing operations on the whole cache when we erroneously decide that the range is big enough (due to l2x0_size being too small) and also prints incorrect cachesize. Signed-off-by: Srinivas Kandagatla Acked-by: Will Deacon Cc: stable@kernel.org Signed-off-by: Russell King --- arch/arm/include/asm/hardware/cache-l2x0.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 16bd48031583..bfa706ffd968 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -64,7 +64,7 @@ #define L2X0_AUX_CTRL_MASK 0xc0000fff #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) +#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17) #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 From 145e10e173c8adf4804334fb0dd10028300a7a7a Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 15 Aug 2011 11:04:41 +0100 Subject: [PATCH 053/249] ARM: 7015/1: ARM errata: Possible cache data corruption with hit-under-miss enabled This patch is a workaround for the 364296 ARM1136 r0p2 erratum (possible cache data corruption with hit-under-miss enabled). It sets the undocumented bit 31 in the auxiliary control register and the FI bit in the control register, thus disabling hit-under-miss without putting the processor into full low interrupt latency mode. Signed-off-by: Catalin Marinas Tested-by: Siarhei Siamashka Signed-off-by: Russell King --- arch/arm/Kconfig | 12 ++++++++++++ arch/arm/mm/proc-v6.S | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5ebc5d922ea1..3269576dbfa8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1271,6 +1271,18 @@ config ARM_ERRATA_754327 This workaround defines cpu_relax() as smp_mb(), preventing correctly written polling loops from denying visibility of updates to memory. +config ARM_ERRATA_364296 + bool "ARM errata: Possible cache data corruption with hit-under-miss enabled" + depends on CPU_V6 && !SMP + help + This options enables the workaround for the 364296 ARM1136 + r0p2 erratum (possible cache data corruption with + hit-under-miss enabled). It sets the undocumented bit 31 in + the auxiliary control register and the FI bit in the control + register, thus disabling hit-under-miss without putting the + processor into full low interrupt latency mode. ARM11MPCore + is not affected. + endmenu source "arch/arm/common/Kconfig" diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 219138d2f158..a923aa0fd00d 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -223,6 +223,22 @@ __v6_setup: mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, r0, r5 @ clear bits them orr r0, r0, r6 @ set them +#ifdef CONFIG_ARM_ERRATA_364296 + /* + * Workaround for the 364296 ARM1136 r0p2 erratum (possible cache data + * corruption with hit-under-miss enabled). The conditional code below + * (setting the undocumented bit 31 in the auxiliary control register + * and the FI bit in the control register) disables hit-under-miss + * without putting the processor into full low interrupt latency mode. + */ + ldr r6, =0x4107b362 @ id for ARM1136 r0p2 + mrc p15, 0, r5, c0, c0, 0 @ get processor id + teq r5, r6 @ check for the faulty core + mrceq p15, 0, r5, c1, c0, 1 @ load aux control reg + orreq r5, r5, #(1 << 31) @ set the undocumented bit 31 + mcreq p15, 0, r5, c1, c0, 1 @ write aux control reg + orreq r0, r0, #(1 << 21) @ low interrupt latency configuration +#endif mov pc, lr @ return to head.S:__ret /* From 795858dbd253462a67e14272edeaae73c6074b17 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Aug 2011 13:02:37 -0700 Subject: [PATCH 054/249] ceph: fix encoding of ino only (not relative) paths A 'path' consists of a starting ino and relative component. Encode even when there is no relative component. This is primarily needed by the NFS reexport code. Signed-off-by: Sage Weil --- fs/ceph/mds_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index fee028b5332e..86c59e16ba74 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1595,7 +1595,7 @@ static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry, r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath); dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen, *ppath); - } else if (rpath) { + } else if (rpath || rino) { *ino = rino; *ppath = rpath; *pathlen = strlen(rpath); From 42c0d26d2c32941e93ee805b32f7aebf8ba0a7d4 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Thu, 18 Aug 2011 21:14:28 +0900 Subject: [PATCH 055/249] ARM: EXYNOS4: Turn the mach-smdkc210.c into mach-smdv310.c Since the components on SMDKC210 are similar with SMDKV310 even though its memory is different. So we can support the SMDKC210 and SMDKV310 on mach-smdkv310.c, one machine file. Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/Kconfig | 17 +- arch/arm/mach-exynos4/Makefile | 2 +- arch/arm/mach-exynos4/mach-smdkc210.c | 309 -------------------------- arch/arm/mach-exynos4/mach-smdkv310.c | 78 +++++++ 4 files changed, 80 insertions(+), 326 deletions(-) delete mode 100644 arch/arm/mach-exynos4/mach-smdkc210.c diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 0c77ab99fa16..bee8f77de2ab 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -113,22 +113,7 @@ menu "EXYNOS4 Machines" config MACH_SMDKC210 bool "SMDKC210" - select CPU_EXYNOS4210 - select S5P_DEV_FIMD0 - select S3C_DEV_RTC - select S3C_DEV_WDT - select S3C_DEV_I2C1 - select S3C_DEV_HSMMC - select S3C_DEV_HSMMC1 - select S3C_DEV_HSMMC2 - select S3C_DEV_HSMMC3 - select SAMSUNG_DEV_PWM - select SAMSUNG_DEV_BACKLIGHT - select EXYNOS4_DEV_PD - select EXYNOS4_DEV_SYSMMU - select EXYNOS4_SETUP_FIMD0 - select EXYNOS4_SETUP_I2C1 - select EXYNOS4_SETUP_SDHCI + select MACH_SMDKV310 help Machine support for Samsung SMDKC210 diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index b7fe1d7b0b1f..e3e93ea41385 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile @@ -25,7 +25,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o # machine support -obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o +obj-$(CONFIG_MACH_SMDKC210) += mach-smdkv310.o obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o obj-$(CONFIG_MACH_ARMLEX4210) += mach-armlex4210.o obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c deleted file mode 100644 index a7c65e05c1eb..000000000000 --- a/arch/arm/mach-exynos4/mach-smdkc210.c +++ /dev/null @@ -1,309 +0,0 @@ -/* linux/arch/arm/mach-exynos4/mach-smdkc210.c - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include