]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/serial/sh-sci.c
serial: sh-sci: clkdev updates for MSTP gating.
[karo-tx-linux.git] / drivers / serial / sh-sci.c
index 980f39449ee5635ccb7b4f681151892e92a493b0..054a8427c739c519472e60c25f8076d94728bab4 100644 (file)
@@ -83,8 +83,8 @@ struct sci_port {
 
        /* Interface clock */
        struct clk              *iclk;
-       /* Data clock */
-       struct clk              *dclk;
+       /* Function clock */
+       struct clk              *fclk;
 
        struct list_head        node;
        struct dma_chan                 *chan_tx;
@@ -803,7 +803,7 @@ static int sci_notifier(struct notifier_block *self,
            (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->dclk);
+                       sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
                spin_unlock_irqrestore(&priv->lock, flags);
        }
 
@@ -814,21 +814,17 @@ static void sci_clk_enable(struct uart_port *port)
 {
        struct sci_port *sci_port = to_sci_port(port);
 
-       clk_enable(sci_port->dclk);
-       sci_port->port.uartclk = clk_get_rate(sci_port->dclk);
-
-       if (sci_port->iclk)
-               clk_enable(sci_port->iclk);
+       clk_enable(sci_port->iclk);
+       sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
+       clk_enable(sci_port->fclk);
 }
 
 static void sci_clk_disable(struct uart_port *port)
 {
        struct sci_port *sci_port = to_sci_port(port);
 
-       if (sci_port->iclk)
-               clk_disable(sci_port->iclk);
-
-       clk_disable(sci_port->dclk);
+       clk_disable(sci_port->fclk);
+       clk_disable(sci_port->iclk);
 }
 
 static int sci_request_irq(struct sci_port *port)
@@ -1557,10 +1553,10 @@ static struct uart_ops sci_uart_ops = {
 #endif
 };
 
-static void __devinit sci_init_single(struct platform_device *dev,
-                                     struct sci_port *sci_port,
-                                     unsigned int index,
-                                     struct plat_sci_port *p)
+static int __devinit sci_init_single(struct platform_device *dev,
+                                    struct sci_port *sci_port,
+                                    unsigned int index,
+                                    struct plat_sci_port *p)
 {
        struct uart_port *port = &sci_port->port;
 
@@ -1581,8 +1577,23 @@ static void __devinit sci_init_single(struct platform_device *dev,
        }
 
        if (dev) {
-               sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL;
-               sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
+               sci_port->iclk = clk_get(&dev->dev, "sci_ick");
+               if (IS_ERR(sci_port->iclk)) {
+                       sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
+                       if (IS_ERR(sci_port->iclk)) {
+                               dev_err(&dev->dev, "can't get iclk\n");
+                               return PTR_ERR(sci_port->iclk);
+                       }
+               }
+
+               /*
+                * The function clock is optional, ignore it if we can't
+                * find it.
+                */
+               sci_port->fclk = clk_get(&dev->dev, "sci_fck");
+               if (IS_ERR(sci_port->fclk))
+                       sci_port->fclk = NULL;
+
                sci_port->enable = sci_clk_enable;
                sci_port->disable = sci_clk_disable;
                port->dev = &dev->dev;
@@ -1609,6 +1620,7 @@ static void __devinit sci_init_single(struct platform_device *dev,
 #endif
 
        memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
+       return 0;
 }
 
 #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
@@ -1758,8 +1770,11 @@ static int sci_remove(struct platform_device *dev)
        cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
 
        spin_lock_irqsave(&priv->lock, flags);
-       list_for_each_entry(p, &priv->ports, node)
+       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);
 
        kfree(priv);
@@ -1785,7 +1800,9 @@ static int __devinit sci_probe_single(struct platform_device *dev,
                return 0;
        }
 
-       sci_init_single(dev, sciport, index, p);
+       ret = sci_init_single(dev, sciport, index, p);
+       if (ret)
+               return ret;
 
        ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
        if (ret)