From patchwork Wed Jan 21 15:13:42 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 3457 X-Patchwork-Delegate: lethal@linux-sh.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n0LFAs8x023030 for ; Wed, 21 Jan 2009 07:11:02 -0800 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754677AbZAUPPk (ORCPT ); Wed, 21 Jan 2009 10:15:40 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753480AbZAUPPk (ORCPT ); Wed, 21 Jan 2009 10:15:40 -0500 Received: from rv-out-0506.google.com ([209.85.198.232]:37964 "EHLO rv-out-0506.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754677AbZAUPPj (ORCPT ); Wed, 21 Jan 2009 10:15:39 -0500 Received: by rv-out-0506.google.com with SMTP id k40so3654714rvb.1 for ; Wed, 21 Jan 2009 07:15:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :in-reply-to:references:subject; bh=e7OTlFa7DhiJBBS5Q0rDs4AvKZ4glSqGDOYYRQIiagE=; b=HAqLqWJ9FV7mowVblp7OZ6KLszLKuo+fI+gaoipTfvVaH6Zj1tEx10qx7TJpz1d0JL gLn2RoqOvdS2WrHHIwNxek56Ay1wC4si5p3LYUXU1/yUzZhLOqDCVJOpjYdP4hcmjjhM 3nzYiNCzC/n2OglmZ8CuNGGRPslwlG+2TqEnw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:in-reply-to:references:subject; b=sLsHyNw2iWR9pi4oDuZ4aQ/tOyMOYiVzOJlfe3LzT0Q6Y/2PtJIk4ETzVwkCIya2UD BYxQEuh/ASTxrDpmx9dWtegxH0wnpN1d8djmLJjd37q5z3FclY6F11jhSk5ObDeg3y2z 9sQe8s0it2BGmnEtP6veZY4+1NZaw+mdd1Nf8= Received: by 10.141.44.13 with SMTP id w13mr4033872rvj.18.1232550938203; Wed, 21 Jan 2009 07:15:38 -0800 (PST) Received: from rx1.opensource.se (114.8.221.202.ts.2iij.net [202.221.8.114]) by mx.google.com with ESMTPS id b8sm15628336rvf.9.2009.01.21.07.15.35 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 21 Jan 2009 07:15:37 -0800 (PST) From: Magnus Damm To: linux-sh@vger.kernel.org Cc: Magnus Damm , lethal@linux-sh.org Date: Thu, 22 Jan 2009 00:13:42 +0900 Message-Id: <20090121151342.29269.60430.sendpatchset@rx1.opensource.se> In-Reply-To: <20090121151334.29269.55519.sendpatchset@rx1.opensource.se> References: <20090121151334.29269.55519.sendpatchset@rx1.opensource.se> Subject: [PATCH 001/013] sh-sci: add platform device private data Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org From: Magnus Damm This patch adds per-platform private data to the sh-sci driver. Signed-off-by: Magnus Damm --- drivers/serial/sh-sci.c | 131 +++++++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 44 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- 0001/drivers/serial/sh-sci.c +++ work/drivers/serial/sh-sci.c 2009-01-20 16:33:04.000000000 +0900 @@ -47,6 +47,7 @@ #include #include #include +#include #ifdef CONFIG_SUPERH #include @@ -78,6 +79,16 @@ struct sci_port { /* Port clock */ struct clk *clk; #endif + struct list_head node; +}; + +struct sh_sci_priv { + spinlock_t lock; + struct list_head ports; + +#ifdef CONFIG_HAVE_CLK + struct notifier_block clk_nb; +#endif }; #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE @@ -724,19 +735,22 @@ static irqreturn_t sci_mpxed_interrupt(i static int sci_notifier(struct notifier_block *self, unsigned long phase, void *p) { - int i; + struct sh_sci_priv *priv = container_of(self, + struct sh_sci_priv, clk_nb); + struct sci_port *sci_port; + unsigned long flags; if ((phase == CPUFREQ_POSTCHANGE) || - (phase == CPUFREQ_RESUMECHANGE)) - for (i = 0; i < SCI_NPORTS; i++) { - struct sci_port *s = &sci_ports[i]; - s->port.uartclk = clk_get_rate(s->clk); - } + (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->clk); + + spin_unlock_irqrestore(&priv->lock, flags); + } return NOTIFY_OK; } - -static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; #endif static int sci_request_irq(struct sci_port *port) @@ -1199,6 +1213,27 @@ static struct uart_driver sci_uart_drive .cons = SCI_CONSOLE, }; + +static int __devexit sci_remove(struct platform_device *dev) +{ + struct sh_sci_priv *priv = platform_get_drvdata(dev); + struct sci_port *p; + unsigned long flags; + +#ifdef CONFIG_HAVE_CLK + cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); +#endif + + spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry(p, &priv->ports, node) + uart_remove_one_port(&sci_uart_driver, &p->port); + + spin_unlock_irqrestore(&priv->lock, flags); + + kfree(priv); + return 0; +} + /* * Register a set of serial devices attached to a platform device. The * list is terminated with a zero flags entry, which means we expect @@ -1208,7 +1243,22 @@ static struct uart_driver sci_uart_drive 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; + unsigned long flags; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + INIT_LIST_HEAD(&priv->ports); + spin_lock_init(&priv->lock); + platform_set_drvdata(dev, priv); + +#ifdef CONFIG_HAVE_CLK + priv->clk_nb.notifier_call = sci_notifier; + cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); +#endif for (i = 0; p && p->flags != 0; p++, i++) { struct sci_port *sciport = &sci_ports[i]; @@ -1252,12 +1302,19 @@ static int __devinit sci_probe(struct pl memcpy(&sciport->irqs, &p->irqs, sizeof(p->irqs)); - uart_add_one_port(&sci_uart_driver, &sciport->port); - } + ret = uart_add_one_port(&sci_uart_driver, &sciport->port); -#ifdef CONFIG_HAVE_CLK - cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); -#endif + if (ret && (p->flags & UPF_IOREMAP)) { + iounmap(p->membase); + goto err_unreg; + } + + INIT_LIST_HEAD(&sciport->node); + + spin_lock_irqsave(&priv->lock, flags); + list_add(&sciport->node, &priv->ports); + spin_unlock_irqrestore(&priv->lock, flags); + } #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_gdb_detach(); @@ -1266,50 +1323,36 @@ static int __devinit sci_probe(struct pl return 0; err_unreg: - for (i = i - 1; i >= 0; i--) - uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); - + sci_remove(dev); return ret; } -static int __devexit sci_remove(struct platform_device *dev) -{ - int i; - -#ifdef CONFIG_HAVE_CLK - cpufreq_unregister_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); -#endif - - for (i = 0; i < SCI_NPORTS; i++) - uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); - - return 0; -} - static int sci_suspend(struct platform_device *dev, pm_message_t state) { - int i; + struct sh_sci_priv *priv = platform_get_drvdata(dev); + struct sci_port *p; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry(p, &priv->ports, node) + uart_suspend_port(&sci_uart_driver, &p->port); - for (i = 0; i < SCI_NPORTS; i++) { - struct sci_port *p = &sci_ports[i]; - - if (p->type != PORT_UNKNOWN && p->port.dev == &dev->dev) - uart_suspend_port(&sci_uart_driver, &p->port); - } + spin_unlock_irqrestore(&priv->lock, flags); return 0; } static int sci_resume(struct platform_device *dev) { - int i; + struct sh_sci_priv *priv = platform_get_drvdata(dev); + struct sci_port *p; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry(p, &priv->ports, node) + uart_resume_port(&sci_uart_driver, &p->port); - for (i = 0; i < SCI_NPORTS; i++) { - struct sci_port *p = &sci_ports[i]; - - if (p->type != PORT_UNKNOWN && p->port.dev == &dev->dev) - uart_resume_port(&sci_uart_driver, &p->port); - } + spin_unlock_irqrestore(&priv->lock, flags); return 0; }