From 7eeff4814224646c896303ba2c2b7ac3c4240cd2 Mon Sep 17 00:00:00 2001 From: Matt Reimer Date: Mon, 15 Jun 2009 13:21:25 -0700 Subject: pxamci: correct DMA flow control The DMA flow control in pxamci_setup_data() is backwards; fix it. Signed-off-by: Matt Reimer Acked-by: Robert Jarzmik Signed-off-by: Eric Miao --- drivers/mmc/host/pxamci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index d7d7109ef47..e55ac792d68 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -168,12 +168,12 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) { host->dma_dir = DMA_FROM_DEVICE; - dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG; + dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; DRCMR(host->dma_drcmrtx) = 0; DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; } else { host->dma_dir = DMA_TO_DEVICE; - dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC; + dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; DRCMR(host->dma_drcmrrx) = 0; DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; } -- cgit v1.2.3-18-g5258 From 82e8b54229fb121946151b82e8ff3c3284bd723f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 19 Jun 2009 10:50:54 +0200 Subject: backlight: fix pwm_bl.c to notify platform code when suspending When suspending, pwm-bl sets duty cycle to 0, and shuts down the pwm device. This patch ensure that the platform code is called before that (through the notify callback_, leaving a chance for the platform code to configure GPIOs (shutting off the backlight, for example), much like it is done during normal operations. Signed-off-by: Marc Zyngier Signed-off-by: Eric Miao --- drivers/video/backlight/pwm_bl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e641584e212..88716626744 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -145,6 +145,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, struct backlight_device *bl = platform_get_drvdata(pdev); struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); + if (pb->notify) + pb->notify(0); pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); return 0; -- cgit v1.2.3-18-g5258 From 2653d1d7f0284f3b68f25dafa208d0a013f7e9db Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Wed, 15 Jul 2009 21:33:22 +0100 Subject: [ARM] 5606/1: Fix ep93xx watchdog driver headers Fix a number of build errors in the ep93xx watchdog driver due to missing io.h Signed-off-by: Ryan Mallon Acked-by: H Hartley Sweeten Signed-off-by: Russell King --- drivers/watchdog/ep93xx_wdt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index e9f950ff86e..cdd55e0d09f 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define WDT_VERSION "0.3" -- cgit v1.2.3-18-g5258 From c46a7aec556ffdbdb7357db0b05904b176cb3375 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 20 Jul 2009 16:04:55 +0100 Subject: vc: create vcs(a) devices for consoles The buffer for the consoles are unconditionally allocated at con_init() time, which miss the creation of the vcs(a) devices. Since 2.6.30 (commit 4995f8ef9d3aac72745e12419d7fbaa8d01b1d81, 'vcs: hook sysfs devices into object lifetime instead of "binding"' to be exact) these devices are no longer created at open() and removed on close(), but controlled by the lifetime of the buffers. Reported-by: Gerardo Exequiel Pozzi Tested-by: Gerardo Exequiel Pozzi Cc: stable@kernel.org Signed-off-by: Kay Sievers Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/char/vc_screen.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index d94d25c12aa..c1791a63d99 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -495,11 +495,15 @@ void vcs_remove_sysfs(int index) int __init vcs_init(void) { + unsigned int i; + if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); vc_class = class_create(THIS_MODULE, "vc"); device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + for (i = 0; i < MIN_NR_CONSOLES; i++) + vcs_make_sysfs(i); return 0; } -- cgit v1.2.3-18-g5258 From 254702568da63ce6f5ad68e77d83b427da693654 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 20 Jul 2009 16:05:07 +0100 Subject: specialix.c: convert nested spin_lock_irqsave to spin_lock If spin_lock_irqsave is called twice in a row with the same second argument, the interrupt state at the point of the second call overwrites the value saved by the first call. Indeed, the second call does not need to save the interrupt state, so it is changed to a simple spin_lock. The semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ expression lock1,lock2; expression flags; @@ *spin_lock_irqsave(lock1,flags) ... when != flags *spin_lock_irqsave(lock2,flags) // Signed-off-by: Julia Lawall Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/char/specialix.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index bfe4cdb2feb..268e17f9ec3 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -1809,10 +1809,10 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, if (clear & TIOCM_DTR) port->MSVR &= ~MSVR_DTR; } - spin_lock_irqsave(&bp->lock, flags); + spin_lock(&bp->lock); sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock(&bp->lock); spin_unlock_irqrestore(&port->lock, flags); func_exit(); return 0; @@ -1833,11 +1833,11 @@ static int sx_send_break(struct tty_struct *tty, int length) port->break_length = SPECIALIX_TPS / HZ * length; port->COR2 |= COR2_ETC; port->IER |= IER_TXRDY; - spin_lock_irqsave(&bp->lock, flags); + spin_lock(&bp->lock); sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_COR2, port->COR2); sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock(&bp->lock); spin_unlock_irqrestore(&port->lock, flags); sx_wait_CCR(bp); spin_lock_irqsave(&bp->lock, flags); @@ -2023,9 +2023,9 @@ static void sx_unthrottle(struct tty_struct *tty) if (sx_crtscts(tty)) port->MSVR |= MSVR_DTR; /* Else clause: see remark in "sx_throttle"... */ - spin_lock_irqsave(&bp->lock, flags); + spin_lock(&bp->lock); sx_out(bp, CD186x_CAR, port_No(port)); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock(&bp->lock); if (I_IXOFF(tty)) { spin_unlock_irqrestore(&port->lock, flags); sx_wait_CCR(bp); @@ -2035,9 +2035,9 @@ static void sx_unthrottle(struct tty_struct *tty) sx_wait_CCR(bp); spin_lock_irqsave(&port->lock, flags); } - spin_lock_irqsave(&bp->lock, flags); + spin_lock(&bp->lock); sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock(&bp->lock); spin_unlock_irqrestore(&port->lock, flags); func_exit(); @@ -2061,10 +2061,10 @@ static void sx_stop(struct tty_struct *tty) spin_lock_irqsave(&port->lock, flags); port->IER &= ~IER_TXRDY; - spin_lock_irqsave(&bp->lock, flags); + spin_lock(&bp->lock); sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock(&bp->lock); spin_unlock_irqrestore(&port->lock, flags); func_exit(); @@ -2089,10 +2089,10 @@ static void sx_start(struct tty_struct *tty) spin_lock_irqsave(&port->lock, flags); if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { port->IER |= IER_TXRDY; - spin_lock_irqsave(&bp->lock, flags); + spin_lock(&bp->lock); sx_out(bp, CD186x_CAR, port_No(port)); sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock(&bp->lock); } spin_unlock_irqrestore(&port->lock, flags); -- cgit v1.2.3-18-g5258 From 23198fda7182969b619613a555f8645fdc3dc334 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 20 Jul 2009 16:05:27 +0100 Subject: tty: fix chars_in_buffers This function does not have an error return and returning an error is instead interpreted as having a lot of pending bytes. Reported by Jeff Harris who provided a list of some of the remaining offenders. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/char/hvc_console.c | 2 +- drivers/char/nozomi.c | 4 +--- drivers/char/pcmcia/ipwireless/tty.c | 4 ++-- drivers/isdn/gigaset/interface.c | 2 ++ drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/serial/mos7720.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 94e7e3c8c05..d97779ef72c 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -552,7 +552,7 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) struct hvc_struct *hp = tty->driver_data; if (!hp) - return -1; + return 0; return hp->n_outbuf; } diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 280b41c507a..ec58d8c387f 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -1866,16 +1866,14 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) { struct port *port = tty->driver_data; struct nozomi *dc = get_dc_by_tty(tty); - s32 rval; + s32 rval = 0; if (unlikely(!dc || !port)) { - rval = -ENODEV; goto exit_in_buffer; } if (unlikely(!port->port.count)) { dev_err(&dc->pdev->dev, "No tty open?\n"); - rval = -ENODEV; goto exit_in_buffer; } diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 569f2f7743a..674b3ab3587 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c @@ -320,10 +320,10 @@ static int ipw_chars_in_buffer(struct tty_struct *linux_tty) struct ipw_tty *tty = linux_tty->driver_data; if (!tty) - return -ENODEV; + return 0; if (!tty->open_count) - return -EINVAL; + return 0; return tty->tx_bytes_queued; } diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 1ebfcab7466..8ff7e35c706 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -408,6 +408,8 @@ static int if_write_room(struct tty_struct *tty) return retval; } +/* FIXME: This function does not have error returns */ + static int if_chars_in_buffer(struct tty_struct *tty) { struct cardstate *cs; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 5b15d9d8896..e1f89416ef8 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -750,7 +750,7 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) { struct acm *acm = tty->driver_data; if (!ACM_READY(acm)) - return -EINVAL; + return 0; /* * This is inaccurate (overcounts), but it works. */ diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index bfc5ce000ef..ccd4dd340d2 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -521,7 +521,7 @@ static int mos7720_chars_in_buffer(struct tty_struct *tty) mos7720_port = usb_get_serial_port_data(port); if (mos7720_port == NULL) { dbg("%s:leaving ...........", __func__); - return -ENODEV; + return 0; } for (i = 0; i < NUM_URBS; ++i) { diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 14971a92699..3bc609fe224 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -727,7 +727,7 @@ static int ti_write_room(struct tty_struct *tty) dbg("%s - port %d", __func__, port->number); if (tport == NULL) - return -ENODEV; + return 0; spin_lock_irqsave(&tport->tp_lock, flags); room = ti_buf_space_avail(tport->tp_write_buf); @@ -748,7 +748,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty) dbg("%s - port %d", __func__, port->number); if (tport == NULL) - return -ENODEV; + return 0; spin_lock_irqsave(&tport->tp_lock, flags); chars = ti_buf_data_avail(tport->tp_write_buf); -- cgit v1.2.3-18-g5258 From 6cdbf734493d6e8f5afc6f539b82897772809d43 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sat, 18 Jul 2009 20:34:37 -0400 Subject: mvsdio: fix handling of partial word at the end of PIO transfer Standard data flow for MMC/SD/SDIO cards requires that the mvsdio controller be set for big endian operation. This is causing problems with buffers which length is not a multiple of 4 bytes as the last partial word doesn't get shifted all the way and stored properly in memory. Let's compensate for this. Signed-off-by: Nicolas Pitre CC: stable@kernel.org Signed-off-by: Linus Torvalds --- drivers/mmc/host/mvsdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index b56d72ff06e..34e23489811 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -384,7 +384,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev) u16 val[2] = {0, 0}; val[0] = mvsd_read(MVSD_FIFO); val[1] = mvsd_read(MVSD_FIFO); - memcpy(p, &val, s); + memcpy(p, ((void *)&val) + 4 - s, s); s = 0; intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); } @@ -423,7 +423,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev) if (s < 4) { if (s && (intr_status & MVSD_NOR_TX_AVAIL)) { u16 val[2] = {0, 0}; - memcpy(&val, p, s); + memcpy(((void *)&val) + 4 - s, p, s); mvsd_write(MVSD_FIFO, val[0]); mvsd_write(MVSD_FIFO, val[1]); s = 0; -- cgit v1.2.3-18-g5258