aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/sh-sci.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-03-10 04:35:14 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-03-10 04:35:14 -0500
commitc7ed1ab3f7b2fe0dedebf34cbf40bf12cb5ae48b (patch)
tree3b109353e338cf43e49b06c9d463dd929010a679 /drivers/serial/sh-sci.c
parentd28c145debb1bd53cde63ac8bccc192e3e00067e (diff)
serial: sh-sci: clkdev updates for MSTP gating.
This fixes up some of the I/D/F clock ambiguity in the sh-sci driver. The interface clock in most cases just wraps back to the peripheral clock, while the function clock wraps in to the MSTP bits. As the logic was somewhat inverted, this cleans that up, and also enables all CPUs with SCI MSTP bits to match function clocks through clkdev lookup. As a result, this gets rid of the clk string abuse on the sh side, and the clock string will be killed off once the ARM code has had a chance to sync up. This also enables MSTP gating on CPUs like 7786 which had never wired it up before. Impacted CPUs are primarily all SH-Mobiles, SH7785, and SH7786. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r--drivers/serial/sh-sci.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 980f39449ee5..054a8427c739 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -83,8 +83,8 @@ struct sci_port {
83 83
84 /* Interface clock */ 84 /* Interface clock */
85 struct clk *iclk; 85 struct clk *iclk;
86 /* Data clock */ 86 /* Function clock */
87 struct clk *dclk; 87 struct clk *fclk;
88 88
89 struct list_head node; 89 struct list_head node;
90 struct dma_chan *chan_tx; 90 struct dma_chan *chan_tx;
@@ -803,7 +803,7 @@ static int sci_notifier(struct notifier_block *self,
803 (phase == CPUFREQ_RESUMECHANGE)) { 803 (phase == CPUFREQ_RESUMECHANGE)) {
804 spin_lock_irqsave(&priv->lock, flags); 804 spin_lock_irqsave(&priv->lock, flags);
805 list_for_each_entry(sci_port, &priv->ports, node) 805 list_for_each_entry(sci_port, &priv->ports, node)
806 sci_port->port.uartclk = clk_get_rate(sci_port->dclk); 806 sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
807 spin_unlock_irqrestore(&priv->lock, flags); 807 spin_unlock_irqrestore(&priv->lock, flags);
808 } 808 }
809 809
@@ -814,21 +814,17 @@ static void sci_clk_enable(struct uart_port *port)
814{ 814{
815 struct sci_port *sci_port = to_sci_port(port); 815 struct sci_port *sci_port = to_sci_port(port);
816 816
817 clk_enable(sci_port->dclk); 817 clk_enable(sci_port->iclk);
818 sci_port->port.uartclk = clk_get_rate(sci_port->dclk); 818 sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
819 819 clk_enable(sci_port->fclk);
820 if (sci_port->iclk)
821 clk_enable(sci_port->iclk);
822} 820}
823 821
824static void sci_clk_disable(struct uart_port *port) 822static void sci_clk_disable(struct uart_port *port)
825{ 823{
826 struct sci_port *sci_port = to_sci_port(port); 824 struct sci_port *sci_port = to_sci_port(port);
827 825
828 if (sci_port->iclk) 826 clk_disable(sci_port->fclk);
829 clk_disable(sci_port->iclk); 827 clk_disable(sci_port->iclk);
830
831 clk_disable(sci_port->dclk);
832} 828}
833 829
834static int sci_request_irq(struct sci_port *port) 830static int sci_request_irq(struct sci_port *port)
@@ -1557,10 +1553,10 @@ static struct uart_ops sci_uart_ops = {
1557#endif 1553#endif
1558}; 1554};
1559 1555
1560static void __devinit sci_init_single(struct platform_device *dev, 1556static int __devinit sci_init_single(struct platform_device *dev,
1561 struct sci_port *sci_port, 1557 struct sci_port *sci_port,
1562 unsigned int index, 1558 unsigned int index,
1563 struct plat_sci_port *p) 1559 struct plat_sci_port *p)
1564{ 1560{
1565 struct uart_port *port = &sci_port->port; 1561 struct uart_port *port = &sci_port->port;
1566 1562
@@ -1581,8 +1577,23 @@ static void __devinit sci_init_single(struct platform_device *dev,
1581 } 1577 }
1582 1578
1583 if (dev) { 1579 if (dev) {
1584 sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; 1580 sci_port->iclk = clk_get(&dev->dev, "sci_ick");
1585 sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); 1581 if (IS_ERR(sci_port->iclk)) {
1582 sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
1583 if (IS_ERR(sci_port->iclk)) {
1584 dev_err(&dev->dev, "can't get iclk\n");
1585 return PTR_ERR(sci_port->iclk);
1586 }
1587 }
1588
1589 /*
1590 * The function clock is optional, ignore it if we can't
1591 * find it.
1592 */
1593 sci_port->fclk = clk_get(&dev->dev, "sci_fck");
1594 if (IS_ERR(sci_port->fclk))
1595 sci_port->fclk = NULL;
1596
1586 sci_port->enable = sci_clk_enable; 1597 sci_port->enable = sci_clk_enable;
1587 sci_port->disable = sci_clk_disable; 1598 sci_port->disable = sci_clk_disable;
1588 port->dev = &dev->dev; 1599 port->dev = &dev->dev;
@@ -1609,6 +1620,7 @@ static void __devinit sci_init_single(struct platform_device *dev,
1609#endif 1620#endif
1610 1621
1611 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); 1622 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
1623 return 0;
1612} 1624}
1613 1625
1614#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE 1626#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
@@ -1758,8 +1770,11 @@ static int sci_remove(struct platform_device *dev)
1758 cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); 1770 cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
1759 1771
1760 spin_lock_irqsave(&priv->lock, flags); 1772 spin_lock_irqsave(&priv->lock, flags);
1761 list_for_each_entry(p, &priv->ports, node) 1773 list_for_each_entry(p, &priv->ports, node) {
1762 uart_remove_one_port(&sci_uart_driver, &p->port); 1774 uart_remove_one_port(&sci_uart_driver, &p->port);
1775 clk_put(p->iclk);
1776 clk_put(p->fclk);
1777 }
1763 spin_unlock_irqrestore(&priv->lock, flags); 1778 spin_unlock_irqrestore(&priv->lock, flags);
1764 1779
1765 kfree(priv); 1780 kfree(priv);
@@ -1785,7 +1800,9 @@ static int __devinit sci_probe_single(struct platform_device *dev,
1785 return 0; 1800 return 0;
1786 } 1801 }
1787 1802
1788 sci_init_single(dev, sciport, index, p); 1803 ret = sci_init_single(dev, sciport, index, p);
1804 if (ret)
1805 return ret;
1789 1806
1790 ret = uart_add_one_port(&sci_uart_driver, &sciport->port); 1807 ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
1791 if (ret) 1808 if (ret)