serial: sh-sci: Require a device per port mapping.
authorPaul Mundt <lethal@linux-sh.org>
Wed, 19 Jan 2011 08:19:35 +0000 (17:19 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 19 Jan 2011 08:19:35 +0000 (17:19 +0900)
In the olden days it was possible to register a map of ports per device,
but this has long since been abandoned due to the desire to match up with
clkdev and other functionality. As a result, all of the in-tree users
have for some time already been migrated off of such behaviour, while
we've left support code in place to deal with either case. Dropping the
code permits for quite a bit of simplification, so we do that now before
any users of the old interface are able to be added back in.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
drivers/serial/sh-sci.c

index 5b3e9769ca2101fc8645a4ef6c1e5835412f0594..3fd1577a162fa829aaec90616697eda762b698df 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/clk.h>
 #include <linux/ctype.h>
 #include <linux/err.h>
-#include <linux/list.h>
 #include <linux/dmaengine.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
@@ -83,8 +82,6 @@ struct sci_port {
        /* Function clock */
        struct clk              *fclk;
 
-       struct list_head        node;
-
        struct dma_chan                 *chan_tx;
        struct dma_chan                 *chan_rx;
 
@@ -105,16 +102,14 @@ struct sci_port {
        struct timer_list               rx_timer;
        unsigned int                    rx_timeout;
 #endif
-};
 
-struct sh_sci_priv {
-       spinlock_t lock;
-       struct list_head ports;
-       struct notifier_block clk_nb;
+       struct notifier_block           freq_transition;
 };
 
 /* Function prototypes */
+static void sci_start_tx(struct uart_port *port);
 static void sci_stop_tx(struct uart_port *port);
+static void sci_start_rx(struct uart_port *port);
 
 #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
 
@@ -827,17 +822,17 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 static int sci_notifier(struct notifier_block *self,
                        unsigned long phase, void *p)
 {
-       struct sh_sci_priv *priv = container_of(self,
-                                               struct sh_sci_priv, clk_nb);
        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)) {
-               spin_lock_irqsave(&priv->lock, flags);
-               list_for_each_entry(sci_port, &priv->ports, node)
-                       sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
-               spin_unlock_irqrestore(&priv->lock, flags);
+               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;
@@ -1025,9 +1020,6 @@ static void sci_dma_rx_complete(void *arg)
        schedule_work(&s->work_rx);
 }
 
-static void sci_start_rx(struct uart_port *port);
-static void sci_start_tx(struct uart_port *port);
-
 static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 {
        struct dma_chan *chan = s->chan_rx;
@@ -1874,24 +1866,18 @@ static struct uart_driver sci_uart_driver = {
        .cons           = SCI_CONSOLE,
 };
 
-
 static int sci_remove(struct platform_device *dev)
 {
-       struct sh_sci_priv *priv = platform_get_drvdata(dev);
-       struct sci_port *p;
-       unsigned long flags;
+       struct sci_port *port = platform_get_drvdata(dev);
 
-       cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
+       cpufreq_unregister_notifier(&port->freq_transition,
+                                   CPUFREQ_TRANSITION_NOTIFIER);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       list_for_each_entry(p, &priv->ports, node) {
-               uart_remove_one_port(&sci_uart_driver, &p->port);
-               clk_put(p->iclk);
-               clk_put(p->fclk);
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
+       uart_remove_one_port(&sci_uart_driver, &port->port);
+
+       clk_put(port->iclk);
+       clk_put(port->fclk);
 
-       kfree(priv);
        return 0;
 }
 
@@ -1900,8 +1886,6 @@ static int __devinit sci_probe_single(struct platform_device *dev,
                                      struct plat_sci_port *p,
                                      struct sci_port *sciport)
 {
-       struct sh_sci_priv *priv = platform_get_drvdata(dev);
-       unsigned long flags;
        int ret;
 
        /* Sanity check */
@@ -1918,17 +1902,7 @@ static int __devinit sci_probe_single(struct platform_device *dev,
        if (ret)
                return ret;
 
-       ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
-       if (ret)
-               return ret;
-
-       INIT_LIST_HEAD(&sciport->node);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       list_add(&sciport->node, &priv->ports);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       return 0;
+       return uart_add_one_port(&sci_uart_driver, &sciport->port);
 }
 
 /*
@@ -1940,46 +1914,38 @@ static int __devinit sci_probe_single(struct platform_device *dev,
 static int __devinit sci_probe(struct platform_device *dev)
 {
        struct plat_sci_port *p = dev->dev.platform_data;
-       struct sh_sci_priv *priv;
-       int i, ret = -EINVAL;
+       struct sci_port *sp = &sci_ports[dev->id];
+       int ret = -EINVAL;
 
 #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
        if (is_early_platform_device(dev)) {
-               if (dev->id == -1)
-                       return -ENOTSUPP;
                early_serial_console.index = dev->id;
                early_serial_console.data = &early_serial_port.port;
+
                sci_init_single(NULL, &early_serial_port, dev->id, p);
+
                serial_console_setup(&early_serial_console, early_serial_buf);
+
                if (!strstr(early_serial_buf, "keep"))
                        early_serial_console.flags |= CON_BOOT;
+
                register_console(&early_serial_console);
                return 0;
        }
 #endif
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
+       platform_set_drvdata(dev, sp);
 
-       INIT_LIST_HEAD(&priv->ports);
-       spin_lock_init(&priv->lock);
-       platform_set_drvdata(dev, priv);
+       ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]);
+       if (ret)
+               goto err_unreg;
 
-       priv->clk_nb.notifier_call = sci_notifier;
-       cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
+       sp->freq_transition.notifier_call = sci_notifier;
 
-       if (dev->id != -1) {
-               ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]);
-               if (ret)
-                       goto err_unreg;
-       } else {
-               for (i = 0; p && p->flags != 0; p++, i++) {
-                       ret = sci_probe_single(dev, i, p, &sci_ports[i]);
-                       if (ret)
-                               goto err_unreg;
-               }
-       }
+       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();
@@ -1994,28 +1960,20 @@ err_unreg:
 
 static int sci_suspend(struct device *dev)
 {
-       struct sh_sci_priv *priv = dev_get_drvdata(dev);
-       struct sci_port *p;
-       unsigned long flags;
+       struct sci_port *sport = dev_get_drvdata(dev);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       list_for_each_entry(p, &priv->ports, node)
-               uart_suspend_port(&sci_uart_driver, &p->port);
-       spin_unlock_irqrestore(&priv->lock, flags);
+       if (sport)
+               uart_suspend_port(&sci_uart_driver, &sport->port);
 
        return 0;
 }
 
 static int sci_resume(struct device *dev)
 {
-       struct sh_sci_priv *priv = dev_get_drvdata(dev);
-       struct sci_port *p;
-       unsigned long flags;
+       struct sci_port *sport = dev_get_drvdata(dev);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       list_for_each_entry(p, &priv->ports, node)
-               uart_resume_port(&sci_uart_driver, &p->port);
-       spin_unlock_irqrestore(&priv->lock, flags);
+       if (sport)
+               uart_resume_port(&sci_uart_driver, &sport->port);
 
        return 0;
 }