diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-11-22 14:05:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-22 14:05:46 -0500 |
commit | 515db09338704a6ad7d27b5f1e33820d3052edd2 (patch) | |
tree | 74f915531710303397d34069b325c2be7a5ac93c /drivers/tty | |
parent | 30be52e44fd4276d768efffb55d424fb682e6505 (diff) | |
parent | cfcfc9eca2bcbd26a8e206baeb005b055dbf8e37 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
Conflicts:
drivers/net/wireless/iwlegacy/iwl-debugfs.c
drivers/net/wireless/iwlegacy/iwl-rx.c
drivers/net/wireless/iwlegacy/iwl-scan.c
drivers/net/wireless/iwlegacy/iwl-tx.c
include/net/bluetooth/bluetooth.h
Diffstat (limited to 'drivers/tty')
30 files changed, 546 insertions, 95 deletions
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 8816f53e004..b3d17416d86 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -1,6 +1,6 @@ config VT bool "Virtual terminal" if EXPERT - depends on !S390 + depends on !S390 && !UML select INPUT default y ---help--- diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index e371753ba92..4222035acfb 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig @@ -34,6 +34,15 @@ config HVC_ISERIES help iSeries machines support a hypervisor virtual console. +config HVC_OPAL + bool "OPAL Console support" + depends on PPC_POWERNV + select HVC_DRIVER + select HVC_IRQ + default y + help + PowerNV machines running under OPAL need that driver to get a console + config HVC_RTAS bool "IBM RTAS Console support" depends on PPC_RTAS diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile index e2920531637..89abf40bc73 100644 --- a/drivers/tty/hvc/Makefile +++ b/drivers/tty/hvc/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o +obj-$(CONFIG_HVC_OPAL) += hvc_opal.o hvsi_lib.o obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 7430bc3c8d5..b6b2d18fa38 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -852,7 +852,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, * find index to use: * see if this vterm id matches one registered for console. */ - for (i = 0; i < MAX_NR_HVC_CONSOLES; i++) + for (i=0; i < MAX_NR_HVC_CONSOLES; i++) if (vtermnos[i] == hp->vtermno && cons_ops[i] == hp->ops) break; @@ -862,13 +862,9 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, i = ++last_hvc; hp->index = i; - hvc_console.index = i; - vtermnos[i] = vtermno; - cons_ops[i] = ops; list_add_tail(&(hp->next), &hvc_structs); spin_unlock(&hvc_structs_lock); - register_console(&hvc_console); return hp; } @@ -879,7 +875,6 @@ int hvc_remove(struct hvc_struct *hp) unsigned long flags; struct tty_struct *tty; - unregister_console(&hvc_console); spin_lock_irqsave(&hp->lock, flags); tty = tty_kref_get(hp->tty); diff --git a/drivers/tty/hvc/hvc_iseries.c b/drivers/tty/hvc/hvc_iseries.c index 21c54955084..3f4a897bf4d 100644 --- a/drivers/tty/hvc/hvc_iseries.c +++ b/drivers/tty/hvc/hvc_iseries.c @@ -23,6 +23,7 @@ #include <linux/types.h> #include <linux/init.h> #include <linux/kernel.h> +#include <linux/module.h> #include <linux/spinlock.h> #include <linux/console.h> diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c new file mode 100644 index 00000000000..ced26c8ccd5 --- /dev/null +++ b/drivers/tty/hvc/hvc_opal.c @@ -0,0 +1,425 @@ +/* + * opal driver interface to hvc_console.c + * + * Copyright 2011 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#undef DEBUG + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/console.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/export.h> + +#include <asm/hvconsole.h> +#include <asm/prom.h> +#include <asm/firmware.h> +#include <asm/hvsi.h> +#include <asm/udbg.h> +#include <asm/opal.h> + +#include "hvc_console.h" + +static const char hvc_opal_name[] = "hvc_opal"; + +static struct of_device_id hvc_opal_match[] __devinitdata = { + { .name = "serial", .compatible = "ibm,opal-console-raw" }, + { .name = "serial", .compatible = "ibm,opal-console-hvsi" }, + { }, +}; + +typedef enum hv_protocol { + HV_PROTOCOL_RAW, + HV_PROTOCOL_HVSI +} hv_protocol_t; + +struct hvc_opal_priv { + hv_protocol_t proto; /* Raw data or HVSI packets */ + struct hvsi_priv hvsi; /* HVSI specific data */ +}; +static struct hvc_opal_priv *hvc_opal_privs[MAX_NR_HVC_CONSOLES]; + +/* For early boot console */ +static struct hvc_opal_priv hvc_opal_boot_priv; +static u32 hvc_opal_boot_termno; + +static const struct hv_ops hvc_opal_raw_ops = { + .get_chars = opal_get_chars, + .put_chars = opal_put_chars, + .notifier_add = notifier_add_irq, + .notifier_del = notifier_del_irq, + .notifier_hangup = notifier_hangup_irq, +}; + +static int hvc_opal_hvsi_get_chars(uint32_t vtermno, char *buf, int count) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[vtermno]; + + if (WARN_ON(!pv)) + return -ENODEV; + + return hvsilib_get_chars(&pv->hvsi, buf, count); +} + +static int hvc_opal_hvsi_put_chars(uint32_t vtermno, const char *buf, int count) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[vtermno]; + + if (WARN_ON(!pv)) + return -ENODEV; + + return hvsilib_put_chars(&pv->hvsi, buf, count); +} + +static int hvc_opal_hvsi_open(struct hvc_struct *hp, int data) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; + int rc; + + pr_devel("HVSI@%x: do open !\n", hp->vtermno); + + rc = notifier_add_irq(hp, data); + if (rc) + return rc; + + return hvsilib_open(&pv->hvsi, hp); +} + +static void hvc_opal_hvsi_close(struct hvc_struct *hp, int data) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; + + pr_devel("HVSI@%x: do close !\n", hp->vtermno); + + hvsilib_close(&pv->hvsi, hp); + + notifier_del_irq(hp, data); +} + +void hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; + + pr_devel("HVSI@%x: do hangup !\n", hp->vtermno); + + hvsilib_close(&pv->hvsi, hp); + + notifier_hangup_irq(hp, data); +} + +static int hvc_opal_hvsi_tiocmget(struct hvc_struct *hp) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; + + if (!pv) + return -EINVAL; + return pv->hvsi.mctrl; +} + +static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set, + unsigned int clear) +{ + struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; + + pr_devel("HVSI@%x: Set modem control, set=%x,clr=%x\n", + hp->vtermno, set, clear); + + if (set & TIOCM_DTR) + hvsilib_write_mctrl(&pv->hvsi, 1); + else if (clear & TIOCM_DTR) + hvsilib_write_mctrl(&pv->hvsi, 0); + + return 0; +} + +static const struct hv_ops hvc_opal_hvsi_ops = { + .get_chars = hvc_opal_hvsi_get_chars, + .put_chars = hvc_opal_hvsi_put_chars, + .notifier_add = hvc_opal_hvsi_open, + .notifier_del = hvc_opal_hvsi_close, + .notifier_hangup = hvc_opal_hvsi_hangup, + .tiocmget = hvc_opal_hvsi_tiocmget, + .tiocmset = hvc_opal_hvsi_tiocmset, +}; + +static int __devinit hvc_opal_probe(struct platform_device *dev) +{ + const struct hv_ops *ops; + struct hvc_struct *hp; + struct hvc_opal_priv *pv; + hv_protocol_t proto; + unsigned int termno, boot = 0; + const __be32 *reg; + + if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) { + proto = HV_PROTOCOL_RAW; + ops = &hvc_opal_raw_ops; + } else if (of_device_is_compatible(dev->dev.of_node, + "ibm,opal-console-hvsi")) { + proto = HV_PROTOCOL_HVSI; + ops = &hvc_opal_hvsi_ops; + } else { + pr_err("hvc_opal: Unkown protocol for %s\n", + dev->dev.of_node->full_name); + return -ENXIO; + } + + reg = of_get_property(dev->dev.of_node, "reg", NULL); + termno = reg ? be32_to_cpup(reg) : 0; + + /* Is it our boot one ? */ + if (hvc_opal_privs[termno] == &hvc_opal_boot_priv) { + pv = hvc_opal_privs[termno]; + boot = 1; + } else if (hvc_opal_privs[termno] == NULL) { + pv = kzalloc(sizeof(struct hvc_opal_priv), GFP_KERNEL); + if (!pv) + return -ENOMEM; + pv->proto = proto; + hvc_opal_privs[termno] = pv; + if (proto == HV_PROTOCOL_HVSI) + hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars, + termno, 0); + + /* Instanciate now to establish a mapping index==vtermno */ + hvc_instantiate(termno, termno, ops); + } else { + pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n", + dev->dev.of_node->full_name, termno); + return -ENXIO; + } + + pr_info("hvc%d: %s protocol on %s%s\n", termno, + proto == HV_PROTOCOL_RAW ? "raw" : "hvsi", + dev->dev.of_node->full_name, + boot ? " (boot console)" : ""); + + /* We don't do IRQ yet */ + hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS); + if (IS_ERR(hp)) + return PTR_ERR(hp); + dev_set_drvdata(&dev->dev, hp); + + return 0; +} + +static int __devexit hvc_opal_remove(struct platform_device *dev) +{ + struct hvc_struct *hp = dev_get_drvdata(&dev->dev); + int rc, termno; + + termno = hp->vtermno; + rc = hvc_remove(hp); + if (rc == 0) { + if (hvc_opal_privs[termno] != &hvc_opal_boot_priv) + kfree(hvc_opal_privs[termno]); + hvc_opal_privs[termno] = NULL; + } + return rc; +} + +static struct platform_driver hvc_opal_driver = { + .probe = hvc_opal_probe, + .remove = __devexit_p(hvc_opal_remove), + .driver = { + .name = hvc_opal_name, + .owner = THIS_MODULE, + .of_match_table = hvc_opal_match, + } +}; + +static int __init hvc_opal_init(void) +{ + if (!firmware_has_feature(FW_FEATURE_OPAL)) + return -ENODEV; + + /* Register as a vio device to receive callbacks */ + return platform_driver_register(&hvc_opal_driver); +} +module_init(hvc_opal_init); + +static void __exit hvc_opal_exit(void) +{ + platform_driver_unregister(&hvc_opal_driver); +} +module_exit(hvc_opal_exit); + +static void udbg_opal_putc(char c) +{ + unsigned int termno = hvc_opal_boot_termno; + int count = -1; + + if (c == '\n') + udbg_opal_putc('\r'); + + do { + switch(hvc_opal_boot_priv.proto) { + case HV_PROTOCOL_RAW: + count = opal_put_chars(termno, &c, 1); + break; + case HV_PROTOCOL_HVSI: + count = hvc_opal_hvsi_put_chars(termno, &c, 1); + break; + } + } while(count == 0 || count == -EAGAIN); +} + +static int udbg_opal_getc_poll(void) +{ + unsigned int termno = hvc_opal_boot_termno; + int rc = 0; + char c; + + switch(hvc_opal_boot_priv.proto) { + case HV_PROTOCOL_RAW: + rc = opal_get_chars(termno, &c, 1); + break; + case HV_PROTOCOL_HVSI: + rc = hvc_opal_hvsi_get_chars(termno, &c, 1); + break; + } + if (!rc) + return -1; + return c; +} + +static int udbg_opal_getc(void) +{ + int ch; + for (;;) { + ch = udbg_opal_getc_poll(); + if (ch == -1) { + /* This shouldn't be needed...but... */ + volatile unsigned long delay; + for (delay=0; delay < 2000000; delay++) + ; + } else { + return ch; + } + } +} + +static void udbg_init_opal_common(void) +{ + udbg_putc = udbg_opal_putc; + udbg_getc = udbg_opal_getc; + udbg_getc_poll = udbg_opal_getc_poll; + tb_ticks_per_usec = 0x200; /* Make udelay not suck */ +} + +void __init hvc_opal_init_early(void) +{ + struct device_node *stdout_node = NULL; + const u32 *termno; + const char *name = NULL; + const struct hv_ops *ops; + u32 index; + + /* find the boot console from /chosen/stdout */ + if (of_chosen) + name = of_get_property(of_chosen, "linux,stdout-path", NULL); + if (name) { + stdout_node = of_find_node_by_path(name); + if (!stdout_node) { + pr_err("hvc_opal: Failed to locate default console!\n"); + return; + } + } else { + struct device_node *opal, *np; + + /* Current OPAL takeover doesn't provide the stdout + * path, so we hard wire it + */ + opal = of_find_node_by_path("/ibm,opal/consoles"); + if (opal) + pr_devel("hvc_opal: Found consoles in new location\n"); + if (!opal) { + opal = of_find_node_by_path("/ibm,opal"); + if (opal) + pr_devel("hvc_opal: " + "Found consoles in old location\n"); + } + if (!opal) + return; + for_each_child_of_node(opal, np) { + if (!strcmp(np->name, "serial")) { + stdout_node = np; + break; + } + } + of_node_put(opal); + } + if (!stdout_node) + return; + termno = of_get_property(stdout_node, "reg", NULL); + index = termno ? *termno : 0; + if (index >= MAX_NR_HVC_CONSOLES) + return; + hvc_opal_privs[index] = &hvc_opal_boot_priv; + + /* Check the protocol */ + if (of_device_is_compatible(stdout_node, "ibm,opal-console-raw")) { + hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW; + ops = &hvc_opal_raw_ops; + pr_devel("hvc_opal: Found RAW console\n"); + } + else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) { + hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI; + ops = &hvc_opal_hvsi_ops; + hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, + opal_put_chars, index, 1); + /* HVSI, perform the handshake now */ + hvsilib_establish(&hvc_opal_boot_priv.hvsi); + pr_devel("hvc_opal: Found HVSI console\n"); + } else + goto out; + hvc_opal_boot_termno = index; + udbg_init_opal_common(); + add_preferred_console("hvc", index, NULL); + hvc_instantiate(index, index, ops); +out: + of_node_put(stdout_node); +} + +#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW +void __init udbg_init_debug_opal(void) +{ + u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO; + hvc_opal_privs[index] = &hvc_opal_boot_priv; + hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW; + hvc_opal_boot_termno = index; + udbg_init_opal_common(); +} +#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_RAW */ + +#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI +void __init udbg_init_debug_opal_hvsi(void) +{ + u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO; + hvc_opal_privs[index] = &hvc_opal_boot_priv; + hvc_opal_boot_termno = index; + udbg_init_opal_common(); + hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars, + index, 1); + hvsilib_establish(&hvc_opal_boot_priv.hvsi); +} +#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI */ diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 130aace67f3..fc3c3ad6c07 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -41,6 +41,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/console.h> +#include <linux/module.h> #include <asm/hvconsole.h> #include <asm/vio.h> diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 55882b5930a..b9040bec36b 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1532,7 +1532,7 @@ static int __devinit hvcs_initialize(void) goto register_fail; } - hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL); + hvcs_pi_buff = (unsigned long *) __get_free_page(GFP_KERNEL); if (!hvcs_pi_buff) { rc = -ENOMEM; goto buff_alloc_fail; @@ -1548,7 +1548,7 @@ static int __devinit hvcs_initialize(void) return 0; kthread_fail: - kfree(hvcs_pi_buff); + free_page((unsigned long)hvcs_pi_buff); buff_alloc_fail: tty_unregister_driver(hvcs_tty_driver); register_fail: @@ -1597,7 +1597,7 @@ static void __exit hvcs_module_exit(void) kthread_stop(hvcs_task); spin_lock(&hvcs_pi_lock); - kfree(hvcs_pi_buff); + free_page((unsigned long)hvcs_pi_buff); hvcs_pi_buff = NULL; spin_unlock(&hvcs_pi_lock); diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c index bd9b09827b2..6f4dd83d869 100644 --- a/drivers/tty/hvc/hvsi_lib.c +++ b/drivers/tty/hvc/hvsi_lib.c @@ -183,7 +183,7 @@ int hvsilib_get_chars(struct hvsi_priv *pv, char *buf, int count) unsigned int tries, read = 0; if (WARN_ON(!pv)) - return 0; + return -ENXIO; /* If we aren't open, don't do anything in order to avoid races * with connection establishment. The hvc core will call this @@ -234,7 +234,7 @@ int hvsilib_put_chars(struct hvsi_priv *pv, const char *buf, int count) int rc, adjcount = min(count, HVSI_MAX_OUTGOING_DATA); if (WARN_ON(!pv)) - return 0; + return -ENODEV; dp.hdr.type = VS_DATA_PACKET_HEADER; dp.hdr.len = adjcount + sizeof(struct hvsi_header); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 4cb0d0a3e57..fc7bbba585c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -66,14 +66,16 @@ static int debug; module_param(debug, int, 0600); -#define T1 (HZ/10) -#define T2 (HZ/3) -#define N2 3 +/* Defaults: these are from the specification */ + +#define T1 10 /* 100mS */ +#define T2 34 /* 333mS */ +#define N2 3 /* Retry 3 times */ /* Use long timers for testing at low speed with debug on */ #ifdef DEBUG_TIMING -#define T1 HZ -#define T2 (2 * HZ) +#define T1 100 +#define T2 200 #endif /* diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index a87a56cb541..eeadf1b8e09 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -450,24 +450,6 @@ static void au_serial_out(struct uart_port *p, int offset, int value) __raw_writel(value, p->membase + offset); } -static unsigned int tsi_serial_in(struct uart_port *p, int offset) -{ - unsigned int tmp; - offset = map_8250_in_reg(p, offset) << p->regshift; - if (offset == UART_IIR) { - tmp = readl(p->membase + (UART_IIR & ~3)); - return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ - } else - return readb(p->membase + offset); -} - -static void tsi_serial_out(struct uart_port *p, int offset, int value) -{ - offset = map_8250_out_reg(p, offset) << p->regshift; - if (!((offset == UART_IER) && (value & UART_IER_UUE))) - writeb(value, p->membase + offset); -} - static unsigned int io_serial_in(struct uart_port *p, int offset) { offset = map_8250_in_reg(p, offset) << p->regshift; @@ -508,11 +490,6 @@ static void set_io_from_upio(struct uart_port *p) p->serial_out = au_serial_out; break; - case UPIO_TSI: - p->serial_in = tsi_serial_in; - p->serial_out = tsi_serial_out; - break; - default: p->serial_in = io_serial_in; p->serial_out = io_serial_out; diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 00a73ecb2df..530181e49f6 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -18,6 +18,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/console.h> +#include <linux/of.h> #include <linux/tty.h> #include <linux/tty_flip.h> #include <linux/serial.h> @@ -472,8 +473,6 @@ static struct of_device_id altera_jtaguart_match[] = { {}, }; MODULE_DEVICE_TABLE(of, altera_jtaguart_match); -#else -#define altera_jtaguart_match NULL #endif /* CONFIG_OF */ static struct platform_driver altera_jtaguart_platform_driver = { @@ -482,7 +481,7 @@ static struct platform_driver altera_jtaguart_platform_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, - .of_match_table = altera_jtaguart_match, + .of_match_table = of_match_ptr(altera_jtaguart_match), }, }; diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index d902558ccfd..1d04c5037f2 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -616,8 +616,6 @@ static struct of_device_id altera_uart_match[] = { {}, }; MODULE_DEVICE_TABLE(of, altera_uart_match); -#else -#define altera_uart_match NULL #endif /* CONFIG_OF */ static struct platform_driver altera_uart_platform_driver = { @@ -626,7 +624,7 @@ static struct platform_driver altera_uart_platform_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, - .of_match_table = altera_uart_match, + .of_match_table = of_match_ptr(altera_uart_match), }, }; diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index c0d10c4ddb7..efdf92c3a35 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -312,12 +312,16 @@ static int pl010_startup(struct uart_port *port) struct uart_amba_port *uap = (struct uart_amba_port *)port; int retval; + retval = clk_prepare(uap->clk); + if (retval) + goto out; + /* * Try to enable the clock producer. */ retval = clk_enable(uap->clk); if (retval) - goto out; + goto clk_unprep; uap->port.uartclk = clk_get_rate(uap->clk); @@ -343,6 +347,8 @@ static int pl010_startup(struct uart_port *port) clk_dis: clk_disable(uap->clk); + clk_unprep: + clk_unprepare(uap->clk); out: return retval; } @@ -370,6 +376,7 @@ static void pl010_shutdown(struct uart_port *port) * Shut down the clock producer */ clk_disable(uap->clk); + clk_unprepare(uap->clk); } static void @@ -626,6 +633,7 @@ static int __init pl010_console_setup(struct console *co, char *options) int bits = 8; int parity = 'n'; int flow = 'n'; + int ret; /* * Check whether an invalid uart number has been specified, and @@ -638,6 +646,10 @@ static int __init pl010_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + ret = clk_prepare(uap->clk); + if (ret) + return ret; + uap->port.uartclk = clk_get_rate(uap->clk); if (options) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index f5f6831b0a6..00233af1acc 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1367,12 +1367,16 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + retval = clk_prepare(uap->clk); + if (retval) + goto out; + /* * Try to enable the clock producer. */ retval = clk_enable(uap->clk); if (retval) - goto out; + goto clk_unprep; uap->port.uartclk = clk_get_rate(uap->clk); @@ -1446,6 +1450,8 @@ static int pl011_startup(struct uart_port *port) clk_dis: clk_disable(uap->clk); + clk_unprep: + clk_unprepare(uap->clk); out: return retval; } @@ -1497,6 +1503,7 @@ static void pl011_shutdown(struct uart_port *port) * Shut down the clock producer */ clk_disable(uap->clk); + clk_unprepare(uap->clk); if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1800,6 +1807,7 @@ static int __init pl011_console_setup(struct console *co, char *options) int bits = 8; int parity = 'n'; int flow = 'n'; + int ret; /* * Check whether an invalid uart number has been specified, and @@ -1812,6 +1820,10 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + ret = clk_prepare(uap->clk); + if (ret) + return ret; + if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 9988c0c305c..4a0f86fa1e9 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -48,7 +48,7 @@ #ifdef CONFIG_ARM #include <mach/cpu.h> -#include <mach/gpio.h> +#include <asm/gpio.h> #endif #define PDC_BUFFER_SIZE 512 diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 54ffdc6243f..163fc9021f5 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1290,17 +1290,20 @@ static int serial_imx_resume(struct platform_device *dev) static int serial_imx_probe_dt(struct imx_port *sport, struct platform_device *pdev) { - static int portnum = 0; struct device_node *np = pdev->dev.of_node; const struct of_device_id *of_id = of_match_device(imx_uart_dt_ids, &pdev->dev); + int ret; if (!np) return -ENODEV; - sport->port.line = portnum++; - if (sport->port.line >= UART_NR) - return -EINVAL; + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); + return -ENODEV; + } + sport->port.line = ret; if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) sport->have_rtscts = 1; diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 648b6a3efa3..7c867a046c9 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -24,7 +24,7 @@ * * ***********************************************************************/ -#include <linux/moduleparam.h> +#include <linux/module.h> #include <linux/pci.h> #include <linux/slab.h> diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 87e7e6c876d..2b42a01a81c 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -19,6 +19,7 @@ #include <linux/console.h> #include <linux/vt_kern.h> #include <linux/input.h> +#include <linux/module.h> #define MAX_CONFIG_LEN 40 diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 2af5aa5f3a8..8a6cc8c30b5 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -43,6 +43,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/device.h> +#include <linux/module.h> #include <linux/serial_core.h> #include <linux/serial.h> #include <linux/spi/spi.h> diff --git a/drivers/tty/serial/max3107-aava.c b/drivers/tty/serial/max3107-aava.c index d73aadd7a9a..90c40f22ec7 100644 --- a/drivers/tty/serial/max3107-aava.c +++ b/drivers/tty/serial/max3107-aava.c @@ -36,6 +36,7 @@ #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/sfi.h> +#include <linux/module.h> #include <asm/mrst.h> #include "max3107.h" diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c index db00b595cab..7827000db4f 100644 --- a/drivers/tty/serial/max3107.c +++ b/drivers/tty/serial/max3107.c @@ -36,6 +36,7 @@ #include <linux/gpio.h> #include <linux/spi/spi.h> #include <linux/freezer.h> +#include <linux/module.h> #include "max3107.h" static const struct baud_table brg26_ext[] = { diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 29cbfd8c4e7..8131e2c2801 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -19,6 +19,7 @@ # define SUPPORT_SYSRQ #endif +#include <linux/atomic.h> #include <linux/hrtimer.h> #include <linux/module.h> #include <linux/io.h> @@ -33,6 +34,8 @@ #include <linux/clk.h> #include <linux/platform_device.h> #include <linux/delay.h> +#include <linux/of.h> +#include <linux/of_device.h> #include "msm_serial.h" @@ -589,9 +592,8 @@ static void msm_release_port(struct uart_port *port) iowrite32(GSBI_PROTOCOL_IDLE, msm_port->gsbi_base + GSBI_CONTROL); - gsbi_resource = platform_get_resource_byname(pdev, - IORESOURCE_MEM, - "gsbi_resource"); + gsbi_resource = platform_get_resource(pdev, + IORESOURCE_MEM, 1); if (unlikely(!gsbi_resource)) return; @@ -612,8 +614,7 @@ static int msm_request_port(struct uart_port *port) resource_size_t size; int ret; - uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "uart_resource"); + uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!uart_resource)) return -ENXIO; @@ -628,8 +629,7 @@ static int msm_request_port(struct uart_port *port) goto fail_release_port; } - gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "gsbi_resource"); + gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1); /* Is this a GSBI-based port? */ if (gsbi_resource) { size = resource_size(gsbi_resource); @@ -857,6 +857,8 @@ static struct uart_driver msm_uart_driver = { .cons = MSM_CONSOLE, }; +static atomic_t msm_uart_next_id = ATOMIC_INIT(0); + static int __init msm_serial_probe(struct platform_device *pdev) { struct msm_port *msm_port; @@ -864,6 +866,9 @@ static int __init msm_serial_probe(struct platform_device *pdev) struct uart_port *port; int irq; + if (pdev->id == -1) + pdev->id = atomic_inc_return(&msm_uart_next_id) - 1; + if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; @@ -873,7 +878,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) port->dev = &pdev->dev; msm_port = UART_TO_MSM(port); - if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource")) + if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) msm_port->is_uartdm = 1; else msm_port->is_uartdm = 0; @@ -897,8 +902,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) printk(KERN_INFO "uartclk = %d\n", port->uartclk); - resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "uart_resource"); + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) return -ENXIO; port->mapbase = resource->start; @@ -922,11 +926,17 @@ static int __devexit msm_serial_remove(struct platform_device *pdev) return 0; } +static struct of_device_id msm_match_table[] = { + { .compatible = "qcom,msm-uart" }, + {} +}; + static struct platform_driver msm_platform_driver = { .remove = msm_serial_remove, .driver = { .name = "msm_serial", .owner = THIS_MODULE, + .of_match_table = msm_match_table, }, }; diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index 9beaff1cec2..dd4c31d1aee 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c @@ -10,6 +10,7 @@ * */ #include <linux/init.h> +#include <linux/export.h> #include <linux/console.h> #include <linux/serial.h> #include <linux/serial_reg.h> diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index e58cece6f44..e8c9cee07d0 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -200,17 +200,7 @@ static struct platform_driver of_platform_serial_driver = { .remove = of_platform_serial_remove, }; -static int __init of_platform_serial_init(void) -{ - return platform_driver_register(&of_platform_serial_driver); -} -module_init(of_platform_serial_init); - -static void __exit of_platform_serial_exit(void) -{ - return platform_driver_unregister(&of_platform_serial_driver); -}; -module_exit(of_platform_serial_exit); +module_platform_driver(of_platform_serial_driver); MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 9871c57b348..aff9d612dff 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -207,6 +207,25 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { }, /* + * Common SH-2(A) SCIF definitions for ports with FIFO data + * count registers. + */ + [SCIx_SH2_SCIF_FIFODATA_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + }, + + /* * Common SH-3 SCIF definitions. */ [SCIx_SH3_SCIF_REGTYPE] = { @@ -1446,12 +1465,8 @@ static bool filter(struct dma_chan *chan, void *slave) dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, param->slave_id); - if (param->dma_dev == chan->device->dev) { - chan->private = param; - return true; - } else { - return false; - } + chan->private = param; + return true; } static void rx_timer_fn(unsigned long arg) @@ -1477,10 +1492,10 @@ static void sci_request_dma(struct uart_port *port) dma_cap_mask_t mask; int nent; - dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, - port->line, s->cfg->dma_dev); + dev_dbg(port->dev, "%s: port %d\n", __func__, + port->line); - if (!s->cfg->dma_dev) + if (s->cfg->dma_slave_tx <= 0 || s->cfg->dma_slave_rx <= 0) return; dma_cap_zero(mask); @@ -1490,7 +1505,6 @@ static void sci_request_dma(struct uart_port *port) /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ param->slave_id = s->cfg->dma_slave_tx; - param->dma_dev = s->cfg->dma_dev; s->cookie_tx = -EINVAL; chan = dma_request_channel(mask, filter, param); @@ -1519,7 +1533,6 @@ static void sci_request_dma(struct uart_port *port) /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ param->slave_id = s->cfg->dma_slave_rx; - param->dma_dev = s->cfg->dma_dev; chan = dma_request_channel(mask, filter, param); dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); @@ -1564,9 +1577,6 @@ static void sci_free_dma(struct uart_port *port) { struct sci_port *s = to_sci_port(port); - if (!s->cfg->dma_dev) - return; - if (s->chan_tx) sci_tx_dma_release(s, false); if (s->chan_rx) @@ -1981,9 +1991,9 @@ static int __devinit sci_init_single(struct platform_device *dev, port->serial_in = sci_serial_in; port->serial_out = sci_serial_out; - if (p->dma_dev) - dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", - p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); + if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) + dev_dbg(port->dev, "DMA tx %d, rx %d\n", + p->dma_slave_tx, p->dma_slave_rx); return 0; } diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index a4b63bfeaa2..e76c8b747fb 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -29,6 +29,7 @@ #include <linux/platform_device.h> #include <linux/ioport.h> #include <linux/slab.h> +#include <linux/module.h> #include "timbuart.h" diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index b908615ccaa..6cd414341d5 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -569,8 +569,6 @@ static struct of_device_id ulite_of_match[] __devinitdata = { {} }; MODULE_DEVICE_TABLE(of, ulite_of_match); -#else /* CONFIG_OF */ -#define ulite_of_match NULL #endif /* CONFIG_OF */ static int __devinit ulite_probe(struct platform_device *pdev) @@ -610,7 +608,7 @@ static struct platform_driver ulite_platform_driver = { .driver = { .owner = THIS_MODULE, .name = "uartlite", - .of_match_table = ulite_of_match, + .of_match_table = of_match_ptr(ulite_of_match), }, }; diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 8c03b127fd0..b627363352e 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -20,6 +20,7 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/module.h> #define XUARTPS_TTY_NAME "ttyPS" #define XUARTPS_NAME "xuartps" diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 66825c9f516..7a367ff5122 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/major.h> #include <linux/errno.h> +#include <linux/export.h> #include <linux/tty.h> #include <linux/interrupt.h> #include <linux/mm.h> |