Loading drivers/serial/samsung.c +96 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <linux/serial.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/cpufreq.h> #include <asm/irq.h> Loading Loading @@ -452,6 +453,8 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, { struct s3c24xx_uart_port *ourport = to_ourport(port); ourport->pm_level = level; switch (level) { case 3: if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) Loading Loading @@ -661,6 +664,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ourport->clksrc = clksrc; ourport->baudclk = clk; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; } switch (termios->c_cflag & CSIZE) { Loading Loading @@ -890,6 +894,93 @@ static inline int s3c24xx_serial_resetport(struct uart_port *port, return (info->reset_port)(port, cfg); } #ifdef CONFIG_CPU_FREQ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data) { struct s3c24xx_uart_port *port; struct uart_port *uport; port = container_of(nb, struct s3c24xx_uart_port, freq_transition); uport = &port->port; /* check to see if port is enabled */ if (port->pm_level != 0) return 0; /* try and work out if the baudrate is changing, we can detect * a change in rate, but we do not have support for detecting * a disturbance in the clock-rate over the change. */ if (IS_ERR(port->clk)) goto exit; if (port->baudclk_rate == clk_get_rate(port->clk)) goto exit; if (val == CPUFREQ_PRECHANGE) { /* we should really shut the port down whilst the * frequency change is in progress. */ } else if (val == CPUFREQ_POSTCHANGE) { struct ktermios *termios; struct tty_struct *tty; if (uport->info == NULL) { printk(KERN_WARNING "%s: info NULL\n", __func__); goto exit; } tty = uport->info->port.tty; if (tty == NULL) { printk(KERN_WARNING "%s: tty is NULL\n", __func__); goto exit; } termios = tty->termios; if (termios == NULL) { printk(KERN_WARNING "%s: no termios?\n", __func__); goto exit; } s3c24xx_serial_set_termios(uport, termios, NULL); } exit: return 0; } static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; return cpufreq_register_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { cpufreq_unregister_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } #else static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { return 0; } static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { } #endif /* s3c24xx_serial_init_port * * initialise a single serial port from the platform device given Loading Loading @@ -1002,6 +1093,10 @@ int s3c24xx_serial_probe(struct platform_device *dev, if (ret < 0) printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__); ret = s3c24xx_serial_cpufreq_register(ourport); if (ret < 0) dev_err(&dev->dev, "failed to add cpufreq notifier\n"); return 0; probe_err: Loading @@ -1015,6 +1110,7 @@ int s3c24xx_serial_remove(struct platform_device *dev) struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); if (port) { s3c24xx_serial_cpufreq_deregister(to_ourport(port)); device_remove_file(&dev->dev, &dev_attr_clock_source); uart_remove_one_port(&s3c24xx_uart_drv, port); } Loading drivers/serial/samsung.h +6 −0 Original line number Diff line number Diff line Loading @@ -33,12 +33,18 @@ struct s3c24xx_uart_info { struct s3c24xx_uart_port { unsigned char rx_claimed; unsigned char tx_claimed; unsigned int pm_level; unsigned long baudclk_rate; struct s3c24xx_uart_info *info; struct s3c24xx_uart_clksrc *clksrc; struct clk *clk; struct clk *baudclk; struct uart_port port; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif }; /* conversion functions */ Loading Loading
drivers/serial/samsung.c +96 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <linux/serial.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/cpufreq.h> #include <asm/irq.h> Loading Loading @@ -452,6 +453,8 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, { struct s3c24xx_uart_port *ourport = to_ourport(port); ourport->pm_level = level; switch (level) { case 3: if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) Loading Loading @@ -661,6 +664,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ourport->clksrc = clksrc; ourport->baudclk = clk; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; } switch (termios->c_cflag & CSIZE) { Loading Loading @@ -890,6 +894,93 @@ static inline int s3c24xx_serial_resetport(struct uart_port *port, return (info->reset_port)(port, cfg); } #ifdef CONFIG_CPU_FREQ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data) { struct s3c24xx_uart_port *port; struct uart_port *uport; port = container_of(nb, struct s3c24xx_uart_port, freq_transition); uport = &port->port; /* check to see if port is enabled */ if (port->pm_level != 0) return 0; /* try and work out if the baudrate is changing, we can detect * a change in rate, but we do not have support for detecting * a disturbance in the clock-rate over the change. */ if (IS_ERR(port->clk)) goto exit; if (port->baudclk_rate == clk_get_rate(port->clk)) goto exit; if (val == CPUFREQ_PRECHANGE) { /* we should really shut the port down whilst the * frequency change is in progress. */ } else if (val == CPUFREQ_POSTCHANGE) { struct ktermios *termios; struct tty_struct *tty; if (uport->info == NULL) { printk(KERN_WARNING "%s: info NULL\n", __func__); goto exit; } tty = uport->info->port.tty; if (tty == NULL) { printk(KERN_WARNING "%s: tty is NULL\n", __func__); goto exit; } termios = tty->termios; if (termios == NULL) { printk(KERN_WARNING "%s: no termios?\n", __func__); goto exit; } s3c24xx_serial_set_termios(uport, termios, NULL); } exit: return 0; } static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; return cpufreq_register_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { cpufreq_unregister_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } #else static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { return 0; } static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { } #endif /* s3c24xx_serial_init_port * * initialise a single serial port from the platform device given Loading Loading @@ -1002,6 +1093,10 @@ int s3c24xx_serial_probe(struct platform_device *dev, if (ret < 0) printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__); ret = s3c24xx_serial_cpufreq_register(ourport); if (ret < 0) dev_err(&dev->dev, "failed to add cpufreq notifier\n"); return 0; probe_err: Loading @@ -1015,6 +1110,7 @@ int s3c24xx_serial_remove(struct platform_device *dev) struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); if (port) { s3c24xx_serial_cpufreq_deregister(to_ourport(port)); device_remove_file(&dev->dev, &dev_attr_clock_source); uart_remove_one_port(&s3c24xx_uart_drv, port); } Loading
drivers/serial/samsung.h +6 −0 Original line number Diff line number Diff line Loading @@ -33,12 +33,18 @@ struct s3c24xx_uart_info { struct s3c24xx_uart_port { unsigned char rx_claimed; unsigned char tx_claimed; unsigned int pm_level; unsigned long baudclk_rate; struct s3c24xx_uart_info *info; struct s3c24xx_uart_clksrc *clksrc; struct clk *clk; struct clk *baudclk; struct uart_port port; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif }; /* conversion functions */ Loading