aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS22
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c4
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c9
-rw-r--r--arch/arm/mach-omap2/pm34xx.c4
-rw-r--r--arch/arm/mach-omap2/usb-ehci.c2
-rw-r--r--arch/arm/plat-omap/dmtimer.c6
-rw-r--r--arch/arm/plat-omap/gpio.c1
-rw-r--r--arch/arm/plat-omap/iovmm.c4
-rw-r--r--arch/um/os-Linux/mem.c1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c23
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/Makefile6
-rw-r--r--drivers/rtc/rtc-ds1307.c4
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c143
-rw-r--r--drivers/staging/batman-adv/bat_sysfs.c24
-rw-r--r--drivers/staging/batman-adv/device.c2
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c9
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c3
-rw-r--r--drivers/staging/hv/channel_mgmt.c41
-rw-r--r--drivers/staging/hv/hv_utils.c28
-rw-r--r--drivers/staging/hv/vmbus.h2
-rw-r--r--drivers/staging/hv/vmbus_drv.c3
-rw-r--r--drivers/staging/mrst-touchscreen/intel-mid-touch.c2
-rw-r--r--drivers/staging/rt2860/usb_main_dev.c1
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c2
-rw-r--r--drivers/staging/rtl8192su/r8192U_core.c43
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c2
-rw-r--r--drivers/staging/usbip/usbip_common.c46
-rw-r--r--drivers/staging/wlags49_h2/wl_enc.c1
-rw-r--r--drivers/staging/wlags49_h2/wl_sysfs.h4
-rw-r--r--drivers/usb/core/driver.c13
-rw-r--r--drivers/usb/core/message.c7
-rw-r--r--drivers/usb/gadget/f_eem.c3
-rw-r--r--drivers/usb/gadget/f_mass_storage.c194
-rw-r--r--drivers/usb/gadget/g_ffs.c11
-rw-r--r--drivers/usb/gadget/printer.c32
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c6
-rw-r--r--drivers/usb/gadget/u_serial.c16
-rw-r--r--drivers/usb/host/ehci-mxc.c13
-rw-r--r--drivers/usb/host/isp1362-hcd.c15
-rw-r--r--drivers/usb/host/r8a66597-hcd.c2
-rw-r--r--drivers/usb/host/xhci-ring.c62
-rw-r--r--drivers/usb/musb/musb_core.c13
-rw-r--r--drivers/usb/musb/musb_core.h6
-rw-r--r--drivers/usb/musb/musbhsdma.c13
-rw-r--r--drivers/usb/otg/ulpi.c17
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h7
-rw-r--r--drivers/usb/serial/qcserial.c3
-rw-r--r--drivers/video/geode/gxfb_core.c20
-rw-r--r--drivers/video/geode/lxfb_core.c18
-rw-r--r--drivers/video/nuc900fb.c2
-rw-r--r--fs/binfmt_flat.c6
-rw-r--r--fs/fcntl.c6
-rw-r--r--fs/proc/task_nommu.c20
-rw-r--r--fs/sysv/ialloc.c6
-rw-r--r--include/linux/compiler-gcc.h10
-rw-r--r--include/linux/compiler-gcc4.h4
-rw-r--r--kernel/futex.c17
-rw-r--r--kernel/kexec.c7
-rw-r--r--lib/genalloc.c1
-rw-r--r--mm/memcontrol.c4
-rw-r--r--mm/mempolicy.c9
64 files changed, 572 insertions, 438 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6c73b3bc7f34..7642365ed6d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -896,11 +896,13 @@ S: Maintained
ARM/SAMSUNG ARM ARCHITECTURES
M: Ben Dooks <ben-linux@fluff.org>
+M: Kukjin Kim <kgene.kim@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.fluff.org/ben/linux/
S: Maintained
-F: arch/arm/plat-s3c/
+F: arch/arm/plat-samsung/
F: arch/arm/plat-s3c24xx/
+F: arch/arm/plat-s5p/
ARM/S3C2410 ARM ARCHITECTURE
M: Ben Dooks <ben-linux@fluff.org>
@@ -1148,7 +1150,7 @@ F: drivers/mmc/host/atmel-mci.c
F: drivers/mmc/host/atmel-mci-regs.h
ATMEL AT91 / AT32 SERIAL DRIVER
-M: Haavard Skinnemoen <hskinnemoen@atmel.com>
+M: Nicolas Ferre <nicolas.ferre@atmel.com>
S: Supported
F: drivers/serial/atmel_serial.c
@@ -1160,18 +1162,18 @@ F: drivers/video/atmel_lcdfb.c
F: include/video/atmel_lcdc.h
ATMEL MACB ETHERNET DRIVER
-M: Haavard Skinnemoen <hskinnemoen@atmel.com>
+M: Nicolas Ferre <nicolas.ferre@atmel.com>
S: Supported
F: drivers/net/macb.*
ATMEL SPI DRIVER
-M: Haavard Skinnemoen <hskinnemoen@atmel.com>
+M: Nicolas Ferre <nicolas.ferre@atmel.com>
S: Supported
F: drivers/spi/atmel_spi.*
ATMEL USBA UDC DRIVER
-M: Haavard Skinnemoen <hskinnemoen@atmel.com>
-L: kernel@avr32linux.org
+M: Nicolas Ferre <nicolas.ferre@atmel.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver
S: Supported
F: drivers/usb/gadget/atmel_usba_udc.*
@@ -3380,7 +3382,7 @@ KPROBES
M: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
M: "David S. Miller" <davem@davemloft.net>
-M: Masami Hiramatsu <mhiramat@redhat.com>
+M: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
S: Maintained
F: Documentation/kprobes.txt
F: include/linux/kprobes.h
@@ -4628,6 +4630,12 @@ M: Robert Jarzmik <robert.jarzmik@free.fr>
L: rtc-linux@googlegroups.com
S: Maintained
+QLOGIC QLA1280 SCSI DRIVER
+M: Michael Reed <mdr@sgi.com>
+L: linux-scsi@vger.kernel.org
+S: Maintained
+F: drivers/scsi/qla1280.[ch]
+
QLOGIC QLA2XXX FC-SCSI DRIVER
M: Andrew Vasquez <andrew.vasquez@qlogic.com>
M: linux-driver@qlogic.com
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index f848ba8dbc16..a04cffd691c5 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -538,9 +538,7 @@ static void ads7846_dev_init(void)
printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
gpio_direction_input(OMAP3_STALKER_TS_GPIO);
-
- omap_set_gpio_debounce(OMAP3_STALKER_TS_GPIO, 1);
- omap_set_gpio_debounce_time(OMAP3_STALKER_TS_GPIO, 0xa);
+ gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310);
}
static int ads7846_get_pendown_state(void)
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 02804224517b..e10db7a90cb2 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -1369,6 +1369,7 @@ static struct clk emif1_ick = {
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "l3_emif_clkdm",
.parent = &ddrphy_ck,
.recalc = &followparent_recalc,
@@ -1379,6 +1380,7 @@ static struct clk emif2_ick = {
.ops = &clkops_omap2_dflt,
.enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
.enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "l3_emif_clkdm",
.parent = &ddrphy_ck,
.recalc = &followparent_recalc,
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 95c9a5f774e1..b7a4133267d8 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -409,10 +409,11 @@ static int _init_main_clk(struct omap_hwmod *oh)
return 0;
oh->_clk = omap_clk_get_by_name(oh->main_clk);
- if (!oh->_clk)
+ if (!oh->_clk) {
pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
oh->name, oh->main_clk);
return -EINVAL;
+ }
if (!oh->_clk->clkdm)
pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
@@ -444,10 +445,11 @@ static int _init_interface_clks(struct omap_hwmod *oh)
continue;
c = omap_clk_get_by_name(os->clk);
- if (!c)
+ if (!c) {
pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
oh->name, os->clk);
ret = -EINVAL;
+ }
os->_clk = c;
}
@@ -470,10 +472,11 @@ static int _init_opt_clks(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
c = omap_clk_get_by_name(oc->clk);
- if (!c)
+ if (!c) {
pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
oh->name, oc->clk);
ret = -EINVAL;
+ }
oc->_clk = c;
}
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 2e967716cc3f..b88737fd6cfe 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -99,7 +99,7 @@ static void omap3_enable_io_chain(void)
/* Do a readback to assure write has been done */
prm_read_mod_reg(WKUP_MOD, PM_WKEN);
- while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+ while (!(prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
OMAP3430_ST_IO_CHAIN_MASK)) {
timeout++;
if (timeout > 1000) {
@@ -108,7 +108,7 @@ static void omap3_enable_io_chain(void)
return;
}
prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
- WKUP_MOD, PM_WKST);
+ WKUP_MOD, PM_WKEN);
}
}
}
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c
index c68f799e83c5..d72d1ac30333 100644
--- a/arch/arm/mach-omap2/usb-ehci.c
+++ b/arch/arm/mach-omap2/usb-ehci.c
@@ -20,6 +20,8 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
#include <asm/io.h>
#include <plat/mux.h>
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index c64875f11fac..44bafdab2dce 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -541,11 +541,11 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer)
* timer is stopped
*/
udelay(3500000 / clk_get_rate(timer->fclk) + 1);
- /* Ack possibly pending interrupt */
- omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
- OMAP_TIMER_INT_OVERFLOW);
#endif
}
+ /* Ack possibly pending interrupt */
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
+ OMAP_TIMER_INT_OVERFLOW);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 393e9219a5b6..9b7e3545f325 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -673,6 +673,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
if (cpu_is_omap34xx() || cpu_is_omap44xx())
clk_disable(bank->dbck);
}
+ bank->dbck_enable_mask = val;
__raw_writel(val, reg);
}
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index e43983ba59c5..8ce0de247c71 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -140,8 +140,10 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
return ERR_PTR(-ENOMEM);
err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
- if (err)
+ if (err) {
+ kfree(sgt);
return ERR_PTR(err);
+ }
pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 93a11d7edfa0..e696144d2be3 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fcntl.h>
#include <string.h>
+#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/param.h>
#include "init.h"
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 35603dd4e6c5..094bdc355b1f 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -302,6 +302,12 @@ struct smi_info {
static int force_kipmid[SI_MAX_PARMS];
static int num_force_kipmid;
+#ifdef CONFIG_PCI
+static int pci_registered;
+#endif
+#ifdef CONFIG_PPC_OF
+static int of_registered;
+#endif
static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
static int num_max_busy_us;
@@ -1018,7 +1024,7 @@ static int ipmi_thread(void *data)
else if (smi_result == SI_SM_IDLE)
schedule_timeout_interruptible(100);
else
- schedule_timeout_interruptible(0);
+ schedule_timeout_interruptible(1);
}
return 0;
}
@@ -3314,6 +3320,8 @@ static __devinit int init_ipmi_si(void)
rv = pci_register_driver(&ipmi_pci_driver);
if (rv)
printk(KERN_ERR PFX "Unable to register PCI driver: %d\n", rv);
+ else
+ pci_registered = 1;
#endif
#ifdef CONFIG_ACPI
@@ -3330,6 +3338,7 @@ static __devinit int init_ipmi_si(void)
#ifdef CONFIG_PPC_OF
of_register_platform_driver(&ipmi_of_platform_driver);
+ of_registered = 1;
#endif
/* We prefer devices with interrupts, but in the case of a machine
@@ -3383,11 +3392,13 @@ static __devinit int init_ipmi_si(void)
if (unload_when_empty && list_empty(&smi_infos)) {
mutex_unlock(&smi_infos_lock);
#ifdef CONFIG_PCI
- pci_unregister_driver(&ipmi_pci_driver);
+ if (pci_registered)
+ pci_unregister_driver(&ipmi_pci_driver);
#endif
#ifdef CONFIG_PPC_OF
- of_unregister_platform_driver(&ipmi_of_platform_driver);
+ if (of_registered)
+ of_unregister_platform_driver(&ipmi_of_platform_driver);
#endif
driver_unregister(&ipmi_driver.driver);
printk(KERN_WARNING PFX
@@ -3478,14 +3489,16 @@ static __exit void cleanup_ipmi_si(void)
return;
#ifdef CONFIG_PCI
- pci_unregister_driver(&ipmi_pci_driver);
+ if (pci_registered)
+ pci_unregister_driver(&ipmi_pci_driver);
#endif
#ifdef CONFIG_ACPI
pnp_unregister_driver(&ipmi_pnp_driver);
#endif
#ifdef CONFIG_PPC_OF
- of_unregister_platform_driver(&ipmi_of_platform_driver);
+ if (of_registered)
+ of_unregister_platform_driver(&ipmi_of_platform_driver);
#endif
mutex_lock(&smi_infos_lock);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 724038dab4ca..7face915b963 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1,5 +1,5 @@
#
-# GPIO infrastructure and expanders
+# platform-neutral GPIO infrastructure and expanders
#
config ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 51c3cdd41b5a..e53dcff49b4f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -1,4 +1,8 @@
-# gpio support: dedicated expander chips, etc
+# generic gpio support: dedicated expander chips, etc
+#
+# NOTE: platform-specific GPIO drivers don't belong in the
+# drivers/gpio directory; put them with other platform setup
+# code, IRQ controllers, board init, etc.
ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index de033b7ac21f..d827ce570a8c 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -777,7 +777,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
read_rtc:
/* read RTC registers */
- tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf);
+ tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, buf);
if (tmp != 8) {
pr_debug("read error %d\n", tmp);
err = -EIO;
@@ -862,7 +862,7 @@ read_rtc:
if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
tmp += 12;
i2c_smbus_write_byte_data(client,
- DS1307_REG_HOUR,
+ ds1307->offset + DS1307_REG_HOUR,
bin2bcd(tmp));
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 9eb62a256e9a..cd6cf575902e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
}
}
+#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE)
+/*
+ * Write a string to the serial port
+ * Note that this is called with interrupts already disabled
+ */
+static void cpm_uart_early_write(struct uart_cpm_port *pinfo,
+ const char *string, u_int count)
+{
+ unsigned int i;
+ cbd_t __iomem *bdp, *bdbase;
+ unsigned char *cpm_outp_addr;
+
+ /* Get the address of the host memory buffer.
+ */
+ bdp = pinfo->tx_cur;
+ bdbase = pinfo->tx_bd_base;
+
+ /*
+ * Now, do each character. This is not as bad as it looks
+ * since this is a holding FIFO and not a transmitting FIFO.
+ * We could add the complexity of filling the entire transmit
+ * buffer, but we would just wait longer between accesses......
+ */
+ for (i = 0; i < count; i++, string++) {
+ /* Wait for transmitter fifo to empty.
+ * Ready indicates output is ready, and xmt is doing
+ * that, not that it is ready for us to send.
+ */
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
+ ;
+
+ /* Send the character out.
+ * If the buffer address is in the CPM DPRAM, don't
+ * convert it.
+ */
+ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr),
+ pinfo);
+ *cpm_outp_addr = *string;
+
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
+
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
+ bdp = bdbase;
+ else
+ bdp++;
+
+ /* if a LF, also do CR... */
+ if (*string == 10) {
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
+ ;
+
+ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr),
+ pinfo);
+ *cpm_outp_addr = 13;
+
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
+
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
+ bdp = bdbase;
+ else
+ bdp++;
+ }
+ }
+
+ /*
+ * Finally, Wait for transmitter & holding register to empty
+ * and restore the IER
+ */
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
+ ;
+
+ pinfo->tx_cur = bdp;
+}
+#endif
+
#ifdef CONFIG_CONSOLE_POLL
/* Serial polling routines for writing and reading from the uart while
* in an interrupt or debug context.
@@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port,
static char ch[2];
ch[0] = (char)c;
- cpm_uart_early_write(pinfo->port.line, ch, 1);
+ cpm_uart_early_write(pinfo, ch, 1);
}
#endif /* CONFIG_CONSOLE_POLL */
@@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s,
u_int count)
{
struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
- unsigned int i;
- cbd_t __iomem *bdp, *bdbase;
- unsigned char *cp;
unsigned long flags;
int nolock = oops_in_progress;
@@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
spin_lock_irqsave(&pinfo->port.lock, flags);
}
- /* Get the address of the host memory buffer.
- */
- bdp = pinfo->tx_cur;
- bdbase = pinfo->tx_bd_base;
-
- /*
- * Now, do each character. This is not as bad as it looks
- * since this is a holding FIFO and not a transmitting FIFO.
- * We could add the complexity of filling the entire transmit
- * buffer, but we would just wait longer between accesses......
- */
- for (i = 0; i < count; i++, s++) {
- /* Wait for transmitter fifo to empty.
- * Ready indicates output is ready, and xmt is doing
- * that, not that it is ready for us to send.
- */
- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
- ;
-
- /* Send the character out.
- * If the buffer address is in the CPM DPRAM, don't
- * convert it.
- */
- cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
- *cp = *s;
-
- out_be16(&bdp->cbd_datlen, 1);
- setbits16(&bdp->cbd_sc, BD_SC_READY);
-
- if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
- bdp = bdbase;
- else
- bdp++;
-
- /* if a LF, also do CR... */
- if (*s == 10) {
- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
- ;
-
- cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
- *cp = 13;
-
- out_be16(&bdp->cbd_datlen, 1);
- setbits16(&bdp->cbd_sc, BD_SC_READY);
-
- if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
- bdp = bdbase;
- else
- bdp++;
- }
- }
-
- /*
- * Finally, Wait for transmitter & holding register to empty
- * and restore the IER
- */
- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
- ;
-
- pinfo->tx_cur = bdp;
+ cpm_uart_early_write(pinfo, s, count);
if (unlikely(nolock)) {
local_irq_restore(flags);
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c
index e2c000b80ca0..212bc21e6d68 100644
--- a/drivers/staging/batman-adv/bat_sysfs.c
+++ b/drivers/staging/batman-adv/bat_sysfs.c
@@ -225,9 +225,9 @@ static struct bat_attribute *mesh_attrs[] = {
NULL,
};
-static ssize_t transtable_local_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
+static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buff, loff_t off, size_t count)
{
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
@@ -235,9 +235,9 @@ static ssize_t transtable_local_read(struct kobject *kobj,
return hna_local_fill_buffer_text(net_dev, buff, count, off);
}
-static ssize_t transtable_global_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
+static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buff, loff_t off, size_t count)
{
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
@@ -245,9 +245,9 @@ static ssize_t transtable_global_read(struct kobject *kobj,
return hna_global_fill_buffer_text(net_dev, buff, count, off);
}
-static ssize_t originators_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
+static ssize_t originators_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buff, loff_t off, size_t count)
{
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
@@ -255,9 +255,9 @@ static ssize_t originators_read(struct kobject *kobj,
return orig_fill_buffer_text(net_dev, buff, count, off);
}
-static ssize_t vis_data_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
+static ssize_t vis_data_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buff, loff_t off, size_t count)
{
struct device *dev = to_dev(kobj->parent);
struct net_device *net_dev = to_net_dev(dev);
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c
index 7eb6559e0315..32204b5572d0 100644
--- a/drivers/staging/batman-adv/device.c
+++ b/drivers/staging/batman-adv/device.c
@@ -196,7 +196,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
kfree(device_packet);
if (error)
- return error;
+ return -EFAULT;
return sizeof(struct icmp_packet);
}
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 36a254cd4413..39d112b708e3 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -824,9 +824,12 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
false, true, true);
- dev_private->scan_delay =
- (async_cmd->scan_begin_arg / (async_cmd->convert_arg *
- async_cmd->chanlist_len)) - 1;
+ if (async_cmd->scan_begin_src == TRIG_TIMER) {
+ dev_private->scan_delay =
+ (async_cmd->scan_begin_arg /
+ (async_cmd->convert_arg *
+ async_cmd->chanlist_len)) - 1;
+ }
break;
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 81829d6fd287..c374bee25068 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -52,7 +52,6 @@ Please report success/failure with other different cards to
#include "8255.h"
#define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */
-#define N_BOARDS 10 /* Number of boards in cb_pcidda_boards */
#define EEPROM_SIZE 128 /* number of entries in eeprom */
#define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */
@@ -307,7 +306,7 @@ static int cb_pcidda_attach(struct comedi_device *dev,
continue;
}
}
- for (index = 0; index < N_BOARDS; index++) {
+ for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) {
if (cb_pcidda_boards[index].device_id ==
pcidev->device) {
goto found;
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index 3f53b4d1e4cf..12db555a3a5d 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/completion.h>
#include "osd.h"
#include "logging.h"
#include "vmbus_private.h"
@@ -293,6 +294,25 @@ void FreeVmbusChannel(struct vmbus_channel *Channel)
Channel);
}
+
+DECLARE_COMPLETION(hv_channel_ready);
+
+/*
+ * Count initialized channels, and ensure all channels are ready when hv_vmbus
+ * module loading completes.
+ */
+static void count_hv_channel(void)
+{
+ static int counter;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+ if (++counter == MAX_MSG_TYPES)
+ complete(&hv_channel_ready);
+ spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+}
+
+
/*
* VmbusChannelProcessOffer - Process the offer by creating a channel/device
* associated with this offer
@@ -373,22 +393,21 @@ static void VmbusChannelProcessOffer(void *context)
* can cleanup properly
*/
newChannel->State = CHANNEL_OPEN_STATE;
- cnt = 0;
- while (cnt != MAX_MSG_TYPES) {
+ /* Open IC channels */
+ for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType,
&hv_cb_utils[cnt].data,
- sizeof(struct hv_guid)) == 0) {
+ sizeof(struct hv_guid)) == 0 &&
+ VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
+ 2 * PAGE_SIZE, NULL, 0,
+ hv_cb_utils[cnt].callback,
+ newChannel) == 0) {
+ hv_cb_utils[cnt].channel = newChannel;
DPRINT_INFO(VMBUS, "%s",
- hv_cb_utils[cnt].log_msg);
-
- if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
- 2 * PAGE_SIZE, NULL, 0,
- hv_cb_utils[cnt].callback,
- newChannel) == 0)
- hv_cb_utils[cnt].channel = newChannel;
+ hv_cb_utils[cnt].log_msg);
+ count_hv_channel();
}
- cnt++;
}
}
DPRINT_EXIT(VMBUS);
diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c
index 8a49aafea37a..2adc9b48ca9c 100644
--- a/drivers/staging/hv/hv_utils.c
+++ b/drivers/staging/hv/hv_utils.c
@@ -24,6 +24,8 @@
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/reboot.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
#include "logging.h"
#include "osd.h"
@@ -251,10 +253,36 @@ static void heartbeat_onchannelcallback(void *context)
DPRINT_EXIT(VMBUS);
}
+static const struct pci_device_id __initconst
+hv_utils_pci_table[] __maybe_unused = {
+ { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, hv_utils_pci_table);
+
+
+static const struct dmi_system_id __initconst
+hv_utils_dmi_table[] __maybe_unused = {
+ {
+ .ident = "Hyper-V",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+ DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
+ },
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table);
+
+
static int __init init_hyperv_utils(void)
{
printk(KERN_INFO "Registering HyperV Utility Driver\n");
+ if (!dmi_check_system(hv_utils_dmi_table))
+ return -ENODEV;
+
hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
&shutdown_onchannelcallback;
hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h
index 0c6ee0f487f3..3c14b2926e00 100644
--- a/drivers/staging/hv/vmbus.h
+++ b/drivers/staging/hv/vmbus.h
@@ -74,4 +74,6 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx);
void vmbus_child_driver_unregister(struct driver_context *driver_ctx);
void vmbus_get_interface(struct vmbus_channel_interface *interface);
+extern struct completion hv_channel_ready;
+
#endif /* _VMBUS_H_ */
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index c21731a12ca7..22c80ece6388 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <linux/completion.h>
#include "version_info.h"
#include "osd.h"
#include "logging.h"
@@ -356,6 +357,8 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
vmbus_drv_obj->GetChannelOffers();
+ wait_for_completion(&hv_channel_ready);
+
cleanup:
DPRINT_EXIT(VMBUS_DRV);
diff --git a/drivers/staging/mrst-touchscreen/intel-mid-touch.c b/drivers/staging/mrst-touchscreen/intel-mid-touch.c
index 1db00975a594..abba22f921be 100644
--- a/drivers/staging/mrst-touchscreen/intel-mid-touch.c
+++ b/drivers/staging/mrst-touchscreen/intel-mid-touch.c
@@ -817,9 +817,9 @@ static int mrstouch_remove(struct spi_device *spi)
free_irq(mrstouchdevp->irq, mrstouchdevp);
input_unregister_device(mrstouchdevp->input);
input_free_device(mrstouchdevp->input);
- kfree(mrstouchdevp);
if (mrstouchdevp->pendet_thrd)
kthread_stop(mrstouchdevp->pendet_thrd);
+ kfree(mrstouchdevp);
return 0;
}
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index b740662d095a..674769d2b59b 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -77,6 +77,7 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */
{USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */
{USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */
+ {USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */
{USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */
{USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */
{USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index dacefea78113..49ab9fa9ffa7 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -66,8 +66,6 @@ static int hwseqnum = 0;
static int hwwep = 0;
static int channels = 0x3fff;
-#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
-#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c
index 447d6474a70c..1b6890611fb6 100644
--- a/drivers/staging/rtl8192su/r8192U_core.c
+++ b/drivers/staging/rtl8192su/r8192U_core.c
@@ -112,28 +112,29 @@ u32 rt_global_debug_component = \
#define CAM_CONTENT_COUNT 8
static const struct usb_device_id rtl8192_usb_id_tbl[] = {
- /* Realtek */
- {USB_DEVICE(0x0bda, 0x8171)},
- {USB_DEVICE(0x0bda, 0x8192)},
- {USB_DEVICE(0x0bda, 0x8709)},
- /* Corega */
- {USB_DEVICE(0x07aa, 0x0043)},
- /* Belkin */
- {USB_DEVICE(0x050d, 0x805E)},
- {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
- /* Sitecom */
- {USB_DEVICE(0x0df6, 0x0031)},
- {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
- /* EnGenius */
- {USB_DEVICE(0x1740, 0x9201)},
- /* Dlink */
- {USB_DEVICE(0x2001, 0x3301)},
- /* Zinwell */
- {USB_DEVICE(0x5a57, 0x0290)},
- /* Guillemot */
- {USB_DEVICE(0x06f8, 0xe031)},
- //92SU
+ {USB_DEVICE(0x0bda, 0x8171)}, /* Realtek */
{USB_DEVICE(0x0bda, 0x8172)},
+ {USB_DEVICE(0x0bda, 0x8173)},
+ {USB_DEVICE(0x0bda, 0x8174)},
+ {USB_DEVICE(0x0bda, 0x8712)},
+ {USB_DEVICE(0x0bda, 0x8713)},
+ {USB_DEVICE(0x07aa, 0x0047)},
+ {USB_DEVICE(0x07d1, 0x3303)},
+ {USB_DEVICE(0x07d1, 0x3302)},
+ {USB_DEVICE(0x07d1, 0x3300)},
+ {USB_DEVICE(0x1740, 0x9603)},
+ {USB_DEVICE(0x1740, 0x9605)},
+ {USB_DEVICE(0x050d, 0x815F)},
+ {USB_DEVICE(0x06f8, 0xe031)},
+ {USB_DEVICE(0x7392, 0x7611)},
+ {USB_DEVICE(0x7392, 0x7612)},
+ {USB_DEVICE(0x7392, 0x7622)},
+ {USB_DEVICE(0x0DF6, 0x0045)},
+ {USB_DEVICE(0x0E66, 0x0015)},
+ {USB_DEVICE(0x0E66, 0x0016)},
+ {USB_DEVICE(0x0b05, 0x1786)},
+ /* these are not in the official list */
+ {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
{}
};
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 2bede271a2f0..f38472c2e75c 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -121,6 +121,8 @@ static const struct usb_device_id rtl8192_usb_id_tbl[] = {
{USB_DEVICE(0x2001, 0x3301)},
/* Zinwell */
{USB_DEVICE(0x5a57, 0x0290)},
+ /* LG */
+ {USB_DEVICE(0x043e, 0x7a01)},
{}
};
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 52408164036f..6a499f0eb594 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -378,47 +378,67 @@ int usbip_thread(void *param)
complete_and_exit(&ut->thread_done, 0);
}
+static void stop_rx_thread(struct usbip_device *ud)
+{
+ if (ud->tcp_rx.thread != NULL) {
+ send_sig(SIGKILL, ud->tcp_rx.thread, 1);
+ wait_for_completion(&ud->tcp_rx.thread_done);
+ usbip_udbg("rx_thread for ud %p has finished\n", ud);
+ }
+}
+
+static void stop_tx_thread(struct usbip_device *ud)
+{
+ if (ud->tcp_tx.thread != NULL) {
+ send_sig(SIGKILL, ud->tcp_tx.thread, 1);
+ wait_for_completion(&ud->tcp_tx.thread_done);
+ usbip_udbg("tx_thread for ud %p has finished\n", ud);
+ }
+}
+
int usbip_start_threads(struct usbip_device *ud)
{
/*
* threads are invoked per one device (per one connection).
*/
struct task_struct *th;
+ int err = 0;
th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
if (IS_ERR(th)) {
printk(KERN_WARNING
"Unable to start control thread\n");
- return PTR_ERR(th);
+ err = PTR_ERR(th);
+ goto ust_exit;
}
+
th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
if (IS_ERR(th)) {
printk(KERN_WARNING
"Unable to start control thread\n");
- return PTR_ERR(th);
+ err = PTR_ERR(th);
+ goto tx_thread_err;
}
/* confirm threads are starting */
wait_for_completion(&ud->tcp_rx.thread_done);
wait_for_completion(&ud->tcp_tx.thread_done);
+
return 0;
+
+tx_thread_err:
+ stop_rx_thread(ud);
+
+ust_exit:
+ return err;
}
EXPORT_SYMBOL_GPL(usbip_start_threads);
void usbip_stop_threads(struct usbip_device *ud)
{
/* kill threads related to this sdev, if v.c. exists */
- if (ud->tcp_rx.thread != NULL) {
- send_sig(SIGKILL, ud->tcp_rx.thread, 1);
- wait_for_completion(&ud->tcp_rx.thread_done);
- usbip_udbg("rx_thread for ud %p has finished\n", ud);
- }
-
- if (ud->tcp_tx.thread != NULL) {
- send_sig(SIGKILL, ud->tcp_tx.thread, 1);
- wait_for_completion(&ud->tcp_tx.thread_done);
- usbip_udbg("tx_thread for ud %p has finished\n", ud);
- }
+ stop_rx_thread(ud);
+ stop_tx_thread(ud);
}
EXPORT_SYMBOL_GPL(usbip_stop_threads);
diff --git a/drivers/staging/wlags49_h2/wl_enc.c b/drivers/staging/wlags49_h2/wl_enc.c
index 48c44c8fdb28..26cf5486edd6 100644
--- a/drivers/staging/wlags49_h2/wl_enc.c
+++ b/drivers/staging/wlags49_h2/wl_enc.c
@@ -62,6 +62,7 @@
/*******************************************************************************
* include files
******************************************************************************/
+#include <linux/string.h>
#include <wl_version.h>
#include <debug.h>
diff --git a/drivers/staging/wlags49_h2/wl_sysfs.h b/drivers/staging/wlags49_h2/wl_sysfs.h
index 6d96d03cf490..fa658c38001e 100644
--- a/drivers/staging/wlags49_h2/wl_sysfs.h
+++ b/drivers/staging/wlags49_h2/wl_sysfs.h
@@ -2,6 +2,6 @@
extern void register_wlags_sysfs(struct net_device *);
extern void unregister_wlags_sysfs(struct net_device *);
#else
-static void register_wlags_sysfs(struct net_device *) { return; };
-static void unregister_wlags_sysfs(struct net_device *) { return; };
+static inline void register_wlags_sysfs(struct net_device *net) { }
+static inline void unregister_wlags_sysfs(struct net_device *net) { }
#endif
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index de98a94d1853..a6bd53ace035 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1272,8 +1272,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
{
- int w, i;
- struct usb_interface *intf;
+ int w;
/* Remote wakeup is needed only when we actually go to sleep.
* For things like FREEZE and QUIESCE, if the device is already
@@ -1285,16 +1284,10 @@ static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
return;
}
- /* If remote wakeup is permitted, see whether any interface drivers
+ /* Enable remote wakeup if it is allowed, even if no interface drivers
* actually want it.
*/
- w = 0;
- if (device_may_wakeup(&udev->dev) && udev->actconfig) {
- for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
- intf = udev->actconfig->interface[i];
- w |= intf->needs_remote_wakeup;
- }
- }
+ w = device_may_wakeup(&udev->dev);
/* If the device is autosuspended with the wrong wakeup setting,
* autoresume now so the setting can be changed.
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index a73e08fdab36..fd4c36ea5e46 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -416,8 +416,11 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
/* A length of zero means transfer the whole sg list */
len = length;
if (len == 0) {
- for_each_sg(sg, sg, nents, i)
- len += sg->length;
+ struct scatterlist *sg2;
+ int j;
+
+ for_each_sg(sg, sg2, nents, j)
+ len += sg2->length;
}
} else {
/*
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index 38226e9a371d..95dd4662d6a8 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -469,8 +469,7 @@ static int eem_unwrap(struct gether *port,
crc = get_unaligned_le32(skb->data + len
- ETH_FCS_LEN);
crc2 = ~crc32_le(~0,
- skb->data,
- skb->len - ETH_FCS_LEN);
+ skb->data, len - ETH_FCS_LEN);
} else {
crc = get_unaligned_be32(skb->data + len
- ETH_FCS_LEN);
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 7d05a0be5c60..4ce899c9b165 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -321,8 +321,8 @@ struct fsg_dev;
/* Data shared by all the FSG instances. */
struct fsg_common {
struct usb_gadget *gadget;
- struct fsg_dev *fsg;
- struct fsg_dev *prev_fsg;
+ struct fsg_dev *fsg, *new_fsg;
+ wait_queue_head_t fsg_wait;
/* filesem protects: backing files in use */
struct rw_semaphore filesem;
@@ -351,7 +351,6 @@ struct fsg_common {
enum fsg_state state; /* For exception handling */
unsigned int exception_req_tag;
- u8 config, new_config;
enum data_direction data_dir;
u32 data_size;
u32 data_size_from_cmnd;
@@ -595,7 +594,7 @@ static int fsg_setup(struct usb_function *f,
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
- if (!fsg->common->config)
+ if (!fsg_is_set(fsg->common))
return -EOPNOTSUPP;
switch (ctrl->bRequest) {
@@ -2303,24 +2302,20 @@ static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
return -ENOMEM;
}
-/*
- * Reset interface setting and re-init endpoint state (toggle etc).
- * Call with altsetting < 0 to disable the interface. The only other
- * available altsetting is 0, which enables the interface.
- */
-static int do_set_interface(struct fsg_common *common, int altsetting)
+/* Reset interface setting and re-init endpoint state (toggle etc). */
+static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
{
- int rc = 0;
- int i;
- const struct usb_endpoint_descriptor *d;
+ const struct usb_endpoint_descriptor *d;
+ struct fsg_dev *fsg;
+ int i, rc = 0;
if (common->running)
DBG(common, "reset interface\n");
reset:
/* Deallocate the requests */
- if (common->prev_fsg) {
- struct fsg_dev *fsg = common->prev_fsg;
+ if (common->fsg) {
+ fsg = common->fsg;
for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
struct fsg_buffhd *bh = &common->buffhds[i];
@@ -2345,88 +2340,53 @@ reset:
fsg->bulk_out_enabled = 0;
}
- common->prev_fsg = 0;
+ common->fsg = NULL;
+ wake_up(&common->fsg_wait);
}
common->running = 0;
- if (altsetting < 0 || rc != 0)
+ if (!new_fsg || rc)
return rc;
- DBG(common, "set interface %d\n", altsetting);
+ common->fsg = new_fsg;
+ fsg = common->fsg;
- if (fsg_is_set(common)) {
- struct fsg_dev *fsg = common->fsg;
- common->prev_fsg = common->fsg;
+ /* Enable the endpoints */
+ d = fsg_ep_desc(common->gadget,
+ &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
+ rc = enable_endpoint(common, fsg->bulk_in, d);
+ if (rc)
+ goto reset;
+ fsg->bulk_in_enabled = 1;
+
+ d = fsg_ep_desc(common->gadget,
+ &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
+ rc = enable_endpoint(common, fsg->bulk_out, d);
+ if (rc)
+ goto reset;
+ fsg->bulk_out_enabled = 1;
+ common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
+ clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
- /* Enable the endpoints */
- d = fsg_ep_desc(common->gadget,
- &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
- rc = enable_endpoint(common, fsg->bulk_in, d);
+ /* Allocate the requests */
+ for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+ struct fsg_buffhd *bh = &common->buffhds[i];
+
+ rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
if (rc)
goto reset;
- fsg->bulk_in_enabled = 1;
-
- d = fsg_ep_desc(common->gadget,
- &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
- rc = enable_endpoint(common, fsg->bulk_out, d);
+ rc = alloc_request(common, fsg->bulk_out, &bh->outreq);
if (rc)
goto reset;
- fsg->bulk_out_enabled = 1;
- common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
- clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
-
- /* Allocate the requests */
- for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
- struct fsg_buffhd *bh = &common->buffhds[i];
-
- rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
- if (rc)
- goto reset;
- rc = alloc_request(common, fsg->bulk_out, &bh->outreq);
- if (rc)
- goto reset;
- bh->inreq->buf = bh->outreq->buf = bh->buf;
- bh->inreq->context = bh->outreq->context = bh;
- bh->inreq->complete = bulk_in_complete;
- bh->outreq->complete = bulk_out_complete;
- }
-
- common->running = 1;
- for (i = 0; i < common->nluns; ++i)
- common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
- return rc;
- } else {
- return -EIO;
- }
-}
-
-
-/*
- * Change our operational configuration. This code must agree with the code
- * that returns config descriptors, and with interface altsetting code.
- *
- * It's also responsible for power management interactions. Some
- * configurations might not work with our current power sources.
- * For now we just assume the gadget is always self-powered.
- */
-static int do_set_config(struct fsg_common *common, u8 new_config)
-{
- int rc = 0;
-
- /* Disable the single interface */
- if (common->config != 0) {
- DBG(common, "reset config\n");
- common->config = 0;
- rc = do_set_interface(common, -1);
+ bh->inreq->buf = bh->outreq->buf = bh->buf;
+ bh->inreq->context = bh->outreq->context = bh;
+ bh->inreq->complete = bulk_in_complete;
+ bh->outreq->complete = bulk_out_complete;
}
- /* Enable the interface */
- if (new_config != 0) {
- common->config = new_config;
- rc = do_set_interface(common, 0);
- if (rc != 0)
- common->config = 0; /* Reset on errors */
- }
+ common->running = 1;
+ for (i = 0; i < common->nluns; ++i)
+ common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
return rc;
}
@@ -2437,9 +2397,7 @@ static int do_set_config(struct fsg_common *common, u8 new_config)
static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{
struct fsg_dev *fsg = fsg_from_func(f);
- fsg->common->prev_fsg = fsg->common->fsg;
- fsg->common->fsg = fsg;
- fsg->common->new_config = 1;
+ fsg->common->new_fsg = fsg;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
return 0;
}
@@ -2447,9 +2405,7 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
static void fsg_disable(struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
- fsg->common->prev_fsg = fsg->common->fsg;
- fsg->common->fsg = fsg;
- fsg->common->new_config = 0;
+ fsg->common->new_fsg = NULL;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
}
@@ -2459,19 +2415,17 @@ static void fsg_disable(struct usb_function *f)
static void handle_exception(struct fsg_common *common)
{
siginfo_t info;
- int sig;
int i;
struct fsg_buffhd *bh;
enum fsg_state old_state;
- u8 new_config;
struct fsg_lun *curlun;
unsigned int exception_req_tag;
- int rc;
/* Clear the existing signals. Anything but SIGUSR1 is converted
* into a high-priority EXIT exception. */
for (;;) {
- sig = dequeue_signal_lock(current, &current->blocked, &info);
+ int sig =
+ dequeue_signal_lock(current, &current->blocked, &info);
if (!sig)
break;
if (sig != SIGUSR1) {
@@ -2482,7 +2436,7 @@ static void handle_exception(struct fsg_common *common)
}
/* Cancel all the pending transfers */
- if (fsg_is_set(common)) {
+ if (likely(common->fsg)) {
for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
bh = &common->buffhds[i];
if (bh->inreq_busy)
@@ -2523,7 +2477,6 @@ static void handle_exception(struct fsg_common *common)
common->next_buffhd_to_fill = &common->buffhds[0];
common->next_buffhd_to_drain = &common->buffhds[0];
exception_req_tag = common->exception_req_tag;
- new_config = common->new_config;
old_state = common->state;
if (old_state == FSG_STATE_ABORT_BULK_OUT)
@@ -2573,12 +2526,12 @@ static void handle_exception(struct fsg_common *common)
break;
case FSG_STATE_CONFIG_CHANGE:
- rc = do_set_config(common, new_config);
+ do_set_interface(common, common->new_fsg);
break;
case FSG_STATE_EXIT:
case FSG_STATE_TERMINATED:
- do_set_config(common, 0); /* Free resources */
+ do_set_interface(common, NULL); /* Free resources */
spin_lock_irq(&common->lock);
common->state = FSG_STATE_TERMINATED; /* Stop the thread */
spin_unlock_irq(&common->lock);
@@ -2863,6 +2816,7 @@ buffhds_first_it:
goto error_release;
}
init_completion(&common->thread_notifier);
+ init_waitqueue_head(&common->fsg_wait);
#undef OR
@@ -2957,9 +2911,17 @@ static void fsg_common_release(struct kref *ref)
static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
+ struct fsg_common *common = fsg->common;
DBG(fsg, "unbind\n");
- fsg_common_put(fsg->common);
+ if (fsg->common->fsg == fsg) {
+ fsg->common->new_fsg = NULL;
+ raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+ /* FIXME: make interruptible or killable somehow? */
+ wait_event(common->fsg_wait, common->fsg != fsg);
+ }
+
+ fsg_common_put(common);
usb_free_descriptors(fsg->function.descriptors);
usb_free_descriptors(fsg->function.hs_descriptors);
kfree(fsg);
@@ -2970,7 +2932,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
struct usb_gadget *gadget = c->cdev->gadget;
- int rc;
int i;
struct usb_ep *ep;
@@ -2996,6 +2957,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
ep->driver_data = fsg->common; /* claim the endpoint */
fsg->bulk_out = ep;
+ /* Copy descriptors */
+ f->descriptors = usb_copy_descriptors(fsg_fs_function);
+ if (unlikely(!f->descriptors))
+ return -ENOMEM;
+
if (gadget_is_dualspeed(gadget)) {
/* Assume endpoint addresses are the same for both speeds */
fsg_hs_bulk_in_desc.bEndpointAddress =
@@ -3003,16 +2969,17 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
fsg_hs_bulk_out_desc.bEndpointAddress =
fsg_fs_bulk_out_desc.bEndpointAddress;
f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
- if (unlikely(!f->hs_descriptors))
+ if (unlikely(!f->hs_descriptors)) {
+ usb_free_descriptors(f->descriptors);
return -ENOMEM;
+ }
}
return 0;
autoconf_fail:
ERROR(fsg, "unable to autoconfigure all endpoints\n");
- rc = -ENOTSUPP;
- return rc;
+ return -ENOTSUPP;
}
@@ -3036,11 +3003,6 @@ static int fsg_add(struct usb_composite_dev *cdev,
fsg->function.name = FSG_DRIVER_DESC;
fsg->function.strings = fsg_strings_array;
- fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function);
- if (unlikely(!fsg->function.descriptors)) {
- rc = -ENOMEM;
- goto error_free_fsg;
- }
fsg->function.bind = fsg_bind;
fsg->function.unbind = fsg_unbind;
fsg->function.setup = fsg_setup;
@@ -3056,19 +3018,9 @@ static int fsg_add(struct usb_composite_dev *cdev,
rc = usb_add_function(c, &fsg->function);
if (unlikely(rc))
- goto error_free_all;
-
- fsg_common_get(fsg->common);
- return 0;
-
-error_free_all:
- usb_free_descriptors(fsg->function.descriptors);
- /* fsg_bind() might have copied those; or maybe not? who cares
- * -- free it just in case. */
- usb_free_descriptors(fsg->function.hs_descriptors);
-error_free_fsg:
- kfree(fsg);
-
+ kfree(fsg);
+ else
+ fsg_common_get(fsg->common);
return rc;
}
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 4b0e4a040d6f..d1af253a9105 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -392,6 +392,17 @@ static int __gfs_do_config(struct usb_configuration *c,
if (unlikely(ret < 0))
return ret;
+ /* After previous do_configs there may be some invalid
+ * pointers in c->interface array. This happens every time
+ * a user space function with fewer interfaces than a user
+ * space function that was run before the new one is run. The
+ * compasit's set_config() assumes that if there is no more
+ * then MAX_CONFIG_INTERFACES interfaces in a configuration
+ * then there is a NULL pointer after the last interface in
+ * c->interface array. We need to make sure this is true. */
+ if (c->next_interface_id < ARRAY_SIZE(c->interface))
+ c->interface[c->next_interface_id] = NULL;
+
return 0;
}
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 43abf55d8c60..4c3ac5c42237 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -82,7 +82,7 @@ static struct class *usb_gadget_class;
struct printer_dev {
spinlock_t lock; /* lock this structure */
/* lock buffer lists during read/write calls */
- spinlock_t lock_printer_io;
+ struct mutex lock_printer_io;
struct usb_gadget *gadget;
struct usb_request *req; /* for control responses */
u8 config;
@@ -567,7 +567,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
DBG(dev, "printer_read trying to read %d bytes\n", (int)len);
- spin_lock(&dev->lock_printer_io);
+ mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
/* We will use this flag later to check if a printer reset happened
@@ -601,7 +601,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
* call or not.
*/
if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -648,7 +648,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
if (dev->reset_printer) {
list_add(&current_rx_req->list, &dev->rx_reqs);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -673,7 +673,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
dev->current_rx_buf = current_rx_buf;
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied);
@@ -697,7 +697,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (len == 0)
return -EINVAL;
- spin_lock(&dev->lock_printer_io);
+ mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
/* Check if a printer reset happens while we have interrupts on */
@@ -713,7 +713,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
* a NON-Blocking call or not.
*/
if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -752,7 +752,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (copy_from_user(req->buf, buf, size)) {
list_add(&req->list, &dev->tx_reqs);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return bytes_copied;
}
@@ -766,14 +766,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (dev->reset_printer) {
list_add(&req->list, &dev->tx_reqs);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) {
list_add(&req->list, &dev->tx_reqs);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -782,7 +782,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
}
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied);
@@ -820,11 +820,11 @@ printer_poll(struct file *fd, poll_table *wait)
unsigned long flags;
int status = 0;
- spin_lock(&dev->lock_printer_io);
+ mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
setup_rx_reqs(dev);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
poll_wait(fd, &dev->rx_wait, wait);
poll_wait(fd, &dev->tx_wait, wait);
@@ -1461,7 +1461,7 @@ autoconf_fail:
}
spin_lock_init(&dev->lock);
- spin_lock_init(&dev->lock_printer_io);
+ mutex_init(&dev->lock_printer_io);
INIT_LIST_HEAD(&dev->tx_reqs);
INIT_LIST_HEAD(&dev->tx_reqs_active);
INIT_LIST_HEAD(&dev->rx_reqs);
@@ -1594,7 +1594,7 @@ cleanup(void)
{
int status;
- spin_lock(&usb_printer_gadget.lock_printer_io);
+ mutex_lock(&usb_printer_gadget.lock_printer_io);
class_destroy(usb_gadget_class);
unregister_chrdev_region(g_printer_devno, 2);
@@ -1602,6 +1602,6 @@ cleanup(void)
if (status)
ERROR(dev, "usb_gadget_unregister_driver %x\n", status);
- spin_unlock(&usb_printer_gadget.lock_printer_io);
+ mutex_unlock(&usb_printer_gadget.lock_printer_io);
}
module_exit(cleanup);
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index d5f4c1d45c97..e724a051bfdd 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1700,9 +1700,13 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (!driver || driver != udc->driver || !driver->unbind)
return -EINVAL;
- dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n",
+ dprintk(DEBUG_NORMAL, "usb_gadget_unregister_driver() '%s'\n",
driver->driver.name);
+ /* report disconnect */
+ if (driver->disconnect)
+ driver->disconnect(&udc->gadget);
+
driver->unbind(&udc->gadget);
device_del(&udc->gadget.dev);
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 16bdf77f582a..3e8dcb5455e3 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -536,17 +536,11 @@ recycle:
list_move(&req->list, &port->read_pool);
}
- /* Push from tty to ldisc; this is immediate with low_latency, and
- * may trigger callbacks to this driver ... so drop the spinlock.
+ /* Push from tty to ldisc; without low_latency set this is handled by
+ * a workqueue, so we won't get callbacks and can hold port_lock
*/
if (tty && do_push) {
- spin_unlock_irq(&port->port_lock);
tty_flip_buffer_push(tty);
- wake_up_interruptible(&tty->read_wait);
- spin_lock_irq(&port->port_lock);
-
- /* tty may have been closed */
- tty = port->port_tty;
}
@@ -784,11 +778,6 @@ static int gs_open(struct tty_struct *tty, struct file *file)
port->open_count = 1;
port->openclose = false;
- /* low_latency means ldiscs work in tasklet context, without
- * needing a workqueue schedule ... easier to keep up.
- */
- tty->low_latency = 1;
-
/* if connected, start the I/O stream */
if (port->port_usb) {
struct gserial *gser = port->port_usb;
@@ -1195,6 +1184,7 @@ void gserial_cleanup(void)
n_ports = 0;
tty_unregister_driver(gs_tty_driver);
+ put_tty_driver(gs_tty_driver);
gs_tty_driver = NULL;
pr_debug("%s: cleaned up ttyGS* support\n", __func__);
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 544ccfd7056e..bd4027745aa7 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -207,10 +207,17 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
/* Initialize the transceiver */
if (pdata->otg) {
pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
- if (otg_init(pdata->otg) != 0)
- dev_err(dev, "unable to init transceiver\n");
- else if (otg_set_vbus(pdata->otg, 1) != 0)
+ ret = otg_init(pdata->otg);
+ if (ret) {
+ dev_err(dev, "unable to init transceiver, probably missing\n");
+ ret = -ENODEV;
+ goto err_add;
+ }
+ ret = otg_set_vbus(pdata->otg, 1);
+ if (ret) {
dev_err(dev, "unable to enable vbus on transceiver\n");
+ goto err_add;
+ }
}
priv->hcd = hcd;
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 20a0dfe0fe36..0587ad4ce5c2 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2224,12 +2224,9 @@ static void remove_debug_file(struct isp1362_hcd *isp1362_hcd)
/*-------------------------------------------------------------------------*/
-static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd)
+static void __isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd)
{
int tmp = 20;
- unsigned long flags;
-
- spin_lock_irqsave(&isp1362_hcd->lock, flags);
isp1362_write_reg16(isp1362_hcd, HCSWRES, HCSWRES_MAGIC);
isp1362_write_reg32(isp1362_hcd, HCCMDSTAT, OHCI_HCR);
@@ -2240,6 +2237,14 @@ static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd)
}
if (!tmp)
pr_err("Software reset timeout\n");
+}
+
+static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&isp1362_hcd->lock, flags);
+ __isp1362_sw_reset(isp1362_hcd);
spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
}
@@ -2418,7 +2423,7 @@ static void isp1362_hc_stop(struct usb_hcd *hcd)
if (isp1362_hcd->board && isp1362_hcd->board->reset)
isp1362_hcd->board->reset(hcd->self.controller, 1);
else
- isp1362_sw_reset(isp1362_hcd);
+ __isp1362_sw_reset(isp1362_hcd);
if (isp1362_hcd->board && isp1362_hcd->board->clock)
isp1362_hcd->board->clock(hcd->self.controller, 0);
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 1a2bb4ce638f..77be3c24a427 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -1065,7 +1065,7 @@ static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port)
else if (speed == LSMODE)
rh->port |= USB_PORT_STAT_LOW_SPEED;
- rh->port &= USB_PORT_STAT_RESET;
+ rh->port &= ~USB_PORT_STAT_RESET;
rh->port |= USB_PORT_STAT_ENABLE;
}
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9012098add6b..94e6934edb09 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -182,8 +182,12 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
* set, but other sections talk about dealing with the chain bit set. This was
* fixed in the 0.96 specification errata, but we have to assume that all 0.95
* xHCI hardware can't handle the chain bit being cleared on a link TRB.
+ *
+ * @more_trbs_coming: Will you enqueue more TRBs before calling
+ * prepare_transfer()?
*/
-static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer)
+static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
+ bool consumer, bool more_trbs_coming)
{
u32 chain;
union xhci_trb *next;
@@ -199,15 +203,28 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
while (last_trb(xhci, ring, ring->enq_seg, next)) {
if (!consumer) {
if (ring != xhci->event_ring) {
- if (chain) {
- next->link.control |= TRB_CHAIN;
-
- /* Give this link TRB to the hardware */
- wmb();
- next->link.control ^= TRB_CYCLE;
- } else {
+ /*
+ * If the caller doesn't plan on enqueueing more
+ * TDs before ringing the doorbell, then we
+ * don't want to give the link TRB to the
+ * hardware just yet. We'll give the link TRB
+ * back in prepare_ring() just before we enqueue
+ * the TD at the top of the ring.
+ */
+ if (!chain && !more_trbs_coming)
break;
+
+ /* If we're not dealing with 0.95 hardware,
+ * carry over the chain bit of the previous TRB
+ * (which may mean the chain bit is cleared).
+ */
+ if (!xhci_link_trb_quirk(xhci)) {
+ next->link.control &= ~TRB_CHAIN;
+ next->link.control |= chain;
}
+ /* Give this link TRB to the hardware */
+ wmb();
+ next->link.control ^= TRB_CYCLE;
}
/* Toggle the cycle bit after the last ring segment. */
if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) {
@@ -1707,9 +1724,12 @@ void xhci_handle_event(struct xhci_hcd *xhci)
/*
* Generic function for queueing a TRB on a ring.
* The caller must have checked to make sure there's room on the ring.
+ *
+ * @more_trbs_coming: Will you enqueue more TRBs before calling
+ * prepare_transfer()?
*/
static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
- bool consumer,
+ bool consumer, bool more_trbs_coming,
u32 field1, u32 field2, u32 field3, u32 field4)
{
struct xhci_generic_trb *trb;
@@ -1719,7 +1739,7 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
trb->field[1] = field2;
trb->field[2] = field3;
trb->field[3] = field4;
- inc_enq(xhci, ring, consumer);
+ inc_enq(xhci, ring, consumer, more_trbs_coming);
}
/*
@@ -1988,6 +2008,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
int trb_buff_len, this_sg_len, running_total;
bool first_trb;
u64 addr;
+ bool more_trbs_coming;
struct xhci_generic_trb *start_trb;
int start_cycle;
@@ -2073,7 +2094,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
length_field = TRB_LEN(trb_buff_len) |
remainder |
TRB_INTR_TARGET(0);
- queue_trb(xhci, ep_ring, false,
+ if (num_trbs > 1)
+ more_trbs_coming = true;
+ else
+ more_trbs_coming = false;
+ queue_trb(xhci, ep_ring, false, more_trbs_coming,
lower_32_bits(addr),
upper_32_bits(addr),
length_field,
@@ -2124,6 +2149,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
int num_trbs;
struct xhci_generic_trb *start_trb;
bool first_trb;
+ bool more_trbs_coming;
int start_cycle;
u32 field, length_field;
@@ -2212,7 +2238,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
length_field = TRB_LEN(trb_buff_len) |
remainder |
TRB_INTR_TARGET(0);
- queue_trb(xhci, ep_ring, false,
+ if (num_trbs > 1)
+ more_trbs_coming = true;
+ else
+ more_trbs_coming = false;
+ queue_trb(xhci, ep_ring, false, more_trbs_coming,
lower_32_bits(addr),
upper_32_bits(addr),
length_field,
@@ -2291,7 +2321,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Queue setup TRB - see section 6.4.1.2.1 */
/* FIXME better way to translate setup_packet into two u32 fields? */
setup = (struct usb_ctrlrequest *) urb->setup_packet;
- queue_trb(xhci, ep_ring, false,
+ queue_trb(xhci, ep_ring, false, true,
/* FIXME endianness is probably going to bite my ass here. */
setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16,
setup->wIndex | setup->wLength << 16,
@@ -2307,7 +2337,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
if (urb->transfer_buffer_length > 0) {
if (setup->bRequestType & USB_DIR_IN)
field |= TRB_DIR_IN;
- queue_trb(xhci, ep_ring, false,
+ queue_trb(xhci, ep_ring, false, true,
lower_32_bits(urb->transfer_dma),
upper_32_bits(urb->transfer_dma),
length_field,
@@ -2324,7 +2354,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field = 0;
else
field = TRB_DIR_IN;
- queue_trb(xhci, ep_ring, false,
+ queue_trb(xhci, ep_ring, false, false,
0,
0,
TRB_INTR_TARGET(0),
@@ -2361,7 +2391,7 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2,
"unfailable commands failed.\n");
return -ENOMEM;
}
- queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
+ queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3,
field4 | xhci->cmd_ring->cycle_state);
return 0;
}
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index fad70bc83555..3b795c56221f 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -219,8 +219,8 @@ static int musb_ulpi_write(struct otg_transceiver *otg,
return 0;
}
#else
-#define musb_ulpi_read(a, b) NULL
-#define musb_ulpi_write(a, b, c) NULL
+#define musb_ulpi_read NULL
+#define musb_ulpi_write NULL
#endif
static struct otg_io_access_ops musb_ulpi_access = {
@@ -451,10 +451,6 @@ void musb_hnp_stop(struct musb *musb)
* @param power
*/
-#define STAGE0_MASK (MUSB_INTR_RESUME | MUSB_INTR_SESSREQ \
- | MUSB_INTR_VBUSERROR | MUSB_INTR_CONNECT \
- | MUSB_INTR_RESET)
-
static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
u8 devctl, u8 power)
{
@@ -642,7 +638,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
handled = IRQ_HANDLED;
}
-
+#endif
if (int_usb & MUSB_INTR_SUSPEND) {
DBG(1, "SUSPEND (%s) devctl %02x power %02x\n",
otg_state_string(musb), devctl, power);
@@ -705,6 +701,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
}
}
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
if (int_usb & MUSB_INTR_CONNECT) {
struct usb_hcd *hcd = musb_to_hcd(musb);
void __iomem *mbase = musb->mregs;
@@ -1597,7 +1594,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
/* the core can interrupt us for multiple reasons; docs have
* a generic interrupt flowchart to follow
*/
- if (musb->int_usb & STAGE0_MASK)
+ if (musb->int_usb)
retval |= musb_stage0_irq(musb, musb->int_usb,
devctl, power);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index b22d02dea7d3..91d67794e350 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -470,7 +470,8 @@ struct musb_csr_regs {
struct musb_context_registers {
-#ifdef CONFIG_PM
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
+ defined(CONFIG_ARCH_OMAP4)
u32 otg_sysconfig, otg_forcestandby;
#endif
u8 power;
@@ -484,7 +485,8 @@ struct musb_context_registers {
struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
};
-#ifdef CONFIG_PM
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
+ defined(CONFIG_ARCH_OMAP4)
extern void musb_platform_save_context(struct musb *musb,
struct musb_context_registers *musb_context);
extern void musb_platform_restore_context(struct musb *musb,
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 1008044a3bbc..dc66e4376d49 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -132,18 +132,9 @@ static void configure_channel(struct dma_channel *channel,
if (mode) {
csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
BUG_ON(len < packet_sz);
-
- if (packet_sz >= 64) {
- csr |= MUSB_HSDMA_BURSTMODE_INCR16
- << MUSB_HSDMA_BURSTMODE_SHIFT;
- } else if (packet_sz >= 32) {
- csr |= MUSB_HSDMA_BURSTMODE_INCR8
- << MUSB_HSDMA_BURSTMODE_SHIFT;
- } else if (packet_sz >= 16) {
- csr |= MUSB_HSDMA_BURSTMODE_INCR4
- << MUSB_HSDMA_BURSTMODE_SHIFT;
- }
}
+ csr |= MUSB_HSDMA_BURSTMODE_INCR16
+ << MUSB_HSDMA_BURSTMODE_SHIFT;
csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
| (1 << MUSB_HSDMA_ENABLE_SHIFT)
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index b1b346932946..d331b222ad21 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -59,12 +59,17 @@ static int ulpi_set_flags(struct otg_transceiver *otg)
static int ulpi_init(struct otg_transceiver *otg)
{
- int i, vid, pid;
-
- vid = (otg_io_read(otg, ULPI_VENDOR_ID_HIGH) << 8) |
- otg_io_read(otg, ULPI_VENDOR_ID_LOW);
- pid = (otg_io_read(otg, ULPI_PRODUCT_ID_HIGH) << 8) |
- otg_io_read(otg, ULPI_PRODUCT_ID_LOW);
+ int i, vid, pid, ret;
+ u32 ulpi_id = 0;
+
+ for (i = 0; i < 4; i++) {
+ ret = otg_io_read(otg, ULPI_PRODUCT_ID_HIGH - i);
+ if (ret < 0)
+ return ret;
+ ulpi_id = (ulpi_id << 8) | ret;
+ }
+ vid = ulpi_id & 0xffff;
+ pid = ulpi_id >> 16;
pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 79dd1ae195e5..da7e334b0407 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -653,7 +653,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
- { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 94d86c3febcb..bbc159a1df45 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -501,13 +501,6 @@
#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
/*
- * Contec products (http://www.contec.com)
- * Submitted by Daniel Sangorrin
- */
-#define CONTEC_VID 0x06CE /* Vendor ID */
-#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
-
-/*
* Definitions for B&B Electronics products.
*/
#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 04bb759536bb..93d72eb8cafc 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -139,6 +139,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
"Could not set interface, error %d\n",
retval);
retval = -ENODEV;
+ kfree(data);
}
return retval;
}
@@ -155,6 +156,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
"Could not set interface, error %d\n",
retval);
retval = -ENODEV;
+ kfree(data);
}
return retval;
}
@@ -163,6 +165,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
default:
dev_err(&serial->dev->dev,
"unknown number of interfaces: %d\n", nintf);
+ kfree(data);
return -ENODEV;
}
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 76e7dac6f259..70b1d9d51c96 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -40,7 +40,7 @@ static int vram;
static int vt_switch;
/* Modes relevant to the GX (taken from modedb.c) */
-static struct fb_videomode gx_modedb[] __initdata = {
+static struct fb_videomode gx_modedb[] __devinitdata = {
/* 640x480-60 VESA */
{ NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -110,14 +110,15 @@ static struct fb_videomode gx_modedb[] __initdata = {
#ifdef CONFIG_OLPC
#include <asm/olpc.h>
-static struct fb_videomode gx_dcon_modedb[] __initdata = {
+static struct fb_videomode gx_dcon_modedb[] __devinitdata = {
/* The only mode the DCON has is 1200x900 */
{ NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED, 0 }
};
-static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
+static void __devinit get_modedb(struct fb_videomode **modedb,
+ unsigned int *size)
{
if (olpc_has_dcon()) {
*modedb = (struct fb_videomode *) gx_dcon_modedb;
@@ -129,7 +130,8 @@ static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
}
#else
-static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
+static void __devinit get_modedb(struct fb_videomode **modedb,
+ unsigned int *size)
{
*modedb = (struct fb_videomode *) gx_modedb;
*size = ARRAY_SIZE(gx_modedb);
@@ -226,7 +228,8 @@ static int gxfb_blank(int blank_mode, struct fb_info *info)
return gx_blank_display(info, blank_mode);
}
-static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
+static int __devinit gxfb_map_video_memory(struct fb_info *info,
+ struct pci_dev *dev)
{
struct gxfb_par *par = info->par;
int ret;
@@ -290,7 +293,7 @@ static struct fb_ops gxfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
+static struct fb_info *__devinit gxfb_init_fbinfo(struct device *dev)
{
struct gxfb_par *par;
struct fb_info *info;
@@ -371,7 +374,8 @@ static int gxfb_resume(struct pci_dev *pdev)
}
#endif
-static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __devinit gxfb_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
{
struct gxfb_par *par;
struct fb_info *info;
@@ -451,7 +455,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
return ret;
}
-static void gxfb_remove(struct pci_dev *pdev)
+static void __devexit gxfb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct gxfb_par *par = info->par;
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 1a18da86d3fa..39bdbedf43b4 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -35,7 +35,7 @@ static int vt_switch;
* we try to make it something sane - 640x480-60 is sane
*/
-static struct fb_videomode geode_modedb[] __initdata = {
+static struct fb_videomode geode_modedb[] __devinitdata = {
/* 640x480-60 */
{ NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
@@ -219,14 +219,15 @@ static struct fb_videomode geode_modedb[] __initdata = {
#ifdef CONFIG_OLPC
#include <asm/olpc.h>
-static struct fb_videomode olpc_dcon_modedb[] __initdata = {
+static struct fb_videomode olpc_dcon_modedb[] __devinitdata = {
/* The only mode the DCON has is 1200x900 */
{ NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED, 0 }
};
-static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
+static void __devinit get_modedb(struct fb_videomode **modedb,
+ unsigned int *size)
{
if (olpc_has_dcon()) {
*modedb = (struct fb_videomode *) olpc_dcon_modedb;
@@ -238,7 +239,8 @@ static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
}
#else
-static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
+static void __devinit get_modedb(struct fb_videomode **modedb,
+ unsigned int *size)
{
*modedb = (struct fb_videomode *) geode_modedb;
*size = ARRAY_SIZE(geode_modedb);
@@ -334,7 +336,7 @@ static int lxfb_blank(int blank_mode, struct fb_info *info)
}
-static int __init lxfb_map_video_memory(struct fb_info *info,
+static int __devinit lxfb_map_video_memory(struct fb_info *info,
struct pci_dev *dev)
{
struct lxfb_par *par = info->par;
@@ -412,7 +414,7 @@ static struct fb_ops lxfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_info * __init lxfb_init_fbinfo(struct device *dev)
+static struct fb_info * __devinit lxfb_init_fbinfo(struct device *dev)
{
struct lxfb_par *par;
struct fb_info *info;
@@ -496,7 +498,7 @@ static int lxfb_resume(struct pci_dev *pdev)
#define lxfb_resume NULL
#endif
-static int __init lxfb_probe(struct pci_dev *pdev,
+static int __devinit lxfb_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct lxfb_par *par;
@@ -588,7 +590,7 @@ err:
return ret;
}
-static void lxfb_remove(struct pci_dev *pdev)
+static void __devexit lxfb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct lxfb_par *par = info->par;
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index d4cde79ea15e..81687ed26ba9 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -596,8 +596,6 @@ static int __devinit nuc900fb_probe(struct platform_device *pdev)
goto release_regs;
}
- nuc900_driver_clksrc_div(&pdev->dev, "ext", 0x2);
-
fbi->clk = clk_get(&pdev->dev, NULL);
if (!fbi->clk || IS_ERR(fbi->clk)) {
printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index b6ab27ccf214..811384bec8de 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -68,11 +68,7 @@
* Here we can be a bit looser than the data sections since this
* needs to only meet arch ABI requirements.
*/
-#ifdef ARCH_SLAB_MINALIGN
-#define FLAT_STACK_ALIGN (ARCH_SLAB_MINALIGN)
-#else
-#define FLAT_STACK_ALIGN (sizeof(void *))
-#endif
+#define FLAT_STACK_ALIGN max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN)
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 51e11bf5708f..9d175d623aab 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -733,12 +733,14 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band)
{
while (fa) {
struct fown_struct *fown;
+ unsigned long flags;
+
if (fa->magic != FASYNC_MAGIC) {
printk(KERN_ERR "kill_fasync: bad magic number in "
"fasync_struct!\n");
return;
}
- spin_lock(&fa->fa_lock);
+ spin_lock_irqsave(&fa->fa_lock, flags);
if (fa->fa_file) {
fown = &fa->fa_file->f_owner;
/* Don't send SIGURG to processes which have not set a
@@ -747,7 +749,7 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band)
if (!(sig == SIGURG && fown->signum == 0))
send_sigio(fown, fa->fa_fd, band);
}
- spin_unlock(&fa->fa_lock);
+ spin_unlock_irqrestore(&fa->fa_lock, flags);
fa = rcu_dereference(fa->fa_next);
}
}
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 46d4b5d72bd3..cb6306e63843 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -122,11 +122,20 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
return size;
}
+static void pad_len_spaces(struct seq_file *m, int len)
+{
+ len = 25 + sizeof(void*) * 6 - len;
+ if (len < 1)
+ len = 1;
+ seq_printf(m, "%*c", len, ' ');
+}
+
/*
* display a single VMA to a sequenced file
*/
static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
{
+ struct mm_struct *mm = vma->vm_mm;
unsigned long ino = 0;
struct file *file;
dev_t dev = 0;
@@ -155,11 +164,14 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
MAJOR(dev), MINOR(dev), ino, &len);
if (file) {
- len = 25 + sizeof(void *) * 6 - len;
- if (len < 1)
- len = 1;
- seq_printf(m, "%*c", len, ' ');
+ pad_len_spaces(m, len);
seq_path(m, &file->f_path, "");
+ } else if (mm) {
+ if (vma->vm_start <= mm->start_stack &&
+ vma->vm_end >= mm->start_stack) {
+ pad_len_spaces(m, len);
+ seq_puts(m, "[stack]");
+ }
}
seq_putc(m, '\n');
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
index bbd69bdb0fa8..fcc498ec9b33 100644
--- a/fs/sysv/ialloc.c
+++ b/fs/sysv/ialloc.c
@@ -25,6 +25,7 @@
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/buffer_head.h>
+#include <linux/writeback.h>
#include "sysv.h"
/* We don't trust the value of
@@ -139,6 +140,9 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
struct inode *inode;
sysv_ino_t ino;
unsigned count;
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_NONE
+ };
inode = new_inode(sb);
if (!inode)
@@ -168,7 +172,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
insert_inode_hash(inode);
mark_inode_dirty(inode);
- sysv_write_inode(inode, 0); /* ensure inode not allocated again */
+ sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */
mark_inode_dirty(inode); /* cleared by sysv_write_inode() */
/* That's it. */
unlock_super(sb);
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 73dcf804bc94..0da5b187f124 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -58,8 +58,12 @@
* naked functions because then mcount is called without stack and frame pointer
* being set up and there is no chance to restore the lr register to the value
* before mcount was called.
+ *
+ * The asm() bodies of naked functions often depend on standard calling conventions,
+ * therefore they must be noinline and noclone. GCC 4.[56] currently fail to enforce
+ * this, so we must do so ourselves. See GCC PR44290.
*/
-#define __naked __attribute__((naked)) notrace
+#define __naked __attribute__((naked)) noinline __noclone notrace
#define __noreturn __attribute__((noreturn))
@@ -85,3 +89,7 @@
#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
#define gcc_header(x) _gcc_header(x)
#include gcc_header(__GNUC__)
+
+#if !defined(__noclone)
+#define __noclone /* not needed */
+#endif
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 94dea3ffbfa1..fcfa5b9a4317 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -48,6 +48,10 @@
* unreleased. Really, we need to have autoconf for the kernel.
*/
#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone __attribute__((__noclone__))
+
#endif
#endif
diff --git a/kernel/futex.c b/kernel/futex.c
index e7a35f1039e7..6a3a5fa1526d 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
static struct task_struct * futex_find_get_task(pid_t pid)
{
struct task_struct *p;
- const struct cred *cred = current_cred(), *pcred;
rcu_read_lock();
p = find_task_by_vpid(pid);
- if (!p) {
- p = ERR_PTR(-ESRCH);
- } else {
- pcred = __task_cred(p);
- if (cred->euid != pcred->euid &&
- cred->euid != pcred->uid)
- p = ERR_PTR(-ESRCH);
- else
- get_task_struct(p);
- }
+ if (p)
+ get_task_struct(p);
rcu_read_unlock();
@@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
if (!pid)
return -ESRCH;
p = futex_find_get_task(pid);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (!p)
+ return -ESRCH;
/*
* We need to look at the task state flags to figure out,
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 474a84715eac..131b1703936f 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1089,9 +1089,10 @@ void crash_kexec(struct pt_regs *regs)
size_t crash_get_memory_size(void)
{
- size_t size;
+ size_t size = 0;
mutex_lock(&kexec_mutex);
- size = crashk_res.end - crashk_res.start + 1;
+ if (crashk_res.end != crashk_res.start)
+ size = crashk_res.end - crashk_res.start + 1;
mutex_unlock(&kexec_mutex);
return size;
}
@@ -1134,7 +1135,7 @@ int crash_shrink_memory(unsigned long new_size)
free_reserved_phys_range(end, crashk_res.end);
- if (start == end)
+ if ((start == end) && (crashk_res.parent != NULL))
release_resource(&crashk_res);
crashk_res.end = end - 1;
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 736c3b06398e..1923f1490e72 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -128,7 +128,6 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
end_bit = (chunk->end_addr - chunk->start_addr) >> order;
- end_bit -= nbits + 1;
spin_lock_irqsave(&chunk->lock, flags);
start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0,
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c6ece0a57595..20a8193a7af8 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1370,7 +1370,7 @@ static void memcg_wakeup_oom(struct mem_cgroup *mem)
static void memcg_oom_recover(struct mem_cgroup *mem)
{
- if (mem->oom_kill_disable && atomic_read(&mem->oom_lock))
+ if (atomic_read(&mem->oom_lock))
memcg_wakeup_oom(mem);
}
@@ -3781,6 +3781,8 @@ static int mem_cgroup_oom_control_write(struct cgroup *cgrp,
return -EINVAL;
}
mem->oom_kill_disable = val;
+ if (!val)
+ memcg_oom_recover(mem);
cgroup_unlock();
return 0;
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 5d6fb339de03..5bc0a96beb51 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2094,7 +2094,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
NODEMASK_SCRATCH(scratch);
if (!scratch)
- return;
+ goto put_mpol;
/* contextualize the tmpfs mount point mempolicy */
new = mpol_new(mpol->mode, mpol->flags, &mpol->w.user_nodemask);
if (IS_ERR(new))
@@ -2103,19 +2103,20 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
task_lock(current);
ret = mpol_set_nodemask(new, &mpol->w.user_nodemask, scratch);
task_unlock(current);
- mpol_put(mpol); /* drop our ref on sb mpol */
if (ret)
- goto put_free;
+ goto put_new;
/* Create pseudo-vma that contains just the policy */
memset(&pvma, 0, sizeof(struct vm_area_struct));
pvma.vm_end = TASK_SIZE; /* policy covers entire file */
mpol_set_shared_policy(sp, &pvma, new); /* adds ref */
-put_free:
+put_new:
mpol_put(new); /* drop initial ref */
free_scratch:
NODEMASK_SCRATCH_FREE(scratch);
+put_mpol:
+ mpol_put(mpol); /* drop our incoming ref on sb mpol */
}
}