From patchwork Fri Jan 8 13:01:38 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: 71787 Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o08DUtWA014762 for ; Fri, 8 Jan 2010 13:30:56 GMT Received: from dlep33.itg.ti.com ([157.170.170.112]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id o08DSN9Z019775 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 8 Jan 2010 07:28:23 -0600 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep33.itg.ti.com (8.13.7/8.13.7) with ESMTP id o08DSLZ6025463; Fri, 8 Jan 2010 07:28:21 -0600 (CST) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 993B380627; Fri, 8 Jan 2010 07:28:21 -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 54F9F80626 for ; Fri, 8 Jan 2010 07:28:20 -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 o08DSIuJ020261; Fri, 8 Jan 2010 07:28:19 -0600 (CST) Received: from symphonyindia.ti.com (symphony-ftp [192.168.247.11]) by tidmzi-ftp.india.ext.ti.com (Postfix) with SMTP id C99C73886B; Fri, 8 Jan 2010 18:55:00 +0530 (IST) Received: from localhost.localdomain ([192.168.247.76]) by symphonyindia.ti.com (8.13.1/8.12.10) with ESMTP id o08DDS6O021639; Fri, 8 Jan 2010 18:43:28 +0530 From: Chaithrika U S To: davinci-linux-open-source@linux.davincidsp.com Subject: [RFC] serial: 8250: Add cpufreq support Date: Fri, 8 Jan 2010 18:31:38 +0530 Message-Id: <1262955698-6130-1-git-send-email-chaithrika@ti.com> X-Mailer: git-send-email 1.5.6 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..612e129 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 *uart_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(!p->port.uartclk) + goto cpu_freq_exit; + + if (p->port.uartclk == clk_get_rate(p->uart_clk)) + goto cpu_freq_exit; + + p->port.uartclk = clk_get_rate(p->uart_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 @@ -3090,6 +3160,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * */ int serial8250_register_port(struct uart_port *port) { + struct plat_serial8250_port *p; struct uart_8250_port *uart; int ret = -ENOSPC; @@ -3116,6 +3187,10 @@ int serial8250_register_port(struct uart_port *port) if (port->dev) uart->port.dev = port->dev; + p = port->dev->platform_data; + if (p->uart_clk) + uart->uart_clk = p->uart_clk; + if (port->flags & UPF_FIXED_TYPE) { uart->port.type = port->type; uart->port.fifosize = uart_config[port->type].fifo_size; @@ -3133,6 +3208,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 +3232,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..d85201f 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 *uart_clk; unsigned int uartclk; /* UART clock rate */ void *private_data; unsigned char regshift; /* register shift */