提交 d535a230 编写于 作者: P Paul Mundt

serial: sh-sci: Require a device per port mapping.

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: NPaul Mundt <lethal@linux-sh.org>
上级 27bd1075
......@@ -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 @@ static int __devinit sci_probe(struct platform_device *dev)
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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册