From patchwork Wed Jan 13 12:35:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chaithrika@ti.com X-Patchwork-Id: 72622 Received: from arroyo.ext.ti.com (arroyo.ext.ti.com [192.94.94.40]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0DD57gR007730 for ; Wed, 13 Jan 2010 13:05:07 GMT Received: from dlep36.itg.ti.com ([157.170.170.91]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id o0DD3P3p011499 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 13 Jan 2010 07:03:25 -0600 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id o0DD3ND4005763; Wed, 13 Jan 2010 07:03:24 -0600 (CST) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id DF2B780627; Wed, 13 Jan 2010 07:03:23 -0600 (CST) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp53.itg.ti.com (dflp53.itg.ti.com [128.247.5.6]) by linux.omap.com (Postfix) with ESMTP id 34B4B80626 for ; Wed, 13 Jan 2010 07:03:23 -0600 (CST) Received: from tidmzi-ftp.india.ext.ti.com (localhost [127.0.0.1]) by dflp53.itg.ti.com (8.13.8/8.13.8) with SMTP id o0DD3Km0001741; Wed, 13 Jan 2010 07:03:21 -0600 (CST) Received: from symphonyindia.ti.com (symphony-ftp [192.168.247.11]) by tidmzi-ftp.india.ext.ti.com (Postfix) with SMTP id 3094D3886B; Wed, 13 Jan 2010 18:30:02 +0530 (IST) Received: from localhost.localdomain ([192.168.247.76]) by symphonyindia.ti.com (8.13.1/8.12.10) with ESMTP id o0DClRQj029344; Wed, 13 Jan 2010 18:17:27 +0530 From: Chaithrika U S To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] serial: 8250: Add cpufreq support Date: Wed, 13 Jan 2010 18:05:21 +0530 Message-Id: <1263386121-6644-1-git-send-email-chaithrika@ti.com> X-Mailer: git-send-email 1.5.6 Cc: davinci-linux-open-source@linux.davincidsp.com, akpm@linux-foundation.org X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c3e37c8..a64d1de 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -156,6 +158,10 @@ struct uart_8250_port { */ void (*pm)(struct uart_port *port, unsigned int state, unsigned int old); + struct clk *clk; +#ifdef CONFIG_CPU_FREQ + struct notifier_block freq_transition; +#endif }; struct irq_info { @@ -2931,6 +2937,70 @@ void serial8250_resume_port(int line) uart_resume_port(&serial8250_reg, &up->port); } +#ifdef CONFIG_CPU_FREQ +static int serial8250_cpufreq_transition(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct uart_8250_port *p; + struct uart_port *uport; + + p = container_of(nb, struct uart_8250_port, freq_transition); + uport = &p->port; + + if (IS_ERR(p->clk)) + goto cpu_freq_exit; + + if (p->port.uartclk == clk_get_rate(p->clk)) + goto cpu_freq_exit; + + p->port.uartclk = clk_get_rate(p->clk); + if (val == CPUFREQ_POSTCHANGE) { + struct ktermios *termios; + struct tty_struct *tty; + if (uport->state == NULL) + goto cpu_freq_exit; + + tty = uport->state->port.tty; + if (tty == NULL) + goto cpu_freq_exit; + + termios = tty->termios; + if (termios == NULL) { + printk(KERN_WARNING "%s: no termios?\n", __func__); + goto cpu_freq_exit; + } + + serial8250_set_termios(uport, termios, NULL); + } + +cpu_freq_exit: + return 0; +} + +static inline int serial8250_cpufreq_register(struct uart_8250_port *p) +{ + p->freq_transition.notifier_call = serial8250_cpufreq_transition; + + return cpufreq_register_notifier(&p->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +} + +static inline void serial8250_cpufreq_deregister(struct uart_8250_port *p) +{ + cpufreq_unregister_notifier(&p->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +} +#else +static inline int serial8250_cpufreq_register(struct uart_8250_port *p) +{ + return 0; +} + +static inline void serial8250_cpufreq_deregister(struct uart_8250_port *p) +{ +} +#endif + /* * Register a set of serial devices attached to a platform device. The * list is terminated with a zero flags entry, which means we expect @@ -2964,6 +3034,9 @@ static int __devinit serial8250_probe(struct platform_device *dev) port.serial_out = p->serial_out; port.dev = &dev->dev; port.irqflags |= irqflag; + if (p->clk) + serial8250_ports[i].clk = p->clk; + ret = serial8250_register_port(&port); if (ret < 0) { dev_err(&dev->dev, "unable to register port at index %d " @@ -3133,6 +3206,11 @@ int serial8250_register_port(struct uart_port *port) ret = uart_add_one_port(&serial8250_reg, &uart->port); if (ret == 0) ret = uart->port.line; + + ret = serial8250_cpufreq_register(uart); + if (ret < 0) + printk(KERN_ERR "Failed to add cpufreq notifier\n"); + } mutex_unlock(&serial_mutex); @@ -3152,6 +3230,7 @@ void serial8250_unregister_port(int line) struct uart_8250_port *uart = &serial8250_ports[line]; mutex_lock(&serial_mutex); + serial8250_cpufreq_deregister(uart); uart_remove_one_port(&serial8250_reg, &uart->port); if (serial8250_isa_devs) { uart->port.flags &= ~UPF_BOOT_AUTOCONF; diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index fb46aba..57d6e69 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -23,6 +23,7 @@ struct plat_serial8250_port { resource_size_t mapbase; /* resource base */ unsigned int irq; /* interrupt number */ unsigned long irqflags; /* request_irq flags */ + struct clk *clk; unsigned int uartclk; /* UART clock rate */ void *private_data; unsigned char regshift; /* register shift */