Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / tty / serial / sh-sci.c
index 1945c70..60f71ec 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/console.h>
 #include <linux/platform_device.h>
 #include <linux/serial_sci.h>
-#include <linux/notifier.h>
 #include <linux/pm_runtime.h>
 #include <linux/cpufreq.h>
 #include <linux/clk.h>
@@ -95,8 +94,6 @@ struct sci_port {
        unsigned int                    rx_timeout;
 #endif
 
-       struct notifier_block           freq_transition;
-
 #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
        unsigned short saved_smr;
        unsigned short saved_fcr;
@@ -206,6 +203,25 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
                [SCLSR]         = sci_reg_invalid,
        },
 
+       /*
+        * Common SH-2(A) SCIF definitions for ports with FIFO data
+        * count registers.
+        */
+       [SCIx_SH2_SCIF_FIFODATA_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x0c,  8 },
+               [SCxSR]         = { 0x10, 16 },
+               [SCxRDR]        = { 0x14,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = { 0x20, 16 },
+               [SCLSR]         = { 0x24, 16 },
+       },
+
        /*
         * Common SH-3 SCIF definitions.
         */
@@ -939,30 +955,6 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
        return ret;
 }
 
-/*
- * Here we define a transition notifier so that we can update all of our
- * ports' baud rate when the peripheral clock changes.
- */
-static int sci_notifier(struct notifier_block *self,
-                       unsigned long phase, void *p)
-{
-       struct sci_port *sci_port;
-       unsigned long flags;
-
-       sci_port = container_of(self, struct sci_port, freq_transition);
-
-       if ((phase == CPUFREQ_POSTCHANGE) ||
-           (phase == CPUFREQ_RESUMECHANGE)) {
-               struct uart_port *port = &sci_port->port;
-
-               spin_lock_irqsave(&port->lock, flags);
-               port->uartclk = clk_get_rate(sci_port->iclk);
-               spin_unlock_irqrestore(&port->lock, flags);
-       }
-
-       return NOTIFY_OK;
-}
-
 static struct sci_irq_desc {
        const char      *desc;
        irq_handler_t   handler;
@@ -1104,17 +1096,20 @@ static void sci_dma_tx_complete(void *arg)
        port->icount.tx += sg_dma_len(&s->sg_tx);
 
        async_tx_ack(s->desc_tx);
-       s->cookie_tx = -EINVAL;
        s->desc_tx = NULL;
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        if (!uart_circ_empty(xmit)) {
+               s->cookie_tx = 0;
                schedule_work(&s->work_tx);
-       } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-               u16 ctrl = sci_in(port, SCSCR);
-               sci_out(port, SCSCR, ctrl & ~SCSCR_TIE);
+       } else {
+               s->cookie_tx = -EINVAL;
+               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+                       u16 ctrl = sci_in(port, SCSCR);
+                       sci_out(port, SCSCR, ctrl & ~SCSCR_TIE);
+               }
        }
 
        spin_unlock_irqrestore(&port->lock, flags);
@@ -1376,8 +1371,10 @@ static void sci_start_tx(struct uart_port *port)
        }
 
        if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
-           s->cookie_tx < 0)
+           s->cookie_tx < 0) {
+               s->cookie_tx = 0;
                schedule_work(&s->work_tx);
+       }
 #endif
 
        if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
@@ -1582,11 +1579,13 @@ static int sci_startup(struct uart_port *port)
 
        sci_port_enable(s);
 
+       sci_request_dma(port);
+
        ret = sci_request_irq(s);
-       if (unlikely(ret < 0))
+       if (unlikely(ret < 0)) {
+               sci_free_dma(port);
                return ret;
-
-       sci_request_dma(port);
+       }
 
        sci_start_tx(port);
        sci_start_rx(port);
@@ -1603,8 +1602,8 @@ static void sci_shutdown(struct uart_port *port)
        sci_stop_rx(port);
        sci_stop_tx(port);
 
-       sci_free_dma(port);
        sci_free_irq(s);
+       sci_free_dma(port);
 
        sci_port_disable(s);
 }
@@ -2147,9 +2146,6 @@ static int sci_remove(struct platform_device *dev)
 {
        struct sci_port *port = platform_get_drvdata(dev);
 
-       cpufreq_unregister_notifier(&port->freq_transition,
-                                   CPUFREQ_TRANSITION_NOTIFIER);
-
        uart_remove_one_port(&sci_uart_driver, &port->port);
 
        clk_put(port->iclk);
@@ -2203,13 +2199,6 @@ static int __devinit sci_probe(struct platform_device *dev)
        if (ret)
                goto err_unreg;
 
-       sp->freq_transition.notifier_call = sci_notifier;
-
-       ret = cpufreq_register_notifier(&sp->freq_transition,
-                                       CPUFREQ_TRANSITION_NOTIFIER);
-       if (unlikely(ret < 0))
-               goto err_unreg;
-
 #ifdef CONFIG_SH_STANDARD_BIOS
        sh_bios_gdb_detach();
 #endif