diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 17:08:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 17:08:47 -0500 |
commit | c6bd5bcc4983f1a2d2f87a3769bf309482ee8c04 (patch) | |
tree | 2ff9c4496dc2258d601a1bcd82040470704dae3b /drivers | |
parent | 8966961b31c251b854169e9886394c2a20f2cea7 (diff) | |
parent | b0ab02361167faa82198b783a8d555eb6f58901c (diff) |
Merge tag 'tty-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY/Serial merge from Greg Kroah-Hartman:
"Here's the big tty/serial tree set of changes for 3.8-rc1.
Contained in here is a bunch more reworks of the tty port layer from
Jiri and bugfixes from Alan, along with a number of other tty and
serial driver updates by the various driver authors.
Also, Jiri has been coerced^Wconvinced to be the co-maintainer of the
TTY layer, which is much appreciated by me.
All of these have been in the linux-next tree for a while.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Fixed up some trivial conflicts in the staging tree, due to the fwserial
driver having come in both ways (but fixed up a bit in the serial tree),
and the ioctl handling in the dgrp driver having been done slightly
differently (staging tree got that one right, and removed both
TIOCGSOFTCAR and TIOCSSOFTCAR).
* tag 'tty-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (146 commits)
staging: sb105x: fix potential NULL pointer dereference in mp_chars_in_buffer()
staging/fwserial: Remove superfluous free
staging/fwserial: Use WARN_ONCE when port table is corrupted
staging/fwserial: Destruct embedded tty_port on teardown
staging/fwserial: Fix build breakage when !CONFIG_BUG
staging: fwserial: Add TTY-over-Firewire serial driver
drivers/tty/serial/serial_core.c: clean up HIGH_BITS_OFFSET usage
staging: dgrp: dgrp_tty.c: Audit the return values of get/put_user()
staging: dgrp: dgrp_tty.c: Remove the TIOCSSOFTCAR ioctl handler from dgrp driver
serial: ifx6x60: Add modem power off function in the platform reboot process
serial: mxs-auart: unmap the scatter list before we copy the data
serial: mxs-auart: disable the Receive Timeout Interrupt when DMA is enabled
serial: max310x: Setup missing "can_sleep" field for GPIO
tty/serial: fix ifx6x60.c declaration warning
serial: samsung: add devicetree properties for non-Exynos SoCs
serial: samsung: fix potential soft lockup during uart write
tty: vt: Remove redundant null check before kfree.
tty/8250 Add check for pci_ioremap_bar failure
tty/8250 Add support for Commtech's Fastcom Async-335 and Fastcom Async-PCIe cards
tty/8250 Add XR17D15x devices to the exar_handle_irq override
...
Diffstat (limited to 'drivers')
132 files changed, 7873 insertions, 1679 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index c8abce3d2d9c..ed0fade46aed 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -270,15 +270,10 @@ static int hci_uart_send_frame(struct sk_buff *skb) | |||
270 | */ | 270 | */ |
271 | static int hci_uart_tty_open(struct tty_struct *tty) | 271 | static int hci_uart_tty_open(struct tty_struct *tty) |
272 | { | 272 | { |
273 | struct hci_uart *hu = (void *) tty->disc_data; | 273 | struct hci_uart *hu; |
274 | 274 | ||
275 | BT_DBG("tty %p", tty); | 275 | BT_DBG("tty %p", tty); |
276 | 276 | ||
277 | /* FIXME: This btw is bogus, nothing requires the old ldisc to clear | ||
278 | the pointer */ | ||
279 | if (hu) | ||
280 | return -EEXIST; | ||
281 | |||
282 | /* Error if the tty has no write op instead of leaving an exploitable | 277 | /* Error if the tty has no write op instead of leaving an exploitable |
283 | hole */ | 278 | hole */ |
284 | if (tty->ops->write == NULL) | 279 | if (tty->ops->write == NULL) |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 21721d25e388..b66eaa04f8cb 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -549,8 +549,10 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
549 | /* Initialize the struct pcmcia_device structure */ | 549 | /* Initialize the struct pcmcia_device structure */ |
550 | 550 | ||
551 | ret = mgslpc_config(link); | 551 | ret = mgslpc_config(link); |
552 | if (ret) | 552 | if (ret) { |
553 | tty_port_destroy(&info->port); | ||
553 | return ret; | 554 | return ret; |
555 | } | ||
554 | 556 | ||
555 | mgslpc_add_device(info); | 557 | mgslpc_add_device(info); |
556 | 558 | ||
@@ -2757,6 +2759,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) | |||
2757 | hdlcdev_exit(info); | 2759 | hdlcdev_exit(info); |
2758 | #endif | 2760 | #endif |
2759 | release_resources(info); | 2761 | release_resources(info); |
2762 | tty_port_destroy(&info->port); | ||
2760 | kfree(info); | 2763 | kfree(info); |
2761 | mgslpc_device_count--; | 2764 | mgslpc_device_count--; |
2762 | return; | 2765 | return; |
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index af98f6d6509b..4945bd3d18d0 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c | |||
@@ -179,7 +179,6 @@ static int __init ttyprintk_init(void) | |||
179 | { | 179 | { |
180 | int ret = -ENOMEM; | 180 | int ret = -ENOMEM; |
181 | 181 | ||
182 | tty_port_init(&tpk_port.port); | ||
183 | tpk_port.port.ops = &null_ops; | 182 | tpk_port.port.ops = &null_ops; |
184 | mutex_init(&tpk_port.port_write_mutex); | 183 | mutex_init(&tpk_port.port_write_mutex); |
185 | 184 | ||
@@ -190,6 +189,8 @@ static int __init ttyprintk_init(void) | |||
190 | if (IS_ERR(ttyprintk_driver)) | 189 | if (IS_ERR(ttyprintk_driver)) |
191 | return PTR_ERR(ttyprintk_driver); | 190 | return PTR_ERR(ttyprintk_driver); |
192 | 191 | ||
192 | tty_port_init(&tpk_port.port); | ||
193 | |||
193 | ttyprintk_driver->driver_name = "ttyprintk"; | 194 | ttyprintk_driver->driver_name = "ttyprintk"; |
194 | ttyprintk_driver->name = "ttyprintk"; | 195 | ttyprintk_driver->name = "ttyprintk"; |
195 | ttyprintk_driver->major = TTYAUX_MAJOR; | 196 | ttyprintk_driver->major = TTYAUX_MAJOR; |
@@ -211,6 +212,7 @@ static int __init ttyprintk_init(void) | |||
211 | error: | 212 | error: |
212 | tty_unregister_driver(ttyprintk_driver); | 213 | tty_unregister_driver(ttyprintk_driver); |
213 | put_tty_driver(ttyprintk_driver); | 214 | put_tty_driver(ttyprintk_driver); |
215 | tty_port_destroy(&tpk_port.port); | ||
214 | ttyprintk_driver = NULL; | 216 | ttyprintk_driver = NULL; |
215 | return ret; | 217 | return ret; |
216 | } | 218 | } |
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index c06ab396e84f..576d53d92677 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c | |||
@@ -415,6 +415,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, | |||
415 | tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); | 415 | tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); |
416 | if (IS_ERR(tty_dev)) { | 416 | if (IS_ERR(tty_dev)) { |
417 | dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); | 417 | dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); |
418 | tty_port_destroy(&channel->tty_port); | ||
418 | continue; | 419 | continue; |
419 | } | 420 | } |
420 | dev_set_drvdata(tty_dev, channel); | 421 | dev_set_drvdata(tty_dev, channel); |
@@ -700,6 +701,7 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) | |||
700 | struct ipoctal_channel *channel = &ipoctal->channel[i]; | 701 | struct ipoctal_channel *channel = &ipoctal->channel[i]; |
701 | tty_unregister_device(ipoctal->tty_drv, i); | 702 | tty_unregister_device(ipoctal->tty_drv, i); |
702 | tty_port_free_xmit_buf(&channel->tty_port); | 703 | tty_port_free_xmit_buf(&channel->tty_port); |
704 | tty_port_destroy(&channel->tty_port); | ||
703 | } | 705 | } |
704 | 706 | ||
705 | tty_unregister_driver(ipoctal->tty_drv); | 707 | tty_unregister_driver(ipoctal->tty_drv); |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index c679867c2ccd..89562a845f6a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -77,8 +77,6 @@ struct ackqueue_entry { | |||
77 | }; | 77 | }; |
78 | 78 | ||
79 | struct capiminor { | 79 | struct capiminor { |
80 | struct kref kref; | ||
81 | |||
82 | unsigned int minor; | 80 | unsigned int minor; |
83 | 81 | ||
84 | struct capi20_appl *ap; | 82 | struct capi20_appl *ap; |
@@ -190,7 +188,20 @@ static void capiminor_del_all_ack(struct capiminor *mp) | |||
190 | 188 | ||
191 | /* -------- struct capiminor ---------------------------------------- */ | 189 | /* -------- struct capiminor ---------------------------------------- */ |
192 | 190 | ||
193 | static const struct tty_port_operations capiminor_port_ops; /* we have none */ | 191 | static void capiminor_destroy(struct tty_port *port) |
192 | { | ||
193 | struct capiminor *mp = container_of(port, struct capiminor, port); | ||
194 | |||
195 | kfree_skb(mp->outskb); | ||
196 | skb_queue_purge(&mp->inqueue); | ||
197 | skb_queue_purge(&mp->outqueue); | ||
198 | capiminor_del_all_ack(mp); | ||
199 | kfree(mp); | ||
200 | } | ||
201 | |||
202 | static const struct tty_port_operations capiminor_port_ops = { | ||
203 | .destruct = capiminor_destroy, | ||
204 | }; | ||
194 | 205 | ||
195 | static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | 206 | static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) |
196 | { | 207 | { |
@@ -204,8 +215,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | |||
204 | return NULL; | 215 | return NULL; |
205 | } | 216 | } |
206 | 217 | ||
207 | kref_init(&mp->kref); | ||
208 | |||
209 | mp->ap = ap; | 218 | mp->ap = ap; |
210 | mp->ncci = ncci; | 219 | mp->ncci = ncci; |
211 | INIT_LIST_HEAD(&mp->ackqueue); | 220 | INIT_LIST_HEAD(&mp->ackqueue); |
@@ -247,21 +256,10 @@ err_out2: | |||
247 | spin_unlock(&capiminors_lock); | 256 | spin_unlock(&capiminors_lock); |
248 | 257 | ||
249 | err_out1: | 258 | err_out1: |
250 | kfree(mp); | 259 | tty_port_put(&mp->port); |
251 | return NULL; | 260 | return NULL; |
252 | } | 261 | } |
253 | 262 | ||
254 | static void capiminor_destroy(struct kref *kref) | ||
255 | { | ||
256 | struct capiminor *mp = container_of(kref, struct capiminor, kref); | ||
257 | |||
258 | kfree_skb(mp->outskb); | ||
259 | skb_queue_purge(&mp->inqueue); | ||
260 | skb_queue_purge(&mp->outqueue); | ||
261 | capiminor_del_all_ack(mp); | ||
262 | kfree(mp); | ||
263 | } | ||
264 | |||
265 | static struct capiminor *capiminor_get(unsigned int minor) | 263 | static struct capiminor *capiminor_get(unsigned int minor) |
266 | { | 264 | { |
267 | struct capiminor *mp; | 265 | struct capiminor *mp; |
@@ -269,7 +267,7 @@ static struct capiminor *capiminor_get(unsigned int minor) | |||
269 | spin_lock(&capiminors_lock); | 267 | spin_lock(&capiminors_lock); |
270 | mp = capiminors[minor]; | 268 | mp = capiminors[minor]; |
271 | if (mp) | 269 | if (mp) |
272 | kref_get(&mp->kref); | 270 | tty_port_get(&mp->port); |
273 | spin_unlock(&capiminors_lock); | 271 | spin_unlock(&capiminors_lock); |
274 | 272 | ||
275 | return mp; | 273 | return mp; |
@@ -277,7 +275,7 @@ static struct capiminor *capiminor_get(unsigned int minor) | |||
277 | 275 | ||
278 | static inline void capiminor_put(struct capiminor *mp) | 276 | static inline void capiminor_put(struct capiminor *mp) |
279 | { | 277 | { |
280 | kref_put(&mp->kref, capiminor_destroy); | 278 | tty_port_put(&mp->port); |
281 | } | 279 | } |
282 | 280 | ||
283 | static void capiminor_free(struct capiminor *mp) | 281 | static void capiminor_free(struct capiminor *mp) |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 30a6b174fbb0..6849a11a1b24 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -507,6 +507,7 @@ void gigaset_freecs(struct cardstate *cs) | |||
507 | gig_dbg(DEBUG_INIT, "clearing at_state"); | 507 | gig_dbg(DEBUG_INIT, "clearing at_state"); |
508 | clear_at_state(&cs->at_state); | 508 | clear_at_state(&cs->at_state); |
509 | dealloc_temp_at_states(cs); | 509 | dealloc_temp_at_states(cs); |
510 | tty_port_destroy(&cs->port); | ||
510 | 511 | ||
511 | /* fall through */ | 512 | /* fall through */ |
512 | case 0: /* error in basic setup */ | 513 | case 0: /* error in basic setup */ |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index b817809f763c..e09dc8a5e743 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1849,6 +1849,8 @@ err_unregister: | |||
1849 | kfree(info->fax); | 1849 | kfree(info->fax); |
1850 | #endif | 1850 | #endif |
1851 | kfree(info->port.xmit_buf - 4); | 1851 | kfree(info->port.xmit_buf - 4); |
1852 | info->port.xmit_buf = NULL; | ||
1853 | tty_port_destroy(&info->port); | ||
1852 | } | 1854 | } |
1853 | tty_unregister_driver(m->tty_modem); | 1855 | tty_unregister_driver(m->tty_modem); |
1854 | err: | 1856 | err: |
@@ -1870,6 +1872,8 @@ isdn_tty_exit(void) | |||
1870 | kfree(info->fax); | 1872 | kfree(info->fax); |
1871 | #endif | 1873 | #endif |
1872 | kfree(info->port.xmit_buf - 4); | 1874 | kfree(info->port.xmit_buf - 4); |
1875 | info->port.xmit_buf = NULL; | ||
1876 | tty_port_destroy(&info->port); | ||
1873 | } | 1877 | } |
1874 | tty_unregister_driver(dev->mdm.tty_modem); | 1878 | tty_unregister_driver(dev->mdm.tty_modem); |
1875 | put_tty_driver(dev->mdm.tty_modem); | 1879 | put_tty_driver(dev->mdm.tty_modem); |
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 7003031c9181..f84ff0c06035 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c | |||
@@ -882,11 +882,14 @@ err: | |||
882 | static void pti_pci_remove(struct pci_dev *pdev) | 882 | static void pti_pci_remove(struct pci_dev *pdev) |
883 | { | 883 | { |
884 | struct pti_dev *drv_data = pci_get_drvdata(pdev); | 884 | struct pti_dev *drv_data = pci_get_drvdata(pdev); |
885 | unsigned int a; | ||
885 | 886 | ||
886 | unregister_console(&pti_console); | 887 | unregister_console(&pti_console); |
887 | 888 | ||
888 | tty_unregister_device(pti_tty_driver, 0); | 889 | for (a = 0; a < PTITTY_MINOR_NUM; a++) { |
889 | tty_unregister_device(pti_tty_driver, 1); | 890 | tty_unregister_device(pti_tty_driver, a); |
891 | tty_port_destroy(&drv_data->port[a]); | ||
892 | } | ||
890 | 893 | ||
891 | iounmap(drv_data->pti_ioaddr); | 894 | iounmap(drv_data->pti_ioaddr); |
892 | pci_set_drvdata(pdev, NULL); | 895 | pci_set_drvdata(pdev, NULL); |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index d2339ea37815..bd57a11acc79 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -66,8 +66,6 @@ struct uart_icount { | |||
66 | 66 | ||
67 | struct sdio_uart_port { | 67 | struct sdio_uart_port { |
68 | struct tty_port port; | 68 | struct tty_port port; |
69 | struct kref kref; | ||
70 | struct tty_struct *tty; | ||
71 | unsigned int index; | 69 | unsigned int index; |
72 | struct sdio_func *func; | 70 | struct sdio_func *func; |
73 | struct mutex func_lock; | 71 | struct mutex func_lock; |
@@ -93,7 +91,6 @@ static int sdio_uart_add_port(struct sdio_uart_port *port) | |||
93 | { | 91 | { |
94 | int index, ret = -EBUSY; | 92 | int index, ret = -EBUSY; |
95 | 93 | ||
96 | kref_init(&port->kref); | ||
97 | mutex_init(&port->func_lock); | 94 | mutex_init(&port->func_lock); |
98 | spin_lock_init(&port->write_lock); | 95 | spin_lock_init(&port->write_lock); |
99 | if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) | 96 | if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) |
@@ -123,23 +120,15 @@ static struct sdio_uart_port *sdio_uart_port_get(unsigned index) | |||
123 | spin_lock(&sdio_uart_table_lock); | 120 | spin_lock(&sdio_uart_table_lock); |
124 | port = sdio_uart_table[index]; | 121 | port = sdio_uart_table[index]; |
125 | if (port) | 122 | if (port) |
126 | kref_get(&port->kref); | 123 | tty_port_get(&port->port); |
127 | spin_unlock(&sdio_uart_table_lock); | 124 | spin_unlock(&sdio_uart_table_lock); |
128 | 125 | ||
129 | return port; | 126 | return port; |
130 | } | 127 | } |
131 | 128 | ||
132 | static void sdio_uart_port_destroy(struct kref *kref) | ||
133 | { | ||
134 | struct sdio_uart_port *port = | ||
135 | container_of(kref, struct sdio_uart_port, kref); | ||
136 | kfifo_free(&port->xmit_fifo); | ||
137 | kfree(port); | ||
138 | } | ||
139 | |||
140 | static void sdio_uart_port_put(struct sdio_uart_port *port) | 129 | static void sdio_uart_port_put(struct sdio_uart_port *port) |
141 | { | 130 | { |
142 | kref_put(&port->kref, sdio_uart_port_destroy); | 131 | tty_port_put(&port->port); |
143 | } | 132 | } |
144 | 133 | ||
145 | static void sdio_uart_port_remove(struct sdio_uart_port *port) | 134 | static void sdio_uart_port_remove(struct sdio_uart_port *port) |
@@ -737,6 +726,14 @@ static void sdio_uart_shutdown(struct tty_port *tport) | |||
737 | sdio_uart_release_func(port); | 726 | sdio_uart_release_func(port); |
738 | } | 727 | } |
739 | 728 | ||
729 | static void sdio_uart_port_destroy(struct tty_port *tport) | ||
730 | { | ||
731 | struct sdio_uart_port *port = | ||
732 | container_of(tport, struct sdio_uart_port, port); | ||
733 | kfifo_free(&port->xmit_fifo); | ||
734 | kfree(port); | ||
735 | } | ||
736 | |||
740 | /** | 737 | /** |
741 | * sdio_uart_install - install method | 738 | * sdio_uart_install - install method |
742 | * @driver: the driver in use (sdio_uart in our case) | 739 | * @driver: the driver in use (sdio_uart in our case) |
@@ -1045,6 +1042,7 @@ static const struct tty_port_operations sdio_uart_port_ops = { | |||
1045 | .carrier_raised = uart_carrier_raised, | 1042 | .carrier_raised = uart_carrier_raised, |
1046 | .shutdown = sdio_uart_shutdown, | 1043 | .shutdown = sdio_uart_shutdown, |
1047 | .activate = sdio_uart_activate, | 1044 | .activate = sdio_uart_activate, |
1045 | .destruct = sdio_uart_port_destroy, | ||
1048 | }; | 1046 | }; |
1049 | 1047 | ||
1050 | static const struct tty_operations sdio_uart_ops = { | 1048 | static const struct tty_operations sdio_uart_ops = { |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 605a4baa9b7b..cd8ccb240f4b 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2274,6 +2274,7 @@ static void hso_serial_common_free(struct hso_serial *serial) | |||
2274 | /* unlink and free TX URB */ | 2274 | /* unlink and free TX URB */ |
2275 | usb_free_urb(serial->tx_urb); | 2275 | usb_free_urb(serial->tx_urb); |
2276 | kfree(serial->tx_data); | 2276 | kfree(serial->tx_data); |
2277 | tty_port_destroy(&serial->port); | ||
2277 | } | 2278 | } |
2278 | 2279 | ||
2279 | static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | 2280 | static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, |
@@ -2283,12 +2284,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2283 | int minor; | 2284 | int minor; |
2284 | int i; | 2285 | int i; |
2285 | 2286 | ||
2287 | tty_port_init(&serial->port); | ||
2288 | |||
2286 | minor = get_free_serial_index(); | 2289 | minor = get_free_serial_index(); |
2287 | if (minor < 0) | 2290 | if (minor < 0) |
2288 | goto exit; | 2291 | goto exit; |
2289 | 2292 | ||
2290 | tty_port_init(&serial->port); | ||
2291 | |||
2292 | /* register our minor number */ | 2293 | /* register our minor number */ |
2293 | serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, | 2294 | serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, |
2294 | minor, &serial->parent->interface->dev); | 2295 | minor, &serial->parent->interface->dev); |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 4ed343e4eb41..40084501c31b 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -677,6 +677,7 @@ static void raw3215_free_info(struct raw3215_info *raw) | |||
677 | { | 677 | { |
678 | kfree(raw->inbuf); | 678 | kfree(raw->inbuf); |
679 | kfree(raw->buffer); | 679 | kfree(raw->buffer); |
680 | tty_port_destroy(&raw->port); | ||
680 | kfree(raw); | 681 | kfree(raw); |
681 | } | 682 | } |
682 | 683 | ||
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 30ec09e3d037..877fbc37c1e7 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -547,7 +547,6 @@ sclp_tty_init(void) | |||
547 | sclp_tty_tolower = 1; | 547 | sclp_tty_tolower = 1; |
548 | } | 548 | } |
549 | sclp_tty_chars_count = 0; | 549 | sclp_tty_chars_count = 0; |
550 | tty_port_init(&sclp_port); | ||
551 | 550 | ||
552 | rc = sclp_register(&sclp_input_event); | 551 | rc = sclp_register(&sclp_input_event); |
553 | if (rc) { | 552 | if (rc) { |
@@ -555,6 +554,8 @@ sclp_tty_init(void) | |||
555 | return rc; | 554 | return rc; |
556 | } | 555 | } |
557 | 556 | ||
557 | tty_port_init(&sclp_port); | ||
558 | |||
558 | driver->driver_name = "sclp_line"; | 559 | driver->driver_name = "sclp_line"; |
559 | driver->name = "sclp_line"; | 560 | driver->name = "sclp_line"; |
560 | driver->major = TTY_MAJOR; | 561 | driver->major = TTY_MAJOR; |
@@ -571,6 +572,7 @@ sclp_tty_init(void) | |||
571 | rc = tty_register_driver(driver); | 572 | rc = tty_register_driver(driver); |
572 | if (rc) { | 573 | if (rc) { |
573 | put_tty_driver(driver); | 574 | put_tty_driver(driver); |
575 | tty_port_destroy(&sclp_port); | ||
574 | return rc; | 576 | return rc; |
575 | } | 577 | } |
576 | sclp_tty_driver = driver; | 578 | sclp_tty_driver = driver; |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 7e60f3d2f3f9..effcc8756e0a 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -615,6 +615,7 @@ static void __init __sclp_vt220_cleanup(void) | |||
615 | return; | 615 | return; |
616 | sclp_unregister(&sclp_vt220_register); | 616 | sclp_unregister(&sclp_vt220_register); |
617 | __sclp_vt220_free_pages(); | 617 | __sclp_vt220_free_pages(); |
618 | tty_port_destroy(&sclp_vt220_port); | ||
618 | } | 619 | } |
619 | 620 | ||
620 | /* Allocate buffer pages and register with sclp core. Controlled by init | 621 | /* Allocate buffer pages and register with sclp core. Controlled by init |
@@ -650,6 +651,7 @@ out: | |||
650 | if (rc) { | 651 | if (rc) { |
651 | __sclp_vt220_free_pages(); | 652 | __sclp_vt220_free_pages(); |
652 | sclp_vt220_init_count--; | 653 | sclp_vt220_init_count--; |
654 | tty_port_destroy(&sclp_vt220_port); | ||
653 | } | 655 | } |
654 | return rc; | 656 | return rc; |
655 | } | 657 | } |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 482ee028f842..43ea0593bdb0 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -722,6 +722,7 @@ out_pages: | |||
722 | while (pages--) | 722 | while (pages--) |
723 | free_pages((unsigned long) tp->freemem_pages[pages], 0); | 723 | free_pages((unsigned long) tp->freemem_pages[pages], 0); |
724 | kfree(tp->freemem_pages); | 724 | kfree(tp->freemem_pages); |
725 | tty_port_destroy(&tp->port); | ||
725 | out_tp: | 726 | out_tp: |
726 | kfree(tp); | 727 | kfree(tp); |
727 | out_err: | 728 | out_err: |
@@ -744,6 +745,7 @@ tty3270_free_view(struct tty3270 *tp) | |||
744 | for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) | 745 | for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) |
745 | free_pages((unsigned long) tp->freemem_pages[pages], 0); | 746 | free_pages((unsigned long) tp->freemem_pages[pages], 0); |
746 | kfree(tp->freemem_pages); | 747 | kfree(tp->freemem_pages); |
748 | tty_port_destroy(&tp->port); | ||
747 | kfree(tp); | 749 | kfree(tp); |
748 | } | 750 | } |
749 | 751 | ||
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 943ca607200c..329bdb42109f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -138,6 +138,8 @@ source "drivers/staging/imx-drm/Kconfig" | |||
138 | 138 | ||
139 | source "drivers/staging/dgrp/Kconfig" | 139 | source "drivers/staging/dgrp/Kconfig" |
140 | 140 | ||
141 | source "drivers/staging/sb105x/Kconfig" | ||
142 | |||
141 | source "drivers/staging/fwserial/Kconfig" | 143 | source "drivers/staging/fwserial/Kconfig" |
142 | 144 | ||
143 | endif # STAGING | 145 | endif # STAGING |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 20c764d7ab33..c7ec486680f7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -61,4 +61,5 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ | |||
61 | obj-$(CONFIG_CED1401) += ced1401/ | 61 | obj-$(CONFIG_CED1401) += ced1401/ |
62 | obj-$(CONFIG_DRM_IMX) += imx-drm/ | 62 | obj-$(CONFIG_DRM_IMX) += imx-drm/ |
63 | obj-$(CONFIG_DGRP) += dgrp/ | 63 | obj-$(CONFIG_DGRP) += dgrp/ |
64 | obj-$(CONFIG_SB105X) += sb105x/ | ||
64 | obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ | 65 | obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ |
diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c index 5b3f5fffea92..373c40656b52 100644 --- a/drivers/staging/ccg/u_serial.c +++ b/drivers/staging/ccg/u_serial.c | |||
@@ -1140,8 +1140,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count) | |||
1140 | 1140 | ||
1141 | return status; | 1141 | return status; |
1142 | fail: | 1142 | fail: |
1143 | while (count--) | 1143 | while (count--) { |
1144 | tty_port_destroy(&ports[count].port->port); | ||
1144 | kfree(ports[count].port); | 1145 | kfree(ports[count].port); |
1146 | } | ||
1145 | put_tty_driver(gs_tty_driver); | 1147 | put_tty_driver(gs_tty_driver); |
1146 | gs_tty_driver = NULL; | 1148 | gs_tty_driver = NULL; |
1147 | return status; | 1149 | return status; |
@@ -1195,6 +1197,7 @@ void gserial_cleanup(void) | |||
1195 | 1197 | ||
1196 | WARN_ON(port->port_usb != NULL); | 1198 | WARN_ON(port->port_usb != NULL); |
1197 | 1199 | ||
1200 | tty_port_destroy(&port->port); | ||
1198 | kfree(port); | 1201 | kfree(port); |
1199 | } | 1202 | } |
1200 | n_ports = 0; | 1203 | n_ports = 0; |
diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h index 05ff338471ac..0583fe9c7b03 100644 --- a/drivers/staging/dgrp/dgrp_common.h +++ b/drivers/staging/dgrp/dgrp_common.h | |||
@@ -31,7 +31,6 @@ | |||
31 | * All global storage allocation. | 31 | * All global storage allocation. |
32 | ************************************************************************/ | 32 | ************************************************************************/ |
33 | 33 | ||
34 | extern int dgrp_rawreadok; /* Allow raw writing of input */ | ||
35 | extern int dgrp_register_cudevices; /* enable legacy cu devices */ | 34 | extern int dgrp_register_cudevices; /* enable legacy cu devices */ |
36 | extern int dgrp_register_prdevices; /* enable transparent print devices */ | 35 | extern int dgrp_register_prdevices; /* enable transparent print devices */ |
37 | extern int dgrp_poll_tick; /* Poll interval - in ms */ | 36 | extern int dgrp_poll_tick; /* Poll interval - in ms */ |
diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c index 6e4a0ebc0749..aa262588e9b9 100644 --- a/drivers/staging/dgrp/dgrp_driver.c +++ b/drivers/staging/dgrp/dgrp_driver.c | |||
@@ -39,14 +39,10 @@ MODULE_VERSION(DIGI_VERSION); | |||
39 | struct list_head nd_struct_list; | 39 | struct list_head nd_struct_list; |
40 | struct dgrp_poll_data dgrp_poll_data; | 40 | struct dgrp_poll_data dgrp_poll_data; |
41 | 41 | ||
42 | int dgrp_rawreadok = 1; /* Bypass flipbuf on input */ | ||
43 | int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */ | 42 | int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */ |
44 | int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */ | 43 | int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */ |
45 | int dgrp_poll_tick = 20; /* Poll interval - in ms */ | 44 | int dgrp_poll_tick = 20; /* Poll interval - in ms */ |
46 | 45 | ||
47 | module_param_named(rawreadok, dgrp_rawreadok, int, 0644); | ||
48 | MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input"); | ||
49 | |||
50 | module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644); | 46 | module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644); |
51 | MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices"); | 47 | MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices"); |
52 | 48 | ||
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index c409cd03e8c1..2d1bbfd5b67c 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c | |||
@@ -151,20 +151,15 @@ static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf, | |||
151 | * Copys the rbuf to the flipbuf and sends to line discipline. | 151 | * Copys the rbuf to the flipbuf and sends to line discipline. |
152 | * Sends input buffer data to the line discipline. | 152 | * Sends input buffer data to the line discipline. |
153 | * | 153 | * |
154 | * There are several modes to consider here: | ||
155 | * rawreadok, tty->real_raw, and IF_PARMRK | ||
156 | */ | 154 | */ |
157 | static void dgrp_input(struct ch_struct *ch) | 155 | static void dgrp_input(struct ch_struct *ch) |
158 | { | 156 | { |
159 | struct nd_struct *nd; | 157 | struct nd_struct *nd; |
160 | struct tty_struct *tty; | 158 | struct tty_struct *tty; |
161 | int remain; | ||
162 | int data_len; | 159 | int data_len; |
163 | int len; | 160 | int len; |
164 | int flip_len; | ||
165 | int tty_count; | 161 | int tty_count; |
166 | ulong lock_flags; | 162 | ulong lock_flags; |
167 | struct tty_ldisc *ld; | ||
168 | u8 *myflipbuf; | 163 | u8 *myflipbuf; |
169 | u8 *myflipflagbuf; | 164 | u8 *myflipflagbuf; |
170 | 165 | ||
@@ -212,37 +207,11 @@ static void dgrp_input(struct ch_struct *ch) | |||
212 | 207 | ||
213 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | 208 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); |
214 | 209 | ||
215 | /* Decide how much data we can send into the tty layer */ | ||
216 | if (dgrp_rawreadok && tty->real_raw) | ||
217 | flip_len = MYFLIPLEN; | ||
218 | else | ||
219 | flip_len = TTY_FLIPBUF_SIZE; | ||
220 | |||
221 | /* data_len should be the number of chars that we read in */ | 210 | /* data_len should be the number of chars that we read in */ |
222 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; | 211 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; |
223 | remain = data_len; | ||
224 | 212 | ||
225 | /* len is the amount of data we are going to transfer here */ | 213 | /* len is the amount of data we are going to transfer here */ |
226 | len = min(data_len, flip_len); | 214 | len = tty_buffer_request_room(tty, data_len); |
227 | |||
228 | /* take into consideration length of ldisc */ | ||
229 | len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt); | ||
230 | |||
231 | ld = tty_ldisc_ref(tty); | ||
232 | |||
233 | /* | ||
234 | * If we were unable to get a reference to the ld, | ||
235 | * don't flush our buffer, and act like the ld doesn't | ||
236 | * have any space to put the data right now. | ||
237 | */ | ||
238 | if (!ld) { | ||
239 | len = 0; | ||
240 | } else if (!ld->ops->receive_buf) { | ||
241 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
242 | ch->ch_rout = ch->ch_rin; | ||
243 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
244 | len = 0; | ||
245 | } | ||
246 | 215 | ||
247 | /* Check DPA flow control */ | 216 | /* Check DPA flow control */ |
248 | if ((nd->nd_dpa_debug) && | 217 | if ((nd->nd_dpa_debug) && |
@@ -254,42 +223,22 @@ static void dgrp_input(struct ch_struct *ch) | |||
254 | 223 | ||
255 | dgrp_read_data_block(ch, myflipbuf, len); | 224 | dgrp_read_data_block(ch, myflipbuf, len); |
256 | 225 | ||
257 | /* | 226 | if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) |
258 | * In high performance mode, we don't have to update | 227 | parity_scan(ch, myflipbuf, myflipflagbuf, &len); |
259 | * flag_buf or any of the counts or pointers into flip buf. | 228 | else |
260 | */ | 229 | memset(myflipflagbuf, TTY_NORMAL, len); |
261 | if (!dgrp_rawreadok || !tty->real_raw) { | ||
262 | if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) | ||
263 | parity_scan(ch, myflipbuf, myflipflagbuf, &len); | ||
264 | else | ||
265 | memset(myflipflagbuf, TTY_NORMAL, len); | ||
266 | } | ||
267 | 230 | ||
268 | if ((nd->nd_dpa_debug) && | 231 | if ((nd->nd_dpa_debug) && |
269 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) | 232 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) |
270 | dgrp_dpa_data(nd, 1, myflipbuf, len); | 233 | dgrp_dpa_data(nd, 1, myflipbuf, len); |
271 | 234 | ||
272 | /* | 235 | tty_insert_flip_string_flags(tty, myflipbuf, |
273 | * If we're doing raw reads, jam it right into the | 236 | myflipflagbuf, len); |
274 | * line disc bypassing the flip buffers. | 237 | tty_flip_buffer_push(tty); |
275 | */ | ||
276 | if (dgrp_rawreadok && tty->real_raw) | ||
277 | ld->ops->receive_buf(tty, myflipbuf, NULL, len); | ||
278 | else { | ||
279 | len = tty_buffer_request_room(tty, len); | ||
280 | tty_insert_flip_string_flags(tty, myflipbuf, | ||
281 | myflipflagbuf, len); | ||
282 | |||
283 | /* Tell the tty layer its okay to "eat" the data now */ | ||
284 | tty_flip_buffer_push(tty); | ||
285 | } | ||
286 | 238 | ||
287 | ch->ch_rxcount += len; | 239 | ch->ch_rxcount += len; |
288 | } | 240 | } |
289 | 241 | ||
290 | if (ld) | ||
291 | tty_ldisc_deref(ld); | ||
292 | |||
293 | /* | 242 | /* |
294 | * Wake up any sleepers (maybe dgrp close) that might be waiting | 243 | * Wake up any sleepers (maybe dgrp close) that might be waiting |
295 | * for a channel flag state change. | 244 | * for a channel flag state change. |
@@ -2549,7 +2498,7 @@ data: | |||
2549 | 2498 | ||
2550 | /* | 2499 | /* |
2551 | * Fabricate and insert a data packet header to | 2500 | * Fabricate and insert a data packet header to |
2552 | * preceed the remaining data when it comes in. | 2501 | * preced the remaining data when it comes in. |
2553 | */ | 2502 | */ |
2554 | 2503 | ||
2555 | if (remain < plen) { | 2504 | if (remain < plen) { |
@@ -2718,7 +2667,7 @@ data: | |||
2718 | } | 2667 | } |
2719 | 2668 | ||
2720 | /* | 2669 | /* |
2721 | * Handle delayed response arrival preceeding | 2670 | * Handle delayed response arrival preceding |
2722 | * the open response we are waiting for. | 2671 | * the open response we are waiting for. |
2723 | */ | 2672 | */ |
2724 | 2673 | ||
@@ -3556,7 +3505,7 @@ void dgrp_poll_handler(unsigned long arg) | |||
3556 | /* | 3505 | /* |
3557 | * Decrement statistics. These are only for use with | 3506 | * Decrement statistics. These are only for use with |
3558 | * KME, so don't worry that the operations are done | 3507 | * KME, so don't worry that the operations are done |
3559 | * unlocked, and so the results are occassionally wrong. | 3508 | * unlocked, and so the results are occasionally wrong. |
3560 | */ | 3509 | */ |
3561 | 3510 | ||
3562 | nd->nd_read_count -= (nd->nd_read_count + | 3511 | nd->nd_read_count -= (nd->nd_read_count + |
diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index 24327c3bad83..c214078a89e9 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c | |||
@@ -629,8 +629,6 @@ static int info_proc_show(struct seq_file *m, void *v) | |||
629 | { | 629 | { |
630 | seq_printf(m, "version: %s\n", DIGI_VERSION); | 630 | seq_printf(m, "version: %s\n", DIGI_VERSION); |
631 | seq_puts(m, "register_with_sysfs: 1\n"); | 631 | seq_puts(m, "register_with_sysfs: 1\n"); |
632 | seq_printf(m, "rawreadok: 0x%08x\t(%d)\n", | ||
633 | dgrp_rawreadok, dgrp_rawreadok); | ||
634 | seq_printf(m, "pollrate: 0x%08x\t(%d)\n", | 632 | seq_printf(m, "pollrate: 0x%08x\t(%d)\n", |
635 | dgrp_poll_tick, dgrp_poll_tick); | 633 | dgrp_poll_tick, dgrp_poll_tick); |
636 | 634 | ||
@@ -754,6 +752,8 @@ static int dgrp_add_id(long id) | |||
754 | 752 | ||
755 | return 0; | 753 | return 0; |
756 | 754 | ||
755 | /* FIXME this guy should free the tty driver stored in nd and destroy | ||
756 | * all channel ports */ | ||
757 | error_out: | 757 | error_out: |
758 | kfree(nd); | 758 | kfree(nd); |
759 | return ret; | 759 | return ret; |
diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c index 43ab9f4d9349..be179adfb7c7 100644 --- a/drivers/staging/dgrp/dgrp_sysfs.c +++ b/drivers/staging/dgrp/dgrp_sysfs.c | |||
@@ -54,23 +54,6 @@ static DEVICE_ATTR(register_with_sysfs, 0400, | |||
54 | dgrp_class_register_with_sysfs_show, NULL); | 54 | dgrp_class_register_with_sysfs_show, NULL); |
55 | 55 | ||
56 | 56 | ||
57 | static ssize_t dgrp_class_rawreadok_show(struct device *c, | ||
58 | struct device_attribute *attr, | ||
59 | char *buf) | ||
60 | { | ||
61 | return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok); | ||
62 | } | ||
63 | static ssize_t dgrp_class_rawreadok_store(struct device *c, | ||
64 | struct device_attribute *attr, | ||
65 | const char *buf, size_t count) | ||
66 | { | ||
67 | sscanf(buf, "0x%x\n", &dgrp_rawreadok); | ||
68 | return count; | ||
69 | } | ||
70 | static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show, | ||
71 | dgrp_class_rawreadok_store); | ||
72 | |||
73 | |||
74 | static ssize_t dgrp_class_pollrate_show(struct device *c, | 57 | static ssize_t dgrp_class_pollrate_show(struct device *c, |
75 | struct device_attribute *attr, | 58 | struct device_attribute *attr, |
76 | char *buf) | 59 | char *buf) |
@@ -90,7 +73,6 @@ static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show, | |||
90 | 73 | ||
91 | static struct attribute *dgrp_sysfs_global_settings_entries[] = { | 74 | static struct attribute *dgrp_sysfs_global_settings_entries[] = { |
92 | &dev_attr_pollrate.attr, | 75 | &dev_attr_pollrate.attr, |
93 | &dev_attr_rawreadok.attr, | ||
94 | &dev_attr_register_with_sysfs.attr, | 76 | &dev_attr_register_with_sysfs.attr, |
95 | NULL | 77 | NULL |
96 | }; | 78 | }; |
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index efa62ced7c8a..51d3ed3dca27 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c | |||
@@ -432,7 +432,7 @@ static void drp_param(struct ch_struct *ch) | |||
432 | /* | 432 | /* |
433 | * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE} | 433 | * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE} |
434 | * is defined for the terminal device file, and the value | 434 | * is defined for the terminal device file, and the value |
435 | * of one of the changable special control characters (see | 435 | * of one of the changeable special control characters (see |
436 | * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be | 436 | * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be |
437 | * disabled, that is, no input data shall be recognized as | 437 | * disabled, that is, no input data shall be recognized as |
438 | * the disabled special character." | 438 | * the disabled special character." |
@@ -2265,9 +2265,7 @@ static int get_modem_info(struct ch_struct *ch, unsigned int *value) | |||
2265 | | ((mlast & DM_RI) ? TIOCM_RNG : 0) | 2265 | | ((mlast & DM_RI) ? TIOCM_RNG : 0) |
2266 | | ((mlast & DM_DSR) ? TIOCM_DSR : 0) | 2266 | | ((mlast & DM_DSR) ? TIOCM_DSR : 0) |
2267 | | ((mlast & DM_CTS) ? TIOCM_CTS : 0); | 2267 | | ((mlast & DM_CTS) ? TIOCM_CTS : 0); |
2268 | put_user(mlast, (unsigned int __user *) value); | 2268 | return put_user(mlast, (unsigned int __user *) value); |
2269 | |||
2270 | return 0; | ||
2271 | } | 2269 | } |
2272 | 2270 | ||
2273 | /* | 2271 | /* |
@@ -2285,7 +2283,8 @@ static int set_modem_info(struct ch_struct *ch, unsigned int command, | |||
2285 | if (error == 0) | 2283 | if (error == 0) |
2286 | return -EFAULT; | 2284 | return -EFAULT; |
2287 | 2285 | ||
2288 | get_user(arg, (unsigned int __user *) value); | 2286 | if (get_user(arg, (unsigned int __user *) value)) |
2287 | return -EFAULT; | ||
2289 | mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0) | 2288 | mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0) |
2290 | | ((arg & TIOCM_DTR) ? DM_DTR : 0); | 2289 | | ((arg & TIOCM_DTR) ? DM_DTR : 0); |
2291 | 2290 | ||
@@ -2684,7 +2683,7 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
2684 | - looking at the tty_ioctl code, these command all call our | 2683 | - looking at the tty_ioctl code, these command all call our |
2685 | tty_set_termios at the driver's end, when a TCSETA* is sent, | 2684 | tty_set_termios at the driver's end, when a TCSETA* is sent, |
2686 | it is expecting the tty to have a termio structure, | 2685 | it is expecting the tty to have a termio structure, |
2687 | NOT a termios stucture. These two structures differ in size | 2686 | NOT a termios structure. These two structures differ in size |
2688 | and the tty_ioctl code does a conversion before processing them both. | 2687 | and the tty_ioctl code does a conversion before processing them both. |
2689 | - we should treat the TCSETAW TCSETAF ioctls the same, and let | 2688 | - we should treat the TCSETAW TCSETAF ioctls the same, and let |
2690 | the tty_ioctl code do the conversion stuff. | 2689 | the tty_ioctl code do the conversion stuff. |
@@ -2836,17 +2835,16 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
2836 | break; | 2835 | break; |
2837 | 2836 | ||
2838 | case DIGI_GETCUSTOMBAUD: | 2837 | case DIGI_GETCUSTOMBAUD: |
2839 | rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int)); | 2838 | if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg)) |
2840 | if (rc == 0) | ||
2841 | return -EFAULT; | 2839 | return -EFAULT; |
2842 | put_user(ch->ch_custom_speed, (unsigned int __user *) arg); | ||
2843 | break; | 2840 | break; |
2844 | 2841 | ||
2845 | case DIGI_SETCUSTOMBAUD: | 2842 | case DIGI_SETCUSTOMBAUD: |
2846 | { | 2843 | { |
2847 | int new_rate; | 2844 | int new_rate; |
2848 | 2845 | ||
2849 | get_user(new_rate, (unsigned int __user *) arg); | 2846 | if (get_user(new_rate, (unsigned int __user *) arg)) |
2847 | return -EFAULT; | ||
2850 | dgrp_set_custom_speed(ch, new_rate); | 2848 | dgrp_set_custom_speed(ch, new_rate); |
2851 | 2849 | ||
2852 | break; | 2850 | break; |
@@ -2981,7 +2979,7 @@ static void dgrp_tty_start(struct tty_struct *tty) | |||
2981 | } | 2979 | } |
2982 | 2980 | ||
2983 | /* | 2981 | /* |
2984 | * Stop the reciever | 2982 | * Stop the receiver |
2985 | */ | 2983 | */ |
2986 | static void dgrp_tty_input_stop(struct tty_struct *tty) | 2984 | static void dgrp_tty_input_stop(struct tty_struct *tty) |
2987 | { | 2985 | { |
@@ -3104,6 +3102,7 @@ static void dgrp_tty_hangup(struct tty_struct *tty) | |||
3104 | void | 3102 | void |
3105 | dgrp_tty_uninit(struct nd_struct *nd) | 3103 | dgrp_tty_uninit(struct nd_struct *nd) |
3106 | { | 3104 | { |
3105 | unsigned int i; | ||
3107 | char id[3]; | 3106 | char id[3]; |
3108 | 3107 | ||
3109 | ID_TO_CHAR(nd->nd_ID, id); | 3108 | ID_TO_CHAR(nd->nd_ID, id); |
@@ -3137,6 +3136,8 @@ dgrp_tty_uninit(struct nd_struct *nd) | |||
3137 | put_tty_driver(nd->nd_xprint_ttdriver); | 3136 | put_tty_driver(nd->nd_xprint_ttdriver); |
3138 | nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG; | 3137 | nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG; |
3139 | } | 3138 | } |
3139 | for (i = 0; i < CHAN_MAX; i++) | ||
3140 | tty_port_destroy(&nd->nd_chan[i].port); | ||
3140 | } | 3141 | } |
3141 | 3142 | ||
3142 | 3143 | ||
@@ -3320,7 +3321,6 @@ dgrp_tty_init(struct nd_struct *nd) | |||
3320 | init_waitqueue_head(&(ch->ch_pun.un_open_wait)); | 3321 | init_waitqueue_head(&(ch->ch_pun.un_open_wait)); |
3321 | init_waitqueue_head(&(ch->ch_pun.un_close_wait)); | 3322 | init_waitqueue_head(&(ch->ch_pun.un_close_wait)); |
3322 | tty_port_init(&ch->port); | 3323 | tty_port_init(&ch->port); |
3323 | tty_port_init(&ch->port); | ||
3324 | } | 3324 | } |
3325 | return 0; | 3325 | return 0; |
3326 | } | 3326 | } |
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 5d4d64a3ea81..61ee29083b26 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c | |||
@@ -939,14 +939,9 @@ static void fwserial_destroy(struct kref *kref) | |||
939 | 939 | ||
940 | mutex_lock(&port_table_lock); | 940 | mutex_lock(&port_table_lock); |
941 | for (j = 0; j < num_ports; ++i, ++j) { | 941 | for (j = 0; j < num_ports; ++i, ++j) { |
942 | static bool once; | 942 | port_table_corrupt |= port_table[i] != ports[j]; |
943 | int corrupt = port_table[i] != ports[j]; | 943 | WARN_ONCE(port_table_corrupt, "port_table[%d]: %p != ports[%d]: %p", |
944 | if (corrupt && !once) { | 944 | i, port_table[i], j, ports[j]); |
945 | WARN(corrupt, "port_table[%d]: %p != ports[%d]: %p", | ||
946 | i, port_table[i], j, ports[j]); | ||
947 | once = true; | ||
948 | port_table_corrupt = true; | ||
949 | } | ||
950 | 945 | ||
951 | port_table[i] = NULL; | 946 | port_table[i] = NULL; |
952 | } | 947 | } |
@@ -954,7 +949,7 @@ static void fwserial_destroy(struct kref *kref) | |||
954 | 949 | ||
955 | for (j = 0; j < num_ports; ++j) { | 950 | for (j = 0; j < num_ports; ++j) { |
956 | fw_core_remove_address_handler(&ports[j]->rx_handler); | 951 | fw_core_remove_address_handler(&ports[j]->rx_handler); |
957 | dma_fifo_free(&ports[j]->tx_fifo); | 952 | tty_port_destroy(&ports[j]->port); |
958 | kfree(ports[j]); | 953 | kfree(ports[j]); |
959 | } | 954 | } |
960 | kfree(serial); | 955 | kfree(serial); |
@@ -2369,8 +2364,10 @@ unregister_ttys: | |||
2369 | return err; | 2364 | return err; |
2370 | 2365 | ||
2371 | free_ports: | 2366 | free_ports: |
2372 | for (--i; i >= 0; --i) | 2367 | for (--i; i >= 0; --i) { |
2368 | tty_port_destroy(&serial->ports[i]->port); | ||
2373 | kfree(serial->ports[i]); | 2369 | kfree(serial->ports[i]); |
2370 | } | ||
2374 | kfree(serial); | 2371 | kfree(serial); |
2375 | return err; | 2372 | return err; |
2376 | } | 2373 | } |
diff --git a/drivers/staging/sb105x/Kconfig b/drivers/staging/sb105x/Kconfig new file mode 100644 index 000000000000..ac87c5e38dee --- /dev/null +++ b/drivers/staging/sb105x/Kconfig | |||
@@ -0,0 +1,9 @@ | |||
1 | config SB105X | ||
2 | tristate "SystemBase PCI Multiport UART" | ||
3 | select SERIAL_CORE | ||
4 | depends on PCI | ||
5 | help | ||
6 | A driver for the SystemBase Multi-2/PCI serial card | ||
7 | |||
8 | To compile this driver a module, choose M here: the module | ||
9 | will be called "sb105x". | ||
diff --git a/drivers/staging/sb105x/Makefile b/drivers/staging/sb105x/Makefile new file mode 100644 index 000000000000..b1bf3779acae --- /dev/null +++ b/drivers/staging/sb105x/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_SB105X) += sb105x.o | ||
2 | |||
3 | sb105x-y := sb_pci_mp.o | ||
diff --git a/drivers/staging/sb105x/sb_mp_register.h b/drivers/staging/sb105x/sb_mp_register.h new file mode 100644 index 000000000000..5480ae11368f --- /dev/null +++ b/drivers/staging/sb105x/sb_mp_register.h | |||
@@ -0,0 +1,295 @@ | |||
1 | |||
2 | /* | ||
3 | * SB105X_UART.h | ||
4 | * | ||
5 | * Copyright (C) 2008 systembase | ||
6 | * | ||
7 | * UART registers. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #ifndef UART_SB105X_H | ||
16 | #define UART_SB105X_H | ||
17 | |||
18 | /* | ||
19 | * option register | ||
20 | */ | ||
21 | |||
22 | /* Device Infomation Register */ | ||
23 | #define MP_OPTR_DIR0 0x04 /* port0 ~ port8 */ | ||
24 | #define MP_OPTR_DIR1 0x05 /* port8 ~ port15 */ | ||
25 | #define MP_OPTR_DIR2 0x06 /* port16 ~ port23 */ | ||
26 | #define MP_OPTR_DIR3 0x07 /* port24 ~ port31 */ | ||
27 | |||
28 | #define DIR_UART_16C550 0 | ||
29 | #define DIR_UART_16C1050 1 | ||
30 | #define DIR_UART_16C1050A 2 | ||
31 | |||
32 | #define DIR_CLK_1843200 0x0 /* input clock 1843200 Hz */ | ||
33 | #define DIR_CLK_3686400 0x1 /* input clock 3686400 Hz */ | ||
34 | #define DIR_CLK_7372800 0x2 /* input clock 7372800 Hz */ | ||
35 | #define DIR_CLK_14745600 0x3 /* input clock 14745600 Hz */ | ||
36 | #define DIR_CLK_29491200 0x4 /* input clock 29491200 Hz */ | ||
37 | #define DIR_CLK_58985400 0x5 /* input clock 58985400 Hz */ | ||
38 | |||
39 | /* Interface Information Register */ | ||
40 | #define MP_OPTR_IIR0 0x08 /* port0 ~ port8 */ | ||
41 | #define MP_OPTR_IIR1 0x09 /* port8 ~ port15 */ | ||
42 | #define MP_OPTR_IIR2 0x0A /* port16 ~ port23 */ | ||
43 | #define MP_OPTR_IIR3 0x0B /* port24 ~ port31 */ | ||
44 | |||
45 | #define IIR_RS232 0x00 /* RS232 type */ | ||
46 | #define IIR_RS422 0x10 /* RS422 type */ | ||
47 | #define IIR_RS485 0x20 /* RS485 type */ | ||
48 | #define IIR_UNKNOWN 0x30 /* unknown type */ | ||
49 | |||
50 | /* Interrrupt Mask Register */ | ||
51 | #define MP_OPTR_IMR0 0x0C /* port0 ~ port8 */ | ||
52 | #define MP_OPTR_IMR1 0x0D /* port8 ~ port15 */ | ||
53 | #define MP_OPTR_IMR2 0x0E /* port16 ~ port23 */ | ||
54 | #define MP_OPTR_IMR3 0x0F /* port24 ~ port31 */ | ||
55 | |||
56 | /* Interrupt Poll Register */ | ||
57 | #define MP_OPTR_IPR0 0x10 /* port0 ~ port8 */ | ||
58 | #define MP_OPTR_IPR1 0x11 /* port8 ~ port15 */ | ||
59 | #define MP_OPTR_IPR2 0x12 /* port16 ~ port23 */ | ||
60 | #define MP_OPTR_IPR3 0x13 /* port24 ~ port31 */ | ||
61 | |||
62 | /* General Purpose Output Control Register */ | ||
63 | #define MP_OPTR_GPOCR 0x20 | ||
64 | |||
65 | /* General Purpose Output Data Register */ | ||
66 | #define MP_OPTR_GPODR 0x21 | ||
67 | |||
68 | /* Parallel Additional Function Register */ | ||
69 | #define MP_OPTR_PAFR 0x23 | ||
70 | |||
71 | /* | ||
72 | * systembase 16c105x UART register | ||
73 | */ | ||
74 | |||
75 | #define PAGE_0 0 | ||
76 | #define PAGE_1 1 | ||
77 | #define PAGE_2 2 | ||
78 | #define PAGE_3 3 | ||
79 | #define PAGE_4 4 | ||
80 | |||
81 | /* | ||
82 | * ****************************************************************** | ||
83 | * * DLAB=0 =============== Page 0 Registers * | ||
84 | * ****************************************************************** | ||
85 | */ | ||
86 | |||
87 | #define SB105X_RX 0 /* In: Receive buffer */ | ||
88 | #define SB105X_TX 0 /* Out: Transmit buffer */ | ||
89 | |||
90 | #define SB105X_IER 1 /* Out: Interrupt Enable Register */ | ||
91 | |||
92 | #define SB105X_IER_CTSI 0x80 /* CTS# Interrupt Enable (Requires EFR[4] = 1) */ | ||
93 | #define SB105X_IER_RTSI 0x40 /* RTS# Interrupt Enable (Requires EFR[4] = 1) */ | ||
94 | #define SB105X_IER_XOI 0x20 /* Xoff Interrupt Enable (Requires EFR[4] = 1) */ | ||
95 | #define SB105X_IER_SME 0x10 /* Sleep Mode Enable (Requires EFR[4] = 1) */ | ||
96 | #define SB105X_IER_MSI 0x08 /* Enable Modem status interrupt */ | ||
97 | #define SB105X_IER_RLSI 0x04 /* Enable receiver line status interrupt */ | ||
98 | #define SB105X_IER_THRI 0x02 /* Enable Transmitter holding register int. */ | ||
99 | #define SB105X_IER_RDI 0x01 /* Enable receiver data interrupt */ | ||
100 | |||
101 | #define SB105X_ISR 2 /* In: Interrupt ID Register */ | ||
102 | |||
103 | #define SB105X_ISR_NOINT 0x01 /* No interrupts pending */ | ||
104 | #define SB105X_ISR_RLSI 0x06 /* Receiver line status interrupt (Priority = 1)*/ | ||
105 | #define SB105X_ISR_RDAI 0x0c /* Receive Data Available interrupt */ | ||
106 | #define SB105X_ISR_CTII 0x04 /* Character Timeout Indication interrupt */ | ||
107 | #define SB105X_ISR_THRI 0x02 /* Transmitter holding register empty */ | ||
108 | #define SB105X_ISR_MSI 0x00 /* Modem status interrupt */ | ||
109 | #define SB105X_ISR_RXCI 0x10 /* Receive Xoff or Special Character interrupt */ | ||
110 | #define SB105X_ISR_RCSI 0x20 /* RTS#, CTS# status interrupt during Auto RTS/CTS flow control */ | ||
111 | |||
112 | #define SB105X_FCR 2 /* Out: FIFO Control Register */ | ||
113 | |||
114 | #define SB105X_FCR_FEN 0x01 /* FIFO Enable */ | ||
115 | #define SB105X_FCR_RXFR 0x02 /* RX FIFO Reset */ | ||
116 | #define SB105X_FCR_TXFR 0x04 /* TX FIFO Reset */ | ||
117 | #define SB105X_FCR_DMS 0x08 /* DMA Mode Select */ | ||
118 | |||
119 | #define SB105X_FCR_RTR08 0x00 /* Receice Trigger Level set at 8 */ | ||
120 | #define SB105X_FCR_RTR16 0x40 /* Receice Trigger Level set at 16 */ | ||
121 | #define SB105X_FCR_RTR56 0x80 /* Receice Trigger Level set at 56 */ | ||
122 | #define SB105X_FCR_RTR60 0xc0 /* Receice Trigger Level set at 60 */ | ||
123 | #define SB105X_FCR_TTR08 0x00 /* Transmit Trigger Level set at 8 */ | ||
124 | #define SB105X_FCR_TTR16 0x10 /* Transmit Trigger Level set at 16 */ | ||
125 | #define SB105X_FCR_TTR32 0x20 /* Transmit Trigger Level set at 32 */ | ||
126 | #define SB105X_FCR_TTR56 0x30 /* Transmit Trigger Level set at 56 */ | ||
127 | |||
128 | #define SB105X_LCR 3 /* Out: Line Control Register */ | ||
129 | /* | ||
130 | * * Note: if the word length is 5 bits (SB105X_LCR_WLEN5), then setting | ||
131 | * * SB105X_LCR_STOP will select 1.5 stop bits, not 2 stop bits. | ||
132 | */ | ||
133 | #define SB105X_LCR_DLAB 0x80 /* Divisor Latch Enable */ | ||
134 | #define SB105X_LCR_SBC 0x40 /* Break Enable*/ | ||
135 | #define SB105X_LCR_SPAR 0x20 /* Set Stick parity */ | ||
136 | #define SB105X_LCR_EPAR 0x10 /* Even parity select */ | ||
137 | #define SB105X_LCR_PAREN 0x08 /* Parity Enable */ | ||
138 | #define SB105X_LCR_STOP 0x04 /* Stop bits: 0->1 bit, 1->2 bits, 1 and SB105X_LCR_WLEN5 -> 1.5 bit */ | ||
139 | #define SB105X_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ | ||
140 | #define SB105X_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ | ||
141 | #define SB105X_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ | ||
142 | #define SB105X_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ | ||
143 | |||
144 | #define SB105X_LCR_BF 0xBF | ||
145 | |||
146 | #define SB105X_MCR 4 /* Out: Modem Control Register */ | ||
147 | #define SB105X_MCR_CPS 0x80 /* Clock Prescaler Select */ | ||
148 | #define SB105X_MCR_P2S 0x40 /* Page 2 Select /Xoff Re-Transmit Access Enable */ | ||
149 | #define SB105X_MCR_XOA 0x20 /* Xon Any Enable */ | ||
150 | #define SB105X_MCR_ILB 0x10 /* Internal Loopback Enable */ | ||
151 | #define SB105X_MCR_OUT2 0x08 /* Out2/Interrupt Output Enable*/ | ||
152 | #define SB105X_MCR_OUT1 0x04 /* Out1/Interrupt Output Enable */ | ||
153 | #define SB105X_MCR_RTS 0x02 /* RTS# Output */ | ||
154 | #define SB105X_MCR_DTR 0x01 /* DTR# Output */ | ||
155 | |||
156 | #define SB105X_LSR 5 /* In: Line Status Register */ | ||
157 | #define SB105X_LSR_RFEI 0x80 /* Receive FIFO data error Indicator */ | ||
158 | #define SB105X_LSR_TEMI 0x40 /* THR and TSR Empty Indicator */ | ||
159 | #define SB105X_LSR_THRE 0x20 /* THR Empty Indicator */ | ||
160 | #define SB105X_LSR_BII 0x10 /* Break interrupt indicator */ | ||
161 | #define SB105X_LSR_FEI 0x08 /* Frame error indicator */ | ||
162 | #define SB105X_LSR_PEI 0x04 /* Parity error indicator */ | ||
163 | #define SB105X_LSR_OEI 0x02 /* Overrun error indicator */ | ||
164 | #define SB105X_LSR_RDRI 0x01 /* Receive data ready Indicator*/ | ||
165 | |||
166 | #define SB105X_MSR 6 /* In: Modem Status Register */ | ||
167 | #define SB105X_MSR_DCD 0x80 /* Data Carrier Detect */ | ||
168 | #define SB105X_MSR_RI 0x40 /* Ring Indicator */ | ||
169 | #define SB105X_MSR_DSR 0x20 /* Data Set Ready */ | ||
170 | #define SB105X_MSR_CTS 0x10 /* Clear to Send */ | ||
171 | #define SB105X_MSR_DDCD 0x08 /* Delta DCD */ | ||
172 | #define SB105X_MSR_DRI 0x04 /* Delta ring indicator */ | ||
173 | #define SB105X_MSR_DDSR 0x02 /* Delta DSR */ | ||
174 | #define SB105X_MSR_DCTS 0x01 /* Delta CTS */ | ||
175 | |||
176 | #define SB105XA_MDR 6 /* Out: Multi Drop mode Register */ | ||
177 | #define SB105XA_MDR_NPS 0x08 /* 9th Bit Polarity Select */ | ||
178 | #define SB105XA_MDR_AME 0x02 /* Auto Multi-drop Enable */ | ||
179 | #define SB105XA_MDR_MDE 0x01 /* Multi Drop Enable */ | ||
180 | |||
181 | #define SB105X_SPR 7 /* I/O: Scratch Register */ | ||
182 | |||
183 | /* | ||
184 | * DLAB=1 | ||
185 | */ | ||
186 | #define SB105X_DLL 0 /* Out: Divisor Latch Low */ | ||
187 | #define SB105X_DLM 1 /* Out: Divisor Latch High */ | ||
188 | |||
189 | /* | ||
190 | * ****************************************************************** | ||
191 | * * DLAB(LCR[7]) = 0 , MCR[6] = 1 ============= Page 2 Registers * | ||
192 | * ****************************************************************** | ||
193 | */ | ||
194 | #define SB105X_GICR 1 /* Global Interrupt Control Register */ | ||
195 | #define SB105X_GICR_GIM 0x01 /* Global Interrupt Mask */ | ||
196 | |||
197 | #define SB105X_GISR 2 /* Global Interrupt Status Register */ | ||
198 | #define SB105X_GISR_MGICR0 0x80 /* Mirror the content of GICR[0] */ | ||
199 | #define SB105X_GISR_CS3IS 0x08 /* SB105X of CS3# Interrupt Status */ | ||
200 | #define SB105X_GISR_CS2IS 0x04 /* SB105X of CS2# Interrupt Status */ | ||
201 | #define SB105X_GISR_CS1IS 0x02 /* SB105X of CS1# Interrupt Status */ | ||
202 | #define SB105X_GISR_CS0IS 0x01 /* SB105X of CS0# Interrupt Status */ | ||
203 | |||
204 | #define SB105X_TFCR 5 /* Transmit FIFO Count Register */ | ||
205 | |||
206 | #define SB105X_RFCR 6 /* Receive FIFO Count Register */ | ||
207 | |||
208 | #define SB105X_FSR 7 /* Flow Control Status Register */ | ||
209 | #define SB105X_FSR_THFS 0x20 /* Transmit Hardware Flow Control Status */ | ||
210 | #define SB105X_FSR_TSFS 0x10 /* Transmit Software Flow Control Status */ | ||
211 | #define SB105X_FSR_RHFS 0x02 /* Receive Hardware Flow Control Status */ | ||
212 | #define SB105X_FSR_RSFS 0x01 /* Receive Software Flow Control Status */ | ||
213 | |||
214 | /* | ||
215 | * ****************************************************************** | ||
216 | * * LCR = 0xBF, PSR[0] = 0 ============= Page 3 Registers * | ||
217 | * ****************************************************************** | ||
218 | */ | ||
219 | |||
220 | #define SB105X_PSR 0 /* Page Select Register */ | ||
221 | #define SB105X_PSR_P3KEY 0xA4 /* Page 3 Select Key */ | ||
222 | #define SB105X_PSR_P4KEY 0xA5 /* Page 5 Select Key */ | ||
223 | |||
224 | #define SB105X_ATR 1 /* Auto Toggle Control Register */ | ||
225 | #define SB105X_ATR_RPS 0x80 /* RXEN Polarity Select */ | ||
226 | #define SB105X_ATR_RCMS 0x40 /* RXEN Control Mode Select */ | ||
227 | #define SB105X_ATR_TPS 0x20 /* TXEN Polarity Select */ | ||
228 | #define SB105X_ATR_TCMS 0x10 /* TXEN Control Mode Select */ | ||
229 | #define SB105X_ATR_ATDIS 0x00 /* Auto Toggle is disabled */ | ||
230 | #define SB105X_ATR_ART 0x01 /* RTS#/TXEN pin operates as TXEN */ | ||
231 | #define SB105X_ATR_ADT 0x02 /* DTR#/TXEN pin operates as TXEN */ | ||
232 | #define SB105X_ATR_A80 0x03 /* only in 80 pin use */ | ||
233 | |||
234 | #define SB105X_EFR 2 /* (Auto) Enhanced Feature Register */ | ||
235 | #define SB105X_EFR_ACTS 0x80 /* Auto-CTS Flow Control Enable */ | ||
236 | #define SB105X_EFR_ARTS 0x40 /* Auto-RTS Flow Control Enable */ | ||
237 | #define SB105X_EFR_SCD 0x20 /* Special Character Detect */ | ||
238 | #define SB105X_EFR_EFBEN 0x10 /* Enhanced Function Bits Enable */ | ||
239 | |||
240 | #define SB105X_XON1 4 /* Xon1 Character Register */ | ||
241 | #define SB105X_XON2 5 /* Xon2 Character Register */ | ||
242 | #define SB105X_XOFF1 6 /* Xoff1 Character Register */ | ||
243 | #define SB105X_XOFF2 7 /* Xoff2 Character Register */ | ||
244 | |||
245 | /* | ||
246 | * ****************************************************************** | ||
247 | * * LCR = 0xBF, PSR[0] = 1 ============ Page 4 Registers * | ||
248 | * ****************************************************************** | ||
249 | */ | ||
250 | |||
251 | #define SB105X_AFR 1 /* Additional Feature Register */ | ||
252 | #define SB105X_AFR_GIPS 0x20 /* Global Interrupt Polarity Select */ | ||
253 | #define SB105X_AFR_GIEN 0x10 /* Global Interrupt Enable */ | ||
254 | #define SB105X_AFR_AFEN 0x01 /* 256-byte FIFO Enable */ | ||
255 | |||
256 | #define SB105X_XRCR 2 /* Xoff Re-transmit Count Register */ | ||
257 | #define SB105X_XRCR_NRC1 0x00 /* Transmits Xoff Character whenever the number of received data is 1 during XOFF status */ | ||
258 | #define SB105X_XRCR_NRC4 0x01 /* Transmits Xoff Character whenever the number of received data is 4 during XOFF status */ | ||
259 | #define SB105X_XRCR_NRC8 0x02 /* Transmits Xoff Character whenever the number of received data is 8 during XOFF status */ | ||
260 | #define SB105X_XRCR_NRC16 0x03 /* Transmits Xoff Character whenever the number of received data is 16 during XOFF status */ | ||
261 | |||
262 | #define SB105X_TTR 4 /* Transmit FIFO Trigger Level Register */ | ||
263 | #define SB105X_RTR 5 /* Receive FIFO Trigger Level Register */ | ||
264 | #define SB105X_FUR 6 /* Flow Control Upper Threshold Register */ | ||
265 | #define SB105X_FLR 7 /* Flow Control Lower Threshold Register */ | ||
266 | |||
267 | |||
268 | /* page 0 */ | ||
269 | |||
270 | #define SB105X_GET_CHAR(port) inb((port)->iobase + SB105X_RX) | ||
271 | #define SB105X_GET_IER(port) inb((port)->iobase + SB105X_IER) | ||
272 | #define SB105X_GET_ISR(port) inb((port)->iobase + SB105X_ISR) | ||
273 | #define SB105X_GET_LCR(port) inb((port)->iobase + SB105X_LCR) | ||
274 | #define SB105X_GET_MCR(port) inb((port)->iobase + SB105X_MCR) | ||
275 | #define SB105X_GET_LSR(port) inb((port)->iobase + SB105X_LSR) | ||
276 | #define SB105X_GET_MSR(port) inb((port)->iobase + SB105X_MSR) | ||
277 | #define SB105X_GET_SPR(port) inb((port)->iobase + SB105X_SPR) | ||
278 | |||
279 | #define SB105X_PUT_CHAR(port,v) outb((v),(port)->iobase + SB105X_TX ) | ||
280 | #define SB105X_PUT_IER(port,v) outb((v),(port)->iobase + SB105X_IER ) | ||
281 | #define SB105X_PUT_FCR(port,v) outb((v),(port)->iobase + SB105X_FCR ) | ||
282 | #define SB105X_PUT_LCR(port,v) outb((v),(port)->iobase + SB105X_LCR ) | ||
283 | #define SB105X_PUT_MCR(port,v) outb((v),(port)->iobase + SB105X_MCR ) | ||
284 | #define SB105X_PUT_SPR(port,v) outb((v),(port)->iobase + SB105X_SPR ) | ||
285 | |||
286 | |||
287 | /* page 1 */ | ||
288 | #define SB105X_GET_REG(port,reg) inb((port)->iobase + (reg)) | ||
289 | #define SB105X_PUT_REG(port,reg,v) outb((v),(port)->iobase + (reg)) | ||
290 | |||
291 | /* page 2 */ | ||
292 | |||
293 | #define SB105X_PUT_PSR(port,v) outb((v),(port)->iobase + SB105X_PSR ) | ||
294 | |||
295 | #endif | ||
diff --git a/drivers/staging/sb105x/sb_pci_mp.c b/drivers/staging/sb105x/sb_pci_mp.c new file mode 100644 index 000000000000..edb2a85b9d52 --- /dev/null +++ b/drivers/staging/sb105x/sb_pci_mp.c | |||
@@ -0,0 +1,3196 @@ | |||
1 | #include "sb_pci_mp.h" | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/parport.h> | ||
4 | |||
5 | extern struct parport *parport_pc_probe_port(unsigned long base_lo, | ||
6 | unsigned long base_hi, | ||
7 | int irq, int dma, | ||
8 | struct device *dev, | ||
9 | int irqflags); | ||
10 | |||
11 | static struct mp_device_t mp_devs[MAX_MP_DEV]; | ||
12 | static int mp_nrpcibrds = sizeof(mp_pciboards)/sizeof(mppcibrd_t); | ||
13 | static int NR_BOARD=0; | ||
14 | static int NR_PORTS=0; | ||
15 | static struct mp_port multi_ports[MAX_MP_PORT]; | ||
16 | static struct irq_info irq_lists[NR_IRQS]; | ||
17 | |||
18 | static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset); | ||
19 | static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value); | ||
20 | static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset); | ||
21 | static int sb1054_get_register(struct sb_uart_port * port, int page, int reg); | ||
22 | static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value); | ||
23 | static void SendATCommand(struct mp_port * mtpt); | ||
24 | static int set_deep_fifo(struct sb_uart_port * port, int status); | ||
25 | static int get_deep_fifo(struct sb_uart_port * port); | ||
26 | static int get_device_type(int arg); | ||
27 | static int set_auto_rts(struct sb_uart_port *port, int status); | ||
28 | static void mp_stop(struct tty_struct *tty); | ||
29 | static void __mp_start(struct tty_struct *tty); | ||
30 | static void mp_start(struct tty_struct *tty); | ||
31 | static void mp_tasklet_action(unsigned long data); | ||
32 | static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear); | ||
33 | static int mp_startup(struct sb_uart_state *state, int init_hw); | ||
34 | static void mp_shutdown(struct sb_uart_state *state); | ||
35 | static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios); | ||
36 | |||
37 | static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c); | ||
38 | static int mp_put_char(struct tty_struct *tty, unsigned char ch); | ||
39 | |||
40 | static void mp_put_chars(struct tty_struct *tty); | ||
41 | static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count); | ||
42 | static int mp_write_room(struct tty_struct *tty); | ||
43 | static int mp_chars_in_buffer(struct tty_struct *tty); | ||
44 | static void mp_flush_buffer(struct tty_struct *tty); | ||
45 | static void mp_send_xchar(struct tty_struct *tty, char ch); | ||
46 | static void mp_throttle(struct tty_struct *tty); | ||
47 | static void mp_unthrottle(struct tty_struct *tty); | ||
48 | static int mp_get_info(struct sb_uart_state *state, struct serial_struct *retinfo); | ||
49 | static int mp_set_info(struct sb_uart_state *state, struct serial_struct *newinfo); | ||
50 | static int mp_get_lsr_info(struct sb_uart_state *state, unsigned int *value); | ||
51 | |||
52 | static int mp_tiocmget(struct tty_struct *tty); | ||
53 | static int mp_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); | ||
54 | static int mp_break_ctl(struct tty_struct *tty, int break_state); | ||
55 | static int mp_do_autoconfig(struct sb_uart_state *state); | ||
56 | static int mp_wait_modem_status(struct sb_uart_state *state, unsigned long arg); | ||
57 | static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt); | ||
58 | static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); | ||
59 | static void mp_set_termios(struct tty_struct *tty, struct MP_TERMIOS *old_termios); | ||
60 | static void mp_close(struct tty_struct *tty, struct file *filp); | ||
61 | static void mp_wait_until_sent(struct tty_struct *tty, int timeout); | ||
62 | static void mp_hangup(struct tty_struct *tty); | ||
63 | static void mp_update_termios(struct sb_uart_state *state); | ||
64 | static int mp_block_til_ready(struct file *filp, struct sb_uart_state *state); | ||
65 | static struct sb_uart_state *uart_get(struct uart_driver *drv, int line); | ||
66 | static int mp_open(struct tty_struct *tty, struct file *filp); | ||
67 | static const char *mp_type(struct sb_uart_port *port); | ||
68 | static void mp_change_pm(struct sb_uart_state *state, int pm_state); | ||
69 | static inline void mp_report_port(struct uart_driver *drv, struct sb_uart_port *port); | ||
70 | static void mp_configure_port(struct uart_driver *drv, struct sb_uart_state *state, struct sb_uart_port *port); | ||
71 | static void mp_unconfigure_port(struct uart_driver *drv, struct sb_uart_state *state); | ||
72 | static int mp_register_driver(struct uart_driver *drv); | ||
73 | static void mp_unregister_driver(struct uart_driver *drv); | ||
74 | static int mp_add_one_port(struct uart_driver *drv, struct sb_uart_port *port); | ||
75 | static int mp_remove_one_port(struct uart_driver *drv, struct sb_uart_port *port); | ||
76 | static void autoconfig(struct mp_port *mtpt, unsigned int probeflags); | ||
77 | static void autoconfig_irq(struct mp_port *mtpt); | ||
78 | static void multi_stop_tx(struct sb_uart_port *port); | ||
79 | static void multi_start_tx(struct sb_uart_port *port); | ||
80 | static void multi_stop_rx(struct sb_uart_port *port); | ||
81 | static void multi_enable_ms(struct sb_uart_port *port); | ||
82 | static _INLINE_ void receive_chars(struct mp_port *mtpt, int *status ); | ||
83 | static _INLINE_ void transmit_chars(struct mp_port *mtpt); | ||
84 | static _INLINE_ void check_modem_status(struct mp_port *mtpt); | ||
85 | static inline void multi_handle_port(struct mp_port *mtpt); | ||
86 | static irqreturn_t multi_interrupt(int irq, void *dev_id); | ||
87 | static void serial_do_unlink(struct irq_info *i, struct mp_port *mtpt); | ||
88 | static int serial_link_irq_chain(struct mp_port *mtpt); | ||
89 | static void serial_unlink_irq_chain(struct mp_port *mtpt); | ||
90 | static void multi_timeout(unsigned long data); | ||
91 | static unsigned int multi_tx_empty(struct sb_uart_port *port); | ||
92 | static unsigned int multi_get_mctrl(struct sb_uart_port *port); | ||
93 | static void multi_set_mctrl(struct sb_uart_port *port, unsigned int mctrl); | ||
94 | static void multi_break_ctl(struct sb_uart_port *port, int break_state); | ||
95 | static int multi_startup(struct sb_uart_port *port); | ||
96 | static void multi_shutdown(struct sb_uart_port *port); | ||
97 | static unsigned int multi_get_divisor(struct sb_uart_port *port, unsigned int baud); | ||
98 | static void multi_set_termios(struct sb_uart_port *port, struct MP_TERMIOS *termios, struct MP_TERMIOS *old); | ||
99 | static void multi_pm(struct sb_uart_port *port, unsigned int state, unsigned int oldstate); | ||
100 | static void multi_release_std_resource(struct mp_port *mtpt); | ||
101 | static void multi_release_port(struct sb_uart_port *port); | ||
102 | static int multi_request_port(struct sb_uart_port *port); | ||
103 | static void multi_config_port(struct sb_uart_port *port, int flags); | ||
104 | static int multi_verify_port(struct sb_uart_port *port, struct serial_struct *ser); | ||
105 | static const char * multi_type(struct sb_uart_port *port); | ||
106 | static void __init multi_init_ports(void); | ||
107 | static void __init multi_register_ports(struct uart_driver *drv); | ||
108 | static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd); | ||
109 | |||
110 | static int deep[256]; | ||
111 | static int deep_count; | ||
112 | static int fcr_arr[256]; | ||
113 | static int fcr_count; | ||
114 | static int ttr[256]; | ||
115 | static int ttr_count; | ||
116 | static int rtr[256]; | ||
117 | static int rtr_count; | ||
118 | |||
119 | module_param_array(deep,int,&deep_count,0); | ||
120 | module_param_array(fcr_arr,int,&fcr_count,0); | ||
121 | module_param_array(ttr,int,&ttr_count,0); | ||
122 | module_param_array(rtr,int,&rtr_count,0); | ||
123 | |||
124 | static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset) | ||
125 | { | ||
126 | return inb(mtpt->port.iobase + offset); | ||
127 | } | ||
128 | |||
129 | static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value) | ||
130 | { | ||
131 | outb(value, mtpt->port.iobase + offset); | ||
132 | } | ||
133 | |||
134 | static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset) | ||
135 | { | ||
136 | return inb(mtpt->option_base_addr + offset); | ||
137 | } | ||
138 | |||
139 | static int sb1053a_get_interface(struct mp_port *mtpt, int port_num) | ||
140 | { | ||
141 | unsigned long option_base_addr = mtpt->option_base_addr; | ||
142 | unsigned int interface = 0; | ||
143 | |||
144 | switch (port_num) | ||
145 | { | ||
146 | case 0: | ||
147 | case 1: | ||
148 | /* set GPO[1:0] = 00 */ | ||
149 | outb(0x00, option_base_addr + MP_OPTR_GPODR); | ||
150 | break; | ||
151 | case 2: | ||
152 | case 3: | ||
153 | /* set GPO[1:0] = 01 */ | ||
154 | outb(0x01, option_base_addr + MP_OPTR_GPODR); | ||
155 | break; | ||
156 | case 4: | ||
157 | case 5: | ||
158 | /* set GPO[1:0] = 10 */ | ||
159 | outb(0x02, option_base_addr + MP_OPTR_GPODR); | ||
160 | break; | ||
161 | default: | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | port_num &= 0x1; | ||
166 | |||
167 | /* get interface */ | ||
168 | interface = inb(option_base_addr + MP_OPTR_IIR0 + port_num); | ||
169 | |||
170 | /* set GPO[1:0] = 11 */ | ||
171 | outb(0x03, option_base_addr + MP_OPTR_GPODR); | ||
172 | |||
173 | return (interface); | ||
174 | } | ||
175 | |||
176 | static int sb1054_get_register(struct sb_uart_port * port, int page, int reg) | ||
177 | { | ||
178 | int ret = 0; | ||
179 | unsigned int lcr = 0; | ||
180 | unsigned int mcr = 0; | ||
181 | unsigned int tmp = 0; | ||
182 | |||
183 | if( page <= 0) | ||
184 | { | ||
185 | printk(" page 0 can not use this fuction\n"); | ||
186 | return -1; | ||
187 | } | ||
188 | |||
189 | switch(page) | ||
190 | { | ||
191 | case 1: | ||
192 | lcr = SB105X_GET_LCR(port); | ||
193 | tmp = lcr | SB105X_LCR_DLAB; | ||
194 | SB105X_PUT_LCR(port, tmp); | ||
195 | |||
196 | tmp = SB105X_GET_LCR(port); | ||
197 | |||
198 | ret = SB105X_GET_REG(port,reg); | ||
199 | SB105X_PUT_LCR(port,lcr); | ||
200 | break; | ||
201 | case 2: | ||
202 | mcr = SB105X_GET_MCR(port); | ||
203 | tmp = mcr | SB105X_MCR_P2S; | ||
204 | SB105X_PUT_MCR(port,tmp); | ||
205 | |||
206 | ret = SB105X_GET_REG(port,reg); | ||
207 | |||
208 | SB105X_PUT_MCR(port,mcr); | ||
209 | break; | ||
210 | case 3: | ||
211 | lcr = SB105X_GET_LCR(port); | ||
212 | tmp = lcr | SB105X_LCR_BF; | ||
213 | SB105X_PUT_LCR(port,tmp); | ||
214 | SB105X_PUT_REG(port,SB105X_PSR,SB105X_PSR_P3KEY); | ||
215 | |||
216 | ret = SB105X_GET_REG(port,reg); | ||
217 | |||
218 | SB105X_PUT_LCR(port,lcr); | ||
219 | break; | ||
220 | case 4: | ||
221 | lcr = SB105X_GET_LCR(port); | ||
222 | tmp = lcr | SB105X_LCR_BF; | ||
223 | SB105X_PUT_LCR(port,tmp); | ||
224 | SB105X_PUT_REG(port,SB105X_PSR,SB105X_PSR_P4KEY); | ||
225 | |||
226 | ret = SB105X_GET_REG(port,reg); | ||
227 | |||
228 | SB105X_PUT_LCR(port,lcr); | ||
229 | break; | ||
230 | default: | ||
231 | printk(" error invalid page number \n"); | ||
232 | return -1; | ||
233 | } | ||
234 | |||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value) | ||
239 | { | ||
240 | int lcr = 0; | ||
241 | int mcr = 0; | ||
242 | int ret = 0; | ||
243 | |||
244 | if( page <= 0) | ||
245 | { | ||
246 | printk(" page 0 can not use this fuction\n"); | ||
247 | return -1; | ||
248 | } | ||
249 | switch(page) | ||
250 | { | ||
251 | case 1: | ||
252 | lcr = SB105X_GET_LCR(port); | ||
253 | SB105X_PUT_LCR(port, lcr | SB105X_LCR_DLAB); | ||
254 | |||
255 | SB105X_PUT_REG(port,reg,value); | ||
256 | |||
257 | SB105X_PUT_LCR(port, lcr); | ||
258 | ret = 1; | ||
259 | break; | ||
260 | case 2: | ||
261 | mcr = SB105X_GET_MCR(port); | ||
262 | SB105X_PUT_MCR(port, mcr | SB105X_MCR_P2S); | ||
263 | |||
264 | SB105X_PUT_REG(port,reg,value); | ||
265 | |||
266 | SB105X_PUT_MCR(port, mcr); | ||
267 | ret = 1; | ||
268 | break; | ||
269 | case 3: | ||
270 | lcr = SB105X_GET_LCR(port); | ||
271 | SB105X_PUT_LCR(port, lcr | SB105X_LCR_BF); | ||
272 | SB105X_PUT_PSR(port, SB105X_PSR_P3KEY); | ||
273 | |||
274 | SB105X_PUT_REG(port,reg,value); | ||
275 | |||
276 | SB105X_PUT_LCR(port, lcr); | ||
277 | ret = 1; | ||
278 | break; | ||
279 | case 4: | ||
280 | lcr = SB105X_GET_LCR(port); | ||
281 | SB105X_PUT_LCR(port, lcr | SB105X_LCR_BF); | ||
282 | SB105X_PUT_PSR(port, SB105X_PSR_P4KEY); | ||
283 | |||
284 | SB105X_PUT_REG(port,reg,value); | ||
285 | |||
286 | SB105X_PUT_LCR(port, lcr); | ||
287 | ret = 1; | ||
288 | break; | ||
289 | default: | ||
290 | printk(" error invalid page number \n"); | ||
291 | return -1; | ||
292 | } | ||
293 | |||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | static int set_multidrop_mode(struct sb_uart_port *port, unsigned int mode) | ||
298 | { | ||
299 | int mdr = SB105XA_MDR_NPS; | ||
300 | |||
301 | if (mode & MDMODE_ENABLE) | ||
302 | { | ||
303 | mdr |= SB105XA_MDR_MDE; | ||
304 | } | ||
305 | |||
306 | if (1) //(mode & MDMODE_AUTO) | ||
307 | { | ||
308 | int efr = 0; | ||
309 | mdr |= SB105XA_MDR_AME; | ||
310 | efr = sb1054_get_register(port, PAGE_3, SB105X_EFR); | ||
311 | efr |= SB105X_EFR_SCD; | ||
312 | sb1054_set_register(port, PAGE_3, SB105X_EFR, efr); | ||
313 | } | ||
314 | |||
315 | sb1054_set_register(port, PAGE_1, SB105XA_MDR, mdr); | ||
316 | port->mdmode &= ~0x6; | ||
317 | port->mdmode |= mode; | ||
318 | printk("[%d] multidrop init: %x\n", port->line, port->mdmode); | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int get_multidrop_addr(struct sb_uart_port *port) | ||
324 | { | ||
325 | return sb1054_get_register(port, PAGE_3, SB105X_XOFF2); | ||
326 | } | ||
327 | |||
328 | static int set_multidrop_addr(struct sb_uart_port *port, unsigned int addr) | ||
329 | { | ||
330 | sb1054_set_register(port, PAGE_3, SB105X_XOFF2, addr); | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static void SendATCommand(struct mp_port * mtpt) | ||
336 | { | ||
337 | // a t cr lf | ||
338 | unsigned char ch[] = {0x61,0x74,0x0d,0x0a,0x0}; | ||
339 | unsigned char lineControl; | ||
340 | unsigned char i=0; | ||
341 | unsigned char Divisor = 0xc; | ||
342 | |||
343 | lineControl = serial_inp(mtpt,UART_LCR); | ||
344 | serial_outp(mtpt,UART_LCR,(lineControl | UART_LCR_DLAB)); | ||
345 | serial_outp(mtpt,UART_DLL,(Divisor & 0xff)); | ||
346 | serial_outp(mtpt,UART_DLM,(Divisor & 0xff00)>>8); //baudrate is 4800 | ||
347 | |||
348 | |||
349 | serial_outp(mtpt,UART_LCR,lineControl); | ||
350 | serial_outp(mtpt,UART_LCR,0x03); // N-8-1 | ||
351 | serial_outp(mtpt,UART_FCR,7); | ||
352 | serial_outp(mtpt,UART_MCR,0x3); | ||
353 | while(ch[i]){ | ||
354 | while((serial_inp(mtpt,UART_LSR) & 0x60) !=0x60){ | ||
355 | ; | ||
356 | } | ||
357 | serial_outp(mtpt,0,ch[i++]); | ||
358 | } | ||
359 | |||
360 | |||
361 | }// end of SendATCommand() | ||
362 | |||
363 | static int set_deep_fifo(struct sb_uart_port * port, int status) | ||
364 | { | ||
365 | int afr_status = 0; | ||
366 | afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR); | ||
367 | |||
368 | if(status == ENABLE) | ||
369 | { | ||
370 | afr_status |= SB105X_AFR_AFEN; | ||
371 | } | ||
372 | else | ||
373 | { | ||
374 | afr_status &= ~SB105X_AFR_AFEN; | ||
375 | } | ||
376 | |||
377 | sb1054_set_register(port,PAGE_4,SB105X_AFR,afr_status); | ||
378 | sb1054_set_register(port,PAGE_4,SB105X_TTR,ttr[port->line]); | ||
379 | sb1054_set_register(port,PAGE_4,SB105X_RTR,rtr[port->line]); | ||
380 | afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR); | ||
381 | |||
382 | return afr_status; | ||
383 | } | ||
384 | |||
385 | static int get_device_type(int arg) | ||
386 | { | ||
387 | int ret; | ||
388 | ret = inb(mp_devs[arg].option_reg_addr+MP_OPTR_DIR0); | ||
389 | ret = (ret & 0xf0) >> 4; | ||
390 | switch (ret) | ||
391 | { | ||
392 | case DIR_UART_16C550: | ||
393 | return PORT_16C55X; | ||
394 | case DIR_UART_16C1050: | ||
395 | return PORT_16C105X; | ||
396 | case DIR_UART_16C1050A: | ||
397 | /* | ||
398 | if (mtpt->port.line < 2) | ||
399 | { | ||
400 | return PORT_16C105XA; | ||
401 | } | ||
402 | else | ||
403 | { | ||
404 | if (mtpt->device->device_id & 0x50) | ||
405 | { | ||
406 | return PORT_16C55X; | ||
407 | } | ||
408 | else | ||
409 | { | ||
410 | return PORT_16C105X; | ||
411 | } | ||
412 | }*/ | ||
413 | return PORT_16C105XA; | ||
414 | default: | ||
415 | return PORT_UNKNOWN; | ||
416 | } | ||
417 | |||
418 | } | ||
419 | static int get_deep_fifo(struct sb_uart_port * port) | ||
420 | { | ||
421 | int afr_status = 0; | ||
422 | afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR); | ||
423 | return afr_status; | ||
424 | } | ||
425 | |||
426 | static int set_auto_rts(struct sb_uart_port *port, int status) | ||
427 | { | ||
428 | int atr_status = 0; | ||
429 | |||
430 | #if 0 | ||
431 | int efr_status = 0; | ||
432 | |||
433 | efr_status = sb1054_get_register(port, PAGE_3, SB105X_EFR); | ||
434 | if(status == ENABLE) | ||
435 | efr_status |= SB105X_EFR_ARTS; | ||
436 | else | ||
437 | efr_status &= ~SB105X_EFR_ARTS; | ||
438 | sb1054_set_register(port,PAGE_3,SB105X_EFR,efr_status); | ||
439 | efr_status = sb1054_get_register(port, PAGE_3, SB105X_EFR); | ||
440 | #endif | ||
441 | |||
442 | //ATR | ||
443 | atr_status = sb1054_get_register(port, PAGE_3, SB105X_ATR); | ||
444 | switch(status) | ||
445 | { | ||
446 | case RS422PTP: | ||
447 | atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_A80); | ||
448 | break; | ||
449 | case RS422MD: | ||
450 | atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80); | ||
451 | break; | ||
452 | case RS485NE: | ||
453 | atr_status = (SB105X_ATR_RCMS) | (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80); | ||
454 | break; | ||
455 | case RS485ECHO: | ||
456 | atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80); | ||
457 | break; | ||
458 | } | ||
459 | |||
460 | sb1054_set_register(port,PAGE_3,SB105X_ATR,atr_status); | ||
461 | atr_status = sb1054_get_register(port, PAGE_3, SB105X_ATR); | ||
462 | |||
463 | return atr_status; | ||
464 | } | ||
465 | |||
466 | static void mp_stop(struct tty_struct *tty) | ||
467 | { | ||
468 | struct sb_uart_state *state = tty->driver_data; | ||
469 | struct sb_uart_port *port = state->port; | ||
470 | unsigned long flags; | ||
471 | |||
472 | spin_lock_irqsave(&port->lock, flags); | ||
473 | port->ops->stop_tx(port); | ||
474 | spin_unlock_irqrestore(&port->lock, flags); | ||
475 | } | ||
476 | |||
477 | static void __mp_start(struct tty_struct *tty) | ||
478 | { | ||
479 | struct sb_uart_state *state = tty->driver_data; | ||
480 | struct sb_uart_port *port = state->port; | ||
481 | |||
482 | if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf && | ||
483 | !tty->stopped && !tty->hw_stopped) | ||
484 | port->ops->start_tx(port); | ||
485 | } | ||
486 | |||
487 | static void mp_start(struct tty_struct *tty) | ||
488 | { | ||
489 | __mp_start(tty); | ||
490 | } | ||
491 | |||
492 | static void mp_tasklet_action(unsigned long data) | ||
493 | { | ||
494 | struct sb_uart_state *state = (struct sb_uart_state *)data; | ||
495 | struct tty_struct *tty; | ||
496 | |||
497 | printk("tasklet is called!\n"); | ||
498 | tty = state->info->tty; | ||
499 | tty_wakeup(tty); | ||
500 | } | ||
501 | |||
502 | static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear) | ||
503 | { | ||
504 | unsigned int old; | ||
505 | |||
506 | old = port->mctrl; | ||
507 | port->mctrl = (old & ~clear) | set; | ||
508 | if (old != port->mctrl) | ||
509 | port->ops->set_mctrl(port, port->mctrl); | ||
510 | } | ||
511 | |||
512 | #define uart_set_mctrl(port,set) mp_update_mctrl(port,set,0) | ||
513 | #define uart_clear_mctrl(port,clear) mp_update_mctrl(port,0,clear) | ||
514 | |||
515 | static int mp_startup(struct sb_uart_state *state, int init_hw) | ||
516 | { | ||
517 | struct sb_uart_info *info = state->info; | ||
518 | struct sb_uart_port *port = state->port; | ||
519 | unsigned long page; | ||
520 | int retval = 0; | ||
521 | |||
522 | if (info->flags & UIF_INITIALIZED) | ||
523 | return 0; | ||
524 | |||
525 | if (info->tty) | ||
526 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
527 | |||
528 | if (port->type == PORT_UNKNOWN) | ||
529 | return 0; | ||
530 | |||
531 | if (!info->xmit.buf) { | ||
532 | page = get_zeroed_page(GFP_KERNEL); | ||
533 | if (!page) | ||
534 | return -ENOMEM; | ||
535 | |||
536 | info->xmit.buf = (unsigned char *) page; | ||
537 | |||
538 | uart_circ_clear(&info->xmit); | ||
539 | } | ||
540 | |||
541 | retval = port->ops->startup(port); | ||
542 | if (retval == 0) { | ||
543 | if (init_hw) { | ||
544 | mp_change_speed(state, NULL); | ||
545 | |||
546 | if (info->tty->termios.c_cflag & CBAUD) | ||
547 | uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | ||
548 | } | ||
549 | |||
550 | info->flags |= UIF_INITIALIZED; | ||
551 | |||
552 | |||
553 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
554 | } | ||
555 | |||
556 | if (retval && capable(CAP_SYS_ADMIN)) | ||
557 | retval = 0; | ||
558 | |||
559 | return retval; | ||
560 | } | ||
561 | |||
562 | static void mp_shutdown(struct sb_uart_state *state) | ||
563 | { | ||
564 | struct sb_uart_info *info = state->info; | ||
565 | struct sb_uart_port *port = state->port; | ||
566 | |||
567 | if (info->tty) | ||
568 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
569 | |||
570 | if (info->flags & UIF_INITIALIZED) { | ||
571 | info->flags &= ~UIF_INITIALIZED; | ||
572 | |||
573 | if (!info->tty || (info->tty->termios.c_cflag & HUPCL)) | ||
574 | uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
575 | |||
576 | wake_up_interruptible(&info->delta_msr_wait); | ||
577 | |||
578 | port->ops->shutdown(port); | ||
579 | |||
580 | synchronize_irq(port->irq); | ||
581 | } | ||
582 | tasklet_kill(&info->tlet); | ||
583 | |||
584 | if (info->xmit.buf) { | ||
585 | free_page((unsigned long)info->xmit.buf); | ||
586 | info->xmit.buf = NULL; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios) | ||
591 | { | ||
592 | struct tty_struct *tty = state->info->tty; | ||
593 | struct sb_uart_port *port = state->port; | ||
594 | |||
595 | if (!tty || port->type == PORT_UNKNOWN) | ||
596 | return; | ||
597 | |||
598 | if (tty->termios.c_cflag & CRTSCTS) | ||
599 | state->info->flags |= UIF_CTS_FLOW; | ||
600 | else | ||
601 | state->info->flags &= ~UIF_CTS_FLOW; | ||
602 | |||
603 | if (tty->termios.c_cflag & CLOCAL) | ||
604 | state->info->flags &= ~UIF_CHECK_CD; | ||
605 | else | ||
606 | state->info->flags |= UIF_CHECK_CD; | ||
607 | |||
608 | port->ops->set_termios(port, &tty->termios, old_termios); | ||
609 | } | ||
610 | |||
611 | static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c) | ||
612 | { | ||
613 | unsigned long flags; | ||
614 | int ret = 0; | ||
615 | |||
616 | if (!circ->buf) | ||
617 | return 0; | ||
618 | |||
619 | spin_lock_irqsave(&port->lock, flags); | ||
620 | if (uart_circ_chars_free(circ) != 0) { | ||
621 | circ->buf[circ->head] = c; | ||
622 | circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); | ||
623 | ret = 1; | ||
624 | } | ||
625 | spin_unlock_irqrestore(&port->lock, flags); | ||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | static int mp_put_char(struct tty_struct *tty, unsigned char ch) | ||
630 | { | ||
631 | struct sb_uart_state *state = tty->driver_data; | ||
632 | |||
633 | return __mp_put_char(state->port, &state->info->xmit, ch); | ||
634 | } | ||
635 | |||
636 | static void mp_put_chars(struct tty_struct *tty) | ||
637 | { | ||
638 | mp_start(tty); | ||
639 | } | ||
640 | |||
641 | static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count) | ||
642 | { | ||
643 | struct sb_uart_state *state = tty->driver_data; | ||
644 | struct sb_uart_port *port; | ||
645 | struct circ_buf *circ; | ||
646 | int c, ret = 0; | ||
647 | |||
648 | if (!state || !state->info) { | ||
649 | return -EL3HLT; | ||
650 | } | ||
651 | |||
652 | port = state->port; | ||
653 | circ = &state->info->xmit; | ||
654 | |||
655 | if (!circ->buf) | ||
656 | return 0; | ||
657 | |||
658 | while (1) { | ||
659 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); | ||
660 | if (count < c) | ||
661 | c = count; | ||
662 | if (c <= 0) | ||
663 | break; | ||
664 | memcpy(circ->buf + circ->head, buf, c); | ||
665 | |||
666 | circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); | ||
667 | buf += c; | ||
668 | count -= c; | ||
669 | ret += c; | ||
670 | } | ||
671 | mp_start(tty); | ||
672 | return ret; | ||
673 | } | ||
674 | |||
675 | static int mp_write_room(struct tty_struct *tty) | ||
676 | { | ||
677 | struct sb_uart_state *state = tty->driver_data; | ||
678 | |||
679 | return uart_circ_chars_free(&state->info->xmit); | ||
680 | } | ||
681 | |||
682 | static int mp_chars_in_buffer(struct tty_struct *tty) | ||
683 | { | ||
684 | struct sb_uart_state *state = tty->driver_data; | ||
685 | |||
686 | return uart_circ_chars_pending(&state->info->xmit); | ||
687 | } | ||
688 | |||
689 | static void mp_flush_buffer(struct tty_struct *tty) | ||
690 | { | ||
691 | struct sb_uart_state *state = tty->driver_data; | ||
692 | struct sb_uart_port *port; | ||
693 | unsigned long flags; | ||
694 | |||
695 | if (!state || !state->info) { | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | port = state->port; | ||
700 | spin_lock_irqsave(&port->lock, flags); | ||
701 | uart_circ_clear(&state->info->xmit); | ||
702 | spin_unlock_irqrestore(&port->lock, flags); | ||
703 | wake_up_interruptible(&tty->write_wait); | ||
704 | tty_wakeup(tty); | ||
705 | } | ||
706 | |||
707 | static void mp_send_xchar(struct tty_struct *tty, char ch) | ||
708 | { | ||
709 | struct sb_uart_state *state = tty->driver_data; | ||
710 | struct sb_uart_port *port = state->port; | ||
711 | unsigned long flags; | ||
712 | |||
713 | if (port->ops->send_xchar) | ||
714 | port->ops->send_xchar(port, ch); | ||
715 | else { | ||
716 | port->x_char = ch; | ||
717 | if (ch) { | ||
718 | spin_lock_irqsave(&port->lock, flags); | ||
719 | port->ops->start_tx(port); | ||
720 | spin_unlock_irqrestore(&port->lock, flags); | ||
721 | } | ||
722 | } | ||
723 | } | ||
724 | |||
725 | static void mp_throttle(struct tty_struct *tty) | ||
726 | { | ||
727 | struct sb_uart_state *state = tty->driver_data; | ||
728 | |||
729 | if (I_IXOFF(tty)) | ||
730 | mp_send_xchar(tty, STOP_CHAR(tty)); | ||
731 | |||
732 | if (tty->termios.c_cflag & CRTSCTS) | ||
733 | uart_clear_mctrl(state->port, TIOCM_RTS); | ||
734 | } | ||
735 | |||
736 | static void mp_unthrottle(struct tty_struct *tty) | ||
737 | { | ||
738 | struct sb_uart_state *state = tty->driver_data; | ||
739 | struct sb_uart_port *port = state->port; | ||
740 | |||
741 | if (I_IXOFF(tty)) { | ||
742 | if (port->x_char) | ||
743 | port->x_char = 0; | ||
744 | else | ||
745 | mp_send_xchar(tty, START_CHAR(tty)); | ||
746 | } | ||
747 | |||
748 | if (tty->termios.c_cflag & CRTSCTS) | ||
749 | uart_set_mctrl(port, TIOCM_RTS); | ||
750 | } | ||
751 | |||
752 | static int mp_get_info(struct sb_uart_state *state, struct serial_struct *retinfo) | ||
753 | { | ||
754 | struct sb_uart_port *port = state->port; | ||
755 | struct serial_struct tmp; | ||
756 | |||
757 | memset(&tmp, 0, sizeof(tmp)); | ||
758 | tmp.type = port->type; | ||
759 | tmp.line = port->line; | ||
760 | tmp.port = port->iobase; | ||
761 | if (HIGH_BITS_OFFSET) | ||
762 | tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET; | ||
763 | tmp.irq = port->irq; | ||
764 | tmp.flags = port->flags; | ||
765 | tmp.xmit_fifo_size = port->fifosize; | ||
766 | tmp.baud_base = port->uartclk / 16; | ||
767 | tmp.close_delay = state->close_delay; | ||
768 | tmp.closing_wait = state->closing_wait == USF_CLOSING_WAIT_NONE ? | ||
769 | ASYNC_CLOSING_WAIT_NONE : | ||
770 | state->closing_wait; | ||
771 | tmp.custom_divisor = port->custom_divisor; | ||
772 | tmp.hub6 = port->hub6; | ||
773 | tmp.io_type = port->iotype; | ||
774 | tmp.iomem_reg_shift = port->regshift; | ||
775 | tmp.iomem_base = (void *)port->mapbase; | ||
776 | |||
777 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
778 | return -EFAULT; | ||
779 | return 0; | ||
780 | } | ||
781 | |||
782 | static int mp_set_info(struct sb_uart_state *state, struct serial_struct *newinfo) | ||
783 | { | ||
784 | struct serial_struct new_serial; | ||
785 | struct sb_uart_port *port = state->port; | ||
786 | unsigned long new_port; | ||
787 | unsigned int change_irq, change_port, closing_wait; | ||
788 | unsigned int old_custom_divisor; | ||
789 | unsigned int old_flags, new_flags; | ||
790 | int retval = 0; | ||
791 | |||
792 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | ||
793 | return -EFAULT; | ||
794 | |||
795 | new_port = new_serial.port; | ||
796 | if (HIGH_BITS_OFFSET) | ||
797 | new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; | ||
798 | |||
799 | new_serial.irq = irq_canonicalize(new_serial.irq); | ||
800 | |||
801 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | ||
802 | USF_CLOSING_WAIT_NONE : new_serial.closing_wait; | ||
803 | MP_STATE_LOCK(state); | ||
804 | |||
805 | change_irq = new_serial.irq != port->irq; | ||
806 | change_port = new_port != port->iobase || | ||
807 | (unsigned long)new_serial.iomem_base != port->mapbase || | ||
808 | new_serial.hub6 != port->hub6 || | ||
809 | new_serial.io_type != port->iotype || | ||
810 | new_serial.iomem_reg_shift != port->regshift || | ||
811 | new_serial.type != port->type; | ||
812 | old_flags = port->flags; | ||
813 | new_flags = new_serial.flags; | ||
814 | old_custom_divisor = port->custom_divisor; | ||
815 | |||
816 | if (!capable(CAP_SYS_ADMIN)) { | ||
817 | retval = -EPERM; | ||
818 | if (change_irq || change_port || | ||
819 | (new_serial.baud_base != port->uartclk / 16) || | ||
820 | (new_serial.close_delay != state->close_delay) || | ||
821 | (closing_wait != state->closing_wait) || | ||
822 | (new_serial.xmit_fifo_size != port->fifosize) || | ||
823 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) | ||
824 | goto exit; | ||
825 | port->flags = ((port->flags & ~UPF_USR_MASK) | | ||
826 | (new_flags & UPF_USR_MASK)); | ||
827 | port->custom_divisor = new_serial.custom_divisor; | ||
828 | goto check_and_exit; | ||
829 | } | ||
830 | |||
831 | if (port->ops->verify_port) | ||
832 | retval = port->ops->verify_port(port, &new_serial); | ||
833 | |||
834 | if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || | ||
835 | (new_serial.baud_base < 9600)) | ||
836 | retval = -EINVAL; | ||
837 | |||
838 | if (retval) | ||
839 | goto exit; | ||
840 | |||
841 | if (change_port || change_irq) { | ||
842 | retval = -EBUSY; | ||
843 | |||
844 | if (uart_users(state) > 1) | ||
845 | goto exit; | ||
846 | |||
847 | mp_shutdown(state); | ||
848 | } | ||
849 | |||
850 | if (change_port) { | ||
851 | unsigned long old_iobase, old_mapbase; | ||
852 | unsigned int old_type, old_iotype, old_hub6, old_shift; | ||
853 | |||
854 | old_iobase = port->iobase; | ||
855 | old_mapbase = port->mapbase; | ||
856 | old_type = port->type; | ||
857 | old_hub6 = port->hub6; | ||
858 | old_iotype = port->iotype; | ||
859 | old_shift = port->regshift; | ||
860 | |||
861 | if (old_type != PORT_UNKNOWN) | ||
862 | port->ops->release_port(port); | ||
863 | |||
864 | port->iobase = new_port; | ||
865 | port->type = new_serial.type; | ||
866 | port->hub6 = new_serial.hub6; | ||
867 | port->iotype = new_serial.io_type; | ||
868 | port->regshift = new_serial.iomem_reg_shift; | ||
869 | port->mapbase = (unsigned long)new_serial.iomem_base; | ||
870 | |||
871 | if (port->type != PORT_UNKNOWN) { | ||
872 | retval = port->ops->request_port(port); | ||
873 | } else { | ||
874 | retval = 0; | ||
875 | } | ||
876 | |||
877 | if (retval && old_type != PORT_UNKNOWN) { | ||
878 | port->iobase = old_iobase; | ||
879 | port->type = old_type; | ||
880 | port->hub6 = old_hub6; | ||
881 | port->iotype = old_iotype; | ||
882 | port->regshift = old_shift; | ||
883 | port->mapbase = old_mapbase; | ||
884 | retval = port->ops->request_port(port); | ||
885 | if (retval) | ||
886 | port->type = PORT_UNKNOWN; | ||
887 | |||
888 | retval = -EBUSY; | ||
889 | } | ||
890 | } | ||
891 | |||
892 | port->irq = new_serial.irq; | ||
893 | port->uartclk = new_serial.baud_base * 16; | ||
894 | port->flags = (port->flags & ~UPF_CHANGE_MASK) | | ||
895 | (new_flags & UPF_CHANGE_MASK); | ||
896 | port->custom_divisor = new_serial.custom_divisor; | ||
897 | state->close_delay = new_serial.close_delay; | ||
898 | state->closing_wait = closing_wait; | ||
899 | port->fifosize = new_serial.xmit_fifo_size; | ||
900 | if (state->info->tty) | ||
901 | state->info->tty->low_latency = | ||
902 | (port->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
903 | |||
904 | check_and_exit: | ||
905 | retval = 0; | ||
906 | if (port->type == PORT_UNKNOWN) | ||
907 | goto exit; | ||
908 | if (state->info->flags & UIF_INITIALIZED) { | ||
909 | if (((old_flags ^ port->flags) & UPF_SPD_MASK) || | ||
910 | old_custom_divisor != port->custom_divisor) { | ||
911 | if (port->flags & UPF_SPD_MASK) { | ||
912 | printk(KERN_NOTICE | ||
913 | "%s sets custom speed on ttyMP%d. This " | ||
914 | "is deprecated.\n", current->comm, | ||
915 | port->line); | ||
916 | } | ||
917 | mp_change_speed(state, NULL); | ||
918 | } | ||
919 | } else | ||
920 | retval = mp_startup(state, 1); | ||
921 | exit: | ||
922 | MP_STATE_UNLOCK(state); | ||
923 | return retval; | ||
924 | } | ||
925 | |||
926 | |||
927 | static int mp_get_lsr_info(struct sb_uart_state *state, unsigned int *value) | ||
928 | { | ||
929 | struct sb_uart_port *port = state->port; | ||
930 | unsigned int result; | ||
931 | |||
932 | result = port->ops->tx_empty(port); | ||
933 | |||
934 | if (port->x_char || | ||
935 | ((uart_circ_chars_pending(&state->info->xmit) > 0) && | ||
936 | !state->info->tty->stopped && !state->info->tty->hw_stopped)) | ||
937 | result &= ~TIOCSER_TEMT; | ||
938 | |||
939 | return put_user(result, value); | ||
940 | } | ||
941 | |||
942 | static int mp_tiocmget(struct tty_struct *tty) | ||
943 | { | ||
944 | struct sb_uart_state *state = tty->driver_data; | ||
945 | struct sb_uart_port *port = state->port; | ||
946 | int result = -EIO; | ||
947 | |||
948 | MP_STATE_LOCK(state); | ||
949 | if (!(tty->flags & (1 << TTY_IO_ERROR))) { | ||
950 | result = port->mctrl; | ||
951 | spin_lock_irq(&port->lock); | ||
952 | result |= port->ops->get_mctrl(port); | ||
953 | spin_unlock_irq(&port->lock); | ||
954 | } | ||
955 | MP_STATE_UNLOCK(state); | ||
956 | return result; | ||
957 | } | ||
958 | |||
959 | static int mp_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) | ||
960 | { | ||
961 | struct sb_uart_state *state = tty->driver_data; | ||
962 | struct sb_uart_port *port = state->port; | ||
963 | int ret = -EIO; | ||
964 | |||
965 | |||
966 | MP_STATE_LOCK(state); | ||
967 | if (!(tty->flags & (1 << TTY_IO_ERROR))) { | ||
968 | mp_update_mctrl(port, set, clear); | ||
969 | ret = 0; | ||
970 | } | ||
971 | MP_STATE_UNLOCK(state); | ||
972 | |||
973 | return ret; | ||
974 | } | ||
975 | |||
976 | static int mp_break_ctl(struct tty_struct *tty, int break_state) | ||
977 | { | ||
978 | struct sb_uart_state *state = tty->driver_data; | ||
979 | struct sb_uart_port *port = state->port; | ||
980 | |||
981 | MP_STATE_LOCK(state); | ||
982 | |||
983 | if (port->type != PORT_UNKNOWN) | ||
984 | port->ops->break_ctl(port, break_state); | ||
985 | |||
986 | MP_STATE_UNLOCK(state); | ||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | static int mp_do_autoconfig(struct sb_uart_state *state) | ||
991 | { | ||
992 | struct sb_uart_port *port = state->port; | ||
993 | int flags, ret; | ||
994 | |||
995 | if (!capable(CAP_SYS_ADMIN)) | ||
996 | return -EPERM; | ||
997 | |||
998 | if (mutex_lock_interruptible(&state->mutex)) | ||
999 | return -ERESTARTSYS; | ||
1000 | ret = -EBUSY; | ||
1001 | if (uart_users(state) == 1) { | ||
1002 | mp_shutdown(state); | ||
1003 | |||
1004 | if (port->type != PORT_UNKNOWN) | ||
1005 | port->ops->release_port(port); | ||
1006 | |||
1007 | flags = UART_CONFIG_TYPE; | ||
1008 | if (port->flags & UPF_AUTO_IRQ) | ||
1009 | flags |= UART_CONFIG_IRQ; | ||
1010 | |||
1011 | port->ops->config_port(port, flags); | ||
1012 | |||
1013 | ret = mp_startup(state, 1); | ||
1014 | } | ||
1015 | MP_STATE_UNLOCK(state); | ||
1016 | return ret; | ||
1017 | } | ||
1018 | |||
1019 | static int mp_wait_modem_status(struct sb_uart_state *state, unsigned long arg) | ||
1020 | { | ||
1021 | struct sb_uart_port *port = state->port; | ||
1022 | DECLARE_WAITQUEUE(wait, current); | ||
1023 | struct sb_uart_icount cprev, cnow; | ||
1024 | int ret; | ||
1025 | |||
1026 | spin_lock_irq(&port->lock); | ||
1027 | memcpy(&cprev, &port->icount, sizeof(struct sb_uart_icount)); | ||
1028 | |||
1029 | port->ops->enable_ms(port); | ||
1030 | spin_unlock_irq(&port->lock); | ||
1031 | |||
1032 | add_wait_queue(&state->info->delta_msr_wait, &wait); | ||
1033 | for (;;) { | ||
1034 | spin_lock_irq(&port->lock); | ||
1035 | memcpy(&cnow, &port->icount, sizeof(struct sb_uart_icount)); | ||
1036 | spin_unlock_irq(&port->lock); | ||
1037 | |||
1038 | set_current_state(TASK_INTERRUPTIBLE); | ||
1039 | |||
1040 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
1041 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
1042 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
1043 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
1044 | ret = 0; | ||
1045 | break; | ||
1046 | } | ||
1047 | |||
1048 | schedule(); | ||
1049 | |||
1050 | if (signal_pending(current)) { | ||
1051 | ret = -ERESTARTSYS; | ||
1052 | break; | ||
1053 | } | ||
1054 | |||
1055 | cprev = cnow; | ||
1056 | } | ||
1057 | |||
1058 | current->state = TASK_RUNNING; | ||
1059 | remove_wait_queue(&state->info->delta_msr_wait, &wait); | ||
1060 | |||
1061 | return ret; | ||
1062 | } | ||
1063 | |||
1064 | static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt) | ||
1065 | { | ||
1066 | struct serial_icounter_struct icount; | ||
1067 | struct sb_uart_icount cnow; | ||
1068 | struct sb_uart_port *port = state->port; | ||
1069 | |||
1070 | spin_lock_irq(&port->lock); | ||
1071 | memcpy(&cnow, &port->icount, sizeof(struct sb_uart_icount)); | ||
1072 | spin_unlock_irq(&port->lock); | ||
1073 | |||
1074 | icount.cts = cnow.cts; | ||
1075 | icount.dsr = cnow.dsr; | ||
1076 | icount.rng = cnow.rng; | ||
1077 | icount.dcd = cnow.dcd; | ||
1078 | icount.rx = cnow.rx; | ||
1079 | icount.tx = cnow.tx; | ||
1080 | icount.frame = cnow.frame; | ||
1081 | icount.overrun = cnow.overrun; | ||
1082 | icount.parity = cnow.parity; | ||
1083 | icount.brk = cnow.brk; | ||
1084 | icount.buf_overrun = cnow.buf_overrun; | ||
1085 | |||
1086 | return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0; | ||
1087 | } | ||
1088 | |||
1089 | static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) | ||
1090 | { | ||
1091 | struct sb_uart_state *state = tty->driver_data; | ||
1092 | struct mp_port *info = (struct mp_port *)state->port; | ||
1093 | int ret = -ENOIOCTLCMD; | ||
1094 | |||
1095 | |||
1096 | switch (cmd) { | ||
1097 | case TIOCSMULTIDROP: | ||
1098 | /* set multi-drop mode enable or disable, and default operation mode is H/W mode */ | ||
1099 | if (info->port.type == PORT_16C105XA) | ||
1100 | { | ||
1101 | //arg &= ~0x6; | ||
1102 | //state->port->mdmode = 0; | ||
1103 | return set_multidrop_mode((struct sb_uart_port *)info, (unsigned int)arg); | ||
1104 | } | ||
1105 | ret = -ENOTSUPP; | ||
1106 | break; | ||
1107 | case GETDEEPFIFO: | ||
1108 | ret = get_deep_fifo(state->port); | ||
1109 | return ret; | ||
1110 | case SETDEEPFIFO: | ||
1111 | ret = set_deep_fifo(state->port,arg); | ||
1112 | deep[state->port->line] = arg; | ||
1113 | return ret; | ||
1114 | case SETTTR: | ||
1115 | if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ | ||
1116 | ret = sb1054_set_register(state->port,PAGE_4,SB105X_TTR,arg); | ||
1117 | ttr[state->port->line] = arg; | ||
1118 | } | ||
1119 | return ret; | ||
1120 | case SETRTR: | ||
1121 | if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ | ||
1122 | ret = sb1054_set_register(state->port,PAGE_4,SB105X_RTR,arg); | ||
1123 | rtr[state->port->line] = arg; | ||
1124 | } | ||
1125 | return ret; | ||
1126 | case GETTTR: | ||
1127 | if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ | ||
1128 | ret = sb1054_get_register(state->port,PAGE_4,SB105X_TTR); | ||
1129 | } | ||
1130 | return ret; | ||
1131 | case GETRTR: | ||
1132 | if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ | ||
1133 | ret = sb1054_get_register(state->port,PAGE_4,SB105X_RTR); | ||
1134 | } | ||
1135 | return ret; | ||
1136 | |||
1137 | case SETFCR: | ||
1138 | if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ | ||
1139 | ret = sb1054_set_register(state->port,PAGE_1,SB105X_FCR,arg); | ||
1140 | } | ||
1141 | else{ | ||
1142 | serial_out(info,2,arg); | ||
1143 | } | ||
1144 | |||
1145 | return ret; | ||
1146 | case TIOCSMDADDR: | ||
1147 | /* set multi-drop address */ | ||
1148 | if (info->port.type == PORT_16C105XA) | ||
1149 | { | ||
1150 | state->port->mdmode |= MDMODE_ADDR; | ||
1151 | return set_multidrop_addr((struct sb_uart_port *)info, (unsigned int)arg); | ||
1152 | } | ||
1153 | ret = -ENOTSUPP; | ||
1154 | break; | ||
1155 | |||
1156 | case TIOCGMDADDR: | ||
1157 | /* set multi-drop address */ | ||
1158 | if ((info->port.type == PORT_16C105XA) && (state->port->mdmode & MDMODE_ADDR)) | ||
1159 | { | ||
1160 | return get_multidrop_addr((struct sb_uart_port *)info); | ||
1161 | } | ||
1162 | ret = -ENOTSUPP; | ||
1163 | break; | ||
1164 | |||
1165 | case TIOCSENDADDR: | ||
1166 | /* send address in multi-drop mode */ | ||
1167 | if ((info->port.type == PORT_16C105XA) | ||
1168 | && (state->port->mdmode & (MDMODE_ENABLE))) | ||
1169 | { | ||
1170 | if (mp_chars_in_buffer(tty) > 0) | ||
1171 | { | ||
1172 | tty_wait_until_sent(tty, 0); | ||
1173 | } | ||
1174 | //while ((serial_in(info, UART_LSR) & 0x60) != 0x60); | ||
1175 | //while (sb1054_get_register(state->port, PAGE_2, SB105X_TFCR) != 0); | ||
1176 | while ((serial_in(info, UART_LSR) & 0x60) != 0x60); | ||
1177 | serial_out(info, UART_SCR, (int)arg); | ||
1178 | } | ||
1179 | break; | ||
1180 | |||
1181 | case TIOCGSERIAL: | ||
1182 | ret = mp_get_info(state, (struct serial_struct *)arg); | ||
1183 | break; | ||
1184 | |||
1185 | case TIOCSSERIAL: | ||
1186 | ret = mp_set_info(state, (struct serial_struct *)arg); | ||
1187 | break; | ||
1188 | |||
1189 | case TIOCSERCONFIG: | ||
1190 | ret = mp_do_autoconfig(state); | ||
1191 | break; | ||
1192 | |||
1193 | case TIOCSERGWILD: /* obsolete */ | ||
1194 | case TIOCSERSWILD: /* obsolete */ | ||
1195 | ret = 0; | ||
1196 | break; | ||
1197 | /* for Multiport */ | ||
1198 | case TIOCGNUMOFPORT: /* Get number of ports */ | ||
1199 | return NR_PORTS; | ||
1200 | case TIOCGGETDEVID: | ||
1201 | return mp_devs[arg].device_id; | ||
1202 | case TIOCGGETREV: | ||
1203 | return mp_devs[arg].revision; | ||
1204 | case TIOCGGETNRPORTS: | ||
1205 | return mp_devs[arg].nr_ports; | ||
1206 | case TIOCGGETBDNO: | ||
1207 | return NR_BOARD; | ||
1208 | case TIOCGGETINTERFACE: | ||
1209 | if (mp_devs[arg].revision == 0xc0) | ||
1210 | { | ||
1211 | /* for SB16C1053APCI */ | ||
1212 | return (sb1053a_get_interface(info, info->port.line)); | ||
1213 | } | ||
1214 | else | ||
1215 | { | ||
1216 | return (inb(mp_devs[arg].option_reg_addr+MP_OPTR_IIR0+(state->port->line/8))); | ||
1217 | } | ||
1218 | case TIOCGGETPORTTYPE: | ||
1219 | ret = get_device_type(arg);; | ||
1220 | return ret; | ||
1221 | case TIOCSMULTIECHO: /* set to multi-drop mode(RS422) or echo mode(RS485)*/ | ||
1222 | outb( ( inb(info->interface_config_addr) & ~0x03 ) | 0x01 , | ||
1223 | info->interface_config_addr); | ||
1224 | return 0; | ||
1225 | case TIOCSPTPNOECHO: /* set to multi-drop mode(RS422) or echo mode(RS485) */ | ||
1226 | outb( ( inb(info->interface_config_addr) & ~0x03 ) , | ||
1227 | info->interface_config_addr); | ||
1228 | return 0; | ||
1229 | } | ||
1230 | |||
1231 | if (ret != -ENOIOCTLCMD) | ||
1232 | goto out; | ||
1233 | |||
1234 | if (tty->flags & (1 << TTY_IO_ERROR)) { | ||
1235 | ret = -EIO; | ||
1236 | goto out; | ||
1237 | } | ||
1238 | |||
1239 | switch (cmd) { | ||
1240 | case TIOCMIWAIT: | ||
1241 | ret = mp_wait_modem_status(state, arg); | ||
1242 | break; | ||
1243 | |||
1244 | case TIOCGICOUNT: | ||
1245 | ret = mp_get_count(state, (struct serial_icounter_struct *)arg); | ||
1246 | break; | ||
1247 | } | ||
1248 | |||
1249 | if (ret != -ENOIOCTLCMD) | ||
1250 | goto out; | ||
1251 | |||
1252 | MP_STATE_LOCK(state); | ||
1253 | switch (cmd) { | ||
1254 | case TIOCSERGETLSR: /* Get line status register */ | ||
1255 | ret = mp_get_lsr_info(state, (unsigned int *)arg); | ||
1256 | break; | ||
1257 | |||
1258 | default: { | ||
1259 | struct sb_uart_port *port = state->port; | ||
1260 | if (port->ops->ioctl) | ||
1261 | ret = port->ops->ioctl(port, cmd, arg); | ||
1262 | break; | ||
1263 | } | ||
1264 | } | ||
1265 | |||
1266 | MP_STATE_UNLOCK(state); | ||
1267 | out: | ||
1268 | return ret; | ||
1269 | } | ||
1270 | |||
1271 | static void mp_set_termios(struct tty_struct *tty, struct MP_TERMIOS *old_termios) | ||
1272 | { | ||
1273 | struct sb_uart_state *state = tty->driver_data; | ||
1274 | unsigned long flags; | ||
1275 | unsigned int cflag = tty->termios.c_cflag; | ||
1276 | |||
1277 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | ||
1278 | |||
1279 | if ((cflag ^ old_termios->c_cflag) == 0 && | ||
1280 | RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0) | ||
1281 | return; | ||
1282 | |||
1283 | mp_change_speed(state, old_termios); | ||
1284 | |||
1285 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) | ||
1286 | uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR); | ||
1287 | |||
1288 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | ||
1289 | unsigned int mask = TIOCM_DTR; | ||
1290 | if (!(cflag & CRTSCTS) || | ||
1291 | !test_bit(TTY_THROTTLED, &tty->flags)) | ||
1292 | mask |= TIOCM_RTS; | ||
1293 | uart_set_mctrl(state->port, mask); | ||
1294 | } | ||
1295 | |||
1296 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { | ||
1297 | spin_lock_irqsave(&state->port->lock, flags); | ||
1298 | tty->hw_stopped = 0; | ||
1299 | __mp_start(tty); | ||
1300 | spin_unlock_irqrestore(&state->port->lock, flags); | ||
1301 | } | ||
1302 | |||
1303 | if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { | ||
1304 | spin_lock_irqsave(&state->port->lock, flags); | ||
1305 | if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { | ||
1306 | tty->hw_stopped = 1; | ||
1307 | state->port->ops->stop_tx(state->port); | ||
1308 | } | ||
1309 | spin_unlock_irqrestore(&state->port->lock, flags); | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | static void mp_close(struct tty_struct *tty, struct file *filp) | ||
1314 | { | ||
1315 | struct sb_uart_state *state = tty->driver_data; | ||
1316 | struct sb_uart_port *port; | ||
1317 | |||
1318 | printk("mp_close!\n"); | ||
1319 | if (!state || !state->port) | ||
1320 | return; | ||
1321 | |||
1322 | port = state->port; | ||
1323 | |||
1324 | printk("close1 %d\n", __LINE__); | ||
1325 | MP_STATE_LOCK(state); | ||
1326 | |||
1327 | printk("close2 %d\n", __LINE__); | ||
1328 | if (tty_hung_up_p(filp)) | ||
1329 | goto done; | ||
1330 | |||
1331 | printk("close3 %d\n", __LINE__); | ||
1332 | if ((tty->count == 1) && (state->count != 1)) { | ||
1333 | printk("mp_close: bad serial port count; tty->count is 1, " | ||
1334 | "state->count is %d\n", state->count); | ||
1335 | state->count = 1; | ||
1336 | } | ||
1337 | printk("close4 %d\n", __LINE__); | ||
1338 | if (--state->count < 0) { | ||
1339 | printk("rs_close: bad serial port count for ttyMP%d: %d\n", | ||
1340 | port->line, state->count); | ||
1341 | state->count = 0; | ||
1342 | } | ||
1343 | if (state->count) | ||
1344 | goto done; | ||
1345 | |||
1346 | tty->closing = 1; | ||
1347 | |||
1348 | printk("close5 %d\n", __LINE__); | ||
1349 | if (state->closing_wait != USF_CLOSING_WAIT_NONE) | ||
1350 | tty_wait_until_sent(tty, state->closing_wait); | ||
1351 | |||
1352 | printk("close6 %d\n", __LINE__); | ||
1353 | if (state->info->flags & UIF_INITIALIZED) { | ||
1354 | unsigned long flags; | ||
1355 | spin_lock_irqsave(&port->lock, flags); | ||
1356 | port->ops->stop_rx(port); | ||
1357 | spin_unlock_irqrestore(&port->lock, flags); | ||
1358 | mp_wait_until_sent(tty, port->timeout); | ||
1359 | } | ||
1360 | printk("close7 %d\n", __LINE__); | ||
1361 | |||
1362 | mp_shutdown(state); | ||
1363 | printk("close8 %d\n", __LINE__); | ||
1364 | mp_flush_buffer(tty); | ||
1365 | tty_ldisc_flush(tty); | ||
1366 | tty->closing = 0; | ||
1367 | state->info->tty = NULL; | ||
1368 | if (state->info->blocked_open) | ||
1369 | { | ||
1370 | if (state->close_delay) | ||
1371 | { | ||
1372 | set_current_state(TASK_INTERRUPTIBLE); | ||
1373 | schedule_timeout(state->close_delay); | ||
1374 | } | ||
1375 | } | ||
1376 | else | ||
1377 | { | ||
1378 | mp_change_pm(state, 3); | ||
1379 | } | ||
1380 | printk("close8 %d\n", __LINE__); | ||
1381 | |||
1382 | state->info->flags &= ~UIF_NORMAL_ACTIVE; | ||
1383 | wake_up_interruptible(&state->info->open_wait); | ||
1384 | |||
1385 | done: | ||
1386 | printk("close done\n"); | ||
1387 | MP_STATE_UNLOCK(state); | ||
1388 | module_put(THIS_MODULE); | ||
1389 | } | ||
1390 | |||
1391 | static void mp_wait_until_sent(struct tty_struct *tty, int timeout) | ||
1392 | { | ||
1393 | struct sb_uart_state *state = tty->driver_data; | ||
1394 | struct sb_uart_port *port = state->port; | ||
1395 | unsigned long char_time, expire; | ||
1396 | |||
1397 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) | ||
1398 | return; | ||
1399 | |||
1400 | char_time = (port->timeout - HZ/50) / port->fifosize; | ||
1401 | char_time = char_time / 5; | ||
1402 | if (char_time == 0) | ||
1403 | char_time = 1; | ||
1404 | if (timeout && timeout < char_time) | ||
1405 | char_time = timeout; | ||
1406 | |||
1407 | if (timeout == 0 || timeout > 2 * port->timeout) | ||
1408 | timeout = 2 * port->timeout; | ||
1409 | |||
1410 | expire = jiffies + timeout; | ||
1411 | |||
1412 | while (!port->ops->tx_empty(port)) { | ||
1413 | set_current_state(TASK_INTERRUPTIBLE); | ||
1414 | schedule_timeout(char_time); | ||
1415 | if (signal_pending(current)) | ||
1416 | break; | ||
1417 | if (time_after(jiffies, expire)) | ||
1418 | break; | ||
1419 | } | ||
1420 | set_current_state(TASK_RUNNING); /* might not be needed */ | ||
1421 | } | ||
1422 | |||
1423 | static void mp_hangup(struct tty_struct *tty) | ||
1424 | { | ||
1425 | struct sb_uart_state *state = tty->driver_data; | ||
1426 | |||
1427 | MP_STATE_LOCK(state); | ||
1428 | if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) { | ||
1429 | mp_flush_buffer(tty); | ||
1430 | mp_shutdown(state); | ||
1431 | state->count = 0; | ||
1432 | state->info->flags &= ~UIF_NORMAL_ACTIVE; | ||
1433 | state->info->tty = NULL; | ||
1434 | wake_up_interruptible(&state->info->open_wait); | ||
1435 | wake_up_interruptible(&state->info->delta_msr_wait); | ||
1436 | } | ||
1437 | MP_STATE_UNLOCK(state); | ||
1438 | } | ||
1439 | |||
1440 | static void mp_update_termios(struct sb_uart_state *state) | ||
1441 | { | ||
1442 | struct tty_struct *tty = state->info->tty; | ||
1443 | struct sb_uart_port *port = state->port; | ||
1444 | |||
1445 | if (!(tty->flags & (1 << TTY_IO_ERROR))) { | ||
1446 | mp_change_speed(state, NULL); | ||
1447 | |||
1448 | if (tty->termios.c_cflag & CBAUD) | ||
1449 | uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | static int mp_block_til_ready(struct file *filp, struct sb_uart_state *state) | ||
1454 | { | ||
1455 | DECLARE_WAITQUEUE(wait, current); | ||
1456 | struct sb_uart_info *info = state->info; | ||
1457 | struct sb_uart_port *port = state->port; | ||
1458 | unsigned int mctrl; | ||
1459 | |||
1460 | info->blocked_open++; | ||
1461 | state->count--; | ||
1462 | |||
1463 | add_wait_queue(&info->open_wait, &wait); | ||
1464 | while (1) { | ||
1465 | set_current_state(TASK_INTERRUPTIBLE); | ||
1466 | |||
1467 | if (tty_hung_up_p(filp) || info->tty == NULL) | ||
1468 | break; | ||
1469 | |||
1470 | if (!(info->flags & UIF_INITIALIZED)) | ||
1471 | break; | ||
1472 | |||
1473 | if ((filp->f_flags & O_NONBLOCK) || | ||
1474 | (info->tty->termios.c_cflag & CLOCAL) || | ||
1475 | (info->tty->flags & (1 << TTY_IO_ERROR))) { | ||
1476 | break; | ||
1477 | } | ||
1478 | |||
1479 | if (info->tty->termios.c_cflag & CBAUD) | ||
1480 | uart_set_mctrl(port, TIOCM_DTR); | ||
1481 | |||
1482 | spin_lock_irq(&port->lock); | ||
1483 | port->ops->enable_ms(port); | ||
1484 | mctrl = port->ops->get_mctrl(port); | ||
1485 | spin_unlock_irq(&port->lock); | ||
1486 | if (mctrl & TIOCM_CAR) | ||
1487 | break; | ||
1488 | |||
1489 | MP_STATE_UNLOCK(state); | ||
1490 | schedule(); | ||
1491 | MP_STATE_LOCK(state); | ||
1492 | |||
1493 | if (signal_pending(current)) | ||
1494 | break; | ||
1495 | } | ||
1496 | set_current_state(TASK_RUNNING); | ||
1497 | remove_wait_queue(&info->open_wait, &wait); | ||
1498 | |||
1499 | state->count++; | ||
1500 | info->blocked_open--; | ||
1501 | |||
1502 | if (signal_pending(current)) | ||
1503 | return -ERESTARTSYS; | ||
1504 | |||
1505 | if (!info->tty || tty_hung_up_p(filp)) | ||
1506 | return -EAGAIN; | ||
1507 | |||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | static struct sb_uart_state *uart_get(struct uart_driver *drv, int line) | ||
1512 | { | ||
1513 | struct sb_uart_state *state; | ||
1514 | |||
1515 | MP_MUTEX_LOCK(mp_mutex); | ||
1516 | state = drv->state + line; | ||
1517 | if (mutex_lock_interruptible(&state->mutex)) { | ||
1518 | state = ERR_PTR(-ERESTARTSYS); | ||
1519 | goto out; | ||
1520 | } | ||
1521 | state->count++; | ||
1522 | if (!state->port) { | ||
1523 | state->count--; | ||
1524 | MP_STATE_UNLOCK(state); | ||
1525 | state = ERR_PTR(-ENXIO); | ||
1526 | goto out; | ||
1527 | } | ||
1528 | |||
1529 | if (!state->info) { | ||
1530 | state->info = kmalloc(sizeof(struct sb_uart_info), GFP_KERNEL); | ||
1531 | if (state->info) { | ||
1532 | memset(state->info, 0, sizeof(struct sb_uart_info)); | ||
1533 | init_waitqueue_head(&state->info->open_wait); | ||
1534 | init_waitqueue_head(&state->info->delta_msr_wait); | ||
1535 | |||
1536 | state->port->info = state->info; | ||
1537 | |||
1538 | tasklet_init(&state->info->tlet, mp_tasklet_action, | ||
1539 | (unsigned long)state); | ||
1540 | } else { | ||
1541 | state->count--; | ||
1542 | MP_STATE_UNLOCK(state); | ||
1543 | state = ERR_PTR(-ENOMEM); | ||
1544 | } | ||
1545 | } | ||
1546 | |||
1547 | out: | ||
1548 | MP_MUTEX_UNLOCK(mp_mutex); | ||
1549 | return state; | ||
1550 | } | ||
1551 | |||
1552 | static int mp_open(struct tty_struct *tty, struct file *filp) | ||
1553 | { | ||
1554 | struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; | ||
1555 | struct sb_uart_state *state; | ||
1556 | int retval; | ||
1557 | int line = tty->index; | ||
1558 | struct mp_port *mtpt; | ||
1559 | |||
1560 | retval = -ENODEV; | ||
1561 | if (line >= tty->driver->num) | ||
1562 | goto fail; | ||
1563 | |||
1564 | state = uart_get(drv, line); | ||
1565 | |||
1566 | mtpt = (struct mp_port *)state->port; | ||
1567 | |||
1568 | if (IS_ERR(state)) { | ||
1569 | retval = PTR_ERR(state); | ||
1570 | goto fail; | ||
1571 | } | ||
1572 | |||
1573 | tty->driver_data = state; | ||
1574 | tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
1575 | tty->alt_speed = 0; | ||
1576 | state->info->tty = tty; | ||
1577 | |||
1578 | if (tty_hung_up_p(filp)) { | ||
1579 | retval = -EAGAIN; | ||
1580 | state->count--; | ||
1581 | MP_STATE_UNLOCK(state); | ||
1582 | goto fail; | ||
1583 | } | ||
1584 | |||
1585 | if (state->count == 1) | ||
1586 | mp_change_pm(state, 0); | ||
1587 | |||
1588 | retval = mp_startup(state, 0); | ||
1589 | |||
1590 | if (retval == 0) | ||
1591 | retval = mp_block_til_ready(filp, state); | ||
1592 | MP_STATE_UNLOCK(state); | ||
1593 | |||
1594 | if (retval == 0 && !(state->info->flags & UIF_NORMAL_ACTIVE)) { | ||
1595 | state->info->flags |= UIF_NORMAL_ACTIVE; | ||
1596 | |||
1597 | mp_update_termios(state); | ||
1598 | } | ||
1599 | |||
1600 | uart_clear_mctrl(state->port, TIOCM_RTS); | ||
1601 | try_module_get(THIS_MODULE); | ||
1602 | fail: | ||
1603 | return retval; | ||
1604 | } | ||
1605 | |||
1606 | |||
1607 | static const char *mp_type(struct sb_uart_port *port) | ||
1608 | { | ||
1609 | const char *str = NULL; | ||
1610 | |||
1611 | if (port->ops->type) | ||
1612 | str = port->ops->type(port); | ||
1613 | |||
1614 | if (!str) | ||
1615 | str = "unknown"; | ||
1616 | |||
1617 | return str; | ||
1618 | } | ||
1619 | |||
1620 | static void mp_change_pm(struct sb_uart_state *state, int pm_state) | ||
1621 | { | ||
1622 | struct sb_uart_port *port = state->port; | ||
1623 | if (port->ops->pm) | ||
1624 | port->ops->pm(port, pm_state, state->pm_state); | ||
1625 | state->pm_state = pm_state; | ||
1626 | } | ||
1627 | |||
1628 | static inline void mp_report_port(struct uart_driver *drv, struct sb_uart_port *port) | ||
1629 | { | ||
1630 | char address[64]; | ||
1631 | |||
1632 | switch (port->iotype) { | ||
1633 | case UPIO_PORT: | ||
1634 | snprintf(address, sizeof(address),"I/O 0x%x", port->iobase); | ||
1635 | break; | ||
1636 | case UPIO_HUB6: | ||
1637 | snprintf(address, sizeof(address),"I/O 0x%x offset 0x%x", port->iobase, port->hub6); | ||
1638 | break; | ||
1639 | case UPIO_MEM: | ||
1640 | snprintf(address, sizeof(address),"MMIO 0x%lx", port->mapbase); | ||
1641 | break; | ||
1642 | default: | ||
1643 | snprintf(address, sizeof(address),"*unknown*" ); | ||
1644 | strlcpy(address, "*unknown*", sizeof(address)); | ||
1645 | break; | ||
1646 | } | ||
1647 | |||
1648 | printk( "%s%d at %s (irq = %d) is a %s\n", | ||
1649 | drv->dev_name, port->line, address, port->irq, mp_type(port)); | ||
1650 | |||
1651 | } | ||
1652 | |||
1653 | static void mp_configure_port(struct uart_driver *drv, struct sb_uart_state *state, struct sb_uart_port *port) | ||
1654 | { | ||
1655 | unsigned int flags; | ||
1656 | |||
1657 | |||
1658 | if (!port->iobase && !port->mapbase && !port->membase) | ||
1659 | { | ||
1660 | DPRINTK("%s error \n",__FUNCTION__); | ||
1661 | return; | ||
1662 | } | ||
1663 | flags = UART_CONFIG_TYPE; | ||
1664 | if (port->flags & UPF_AUTO_IRQ) | ||
1665 | flags |= UART_CONFIG_IRQ; | ||
1666 | if (port->flags & UPF_BOOT_AUTOCONF) { | ||
1667 | port->type = PORT_UNKNOWN; | ||
1668 | port->ops->config_port(port, flags); | ||
1669 | } | ||
1670 | |||
1671 | if (port->type != PORT_UNKNOWN) { | ||
1672 | unsigned long flags; | ||
1673 | |||
1674 | mp_report_port(drv, port); | ||
1675 | |||
1676 | spin_lock_irqsave(&port->lock, flags); | ||
1677 | port->ops->set_mctrl(port, 0); | ||
1678 | spin_unlock_irqrestore(&port->lock, flags); | ||
1679 | |||
1680 | mp_change_pm(state, 3); | ||
1681 | } | ||
1682 | } | ||
1683 | |||
1684 | static void mp_unconfigure_port(struct uart_driver *drv, struct sb_uart_state *state) | ||
1685 | { | ||
1686 | struct sb_uart_port *port = state->port; | ||
1687 | struct sb_uart_info *info = state->info; | ||
1688 | |||
1689 | if (info && info->tty) | ||
1690 | tty_hangup(info->tty); | ||
1691 | |||
1692 | MP_STATE_LOCK(state); | ||
1693 | |||
1694 | state->info = NULL; | ||
1695 | |||
1696 | if (port->type != PORT_UNKNOWN) | ||
1697 | port->ops->release_port(port); | ||
1698 | |||
1699 | port->type = PORT_UNKNOWN; | ||
1700 | |||
1701 | if (info) { | ||
1702 | tasklet_kill(&info->tlet); | ||
1703 | kfree(info); | ||
1704 | } | ||
1705 | |||
1706 | MP_STATE_UNLOCK(state); | ||
1707 | } | ||
1708 | static struct tty_operations mp_ops = { | ||
1709 | .open = mp_open, | ||
1710 | .close = mp_close, | ||
1711 | .write = mp_write, | ||
1712 | .put_char = mp_put_char, | ||
1713 | .flush_chars = mp_put_chars, | ||
1714 | .write_room = mp_write_room, | ||
1715 | .chars_in_buffer= mp_chars_in_buffer, | ||
1716 | .flush_buffer = mp_flush_buffer, | ||
1717 | .ioctl = mp_ioctl, | ||
1718 | .throttle = mp_throttle, | ||
1719 | .unthrottle = mp_unthrottle, | ||
1720 | .send_xchar = mp_send_xchar, | ||
1721 | .set_termios = mp_set_termios, | ||
1722 | .stop = mp_stop, | ||
1723 | .start = mp_start, | ||
1724 | .hangup = mp_hangup, | ||
1725 | .break_ctl = mp_break_ctl, | ||
1726 | .wait_until_sent= mp_wait_until_sent, | ||
1727 | #ifdef CONFIG_PROC_FS | ||
1728 | .proc_fops = NULL, | ||
1729 | #endif | ||
1730 | .tiocmget = mp_tiocmget, | ||
1731 | .tiocmset = mp_tiocmset, | ||
1732 | }; | ||
1733 | |||
1734 | static int mp_register_driver(struct uart_driver *drv) | ||
1735 | { | ||
1736 | struct tty_driver *normal = NULL; | ||
1737 | int i, retval; | ||
1738 | |||
1739 | drv->state = kmalloc(sizeof(struct sb_uart_state) * drv->nr, GFP_KERNEL); | ||
1740 | retval = -ENOMEM; | ||
1741 | if (!drv->state) | ||
1742 | { | ||
1743 | printk("SB PCI Error: Kernel memory allocation error!\n"); | ||
1744 | goto out; | ||
1745 | } | ||
1746 | memset(drv->state, 0, sizeof(struct sb_uart_state) * drv->nr); | ||
1747 | |||
1748 | normal = alloc_tty_driver(drv->nr); | ||
1749 | if (!normal) | ||
1750 | { | ||
1751 | printk("SB PCI Error: tty allocation error!\n"); | ||
1752 | goto out; | ||
1753 | } | ||
1754 | |||
1755 | drv->tty_driver = normal; | ||
1756 | |||
1757 | normal->owner = drv->owner; | ||
1758 | normal->magic = TTY_DRIVER_MAGIC; | ||
1759 | normal->driver_name = drv->driver_name; | ||
1760 | normal->name = drv->dev_name; | ||
1761 | normal->major = drv->major; | ||
1762 | normal->minor_start = drv->minor; | ||
1763 | |||
1764 | normal->num = MAX_MP_PORT ; | ||
1765 | |||
1766 | normal->type = TTY_DRIVER_TYPE_SERIAL; | ||
1767 | normal->subtype = SERIAL_TYPE_NORMAL; | ||
1768 | normal->init_termios = tty_std_termios; | ||
1769 | normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
1770 | normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
1771 | normal->driver_state = drv; | ||
1772 | |||
1773 | tty_set_operations(normal, &mp_ops); | ||
1774 | |||
1775 | for (i = 0; i < drv->nr; i++) { | ||
1776 | struct sb_uart_state *state = drv->state + i; | ||
1777 | |||
1778 | state->close_delay = 500; | ||
1779 | state->closing_wait = 30000; | ||
1780 | |||
1781 | mutex_init(&state->mutex); | ||
1782 | } | ||
1783 | |||
1784 | retval = tty_register_driver(normal); | ||
1785 | out: | ||
1786 | if (retval < 0) { | ||
1787 | printk("Register tty driver Fail!\n"); | ||
1788 | put_tty_driver(normal); | ||
1789 | kfree(drv->state); | ||
1790 | } | ||
1791 | |||
1792 | return retval; | ||
1793 | } | ||
1794 | |||
1795 | void mp_unregister_driver(struct uart_driver *drv) | ||
1796 | { | ||
1797 | struct tty_driver *normal = NULL; | ||
1798 | |||
1799 | normal = drv->tty_driver; | ||
1800 | |||
1801 | if (!normal) | ||
1802 | { | ||
1803 | return; | ||
1804 | } | ||
1805 | |||
1806 | tty_unregister_driver(normal); | ||
1807 | put_tty_driver(normal); | ||
1808 | drv->tty_driver = NULL; | ||
1809 | |||
1810 | |||
1811 | if (drv->state) | ||
1812 | { | ||
1813 | kfree(drv->state); | ||
1814 | } | ||
1815 | |||
1816 | } | ||
1817 | |||
1818 | static int mp_add_one_port(struct uart_driver *drv, struct sb_uart_port *port) | ||
1819 | { | ||
1820 | struct sb_uart_state *state; | ||
1821 | int ret = 0; | ||
1822 | |||
1823 | |||
1824 | if (port->line >= drv->nr) | ||
1825 | return -EINVAL; | ||
1826 | |||
1827 | state = drv->state + port->line; | ||
1828 | |||
1829 | MP_MUTEX_LOCK(mp_mutex); | ||
1830 | if (state->port) { | ||
1831 | ret = -EINVAL; | ||
1832 | goto out; | ||
1833 | } | ||
1834 | |||
1835 | state->port = port; | ||
1836 | |||
1837 | spin_lock_init(&port->lock); | ||
1838 | port->cons = drv->cons; | ||
1839 | port->info = state->info; | ||
1840 | |||
1841 | mp_configure_port(drv, state, port); | ||
1842 | |||
1843 | tty_register_device(drv->tty_driver, port->line, port->dev); | ||
1844 | |||
1845 | out: | ||
1846 | MP_MUTEX_UNLOCK(mp_mutex); | ||
1847 | |||
1848 | |||
1849 | return ret; | ||
1850 | } | ||
1851 | |||
1852 | static int mp_remove_one_port(struct uart_driver *drv, struct sb_uart_port *port) | ||
1853 | { | ||
1854 | struct sb_uart_state *state = drv->state + port->line; | ||
1855 | |||
1856 | if (state->port != port) | ||
1857 | printk(KERN_ALERT "Removing wrong port: %p != %p\n", | ||
1858 | state->port, port); | ||
1859 | |||
1860 | MP_MUTEX_LOCK(mp_mutex); | ||
1861 | |||
1862 | tty_unregister_device(drv->tty_driver, port->line); | ||
1863 | |||
1864 | mp_unconfigure_port(drv, state); | ||
1865 | state->port = NULL; | ||
1866 | MP_MUTEX_UNLOCK(mp_mutex); | ||
1867 | |||
1868 | return 0; | ||
1869 | } | ||
1870 | |||
1871 | static void autoconfig(struct mp_port *mtpt, unsigned int probeflags) | ||
1872 | { | ||
1873 | unsigned char status1, scratch, scratch2, scratch3; | ||
1874 | unsigned char save_lcr, save_mcr; | ||
1875 | unsigned long flags; | ||
1876 | |||
1877 | unsigned char u_type; | ||
1878 | unsigned char b_ret = 0; | ||
1879 | |||
1880 | if (!mtpt->port.iobase && !mtpt->port.mapbase && !mtpt->port.membase) | ||
1881 | return; | ||
1882 | |||
1883 | DEBUG_AUTOCONF("ttyMP%d: autoconf (0x%04x, 0x%p): ", | ||
1884 | mtpt->port.line, mtpt->port.iobase, mtpt->port.membase); | ||
1885 | |||
1886 | spin_lock_irqsave(&mtpt->port.lock, flags); | ||
1887 | |||
1888 | if (!(mtpt->port.flags & UPF_BUGGY_UART)) { | ||
1889 | scratch = serial_inp(mtpt, UART_IER); | ||
1890 | serial_outp(mtpt, UART_IER, 0); | ||
1891 | #ifdef __i386__ | ||
1892 | outb(0xff, 0x080); | ||
1893 | #endif | ||
1894 | scratch2 = serial_inp(mtpt, UART_IER) & 0x0f; | ||
1895 | serial_outp(mtpt, UART_IER, 0x0F); | ||
1896 | #ifdef __i386__ | ||
1897 | outb(0, 0x080); | ||
1898 | #endif | ||
1899 | scratch3 = serial_inp(mtpt, UART_IER) & 0x0F; | ||
1900 | serial_outp(mtpt, UART_IER, scratch); | ||
1901 | if (scratch2 != 0 || scratch3 != 0x0F) { | ||
1902 | DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", | ||
1903 | scratch2, scratch3); | ||
1904 | goto out; | ||
1905 | } | ||
1906 | } | ||
1907 | |||
1908 | save_mcr = serial_in(mtpt, UART_MCR); | ||
1909 | save_lcr = serial_in(mtpt, UART_LCR); | ||
1910 | |||
1911 | if (!(mtpt->port.flags & UPF_SKIP_TEST)) { | ||
1912 | serial_outp(mtpt, UART_MCR, UART_MCR_LOOP | 0x0A); | ||
1913 | status1 = serial_inp(mtpt, UART_MSR) & 0xF0; | ||
1914 | serial_outp(mtpt, UART_MCR, save_mcr); | ||
1915 | if (status1 != 0x90) { | ||
1916 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", | ||
1917 | status1); | ||
1918 | goto out; | ||
1919 | } | ||
1920 | } | ||
1921 | |||
1922 | serial_outp(mtpt, UART_LCR, 0xBF); | ||
1923 | serial_outp(mtpt, UART_EFR, 0); | ||
1924 | serial_outp(mtpt, UART_LCR, 0); | ||
1925 | |||
1926 | serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO); | ||
1927 | scratch = serial_in(mtpt, UART_IIR) >> 6; | ||
1928 | |||
1929 | DEBUG_AUTOCONF("iir=%d ", scratch); | ||
1930 | if(mtpt->device->nr_ports >= 8) | ||
1931 | b_ret = read_option_register(mtpt,(MP_OPTR_DIR0 + ((mtpt->port.line)/8))); | ||
1932 | else | ||
1933 | b_ret = read_option_register(mtpt,MP_OPTR_DIR0); | ||
1934 | u_type = (b_ret & 0xf0) >> 4; | ||
1935 | if(mtpt->port.type == PORT_UNKNOWN ) | ||
1936 | { | ||
1937 | switch (u_type) | ||
1938 | { | ||
1939 | case DIR_UART_16C550: | ||
1940 | mtpt->port.type = PORT_16C55X; | ||
1941 | break; | ||
1942 | case DIR_UART_16C1050: | ||
1943 | mtpt->port.type = PORT_16C105X; | ||
1944 | break; | ||
1945 | case DIR_UART_16C1050A: | ||
1946 | if (mtpt->port.line < 2) | ||
1947 | { | ||
1948 | mtpt->port.type = PORT_16C105XA; | ||
1949 | } | ||
1950 | else | ||
1951 | { | ||
1952 | if (mtpt->device->device_id & 0x50) | ||
1953 | { | ||
1954 | mtpt->port.type = PORT_16C55X; | ||
1955 | } | ||
1956 | else | ||
1957 | { | ||
1958 | mtpt->port.type = PORT_16C105X; | ||
1959 | } | ||
1960 | } | ||
1961 | break; | ||
1962 | default: | ||
1963 | mtpt->port.type = PORT_UNKNOWN; | ||
1964 | break; | ||
1965 | } | ||
1966 | } | ||
1967 | |||
1968 | if(mtpt->port.type == PORT_UNKNOWN ) | ||
1969 | { | ||
1970 | printk("unknow2\n"); | ||
1971 | switch (scratch) { | ||
1972 | case 0: | ||
1973 | case 1: | ||
1974 | mtpt->port.type = PORT_UNKNOWN; | ||
1975 | break; | ||
1976 | case 2: | ||
1977 | case 3: | ||
1978 | mtpt->port.type = PORT_16C55X; | ||
1979 | break; | ||
1980 | } | ||
1981 | } | ||
1982 | |||
1983 | serial_outp(mtpt, UART_LCR, save_lcr); | ||
1984 | |||
1985 | mtpt->port.fifosize = uart_config[mtpt->port.type].dfl_xmit_fifo_size; | ||
1986 | mtpt->capabilities = uart_config[mtpt->port.type].flags; | ||
1987 | |||
1988 | if (mtpt->port.type == PORT_UNKNOWN) | ||
1989 | goto out; | ||
1990 | serial_outp(mtpt, UART_MCR, save_mcr); | ||
1991 | serial_outp(mtpt, UART_FCR, (UART_FCR_ENABLE_FIFO | | ||
1992 | UART_FCR_CLEAR_RCVR | | ||
1993 | UART_FCR_CLEAR_XMIT)); | ||
1994 | serial_outp(mtpt, UART_FCR, 0); | ||
1995 | (void)serial_in(mtpt, UART_RX); | ||
1996 | serial_outp(mtpt, UART_IER, 0); | ||
1997 | |||
1998 | out: | ||
1999 | spin_unlock_irqrestore(&mtpt->port.lock, flags); | ||
2000 | DEBUG_AUTOCONF("type=%s\n", uart_config[mtpt->port.type].name); | ||
2001 | } | ||
2002 | |||
2003 | static void autoconfig_irq(struct mp_port *mtpt) | ||
2004 | { | ||
2005 | unsigned char save_mcr, save_ier; | ||
2006 | unsigned long irqs; | ||
2007 | int irq; | ||
2008 | |||
2009 | /* forget possible initially masked and pending IRQ */ | ||
2010 | probe_irq_off(probe_irq_on()); | ||
2011 | save_mcr = serial_inp(mtpt, UART_MCR); | ||
2012 | save_ier = serial_inp(mtpt, UART_IER); | ||
2013 | serial_outp(mtpt, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); | ||
2014 | |||
2015 | irqs = probe_irq_on(); | ||
2016 | serial_outp(mtpt, UART_MCR, 0); | ||
2017 | serial_outp(mtpt, UART_MCR, | ||
2018 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); | ||
2019 | |||
2020 | serial_outp(mtpt, UART_IER, 0x0f); /* enable all intrs */ | ||
2021 | (void)serial_inp(mtpt, UART_LSR); | ||
2022 | (void)serial_inp(mtpt, UART_RX); | ||
2023 | (void)serial_inp(mtpt, UART_IIR); | ||
2024 | (void)serial_inp(mtpt, UART_MSR); | ||
2025 | serial_outp(mtpt, UART_TX, 0xFF); | ||
2026 | irq = probe_irq_off(irqs); | ||
2027 | |||
2028 | serial_outp(mtpt, UART_MCR, save_mcr); | ||
2029 | serial_outp(mtpt, UART_IER, save_ier); | ||
2030 | |||
2031 | mtpt->port.irq = (irq > 0) ? irq : 0; | ||
2032 | } | ||
2033 | |||
2034 | static void multi_stop_tx(struct sb_uart_port *port) | ||
2035 | { | ||
2036 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2037 | |||
2038 | if (mtpt->ier & UART_IER_THRI) { | ||
2039 | mtpt->ier &= ~UART_IER_THRI; | ||
2040 | serial_out(mtpt, UART_IER, mtpt->ier); | ||
2041 | } | ||
2042 | |||
2043 | tasklet_schedule(&port->info->tlet); | ||
2044 | } | ||
2045 | |||
2046 | static void multi_start_tx(struct sb_uart_port *port) | ||
2047 | { | ||
2048 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2049 | |||
2050 | if (!(mtpt->ier & UART_IER_THRI)) { | ||
2051 | mtpt->ier |= UART_IER_THRI; | ||
2052 | serial_out(mtpt, UART_IER, mtpt->ier); | ||
2053 | } | ||
2054 | } | ||
2055 | |||
2056 | static void multi_stop_rx(struct sb_uart_port *port) | ||
2057 | { | ||
2058 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2059 | |||
2060 | mtpt->ier &= ~UART_IER_RLSI; | ||
2061 | mtpt->port.read_status_mask &= ~UART_LSR_DR; | ||
2062 | serial_out(mtpt, UART_IER, mtpt->ier); | ||
2063 | } | ||
2064 | |||
2065 | static void multi_enable_ms(struct sb_uart_port *port) | ||
2066 | { | ||
2067 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2068 | |||
2069 | mtpt->ier |= UART_IER_MSI; | ||
2070 | serial_out(mtpt, UART_IER, mtpt->ier); | ||
2071 | } | ||
2072 | |||
2073 | |||
2074 | static _INLINE_ void receive_chars(struct mp_port *mtpt, int *status ) | ||
2075 | { | ||
2076 | struct tty_struct *tty = mtpt->port.info->tty; | ||
2077 | unsigned char lsr = *status; | ||
2078 | int max_count = 256; | ||
2079 | unsigned char ch; | ||
2080 | char flag; | ||
2081 | |||
2082 | //lsr &= mtpt->port.read_status_mask; | ||
2083 | |||
2084 | do { | ||
2085 | if ((lsr & UART_LSR_PE) && (mtpt->port.mdmode & MDMODE_ENABLE)) | ||
2086 | { | ||
2087 | ch = serial_inp(mtpt, UART_RX); | ||
2088 | } | ||
2089 | else if (lsr & UART_LSR_SPECIAL) | ||
2090 | { | ||
2091 | flag = 0; | ||
2092 | ch = serial_inp(mtpt, UART_RX); | ||
2093 | |||
2094 | if (lsr & UART_LSR_BI) | ||
2095 | { | ||
2096 | |||
2097 | mtpt->port.icount.brk++; | ||
2098 | flag = TTY_BREAK; | ||
2099 | |||
2100 | if (sb_uart_handle_break(&mtpt->port)) | ||
2101 | goto ignore_char; | ||
2102 | } | ||
2103 | if (lsr & UART_LSR_PE) | ||
2104 | { | ||
2105 | mtpt->port.icount.parity++; | ||
2106 | flag = TTY_PARITY; | ||
2107 | } | ||
2108 | if (lsr & UART_LSR_FE) | ||
2109 | { | ||
2110 | mtpt->port.icount.frame++; | ||
2111 | flag = TTY_FRAME; | ||
2112 | } | ||
2113 | if (lsr & UART_LSR_OE) | ||
2114 | { | ||
2115 | mtpt->port.icount.overrun++; | ||
2116 | flag = TTY_OVERRUN; | ||
2117 | } | ||
2118 | tty_insert_flip_char(tty, ch, flag); | ||
2119 | } | ||
2120 | else | ||
2121 | { | ||
2122 | ch = serial_inp(mtpt, UART_RX); | ||
2123 | tty_insert_flip_char(tty, ch, 0); | ||
2124 | } | ||
2125 | ignore_char: | ||
2126 | lsr = serial_inp(mtpt, UART_LSR); | ||
2127 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); | ||
2128 | |||
2129 | tty_flip_buffer_push(tty); | ||
2130 | } | ||
2131 | |||
2132 | |||
2133 | |||
2134 | |||
2135 | static _INLINE_ void transmit_chars(struct mp_port *mtpt) | ||
2136 | { | ||
2137 | struct circ_buf *xmit = &mtpt->port.info->xmit; | ||
2138 | int count; | ||
2139 | |||
2140 | if (mtpt->port.x_char) { | ||
2141 | serial_outp(mtpt, UART_TX, mtpt->port.x_char); | ||
2142 | mtpt->port.icount.tx++; | ||
2143 | mtpt->port.x_char = 0; | ||
2144 | return; | ||
2145 | } | ||
2146 | if (uart_circ_empty(xmit) || uart_tx_stopped(&mtpt->port)) { | ||
2147 | multi_stop_tx(&mtpt->port); | ||
2148 | return; | ||
2149 | } | ||
2150 | |||
2151 | count = uart_circ_chars_pending(xmit); | ||
2152 | |||
2153 | if(count > mtpt->port.fifosize) | ||
2154 | { | ||
2155 | count = mtpt->port.fifosize; | ||
2156 | } | ||
2157 | |||
2158 | printk("[%d] mdmode: %x\n", mtpt->port.line, mtpt->port.mdmode); | ||
2159 | do { | ||
2160 | #if 0 | ||
2161 | /* check multi-drop mode */ | ||
2162 | if ((mtpt->port.mdmode & (MDMODE_ENABLE | MDMODE_ADDR)) == (MDMODE_ENABLE | MDMODE_ADDR)) | ||
2163 | { | ||
2164 | printk("send address\n"); | ||
2165 | /* send multi-drop address */ | ||
2166 | serial_out(mtpt, UART_SCR, xmit->buf[xmit->tail]); | ||
2167 | } | ||
2168 | else | ||
2169 | #endif | ||
2170 | { | ||
2171 | serial_out(mtpt, UART_TX, xmit->buf[xmit->tail]); | ||
2172 | } | ||
2173 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
2174 | mtpt->port.icount.tx++; | ||
2175 | } while (--count > 0); | ||
2176 | } | ||
2177 | |||
2178 | |||
2179 | |||
2180 | static _INLINE_ void check_modem_status(struct mp_port *mtpt) | ||
2181 | { | ||
2182 | int status; | ||
2183 | |||
2184 | status = serial_in(mtpt, UART_MSR); | ||
2185 | |||
2186 | if ((status & UART_MSR_ANY_DELTA) == 0) | ||
2187 | return; | ||
2188 | |||
2189 | if (status & UART_MSR_TERI) | ||
2190 | mtpt->port.icount.rng++; | ||
2191 | if (status & UART_MSR_DDSR) | ||
2192 | mtpt->port.icount.dsr++; | ||
2193 | if (status & UART_MSR_DDCD) | ||
2194 | sb_uart_handle_dcd_change(&mtpt->port, status & UART_MSR_DCD); | ||
2195 | if (status & UART_MSR_DCTS) | ||
2196 | sb_uart_handle_cts_change(&mtpt->port, status & UART_MSR_CTS); | ||
2197 | |||
2198 | wake_up_interruptible(&mtpt->port.info->delta_msr_wait); | ||
2199 | } | ||
2200 | |||
2201 | static inline void multi_handle_port(struct mp_port *mtpt) | ||
2202 | { | ||
2203 | unsigned int status = serial_inp(mtpt, UART_LSR); | ||
2204 | |||
2205 | //printk("lsr: %x\n", status); | ||
2206 | |||
2207 | if ((status & UART_LSR_DR) || (status & UART_LSR_SPECIAL)) | ||
2208 | receive_chars(mtpt, &status); | ||
2209 | check_modem_status(mtpt); | ||
2210 | if (status & UART_LSR_THRE) | ||
2211 | { | ||
2212 | if ((mtpt->port.type == PORT_16C105X) | ||
2213 | || (mtpt->port.type == PORT_16C105XA)) | ||
2214 | transmit_chars(mtpt); | ||
2215 | else | ||
2216 | { | ||
2217 | if (mtpt->interface >= RS485NE) | ||
2218 | uart_set_mctrl(&mtpt->port, TIOCM_RTS); | ||
2219 | |||
2220 | transmit_chars(mtpt); | ||
2221 | |||
2222 | |||
2223 | if (mtpt->interface >= RS485NE) | ||
2224 | { | ||
2225 | while((status=serial_in(mtpt,UART_LSR) &0x60)!=0x60); | ||
2226 | uart_clear_mctrl(&mtpt->port, TIOCM_RTS); | ||
2227 | } | ||
2228 | } | ||
2229 | } | ||
2230 | } | ||
2231 | |||
2232 | |||
2233 | |||
2234 | static irqreturn_t multi_interrupt(int irq, void *dev_id) | ||
2235 | { | ||
2236 | struct irq_info *iinfo = dev_id; | ||
2237 | struct list_head *lhead, *end = NULL; | ||
2238 | int pass_counter = 0; | ||
2239 | |||
2240 | |||
2241 | spin_lock(&iinfo->lock); | ||
2242 | |||
2243 | lhead = iinfo->head; | ||
2244 | do { | ||
2245 | struct mp_port *mtpt; | ||
2246 | unsigned int iir; | ||
2247 | |||
2248 | mtpt = list_entry(lhead, struct mp_port, list); | ||
2249 | |||
2250 | iir = serial_in(mtpt, UART_IIR); | ||
2251 | printk("intrrupt! port %d, iir 0x%x\n", mtpt->port.line, iir); //wlee | ||
2252 | if (!(iir & UART_IIR_NO_INT)) | ||
2253 | { | ||
2254 | printk("interrupt handle\n"); | ||
2255 | spin_lock(&mtpt->port.lock); | ||
2256 | multi_handle_port(mtpt); | ||
2257 | spin_unlock(&mtpt->port.lock); | ||
2258 | |||
2259 | end = NULL; | ||
2260 | } else if (end == NULL) | ||
2261 | end = lhead; | ||
2262 | |||
2263 | lhead = lhead->next; | ||
2264 | if (lhead == iinfo->head && pass_counter++ > PASS_LIMIT) | ||
2265 | { | ||
2266 | printk(KERN_ERR "multi: too much work for " | ||
2267 | "irq%d\n", irq); | ||
2268 | printk( "multi: too much work for " | ||
2269 | "irq%d\n", irq); | ||
2270 | break; | ||
2271 | } | ||
2272 | } while (lhead != end); | ||
2273 | |||
2274 | spin_unlock(&iinfo->lock); | ||
2275 | |||
2276 | |||
2277 | return IRQ_HANDLED; | ||
2278 | } | ||
2279 | |||
2280 | static void serial_do_unlink(struct irq_info *i, struct mp_port *mtpt) | ||
2281 | { | ||
2282 | spin_lock_irq(&i->lock); | ||
2283 | |||
2284 | if (!list_empty(i->head)) { | ||
2285 | if (i->head == &mtpt->list) | ||
2286 | i->head = i->head->next; | ||
2287 | list_del(&mtpt->list); | ||
2288 | } else { | ||
2289 | i->head = NULL; | ||
2290 | } | ||
2291 | |||
2292 | spin_unlock_irq(&i->lock); | ||
2293 | } | ||
2294 | |||
2295 | static int serial_link_irq_chain(struct mp_port *mtpt) | ||
2296 | { | ||
2297 | struct irq_info *i = irq_lists + mtpt->port.irq; | ||
2298 | int ret, irq_flags = mtpt->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; | ||
2299 | spin_lock_irq(&i->lock); | ||
2300 | |||
2301 | if (i->head) { | ||
2302 | list_add(&mtpt->list, i->head); | ||
2303 | spin_unlock_irq(&i->lock); | ||
2304 | |||
2305 | ret = 0; | ||
2306 | } else { | ||
2307 | INIT_LIST_HEAD(&mtpt->list); | ||
2308 | i->head = &mtpt->list; | ||
2309 | spin_unlock_irq(&i->lock); | ||
2310 | |||
2311 | ret = request_irq(mtpt->port.irq, multi_interrupt, | ||
2312 | irq_flags, "serial", i); | ||
2313 | if (ret < 0) | ||
2314 | serial_do_unlink(i, mtpt); | ||
2315 | } | ||
2316 | |||
2317 | return ret; | ||
2318 | } | ||
2319 | |||
2320 | |||
2321 | |||
2322 | |||
2323 | static void serial_unlink_irq_chain(struct mp_port *mtpt) | ||
2324 | { | ||
2325 | struct irq_info *i = irq_lists + mtpt->port.irq; | ||
2326 | |||
2327 | if (list_empty(i->head)) | ||
2328 | { | ||
2329 | free_irq(mtpt->port.irq, i); | ||
2330 | } | ||
2331 | serial_do_unlink(i, mtpt); | ||
2332 | } | ||
2333 | |||
2334 | static void multi_timeout(unsigned long data) | ||
2335 | { | ||
2336 | struct mp_port *mtpt = (struct mp_port *)data; | ||
2337 | |||
2338 | |||
2339 | spin_lock(&mtpt->port.lock); | ||
2340 | multi_handle_port(mtpt); | ||
2341 | spin_unlock(&mtpt->port.lock); | ||
2342 | |||
2343 | mod_timer(&mtpt->timer, jiffies+1 ); | ||
2344 | } | ||
2345 | |||
2346 | static unsigned int multi_tx_empty(struct sb_uart_port *port) | ||
2347 | { | ||
2348 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2349 | unsigned long flags; | ||
2350 | unsigned int ret; | ||
2351 | |||
2352 | spin_lock_irqsave(&mtpt->port.lock, flags); | ||
2353 | ret = serial_in(mtpt, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | ||
2354 | spin_unlock_irqrestore(&mtpt->port.lock, flags); | ||
2355 | |||
2356 | return ret; | ||
2357 | } | ||
2358 | |||
2359 | |||
2360 | static unsigned int multi_get_mctrl(struct sb_uart_port *port) | ||
2361 | { | ||
2362 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2363 | unsigned char status; | ||
2364 | unsigned int ret; | ||
2365 | |||
2366 | status = serial_in(mtpt, UART_MSR); | ||
2367 | |||
2368 | ret = 0; | ||
2369 | if (status & UART_MSR_DCD) | ||
2370 | ret |= TIOCM_CAR; | ||
2371 | if (status & UART_MSR_RI) | ||
2372 | ret |= TIOCM_RNG; | ||
2373 | if (status & UART_MSR_DSR) | ||
2374 | ret |= TIOCM_DSR; | ||
2375 | if (status & UART_MSR_CTS) | ||
2376 | ret |= TIOCM_CTS; | ||
2377 | return ret; | ||
2378 | } | ||
2379 | |||
2380 | static void multi_set_mctrl(struct sb_uart_port *port, unsigned int mctrl) | ||
2381 | { | ||
2382 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2383 | unsigned char mcr = 0; | ||
2384 | |||
2385 | mctrl &= 0xff; | ||
2386 | |||
2387 | if (mctrl & TIOCM_RTS) | ||
2388 | mcr |= UART_MCR_RTS; | ||
2389 | if (mctrl & TIOCM_DTR) | ||
2390 | mcr |= UART_MCR_DTR; | ||
2391 | if (mctrl & TIOCM_OUT1) | ||
2392 | mcr |= UART_MCR_OUT1; | ||
2393 | if (mctrl & TIOCM_OUT2) | ||
2394 | mcr |= UART_MCR_OUT2; | ||
2395 | if (mctrl & TIOCM_LOOP) | ||
2396 | mcr |= UART_MCR_LOOP; | ||
2397 | |||
2398 | |||
2399 | serial_out(mtpt, UART_MCR, mcr); | ||
2400 | } | ||
2401 | |||
2402 | |||
2403 | static void multi_break_ctl(struct sb_uart_port *port, int break_state) | ||
2404 | { | ||
2405 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2406 | unsigned long flags; | ||
2407 | |||
2408 | spin_lock_irqsave(&mtpt->port.lock, flags); | ||
2409 | if (break_state == -1) | ||
2410 | mtpt->lcr |= UART_LCR_SBC; | ||
2411 | else | ||
2412 | mtpt->lcr &= ~UART_LCR_SBC; | ||
2413 | serial_out(mtpt, UART_LCR, mtpt->lcr); | ||
2414 | spin_unlock_irqrestore(&mtpt->port.lock, flags); | ||
2415 | } | ||
2416 | |||
2417 | |||
2418 | |||
2419 | static int multi_startup(struct sb_uart_port *port) | ||
2420 | { | ||
2421 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2422 | unsigned long flags; | ||
2423 | int retval; | ||
2424 | |||
2425 | mtpt->capabilities = uart_config[mtpt->port.type].flags; | ||
2426 | mtpt->mcr = 0; | ||
2427 | |||
2428 | if (mtpt->capabilities & UART_CLEAR_FIFO) { | ||
2429 | serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO); | ||
2430 | serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
2431 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
2432 | serial_outp(mtpt, UART_FCR, 0); | ||
2433 | } | ||
2434 | |||
2435 | (void) serial_inp(mtpt, UART_LSR); | ||
2436 | (void) serial_inp(mtpt, UART_RX); | ||
2437 | (void) serial_inp(mtpt, UART_IIR); | ||
2438 | (void) serial_inp(mtpt, UART_MSR); | ||
2439 | //test-wlee 9-bit disable | ||
2440 | serial_outp(mtpt, UART_MSR, 0); | ||
2441 | |||
2442 | |||
2443 | if (!(mtpt->port.flags & UPF_BUGGY_UART) && | ||
2444 | (serial_inp(mtpt, UART_LSR) == 0xff)) { | ||
2445 | printk("ttyS%d: LSR safety check engaged!\n", mtpt->port.line); | ||
2446 | //return -ENODEV; | ||
2447 | } | ||
2448 | |||
2449 | if ((!is_real_interrupt(mtpt->port.irq)) || (mtpt->poll_type==TYPE_POLL)) { | ||
2450 | unsigned int timeout = mtpt->port.timeout; | ||
2451 | |||
2452 | timeout = timeout > 6 ? (timeout / 2 - 2) : 1; | ||
2453 | |||
2454 | mtpt->timer.data = (unsigned long)mtpt; | ||
2455 | mod_timer(&mtpt->timer, jiffies + timeout); | ||
2456 | } | ||
2457 | else | ||
2458 | { | ||
2459 | retval = serial_link_irq_chain(mtpt); | ||
2460 | if (retval) | ||
2461 | return retval; | ||
2462 | } | ||
2463 | |||
2464 | serial_outp(mtpt, UART_LCR, UART_LCR_WLEN8); | ||
2465 | |||
2466 | spin_lock_irqsave(&mtpt->port.lock, flags); | ||
2467 | if ((is_real_interrupt(mtpt->port.irq))||(mtpt->poll_type==TYPE_INTERRUPT)) | ||
2468 | mtpt->port.mctrl |= TIOCM_OUT2; | ||
2469 | |||
2470 | multi_set_mctrl(&mtpt->port, mtpt->port.mctrl); | ||
2471 | spin_unlock_irqrestore(&mtpt->port.lock, flags); | ||
2472 | |||
2473 | |||
2474 | mtpt->ier = UART_IER_RLSI | UART_IER_RDI; | ||
2475 | serial_outp(mtpt, UART_IER, mtpt->ier); | ||
2476 | |||
2477 | (void) serial_inp(mtpt, UART_LSR); | ||
2478 | (void) serial_inp(mtpt, UART_RX); | ||
2479 | (void) serial_inp(mtpt, UART_IIR); | ||
2480 | (void) serial_inp(mtpt, UART_MSR); | ||
2481 | |||
2482 | return 0; | ||
2483 | } | ||
2484 | |||
2485 | |||
2486 | |||
2487 | static void multi_shutdown(struct sb_uart_port *port) | ||
2488 | { | ||
2489 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2490 | unsigned long flags; | ||
2491 | |||
2492 | |||
2493 | mtpt->ier = 0; | ||
2494 | serial_outp(mtpt, UART_IER, 0); | ||
2495 | |||
2496 | spin_lock_irqsave(&mtpt->port.lock, flags); | ||
2497 | mtpt->port.mctrl &= ~TIOCM_OUT2; | ||
2498 | |||
2499 | multi_set_mctrl(&mtpt->port, mtpt->port.mctrl); | ||
2500 | spin_unlock_irqrestore(&mtpt->port.lock, flags); | ||
2501 | |||
2502 | serial_out(mtpt, UART_LCR, serial_inp(mtpt, UART_LCR) & ~UART_LCR_SBC); | ||
2503 | serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
2504 | UART_FCR_CLEAR_RCVR | | ||
2505 | UART_FCR_CLEAR_XMIT); | ||
2506 | serial_outp(mtpt, UART_FCR, 0); | ||
2507 | |||
2508 | |||
2509 | (void) serial_in(mtpt, UART_RX); | ||
2510 | |||
2511 | if ((!is_real_interrupt(mtpt->port.irq))||(mtpt->poll_type==TYPE_POLL)) | ||
2512 | { | ||
2513 | del_timer_sync(&mtpt->timer); | ||
2514 | } | ||
2515 | else | ||
2516 | { | ||
2517 | serial_unlink_irq_chain(mtpt); | ||
2518 | } | ||
2519 | } | ||
2520 | |||
2521 | |||
2522 | |||
2523 | static unsigned int multi_get_divisor(struct sb_uart_port *port, unsigned int baud) | ||
2524 | { | ||
2525 | unsigned int quot; | ||
2526 | |||
2527 | if ((port->flags & UPF_MAGIC_MULTIPLIER) && | ||
2528 | baud == (port->uartclk/4)) | ||
2529 | quot = 0x8001; | ||
2530 | else if ((port->flags & UPF_MAGIC_MULTIPLIER) && | ||
2531 | baud == (port->uartclk/8)) | ||
2532 | quot = 0x8002; | ||
2533 | else | ||
2534 | quot = sb_uart_get_divisor(port, baud); | ||
2535 | |||
2536 | return quot; | ||
2537 | } | ||
2538 | |||
2539 | |||
2540 | |||
2541 | |||
2542 | static void multi_set_termios(struct sb_uart_port *port, struct MP_TERMIOS *termios, struct MP_TERMIOS *old) | ||
2543 | { | ||
2544 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2545 | unsigned char cval, fcr = 0; | ||
2546 | unsigned long flags; | ||
2547 | unsigned int baud, quot; | ||
2548 | |||
2549 | switch (termios->c_cflag & CSIZE) { | ||
2550 | case CS5: | ||
2551 | cval = 0x00; | ||
2552 | break; | ||
2553 | case CS6: | ||
2554 | cval = 0x01; | ||
2555 | break; | ||
2556 | case CS7: | ||
2557 | cval = 0x02; | ||
2558 | break; | ||
2559 | default: | ||
2560 | case CS8: | ||
2561 | cval = 0x03; | ||
2562 | break; | ||
2563 | } | ||
2564 | |||
2565 | if (termios->c_cflag & CSTOPB) | ||
2566 | cval |= 0x04; | ||
2567 | if (termios->c_cflag & PARENB) | ||
2568 | cval |= UART_LCR_PARITY; | ||
2569 | if (!(termios->c_cflag & PARODD)) | ||
2570 | cval |= UART_LCR_EPAR; | ||
2571 | |||
2572 | #ifdef CMSPAR | ||
2573 | if (termios->c_cflag & CMSPAR) | ||
2574 | cval |= UART_LCR_SPAR; | ||
2575 | #endif | ||
2576 | |||
2577 | baud = sb_uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | ||
2578 | quot = multi_get_divisor(port, baud); | ||
2579 | |||
2580 | if (mtpt->capabilities & UART_USE_FIFO) { | ||
2581 | //if (baud < 2400) | ||
2582 | // fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; | ||
2583 | //else | ||
2584 | // fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; | ||
2585 | |||
2586 | // fcr = UART_FCR_ENABLE_FIFO | 0x90; | ||
2587 | fcr = fcr_arr[mtpt->port.line]; | ||
2588 | } | ||
2589 | |||
2590 | spin_lock_irqsave(&mtpt->port.lock, flags); | ||
2591 | |||
2592 | sb_uart_update_timeout(port, termios->c_cflag, baud); | ||
2593 | |||
2594 | mtpt->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | ||
2595 | if (termios->c_iflag & INPCK) | ||
2596 | mtpt->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; | ||
2597 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
2598 | mtpt->port.read_status_mask |= UART_LSR_BI; | ||
2599 | |||
2600 | mtpt->port.ignore_status_mask = 0; | ||
2601 | if (termios->c_iflag & IGNPAR) | ||
2602 | mtpt->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | ||
2603 | if (termios->c_iflag & IGNBRK) { | ||
2604 | mtpt->port.ignore_status_mask |= UART_LSR_BI; | ||
2605 | if (termios->c_iflag & IGNPAR) | ||
2606 | mtpt->port.ignore_status_mask |= UART_LSR_OE; | ||
2607 | } | ||
2608 | |||
2609 | if ((termios->c_cflag & CREAD) == 0) | ||
2610 | mtpt->port.ignore_status_mask |= UART_LSR_DR; | ||
2611 | |||
2612 | mtpt->ier &= ~UART_IER_MSI; | ||
2613 | if (UART_ENABLE_MS(&mtpt->port, termios->c_cflag)) | ||
2614 | mtpt->ier |= UART_IER_MSI; | ||
2615 | |||
2616 | serial_out(mtpt, UART_IER, mtpt->ier); | ||
2617 | |||
2618 | if (mtpt->capabilities & UART_STARTECH) { | ||
2619 | serial_outp(mtpt, UART_LCR, 0xBF); | ||
2620 | serial_outp(mtpt, UART_EFR, | ||
2621 | termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0); | ||
2622 | } | ||
2623 | |||
2624 | serial_outp(mtpt, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ | ||
2625 | |||
2626 | serial_outp(mtpt, UART_DLL, quot & 0xff); /* LS of divisor */ | ||
2627 | serial_outp(mtpt, UART_DLM, quot >> 8); /* MS of divisor */ | ||
2628 | |||
2629 | serial_outp(mtpt, UART_LCR, cval); /* reset DLAB */ | ||
2630 | mtpt->lcr = cval; /* Save LCR */ | ||
2631 | |||
2632 | if (fcr & UART_FCR_ENABLE_FIFO) { | ||
2633 | /* emulated UARTs (Lucent Venus 167x) need two steps */ | ||
2634 | serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO); | ||
2635 | } | ||
2636 | |||
2637 | serial_outp(mtpt, UART_FCR, fcr); /* set fcr */ | ||
2638 | |||
2639 | |||
2640 | if ((mtpt->port.type == PORT_16C105X) | ||
2641 | || (mtpt->port.type == PORT_16C105XA)) | ||
2642 | { | ||
2643 | if(deep[mtpt->port.line]!=0) | ||
2644 | set_deep_fifo(port, ENABLE); | ||
2645 | |||
2646 | if (mtpt->interface != RS232) | ||
2647 | set_auto_rts(port,mtpt->interface); | ||
2648 | |||
2649 | } | ||
2650 | else | ||
2651 | { | ||
2652 | if (mtpt->interface >= RS485NE) | ||
2653 | { | ||
2654 | uart_clear_mctrl(&mtpt->port, TIOCM_RTS); | ||
2655 | } | ||
2656 | } | ||
2657 | |||
2658 | if(mtpt->device->device_id == PCI_DEVICE_ID_MP4M) | ||
2659 | { | ||
2660 | SendATCommand(mtpt); | ||
2661 | printk("SendATCommand\n"); | ||
2662 | } | ||
2663 | multi_set_mctrl(&mtpt->port, mtpt->port.mctrl); | ||
2664 | spin_unlock_irqrestore(&mtpt->port.lock, flags); | ||
2665 | } | ||
2666 | |||
2667 | static void multi_pm(struct sb_uart_port *port, unsigned int state, unsigned int oldstate) | ||
2668 | { | ||
2669 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2670 | if (state) { | ||
2671 | if (mtpt->capabilities & UART_STARTECH) { | ||
2672 | serial_outp(mtpt, UART_LCR, 0xBF); | ||
2673 | serial_outp(mtpt, UART_EFR, UART_EFR_ECB); | ||
2674 | serial_outp(mtpt, UART_LCR, 0); | ||
2675 | serial_outp(mtpt, UART_IER, UART_IERX_SLEEP); | ||
2676 | serial_outp(mtpt, UART_LCR, 0xBF); | ||
2677 | serial_outp(mtpt, UART_EFR, 0); | ||
2678 | serial_outp(mtpt, UART_LCR, 0); | ||
2679 | } | ||
2680 | |||
2681 | if (mtpt->pm) | ||
2682 | mtpt->pm(port, state, oldstate); | ||
2683 | } | ||
2684 | else | ||
2685 | { | ||
2686 | if (mtpt->capabilities & UART_STARTECH) { | ||
2687 | serial_outp(mtpt, UART_LCR, 0xBF); | ||
2688 | serial_outp(mtpt, UART_EFR, UART_EFR_ECB); | ||
2689 | serial_outp(mtpt, UART_LCR, 0); | ||
2690 | serial_outp(mtpt, UART_IER, 0); | ||
2691 | serial_outp(mtpt, UART_LCR, 0xBF); | ||
2692 | serial_outp(mtpt, UART_EFR, 0); | ||
2693 | serial_outp(mtpt, UART_LCR, 0); | ||
2694 | } | ||
2695 | |||
2696 | if (mtpt->pm) | ||
2697 | mtpt->pm(port, state, oldstate); | ||
2698 | } | ||
2699 | } | ||
2700 | |||
2701 | static void multi_release_std_resource(struct mp_port *mtpt) | ||
2702 | { | ||
2703 | unsigned int size = 8 << mtpt->port.regshift; | ||
2704 | |||
2705 | switch (mtpt->port.iotype) { | ||
2706 | case UPIO_MEM: | ||
2707 | if (!mtpt->port.mapbase) | ||
2708 | break; | ||
2709 | |||
2710 | if (mtpt->port.flags & UPF_IOREMAP) { | ||
2711 | iounmap(mtpt->port.membase); | ||
2712 | mtpt->port.membase = NULL; | ||
2713 | } | ||
2714 | |||
2715 | release_mem_region(mtpt->port.mapbase, size); | ||
2716 | break; | ||
2717 | |||
2718 | case UPIO_HUB6: | ||
2719 | case UPIO_PORT: | ||
2720 | release_region(mtpt->port.iobase,size); | ||
2721 | break; | ||
2722 | } | ||
2723 | } | ||
2724 | |||
2725 | static void multi_release_port(struct sb_uart_port *port) | ||
2726 | { | ||
2727 | } | ||
2728 | |||
2729 | static int multi_request_port(struct sb_uart_port *port) | ||
2730 | { | ||
2731 | return 0; | ||
2732 | } | ||
2733 | |||
2734 | static void multi_config_port(struct sb_uart_port *port, int flags) | ||
2735 | { | ||
2736 | struct mp_port *mtpt = (struct mp_port *)port; | ||
2737 | int probeflags = PROBE_ANY; | ||
2738 | |||
2739 | if (flags & UART_CONFIG_TYPE) | ||
2740 | autoconfig(mtpt, probeflags); | ||
2741 | if (mtpt->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) | ||
2742 | autoconfig_irq(mtpt); | ||
2743 | |||
2744 | if (mtpt->port.type == PORT_UNKNOWN) | ||
2745 | multi_release_std_resource(mtpt); | ||
2746 | } | ||
2747 | |||
2748 | static int multi_verify_port(struct sb_uart_port *port, struct serial_struct *ser) | ||
2749 | { | ||
2750 | if (ser->irq >= NR_IRQS || ser->irq < 0 || | ||
2751 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | ||
2752 | ser->type == PORT_STARTECH) | ||
2753 | return -EINVAL; | ||
2754 | return 0; | ||
2755 | } | ||
2756 | |||
2757 | static const char * multi_type(struct sb_uart_port *port) | ||
2758 | { | ||
2759 | int type = port->type; | ||
2760 | |||
2761 | if (type >= ARRAY_SIZE(uart_config)) | ||
2762 | type = 0; | ||
2763 | return uart_config[type].name; | ||
2764 | } | ||
2765 | |||
2766 | static struct sb_uart_ops multi_pops = { | ||
2767 | .tx_empty = multi_tx_empty, | ||
2768 | .set_mctrl = multi_set_mctrl, | ||
2769 | .get_mctrl = multi_get_mctrl, | ||
2770 | .stop_tx = multi_stop_tx, | ||
2771 | .start_tx = multi_start_tx, | ||
2772 | .stop_rx = multi_stop_rx, | ||
2773 | .enable_ms = multi_enable_ms, | ||
2774 | .break_ctl = multi_break_ctl, | ||
2775 | .startup = multi_startup, | ||
2776 | .shutdown = multi_shutdown, | ||
2777 | .set_termios = multi_set_termios, | ||
2778 | .pm = multi_pm, | ||
2779 | .type = multi_type, | ||
2780 | .release_port = multi_release_port, | ||
2781 | .request_port = multi_request_port, | ||
2782 | .config_port = multi_config_port, | ||
2783 | .verify_port = multi_verify_port, | ||
2784 | }; | ||
2785 | |||
2786 | static struct uart_driver multi_reg = { | ||
2787 | .owner = THIS_MODULE, | ||
2788 | .driver_name = "goldel_tulip", | ||
2789 | .dev_name = "ttyMP", | ||
2790 | .major = SB_TTY_MP_MAJOR, | ||
2791 | .minor = 0, | ||
2792 | .nr = MAX_MP_PORT, | ||
2793 | .cons = NULL, | ||
2794 | }; | ||
2795 | |||
2796 | static void __init multi_init_ports(void) | ||
2797 | { | ||
2798 | struct mp_port *mtpt; | ||
2799 | static int first = 1; | ||
2800 | int i,j,k; | ||
2801 | unsigned char osc; | ||
2802 | unsigned char b_ret = 0; | ||
2803 | static struct mp_device_t * sbdev; | ||
2804 | |||
2805 | if (!first) | ||
2806 | return; | ||
2807 | first = 0; | ||
2808 | |||
2809 | mtpt = multi_ports; | ||
2810 | |||
2811 | for (k=0;k<NR_BOARD;k++) | ||
2812 | { | ||
2813 | sbdev = &mp_devs[k]; | ||
2814 | |||
2815 | for (i = 0; i < sbdev->nr_ports; i++, mtpt++) | ||
2816 | { | ||
2817 | mtpt->device = sbdev; | ||
2818 | mtpt->port.iobase = sbdev->uart_access_addr + 8*i; | ||
2819 | mtpt->port.irq = sbdev->irq; | ||
2820 | if ( ((sbdev->device_id == PCI_DEVICE_ID_MP4)&&(sbdev->revision==0x91))) | ||
2821 | mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + i; | ||
2822 | else if (sbdev->revision == 0xc0) | ||
2823 | mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + (i & 0x1); | ||
2824 | else | ||
2825 | mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + i/8; | ||
2826 | |||
2827 | mtpt->option_base_addr = sbdev->option_reg_addr; | ||
2828 | |||
2829 | mtpt->poll_type = sbdev->poll_type; | ||
2830 | |||
2831 | mtpt->port.uartclk = BASE_BAUD * 16; | ||
2832 | |||
2833 | /* get input clock infomation */ | ||
2834 | osc = inb(sbdev->option_reg_addr + MP_OPTR_DIR0 + i/8) & 0x0F; | ||
2835 | if (osc==0x0f) | ||
2836 | osc = 0; | ||
2837 | for(j=0;j<osc;j++) | ||
2838 | mtpt->port.uartclk *= 2; | ||
2839 | mtpt->port.flags |= STD_COM_FLAGS | UPF_SHARE_IRQ ; | ||
2840 | mtpt->port.iotype = UPIO_PORT; | ||
2841 | mtpt->port.ops = &multi_pops; | ||
2842 | |||
2843 | if (sbdev->revision == 0xc0) | ||
2844 | { | ||
2845 | /* for SB16C1053APCI */ | ||
2846 | b_ret = sb1053a_get_interface(mtpt, i); | ||
2847 | } | ||
2848 | else | ||
2849 | { | ||
2850 | b_ret = read_option_register(mtpt,(MP_OPTR_IIR0 + i/8)); | ||
2851 | printk("IIR_RET = %x\n",b_ret); | ||
2852 | } | ||
2853 | |||
2854 | if(IIR_RS232 == (b_ret & IIR_RS232)) | ||
2855 | { | ||
2856 | mtpt->interface = RS232; | ||
2857 | } | ||
2858 | if(IIR_RS422 == (b_ret & IIR_RS422)) | ||
2859 | { | ||
2860 | mtpt->interface = RS422PTP; | ||
2861 | } | ||
2862 | if(IIR_RS485 == (b_ret & IIR_RS485)) | ||
2863 | { | ||
2864 | mtpt->interface = RS485NE; | ||
2865 | } | ||
2866 | } | ||
2867 | } | ||
2868 | } | ||
2869 | |||
2870 | static void __init multi_register_ports(struct uart_driver *drv) | ||
2871 | { | ||
2872 | int i; | ||
2873 | |||
2874 | multi_init_ports(); | ||
2875 | |||
2876 | for (i = 0; i < NR_PORTS; i++) { | ||
2877 | struct mp_port *mtpt = &multi_ports[i]; | ||
2878 | |||
2879 | mtpt->port.line = i; | ||
2880 | mtpt->port.ops = &multi_pops; | ||
2881 | init_timer(&mtpt->timer); | ||
2882 | mtpt->timer.function = multi_timeout; | ||
2883 | mp_add_one_port(drv, &mtpt->port); | ||
2884 | } | ||
2885 | } | ||
2886 | |||
2887 | /** | ||
2888 | * pci_remap_base - remap BAR value of pci device | ||
2889 | * | ||
2890 | * PARAMETERS | ||
2891 | * pcidev - pci_dev structure address | ||
2892 | * offset - BAR offset PCI_BASE_ADDRESS_0 ~ PCI_BASE_ADDRESS_4 | ||
2893 | * address - address to be changed BAR value | ||
2894 | * size - size of address space | ||
2895 | * | ||
2896 | * RETURNS | ||
2897 | * If this function performs successful, it returns 0. Otherwise, It returns -1. | ||
2898 | */ | ||
2899 | static int pci_remap_base(struct pci_dev *pcidev, unsigned int offset, | ||
2900 | unsigned int address, unsigned int size) | ||
2901 | { | ||
2902 | #if 0 | ||
2903 | struct resource *root; | ||
2904 | unsigned index = (offset - 0x10) >> 2; | ||
2905 | #endif | ||
2906 | |||
2907 | pci_write_config_dword(pcidev, offset, address); | ||
2908 | #if 0 | ||
2909 | root = pcidev->resource[index].parent; | ||
2910 | release_resource(&pcidev->resource[index]); | ||
2911 | address &= ~0x1; | ||
2912 | pcidev->resource[index].start = address; | ||
2913 | pcidev->resource[index].end = address + size - 1; | ||
2914 | |||
2915 | if (request_resource(root, &pcidev->resource[index]) != NULL) | ||
2916 | { | ||
2917 | printk(KERN_ERR "pci remap conflict!! 0x%x\n", address); | ||
2918 | return (-1); | ||
2919 | } | ||
2920 | #endif | ||
2921 | |||
2922 | return (0); | ||
2923 | } | ||
2924 | |||
2925 | static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd) | ||
2926 | { | ||
2927 | static struct mp_device_t * sbdev = mp_devs; | ||
2928 | unsigned long addr = 0; | ||
2929 | int j; | ||
2930 | struct resource * ret = NULL; | ||
2931 | |||
2932 | sbdev->device_id = brd.device_id; | ||
2933 | pci_read_config_byte(pcidev, PCI_CLASS_REVISION, &(sbdev->revision)); | ||
2934 | sbdev->name = brd.name; | ||
2935 | sbdev->uart_access_addr = pcidev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK; | ||
2936 | |||
2937 | /* check revision. The SB16C1053APCI's option i/o address is BAR4 */ | ||
2938 | if (sbdev->revision == 0xc0) | ||
2939 | { | ||
2940 | /* SB16C1053APCI */ | ||
2941 | sbdev->option_reg_addr = pcidev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; | ||
2942 | } | ||
2943 | else | ||
2944 | { | ||
2945 | sbdev->option_reg_addr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; | ||
2946 | } | ||
2947 | #if 1 | ||
2948 | if (sbdev->revision == 0xc0) | ||
2949 | { | ||
2950 | outb(0x00, sbdev->option_reg_addr + MP_OPTR_GPOCR); | ||
2951 | inb(sbdev->option_reg_addr + MP_OPTR_GPOCR); | ||
2952 | outb(0x83, sbdev->option_reg_addr + MP_OPTR_GPOCR); | ||
2953 | } | ||
2954 | #endif | ||
2955 | |||
2956 | sbdev->irq = pcidev->irq; | ||
2957 | |||
2958 | if ((brd.device_id & 0x0800) || !(brd.device_id &0xff00)) | ||
2959 | { | ||
2960 | sbdev->poll_type = TYPE_INTERRUPT; | ||
2961 | } | ||
2962 | else | ||
2963 | { | ||
2964 | sbdev->poll_type = TYPE_POLL; | ||
2965 | } | ||
2966 | |||
2967 | /* codes which is specific to each board*/ | ||
2968 | switch(brd.device_id){ | ||
2969 | case PCI_DEVICE_ID_MP1 : | ||
2970 | case PCIE_DEVICE_ID_MP1 : | ||
2971 | case PCIE_DEVICE_ID_MP1E : | ||
2972 | case PCIE_DEVICE_ID_GT_MP1 : | ||
2973 | sbdev->nr_ports = 1; | ||
2974 | break; | ||
2975 | case PCI_DEVICE_ID_MP2 : | ||
2976 | case PCIE_DEVICE_ID_MP2 : | ||
2977 | case PCIE_DEVICE_ID_GT_MP2 : | ||
2978 | case PCIE_DEVICE_ID_MP2B : | ||
2979 | case PCIE_DEVICE_ID_MP2E : | ||
2980 | sbdev->nr_ports = 2; | ||
2981 | |||
2982 | /* serial base address remap */ | ||
2983 | if (sbdev->revision == 0xc0) | ||
2984 | { | ||
2985 | int prev_port_addr = 0; | ||
2986 | |||
2987 | pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); | ||
2988 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); | ||
2989 | } | ||
2990 | break; | ||
2991 | case PCI_DEVICE_ID_MP4 : | ||
2992 | case PCI_DEVICE_ID_MP4A : | ||
2993 | case PCIE_DEVICE_ID_MP4 : | ||
2994 | case PCI_DEVICE_ID_GT_MP4 : | ||
2995 | case PCI_DEVICE_ID_GT_MP4A : | ||
2996 | case PCIE_DEVICE_ID_GT_MP4 : | ||
2997 | case PCI_DEVICE_ID_MP4M : | ||
2998 | case PCIE_DEVICE_ID_MP4B : | ||
2999 | sbdev->nr_ports = 4; | ||
3000 | |||
3001 | if(sbdev->revision == 0x91){ | ||
3002 | sbdev->reserved_addr[0] = pcidev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK; | ||
3003 | outb(0x03 , sbdev->reserved_addr[0] + 0x01); | ||
3004 | outb(0x03 , sbdev->reserved_addr[0] + 0x02); | ||
3005 | outb(0x01 , sbdev->reserved_addr[0] + 0x20); | ||
3006 | outb(0x00 , sbdev->reserved_addr[0] + 0x21); | ||
3007 | request_region(sbdev->reserved_addr[0], 32, sbdev->name); | ||
3008 | sbdev->uart_access_addr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; | ||
3009 | sbdev->option_reg_addr = pcidev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK; | ||
3010 | } | ||
3011 | |||
3012 | /* SB16C1053APCI */ | ||
3013 | if (sbdev->revision == 0xc0) | ||
3014 | { | ||
3015 | int prev_port_addr = 0; | ||
3016 | |||
3017 | pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); | ||
3018 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); | ||
3019 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_2, prev_port_addr + 16, 8); | ||
3020 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_3, prev_port_addr + 24, 8); | ||
3021 | } | ||
3022 | break; | ||
3023 | case PCI_DEVICE_ID_MP6 : | ||
3024 | case PCI_DEVICE_ID_MP6A : | ||
3025 | case PCI_DEVICE_ID_GT_MP6 : | ||
3026 | case PCI_DEVICE_ID_GT_MP6A : | ||
3027 | sbdev->nr_ports = 6; | ||
3028 | |||
3029 | /* SB16C1053APCI */ | ||
3030 | if (sbdev->revision == 0xc0) | ||
3031 | { | ||
3032 | int prev_port_addr = 0; | ||
3033 | |||
3034 | pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); | ||
3035 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); | ||
3036 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_2, prev_port_addr + 16, 16); | ||
3037 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_3, prev_port_addr + 32, 16); | ||
3038 | } | ||
3039 | break; | ||
3040 | case PCI_DEVICE_ID_MP8 : | ||
3041 | case PCIE_DEVICE_ID_MP8 : | ||
3042 | case PCI_DEVICE_ID_GT_MP8 : | ||
3043 | case PCIE_DEVICE_ID_GT_MP8 : | ||
3044 | case PCIE_DEVICE_ID_MP8B : | ||
3045 | sbdev->nr_ports = 8; | ||
3046 | break; | ||
3047 | case PCI_DEVICE_ID_MP32 : | ||
3048 | case PCIE_DEVICE_ID_MP32 : | ||
3049 | case PCI_DEVICE_ID_GT_MP32 : | ||
3050 | case PCIE_DEVICE_ID_GT_MP32 : | ||
3051 | { | ||
3052 | int portnum_hex=0; | ||
3053 | portnum_hex = inb(sbdev->option_reg_addr); | ||
3054 | sbdev->nr_ports = ((portnum_hex/16)*10) + (portnum_hex % 16); | ||
3055 | } | ||
3056 | break; | ||
3057 | case PCI_DEVICE_ID_MP2S1P : | ||
3058 | sbdev->nr_ports = 2; | ||
3059 | |||
3060 | /* SB16C1053APCI */ | ||
3061 | if (sbdev->revision == 0xc0) | ||
3062 | { | ||
3063 | int prev_port_addr = 0; | ||
3064 | |||
3065 | pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); | ||
3066 | pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); | ||
3067 | } | ||
3068 | |||
3069 | /* add PC compatible parallel port */ | ||
3070 | parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0); | ||
3071 | break; | ||
3072 | case PCI_DEVICE_ID_MP1P : | ||
3073 | /* add PC compatible parallel port */ | ||
3074 | parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0); | ||
3075 | break; | ||
3076 | } | ||
3077 | |||
3078 | ret = request_region(sbdev->uart_access_addr, (8*sbdev->nr_ports), sbdev->name); | ||
3079 | |||
3080 | if (sbdev->revision == 0xc0) | ||
3081 | { | ||
3082 | ret = request_region(sbdev->option_reg_addr, 0x40, sbdev->name); | ||
3083 | } | ||
3084 | else | ||
3085 | { | ||
3086 | ret = request_region(sbdev->option_reg_addr, 0x20, sbdev->name); | ||
3087 | } | ||
3088 | |||
3089 | |||
3090 | NR_BOARD++; | ||
3091 | NR_PORTS += sbdev->nr_ports; | ||
3092 | |||
3093 | /* Enable PCI interrupt */ | ||
3094 | addr = sbdev->option_reg_addr + MP_OPTR_IMR0; | ||
3095 | for(j=0; j < (sbdev->nr_ports/8)+1; j++) | ||
3096 | { | ||
3097 | if (sbdev->poll_type == TYPE_INTERRUPT) | ||
3098 | { | ||
3099 | outb(0xff,addr +j); | ||
3100 | } | ||
3101 | } | ||
3102 | sbdev++; | ||
3103 | |||
3104 | return 0; | ||
3105 | } | ||
3106 | |||
3107 | static int __init multi_init(void) | ||
3108 | { | ||
3109 | int ret, i; | ||
3110 | struct pci_dev *dev = NULL; | ||
3111 | |||
3112 | if(fcr_count==0) | ||
3113 | { | ||
3114 | for(i=0;i<256;i++) | ||
3115 | { | ||
3116 | fcr_arr[i] = 0x01; | ||
3117 | |||
3118 | } | ||
3119 | } | ||
3120 | if(deep_count==0) | ||
3121 | { | ||
3122 | for(i=0;i<256;i++) | ||
3123 | { | ||
3124 | deep[i] = 1; | ||
3125 | |||
3126 | } | ||
3127 | } | ||
3128 | if(rtr_count==0) | ||
3129 | { | ||
3130 | for(i=0;i<256;i++) | ||
3131 | { | ||
3132 | rtr[i] = 0x10; | ||
3133 | } | ||
3134 | } | ||
3135 | if(ttr_count==0) | ||
3136 | { | ||
3137 | for(i=0;i<256;i++) | ||
3138 | { | ||
3139 | ttr[i] = 0x38; | ||
3140 | } | ||
3141 | } | ||
3142 | |||
3143 | |||
3144 | printk("MULTI INIT\n"); | ||
3145 | for( i=0; i< mp_nrpcibrds; i++) | ||
3146 | { | ||
3147 | |||
3148 | while( (dev = pci_get_device(mp_pciboards[i].vendor_id, mp_pciboards[i].device_id, dev) ) ) | ||
3149 | |||
3150 | { | ||
3151 | printk("FOUND~~~\n"); | ||
3152 | // Cent OS bug fix | ||
3153 | // if (mp_pciboards[i].device_id & 0x0800) | ||
3154 | { | ||
3155 | int status; | ||
3156 | pci_disable_device(dev); | ||
3157 | status = pci_enable_device(dev); | ||
3158 | |||
3159 | if (status != 0) | ||
3160 | { | ||
3161 | printk("Multiport Board Enable Fail !\n\n"); | ||
3162 | status = -ENXIO; | ||
3163 | return status; | ||
3164 | } | ||
3165 | } | ||
3166 | |||
3167 | init_mp_dev(dev, mp_pciboards[i]); | ||
3168 | } | ||
3169 | } | ||
3170 | |||
3171 | for (i = 0; i < NR_IRQS; i++) | ||
3172 | spin_lock_init(&irq_lists[i].lock); | ||
3173 | |||
3174 | ret = mp_register_driver(&multi_reg); | ||
3175 | |||
3176 | if (ret >= 0) | ||
3177 | multi_register_ports(&multi_reg); | ||
3178 | |||
3179 | return ret; | ||
3180 | } | ||
3181 | |||
3182 | static void __exit multi_exit(void) | ||
3183 | { | ||
3184 | int i; | ||
3185 | |||
3186 | for (i = 0; i < NR_PORTS; i++) | ||
3187 | mp_remove_one_port(&multi_reg, &multi_ports[i].port); | ||
3188 | |||
3189 | mp_unregister_driver(&multi_reg); | ||
3190 | } | ||
3191 | |||
3192 | module_init(multi_init); | ||
3193 | module_exit(multi_exit); | ||
3194 | |||
3195 | MODULE_DESCRIPTION("SystemBase Multiport PCI/PCIe CORE"); | ||
3196 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/sb105x/sb_pci_mp.h b/drivers/staging/sb105x/sb_pci_mp.h new file mode 100644 index 000000000000..f33efde07b97 --- /dev/null +++ b/drivers/staging/sb105x/sb_pci_mp.h | |||
@@ -0,0 +1,293 @@ | |||
1 | #include <linux/errno.h> | ||
2 | #include <linux/signal.h> | ||
3 | #include <linux/tty.h> | ||
4 | #include <linux/tty_flip.h> | ||
5 | #include <linux/serial.h> | ||
6 | #include <linux/serial_reg.h> | ||
7 | #include <linux/ioport.h> | ||
8 | #include <linux/mm.h> | ||
9 | #include <linux/sched.h> | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/wait.h> | ||
15 | #include <linux/tty_driver.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/circ_buf.h> | ||
18 | |||
19 | #include <asm/uaccess.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/irq.h> | ||
22 | #include <asm/segment.h> | ||
23 | #include <asm/serial.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | |||
26 | |||
27 | #include <linux/parport.h> | ||
28 | #include <linux/ctype.h> | ||
29 | #include <linux/poll.h> | ||
30 | |||
31 | |||
32 | #define MP_TERMIOS ktermios | ||
33 | |||
34 | #include "sb_mp_register.h" | ||
35 | #include "sb_ser_core.h" | ||
36 | |||
37 | #define DRIVER_VERSION "1.1" | ||
38 | #define DRIVER_DATE "2012/01/05" | ||
39 | #define DRIVER_AUTHOR "SYSTEMBASE<tech@sysbas.com>" | ||
40 | #define DRIVER_DESC "SystemBase PCI/PCIe Multiport Core" | ||
41 | |||
42 | #define SB_TTY_MP_MAJOR 54 | ||
43 | #define PCI_VENDOR_ID_MULTIPORT 0x14A1 | ||
44 | |||
45 | #define PCI_DEVICE_ID_MP1 0x4d01 | ||
46 | #define PCI_DEVICE_ID_MP2 0x4d02 | ||
47 | #define PCI_DEVICE_ID_MP4 0x4d04 | ||
48 | #define PCI_DEVICE_ID_MP4A 0x4d54 | ||
49 | #define PCI_DEVICE_ID_MP6 0x4d06 | ||
50 | #define PCI_DEVICE_ID_MP6A 0x4d56 | ||
51 | #define PCI_DEVICE_ID_MP8 0x4d08 | ||
52 | #define PCI_DEVICE_ID_MP32 0x4d32 | ||
53 | /* Parallel port */ | ||
54 | #define PCI_DEVICE_ID_MP1P 0x4301 | ||
55 | #define PCI_DEVICE_ID_MP2S1P 0x4303 | ||
56 | |||
57 | #define PCIE_DEVICE_ID_MP1 0x4501 | ||
58 | #define PCIE_DEVICE_ID_MP2 0x4502 | ||
59 | #define PCIE_DEVICE_ID_MP4 0x4504 | ||
60 | #define PCIE_DEVICE_ID_MP8 0x4508 | ||
61 | #define PCIE_DEVICE_ID_MP32 0x4532 | ||
62 | |||
63 | #define PCIE_DEVICE_ID_MP1E 0x4e01 | ||
64 | #define PCIE_DEVICE_ID_MP2E 0x4e02 | ||
65 | #define PCIE_DEVICE_ID_MP2B 0x4b02 | ||
66 | #define PCIE_DEVICE_ID_MP4B 0x4b04 | ||
67 | #define PCIE_DEVICE_ID_MP8B 0x4b08 | ||
68 | |||
69 | #define PCI_DEVICE_ID_GT_MP4 0x0004 | ||
70 | #define PCI_DEVICE_ID_GT_MP4A 0x0054 | ||
71 | #define PCI_DEVICE_ID_GT_MP6 0x0006 | ||
72 | #define PCI_DEVICE_ID_GT_MP6A 0x0056 | ||
73 | #define PCI_DEVICE_ID_GT_MP8 0x0008 | ||
74 | #define PCI_DEVICE_ID_GT_MP32 0x0032 | ||
75 | |||
76 | #define PCIE_DEVICE_ID_GT_MP1 0x1501 | ||
77 | #define PCIE_DEVICE_ID_GT_MP2 0x1502 | ||
78 | #define PCIE_DEVICE_ID_GT_MP4 0x1504 | ||
79 | #define PCIE_DEVICE_ID_GT_MP8 0x1508 | ||
80 | #define PCIE_DEVICE_ID_GT_MP32 0x1532 | ||
81 | |||
82 | #define PCI_DEVICE_ID_MP4M 0x4604 //modem | ||
83 | |||
84 | #define MAX_MP_DEV 8 | ||
85 | #define BD_MAX_PORT 32 /* Max serial port in one board */ | ||
86 | #define MAX_MP_PORT 256 /* Max serial port in one PC */ | ||
87 | |||
88 | #define PORT_16C105XA 3 | ||
89 | #define PORT_16C105X 2 | ||
90 | #define PORT_16C55X 1 | ||
91 | |||
92 | #define ENABLE 1 | ||
93 | #define DISABLE 0 | ||
94 | |||
95 | /* ioctls */ | ||
96 | #define TIOCGNUMOFPORT 0x545F | ||
97 | #define TIOCSMULTIECHO 0x5440 | ||
98 | #define TIOCSPTPNOECHO 0x5441 | ||
99 | |||
100 | #define TIOCGOPTIONREG 0x5461 | ||
101 | #define TIOCGDISABLEIRQ 0x5462 | ||
102 | #define TIOCGENABLEIRQ 0x5463 | ||
103 | #define TIOCGSOFTRESET 0x5464 | ||
104 | #define TIOCGSOFTRESETR 0x5465 | ||
105 | #define TIOCGREGINFO 0x5466 | ||
106 | #define TIOCGGETLSR 0x5467 | ||
107 | #define TIOCGGETDEVID 0x5468 | ||
108 | #define TIOCGGETBDNO 0x5469 | ||
109 | #define TIOCGGETINTERFACE 0x546A | ||
110 | #define TIOCGGETREV 0x546B | ||
111 | #define TIOCGGETNRPORTS 0x546C | ||
112 | #define TIOCGGETPORTTYPE 0x546D | ||
113 | #define GETDEEPFIFO 0x54AA | ||
114 | #define SETDEEPFIFO 0x54AB | ||
115 | #define SETFCR 0x54BA | ||
116 | #define SETTTR 0x54B1 | ||
117 | #define SETRTR 0x54B2 | ||
118 | #define GETTTR 0x54B3 | ||
119 | #define GETRTR 0x54B4 | ||
120 | |||
121 | /* multi-drop mode related ioctl commands */ | ||
122 | #define TIOCSMULTIDROP 0x5470 | ||
123 | #define TIOCSMDADDR 0x5471 | ||
124 | #define TIOCGMDADDR 0x5472 | ||
125 | #define TIOCSENDADDR 0x5473 | ||
126 | |||
127 | |||
128 | /* serial interface */ | ||
129 | #define RS232 1 | ||
130 | #define RS422PTP 2 | ||
131 | #define RS422MD 3 | ||
132 | #define RS485NE 4 | ||
133 | #define RS485ECHO 5 | ||
134 | |||
135 | #define serial_inp(up, offset) serial_in(up, offset) | ||
136 | #define serial_outp(up, offset, value) serial_out(up, offset, value) | ||
137 | |||
138 | #define PASS_LIMIT 256 | ||
139 | #define is_real_interrupt(irq) ((irq) != 0) | ||
140 | |||
141 | #define PROBE_ANY (~0) | ||
142 | |||
143 | static DEFINE_MUTEX(mp_mutex); | ||
144 | #define MP_MUTEX_LOCK(x) mutex_lock(&(x)) | ||
145 | #define MP_MUTEX_UNLOCK(x) mutex_unlock(&(x)) | ||
146 | #define MP_STATE_LOCK(x) mutex_lock(&((x)->mutex)) | ||
147 | #define MP_STATE_UNLOCK(x) mutex_unlock(&((x)->mutex)) | ||
148 | |||
149 | |||
150 | #define UART_LSR_SPECIAL 0x1E | ||
151 | |||
152 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | ||
153 | #define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0)) | ||
154 | |||
155 | |||
156 | //#define MP_DEBUG 1 | ||
157 | #undef MP_DEBUG | ||
158 | |||
159 | #ifdef MP_DEBUG | ||
160 | #define DPRINTK(x...) printk(x) | ||
161 | #else | ||
162 | #define DPRINTK(x...) do { } while (0) | ||
163 | #endif | ||
164 | |||
165 | #ifdef MP_DEBUG | ||
166 | #define DEBUG_AUTOCONF(fmt...) printk(fmt) | ||
167 | #else | ||
168 | #define DEBUG_AUTOCONF(fmt...) do { } while (0) | ||
169 | #endif | ||
170 | |||
171 | #ifdef MP_DEBUG | ||
172 | #define DEBUG_INTR(fmt...) printk(fmt) | ||
173 | #else | ||
174 | #define DEBUG_INTR(fmt...) do { } while (0) | ||
175 | #endif | ||
176 | |||
177 | #if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) | ||
178 | #define SERIAL_INLINE | ||
179 | #endif | ||
180 | #ifdef SERIAL_INLINE | ||
181 | #define _INLINE_ inline | ||
182 | #else | ||
183 | #define _INLINE_ | ||
184 | #endif | ||
185 | |||
186 | #define TYPE_POLL 1 | ||
187 | #define TYPE_INTERRUPT 2 | ||
188 | |||
189 | |||
190 | struct mp_device_t { | ||
191 | unsigned short device_id; | ||
192 | unsigned char revision; | ||
193 | char *name; | ||
194 | unsigned long uart_access_addr; | ||
195 | unsigned long option_reg_addr; | ||
196 | unsigned long reserved_addr[4]; | ||
197 | int irq; | ||
198 | int nr_ports; | ||
199 | int poll_type; | ||
200 | }; | ||
201 | |||
202 | typedef struct mppcibrd { | ||
203 | char *name; | ||
204 | unsigned short vendor_id; | ||
205 | unsigned short device_id; | ||
206 | } mppcibrd_t; | ||
207 | |||
208 | static mppcibrd_t mp_pciboards[] = { | ||
209 | |||
210 | { "Multi-1 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1} , | ||
211 | { "Multi-2 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2} , | ||
212 | { "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4} , | ||
213 | { "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4A} , | ||
214 | { "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6} , | ||
215 | { "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6A} , | ||
216 | { "Multi-8 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP8} , | ||
217 | { "Multi-32 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP32} , | ||
218 | |||
219 | { "Multi-1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1P} , | ||
220 | { "Multi-2S1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2S1P} , | ||
221 | |||
222 | { "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4} , | ||
223 | { "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4A} , | ||
224 | { "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6} , | ||
225 | { "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6A} , | ||
226 | { "Multi-8(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP8} , | ||
227 | { "Multi-32(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP32} , | ||
228 | |||
229 | { "Multi-1 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1} , | ||
230 | { "Multi-2 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2} , | ||
231 | { "Multi-4 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4} , | ||
232 | { "Multi-8 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8} , | ||
233 | { "Multi-32 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP32} , | ||
234 | |||
235 | { "Multi-1 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1E} , | ||
236 | { "Multi-2 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2E} , | ||
237 | { "Multi-2 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2B} , | ||
238 | { "Multi-4 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4B} , | ||
239 | { "Multi-8 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8B} , | ||
240 | |||
241 | { "Multi-1(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP1} , | ||
242 | { "Multi-2(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP2} , | ||
243 | { "Multi-4(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP4} , | ||
244 | { "Multi-8(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP8} , | ||
245 | { "Multi-32(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP32} , | ||
246 | |||
247 | { "Multi-4M PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4M} , | ||
248 | }; | ||
249 | |||
250 | struct mp_port { | ||
251 | struct sb_uart_port port; | ||
252 | |||
253 | struct timer_list timer; /* "no irq" timer */ | ||
254 | struct list_head list; /* ports on this IRQ */ | ||
255 | unsigned int capabilities; /* port capabilities */ | ||
256 | unsigned short rev; | ||
257 | unsigned char acr; | ||
258 | unsigned char ier; | ||
259 | unsigned char lcr; | ||
260 | unsigned char mcr; | ||
261 | unsigned char mcr_mask; /* mask of user bits */ | ||
262 | unsigned char mcr_force; /* mask of forced bits */ | ||
263 | unsigned char lsr_break_flag; | ||
264 | |||
265 | void (*pm)(struct sb_uart_port *port, | ||
266 | unsigned int state, unsigned int old); | ||
267 | struct mp_device_t *device; | ||
268 | unsigned long interface_config_addr; | ||
269 | unsigned long option_base_addr; | ||
270 | unsigned char interface; | ||
271 | unsigned char poll_type; | ||
272 | }; | ||
273 | |||
274 | struct irq_info { | ||
275 | spinlock_t lock; | ||
276 | struct list_head *head; | ||
277 | }; | ||
278 | |||
279 | struct sb105x_uart_config { | ||
280 | char *name; | ||
281 | int dfl_xmit_fifo_size; | ||
282 | int flags; | ||
283 | }; | ||
284 | |||
285 | static const struct sb105x_uart_config uart_config[] = { | ||
286 | { "unknown", 1, 0 }, | ||
287 | { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, | ||
288 | { "SB16C1050", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, | ||
289 | { "SB16C1050A", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, | ||
290 | }; | ||
291 | |||
292 | |||
293 | |||
diff --git a/drivers/staging/sb105x/sb_ser_core.h b/drivers/staging/sb105x/sb_ser_core.h new file mode 100644 index 000000000000..c8fb99173299 --- /dev/null +++ b/drivers/staging/sb105x/sb_ser_core.h | |||
@@ -0,0 +1,368 @@ | |||
1 | #include <linux/wait.h> | ||
2 | |||
3 | #define UART_CONFIG_TYPE (1 << 0) | ||
4 | #define UART_CONFIG_IRQ (1 << 1) | ||
5 | #define UPIO_PORT (0) | ||
6 | #define UPIO_HUB6 (1) | ||
7 | #define UPIO_MEM (2) | ||
8 | #define UPIO_MEM32 (3) | ||
9 | #define UPIO_AU (4) /* Au1x00 type IO */ | ||
10 | #define UPIO_TSI (5) /* Tsi108/109 type IO */ | ||
11 | #define UPF_FOURPORT (1 << 1) | ||
12 | #define UPF_SAK (1 << 2) | ||
13 | #define UPF_SPD_MASK (0x1030) | ||
14 | #define UPF_SPD_HI (0x0010) | ||
15 | #define UPF_SPD_VHI (0x0020) | ||
16 | #define UPF_SPD_CUST (0x0030) | ||
17 | #define UPF_SPD_SHI (0x1000) | ||
18 | #define UPF_SPD_WARP (0x1010) | ||
19 | #define UPF_SKIP_TEST (1 << 6) | ||
20 | #define UPF_AUTO_IRQ (1 << 7) | ||
21 | #define UPF_HARDPPS_CD (1 << 11) | ||
22 | #define UPF_LOW_LATENCY (1 << 13) | ||
23 | #define UPF_BUGGY_UART (1 << 14) | ||
24 | #define UPF_MAGIC_MULTIPLIER (1 << 16) | ||
25 | #define UPF_CONS_FLOW (1 << 23) | ||
26 | #define UPF_SHARE_IRQ (1 << 24) | ||
27 | #define UPF_BOOT_AUTOCONF (1 << 28) | ||
28 | #define UPF_DEAD (1 << 30) | ||
29 | #define UPF_IOREMAP (1 << 31) | ||
30 | #define UPF_CHANGE_MASK (0x17fff) | ||
31 | #define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY) | ||
32 | #define USF_CLOSING_WAIT_INF (0) | ||
33 | #define USF_CLOSING_WAIT_NONE (~0U) | ||
34 | |||
35 | #define UART_XMIT_SIZE PAGE_SIZE | ||
36 | |||
37 | #define UIF_CHECK_CD (1 << 25) | ||
38 | #define UIF_CTS_FLOW (1 << 26) | ||
39 | #define UIF_NORMAL_ACTIVE (1 << 29) | ||
40 | #define UIF_INITIALIZED (1 << 31) | ||
41 | #define UIF_SUSPENDED (1 << 30) | ||
42 | |||
43 | #define WAKEUP_CHARS 256 | ||
44 | |||
45 | #define uart_circ_empty(circ) ((circ)->head == (circ)->tail) | ||
46 | #define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0) | ||
47 | |||
48 | #define uart_circ_chars_pending(circ) \ | ||
49 | (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | ||
50 | |||
51 | #define uart_circ_chars_free(circ) \ | ||
52 | (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | ||
53 | |||
54 | #define uart_tx_stopped(port) \ | ||
55 | ((port)->info->tty->stopped || (port)->info->tty->hw_stopped) | ||
56 | |||
57 | #define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \ | ||
58 | (cflag) & CRTSCTS || \ | ||
59 | !((cflag) & CLOCAL)) | ||
60 | |||
61 | |||
62 | struct sb_uart_port; | ||
63 | struct sb_uart_info; | ||
64 | struct serial_struct; | ||
65 | struct device; | ||
66 | |||
67 | struct sb_uart_ops { | ||
68 | unsigned int (*tx_empty)(struct sb_uart_port *); | ||
69 | void (*set_mctrl)(struct sb_uart_port *, unsigned int mctrl); | ||
70 | unsigned int (*get_mctrl)(struct sb_uart_port *); | ||
71 | void (*stop_tx)(struct sb_uart_port *); | ||
72 | void (*start_tx)(struct sb_uart_port *); | ||
73 | void (*send_xchar)(struct sb_uart_port *, char ch); | ||
74 | void (*stop_rx)(struct sb_uart_port *); | ||
75 | void (*enable_ms)(struct sb_uart_port *); | ||
76 | void (*break_ctl)(struct sb_uart_port *, int ctl); | ||
77 | int (*startup)(struct sb_uart_port *); | ||
78 | void (*shutdown)(struct sb_uart_port *); | ||
79 | void (*set_termios)(struct sb_uart_port *, struct MP_TERMIOS *new, | ||
80 | struct MP_TERMIOS *old); | ||
81 | void (*pm)(struct sb_uart_port *, unsigned int state, | ||
82 | unsigned int oldstate); | ||
83 | int (*set_wake)(struct sb_uart_port *, unsigned int state); | ||
84 | |||
85 | const char *(*type)(struct sb_uart_port *); | ||
86 | |||
87 | void (*release_port)(struct sb_uart_port *); | ||
88 | |||
89 | int (*request_port)(struct sb_uart_port *); | ||
90 | void (*config_port)(struct sb_uart_port *, int); | ||
91 | int (*verify_port)(struct sb_uart_port *, struct serial_struct *); | ||
92 | int (*ioctl)(struct sb_uart_port *, unsigned int, unsigned long); | ||
93 | }; | ||
94 | |||
95 | |||
96 | struct sb_uart_icount { | ||
97 | __u32 cts; | ||
98 | __u32 dsr; | ||
99 | __u32 rng; | ||
100 | __u32 dcd; | ||
101 | __u32 rx; | ||
102 | __u32 tx; | ||
103 | __u32 frame; | ||
104 | __u32 overrun; | ||
105 | __u32 parity; | ||
106 | __u32 brk; | ||
107 | __u32 buf_overrun; | ||
108 | }; | ||
109 | typedef unsigned int upf_t; | ||
110 | |||
111 | struct sb_uart_port { | ||
112 | spinlock_t lock; /* port lock */ | ||
113 | unsigned int iobase; /* in/out[bwl] */ | ||
114 | unsigned char __iomem *membase; /* read/write[bwl] */ | ||
115 | unsigned int irq; /* irq number */ | ||
116 | unsigned int uartclk; /* base uart clock */ | ||
117 | unsigned int fifosize; /* tx fifo size */ | ||
118 | unsigned char x_char; /* xon/xoff char */ | ||
119 | unsigned char regshift; /* reg offset shift */ | ||
120 | unsigned char iotype; /* io access style */ | ||
121 | unsigned char unused1; | ||
122 | |||
123 | |||
124 | unsigned int read_status_mask; /* driver specific */ | ||
125 | unsigned int ignore_status_mask; /* driver specific */ | ||
126 | struct sb_uart_info *info; /* pointer to parent info */ | ||
127 | struct sb_uart_icount icount; /* statistics */ | ||
128 | |||
129 | struct console *cons; /* struct console, if any */ | ||
130 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | ||
131 | unsigned long sysrq; /* sysrq timeout */ | ||
132 | #endif | ||
133 | |||
134 | upf_t flags; | ||
135 | |||
136 | unsigned int mctrl; /* current modem ctrl settings */ | ||
137 | unsigned int timeout; /* character-based timeout */ | ||
138 | unsigned int type; /* port type */ | ||
139 | const struct sb_uart_ops *ops; | ||
140 | unsigned int custom_divisor; | ||
141 | unsigned int line; /* port index */ | ||
142 | unsigned long mapbase; /* for ioremap */ | ||
143 | struct device *dev; /* parent device */ | ||
144 | unsigned char hub6; /* this should be in the 8250 driver */ | ||
145 | unsigned char unused[3]; | ||
146 | }; | ||
147 | |||
148 | #define mdmode unused[2] | ||
149 | #define MDMODE_ADDR 0x1 | ||
150 | #define MDMODE_ENABLE 0x2 | ||
151 | #define MDMODE_AUTO 0x4 | ||
152 | #define MDMODE_ADDRSEND 0x8 | ||
153 | |||
154 | struct sb_uart_state { | ||
155 | unsigned int close_delay; /* msec */ | ||
156 | unsigned int closing_wait; /* msec */ | ||
157 | |||
158 | |||
159 | int count; | ||
160 | int pm_state; | ||
161 | struct sb_uart_info *info; | ||
162 | struct sb_uart_port *port; | ||
163 | |||
164 | struct mutex mutex; | ||
165 | }; | ||
166 | |||
167 | typedef unsigned int uif_t; | ||
168 | |||
169 | struct sb_uart_info { | ||
170 | struct tty_struct *tty; | ||
171 | struct circ_buf xmit; | ||
172 | uif_t flags; | ||
173 | |||
174 | int blocked_open; | ||
175 | |||
176 | struct tasklet_struct tlet; | ||
177 | |||
178 | wait_queue_head_t open_wait; | ||
179 | wait_queue_head_t delta_msr_wait; | ||
180 | }; | ||
181 | |||
182 | |||
183 | struct module; | ||
184 | struct tty_driver; | ||
185 | |||
186 | struct uart_driver { | ||
187 | struct module *owner; | ||
188 | const char *driver_name; | ||
189 | const char *dev_name; | ||
190 | int major; | ||
191 | int minor; | ||
192 | int nr; | ||
193 | struct console *cons; | ||
194 | |||
195 | struct sb_uart_state *state; | ||
196 | struct tty_driver *tty_driver; | ||
197 | }; | ||
198 | |||
199 | void sb_uart_write_wakeup(struct sb_uart_port *port) | ||
200 | { | ||
201 | struct sb_uart_info *info = port->info; | ||
202 | tasklet_schedule(&info->tlet); | ||
203 | } | ||
204 | |||
205 | void sb_uart_update_timeout(struct sb_uart_port *port, unsigned int cflag, | ||
206 | unsigned int baud) | ||
207 | { | ||
208 | unsigned int bits; | ||
209 | |||
210 | switch (cflag & CSIZE) | ||
211 | { | ||
212 | case CS5: | ||
213 | bits = 7; | ||
214 | break; | ||
215 | |||
216 | case CS6: | ||
217 | bits = 8; | ||
218 | break; | ||
219 | |||
220 | case CS7: | ||
221 | bits = 9; | ||
222 | break; | ||
223 | |||
224 | default: | ||
225 | bits = 10; | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | if (cflag & CSTOPB) | ||
230 | { | ||
231 | bits++; | ||
232 | } | ||
233 | |||
234 | if (cflag & PARENB) | ||
235 | { | ||
236 | bits++; | ||
237 | } | ||
238 | |||
239 | bits = bits * port->fifosize; | ||
240 | |||
241 | port->timeout = (HZ * bits) / baud + HZ/50; | ||
242 | } | ||
243 | unsigned int sb_uart_get_baud_rate(struct sb_uart_port *port, struct MP_TERMIOS *termios, | ||
244 | struct MP_TERMIOS *old, unsigned int min, | ||
245 | unsigned int max) | ||
246 | { | ||
247 | unsigned int try, baud, altbaud = 38400; | ||
248 | upf_t flags = port->flags & UPF_SPD_MASK; | ||
249 | |||
250 | if (flags == UPF_SPD_HI) | ||
251 | altbaud = 57600; | ||
252 | if (flags == UPF_SPD_VHI) | ||
253 | altbaud = 115200; | ||
254 | if (flags == UPF_SPD_SHI) | ||
255 | altbaud = 230400; | ||
256 | if (flags == UPF_SPD_WARP) | ||
257 | altbaud = 460800; | ||
258 | |||
259 | for (try = 0; try < 2; try++) { | ||
260 | |||
261 | switch (termios->c_cflag & (CBAUD | CBAUDEX)) | ||
262 | { | ||
263 | case B921600 : baud = 921600; break; | ||
264 | case B460800 : baud = 460800; break; | ||
265 | case B230400 : baud = 230400; break; | ||
266 | case B115200 : baud = 115200; break; | ||
267 | case B57600 : baud = 57600; break; | ||
268 | case B38400 : baud = 38400; break; | ||
269 | case B19200 : baud = 19200; break; | ||
270 | case B9600 : baud = 9600; break; | ||
271 | case B4800 : baud = 4800; break; | ||
272 | case B2400 : baud = 2400; break; | ||
273 | case B1800 : baud = 1800; break; | ||
274 | case B1200 : baud = 1200; break; | ||
275 | case B600 : baud = 600; break; | ||
276 | case B300 : baud = 300; break; | ||
277 | case B200 : baud = 200; break; | ||
278 | case B150 : baud = 150; break; | ||
279 | case B134 : baud = 134; break; | ||
280 | case B110 : baud = 110; break; | ||
281 | case B75 : baud = 75; break; | ||
282 | case B50 : baud = 50; break; | ||
283 | default : baud = 9600; break; | ||
284 | } | ||
285 | |||
286 | if (baud == 38400) | ||
287 | baud = altbaud; | ||
288 | |||
289 | if (baud == 0) | ||
290 | baud = 9600; | ||
291 | |||
292 | if (baud >= min && baud <= max) | ||
293 | return baud; | ||
294 | |||
295 | termios->c_cflag &= ~CBAUD; | ||
296 | if (old) { | ||
297 | termios->c_cflag |= old->c_cflag & CBAUD; | ||
298 | old = NULL; | ||
299 | continue; | ||
300 | } | ||
301 | |||
302 | termios->c_cflag |= B9600; | ||
303 | } | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | unsigned int sb_uart_get_divisor(struct sb_uart_port *port, unsigned int baud) | ||
308 | { | ||
309 | unsigned int quot; | ||
310 | |||
311 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) | ||
312 | quot = port->custom_divisor; | ||
313 | else | ||
314 | quot = (port->uartclk + (8 * baud)) / (16 * baud); | ||
315 | |||
316 | return quot; | ||
317 | } | ||
318 | |||
319 | |||
320 | |||
321 | static inline int sb_uart_handle_break(struct sb_uart_port *port) | ||
322 | { | ||
323 | struct sb_uart_info *info = port->info; | ||
324 | |||
325 | if (port->flags & UPF_SAK) | ||
326 | do_SAK(info->tty); | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static inline void sb_uart_handle_dcd_change(struct sb_uart_port *port, unsigned int status) | ||
331 | { | ||
332 | struct sb_uart_info *info = port->info; | ||
333 | |||
334 | port->icount.dcd++; | ||
335 | |||
336 | if (info->flags & UIF_CHECK_CD) { | ||
337 | if (status) | ||
338 | wake_up_interruptible(&info->open_wait); | ||
339 | else if (info->tty) | ||
340 | tty_hangup(info->tty); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | static inline void sb_uart_handle_cts_change(struct sb_uart_port *port, unsigned int status) | ||
345 | { | ||
346 | struct sb_uart_info *info = port->info; | ||
347 | struct tty_struct *tty = info->tty; | ||
348 | |||
349 | port->icount.cts++; | ||
350 | |||
351 | if (info->flags & UIF_CTS_FLOW) { | ||
352 | if (tty->hw_stopped) { | ||
353 | if (status) { | ||
354 | tty->hw_stopped = 0; | ||
355 | port->ops->start_tx(port); | ||
356 | sb_uart_write_wakeup(port); | ||
357 | } | ||
358 | } else { | ||
359 | if (!status) { | ||
360 | tty->hw_stopped = 1; | ||
361 | port->ops->stop_tx(port); | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
367 | |||
368 | |||
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 42d0a2581a87..9d7d00cdfecb 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -1771,6 +1771,7 @@ fail_free_irq: | |||
1771 | fail_unregister: | 1771 | fail_unregister: |
1772 | tty_unregister_driver(serial_driver); | 1772 | tty_unregister_driver(serial_driver); |
1773 | fail_put_tty_driver: | 1773 | fail_put_tty_driver: |
1774 | tty_port_destroy(&state->tport); | ||
1774 | put_tty_driver(serial_driver); | 1775 | put_tty_driver(serial_driver); |
1775 | return error; | 1776 | return error; |
1776 | } | 1777 | } |
@@ -1785,6 +1786,7 @@ static int __exit amiga_serial_remove(struct platform_device *pdev) | |||
1785 | printk("SERIAL: failed to unregister serial driver (%d)\n", | 1786 | printk("SERIAL: failed to unregister serial driver (%d)\n", |
1786 | error); | 1787 | error); |
1787 | put_tty_driver(serial_driver); | 1788 | put_tty_driver(serial_driver); |
1789 | tty_port_destroy(&state->tport); | ||
1788 | 1790 | ||
1789 | free_irq(IRQ_AMIGA_TBE, state); | 1791 | free_irq(IRQ_AMIGA_TBE, state); |
1790 | free_irq(IRQ_AMIGA_RBF, state); | 1792 | free_irq(IRQ_AMIGA_RBF, state); |
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 02b7d3a09696..1cfcdbf1d0cc 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c | |||
@@ -240,8 +240,6 @@ static int __init bfin_jc_init(void) | |||
240 | { | 240 | { |
241 | int ret; | 241 | int ret; |
242 | 242 | ||
243 | tty_port_init(&port); | ||
244 | |||
245 | bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); | 243 | bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); |
246 | if (IS_ERR(bfin_jc_kthread)) | 244 | if (IS_ERR(bfin_jc_kthread)) |
247 | return PTR_ERR(bfin_jc_kthread); | 245 | return PTR_ERR(bfin_jc_kthread); |
@@ -257,6 +255,8 @@ static int __init bfin_jc_init(void) | |||
257 | if (!bfin_jc_driver) | 255 | if (!bfin_jc_driver) |
258 | goto err_driver; | 256 | goto err_driver; |
259 | 257 | ||
258 | tty_port_init(&port); | ||
259 | |||
260 | bfin_jc_driver->driver_name = DRV_NAME; | 260 | bfin_jc_driver->driver_name = DRV_NAME; |
261 | bfin_jc_driver->name = DEV_NAME; | 261 | bfin_jc_driver->name = DEV_NAME; |
262 | bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; | 262 | bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; |
@@ -274,6 +274,7 @@ static int __init bfin_jc_init(void) | |||
274 | return 0; | 274 | return 0; |
275 | 275 | ||
276 | err: | 276 | err: |
277 | tty_port_destroy(&port); | ||
277 | put_tty_driver(bfin_jc_driver); | 278 | put_tty_driver(bfin_jc_driver); |
278 | err_driver: | 279 | err_driver: |
279 | kfree(bfin_jc_write_buf.buf); | 280 | kfree(bfin_jc_write_buf.buf); |
@@ -289,6 +290,7 @@ static void __exit bfin_jc_exit(void) | |||
289 | kfree(bfin_jc_write_buf.buf); | 290 | kfree(bfin_jc_write_buf.buf); |
290 | tty_unregister_driver(bfin_jc_driver); | 291 | tty_unregister_driver(bfin_jc_driver); |
291 | put_tty_driver(bfin_jc_driver); | 292 | put_tty_driver(bfin_jc_driver); |
293 | tty_port_destroy(&port); | ||
292 | } | 294 | } |
293 | module_exit(bfin_jc_exit); | 295 | module_exit(bfin_jc_exit); |
294 | 296 | ||
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 0a6a0bc1b598..b09c8d1f9a66 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -3099,7 +3099,7 @@ static const struct tty_port_operations cyz_port_ops = { | |||
3099 | * --------------------------------------------------------------------- | 3099 | * --------------------------------------------------------------------- |
3100 | */ | 3100 | */ |
3101 | 3101 | ||
3102 | static int __devinit cy_init_card(struct cyclades_card *cinfo) | 3102 | static int cy_init_card(struct cyclades_card *cinfo) |
3103 | { | 3103 | { |
3104 | struct cyclades_port *info; | 3104 | struct cyclades_port *info; |
3105 | unsigned int channel, port; | 3105 | unsigned int channel, port; |
@@ -3196,7 +3196,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
3196 | 3196 | ||
3197 | /* initialize chips on Cyclom-Y card -- return number of valid | 3197 | /* initialize chips on Cyclom-Y card -- return number of valid |
3198 | chips (which is number of ports/4) */ | 3198 | chips (which is number of ports/4) */ |
3199 | static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, | 3199 | static unsigned short cyy_init_card(void __iomem *true_base_addr, |
3200 | int index) | 3200 | int index) |
3201 | { | 3201 | { |
3202 | unsigned int chip_number; | 3202 | unsigned int chip_number; |
@@ -3405,7 +3405,7 @@ static int __init cy_detect_isa(void) | |||
3405 | } /* cy_detect_isa */ | 3405 | } /* cy_detect_isa */ |
3406 | 3406 | ||
3407 | #ifdef CONFIG_PCI | 3407 | #ifdef CONFIG_PCI |
3408 | static inline int __devinit cyc_isfwstr(const char *str, unsigned int size) | 3408 | static inline int cyc_isfwstr(const char *str, unsigned int size) |
3409 | { | 3409 | { |
3410 | unsigned int a; | 3410 | unsigned int a; |
3411 | 3411 | ||
@@ -3420,7 +3420,7 @@ static inline int __devinit cyc_isfwstr(const char *str, unsigned int size) | |||
3420 | return 0; | 3420 | return 0; |
3421 | } | 3421 | } |
3422 | 3422 | ||
3423 | static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data, | 3423 | static inline void cyz_fpga_copy(void __iomem *fpga, const u8 *data, |
3424 | unsigned int size) | 3424 | unsigned int size) |
3425 | { | 3425 | { |
3426 | for (; size > 0; size--) { | 3426 | for (; size > 0; size--) { |
@@ -3429,7 +3429,7 @@ static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data, | |||
3429 | } | 3429 | } |
3430 | } | 3430 | } |
3431 | 3431 | ||
3432 | static void __devinit plx_init(struct pci_dev *pdev, int irq, | 3432 | static void plx_init(struct pci_dev *pdev, int irq, |
3433 | struct RUNTIME_9060 __iomem *addr) | 3433 | struct RUNTIME_9060 __iomem *addr) |
3434 | { | 3434 | { |
3435 | /* Reset PLX */ | 3435 | /* Reset PLX */ |
@@ -3449,7 +3449,7 @@ static void __devinit plx_init(struct pci_dev *pdev, int irq, | |||
3449 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); | 3449 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); |
3450 | } | 3450 | } |
3451 | 3451 | ||
3452 | static int __devinit __cyz_load_fw(const struct firmware *fw, | 3452 | static int __cyz_load_fw(const struct firmware *fw, |
3453 | const char *name, const u32 mailbox, void __iomem *base, | 3453 | const char *name, const u32 mailbox, void __iomem *base, |
3454 | void __iomem *fpga) | 3454 | void __iomem *fpga) |
3455 | { | 3455 | { |
@@ -3526,7 +3526,7 @@ static int __devinit __cyz_load_fw(const struct firmware *fw, | |||
3526 | return 0; | 3526 | return 0; |
3527 | } | 3527 | } |
3528 | 3528 | ||
3529 | static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr, | 3529 | static int cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr, |
3530 | struct RUNTIME_9060 __iomem *ctl_addr, int irq) | 3530 | struct RUNTIME_9060 __iomem *ctl_addr, int irq) |
3531 | { | 3531 | { |
3532 | const struct firmware *fw; | 3532 | const struct firmware *fw; |
@@ -3692,7 +3692,7 @@ err: | |||
3692 | return retval; | 3692 | return retval; |
3693 | } | 3693 | } |
3694 | 3694 | ||
3695 | static int __devinit cy_pci_probe(struct pci_dev *pdev, | 3695 | static int cy_pci_probe(struct pci_dev *pdev, |
3696 | const struct pci_device_id *ent) | 3696 | const struct pci_device_id *ent) |
3697 | { | 3697 | { |
3698 | struct cyclades_card *card; | 3698 | struct cyclades_card *card; |
@@ -3931,10 +3931,10 @@ err: | |||
3931 | return retval; | 3931 | return retval; |
3932 | } | 3932 | } |
3933 | 3933 | ||
3934 | static void __devexit cy_pci_remove(struct pci_dev *pdev) | 3934 | static void cy_pci_remove(struct pci_dev *pdev) |
3935 | { | 3935 | { |
3936 | struct cyclades_card *cinfo = pci_get_drvdata(pdev); | 3936 | struct cyclades_card *cinfo = pci_get_drvdata(pdev); |
3937 | unsigned int i; | 3937 | unsigned int i, channel; |
3938 | 3938 | ||
3939 | /* non-Z with old PLX */ | 3939 | /* non-Z with old PLX */ |
3940 | if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == | 3940 | if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == |
@@ -3960,9 +3960,11 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev) | |||
3960 | pci_release_regions(pdev); | 3960 | pci_release_regions(pdev); |
3961 | 3961 | ||
3962 | cinfo->base_addr = NULL; | 3962 | cinfo->base_addr = NULL; |
3963 | for (i = cinfo->first_line; i < cinfo->first_line + | 3963 | for (channel = 0, i = cinfo->first_line; i < cinfo->first_line + |
3964 | cinfo->nports; i++) | 3964 | cinfo->nports; i++, channel++) { |
3965 | tty_unregister_device(cy_serial_driver, i); | 3965 | tty_unregister_device(cy_serial_driver, i); |
3966 | tty_port_destroy(&cinfo->ports[channel].port); | ||
3967 | } | ||
3966 | cinfo->nports = 0; | 3968 | cinfo->nports = 0; |
3967 | kfree(cinfo->ports); | 3969 | kfree(cinfo->ports); |
3968 | } | 3970 | } |
@@ -3971,7 +3973,7 @@ static struct pci_driver cy_pci_driver = { | |||
3971 | .name = "cyclades", | 3973 | .name = "cyclades", |
3972 | .id_table = cy_pci_dev_id, | 3974 | .id_table = cy_pci_dev_id, |
3973 | .probe = cy_pci_probe, | 3975 | .probe = cy_pci_probe, |
3974 | .remove = __devexit_p(cy_pci_remove) | 3976 | .remove = cy_pci_remove |
3975 | }; | 3977 | }; |
3976 | #endif | 3978 | #endif |
3977 | 3979 | ||
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 4ab936b7aac6..c117d775a22f 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -699,7 +699,7 @@ static const struct tty_port_operations ehv_bc_tty_port_ops = { | |||
699 | .shutdown = ehv_bc_tty_port_shutdown, | 699 | .shutdown = ehv_bc_tty_port_shutdown, |
700 | }; | 700 | }; |
701 | 701 | ||
702 | static int __devinit ehv_bc_tty_probe(struct platform_device *pdev) | 702 | static int ehv_bc_tty_probe(struct platform_device *pdev) |
703 | { | 703 | { |
704 | struct device_node *np = pdev->dev.of_node; | 704 | struct device_node *np = pdev->dev.of_node; |
705 | struct ehv_bc_data *bc; | 705 | struct ehv_bc_data *bc; |
@@ -757,6 +757,7 @@ static int __devinit ehv_bc_tty_probe(struct platform_device *pdev) | |||
757 | return 0; | 757 | return 0; |
758 | 758 | ||
759 | error: | 759 | error: |
760 | tty_port_destroy(&bc->port); | ||
760 | irq_dispose_mapping(bc->tx_irq); | 761 | irq_dispose_mapping(bc->tx_irq); |
761 | irq_dispose_mapping(bc->rx_irq); | 762 | irq_dispose_mapping(bc->rx_irq); |
762 | 763 | ||
@@ -770,6 +771,7 @@ static int ehv_bc_tty_remove(struct platform_device *pdev) | |||
770 | 771 | ||
771 | tty_unregister_device(ehv_bc_driver, bc - bcs); | 772 | tty_unregister_device(ehv_bc_driver, bc - bcs); |
772 | 773 | ||
774 | tty_port_destroy(&bc->port); | ||
773 | irq_dispose_mapping(bc->tx_irq); | 775 | irq_dispose_mapping(bc->tx_irq); |
774 | irq_dispose_mapping(bc->rx_irq); | 776 | irq_dispose_mapping(bc->rx_irq); |
775 | 777 | ||
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 0d2ea0c224c3..be1a9a1e749e 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | static const char hvc_opal_name[] = "hvc_opal"; | 42 | static const char hvc_opal_name[] = "hvc_opal"; |
43 | 43 | ||
44 | static struct of_device_id hvc_opal_match[] __devinitdata = { | 44 | static struct of_device_id hvc_opal_match[] = { |
45 | { .name = "serial", .compatible = "ibm,opal-console-raw" }, | 45 | { .name = "serial", .compatible = "ibm,opal-console-raw" }, |
46 | { .name = "serial", .compatible = "ibm,opal-console-hvsi" }, | 46 | { .name = "serial", .compatible = "ibm,opal-console-hvsi" }, |
47 | { }, | 47 | { }, |
@@ -161,7 +161,7 @@ static const struct hv_ops hvc_opal_hvsi_ops = { | |||
161 | .tiocmset = hvc_opal_hvsi_tiocmset, | 161 | .tiocmset = hvc_opal_hvsi_tiocmset, |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static int __devinit hvc_opal_probe(struct platform_device *dev) | 164 | static int hvc_opal_probe(struct platform_device *dev) |
165 | { | 165 | { |
166 | const struct hv_ops *ops; | 166 | const struct hv_ops *ops; |
167 | struct hvc_struct *hp; | 167 | struct hvc_struct *hp; |
@@ -222,7 +222,7 @@ static int __devinit hvc_opal_probe(struct platform_device *dev) | |||
222 | return 0; | 222 | return 0; |
223 | } | 223 | } |
224 | 224 | ||
225 | static int __devexit hvc_opal_remove(struct platform_device *dev) | 225 | static int hvc_opal_remove(struct platform_device *dev) |
226 | { | 226 | { |
227 | struct hvc_struct *hp = dev_get_drvdata(&dev->dev); | 227 | struct hvc_struct *hp = dev_get_drvdata(&dev->dev); |
228 | int rc, termno; | 228 | int rc, termno; |
@@ -239,7 +239,7 @@ static int __devexit hvc_opal_remove(struct platform_device *dev) | |||
239 | 239 | ||
240 | static struct platform_driver hvc_opal_driver = { | 240 | static struct platform_driver hvc_opal_driver = { |
241 | .probe = hvc_opal_probe, | 241 | .probe = hvc_opal_probe, |
242 | .remove = __devexit_p(hvc_opal_remove), | 242 | .remove = hvc_opal_remove, |
243 | .driver = { | 243 | .driver = { |
244 | .name = hvc_opal_name, | 244 | .name = hvc_opal_name, |
245 | .owner = THIS_MODULE, | 245 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 070c0ee68642..ed6f5f1f5a55 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c | |||
@@ -53,7 +53,7 @@ | |||
53 | 53 | ||
54 | static const char hvc_driver_name[] = "hvc_console"; | 54 | static const char hvc_driver_name[] = "hvc_console"; |
55 | 55 | ||
56 | static struct vio_device_id hvc_driver_table[] __devinitdata = { | 56 | static struct vio_device_id hvc_driver_table[] = { |
57 | {"serial", "hvterm1"}, | 57 | {"serial", "hvterm1"}, |
58 | #ifndef HVC_OLD_HVSI | 58 | #ifndef HVC_OLD_HVSI |
59 | {"serial", "hvterm-protocol"}, | 59 | {"serial", "hvterm-protocol"}, |
@@ -293,7 +293,7 @@ static int udbg_hvc_getc(void) | |||
293 | } | 293 | } |
294 | } | 294 | } |
295 | 295 | ||
296 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, | 296 | static int hvc_vio_probe(struct vio_dev *vdev, |
297 | const struct vio_device_id *id) | 297 | const struct vio_device_id *id) |
298 | { | 298 | { |
299 | const struct hv_ops *ops; | 299 | const struct hv_ops *ops; |
@@ -362,7 +362,7 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev, | |||
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | static int __devexit hvc_vio_remove(struct vio_dev *vdev) | 365 | static int hvc_vio_remove(struct vio_dev *vdev) |
366 | { | 366 | { |
367 | struct hvc_struct *hp = dev_get_drvdata(&vdev->dev); | 367 | struct hvc_struct *hp = dev_get_drvdata(&vdev->dev); |
368 | int rc, termno; | 368 | int rc, termno; |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index f4abfe238f98..19843ec3f80a 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -422,7 +422,7 @@ static int xencons_connect_backend(struct xenbus_device *dev, | |||
422 | return ret; | 422 | return ret; |
423 | } | 423 | } |
424 | 424 | ||
425 | static int __devinit xencons_probe(struct xenbus_device *dev, | 425 | static int xencons_probe(struct xenbus_device *dev, |
426 | const struct xenbus_device_id *id) | 426 | const struct xenbus_device_id *id) |
427 | { | 427 | { |
428 | int ret, devid; | 428 | int ret, devid; |
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index cab5c7adf8e8..877635733952 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -330,12 +330,12 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp); | |||
330 | static void hvcs_close(struct tty_struct *tty, struct file *filp); | 330 | static void hvcs_close(struct tty_struct *tty, struct file *filp); |
331 | static void hvcs_hangup(struct tty_struct * tty); | 331 | static void hvcs_hangup(struct tty_struct * tty); |
332 | 332 | ||
333 | static int __devinit hvcs_probe(struct vio_dev *dev, | 333 | static int hvcs_probe(struct vio_dev *dev, |
334 | const struct vio_device_id *id); | 334 | const struct vio_device_id *id); |
335 | static int __devexit hvcs_remove(struct vio_dev *dev); | 335 | static int hvcs_remove(struct vio_dev *dev); |
336 | static int __init hvcs_module_init(void); | 336 | static int __init hvcs_module_init(void); |
337 | static void __exit hvcs_module_exit(void); | 337 | static void __exit hvcs_module_exit(void); |
338 | static int __devinit hvcs_initialize(void); | 338 | static int hvcs_initialize(void); |
339 | 339 | ||
340 | #define HVCS_SCHED_READ 0x00000001 | 340 | #define HVCS_SCHED_READ 0x00000001 |
341 | #define HVCS_QUICK_READ 0x00000002 | 341 | #define HVCS_QUICK_READ 0x00000002 |
@@ -676,7 +676,7 @@ static int khvcsd(void *unused) | |||
676 | return 0; | 676 | return 0; |
677 | } | 677 | } |
678 | 678 | ||
679 | static struct vio_device_id hvcs_driver_table[] __devinitdata= { | 679 | static struct vio_device_id hvcs_driver_table[] = { |
680 | {"serial-server", "hvterm2"}, | 680 | {"serial-server", "hvterm2"}, |
681 | { "", "" } | 681 | { "", "" } |
682 | }; | 682 | }; |
@@ -756,7 +756,7 @@ static int hvcs_get_index(void) | |||
756 | return -1; | 756 | return -1; |
757 | } | 757 | } |
758 | 758 | ||
759 | static int __devinit hvcs_probe( | 759 | static int hvcs_probe( |
760 | struct vio_dev *dev, | 760 | struct vio_dev *dev, |
761 | const struct vio_device_id *id) | 761 | const struct vio_device_id *id) |
762 | { | 762 | { |
@@ -835,7 +835,7 @@ static int __devinit hvcs_probe( | |||
835 | return 0; | 835 | return 0; |
836 | } | 836 | } |
837 | 837 | ||
838 | static int __devexit hvcs_remove(struct vio_dev *dev) | 838 | static int hvcs_remove(struct vio_dev *dev) |
839 | { | 839 | { |
840 | struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev); | 840 | struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev); |
841 | unsigned long flags; | 841 | unsigned long flags; |
@@ -874,7 +874,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev) | |||
874 | static struct vio_driver hvcs_vio_driver = { | 874 | static struct vio_driver hvcs_vio_driver = { |
875 | .id_table = hvcs_driver_table, | 875 | .id_table = hvcs_driver_table, |
876 | .probe = hvcs_probe, | 876 | .probe = hvcs_probe, |
877 | .remove = __devexit_p(hvcs_remove), | 877 | .remove = hvcs_remove, |
878 | .name = hvcs_driver_name, | 878 | .name = hvcs_driver_name, |
879 | }; | 879 | }; |
880 | 880 | ||
@@ -1478,7 +1478,7 @@ static void hvcs_free_index_list(void) | |||
1478 | hvcs_index_count = 0; | 1478 | hvcs_index_count = 0; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | static int __devinit hvcs_initialize(void) | 1481 | static int hvcs_initialize(void) |
1482 | { | 1482 | { |
1483 | int rc, num_ttys_to_alloc; | 1483 | int rc, num_ttys_to_alloc; |
1484 | 1484 | ||
@@ -1496,8 +1496,10 @@ static int __devinit hvcs_initialize(void) | |||
1496 | num_ttys_to_alloc = hvcs_parm_num_devs; | 1496 | num_ttys_to_alloc = hvcs_parm_num_devs; |
1497 | 1497 | ||
1498 | hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc); | 1498 | hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc); |
1499 | if (!hvcs_tty_driver) | 1499 | if (!hvcs_tty_driver) { |
1500 | mutex_unlock(&hvcs_init_mutex); | ||
1500 | return -ENOMEM; | 1501 | return -ENOMEM; |
1502 | } | ||
1501 | 1503 | ||
1502 | if (hvcs_alloc_index_list(num_ttys_to_alloc)) { | 1504 | if (hvcs_alloc_index_list(num_ttys_to_alloc)) { |
1503 | rc = -ENOMEM; | 1505 | rc = -ENOMEM; |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 5b95b4f28cf3..68357a6e4de9 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
@@ -1218,6 +1218,7 @@ static int __init hvsi_console_init(void) | |||
1218 | if (hp->virq == 0) { | 1218 | if (hp->virq == 0) { |
1219 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", | 1219 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", |
1220 | __func__, irq[0]); | 1220 | __func__, irq[0]); |
1221 | tty_port_destroy(&hp->port); | ||
1221 | continue; | 1222 | continue; |
1222 | } | 1223 | } |
1223 | 1224 | ||
diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index 57102e66165a..c0dfb642383b 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c | |||
@@ -352,6 +352,8 @@ static struct sk_buff *ipw_packet_received_skb(unsigned char *data, | |||
352 | } | 352 | } |
353 | 353 | ||
354 | skb = dev_alloc_skb(length + 4); | 354 | skb = dev_alloc_skb(length + 4); |
355 | if (skb == NULL) | ||
356 | return NULL; | ||
355 | skb_reserve(skb, 2); | 357 | skb_reserve(skb, 2); |
356 | memcpy(skb_put(skb, length), data, length); | 358 | memcpy(skb_put(skb, length), data, length); |
357 | 359 | ||
@@ -397,7 +399,8 @@ void ipwireless_network_packet_received(struct ipw_network *network, | |||
397 | 399 | ||
398 | /* Send the data to the ppp_generic module. */ | 400 | /* Send the data to the ppp_generic module. */ |
399 | skb = ipw_packet_received_skb(data, length); | 401 | skb = ipw_packet_received_skb(data, length); |
400 | ppp_input(network->ppp_channel, skb); | 402 | if (skb) |
403 | ppp_input(network->ppp_channel, skb); | ||
401 | } else | 404 | } else |
402 | spin_unlock_irqrestore(&network->lock, | 405 | spin_unlock_irqrestore(&network->lock, |
403 | flags); | 406 | flags); |
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 160f0ad9589d..2cde13ddf9fc 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
@@ -566,6 +566,7 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
566 | ipwireless_disassociate_network_ttys(network, | 566 | ipwireless_disassociate_network_ttys(network, |
567 | ttyj->channel_idx); | 567 | ttyj->channel_idx); |
568 | tty_unregister_device(ipw_tty_driver, j); | 568 | tty_unregister_device(ipw_tty_driver, j); |
569 | tty_port_destroy(&ttyj->port); | ||
569 | ttys[j] = NULL; | 570 | ttys[j] = NULL; |
570 | mutex_unlock(&ttyj->ipw_tty_mutex); | 571 | mutex_unlock(&ttyj->ipw_tty_mutex); |
571 | kfree(ttyj); | 572 | kfree(ttyj); |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index d7492e183607..3205b2e9090b 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -148,7 +148,7 @@ | |||
148 | #endif | 148 | #endif |
149 | 149 | ||
150 | static int isicom_probe(struct pci_dev *, const struct pci_device_id *); | 150 | static int isicom_probe(struct pci_dev *, const struct pci_device_id *); |
151 | static void __devexit isicom_remove(struct pci_dev *); | 151 | static void isicom_remove(struct pci_dev *); |
152 | 152 | ||
153 | static struct pci_device_id isicom_pci_tbl[] = { | 153 | static struct pci_device_id isicom_pci_tbl[] = { |
154 | { PCI_DEVICE(VENDOR_ID, 0x2028) }, | 154 | { PCI_DEVICE(VENDOR_ID, 0x2028) }, |
@@ -168,7 +168,7 @@ static struct pci_driver isicom_driver = { | |||
168 | .name = "isicom", | 168 | .name = "isicom", |
169 | .id_table = isicom_pci_tbl, | 169 | .id_table = isicom_pci_tbl, |
170 | .probe = isicom_probe, | 170 | .probe = isicom_probe, |
171 | .remove = __devexit_p(isicom_remove) | 171 | .remove = isicom_remove |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static int prev_card = 3; /* start servicing isi_card[0] */ | 174 | static int prev_card = 3; /* start servicing isi_card[0] */ |
@@ -603,7 +603,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
603 | if (tty_port_cts_enabled(&port->port)) { | 603 | if (tty_port_cts_enabled(&port->port)) { |
604 | if (tty->hw_stopped) { | 604 | if (tty->hw_stopped) { |
605 | if (header & ISI_CTS) { | 605 | if (header & ISI_CTS) { |
606 | port->port.tty->hw_stopped = 0; | 606 | tty->hw_stopped = 0; |
607 | /* start tx ing */ | 607 | /* start tx ing */ |
608 | port->status |= (ISI_TXOK | 608 | port->status |= (ISI_TXOK |
609 | | ISI_CTS); | 609 | | ISI_CTS); |
@@ -1307,7 +1307,7 @@ static const struct tty_port_operations isicom_port_ops = { | |||
1307 | .shutdown = isicom_shutdown, | 1307 | .shutdown = isicom_shutdown, |
1308 | }; | 1308 | }; |
1309 | 1309 | ||
1310 | static int __devinit reset_card(struct pci_dev *pdev, | 1310 | static int reset_card(struct pci_dev *pdev, |
1311 | const unsigned int card, unsigned int *signature) | 1311 | const unsigned int card, unsigned int *signature) |
1312 | { | 1312 | { |
1313 | struct isi_board *board = pci_get_drvdata(pdev); | 1313 | struct isi_board *board = pci_get_drvdata(pdev); |
@@ -1368,7 +1368,7 @@ end: | |||
1368 | return retval; | 1368 | return retval; |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | static int __devinit load_firmware(struct pci_dev *pdev, | 1371 | static int load_firmware(struct pci_dev *pdev, |
1372 | const unsigned int index, const unsigned int signature) | 1372 | const unsigned int index, const unsigned int signature) |
1373 | { | 1373 | { |
1374 | struct isi_board *board = pci_get_drvdata(pdev); | 1374 | struct isi_board *board = pci_get_drvdata(pdev); |
@@ -1548,7 +1548,7 @@ end: | |||
1548 | */ | 1548 | */ |
1549 | static unsigned int card_count; | 1549 | static unsigned int card_count; |
1550 | 1550 | ||
1551 | static int __devinit isicom_probe(struct pci_dev *pdev, | 1551 | static int isicom_probe(struct pci_dev *pdev, |
1552 | const struct pci_device_id *ent) | 1552 | const struct pci_device_id *ent) |
1553 | { | 1553 | { |
1554 | unsigned int uninitialized_var(signature), index; | 1554 | unsigned int uninitialized_var(signature), index; |
@@ -1610,10 +1610,15 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1610 | if (retval < 0) | 1610 | if (retval < 0) |
1611 | goto errunri; | 1611 | goto errunri; |
1612 | 1612 | ||
1613 | for (index = 0; index < board->port_count; index++) | 1613 | for (index = 0; index < board->port_count; index++) { |
1614 | tty_port_register_device(&board->ports[index].port, | 1614 | struct tty_port *tport = &board->ports[index].port; |
1615 | isicom_normal, board->index * 16 + index, | 1615 | tty_port_init(tport); |
1616 | &pdev->dev); | 1616 | tport->ops = &isicom_port_ops; |
1617 | tport->close_delay = 50 * HZ/100; | ||
1618 | tport->closing_wait = 3000 * HZ/100; | ||
1619 | tty_port_register_device(tport, isicom_normal, | ||
1620 | board->index * 16 + index, &pdev->dev); | ||
1621 | } | ||
1617 | 1622 | ||
1618 | return 0; | 1623 | return 0; |
1619 | 1624 | ||
@@ -1630,13 +1635,15 @@ err: | |||
1630 | return retval; | 1635 | return retval; |
1631 | } | 1636 | } |
1632 | 1637 | ||
1633 | static void __devexit isicom_remove(struct pci_dev *pdev) | 1638 | static void isicom_remove(struct pci_dev *pdev) |
1634 | { | 1639 | { |
1635 | struct isi_board *board = pci_get_drvdata(pdev); | 1640 | struct isi_board *board = pci_get_drvdata(pdev); |
1636 | unsigned int i; | 1641 | unsigned int i; |
1637 | 1642 | ||
1638 | for (i = 0; i < board->port_count; i++) | 1643 | for (i = 0; i < board->port_count; i++) { |
1639 | tty_unregister_device(isicom_normal, board->index * 16 + i); | 1644 | tty_unregister_device(isicom_normal, board->index * 16 + i); |
1645 | tty_port_destroy(&board->ports[i].port); | ||
1646 | } | ||
1640 | 1647 | ||
1641 | free_irq(board->irq, board); | 1648 | free_irq(board->irq, board); |
1642 | pci_release_region(pdev, 3); | 1649 | pci_release_region(pdev, 3); |
@@ -1655,13 +1662,9 @@ static int __init isicom_init(void) | |||
1655 | isi_card[idx].ports = port; | 1662 | isi_card[idx].ports = port; |
1656 | spin_lock_init(&isi_card[idx].card_lock); | 1663 | spin_lock_init(&isi_card[idx].card_lock); |
1657 | for (channel = 0; channel < 16; channel++, port++) { | 1664 | for (channel = 0; channel < 16; channel++, port++) { |
1658 | tty_port_init(&port->port); | ||
1659 | port->port.ops = &isicom_port_ops; | ||
1660 | port->magic = ISICOM_MAGIC; | 1665 | port->magic = ISICOM_MAGIC; |
1661 | port->card = &isi_card[idx]; | 1666 | port->card = &isi_card[idx]; |
1662 | port->channel = channel; | 1667 | port->channel = channel; |
1663 | port->port.close_delay = 50 * HZ/100; | ||
1664 | port->port.closing_wait = 3000 * HZ/100; | ||
1665 | port->status = 0; | 1668 | port->status = 0; |
1666 | /* . . . */ | 1669 | /* . . . */ |
1667 | } | 1670 | } |
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 56e616b9109a..f9d28503bdec 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -895,6 +895,8 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | |||
895 | 895 | ||
896 | return 0; | 896 | return 0; |
897 | err_free: | 897 | err_free: |
898 | for (i = 0; i < MAX_PORTS_PER_BOARD; i++) | ||
899 | tty_port_destroy(&brd->ports[i].port); | ||
898 | kfree(brd->ports); | 900 | kfree(brd->ports); |
899 | err: | 901 | err: |
900 | return ret; | 902 | return ret; |
@@ -919,6 +921,8 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
919 | tty_kref_put(tty); | 921 | tty_kref_put(tty); |
920 | } | 922 | } |
921 | } | 923 | } |
924 | for (a = 0; a < MAX_PORTS_PER_BOARD; a++) | ||
925 | tty_port_destroy(&brd->ports[a].port); | ||
922 | while (1) { | 926 | while (1) { |
923 | opened = 0; | 927 | opened = 0; |
924 | for (a = 0; a < brd->numPorts; a++) | 928 | for (a = 0; a < brd->numPorts; a++) |
@@ -941,7 +945,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
941 | } | 945 | } |
942 | 946 | ||
943 | #ifdef CONFIG_PCI | 947 | #ifdef CONFIG_PCI |
944 | static int __devinit moxa_pci_probe(struct pci_dev *pdev, | 948 | static int moxa_pci_probe(struct pci_dev *pdev, |
945 | const struct pci_device_id *ent) | 949 | const struct pci_device_id *ent) |
946 | { | 950 | { |
947 | struct moxa_board_conf *board; | 951 | struct moxa_board_conf *board; |
@@ -1016,7 +1020,7 @@ err: | |||
1016 | return retval; | 1020 | return retval; |
1017 | } | 1021 | } |
1018 | 1022 | ||
1019 | static void __devexit moxa_pci_remove(struct pci_dev *pdev) | 1023 | static void moxa_pci_remove(struct pci_dev *pdev) |
1020 | { | 1024 | { |
1021 | struct moxa_board_conf *brd = pci_get_drvdata(pdev); | 1025 | struct moxa_board_conf *brd = pci_get_drvdata(pdev); |
1022 | 1026 | ||
@@ -1029,7 +1033,7 @@ static struct pci_driver moxa_pci_driver = { | |||
1029 | .name = "moxa", | 1033 | .name = "moxa", |
1030 | .id_table = moxa_pcibrds, | 1034 | .id_table = moxa_pcibrds, |
1031 | .probe = moxa_pci_probe, | 1035 | .probe = moxa_pci_probe, |
1032 | .remove = __devexit_p(moxa_pci_remove) | 1036 | .remove = moxa_pci_remove |
1033 | }; | 1037 | }; |
1034 | #endif /* CONFIG_PCI */ | 1038 | #endif /* CONFIG_PCI */ |
1035 | 1039 | ||
@@ -1370,7 +1374,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | |||
1370 | p->DCDState = dcd; | 1374 | p->DCDState = dcd; |
1371 | spin_unlock_irqrestore(&p->port.lock, flags); | 1375 | spin_unlock_irqrestore(&p->port.lock, flags); |
1372 | tty = tty_port_tty_get(&p->port); | 1376 | tty = tty_port_tty_get(&p->port); |
1373 | if (tty && C_CLOCAL(tty) && !dcd) | 1377 | if (tty && !C_CLOCAL(tty) && !dcd) |
1374 | tty_hangup(tty); | 1378 | tty_hangup(tty); |
1375 | tty_kref_put(tty); | 1379 | tty_kref_put(tty); |
1376 | } | 1380 | } |
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index cfda47dabd28..40113868bec2 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -487,7 +487,7 @@ static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) | |||
487 | } | 487 | } |
488 | 488 | ||
489 | #ifdef CONFIG_PCI | 489 | #ifdef CONFIG_PCI |
490 | static int __devinit CheckIsMoxaMust(unsigned long io) | 490 | static int CheckIsMoxaMust(unsigned long io) |
491 | { | 491 | { |
492 | u8 oldmcr, hwid; | 492 | u8 oldmcr, hwid; |
493 | int i; | 493 | int i; |
@@ -2369,7 +2369,7 @@ static void mxser_release_ISA_res(struct mxser_board *brd) | |||
2369 | mxser_release_vector(brd); | 2369 | mxser_release_vector(brd); |
2370 | } | 2370 | } |
2371 | 2371 | ||
2372 | static int __devinit mxser_initbrd(struct mxser_board *brd, | 2372 | static int mxser_initbrd(struct mxser_board *brd, |
2373 | struct pci_dev *pdev) | 2373 | struct pci_dev *pdev) |
2374 | { | 2374 | { |
2375 | struct mxser_port *info; | 2375 | struct mxser_port *info; |
@@ -2411,14 +2411,27 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2411 | 2411 | ||
2412 | retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", | 2412 | retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", |
2413 | brd); | 2413 | brd); |
2414 | if (retval) | 2414 | if (retval) { |
2415 | for (i = 0; i < brd->info->nports; i++) | ||
2416 | tty_port_destroy(&brd->ports[i].port); | ||
2415 | printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " | 2417 | printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " |
2416 | "conflict with another device.\n", | 2418 | "conflict with another device.\n", |
2417 | brd->info->name, brd->irq); | 2419 | brd->info->name, brd->irq); |
2420 | } | ||
2418 | 2421 | ||
2419 | return retval; | 2422 | return retval; |
2420 | } | 2423 | } |
2421 | 2424 | ||
2425 | static void mxser_board_remove(struct mxser_board *brd) | ||
2426 | { | ||
2427 | unsigned int i; | ||
2428 | |||
2429 | for (i = 0; i < brd->info->nports; i++) { | ||
2430 | tty_unregister_device(mxvar_sdriver, brd->idx + i); | ||
2431 | tty_port_destroy(&brd->ports[i].port); | ||
2432 | } | ||
2433 | } | ||
2434 | |||
2422 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | 2435 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) |
2423 | { | 2436 | { |
2424 | int id, i, bits, ret; | 2437 | int id, i, bits, ret; |
@@ -2534,7 +2547,7 @@ err_irqconflict: | |||
2534 | return -EIO; | 2547 | return -EIO; |
2535 | } | 2548 | } |
2536 | 2549 | ||
2537 | static int __devinit mxser_probe(struct pci_dev *pdev, | 2550 | static int mxser_probe(struct pci_dev *pdev, |
2538 | const struct pci_device_id *ent) | 2551 | const struct pci_device_id *ent) |
2539 | { | 2552 | { |
2540 | #ifdef CONFIG_PCI | 2553 | #ifdef CONFIG_PCI |
@@ -2645,14 +2658,12 @@ err: | |||
2645 | #endif | 2658 | #endif |
2646 | } | 2659 | } |
2647 | 2660 | ||
2648 | static void __devexit mxser_remove(struct pci_dev *pdev) | 2661 | static void mxser_remove(struct pci_dev *pdev) |
2649 | { | 2662 | { |
2650 | #ifdef CONFIG_PCI | 2663 | #ifdef CONFIG_PCI |
2651 | struct mxser_board *brd = pci_get_drvdata(pdev); | 2664 | struct mxser_board *brd = pci_get_drvdata(pdev); |
2652 | unsigned int i; | ||
2653 | 2665 | ||
2654 | for (i = 0; i < brd->info->nports; i++) | 2666 | mxser_board_remove(brd); |
2655 | tty_unregister_device(mxvar_sdriver, brd->idx + i); | ||
2656 | 2667 | ||
2657 | free_irq(pdev->irq, brd); | 2668 | free_irq(pdev->irq, brd); |
2658 | pci_release_region(pdev, 2); | 2669 | pci_release_region(pdev, 2); |
@@ -2666,7 +2677,7 @@ static struct pci_driver mxser_driver = { | |||
2666 | .name = "mxser", | 2677 | .name = "mxser", |
2667 | .id_table = mxser_pcibrds, | 2678 | .id_table = mxser_pcibrds, |
2668 | .probe = mxser_probe, | 2679 | .probe = mxser_probe, |
2669 | .remove = __devexit_p(mxser_remove) | 2680 | .remove = mxser_remove |
2670 | }; | 2681 | }; |
2671 | 2682 | ||
2672 | static int __init mxser_module_init(void) | 2683 | static int __init mxser_module_init(void) |
@@ -2748,15 +2759,13 @@ err_put: | |||
2748 | 2759 | ||
2749 | static void __exit mxser_module_exit(void) | 2760 | static void __exit mxser_module_exit(void) |
2750 | { | 2761 | { |
2751 | unsigned int i, j; | 2762 | unsigned int i; |
2752 | 2763 | ||
2753 | pci_unregister_driver(&mxser_driver); | 2764 | pci_unregister_driver(&mxser_driver); |
2754 | 2765 | ||
2755 | for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ | 2766 | for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ |
2756 | if (mxser_boards[i].info != NULL) | 2767 | if (mxser_boards[i].info != NULL) |
2757 | for (j = 0; j < mxser_boards[i].info->nports; j++) | 2768 | mxser_board_remove(&mxser_boards[i]); |
2758 | tty_unregister_device(mxvar_sdriver, | ||
2759 | mxser_boards[i].idx + j); | ||
2760 | tty_unregister_driver(mxvar_sdriver); | 2769 | tty_unregister_driver(mxvar_sdriver); |
2761 | put_tty_driver(mxvar_sdriver); | 2770 | put_tty_driver(mxvar_sdriver); |
2762 | 2771 | ||
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1e8e8ce55959..dcc0430a49c8 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -134,7 +134,6 @@ struct gsm_dlci { | |||
134 | #define DLCI_OPENING 1 /* Sending SABM not seen UA */ | 134 | #define DLCI_OPENING 1 /* Sending SABM not seen UA */ |
135 | #define DLCI_OPEN 2 /* SABM/UA complete */ | 135 | #define DLCI_OPEN 2 /* SABM/UA complete */ |
136 | #define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */ | 136 | #define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */ |
137 | struct kref ref; /* freed from port or mux close */ | ||
138 | struct mutex mutex; | 137 | struct mutex mutex; |
139 | 138 | ||
140 | /* Link layer */ | 139 | /* Link layer */ |
@@ -1635,7 +1634,6 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) | |||
1635 | if (dlci == NULL) | 1634 | if (dlci == NULL) |
1636 | return NULL; | 1635 | return NULL; |
1637 | spin_lock_init(&dlci->lock); | 1636 | spin_lock_init(&dlci->lock); |
1638 | kref_init(&dlci->ref); | ||
1639 | mutex_init(&dlci->mutex); | 1637 | mutex_init(&dlci->mutex); |
1640 | dlci->fifo = &dlci->_fifo; | 1638 | dlci->fifo = &dlci->_fifo; |
1641 | if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) { | 1639 | if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) { |
@@ -1669,9 +1667,9 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) | |||
1669 | * | 1667 | * |
1670 | * Can sleep. | 1668 | * Can sleep. |
1671 | */ | 1669 | */ |
1672 | static void gsm_dlci_free(struct kref *ref) | 1670 | static void gsm_dlci_free(struct tty_port *port) |
1673 | { | 1671 | { |
1674 | struct gsm_dlci *dlci = container_of(ref, struct gsm_dlci, ref); | 1672 | struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); |
1675 | 1673 | ||
1676 | del_timer_sync(&dlci->t1); | 1674 | del_timer_sync(&dlci->t1); |
1677 | dlci->gsm->dlci[dlci->addr] = NULL; | 1675 | dlci->gsm->dlci[dlci->addr] = NULL; |
@@ -1683,12 +1681,12 @@ static void gsm_dlci_free(struct kref *ref) | |||
1683 | 1681 | ||
1684 | static inline void dlci_get(struct gsm_dlci *dlci) | 1682 | static inline void dlci_get(struct gsm_dlci *dlci) |
1685 | { | 1683 | { |
1686 | kref_get(&dlci->ref); | 1684 | tty_port_get(&dlci->port); |
1687 | } | 1685 | } |
1688 | 1686 | ||
1689 | static inline void dlci_put(struct gsm_dlci *dlci) | 1687 | static inline void dlci_put(struct gsm_dlci *dlci) |
1690 | { | 1688 | { |
1691 | kref_put(&dlci->ref, gsm_dlci_free); | 1689 | tty_port_put(&dlci->port); |
1692 | } | 1690 | } |
1693 | 1691 | ||
1694 | /** | 1692 | /** |
@@ -2874,6 +2872,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff) | |||
2874 | static const struct tty_port_operations gsm_port_ops = { | 2872 | static const struct tty_port_operations gsm_port_ops = { |
2875 | .carrier_raised = gsm_carrier_raised, | 2873 | .carrier_raised = gsm_carrier_raised, |
2876 | .dtr_rts = gsm_dtr_rts, | 2874 | .dtr_rts = gsm_dtr_rts, |
2875 | .destruct = gsm_dlci_free, | ||
2877 | }; | 2876 | }; |
2878 | 2877 | ||
2879 | static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) | 2878 | static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 8c0b7b42319c..19083efa2314 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -73,10 +73,42 @@ | |||
73 | #define ECHO_OP_SET_CANON_COL 0x81 | 73 | #define ECHO_OP_SET_CANON_COL 0x81 |
74 | #define ECHO_OP_ERASE_TAB 0x82 | 74 | #define ECHO_OP_ERASE_TAB 0x82 |
75 | 75 | ||
76 | struct n_tty_data { | ||
77 | unsigned int column; | ||
78 | unsigned long overrun_time; | ||
79 | int num_overrun; | ||
80 | |||
81 | unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; | ||
82 | unsigned char echo_overrun:1; | ||
83 | |||
84 | DECLARE_BITMAP(process_char_map, 256); | ||
85 | DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); | ||
86 | |||
87 | char *read_buf; | ||
88 | int read_head; | ||
89 | int read_tail; | ||
90 | int read_cnt; | ||
91 | |||
92 | unsigned char *echo_buf; | ||
93 | unsigned int echo_pos; | ||
94 | unsigned int echo_cnt; | ||
95 | |||
96 | int canon_data; | ||
97 | unsigned long canon_head; | ||
98 | unsigned int canon_column; | ||
99 | |||
100 | struct mutex atomic_read_lock; | ||
101 | struct mutex output_lock; | ||
102 | struct mutex echo_lock; | ||
103 | spinlock_t read_lock; | ||
104 | }; | ||
105 | |||
76 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | 106 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, |
77 | unsigned char __user *ptr) | 107 | unsigned char __user *ptr) |
78 | { | 108 | { |
79 | tty_audit_add_data(tty, &x, 1); | 109 | struct n_tty_data *ldata = tty->disc_data; |
110 | |||
111 | tty_audit_add_data(tty, &x, 1, ldata->icanon); | ||
80 | return put_user(x, ptr); | 112 | return put_user(x, ptr); |
81 | } | 113 | } |
82 | 114 | ||
@@ -92,17 +124,18 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
92 | 124 | ||
93 | static void n_tty_set_room(struct tty_struct *tty) | 125 | static void n_tty_set_room(struct tty_struct *tty) |
94 | { | 126 | { |
127 | struct n_tty_data *ldata = tty->disc_data; | ||
95 | int left; | 128 | int left; |
96 | int old_left; | 129 | int old_left; |
97 | 130 | ||
98 | /* tty->read_cnt is not read locked ? */ | 131 | /* ldata->read_cnt is not read locked ? */ |
99 | if (I_PARMRK(tty)) { | 132 | if (I_PARMRK(tty)) { |
100 | /* Multiply read_cnt by 3, since each byte might take up to | 133 | /* Multiply read_cnt by 3, since each byte might take up to |
101 | * three times as many spaces when PARMRK is set (depending on | 134 | * three times as many spaces when PARMRK is set (depending on |
102 | * its flags, e.g. parity error). */ | 135 | * its flags, e.g. parity error). */ |
103 | left = N_TTY_BUF_SIZE - tty->read_cnt * 3 - 1; | 136 | left = N_TTY_BUF_SIZE - ldata->read_cnt * 3 - 1; |
104 | } else | 137 | } else |
105 | left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | 138 | left = N_TTY_BUF_SIZE - ldata->read_cnt - 1; |
106 | 139 | ||
107 | /* | 140 | /* |
108 | * If we are doing input canonicalization, and there are no | 141 | * If we are doing input canonicalization, and there are no |
@@ -111,44 +144,47 @@ static void n_tty_set_room(struct tty_struct *tty) | |||
111 | * characters will be beeped. | 144 | * characters will be beeped. |
112 | */ | 145 | */ |
113 | if (left <= 0) | 146 | if (left <= 0) |
114 | left = tty->icanon && !tty->canon_data; | 147 | left = ldata->icanon && !ldata->canon_data; |
115 | old_left = tty->receive_room; | 148 | old_left = tty->receive_room; |
116 | tty->receive_room = left; | 149 | tty->receive_room = left; |
117 | 150 | ||
118 | /* Did this open up the receive buffer? We may need to flip */ | 151 | /* Did this open up the receive buffer? We may need to flip */ |
119 | if (left && !old_left) | 152 | if (left && !old_left) { |
120 | schedule_work(&tty->buf.work); | 153 | WARN_RATELIMIT(tty->port->itty == NULL, |
154 | "scheduling with invalid itty\n"); | ||
155 | schedule_work(&tty->port->buf.work); | ||
156 | } | ||
121 | } | 157 | } |
122 | 158 | ||
123 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 159 | static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata) |
124 | { | 160 | { |
125 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 161 | if (ldata->read_cnt < N_TTY_BUF_SIZE) { |
126 | tty->read_buf[tty->read_head] = c; | 162 | ldata->read_buf[ldata->read_head] = c; |
127 | tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1); | 163 | ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1); |
128 | tty->read_cnt++; | 164 | ldata->read_cnt++; |
129 | } | 165 | } |
130 | } | 166 | } |
131 | 167 | ||
132 | /** | 168 | /** |
133 | * put_tty_queue - add character to tty | 169 | * put_tty_queue - add character to tty |
134 | * @c: character | 170 | * @c: character |
135 | * @tty: tty device | 171 | * @ldata: n_tty data |
136 | * | 172 | * |
137 | * Add a character to the tty read_buf queue. This is done under the | 173 | * Add a character to the tty read_buf queue. This is done under the |
138 | * read_lock to serialize character addition and also to protect us | 174 | * read_lock to serialize character addition and also to protect us |
139 | * against parallel reads or flushes | 175 | * against parallel reads or flushes |
140 | */ | 176 | */ |
141 | 177 | ||
142 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) | 178 | static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) |
143 | { | 179 | { |
144 | unsigned long flags; | 180 | unsigned long flags; |
145 | /* | 181 | /* |
146 | * The problem of stomping on the buffers ends here. | 182 | * The problem of stomping on the buffers ends here. |
147 | * Why didn't anyone see this one coming? --AJK | 183 | * Why didn't anyone see this one coming? --AJK |
148 | */ | 184 | */ |
149 | spin_lock_irqsave(&tty->read_lock, flags); | 185 | spin_lock_irqsave(&ldata->read_lock, flags); |
150 | put_tty_queue_nolock(c, tty); | 186 | put_tty_queue_nolock(c, ldata); |
151 | spin_unlock_irqrestore(&tty->read_lock, flags); | 187 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
152 | } | 188 | } |
153 | 189 | ||
154 | /** | 190 | /** |
@@ -179,18 +215,19 @@ static void check_unthrottle(struct tty_struct *tty) | |||
179 | 215 | ||
180 | static void reset_buffer_flags(struct tty_struct *tty) | 216 | static void reset_buffer_flags(struct tty_struct *tty) |
181 | { | 217 | { |
218 | struct n_tty_data *ldata = tty->disc_data; | ||
182 | unsigned long flags; | 219 | unsigned long flags; |
183 | 220 | ||
184 | spin_lock_irqsave(&tty->read_lock, flags); | 221 | spin_lock_irqsave(&ldata->read_lock, flags); |
185 | tty->read_head = tty->read_tail = tty->read_cnt = 0; | 222 | ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; |
186 | spin_unlock_irqrestore(&tty->read_lock, flags); | 223 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
187 | 224 | ||
188 | mutex_lock(&tty->echo_lock); | 225 | mutex_lock(&ldata->echo_lock); |
189 | tty->echo_pos = tty->echo_cnt = tty->echo_overrun = 0; | 226 | ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; |
190 | mutex_unlock(&tty->echo_lock); | 227 | mutex_unlock(&ldata->echo_lock); |
191 | 228 | ||
192 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 229 | ldata->canon_head = ldata->canon_data = ldata->erasing = 0; |
193 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 230 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); |
194 | n_tty_set_room(tty); | 231 | n_tty_set_room(tty); |
195 | } | 232 | } |
196 | 233 | ||
@@ -235,18 +272,19 @@ static void n_tty_flush_buffer(struct tty_struct *tty) | |||
235 | 272 | ||
236 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | 273 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) |
237 | { | 274 | { |
275 | struct n_tty_data *ldata = tty->disc_data; | ||
238 | unsigned long flags; | 276 | unsigned long flags; |
239 | ssize_t n = 0; | 277 | ssize_t n = 0; |
240 | 278 | ||
241 | spin_lock_irqsave(&tty->read_lock, flags); | 279 | spin_lock_irqsave(&ldata->read_lock, flags); |
242 | if (!tty->icanon) { | 280 | if (!ldata->icanon) { |
243 | n = tty->read_cnt; | 281 | n = ldata->read_cnt; |
244 | } else if (tty->canon_data) { | 282 | } else if (ldata->canon_data) { |
245 | n = (tty->canon_head > tty->read_tail) ? | 283 | n = (ldata->canon_head > ldata->read_tail) ? |
246 | tty->canon_head - tty->read_tail : | 284 | ldata->canon_head - ldata->read_tail : |
247 | tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail); | 285 | ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); |
248 | } | 286 | } |
249 | spin_unlock_irqrestore(&tty->read_lock, flags); | 287 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
250 | return n; | 288 | return n; |
251 | } | 289 | } |
252 | 290 | ||
@@ -301,6 +339,7 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty) | |||
301 | 339 | ||
302 | static int do_output_char(unsigned char c, struct tty_struct *tty, int space) | 340 | static int do_output_char(unsigned char c, struct tty_struct *tty, int space) |
303 | { | 341 | { |
342 | struct n_tty_data *ldata = tty->disc_data; | ||
304 | int spaces; | 343 | int spaces; |
305 | 344 | ||
306 | if (!space) | 345 | if (!space) |
@@ -309,48 +348,48 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) | |||
309 | switch (c) { | 348 | switch (c) { |
310 | case '\n': | 349 | case '\n': |
311 | if (O_ONLRET(tty)) | 350 | if (O_ONLRET(tty)) |
312 | tty->column = 0; | 351 | ldata->column = 0; |
313 | if (O_ONLCR(tty)) { | 352 | if (O_ONLCR(tty)) { |
314 | if (space < 2) | 353 | if (space < 2) |
315 | return -1; | 354 | return -1; |
316 | tty->canon_column = tty->column = 0; | 355 | ldata->canon_column = ldata->column = 0; |
317 | tty->ops->write(tty, "\r\n", 2); | 356 | tty->ops->write(tty, "\r\n", 2); |
318 | return 2; | 357 | return 2; |
319 | } | 358 | } |
320 | tty->canon_column = tty->column; | 359 | ldata->canon_column = ldata->column; |
321 | break; | 360 | break; |
322 | case '\r': | 361 | case '\r': |
323 | if (O_ONOCR(tty) && tty->column == 0) | 362 | if (O_ONOCR(tty) && ldata->column == 0) |
324 | return 0; | 363 | return 0; |
325 | if (O_OCRNL(tty)) { | 364 | if (O_OCRNL(tty)) { |
326 | c = '\n'; | 365 | c = '\n'; |
327 | if (O_ONLRET(tty)) | 366 | if (O_ONLRET(tty)) |
328 | tty->canon_column = tty->column = 0; | 367 | ldata->canon_column = ldata->column = 0; |
329 | break; | 368 | break; |
330 | } | 369 | } |
331 | tty->canon_column = tty->column = 0; | 370 | ldata->canon_column = ldata->column = 0; |
332 | break; | 371 | break; |
333 | case '\t': | 372 | case '\t': |
334 | spaces = 8 - (tty->column & 7); | 373 | spaces = 8 - (ldata->column & 7); |
335 | if (O_TABDLY(tty) == XTABS) { | 374 | if (O_TABDLY(tty) == XTABS) { |
336 | if (space < spaces) | 375 | if (space < spaces) |
337 | return -1; | 376 | return -1; |
338 | tty->column += spaces; | 377 | ldata->column += spaces; |
339 | tty->ops->write(tty, " ", spaces); | 378 | tty->ops->write(tty, " ", spaces); |
340 | return spaces; | 379 | return spaces; |
341 | } | 380 | } |
342 | tty->column += spaces; | 381 | ldata->column += spaces; |
343 | break; | 382 | break; |
344 | case '\b': | 383 | case '\b': |
345 | if (tty->column > 0) | 384 | if (ldata->column > 0) |
346 | tty->column--; | 385 | ldata->column--; |
347 | break; | 386 | break; |
348 | default: | 387 | default: |
349 | if (!iscntrl(c)) { | 388 | if (!iscntrl(c)) { |
350 | if (O_OLCUC(tty)) | 389 | if (O_OLCUC(tty)) |
351 | c = toupper(c); | 390 | c = toupper(c); |
352 | if (!is_continuation(c, tty)) | 391 | if (!is_continuation(c, tty)) |
353 | tty->column++; | 392 | ldata->column++; |
354 | } | 393 | } |
355 | break; | 394 | break; |
356 | } | 395 | } |
@@ -375,14 +414,15 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) | |||
375 | 414 | ||
376 | static int process_output(unsigned char c, struct tty_struct *tty) | 415 | static int process_output(unsigned char c, struct tty_struct *tty) |
377 | { | 416 | { |
417 | struct n_tty_data *ldata = tty->disc_data; | ||
378 | int space, retval; | 418 | int space, retval; |
379 | 419 | ||
380 | mutex_lock(&tty->output_lock); | 420 | mutex_lock(&ldata->output_lock); |
381 | 421 | ||
382 | space = tty_write_room(tty); | 422 | space = tty_write_room(tty); |
383 | retval = do_output_char(c, tty, space); | 423 | retval = do_output_char(c, tty, space); |
384 | 424 | ||
385 | mutex_unlock(&tty->output_lock); | 425 | mutex_unlock(&ldata->output_lock); |
386 | if (retval < 0) | 426 | if (retval < 0) |
387 | return -1; | 427 | return -1; |
388 | else | 428 | else |
@@ -411,15 +451,16 @@ static int process_output(unsigned char c, struct tty_struct *tty) | |||
411 | static ssize_t process_output_block(struct tty_struct *tty, | 451 | static ssize_t process_output_block(struct tty_struct *tty, |
412 | const unsigned char *buf, unsigned int nr) | 452 | const unsigned char *buf, unsigned int nr) |
413 | { | 453 | { |
454 | struct n_tty_data *ldata = tty->disc_data; | ||
414 | int space; | 455 | int space; |
415 | int i; | 456 | int i; |
416 | const unsigned char *cp; | 457 | const unsigned char *cp; |
417 | 458 | ||
418 | mutex_lock(&tty->output_lock); | 459 | mutex_lock(&ldata->output_lock); |
419 | 460 | ||
420 | space = tty_write_room(tty); | 461 | space = tty_write_room(tty); |
421 | if (!space) { | 462 | if (!space) { |
422 | mutex_unlock(&tty->output_lock); | 463 | mutex_unlock(&ldata->output_lock); |
423 | return 0; | 464 | return 0; |
424 | } | 465 | } |
425 | if (nr > space) | 466 | if (nr > space) |
@@ -431,30 +472,30 @@ static ssize_t process_output_block(struct tty_struct *tty, | |||
431 | switch (c) { | 472 | switch (c) { |
432 | case '\n': | 473 | case '\n': |
433 | if (O_ONLRET(tty)) | 474 | if (O_ONLRET(tty)) |
434 | tty->column = 0; | 475 | ldata->column = 0; |
435 | if (O_ONLCR(tty)) | 476 | if (O_ONLCR(tty)) |
436 | goto break_out; | 477 | goto break_out; |
437 | tty->canon_column = tty->column; | 478 | ldata->canon_column = ldata->column; |
438 | break; | 479 | break; |
439 | case '\r': | 480 | case '\r': |
440 | if (O_ONOCR(tty) && tty->column == 0) | 481 | if (O_ONOCR(tty) && ldata->column == 0) |
441 | goto break_out; | 482 | goto break_out; |
442 | if (O_OCRNL(tty)) | 483 | if (O_OCRNL(tty)) |
443 | goto break_out; | 484 | goto break_out; |
444 | tty->canon_column = tty->column = 0; | 485 | ldata->canon_column = ldata->column = 0; |
445 | break; | 486 | break; |
446 | case '\t': | 487 | case '\t': |
447 | goto break_out; | 488 | goto break_out; |
448 | case '\b': | 489 | case '\b': |
449 | if (tty->column > 0) | 490 | if (ldata->column > 0) |
450 | tty->column--; | 491 | ldata->column--; |
451 | break; | 492 | break; |
452 | default: | 493 | default: |
453 | if (!iscntrl(c)) { | 494 | if (!iscntrl(c)) { |
454 | if (O_OLCUC(tty)) | 495 | if (O_OLCUC(tty)) |
455 | goto break_out; | 496 | goto break_out; |
456 | if (!is_continuation(c, tty)) | 497 | if (!is_continuation(c, tty)) |
457 | tty->column++; | 498 | ldata->column++; |
458 | } | 499 | } |
459 | break; | 500 | break; |
460 | } | 501 | } |
@@ -462,7 +503,7 @@ static ssize_t process_output_block(struct tty_struct *tty, | |||
462 | break_out: | 503 | break_out: |
463 | i = tty->ops->write(tty, buf, i); | 504 | i = tty->ops->write(tty, buf, i); |
464 | 505 | ||
465 | mutex_unlock(&tty->output_lock); | 506 | mutex_unlock(&ldata->output_lock); |
466 | return i; | 507 | return i; |
467 | } | 508 | } |
468 | 509 | ||
@@ -494,21 +535,22 @@ break_out: | |||
494 | 535 | ||
495 | static void process_echoes(struct tty_struct *tty) | 536 | static void process_echoes(struct tty_struct *tty) |
496 | { | 537 | { |
538 | struct n_tty_data *ldata = tty->disc_data; | ||
497 | int space, nr; | 539 | int space, nr; |
498 | unsigned char c; | 540 | unsigned char c; |
499 | unsigned char *cp, *buf_end; | 541 | unsigned char *cp, *buf_end; |
500 | 542 | ||
501 | if (!tty->echo_cnt) | 543 | if (!ldata->echo_cnt) |
502 | return; | 544 | return; |
503 | 545 | ||
504 | mutex_lock(&tty->output_lock); | 546 | mutex_lock(&ldata->output_lock); |
505 | mutex_lock(&tty->echo_lock); | 547 | mutex_lock(&ldata->echo_lock); |
506 | 548 | ||
507 | space = tty_write_room(tty); | 549 | space = tty_write_room(tty); |
508 | 550 | ||
509 | buf_end = tty->echo_buf + N_TTY_BUF_SIZE; | 551 | buf_end = ldata->echo_buf + N_TTY_BUF_SIZE; |
510 | cp = tty->echo_buf + tty->echo_pos; | 552 | cp = ldata->echo_buf + ldata->echo_pos; |
511 | nr = tty->echo_cnt; | 553 | nr = ldata->echo_cnt; |
512 | while (nr > 0) { | 554 | while (nr > 0) { |
513 | c = *cp; | 555 | c = *cp; |
514 | if (c == ECHO_OP_START) { | 556 | if (c == ECHO_OP_START) { |
@@ -545,7 +587,7 @@ static void process_echoes(struct tty_struct *tty) | |||
545 | * Otherwise, tab spacing is normal. | 587 | * Otherwise, tab spacing is normal. |
546 | */ | 588 | */ |
547 | if (!(num_chars & 0x80)) | 589 | if (!(num_chars & 0x80)) |
548 | num_chars += tty->canon_column; | 590 | num_chars += ldata->canon_column; |
549 | num_bs = 8 - (num_chars & 7); | 591 | num_bs = 8 - (num_chars & 7); |
550 | 592 | ||
551 | if (num_bs > space) { | 593 | if (num_bs > space) { |
@@ -555,22 +597,22 @@ static void process_echoes(struct tty_struct *tty) | |||
555 | space -= num_bs; | 597 | space -= num_bs; |
556 | while (num_bs--) { | 598 | while (num_bs--) { |
557 | tty_put_char(tty, '\b'); | 599 | tty_put_char(tty, '\b'); |
558 | if (tty->column > 0) | 600 | if (ldata->column > 0) |
559 | tty->column--; | 601 | ldata->column--; |
560 | } | 602 | } |
561 | cp += 3; | 603 | cp += 3; |
562 | nr -= 3; | 604 | nr -= 3; |
563 | break; | 605 | break; |
564 | 606 | ||
565 | case ECHO_OP_SET_CANON_COL: | 607 | case ECHO_OP_SET_CANON_COL: |
566 | tty->canon_column = tty->column; | 608 | ldata->canon_column = ldata->column; |
567 | cp += 2; | 609 | cp += 2; |
568 | nr -= 2; | 610 | nr -= 2; |
569 | break; | 611 | break; |
570 | 612 | ||
571 | case ECHO_OP_MOVE_BACK_COL: | 613 | case ECHO_OP_MOVE_BACK_COL: |
572 | if (tty->column > 0) | 614 | if (ldata->column > 0) |
573 | tty->column--; | 615 | ldata->column--; |
574 | cp += 2; | 616 | cp += 2; |
575 | nr -= 2; | 617 | nr -= 2; |
576 | break; | 618 | break; |
@@ -582,7 +624,7 @@ static void process_echoes(struct tty_struct *tty) | |||
582 | break; | 624 | break; |
583 | } | 625 | } |
584 | tty_put_char(tty, ECHO_OP_START); | 626 | tty_put_char(tty, ECHO_OP_START); |
585 | tty->column++; | 627 | ldata->column++; |
586 | space--; | 628 | space--; |
587 | cp += 2; | 629 | cp += 2; |
588 | nr -= 2; | 630 | nr -= 2; |
@@ -604,7 +646,7 @@ static void process_echoes(struct tty_struct *tty) | |||
604 | } | 646 | } |
605 | tty_put_char(tty, '^'); | 647 | tty_put_char(tty, '^'); |
606 | tty_put_char(tty, op ^ 0100); | 648 | tty_put_char(tty, op ^ 0100); |
607 | tty->column += 2; | 649 | ldata->column += 2; |
608 | space -= 2; | 650 | space -= 2; |
609 | cp += 2; | 651 | cp += 2; |
610 | nr -= 2; | 652 | nr -= 2; |
@@ -635,20 +677,20 @@ static void process_echoes(struct tty_struct *tty) | |||
635 | } | 677 | } |
636 | 678 | ||
637 | if (nr == 0) { | 679 | if (nr == 0) { |
638 | tty->echo_pos = 0; | 680 | ldata->echo_pos = 0; |
639 | tty->echo_cnt = 0; | 681 | ldata->echo_cnt = 0; |
640 | tty->echo_overrun = 0; | 682 | ldata->echo_overrun = 0; |
641 | } else { | 683 | } else { |
642 | int num_processed = tty->echo_cnt - nr; | 684 | int num_processed = ldata->echo_cnt - nr; |
643 | tty->echo_pos += num_processed; | 685 | ldata->echo_pos += num_processed; |
644 | tty->echo_pos &= N_TTY_BUF_SIZE - 1; | 686 | ldata->echo_pos &= N_TTY_BUF_SIZE - 1; |
645 | tty->echo_cnt = nr; | 687 | ldata->echo_cnt = nr; |
646 | if (num_processed > 0) | 688 | if (num_processed > 0) |
647 | tty->echo_overrun = 0; | 689 | ldata->echo_overrun = 0; |
648 | } | 690 | } |
649 | 691 | ||
650 | mutex_unlock(&tty->echo_lock); | 692 | mutex_unlock(&ldata->echo_lock); |
651 | mutex_unlock(&tty->output_lock); | 693 | mutex_unlock(&ldata->output_lock); |
652 | 694 | ||
653 | if (tty->ops->flush_chars) | 695 | if (tty->ops->flush_chars) |
654 | tty->ops->flush_chars(tty); | 696 | tty->ops->flush_chars(tty); |
@@ -657,72 +699,70 @@ static void process_echoes(struct tty_struct *tty) | |||
657 | /** | 699 | /** |
658 | * add_echo_byte - add a byte to the echo buffer | 700 | * add_echo_byte - add a byte to the echo buffer |
659 | * @c: unicode byte to echo | 701 | * @c: unicode byte to echo |
660 | * @tty: terminal device | 702 | * @ldata: n_tty data |
661 | * | 703 | * |
662 | * Add a character or operation byte to the echo buffer. | 704 | * Add a character or operation byte to the echo buffer. |
663 | * | 705 | * |
664 | * Should be called under the echo lock to protect the echo buffer. | 706 | * Should be called under the echo lock to protect the echo buffer. |
665 | */ | 707 | */ |
666 | 708 | ||
667 | static void add_echo_byte(unsigned char c, struct tty_struct *tty) | 709 | static void add_echo_byte(unsigned char c, struct n_tty_data *ldata) |
668 | { | 710 | { |
669 | int new_byte_pos; | 711 | int new_byte_pos; |
670 | 712 | ||
671 | if (tty->echo_cnt == N_TTY_BUF_SIZE) { | 713 | if (ldata->echo_cnt == N_TTY_BUF_SIZE) { |
672 | /* Circular buffer is already at capacity */ | 714 | /* Circular buffer is already at capacity */ |
673 | new_byte_pos = tty->echo_pos; | 715 | new_byte_pos = ldata->echo_pos; |
674 | 716 | ||
675 | /* | 717 | /* |
676 | * Since the buffer start position needs to be advanced, | 718 | * Since the buffer start position needs to be advanced, |
677 | * be sure to step by a whole operation byte group. | 719 | * be sure to step by a whole operation byte group. |
678 | */ | 720 | */ |
679 | if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) { | 721 | if (ldata->echo_buf[ldata->echo_pos] == ECHO_OP_START) { |
680 | if (tty->echo_buf[(tty->echo_pos + 1) & | 722 | if (ldata->echo_buf[(ldata->echo_pos + 1) & |
681 | (N_TTY_BUF_SIZE - 1)] == | 723 | (N_TTY_BUF_SIZE - 1)] == |
682 | ECHO_OP_ERASE_TAB) { | 724 | ECHO_OP_ERASE_TAB) { |
683 | tty->echo_pos += 3; | 725 | ldata->echo_pos += 3; |
684 | tty->echo_cnt -= 2; | 726 | ldata->echo_cnt -= 2; |
685 | } else { | 727 | } else { |
686 | tty->echo_pos += 2; | 728 | ldata->echo_pos += 2; |
687 | tty->echo_cnt -= 1; | 729 | ldata->echo_cnt -= 1; |
688 | } | 730 | } |
689 | } else { | 731 | } else { |
690 | tty->echo_pos++; | 732 | ldata->echo_pos++; |
691 | } | 733 | } |
692 | tty->echo_pos &= N_TTY_BUF_SIZE - 1; | 734 | ldata->echo_pos &= N_TTY_BUF_SIZE - 1; |
693 | 735 | ||
694 | tty->echo_overrun = 1; | 736 | ldata->echo_overrun = 1; |
695 | } else { | 737 | } else { |
696 | new_byte_pos = tty->echo_pos + tty->echo_cnt; | 738 | new_byte_pos = ldata->echo_pos + ldata->echo_cnt; |
697 | new_byte_pos &= N_TTY_BUF_SIZE - 1; | 739 | new_byte_pos &= N_TTY_BUF_SIZE - 1; |
698 | tty->echo_cnt++; | 740 | ldata->echo_cnt++; |
699 | } | 741 | } |
700 | 742 | ||
701 | tty->echo_buf[new_byte_pos] = c; | 743 | ldata->echo_buf[new_byte_pos] = c; |
702 | } | 744 | } |
703 | 745 | ||
704 | /** | 746 | /** |
705 | * echo_move_back_col - add operation to move back a column | 747 | * echo_move_back_col - add operation to move back a column |
706 | * @tty: terminal device | 748 | * @ldata: n_tty data |
707 | * | 749 | * |
708 | * Add an operation to the echo buffer to move back one column. | 750 | * Add an operation to the echo buffer to move back one column. |
709 | * | 751 | * |
710 | * Locking: echo_lock to protect the echo buffer | 752 | * Locking: echo_lock to protect the echo buffer |
711 | */ | 753 | */ |
712 | 754 | ||
713 | static void echo_move_back_col(struct tty_struct *tty) | 755 | static void echo_move_back_col(struct n_tty_data *ldata) |
714 | { | 756 | { |
715 | mutex_lock(&tty->echo_lock); | 757 | mutex_lock(&ldata->echo_lock); |
716 | 758 | add_echo_byte(ECHO_OP_START, ldata); | |
717 | add_echo_byte(ECHO_OP_START, tty); | 759 | add_echo_byte(ECHO_OP_MOVE_BACK_COL, ldata); |
718 | add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty); | 760 | mutex_unlock(&ldata->echo_lock); |
719 | |||
720 | mutex_unlock(&tty->echo_lock); | ||
721 | } | 761 | } |
722 | 762 | ||
723 | /** | 763 | /** |
724 | * echo_set_canon_col - add operation to set the canon column | 764 | * echo_set_canon_col - add operation to set the canon column |
725 | * @tty: terminal device | 765 | * @ldata: n_tty data |
726 | * | 766 | * |
727 | * Add an operation to the echo buffer to set the canon column | 767 | * Add an operation to the echo buffer to set the canon column |
728 | * to the current column. | 768 | * to the current column. |
@@ -730,21 +770,19 @@ static void echo_move_back_col(struct tty_struct *tty) | |||
730 | * Locking: echo_lock to protect the echo buffer | 770 | * Locking: echo_lock to protect the echo buffer |
731 | */ | 771 | */ |
732 | 772 | ||
733 | static void echo_set_canon_col(struct tty_struct *tty) | 773 | static void echo_set_canon_col(struct n_tty_data *ldata) |
734 | { | 774 | { |
735 | mutex_lock(&tty->echo_lock); | 775 | mutex_lock(&ldata->echo_lock); |
736 | 776 | add_echo_byte(ECHO_OP_START, ldata); | |
737 | add_echo_byte(ECHO_OP_START, tty); | 777 | add_echo_byte(ECHO_OP_SET_CANON_COL, ldata); |
738 | add_echo_byte(ECHO_OP_SET_CANON_COL, tty); | 778 | mutex_unlock(&ldata->echo_lock); |
739 | |||
740 | mutex_unlock(&tty->echo_lock); | ||
741 | } | 779 | } |
742 | 780 | ||
743 | /** | 781 | /** |
744 | * echo_erase_tab - add operation to erase a tab | 782 | * echo_erase_tab - add operation to erase a tab |
745 | * @num_chars: number of character columns already used | 783 | * @num_chars: number of character columns already used |
746 | * @after_tab: true if num_chars starts after a previous tab | 784 | * @after_tab: true if num_chars starts after a previous tab |
747 | * @tty: terminal device | 785 | * @ldata: n_tty data |
748 | * | 786 | * |
749 | * Add an operation to the echo buffer to erase a tab. | 787 | * Add an operation to the echo buffer to erase a tab. |
750 | * | 788 | * |
@@ -758,12 +796,12 @@ static void echo_set_canon_col(struct tty_struct *tty) | |||
758 | */ | 796 | */ |
759 | 797 | ||
760 | static void echo_erase_tab(unsigned int num_chars, int after_tab, | 798 | static void echo_erase_tab(unsigned int num_chars, int after_tab, |
761 | struct tty_struct *tty) | 799 | struct n_tty_data *ldata) |
762 | { | 800 | { |
763 | mutex_lock(&tty->echo_lock); | 801 | mutex_lock(&ldata->echo_lock); |
764 | 802 | ||
765 | add_echo_byte(ECHO_OP_START, tty); | 803 | add_echo_byte(ECHO_OP_START, ldata); |
766 | add_echo_byte(ECHO_OP_ERASE_TAB, tty); | 804 | add_echo_byte(ECHO_OP_ERASE_TAB, ldata); |
767 | 805 | ||
768 | /* We only need to know this modulo 8 (tab spacing) */ | 806 | /* We only need to know this modulo 8 (tab spacing) */ |
769 | num_chars &= 7; | 807 | num_chars &= 7; |
@@ -772,9 +810,9 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, | |||
772 | if (after_tab) | 810 | if (after_tab) |
773 | num_chars |= 0x80; | 811 | num_chars |= 0x80; |
774 | 812 | ||
775 | add_echo_byte(num_chars, tty); | 813 | add_echo_byte(num_chars, ldata); |
776 | 814 | ||
777 | mutex_unlock(&tty->echo_lock); | 815 | mutex_unlock(&ldata->echo_lock); |
778 | } | 816 | } |
779 | 817 | ||
780 | /** | 818 | /** |
@@ -790,18 +828,16 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, | |||
790 | * Locking: echo_lock to protect the echo buffer | 828 | * Locking: echo_lock to protect the echo buffer |
791 | */ | 829 | */ |
792 | 830 | ||
793 | static void echo_char_raw(unsigned char c, struct tty_struct *tty) | 831 | static void echo_char_raw(unsigned char c, struct n_tty_data *ldata) |
794 | { | 832 | { |
795 | mutex_lock(&tty->echo_lock); | 833 | mutex_lock(&ldata->echo_lock); |
796 | |||
797 | if (c == ECHO_OP_START) { | 834 | if (c == ECHO_OP_START) { |
798 | add_echo_byte(ECHO_OP_START, tty); | 835 | add_echo_byte(ECHO_OP_START, ldata); |
799 | add_echo_byte(ECHO_OP_START, tty); | 836 | add_echo_byte(ECHO_OP_START, ldata); |
800 | } else { | 837 | } else { |
801 | add_echo_byte(c, tty); | 838 | add_echo_byte(c, ldata); |
802 | } | 839 | } |
803 | 840 | mutex_unlock(&ldata->echo_lock); | |
804 | mutex_unlock(&tty->echo_lock); | ||
805 | } | 841 | } |
806 | 842 | ||
807 | /** | 843 | /** |
@@ -820,30 +856,32 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty) | |||
820 | 856 | ||
821 | static void echo_char(unsigned char c, struct tty_struct *tty) | 857 | static void echo_char(unsigned char c, struct tty_struct *tty) |
822 | { | 858 | { |
823 | mutex_lock(&tty->echo_lock); | 859 | struct n_tty_data *ldata = tty->disc_data; |
860 | |||
861 | mutex_lock(&ldata->echo_lock); | ||
824 | 862 | ||
825 | if (c == ECHO_OP_START) { | 863 | if (c == ECHO_OP_START) { |
826 | add_echo_byte(ECHO_OP_START, tty); | 864 | add_echo_byte(ECHO_OP_START, ldata); |
827 | add_echo_byte(ECHO_OP_START, tty); | 865 | add_echo_byte(ECHO_OP_START, ldata); |
828 | } else { | 866 | } else { |
829 | if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') | 867 | if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') |
830 | add_echo_byte(ECHO_OP_START, tty); | 868 | add_echo_byte(ECHO_OP_START, ldata); |
831 | add_echo_byte(c, tty); | 869 | add_echo_byte(c, ldata); |
832 | } | 870 | } |
833 | 871 | ||
834 | mutex_unlock(&tty->echo_lock); | 872 | mutex_unlock(&ldata->echo_lock); |
835 | } | 873 | } |
836 | 874 | ||
837 | /** | 875 | /** |
838 | * finish_erasing - complete erase | 876 | * finish_erasing - complete erase |
839 | * @tty: tty doing the erase | 877 | * @ldata: n_tty data |
840 | */ | 878 | */ |
841 | 879 | ||
842 | static inline void finish_erasing(struct tty_struct *tty) | 880 | static inline void finish_erasing(struct n_tty_data *ldata) |
843 | { | 881 | { |
844 | if (tty->erasing) { | 882 | if (ldata->erasing) { |
845 | echo_char_raw('/', tty); | 883 | echo_char_raw('/', ldata); |
846 | tty->erasing = 0; | 884 | ldata->erasing = 0; |
847 | } | 885 | } |
848 | } | 886 | } |
849 | 887 | ||
@@ -861,12 +899,13 @@ static inline void finish_erasing(struct tty_struct *tty) | |||
861 | 899 | ||
862 | static void eraser(unsigned char c, struct tty_struct *tty) | 900 | static void eraser(unsigned char c, struct tty_struct *tty) |
863 | { | 901 | { |
902 | struct n_tty_data *ldata = tty->disc_data; | ||
864 | enum { ERASE, WERASE, KILL } kill_type; | 903 | enum { ERASE, WERASE, KILL } kill_type; |
865 | int head, seen_alnums, cnt; | 904 | int head, seen_alnums, cnt; |
866 | unsigned long flags; | 905 | unsigned long flags; |
867 | 906 | ||
868 | /* FIXME: locking needed ? */ | 907 | /* FIXME: locking needed ? */ |
869 | if (tty->read_head == tty->canon_head) { | 908 | if (ldata->read_head == ldata->canon_head) { |
870 | /* process_output('\a', tty); */ /* what do you think? */ | 909 | /* process_output('\a', tty); */ /* what do you think? */ |
871 | return; | 910 | return; |
872 | } | 911 | } |
@@ -876,24 +915,24 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
876 | kill_type = WERASE; | 915 | kill_type = WERASE; |
877 | else { | 916 | else { |
878 | if (!L_ECHO(tty)) { | 917 | if (!L_ECHO(tty)) { |
879 | spin_lock_irqsave(&tty->read_lock, flags); | 918 | spin_lock_irqsave(&ldata->read_lock, flags); |
880 | tty->read_cnt -= ((tty->read_head - tty->canon_head) & | 919 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & |
881 | (N_TTY_BUF_SIZE - 1)); | 920 | (N_TTY_BUF_SIZE - 1)); |
882 | tty->read_head = tty->canon_head; | 921 | ldata->read_head = ldata->canon_head; |
883 | spin_unlock_irqrestore(&tty->read_lock, flags); | 922 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
884 | return; | 923 | return; |
885 | } | 924 | } |
886 | if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { | 925 | if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { |
887 | spin_lock_irqsave(&tty->read_lock, flags); | 926 | spin_lock_irqsave(&ldata->read_lock, flags); |
888 | tty->read_cnt -= ((tty->read_head - tty->canon_head) & | 927 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & |
889 | (N_TTY_BUF_SIZE - 1)); | 928 | (N_TTY_BUF_SIZE - 1)); |
890 | tty->read_head = tty->canon_head; | 929 | ldata->read_head = ldata->canon_head; |
891 | spin_unlock_irqrestore(&tty->read_lock, flags); | 930 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
892 | finish_erasing(tty); | 931 | finish_erasing(ldata); |
893 | echo_char(KILL_CHAR(tty), tty); | 932 | echo_char(KILL_CHAR(tty), tty); |
894 | /* Add a newline if ECHOK is on and ECHOKE is off. */ | 933 | /* Add a newline if ECHOK is on and ECHOKE is off. */ |
895 | if (L_ECHOK(tty)) | 934 | if (L_ECHOK(tty)) |
896 | echo_char_raw('\n', tty); | 935 | echo_char_raw('\n', ldata); |
897 | return; | 936 | return; |
898 | } | 937 | } |
899 | kill_type = KILL; | 938 | kill_type = KILL; |
@@ -901,14 +940,14 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
901 | 940 | ||
902 | seen_alnums = 0; | 941 | seen_alnums = 0; |
903 | /* FIXME: Locking ?? */ | 942 | /* FIXME: Locking ?? */ |
904 | while (tty->read_head != tty->canon_head) { | 943 | while (ldata->read_head != ldata->canon_head) { |
905 | head = tty->read_head; | 944 | head = ldata->read_head; |
906 | 945 | ||
907 | /* erase a single possibly multibyte character */ | 946 | /* erase a single possibly multibyte character */ |
908 | do { | 947 | do { |
909 | head = (head - 1) & (N_TTY_BUF_SIZE-1); | 948 | head = (head - 1) & (N_TTY_BUF_SIZE-1); |
910 | c = tty->read_buf[head]; | 949 | c = ldata->read_buf[head]; |
911 | } while (is_continuation(c, tty) && head != tty->canon_head); | 950 | } while (is_continuation(c, tty) && head != ldata->canon_head); |
912 | 951 | ||
913 | /* do not partially erase */ | 952 | /* do not partially erase */ |
914 | if (is_continuation(c, tty)) | 953 | if (is_continuation(c, tty)) |
@@ -921,30 +960,31 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
921 | else if (seen_alnums) | 960 | else if (seen_alnums) |
922 | break; | 961 | break; |
923 | } | 962 | } |
924 | cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1); | 963 | cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); |
925 | spin_lock_irqsave(&tty->read_lock, flags); | 964 | spin_lock_irqsave(&ldata->read_lock, flags); |
926 | tty->read_head = head; | 965 | ldata->read_head = head; |
927 | tty->read_cnt -= cnt; | 966 | ldata->read_cnt -= cnt; |
928 | spin_unlock_irqrestore(&tty->read_lock, flags); | 967 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
929 | if (L_ECHO(tty)) { | 968 | if (L_ECHO(tty)) { |
930 | if (L_ECHOPRT(tty)) { | 969 | if (L_ECHOPRT(tty)) { |
931 | if (!tty->erasing) { | 970 | if (!ldata->erasing) { |
932 | echo_char_raw('\\', tty); | 971 | echo_char_raw('\\', ldata); |
933 | tty->erasing = 1; | 972 | ldata->erasing = 1; |
934 | } | 973 | } |
935 | /* if cnt > 1, output a multi-byte character */ | 974 | /* if cnt > 1, output a multi-byte character */ |
936 | echo_char(c, tty); | 975 | echo_char(c, tty); |
937 | while (--cnt > 0) { | 976 | while (--cnt > 0) { |
938 | head = (head+1) & (N_TTY_BUF_SIZE-1); | 977 | head = (head+1) & (N_TTY_BUF_SIZE-1); |
939 | echo_char_raw(tty->read_buf[head], tty); | 978 | echo_char_raw(ldata->read_buf[head], |
940 | echo_move_back_col(tty); | 979 | ldata); |
980 | echo_move_back_col(ldata); | ||
941 | } | 981 | } |
942 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { | 982 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { |
943 | echo_char(ERASE_CHAR(tty), tty); | 983 | echo_char(ERASE_CHAR(tty), tty); |
944 | } else if (c == '\t') { | 984 | } else if (c == '\t') { |
945 | unsigned int num_chars = 0; | 985 | unsigned int num_chars = 0; |
946 | int after_tab = 0; | 986 | int after_tab = 0; |
947 | unsigned long tail = tty->read_head; | 987 | unsigned long tail = ldata->read_head; |
948 | 988 | ||
949 | /* | 989 | /* |
950 | * Count the columns used for characters | 990 | * Count the columns used for characters |
@@ -953,9 +993,9 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
953 | * This info is used to go back the correct | 993 | * This info is used to go back the correct |
954 | * number of columns. | 994 | * number of columns. |
955 | */ | 995 | */ |
956 | while (tail != tty->canon_head) { | 996 | while (tail != ldata->canon_head) { |
957 | tail = (tail-1) & (N_TTY_BUF_SIZE-1); | 997 | tail = (tail-1) & (N_TTY_BUF_SIZE-1); |
958 | c = tty->read_buf[tail]; | 998 | c = ldata->read_buf[tail]; |
959 | if (c == '\t') { | 999 | if (c == '\t') { |
960 | after_tab = 1; | 1000 | after_tab = 1; |
961 | break; | 1001 | break; |
@@ -966,25 +1006,25 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
966 | num_chars++; | 1006 | num_chars++; |
967 | } | 1007 | } |
968 | } | 1008 | } |
969 | echo_erase_tab(num_chars, after_tab, tty); | 1009 | echo_erase_tab(num_chars, after_tab, ldata); |
970 | } else { | 1010 | } else { |
971 | if (iscntrl(c) && L_ECHOCTL(tty)) { | 1011 | if (iscntrl(c) && L_ECHOCTL(tty)) { |
972 | echo_char_raw('\b', tty); | 1012 | echo_char_raw('\b', ldata); |
973 | echo_char_raw(' ', tty); | 1013 | echo_char_raw(' ', ldata); |
974 | echo_char_raw('\b', tty); | 1014 | echo_char_raw('\b', ldata); |
975 | } | 1015 | } |
976 | if (!iscntrl(c) || L_ECHOCTL(tty)) { | 1016 | if (!iscntrl(c) || L_ECHOCTL(tty)) { |
977 | echo_char_raw('\b', tty); | 1017 | echo_char_raw('\b', ldata); |
978 | echo_char_raw(' ', tty); | 1018 | echo_char_raw(' ', ldata); |
979 | echo_char_raw('\b', tty); | 1019 | echo_char_raw('\b', ldata); |
980 | } | 1020 | } |
981 | } | 1021 | } |
982 | } | 1022 | } |
983 | if (kill_type == ERASE) | 1023 | if (kill_type == ERASE) |
984 | break; | 1024 | break; |
985 | } | 1025 | } |
986 | if (tty->read_head == tty->canon_head && L_ECHO(tty)) | 1026 | if (ldata->read_head == ldata->canon_head && L_ECHO(tty)) |
987 | finish_erasing(tty); | 1027 | finish_erasing(ldata); |
988 | } | 1028 | } |
989 | 1029 | ||
990 | /** | 1030 | /** |
@@ -1023,6 +1063,8 @@ static inline void isig(int sig, struct tty_struct *tty, int flush) | |||
1023 | 1063 | ||
1024 | static inline void n_tty_receive_break(struct tty_struct *tty) | 1064 | static inline void n_tty_receive_break(struct tty_struct *tty) |
1025 | { | 1065 | { |
1066 | struct n_tty_data *ldata = tty->disc_data; | ||
1067 | |||
1026 | if (I_IGNBRK(tty)) | 1068 | if (I_IGNBRK(tty)) |
1027 | return; | 1069 | return; |
1028 | if (I_BRKINT(tty)) { | 1070 | if (I_BRKINT(tty)) { |
@@ -1030,10 +1072,10 @@ static inline void n_tty_receive_break(struct tty_struct *tty) | |||
1030 | return; | 1072 | return; |
1031 | } | 1073 | } |
1032 | if (I_PARMRK(tty)) { | 1074 | if (I_PARMRK(tty)) { |
1033 | put_tty_queue('\377', tty); | 1075 | put_tty_queue('\377', ldata); |
1034 | put_tty_queue('\0', tty); | 1076 | put_tty_queue('\0', ldata); |
1035 | } | 1077 | } |
1036 | put_tty_queue('\0', tty); | 1078 | put_tty_queue('\0', ldata); |
1037 | wake_up_interruptible(&tty->read_wait); | 1079 | wake_up_interruptible(&tty->read_wait); |
1038 | } | 1080 | } |
1039 | 1081 | ||
@@ -1052,16 +1094,17 @@ static inline void n_tty_receive_break(struct tty_struct *tty) | |||
1052 | 1094 | ||
1053 | static inline void n_tty_receive_overrun(struct tty_struct *tty) | 1095 | static inline void n_tty_receive_overrun(struct tty_struct *tty) |
1054 | { | 1096 | { |
1097 | struct n_tty_data *ldata = tty->disc_data; | ||
1055 | char buf[64]; | 1098 | char buf[64]; |
1056 | 1099 | ||
1057 | tty->num_overrun++; | 1100 | ldata->num_overrun++; |
1058 | if (time_before(tty->overrun_time, jiffies - HZ) || | 1101 | if (time_after(jiffies, ldata->overrun_time + HZ) || |
1059 | time_after(tty->overrun_time, jiffies)) { | 1102 | time_after(ldata->overrun_time, jiffies)) { |
1060 | printk(KERN_WARNING "%s: %d input overrun(s)\n", | 1103 | printk(KERN_WARNING "%s: %d input overrun(s)\n", |
1061 | tty_name(tty, buf), | 1104 | tty_name(tty, buf), |
1062 | tty->num_overrun); | 1105 | ldata->num_overrun); |
1063 | tty->overrun_time = jiffies; | 1106 | ldata->overrun_time = jiffies; |
1064 | tty->num_overrun = 0; | 1107 | ldata->num_overrun = 0; |
1065 | } | 1108 | } |
1066 | } | 1109 | } |
1067 | 1110 | ||
@@ -1076,16 +1119,18 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty) | |||
1076 | static inline void n_tty_receive_parity_error(struct tty_struct *tty, | 1119 | static inline void n_tty_receive_parity_error(struct tty_struct *tty, |
1077 | unsigned char c) | 1120 | unsigned char c) |
1078 | { | 1121 | { |
1122 | struct n_tty_data *ldata = tty->disc_data; | ||
1123 | |||
1079 | if (I_IGNPAR(tty)) | 1124 | if (I_IGNPAR(tty)) |
1080 | return; | 1125 | return; |
1081 | if (I_PARMRK(tty)) { | 1126 | if (I_PARMRK(tty)) { |
1082 | put_tty_queue('\377', tty); | 1127 | put_tty_queue('\377', ldata); |
1083 | put_tty_queue('\0', tty); | 1128 | put_tty_queue('\0', ldata); |
1084 | put_tty_queue(c, tty); | 1129 | put_tty_queue(c, ldata); |
1085 | } else if (I_INPCK(tty)) | 1130 | } else if (I_INPCK(tty)) |
1086 | put_tty_queue('\0', tty); | 1131 | put_tty_queue('\0', ldata); |
1087 | else | 1132 | else |
1088 | put_tty_queue(c, tty); | 1133 | put_tty_queue(c, ldata); |
1089 | wake_up_interruptible(&tty->read_wait); | 1134 | wake_up_interruptible(&tty->read_wait); |
1090 | } | 1135 | } |
1091 | 1136 | ||
@@ -1101,11 +1146,12 @@ static inline void n_tty_receive_parity_error(struct tty_struct *tty, | |||
1101 | 1146 | ||
1102 | static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | 1147 | static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) |
1103 | { | 1148 | { |
1149 | struct n_tty_data *ldata = tty->disc_data; | ||
1104 | unsigned long flags; | 1150 | unsigned long flags; |
1105 | int parmrk; | 1151 | int parmrk; |
1106 | 1152 | ||
1107 | if (tty->raw) { | 1153 | if (ldata->raw) { |
1108 | put_tty_queue(c, tty); | 1154 | put_tty_queue(c, ldata); |
1109 | return; | 1155 | return; |
1110 | } | 1156 | } |
1111 | 1157 | ||
@@ -1115,7 +1161,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
1115 | c = tolower(c); | 1161 | c = tolower(c); |
1116 | 1162 | ||
1117 | if (L_EXTPROC(tty)) { | 1163 | if (L_EXTPROC(tty)) { |
1118 | put_tty_queue(c, tty); | 1164 | put_tty_queue(c, ldata); |
1119 | return; | 1165 | return; |
1120 | } | 1166 | } |
1121 | 1167 | ||
@@ -1143,26 +1189,26 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
1143 | * handle specially, do shortcut processing to speed things | 1189 | * handle specially, do shortcut processing to speed things |
1144 | * up. | 1190 | * up. |
1145 | */ | 1191 | */ |
1146 | if (!test_bit(c, tty->process_char_map) || tty->lnext) { | 1192 | if (!test_bit(c, ldata->process_char_map) || ldata->lnext) { |
1147 | tty->lnext = 0; | 1193 | ldata->lnext = 0; |
1148 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; | 1194 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; |
1149 | if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { | 1195 | if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { |
1150 | /* beep if no space */ | 1196 | /* beep if no space */ |
1151 | if (L_ECHO(tty)) | 1197 | if (L_ECHO(tty)) |
1152 | process_output('\a', tty); | 1198 | process_output('\a', tty); |
1153 | return; | 1199 | return; |
1154 | } | 1200 | } |
1155 | if (L_ECHO(tty)) { | 1201 | if (L_ECHO(tty)) { |
1156 | finish_erasing(tty); | 1202 | finish_erasing(ldata); |
1157 | /* Record the column of first canon char. */ | 1203 | /* Record the column of first canon char. */ |
1158 | if (tty->canon_head == tty->read_head) | 1204 | if (ldata->canon_head == ldata->read_head) |
1159 | echo_set_canon_col(tty); | 1205 | echo_set_canon_col(ldata); |
1160 | echo_char(c, tty); | 1206 | echo_char(c, tty); |
1161 | process_echoes(tty); | 1207 | process_echoes(tty); |
1162 | } | 1208 | } |
1163 | if (parmrk) | 1209 | if (parmrk) |
1164 | put_tty_queue(c, tty); | 1210 | put_tty_queue(c, ldata); |
1165 | put_tty_queue(c, tty); | 1211 | put_tty_queue(c, ldata); |
1166 | return; | 1212 | return; |
1167 | } | 1213 | } |
1168 | 1214 | ||
@@ -1218,7 +1264,7 @@ send_signal: | |||
1218 | } else if (c == '\n' && I_INLCR(tty)) | 1264 | } else if (c == '\n' && I_INLCR(tty)) |
1219 | c = '\r'; | 1265 | c = '\r'; |
1220 | 1266 | ||
1221 | if (tty->icanon) { | 1267 | if (ldata->icanon) { |
1222 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || | 1268 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || |
1223 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { | 1269 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { |
1224 | eraser(c, tty); | 1270 | eraser(c, tty); |
@@ -1226,12 +1272,12 @@ send_signal: | |||
1226 | return; | 1272 | return; |
1227 | } | 1273 | } |
1228 | if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { | 1274 | if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { |
1229 | tty->lnext = 1; | 1275 | ldata->lnext = 1; |
1230 | if (L_ECHO(tty)) { | 1276 | if (L_ECHO(tty)) { |
1231 | finish_erasing(tty); | 1277 | finish_erasing(ldata); |
1232 | if (L_ECHOCTL(tty)) { | 1278 | if (L_ECHOCTL(tty)) { |
1233 | echo_char_raw('^', tty); | 1279 | echo_char_raw('^', ldata); |
1234 | echo_char_raw('\b', tty); | 1280 | echo_char_raw('\b', ldata); |
1235 | process_echoes(tty); | 1281 | process_echoes(tty); |
1236 | } | 1282 | } |
1237 | } | 1283 | } |
@@ -1239,34 +1285,34 @@ send_signal: | |||
1239 | } | 1285 | } |
1240 | if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && | 1286 | if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && |
1241 | L_IEXTEN(tty)) { | 1287 | L_IEXTEN(tty)) { |
1242 | unsigned long tail = tty->canon_head; | 1288 | unsigned long tail = ldata->canon_head; |
1243 | 1289 | ||
1244 | finish_erasing(tty); | 1290 | finish_erasing(ldata); |
1245 | echo_char(c, tty); | 1291 | echo_char(c, tty); |
1246 | echo_char_raw('\n', tty); | 1292 | echo_char_raw('\n', ldata); |
1247 | while (tail != tty->read_head) { | 1293 | while (tail != ldata->read_head) { |
1248 | echo_char(tty->read_buf[tail], tty); | 1294 | echo_char(ldata->read_buf[tail], tty); |
1249 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | 1295 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); |
1250 | } | 1296 | } |
1251 | process_echoes(tty); | 1297 | process_echoes(tty); |
1252 | return; | 1298 | return; |
1253 | } | 1299 | } |
1254 | if (c == '\n') { | 1300 | if (c == '\n') { |
1255 | if (tty->read_cnt >= N_TTY_BUF_SIZE) { | 1301 | if (ldata->read_cnt >= N_TTY_BUF_SIZE) { |
1256 | if (L_ECHO(tty)) | 1302 | if (L_ECHO(tty)) |
1257 | process_output('\a', tty); | 1303 | process_output('\a', tty); |
1258 | return; | 1304 | return; |
1259 | } | 1305 | } |
1260 | if (L_ECHO(tty) || L_ECHONL(tty)) { | 1306 | if (L_ECHO(tty) || L_ECHONL(tty)) { |
1261 | echo_char_raw('\n', tty); | 1307 | echo_char_raw('\n', ldata); |
1262 | process_echoes(tty); | 1308 | process_echoes(tty); |
1263 | } | 1309 | } |
1264 | goto handle_newline; | 1310 | goto handle_newline; |
1265 | } | 1311 | } |
1266 | if (c == EOF_CHAR(tty)) { | 1312 | if (c == EOF_CHAR(tty)) { |
1267 | if (tty->read_cnt >= N_TTY_BUF_SIZE) | 1313 | if (ldata->read_cnt >= N_TTY_BUF_SIZE) |
1268 | return; | 1314 | return; |
1269 | if (tty->canon_head != tty->read_head) | 1315 | if (ldata->canon_head != ldata->read_head) |
1270 | set_bit(TTY_PUSH, &tty->flags); | 1316 | set_bit(TTY_PUSH, &tty->flags); |
1271 | c = __DISABLED_CHAR; | 1317 | c = __DISABLED_CHAR; |
1272 | goto handle_newline; | 1318 | goto handle_newline; |
@@ -1275,7 +1321,7 @@ send_signal: | |||
1275 | (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { | 1321 | (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { |
1276 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) | 1322 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) |
1277 | ? 1 : 0; | 1323 | ? 1 : 0; |
1278 | if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) { | 1324 | if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) { |
1279 | if (L_ECHO(tty)) | 1325 | if (L_ECHO(tty)) |
1280 | process_output('\a', tty); | 1326 | process_output('\a', tty); |
1281 | return; | 1327 | return; |
@@ -1285,8 +1331,8 @@ send_signal: | |||
1285 | */ | 1331 | */ |
1286 | if (L_ECHO(tty)) { | 1332 | if (L_ECHO(tty)) { |
1287 | /* Record the column of first canon char. */ | 1333 | /* Record the column of first canon char. */ |
1288 | if (tty->canon_head == tty->read_head) | 1334 | if (ldata->canon_head == ldata->read_head) |
1289 | echo_set_canon_col(tty); | 1335 | echo_set_canon_col(ldata); |
1290 | echo_char(c, tty); | 1336 | echo_char(c, tty); |
1291 | process_echoes(tty); | 1337 | process_echoes(tty); |
1292 | } | 1338 | } |
@@ -1295,15 +1341,15 @@ send_signal: | |||
1295 | * EOL_CHAR and EOL2_CHAR? | 1341 | * EOL_CHAR and EOL2_CHAR? |
1296 | */ | 1342 | */ |
1297 | if (parmrk) | 1343 | if (parmrk) |
1298 | put_tty_queue(c, tty); | 1344 | put_tty_queue(c, ldata); |
1299 | 1345 | ||
1300 | handle_newline: | 1346 | handle_newline: |
1301 | spin_lock_irqsave(&tty->read_lock, flags); | 1347 | spin_lock_irqsave(&ldata->read_lock, flags); |
1302 | set_bit(tty->read_head, tty->read_flags); | 1348 | set_bit(ldata->read_head, ldata->read_flags); |
1303 | put_tty_queue_nolock(c, tty); | 1349 | put_tty_queue_nolock(c, ldata); |
1304 | tty->canon_head = tty->read_head; | 1350 | ldata->canon_head = ldata->read_head; |
1305 | tty->canon_data++; | 1351 | ldata->canon_data++; |
1306 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1352 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
1307 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1353 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1308 | if (waitqueue_active(&tty->read_wait)) | 1354 | if (waitqueue_active(&tty->read_wait)) |
1309 | wake_up_interruptible(&tty->read_wait); | 1355 | wake_up_interruptible(&tty->read_wait); |
@@ -1312,29 +1358,29 @@ handle_newline: | |||
1312 | } | 1358 | } |
1313 | 1359 | ||
1314 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; | 1360 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; |
1315 | if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { | 1361 | if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { |
1316 | /* beep if no space */ | 1362 | /* beep if no space */ |
1317 | if (L_ECHO(tty)) | 1363 | if (L_ECHO(tty)) |
1318 | process_output('\a', tty); | 1364 | process_output('\a', tty); |
1319 | return; | 1365 | return; |
1320 | } | 1366 | } |
1321 | if (L_ECHO(tty)) { | 1367 | if (L_ECHO(tty)) { |
1322 | finish_erasing(tty); | 1368 | finish_erasing(ldata); |
1323 | if (c == '\n') | 1369 | if (c == '\n') |
1324 | echo_char_raw('\n', tty); | 1370 | echo_char_raw('\n', ldata); |
1325 | else { | 1371 | else { |
1326 | /* Record the column of first canon char. */ | 1372 | /* Record the column of first canon char. */ |
1327 | if (tty->canon_head == tty->read_head) | 1373 | if (ldata->canon_head == ldata->read_head) |
1328 | echo_set_canon_col(tty); | 1374 | echo_set_canon_col(ldata); |
1329 | echo_char(c, tty); | 1375 | echo_char(c, tty); |
1330 | } | 1376 | } |
1331 | process_echoes(tty); | 1377 | process_echoes(tty); |
1332 | } | 1378 | } |
1333 | 1379 | ||
1334 | if (parmrk) | 1380 | if (parmrk) |
1335 | put_tty_queue(c, tty); | 1381 | put_tty_queue(c, ldata); |
1336 | 1382 | ||
1337 | put_tty_queue(c, tty); | 1383 | put_tty_queue(c, ldata); |
1338 | } | 1384 | } |
1339 | 1385 | ||
1340 | 1386 | ||
@@ -1369,33 +1415,31 @@ static void n_tty_write_wakeup(struct tty_struct *tty) | |||
1369 | static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 1415 | static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
1370 | char *fp, int count) | 1416 | char *fp, int count) |
1371 | { | 1417 | { |
1418 | struct n_tty_data *ldata = tty->disc_data; | ||
1372 | const unsigned char *p; | 1419 | const unsigned char *p; |
1373 | char *f, flags = TTY_NORMAL; | 1420 | char *f, flags = TTY_NORMAL; |
1374 | int i; | 1421 | int i; |
1375 | char buf[64]; | 1422 | char buf[64]; |
1376 | unsigned long cpuflags; | 1423 | unsigned long cpuflags; |
1377 | 1424 | ||
1378 | if (!tty->read_buf) | 1425 | if (ldata->real_raw) { |
1379 | return; | 1426 | spin_lock_irqsave(&ldata->read_lock, cpuflags); |
1380 | 1427 | i = min(N_TTY_BUF_SIZE - ldata->read_cnt, | |
1381 | if (tty->real_raw) { | 1428 | N_TTY_BUF_SIZE - ldata->read_head); |
1382 | spin_lock_irqsave(&tty->read_lock, cpuflags); | ||
1383 | i = min(N_TTY_BUF_SIZE - tty->read_cnt, | ||
1384 | N_TTY_BUF_SIZE - tty->read_head); | ||
1385 | i = min(count, i); | 1429 | i = min(count, i); |
1386 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1430 | memcpy(ldata->read_buf + ldata->read_head, cp, i); |
1387 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1431 | ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); |
1388 | tty->read_cnt += i; | 1432 | ldata->read_cnt += i; |
1389 | cp += i; | 1433 | cp += i; |
1390 | count -= i; | 1434 | count -= i; |
1391 | 1435 | ||
1392 | i = min(N_TTY_BUF_SIZE - tty->read_cnt, | 1436 | i = min(N_TTY_BUF_SIZE - ldata->read_cnt, |
1393 | N_TTY_BUF_SIZE - tty->read_head); | 1437 | N_TTY_BUF_SIZE - ldata->read_head); |
1394 | i = min(count, i); | 1438 | i = min(count, i); |
1395 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1439 | memcpy(ldata->read_buf + ldata->read_head, cp, i); |
1396 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1440 | ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); |
1397 | tty->read_cnt += i; | 1441 | ldata->read_cnt += i; |
1398 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); | 1442 | spin_unlock_irqrestore(&ldata->read_lock, cpuflags); |
1399 | } else { | 1443 | } else { |
1400 | for (i = count, p = cp, f = fp; i; i--, p++) { | 1444 | for (i = count, p = cp, f = fp; i; i--, p++) { |
1401 | if (f) | 1445 | if (f) |
@@ -1426,7 +1470,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1426 | 1470 | ||
1427 | n_tty_set_room(tty); | 1471 | n_tty_set_room(tty); |
1428 | 1472 | ||
1429 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || | 1473 | if ((!ldata->icanon && (ldata->read_cnt >= tty->minimum_to_wake)) || |
1430 | L_EXTPROC(tty)) { | 1474 | L_EXTPROC(tty)) { |
1431 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1475 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1432 | if (waitqueue_active(&tty->read_wait)) | 1476 | if (waitqueue_active(&tty->read_wait)) |
@@ -1470,25 +1514,25 @@ int is_ignored(int sig) | |||
1470 | 1514 | ||
1471 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | 1515 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) |
1472 | { | 1516 | { |
1517 | struct n_tty_data *ldata = tty->disc_data; | ||
1473 | int canon_change = 1; | 1518 | int canon_change = 1; |
1474 | BUG_ON(!tty); | ||
1475 | 1519 | ||
1476 | if (old) | 1520 | if (old) |
1477 | canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; | 1521 | canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; |
1478 | if (canon_change) { | 1522 | if (canon_change) { |
1479 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 1523 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); |
1480 | tty->canon_head = tty->read_tail; | 1524 | ldata->canon_head = ldata->read_tail; |
1481 | tty->canon_data = 0; | 1525 | ldata->canon_data = 0; |
1482 | tty->erasing = 0; | 1526 | ldata->erasing = 0; |
1483 | } | 1527 | } |
1484 | 1528 | ||
1485 | if (canon_change && !L_ICANON(tty) && tty->read_cnt) | 1529 | if (canon_change && !L_ICANON(tty) && ldata->read_cnt) |
1486 | wake_up_interruptible(&tty->read_wait); | 1530 | wake_up_interruptible(&tty->read_wait); |
1487 | 1531 | ||
1488 | tty->icanon = (L_ICANON(tty) != 0); | 1532 | ldata->icanon = (L_ICANON(tty) != 0); |
1489 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1533 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1490 | tty->raw = 1; | 1534 | ldata->raw = 1; |
1491 | tty->real_raw = 1; | 1535 | ldata->real_raw = 1; |
1492 | n_tty_set_room(tty); | 1536 | n_tty_set_room(tty); |
1493 | return; | 1537 | return; |
1494 | } | 1538 | } |
@@ -1496,51 +1540,51 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1496 | I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || | 1540 | I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || |
1497 | I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || | 1541 | I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || |
1498 | I_PARMRK(tty)) { | 1542 | I_PARMRK(tty)) { |
1499 | memset(tty->process_char_map, 0, 256/8); | 1543 | bitmap_zero(ldata->process_char_map, 256); |
1500 | 1544 | ||
1501 | if (I_IGNCR(tty) || I_ICRNL(tty)) | 1545 | if (I_IGNCR(tty) || I_ICRNL(tty)) |
1502 | set_bit('\r', tty->process_char_map); | 1546 | set_bit('\r', ldata->process_char_map); |
1503 | if (I_INLCR(tty)) | 1547 | if (I_INLCR(tty)) |
1504 | set_bit('\n', tty->process_char_map); | 1548 | set_bit('\n', ldata->process_char_map); |
1505 | 1549 | ||
1506 | if (L_ICANON(tty)) { | 1550 | if (L_ICANON(tty)) { |
1507 | set_bit(ERASE_CHAR(tty), tty->process_char_map); | 1551 | set_bit(ERASE_CHAR(tty), ldata->process_char_map); |
1508 | set_bit(KILL_CHAR(tty), tty->process_char_map); | 1552 | set_bit(KILL_CHAR(tty), ldata->process_char_map); |
1509 | set_bit(EOF_CHAR(tty), tty->process_char_map); | 1553 | set_bit(EOF_CHAR(tty), ldata->process_char_map); |
1510 | set_bit('\n', tty->process_char_map); | 1554 | set_bit('\n', ldata->process_char_map); |
1511 | set_bit(EOL_CHAR(tty), tty->process_char_map); | 1555 | set_bit(EOL_CHAR(tty), ldata->process_char_map); |
1512 | if (L_IEXTEN(tty)) { | 1556 | if (L_IEXTEN(tty)) { |
1513 | set_bit(WERASE_CHAR(tty), | 1557 | set_bit(WERASE_CHAR(tty), |
1514 | tty->process_char_map); | 1558 | ldata->process_char_map); |
1515 | set_bit(LNEXT_CHAR(tty), | 1559 | set_bit(LNEXT_CHAR(tty), |
1516 | tty->process_char_map); | 1560 | ldata->process_char_map); |
1517 | set_bit(EOL2_CHAR(tty), | 1561 | set_bit(EOL2_CHAR(tty), |
1518 | tty->process_char_map); | 1562 | ldata->process_char_map); |
1519 | if (L_ECHO(tty)) | 1563 | if (L_ECHO(tty)) |
1520 | set_bit(REPRINT_CHAR(tty), | 1564 | set_bit(REPRINT_CHAR(tty), |
1521 | tty->process_char_map); | 1565 | ldata->process_char_map); |
1522 | } | 1566 | } |
1523 | } | 1567 | } |
1524 | if (I_IXON(tty)) { | 1568 | if (I_IXON(tty)) { |
1525 | set_bit(START_CHAR(tty), tty->process_char_map); | 1569 | set_bit(START_CHAR(tty), ldata->process_char_map); |
1526 | set_bit(STOP_CHAR(tty), tty->process_char_map); | 1570 | set_bit(STOP_CHAR(tty), ldata->process_char_map); |
1527 | } | 1571 | } |
1528 | if (L_ISIG(tty)) { | 1572 | if (L_ISIG(tty)) { |
1529 | set_bit(INTR_CHAR(tty), tty->process_char_map); | 1573 | set_bit(INTR_CHAR(tty), ldata->process_char_map); |
1530 | set_bit(QUIT_CHAR(tty), tty->process_char_map); | 1574 | set_bit(QUIT_CHAR(tty), ldata->process_char_map); |
1531 | set_bit(SUSP_CHAR(tty), tty->process_char_map); | 1575 | set_bit(SUSP_CHAR(tty), ldata->process_char_map); |
1532 | } | 1576 | } |
1533 | clear_bit(__DISABLED_CHAR, tty->process_char_map); | 1577 | clear_bit(__DISABLED_CHAR, ldata->process_char_map); |
1534 | tty->raw = 0; | 1578 | ldata->raw = 0; |
1535 | tty->real_raw = 0; | 1579 | ldata->real_raw = 0; |
1536 | } else { | 1580 | } else { |
1537 | tty->raw = 1; | 1581 | ldata->raw = 1; |
1538 | if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) && | 1582 | if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) && |
1539 | (I_IGNPAR(tty) || !I_INPCK(tty)) && | 1583 | (I_IGNPAR(tty) || !I_INPCK(tty)) && |
1540 | (tty->driver->flags & TTY_DRIVER_REAL_RAW)) | 1584 | (tty->driver->flags & TTY_DRIVER_REAL_RAW)) |
1541 | tty->real_raw = 1; | 1585 | ldata->real_raw = 1; |
1542 | else | 1586 | else |
1543 | tty->real_raw = 0; | 1587 | ldata->real_raw = 0; |
1544 | } | 1588 | } |
1545 | n_tty_set_room(tty); | 1589 | n_tty_set_room(tty); |
1546 | /* The termios change make the tty ready for I/O */ | 1590 | /* The termios change make the tty ready for I/O */ |
@@ -1560,15 +1604,13 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1560 | 1604 | ||
1561 | static void n_tty_close(struct tty_struct *tty) | 1605 | static void n_tty_close(struct tty_struct *tty) |
1562 | { | 1606 | { |
1607 | struct n_tty_data *ldata = tty->disc_data; | ||
1608 | |||
1563 | n_tty_flush_buffer(tty); | 1609 | n_tty_flush_buffer(tty); |
1564 | if (tty->read_buf) { | 1610 | kfree(ldata->read_buf); |
1565 | kfree(tty->read_buf); | 1611 | kfree(ldata->echo_buf); |
1566 | tty->read_buf = NULL; | 1612 | kfree(ldata); |
1567 | } | 1613 | tty->disc_data = NULL; |
1568 | if (tty->echo_buf) { | ||
1569 | kfree(tty->echo_buf); | ||
1570 | tty->echo_buf = NULL; | ||
1571 | } | ||
1572 | } | 1614 | } |
1573 | 1615 | ||
1574 | /** | 1616 | /** |
@@ -1583,37 +1625,50 @@ static void n_tty_close(struct tty_struct *tty) | |||
1583 | 1625 | ||
1584 | static int n_tty_open(struct tty_struct *tty) | 1626 | static int n_tty_open(struct tty_struct *tty) |
1585 | { | 1627 | { |
1586 | if (!tty) | 1628 | struct n_tty_data *ldata; |
1587 | return -EINVAL; | 1629 | |
1630 | ldata = kzalloc(sizeof(*ldata), GFP_KERNEL); | ||
1631 | if (!ldata) | ||
1632 | goto err; | ||
1633 | |||
1634 | ldata->overrun_time = jiffies; | ||
1635 | mutex_init(&ldata->atomic_read_lock); | ||
1636 | mutex_init(&ldata->output_lock); | ||
1637 | mutex_init(&ldata->echo_lock); | ||
1638 | spin_lock_init(&ldata->read_lock); | ||
1588 | 1639 | ||
1589 | /* These are ugly. Currently a malloc failure here can panic */ | 1640 | /* These are ugly. Currently a malloc failure here can panic */ |
1590 | if (!tty->read_buf) { | 1641 | ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); |
1591 | tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); | 1642 | ldata->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); |
1592 | if (!tty->read_buf) | 1643 | if (!ldata->read_buf || !ldata->echo_buf) |
1593 | return -ENOMEM; | 1644 | goto err_free_bufs; |
1594 | } | ||
1595 | if (!tty->echo_buf) { | ||
1596 | tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); | ||
1597 | 1645 | ||
1598 | if (!tty->echo_buf) | 1646 | tty->disc_data = ldata; |
1599 | return -ENOMEM; | ||
1600 | } | ||
1601 | reset_buffer_flags(tty); | 1647 | reset_buffer_flags(tty); |
1602 | tty_unthrottle(tty); | 1648 | tty_unthrottle(tty); |
1603 | tty->column = 0; | 1649 | ldata->column = 0; |
1604 | n_tty_set_termios(tty, NULL); | 1650 | n_tty_set_termios(tty, NULL); |
1605 | tty->minimum_to_wake = 1; | 1651 | tty->minimum_to_wake = 1; |
1606 | tty->closing = 0; | 1652 | tty->closing = 0; |
1653 | |||
1607 | return 0; | 1654 | return 0; |
1655 | err_free_bufs: | ||
1656 | kfree(ldata->read_buf); | ||
1657 | kfree(ldata->echo_buf); | ||
1658 | kfree(ldata); | ||
1659 | err: | ||
1660 | return -ENOMEM; | ||
1608 | } | 1661 | } |
1609 | 1662 | ||
1610 | static inline int input_available_p(struct tty_struct *tty, int amt) | 1663 | static inline int input_available_p(struct tty_struct *tty, int amt) |
1611 | { | 1664 | { |
1665 | struct n_tty_data *ldata = tty->disc_data; | ||
1666 | |||
1612 | tty_flush_to_ldisc(tty); | 1667 | tty_flush_to_ldisc(tty); |
1613 | if (tty->icanon && !L_EXTPROC(tty)) { | 1668 | if (ldata->icanon && !L_EXTPROC(tty)) { |
1614 | if (tty->canon_data) | 1669 | if (ldata->canon_data) |
1615 | return 1; | 1670 | return 1; |
1616 | } else if (tty->read_cnt >= (amt ? amt : 1)) | 1671 | } else if (ldata->read_cnt >= (amt ? amt : 1)) |
1617 | return 1; | 1672 | return 1; |
1618 | 1673 | ||
1619 | return 0; | 1674 | return 0; |
@@ -1632,7 +1687,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1632 | * buffer, and once to drain the space from the (physical) beginning of | 1687 | * buffer, and once to drain the space from the (physical) beginning of |
1633 | * the buffer to head pointer. | 1688 | * the buffer to head pointer. |
1634 | * | 1689 | * |
1635 | * Called under the tty->atomic_read_lock sem | 1690 | * Called under the ldata->atomic_read_lock sem |
1636 | * | 1691 | * |
1637 | */ | 1692 | */ |
1638 | 1693 | ||
@@ -1641,29 +1696,31 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1641 | size_t *nr) | 1696 | size_t *nr) |
1642 | 1697 | ||
1643 | { | 1698 | { |
1699 | struct n_tty_data *ldata = tty->disc_data; | ||
1644 | int retval; | 1700 | int retval; |
1645 | size_t n; | 1701 | size_t n; |
1646 | unsigned long flags; | 1702 | unsigned long flags; |
1647 | bool is_eof; | 1703 | bool is_eof; |
1648 | 1704 | ||
1649 | retval = 0; | 1705 | retval = 0; |
1650 | spin_lock_irqsave(&tty->read_lock, flags); | 1706 | spin_lock_irqsave(&ldata->read_lock, flags); |
1651 | n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail); | 1707 | n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); |
1652 | n = min(*nr, n); | 1708 | n = min(*nr, n); |
1653 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1709 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
1654 | if (n) { | 1710 | if (n) { |
1655 | retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n); | 1711 | retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); |
1656 | n -= retval; | 1712 | n -= retval; |
1657 | is_eof = n == 1 && | 1713 | is_eof = n == 1 && |
1658 | tty->read_buf[tty->read_tail] == EOF_CHAR(tty); | 1714 | ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); |
1659 | tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n); | 1715 | tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, |
1660 | spin_lock_irqsave(&tty->read_lock, flags); | 1716 | ldata->icanon); |
1661 | tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); | 1717 | spin_lock_irqsave(&ldata->read_lock, flags); |
1662 | tty->read_cnt -= n; | 1718 | ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); |
1719 | ldata->read_cnt -= n; | ||
1663 | /* Turn single EOF into zero-length read */ | 1720 | /* Turn single EOF into zero-length read */ |
1664 | if (L_EXTPROC(tty) && tty->icanon && is_eof && !tty->read_cnt) | 1721 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) |
1665 | n = 0; | 1722 | n = 0; |
1666 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1723 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
1667 | *b += n; | 1724 | *b += n; |
1668 | *nr -= n; | 1725 | *nr -= n; |
1669 | } | 1726 | } |
@@ -1730,6 +1787,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1730 | static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | 1787 | static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, |
1731 | unsigned char __user *buf, size_t nr) | 1788 | unsigned char __user *buf, size_t nr) |
1732 | { | 1789 | { |
1790 | struct n_tty_data *ldata = tty->disc_data; | ||
1733 | unsigned char __user *b = buf; | 1791 | unsigned char __user *b = buf; |
1734 | DECLARE_WAITQUEUE(wait, current); | 1792 | DECLARE_WAITQUEUE(wait, current); |
1735 | int c; | 1793 | int c; |
@@ -1741,17 +1799,13 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
1741 | int packet; | 1799 | int packet; |
1742 | 1800 | ||
1743 | do_it_again: | 1801 | do_it_again: |
1744 | |||
1745 | if (WARN_ON(!tty->read_buf)) | ||
1746 | return -EAGAIN; | ||
1747 | |||
1748 | c = job_control(tty, file); | 1802 | c = job_control(tty, file); |
1749 | if (c < 0) | 1803 | if (c < 0) |
1750 | return c; | 1804 | return c; |
1751 | 1805 | ||
1752 | minimum = time = 0; | 1806 | minimum = time = 0; |
1753 | timeout = MAX_SCHEDULE_TIMEOUT; | 1807 | timeout = MAX_SCHEDULE_TIMEOUT; |
1754 | if (!tty->icanon) { | 1808 | if (!ldata->icanon) { |
1755 | time = (HZ / 10) * TIME_CHAR(tty); | 1809 | time = (HZ / 10) * TIME_CHAR(tty); |
1756 | minimum = MIN_CHAR(tty); | 1810 | minimum = MIN_CHAR(tty); |
1757 | if (minimum) { | 1811 | if (minimum) { |
@@ -1774,10 +1828,10 @@ do_it_again: | |||
1774 | * Internal serialization of reads. | 1828 | * Internal serialization of reads. |
1775 | */ | 1829 | */ |
1776 | if (file->f_flags & O_NONBLOCK) { | 1830 | if (file->f_flags & O_NONBLOCK) { |
1777 | if (!mutex_trylock(&tty->atomic_read_lock)) | 1831 | if (!mutex_trylock(&ldata->atomic_read_lock)) |
1778 | return -EAGAIN; | 1832 | return -EAGAIN; |
1779 | } else { | 1833 | } else { |
1780 | if (mutex_lock_interruptible(&tty->atomic_read_lock)) | 1834 | if (mutex_lock_interruptible(&ldata->atomic_read_lock)) |
1781 | return -ERESTARTSYS; | 1835 | return -ERESTARTSYS; |
1782 | } | 1836 | } |
1783 | packet = tty->packet; | 1837 | packet = tty->packet; |
@@ -1830,7 +1884,6 @@ do_it_again: | |||
1830 | /* FIXME: does n_tty_set_room need locking ? */ | 1884 | /* FIXME: does n_tty_set_room need locking ? */ |
1831 | n_tty_set_room(tty); | 1885 | n_tty_set_room(tty); |
1832 | timeout = schedule_timeout(timeout); | 1886 | timeout = schedule_timeout(timeout); |
1833 | BUG_ON(!tty->read_buf); | ||
1834 | continue; | 1887 | continue; |
1835 | } | 1888 | } |
1836 | __set_current_state(TASK_RUNNING); | 1889 | __set_current_state(TASK_RUNNING); |
@@ -1845,45 +1898,45 @@ do_it_again: | |||
1845 | nr--; | 1898 | nr--; |
1846 | } | 1899 | } |
1847 | 1900 | ||
1848 | if (tty->icanon && !L_EXTPROC(tty)) { | 1901 | if (ldata->icanon && !L_EXTPROC(tty)) { |
1849 | /* N.B. avoid overrun if nr == 0 */ | 1902 | /* N.B. avoid overrun if nr == 0 */ |
1850 | spin_lock_irqsave(&tty->read_lock, flags); | 1903 | spin_lock_irqsave(&ldata->read_lock, flags); |
1851 | while (nr && tty->read_cnt) { | 1904 | while (nr && ldata->read_cnt) { |
1852 | int eol; | 1905 | int eol; |
1853 | 1906 | ||
1854 | eol = test_and_clear_bit(tty->read_tail, | 1907 | eol = test_and_clear_bit(ldata->read_tail, |
1855 | tty->read_flags); | 1908 | ldata->read_flags); |
1856 | c = tty->read_buf[tty->read_tail]; | 1909 | c = ldata->read_buf[ldata->read_tail]; |
1857 | tty->read_tail = ((tty->read_tail+1) & | 1910 | ldata->read_tail = ((ldata->read_tail+1) & |
1858 | (N_TTY_BUF_SIZE-1)); | 1911 | (N_TTY_BUF_SIZE-1)); |
1859 | tty->read_cnt--; | 1912 | ldata->read_cnt--; |
1860 | if (eol) { | 1913 | if (eol) { |
1861 | /* this test should be redundant: | 1914 | /* this test should be redundant: |
1862 | * we shouldn't be reading data if | 1915 | * we shouldn't be reading data if |
1863 | * canon_data is 0 | 1916 | * canon_data is 0 |
1864 | */ | 1917 | */ |
1865 | if (--tty->canon_data < 0) | 1918 | if (--ldata->canon_data < 0) |
1866 | tty->canon_data = 0; | 1919 | ldata->canon_data = 0; |
1867 | } | 1920 | } |
1868 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1921 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
1869 | 1922 | ||
1870 | if (!eol || (c != __DISABLED_CHAR)) { | 1923 | if (!eol || (c != __DISABLED_CHAR)) { |
1871 | if (tty_put_user(tty, c, b++)) { | 1924 | if (tty_put_user(tty, c, b++)) { |
1872 | retval = -EFAULT; | 1925 | retval = -EFAULT; |
1873 | b--; | 1926 | b--; |
1874 | spin_lock_irqsave(&tty->read_lock, flags); | 1927 | spin_lock_irqsave(&ldata->read_lock, flags); |
1875 | break; | 1928 | break; |
1876 | } | 1929 | } |
1877 | nr--; | 1930 | nr--; |
1878 | } | 1931 | } |
1879 | if (eol) { | 1932 | if (eol) { |
1880 | tty_audit_push(tty); | 1933 | tty_audit_push(tty); |
1881 | spin_lock_irqsave(&tty->read_lock, flags); | 1934 | spin_lock_irqsave(&ldata->read_lock, flags); |
1882 | break; | 1935 | break; |
1883 | } | 1936 | } |
1884 | spin_lock_irqsave(&tty->read_lock, flags); | 1937 | spin_lock_irqsave(&ldata->read_lock, flags); |
1885 | } | 1938 | } |
1886 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1939 | spin_unlock_irqrestore(&ldata->read_lock, flags); |
1887 | if (retval) | 1940 | if (retval) |
1888 | break; | 1941 | break; |
1889 | } else { | 1942 | } else { |
@@ -1915,7 +1968,7 @@ do_it_again: | |||
1915 | if (time) | 1968 | if (time) |
1916 | timeout = time; | 1969 | timeout = time; |
1917 | } | 1970 | } |
1918 | mutex_unlock(&tty->atomic_read_lock); | 1971 | mutex_unlock(&ldata->atomic_read_lock); |
1919 | remove_wait_queue(&tty->read_wait, &wait); | 1972 | remove_wait_queue(&tty->read_wait, &wait); |
1920 | 1973 | ||
1921 | if (!waitqueue_active(&tty->read_wait)) | 1974 | if (!waitqueue_active(&tty->read_wait)) |
@@ -2076,19 +2129,19 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, | |||
2076 | return mask; | 2129 | return mask; |
2077 | } | 2130 | } |
2078 | 2131 | ||
2079 | static unsigned long inq_canon(struct tty_struct *tty) | 2132 | static unsigned long inq_canon(struct n_tty_data *ldata) |
2080 | { | 2133 | { |
2081 | int nr, head, tail; | 2134 | int nr, head, tail; |
2082 | 2135 | ||
2083 | if (!tty->canon_data) | 2136 | if (!ldata->canon_data) |
2084 | return 0; | 2137 | return 0; |
2085 | head = tty->canon_head; | 2138 | head = ldata->canon_head; |
2086 | tail = tty->read_tail; | 2139 | tail = ldata->read_tail; |
2087 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); | 2140 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); |
2088 | /* Skip EOF-chars.. */ | 2141 | /* Skip EOF-chars.. */ |
2089 | while (head != tail) { | 2142 | while (head != tail) { |
2090 | if (test_bit(tail, tty->read_flags) && | 2143 | if (test_bit(tail, ldata->read_flags) && |
2091 | tty->read_buf[tail] == __DISABLED_CHAR) | 2144 | ldata->read_buf[tail] == __DISABLED_CHAR) |
2092 | nr--; | 2145 | nr--; |
2093 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | 2146 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); |
2094 | } | 2147 | } |
@@ -2098,6 +2151,7 @@ static unsigned long inq_canon(struct tty_struct *tty) | |||
2098 | static int n_tty_ioctl(struct tty_struct *tty, struct file *file, | 2151 | static int n_tty_ioctl(struct tty_struct *tty, struct file *file, |
2099 | unsigned int cmd, unsigned long arg) | 2152 | unsigned int cmd, unsigned long arg) |
2100 | { | 2153 | { |
2154 | struct n_tty_data *ldata = tty->disc_data; | ||
2101 | int retval; | 2155 | int retval; |
2102 | 2156 | ||
2103 | switch (cmd) { | 2157 | switch (cmd) { |
@@ -2105,9 +2159,9 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
2105 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | 2159 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); |
2106 | case TIOCINQ: | 2160 | case TIOCINQ: |
2107 | /* FIXME: Locking */ | 2161 | /* FIXME: Locking */ |
2108 | retval = tty->read_cnt; | 2162 | retval = ldata->read_cnt; |
2109 | if (L_ICANON(tty)) | 2163 | if (L_ICANON(tty)) |
2110 | retval = inq_canon(tty); | 2164 | retval = inq_canon(ldata); |
2111 | return put_user(retval, (unsigned int __user *) arg); | 2165 | return put_user(retval, (unsigned int __user *) arg); |
2112 | default: | 2166 | default: |
2113 | return n_tty_ioctl_helper(tty, file, cmd, arg); | 2167 | return n_tty_ioctl_helper(tty, file, cmd, arg); |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index b917c9424954..a0c69ab04399 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -400,7 +400,7 @@ struct buffer { | |||
400 | } __attribute__ ((packed)); | 400 | } __attribute__ ((packed)); |
401 | 401 | ||
402 | /* Global variables */ | 402 | /* Global variables */ |
403 | static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = { | 403 | static const struct pci_device_id nozomi_pci_tbl[] = { |
404 | {PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */ | 404 | {PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */ |
405 | {}, | 405 | {}, |
406 | }; | 406 | }; |
@@ -1360,7 +1360,7 @@ static void remove_sysfs_files(struct nozomi *dc) | |||
1360 | } | 1360 | } |
1361 | 1361 | ||
1362 | /* Allocate memory for one device */ | 1362 | /* Allocate memory for one device */ |
1363 | static int __devinit nozomi_card_init(struct pci_dev *pdev, | 1363 | static int nozomi_card_init(struct pci_dev *pdev, |
1364 | const struct pci_device_id *ent) | 1364 | const struct pci_device_id *ent) |
1365 | { | 1365 | { |
1366 | resource_size_t start; | 1366 | resource_size_t start; |
@@ -1479,6 +1479,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1479 | if (IS_ERR(tty_dev)) { | 1479 | if (IS_ERR(tty_dev)) { |
1480 | ret = PTR_ERR(tty_dev); | 1480 | ret = PTR_ERR(tty_dev); |
1481 | dev_err(&pdev->dev, "Could not allocate tty?\n"); | 1481 | dev_err(&pdev->dev, "Could not allocate tty?\n"); |
1482 | tty_port_destroy(&port->port); | ||
1482 | goto err_free_tty; | 1483 | goto err_free_tty; |
1483 | } | 1484 | } |
1484 | } | 1485 | } |
@@ -1486,8 +1487,10 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1486 | return 0; | 1487 | return 0; |
1487 | 1488 | ||
1488 | err_free_tty: | 1489 | err_free_tty: |
1489 | for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) | 1490 | for (i = 0; i < MAX_PORT; ++i) { |
1490 | tty_unregister_device(ntty_driver, i); | 1491 | tty_unregister_device(ntty_driver, dc->index_start + i); |
1492 | tty_port_destroy(&dc->port[i].port); | ||
1493 | } | ||
1491 | err_free_kfifo: | 1494 | err_free_kfifo: |
1492 | for (i = 0; i < MAX_PORT; i++) | 1495 | for (i = 0; i < MAX_PORT; i++) |
1493 | kfifo_free(&dc->port[i].fifo_ul); | 1496 | kfifo_free(&dc->port[i].fifo_ul); |
@@ -1504,7 +1507,7 @@ err: | |||
1504 | return ret; | 1507 | return ret; |
1505 | } | 1508 | } |
1506 | 1509 | ||
1507 | static void __devexit tty_exit(struct nozomi *dc) | 1510 | static void tty_exit(struct nozomi *dc) |
1508 | { | 1511 | { |
1509 | unsigned int i; | 1512 | unsigned int i; |
1510 | 1513 | ||
@@ -1520,12 +1523,14 @@ static void __devexit tty_exit(struct nozomi *dc) | |||
1520 | complete off a hangup method ? */ | 1523 | complete off a hangup method ? */ |
1521 | while (dc->open_ttys) | 1524 | while (dc->open_ttys) |
1522 | msleep(1); | 1525 | msleep(1); |
1523 | for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) | 1526 | for (i = 0; i < MAX_PORT; ++i) { |
1524 | tty_unregister_device(ntty_driver, i); | 1527 | tty_unregister_device(ntty_driver, dc->index_start + i); |
1528 | tty_port_destroy(&dc->port[i].port); | ||
1529 | } | ||
1525 | } | 1530 | } |
1526 | 1531 | ||
1527 | /* Deallocate memory for one device */ | 1532 | /* Deallocate memory for one device */ |
1528 | static void __devexit nozomi_card_exit(struct pci_dev *pdev) | 1533 | static void nozomi_card_exit(struct pci_dev *pdev) |
1529 | { | 1534 | { |
1530 | int i; | 1535 | int i; |
1531 | struct ctrl_ul ctrl; | 1536 | struct ctrl_ul ctrl; |
@@ -1903,7 +1908,7 @@ static struct pci_driver nozomi_driver = { | |||
1903 | .name = NOZOMI_NAME, | 1908 | .name = NOZOMI_NAME, |
1904 | .id_table = nozomi_pci_tbl, | 1909 | .id_table = nozomi_pci_tbl, |
1905 | .probe = nozomi_card_init, | 1910 | .probe = nozomi_card_init, |
1906 | .remove = __devexit_p(nozomi_card_exit), | 1911 | .remove = nozomi_card_exit, |
1907 | }; | 1912 | }; |
1908 | 1913 | ||
1909 | static __init int nozomi_init(void) | 1914 | static __init int nozomi_init(void) |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a82b39939a9c..be6a373601b7 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -4,9 +4,6 @@ | |||
4 | * Added support for a Unix98-style ptmx device. | 4 | * Added support for a Unix98-style ptmx device. |
5 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 | 5 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 |
6 | * | 6 | * |
7 | * When reading this code see also fs/devpts. In particular note that the | ||
8 | * driver_data field is used by the devpts side as a binding to the devpts | ||
9 | * inode. | ||
10 | */ | 7 | */ |
11 | 8 | ||
12 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
59 | #ifdef CONFIG_UNIX98_PTYS | 56 | #ifdef CONFIG_UNIX98_PTYS |
60 | if (tty->driver == ptm_driver) { | 57 | if (tty->driver == ptm_driver) { |
61 | mutex_lock(&devpts_mutex); | 58 | mutex_lock(&devpts_mutex); |
62 | devpts_pty_kill(tty->link); | 59 | devpts_pty_kill(tty->link->driver_data); |
63 | mutex_unlock(&devpts_mutex); | 60 | mutex_unlock(&devpts_mutex); |
64 | } | 61 | } |
65 | #endif | 62 | #endif |
@@ -96,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty) | |||
96 | 93 | ||
97 | static int pty_space(struct tty_struct *to) | 94 | static int pty_space(struct tty_struct *to) |
98 | { | 95 | { |
99 | int n = 8192 - to->buf.memory_used; | 96 | int n = 8192 - to->port->buf.memory_used; |
100 | if (n < 0) | 97 | if (n < 0) |
101 | return 0; | 98 | return 0; |
102 | return n; | 99 | return n; |
@@ -174,6 +171,41 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg) | |||
174 | return 0; | 171 | return 0; |
175 | } | 172 | } |
176 | 173 | ||
174 | static int pty_get_lock(struct tty_struct *tty, int __user *arg) | ||
175 | { | ||
176 | int locked = test_bit(TTY_PTY_LOCK, &tty->flags); | ||
177 | return put_user(locked, arg); | ||
178 | } | ||
179 | |||
180 | /* Set the packet mode on a pty */ | ||
181 | static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) | ||
182 | { | ||
183 | unsigned long flags; | ||
184 | int pktmode; | ||
185 | |||
186 | if (get_user(pktmode, arg)) | ||
187 | return -EFAULT; | ||
188 | |||
189 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
190 | if (pktmode) { | ||
191 | if (!tty->packet) { | ||
192 | tty->packet = 1; | ||
193 | tty->link->ctrl_status = 0; | ||
194 | } | ||
195 | } else | ||
196 | tty->packet = 0; | ||
197 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | /* Get the packet mode of a pty */ | ||
203 | static int pty_get_pktmode(struct tty_struct *tty, int __user *arg) | ||
204 | { | ||
205 | int pktmode = tty->packet; | ||
206 | return put_user(pktmode, arg); | ||
207 | } | ||
208 | |||
177 | /* Send a signal to the slave */ | 209 | /* Send a signal to the slave */ |
178 | static int pty_signal(struct tty_struct *tty, int sig) | 210 | static int pty_signal(struct tty_struct *tty, int sig) |
179 | { | 211 | { |
@@ -245,7 +277,7 @@ static void pty_set_termios(struct tty_struct *tty, | |||
245 | * peform a terminal resize correctly | 277 | * peform a terminal resize correctly |
246 | */ | 278 | */ |
247 | 279 | ||
248 | int pty_resize(struct tty_struct *tty, struct winsize *ws) | 280 | static int pty_resize(struct tty_struct *tty, struct winsize *ws) |
249 | { | 281 | { |
250 | struct pid *pgrp, *rpgrp; | 282 | struct pid *pgrp, *rpgrp; |
251 | unsigned long flags; | 283 | unsigned long flags; |
@@ -348,6 +380,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
348 | tty_port_init(ports[1]); | 380 | tty_port_init(ports[1]); |
349 | o_tty->port = ports[0]; | 381 | o_tty->port = ports[0]; |
350 | tty->port = ports[1]; | 382 | tty->port = ports[1]; |
383 | o_tty->port->itty = o_tty; | ||
351 | 384 | ||
352 | tty_driver_kref_get(driver); | 385 | tty_driver_kref_get(driver); |
353 | tty->count++; | 386 | tty->count++; |
@@ -366,9 +399,16 @@ err: | |||
366 | return retval; | 399 | return retval; |
367 | } | 400 | } |
368 | 401 | ||
402 | /* this is called once with whichever end is closed last */ | ||
403 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
404 | { | ||
405 | devpts_kill_index(tty->driver_data, tty->index); | ||
406 | } | ||
407 | |||
369 | static void pty_cleanup(struct tty_struct *tty) | 408 | static void pty_cleanup(struct tty_struct *tty) |
370 | { | 409 | { |
371 | kfree(tty->port); | 410 | tty->port->itty = NULL; |
411 | tty_port_put(tty->port); | ||
372 | } | 412 | } |
373 | 413 | ||
374 | /* Traditional BSD devices */ | 414 | /* Traditional BSD devices */ |
@@ -393,6 +433,12 @@ static int pty_bsd_ioctl(struct tty_struct *tty, | |||
393 | switch (cmd) { | 433 | switch (cmd) { |
394 | case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ | 434 | case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ |
395 | return pty_set_lock(tty, (int __user *) arg); | 435 | return pty_set_lock(tty, (int __user *) arg); |
436 | case TIOCGPTLCK: /* Get PT Lock status */ | ||
437 | return pty_get_lock(tty, (int __user *)arg); | ||
438 | case TIOCPKT: /* Set PT packet mode */ | ||
439 | return pty_set_pktmode(tty, (int __user *)arg); | ||
440 | case TIOCGPKT: /* Get PT packet mode */ | ||
441 | return pty_get_pktmode(tty, (int __user *)arg); | ||
396 | case TIOCSIG: /* Send signal to other side of pty */ | 442 | case TIOCSIG: /* Send signal to other side of pty */ |
397 | return pty_signal(tty, (int) arg); | 443 | return pty_signal(tty, (int) arg); |
398 | } | 444 | } |
@@ -507,6 +553,12 @@ static int pty_unix98_ioctl(struct tty_struct *tty, | |||
507 | switch (cmd) { | 553 | switch (cmd) { |
508 | case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ | 554 | case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ |
509 | return pty_set_lock(tty, (int __user *)arg); | 555 | return pty_set_lock(tty, (int __user *)arg); |
556 | case TIOCGPTLCK: /* Get PT Lock status */ | ||
557 | return pty_get_lock(tty, (int __user *)arg); | ||
558 | case TIOCPKT: /* Set PT packet mode */ | ||
559 | return pty_set_pktmode(tty, (int __user *)arg); | ||
560 | case TIOCGPKT: /* Get PT packet mode */ | ||
561 | return pty_get_pktmode(tty, (int __user *)arg); | ||
510 | case TIOCGPTN: /* Get PT Number */ | 562 | case TIOCGPTN: /* Get PT Number */ |
511 | return put_user(tty->index, (unsigned int __user *)arg); | 563 | return put_user(tty->index, (unsigned int __user *)arg); |
512 | case TIOCSIG: /* Send signal to other side of pty */ | 564 | case TIOCSIG: /* Send signal to other side of pty */ |
@@ -547,7 +599,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | |||
547 | struct tty_struct *tty; | 599 | struct tty_struct *tty; |
548 | 600 | ||
549 | mutex_lock(&devpts_mutex); | 601 | mutex_lock(&devpts_mutex); |
550 | tty = devpts_get_tty(pts_inode, idx); | 602 | tty = devpts_get_priv(pts_inode); |
551 | mutex_unlock(&devpts_mutex); | 603 | mutex_unlock(&devpts_mutex); |
552 | /* Master must be open before slave */ | 604 | /* Master must be open before slave */ |
553 | if (!tty) | 605 | if (!tty) |
@@ -581,6 +633,7 @@ static const struct tty_operations ptm_unix98_ops = { | |||
581 | .set_termios = pty_set_termios, | 633 | .set_termios = pty_set_termios, |
582 | .ioctl = pty_unix98_ioctl, | 634 | .ioctl = pty_unix98_ioctl, |
583 | .resize = pty_resize, | 635 | .resize = pty_resize, |
636 | .shutdown = pty_unix98_shutdown, | ||
584 | .cleanup = pty_cleanup | 637 | .cleanup = pty_cleanup |
585 | }; | 638 | }; |
586 | 639 | ||
@@ -596,6 +649,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
596 | .chars_in_buffer = pty_chars_in_buffer, | 649 | .chars_in_buffer = pty_chars_in_buffer, |
597 | .unthrottle = pty_unthrottle, | 650 | .unthrottle = pty_unthrottle, |
598 | .set_termios = pty_set_termios, | 651 | .set_termios = pty_set_termios, |
652 | .shutdown = pty_unix98_shutdown, | ||
599 | .cleanup = pty_cleanup, | 653 | .cleanup = pty_cleanup, |
600 | }; | 654 | }; |
601 | 655 | ||
@@ -614,6 +668,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
614 | static int ptmx_open(struct inode *inode, struct file *filp) | 668 | static int ptmx_open(struct inode *inode, struct file *filp) |
615 | { | 669 | { |
616 | struct tty_struct *tty; | 670 | struct tty_struct *tty; |
671 | struct inode *slave_inode; | ||
617 | int retval; | 672 | int retval; |
618 | int index; | 673 | int index; |
619 | 674 | ||
@@ -650,15 +705,21 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
650 | 705 | ||
651 | tty_add_file(tty, filp); | 706 | tty_add_file(tty, filp); |
652 | 707 | ||
653 | retval = devpts_pty_new(inode, tty->link); | 708 | slave_inode = devpts_pty_new(inode, |
654 | if (retval) | 709 | MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, |
710 | tty->link); | ||
711 | if (IS_ERR(slave_inode)) { | ||
712 | retval = PTR_ERR(slave_inode); | ||
655 | goto err_release; | 713 | goto err_release; |
714 | } | ||
656 | 715 | ||
657 | retval = ptm_driver->ops->open(tty, filp); | 716 | retval = ptm_driver->ops->open(tty, filp); |
658 | if (retval) | 717 | if (retval) |
659 | goto err_release; | 718 | goto err_release; |
660 | 719 | ||
661 | tty_unlock(tty); | 720 | tty_unlock(tty); |
721 | tty->driver_data = inode; | ||
722 | tty->link->driver_data = slave_inode; | ||
662 | return 0; | 723 | return 0; |
663 | err_release: | 724 | err_release: |
664 | tty_unlock(tty); | 725 | tty_unlock(tty); |
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 9700d34b20a3..e42009a00529 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -673,6 +673,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
673 | if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) { | 673 | if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) { |
674 | printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n", | 674 | printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n", |
675 | board, aiop, chan); | 675 | board, aiop, chan); |
676 | tty_port_destroy(&info->port); | ||
676 | kfree(info); | 677 | kfree(info); |
677 | return; | 678 | return; |
678 | } | 679 | } |
@@ -1757,7 +1758,7 @@ static void rp_flush_buffer(struct tty_struct *tty) | |||
1757 | 1758 | ||
1758 | #ifdef CONFIG_PCI | 1759 | #ifdef CONFIG_PCI |
1759 | 1760 | ||
1760 | static struct pci_device_id __devinitdata __used rocket_pci_ids[] = { | 1761 | static struct pci_device_id __used rocket_pci_ids[] = { |
1761 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, | 1762 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, |
1762 | { } | 1763 | { } |
1763 | }; | 1764 | }; |
@@ -2357,6 +2358,7 @@ static void rp_cleanup_module(void) | |||
2357 | for (i = 0; i < MAX_RP_PORTS; i++) | 2358 | for (i = 0; i < MAX_RP_PORTS; i++) |
2358 | if (rp_table[i]) { | 2359 | if (rp_table[i]) { |
2359 | tty_unregister_device(rocket_driver, i); | 2360 | tty_unregister_device(rocket_driver, i); |
2361 | tty_port_destroy(&rp_table[i]->port); | ||
2360 | kfree(rp_table[i]); | 2362 | kfree(rp_table[i]); |
2361 | } | 2363 | } |
2362 | 2364 | ||
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 66c38a3f74ce..f99a84526f82 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -1225,6 +1225,8 @@ rs68328_init(void) | |||
1225 | 1225 | ||
1226 | if (tty_register_driver(serial_driver)) { | 1226 | if (tty_register_driver(serial_driver)) { |
1227 | put_tty_driver(serial_driver); | 1227 | put_tty_driver(serial_driver); |
1228 | for (i = 0; i < NR_PORTS; i++) | ||
1229 | tty_port_destroy(&m68k_soft[i].tport); | ||
1228 | printk(KERN_ERR "Couldn't register serial driver\n"); | 1230 | printk(KERN_ERR "Couldn't register serial driver\n"); |
1229 | return -ENOMEM; | 1231 | return -ENOMEM; |
1230 | } | 1232 | } |
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 3ba4234592bc..d085e3a8ec06 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
@@ -280,7 +280,17 @@ static const struct serial8250_config uart_config[] = { | |||
280 | .fifo_size = 64, | 280 | .fifo_size = 64, |
281 | .tx_loadsz = 64, | 281 | .tx_loadsz = 64, |
282 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 282 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
283 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, | 283 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | |
284 | UART_CAP_SLEEP, | ||
285 | }, | ||
286 | [PORT_XR17V35X] = { | ||
287 | .name = "XR17V35X", | ||
288 | .fifo_size = 256, | ||
289 | .tx_loadsz = 256, | ||
290 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | | ||
291 | UART_FCR_T_TRIG_11, | ||
292 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | | ||
293 | UART_CAP_SLEEP, | ||
284 | }, | 294 | }, |
285 | [PORT_LPC3220] = { | 295 | [PORT_LPC3220] = { |
286 | .name = "LPC3220", | 296 | .name = "LPC3220", |
@@ -455,6 +465,7 @@ static void io_serial_out(struct uart_port *p, int offset, int value) | |||
455 | } | 465 | } |
456 | 466 | ||
457 | static int serial8250_default_handle_irq(struct uart_port *port); | 467 | static int serial8250_default_handle_irq(struct uart_port *port); |
468 | static int exar_handle_irq(struct uart_port *port); | ||
458 | 469 | ||
459 | static void set_io_from_upio(struct uart_port *p) | 470 | static void set_io_from_upio(struct uart_port *p) |
460 | { | 471 | { |
@@ -574,6 +585,19 @@ EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); | |||
574 | */ | 585 | */ |
575 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | 586 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) |
576 | { | 587 | { |
588 | /* | ||
589 | * Exar UARTs have a SLEEP register that enables or disables | ||
590 | * each UART to enter sleep mode separately. On the XR17V35x the | ||
591 | * register is accessible to each UART at the UART_EXAR_SLEEP | ||
592 | * offset but the UART channel may only write to the corresponding | ||
593 | * bit. | ||
594 | */ | ||
595 | if ((p->port.type == PORT_XR17V35X) || | ||
596 | (p->port.type == PORT_XR17D15X)) { | ||
597 | serial_out(p, UART_EXAR_SLEEP, 0xff); | ||
598 | return; | ||
599 | } | ||
600 | |||
577 | if (p->capabilities & UART_CAP_SLEEP) { | 601 | if (p->capabilities & UART_CAP_SLEEP) { |
578 | if (p->capabilities & UART_CAP_EFR) { | 602 | if (p->capabilities & UART_CAP_EFR) { |
579 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); | 603 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
@@ -882,6 +906,27 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
882 | up->capabilities |= UART_CAP_FIFO; | 906 | up->capabilities |= UART_CAP_FIFO; |
883 | 907 | ||
884 | /* | 908 | /* |
909 | * XR17V35x UARTs have an extra divisor register, DLD | ||
910 | * that gets enabled with when DLAB is set which will | ||
911 | * cause the device to incorrectly match and assign | ||
912 | * port type to PORT_16650. The EFR for this UART is | ||
913 | * found at offset 0x09. Instead check the Deice ID (DVID) | ||
914 | * register for a 2, 4 or 8 port UART. | ||
915 | */ | ||
916 | if (up->port.flags & UPF_EXAR_EFR) { | ||
917 | status1 = serial_in(up, UART_EXAR_DVID); | ||
918 | if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) { | ||
919 | DEBUG_AUTOCONF("Exar XR17V35x "); | ||
920 | up->port.type = PORT_XR17V35X; | ||
921 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | | ||
922 | UART_CAP_SLEEP; | ||
923 | |||
924 | return; | ||
925 | } | ||
926 | |||
927 | } | ||
928 | |||
929 | /* | ||
885 | * Check for presence of the EFR when DLAB is set. | 930 | * Check for presence of the EFR when DLAB is set. |
886 | * Only ST16C650V1 UARTs pass this test. | 931 | * Only ST16C650V1 UARTs pass this test. |
887 | */ | 932 | */ |
@@ -1013,8 +1058,12 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
1013 | * Exar uarts have EFR in a weird location | 1058 | * Exar uarts have EFR in a weird location |
1014 | */ | 1059 | */ |
1015 | if (up->port.flags & UPF_EXAR_EFR) { | 1060 | if (up->port.flags & UPF_EXAR_EFR) { |
1061 | DEBUG_AUTOCONF("Exar XR17D15x "); | ||
1016 | up->port.type = PORT_XR17D15X; | 1062 | up->port.type = PORT_XR17D15X; |
1017 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR; | 1063 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | |
1064 | UART_CAP_SLEEP; | ||
1065 | |||
1066 | return; | ||
1018 | } | 1067 | } |
1019 | 1068 | ||
1020 | /* | 1069 | /* |
@@ -1516,6 +1565,31 @@ static int serial8250_default_handle_irq(struct uart_port *port) | |||
1516 | } | 1565 | } |
1517 | 1566 | ||
1518 | /* | 1567 | /* |
1568 | * These Exar UARTs have an extra interrupt indicator that could | ||
1569 | * fire for a few unimplemented interrupts. One of which is a | ||
1570 | * wakeup event when coming out of sleep. Put this here just | ||
1571 | * to be on the safe side that these interrupts don't go unhandled. | ||
1572 | */ | ||
1573 | static int exar_handle_irq(struct uart_port *port) | ||
1574 | { | ||
1575 | unsigned char int0, int1, int2, int3; | ||
1576 | unsigned int iir = serial_port_in(port, UART_IIR); | ||
1577 | int ret; | ||
1578 | |||
1579 | ret = serial8250_handle_irq(port, iir); | ||
1580 | |||
1581 | if ((port->type == PORT_XR17V35X) || | ||
1582 | (port->type == PORT_XR17D15X)) { | ||
1583 | int0 = serial_port_in(port, 0x80); | ||
1584 | int1 = serial_port_in(port, 0x81); | ||
1585 | int2 = serial_port_in(port, 0x82); | ||
1586 | int3 = serial_port_in(port, 0x83); | ||
1587 | } | ||
1588 | |||
1589 | return ret; | ||
1590 | } | ||
1591 | |||
1592 | /* | ||
1519 | * This is the serial driver's interrupt routine. | 1593 | * This is the serial driver's interrupt routine. |
1520 | * | 1594 | * |
1521 | * Arjan thinks the old way was overly complex, so it got simplified. | 1595 | * Arjan thinks the old way was overly complex, so it got simplified. |
@@ -2349,16 +2423,14 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2349 | serial_port_out(port, UART_EFR, efr); | 2423 | serial_port_out(port, UART_EFR, efr); |
2350 | } | 2424 | } |
2351 | 2425 | ||
2352 | #ifdef CONFIG_ARCH_OMAP1 | ||
2353 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ | 2426 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ |
2354 | if (cpu_is_omap1510() && is_omap_port(up)) { | 2427 | if (is_omap1510_8250(up)) { |
2355 | if (baud == 115200) { | 2428 | if (baud == 115200) { |
2356 | quot = 1; | 2429 | quot = 1; |
2357 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); | 2430 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); |
2358 | } else | 2431 | } else |
2359 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); | 2432 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); |
2360 | } | 2433 | } |
2361 | #endif | ||
2362 | 2434 | ||
2363 | /* | 2435 | /* |
2364 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, | 2436 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, |
@@ -2439,10 +2511,9 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt) | |||
2439 | { | 2511 | { |
2440 | if (pt->port.iotype == UPIO_AU) | 2512 | if (pt->port.iotype == UPIO_AU) |
2441 | return 0x1000; | 2513 | return 0x1000; |
2442 | #ifdef CONFIG_ARCH_OMAP1 | 2514 | if (is_omap1_8250(pt)) |
2443 | if (is_omap_port(pt)) | ||
2444 | return 0x16 << pt->port.regshift; | 2515 | return 0x16 << pt->port.regshift; |
2445 | #endif | 2516 | |
2446 | return 8 << pt->port.regshift; | 2517 | return 8 << pt->port.regshift; |
2447 | } | 2518 | } |
2448 | 2519 | ||
@@ -2617,6 +2688,11 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
2617 | serial8250_release_rsa_resource(up); | 2688 | serial8250_release_rsa_resource(up); |
2618 | if (port->type == PORT_UNKNOWN) | 2689 | if (port->type == PORT_UNKNOWN) |
2619 | serial8250_release_std_resource(up); | 2690 | serial8250_release_std_resource(up); |
2691 | |||
2692 | /* Fixme: probably not the best place for this */ | ||
2693 | if ((port->type == PORT_XR17V35X) || | ||
2694 | (port->type == PORT_XR17D15X)) | ||
2695 | port->handle_irq = exar_handle_irq; | ||
2620 | } | 2696 | } |
2621 | 2697 | ||
2622 | static int | 2698 | static int |
@@ -2992,7 +3068,7 @@ void serial8250_resume_port(int line) | |||
2992 | * list is terminated with a zero flags entry, which means we expect | 3068 | * list is terminated with a zero flags entry, which means we expect |
2993 | * all entries to have at least UPF_BOOT_AUTOCONF set. | 3069 | * all entries to have at least UPF_BOOT_AUTOCONF set. |
2994 | */ | 3070 | */ |
2995 | static int __devinit serial8250_probe(struct platform_device *dev) | 3071 | static int serial8250_probe(struct platform_device *dev) |
2996 | { | 3072 | { |
2997 | struct plat_serial8250_port *p = dev->dev.platform_data; | 3073 | struct plat_serial8250_port *p = dev->dev.platform_data; |
2998 | struct uart_8250_port uart; | 3074 | struct uart_8250_port uart; |
@@ -3038,7 +3114,7 @@ static int __devinit serial8250_probe(struct platform_device *dev) | |||
3038 | /* | 3114 | /* |
3039 | * Remove serial ports registered against a platform device. | 3115 | * Remove serial ports registered against a platform device. |
3040 | */ | 3116 | */ |
3041 | static int __devexit serial8250_remove(struct platform_device *dev) | 3117 | static int serial8250_remove(struct platform_device *dev) |
3042 | { | 3118 | { |
3043 | int i; | 3119 | int i; |
3044 | 3120 | ||
@@ -3081,7 +3157,7 @@ static int serial8250_resume(struct platform_device *dev) | |||
3081 | 3157 | ||
3082 | static struct platform_driver serial8250_isa_driver = { | 3158 | static struct platform_driver serial8250_isa_driver = { |
3083 | .probe = serial8250_probe, | 3159 | .probe = serial8250_probe, |
3084 | .remove = __devexit_p(serial8250_remove), | 3160 | .remove = serial8250_remove, |
3085 | .suspend = serial8250_suspend, | 3161 | .suspend = serial8250_suspend, |
3086 | .resume = serial8250_resume, | 3162 | .resume = serial8250_resume, |
3087 | .driver = { | 3163 | .driver = { |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 5a76f9c8d36b..3b4ea84898c2 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -106,3 +106,39 @@ static inline int serial8250_pnp_init(void) { return 0; } | |||
106 | static inline void serial8250_pnp_exit(void) { } | 106 | static inline void serial8250_pnp_exit(void) { } |
107 | #endif | 107 | #endif |
108 | 108 | ||
109 | #ifdef CONFIG_ARCH_OMAP1 | ||
110 | static inline int is_omap1_8250(struct uart_8250_port *pt) | ||
111 | { | ||
112 | int res; | ||
113 | |||
114 | switch (pt->port.mapbase) { | ||
115 | case OMAP1_UART1_BASE: | ||
116 | case OMAP1_UART2_BASE: | ||
117 | case OMAP1_UART3_BASE: | ||
118 | res = 1; | ||
119 | break; | ||
120 | default: | ||
121 | res = 0; | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | return res; | ||
126 | } | ||
127 | |||
128 | static inline int is_omap1510_8250(struct uart_8250_port *pt) | ||
129 | { | ||
130 | if (!cpu_is_omap1510()) | ||
131 | return 0; | ||
132 | |||
133 | return is_omap1_8250(pt); | ||
134 | } | ||
135 | #else | ||
136 | static inline int is_omap1_8250(struct uart_8250_port *pt) | ||
137 | { | ||
138 | return 0; | ||
139 | } | ||
140 | static inline int is_omap1510_8250(struct uart_8250_port *pt) | ||
141 | { | ||
142 | return 0; | ||
143 | } | ||
144 | #endif | ||
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c index 857498312a9a..549aa07c0d27 100644 --- a/drivers/tty/serial/8250/8250_acorn.c +++ b/drivers/tty/serial/8250/8250_acorn.c | |||
@@ -38,7 +38,7 @@ struct serial_card_info { | |||
38 | void __iomem *vaddr; | 38 | void __iomem *vaddr; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static int __devinit | 41 | static int |
42 | serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | 42 | serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) |
43 | { | 43 | { |
44 | struct serial_card_info *info; | 44 | struct serial_card_info *info; |
@@ -80,7 +80,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | static void __devexit serial_card_remove(struct expansion_card *ec) | 83 | static void serial_card_remove(struct expansion_card *ec) |
84 | { | 84 | { |
85 | struct serial_card_info *info = ecard_get_drvdata(ec); | 85 | struct serial_card_info *info = ecard_get_drvdata(ec); |
86 | int i; | 86 | int i; |
@@ -116,7 +116,7 @@ static const struct ecard_id serial_cids[] = { | |||
116 | 116 | ||
117 | static struct ecard_driver serial_card_driver = { | 117 | static struct ecard_driver serial_card_driver = { |
118 | .probe = serial_card_probe, | 118 | .probe = serial_card_probe, |
119 | .remove = __devexit_p(serial_card_remove), | 119 | .remove = serial_card_remove, |
120 | .id_table = serial_cids, | 120 | .id_table = serial_cids, |
121 | .drv = { | 121 | .drv = { |
122 | .name = "8250_acorn", | 122 | .name = "8250_acorn", |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index c3b2ec0c8c0b..1d0dba2d562d 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -87,7 +87,7 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | 89 | ||
90 | static int __devinit dw8250_probe(struct platform_device *pdev) | 90 | static int dw8250_probe(struct platform_device *pdev) |
91 | { | 91 | { |
92 | struct uart_8250_port uart = {}; | 92 | struct uart_8250_port uart = {}; |
93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -152,7 +152,7 @@ static int __devinit dw8250_probe(struct platform_device *pdev) | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int __devexit dw8250_remove(struct platform_device *pdev) | 155 | static int dw8250_remove(struct platform_device *pdev) |
156 | { | 156 | { |
157 | struct dw8250_data *data = platform_get_drvdata(pdev); | 157 | struct dw8250_data *data = platform_get_drvdata(pdev); |
158 | 158 | ||
@@ -161,6 +161,29 @@ static int __devexit dw8250_remove(struct platform_device *pdev) | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | #ifdef CONFIG_PM | ||
165 | static int dw8250_suspend(struct platform_device *pdev, pm_message_t state) | ||
166 | { | ||
167 | struct dw8250_data *data = platform_get_drvdata(pdev); | ||
168 | |||
169 | serial8250_suspend_port(data->line); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int dw8250_resume(struct platform_device *pdev) | ||
175 | { | ||
176 | struct dw8250_data *data = platform_get_drvdata(pdev); | ||
177 | |||
178 | serial8250_resume_port(data->line); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | #else | ||
183 | #define dw8250_suspend NULL | ||
184 | #define dw8250_resume NULL | ||
185 | #endif /* CONFIG_PM */ | ||
186 | |||
164 | static const struct of_device_id dw8250_match[] = { | 187 | static const struct of_device_id dw8250_match[] = { |
165 | { .compatible = "snps,dw-apb-uart" }, | 188 | { .compatible = "snps,dw-apb-uart" }, |
166 | { /* Sentinel */ } | 189 | { /* Sentinel */ } |
@@ -174,7 +197,9 @@ static struct platform_driver dw8250_platform_driver = { | |||
174 | .of_match_table = dw8250_match, | 197 | .of_match_table = dw8250_match, |
175 | }, | 198 | }, |
176 | .probe = dw8250_probe, | 199 | .probe = dw8250_probe, |
177 | .remove = __devexit_p(dw8250_remove), | 200 | .remove = dw8250_remove, |
201 | .suspend = dw8250_suspend, | ||
202 | .resume = dw8250_resume, | ||
178 | }; | 203 | }; |
179 | 204 | ||
180 | module_platform_driver(dw8250_platform_driver); | 205 | module_platform_driver(dw8250_platform_driver); |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index eaafb98debed..f53a7db4350d 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -48,7 +48,7 @@ struct early_serial8250_device { | |||
48 | 48 | ||
49 | static struct early_serial8250_device early_device; | 49 | static struct early_serial8250_device early_device; |
50 | 50 | ||
51 | static unsigned int __init serial_in(struct uart_port *port, int offset) | 51 | unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset) |
52 | { | 52 | { |
53 | switch (port->iotype) { | 53 | switch (port->iotype) { |
54 | case UPIO_MEM: | 54 | case UPIO_MEM: |
@@ -62,7 +62,7 @@ static unsigned int __init serial_in(struct uart_port *port, int offset) | |||
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
65 | static void __init serial_out(struct uart_port *port, int offset, int value) | 65 | void __weak __init serial8250_early_out(struct uart_port *port, int offset, int value) |
66 | { | 66 | { |
67 | switch (port->iotype) { | 67 | switch (port->iotype) { |
68 | case UPIO_MEM: | 68 | case UPIO_MEM: |
@@ -84,7 +84,7 @@ static void __init wait_for_xmitr(struct uart_port *port) | |||
84 | unsigned int status; | 84 | unsigned int status; |
85 | 85 | ||
86 | for (;;) { | 86 | for (;;) { |
87 | status = serial_in(port, UART_LSR); | 87 | status = serial8250_early_in(port, UART_LSR); |
88 | if ((status & BOTH_EMPTY) == BOTH_EMPTY) | 88 | if ((status & BOTH_EMPTY) == BOTH_EMPTY) |
89 | return; | 89 | return; |
90 | cpu_relax(); | 90 | cpu_relax(); |
@@ -94,7 +94,7 @@ static void __init wait_for_xmitr(struct uart_port *port) | |||
94 | static void __init serial_putc(struct uart_port *port, int c) | 94 | static void __init serial_putc(struct uart_port *port, int c) |
95 | { | 95 | { |
96 | wait_for_xmitr(port); | 96 | wait_for_xmitr(port); |
97 | serial_out(port, UART_TX, c); | 97 | serial8250_early_out(port, UART_TX, c); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void __init early_serial8250_write(struct console *console, | 100 | static void __init early_serial8250_write(struct console *console, |
@@ -104,14 +104,14 @@ static void __init early_serial8250_write(struct console *console, | |||
104 | unsigned int ier; | 104 | unsigned int ier; |
105 | 105 | ||
106 | /* Save the IER and disable interrupts */ | 106 | /* Save the IER and disable interrupts */ |
107 | ier = serial_in(port, UART_IER); | 107 | ier = serial8250_early_in(port, UART_IER); |
108 | serial_out(port, UART_IER, 0); | 108 | serial8250_early_out(port, UART_IER, 0); |
109 | 109 | ||
110 | uart_console_write(port, s, count, serial_putc); | 110 | uart_console_write(port, s, count, serial_putc); |
111 | 111 | ||
112 | /* Wait for transmitter to become empty and restore the IER */ | 112 | /* Wait for transmitter to become empty and restore the IER */ |
113 | wait_for_xmitr(port); | 113 | wait_for_xmitr(port); |
114 | serial_out(port, UART_IER, ier); | 114 | serial8250_early_out(port, UART_IER, ier); |
115 | } | 115 | } |
116 | 116 | ||
117 | static unsigned int __init probe_baud(struct uart_port *port) | 117 | static unsigned int __init probe_baud(struct uart_port *port) |
@@ -119,11 +119,11 @@ static unsigned int __init probe_baud(struct uart_port *port) | |||
119 | unsigned char lcr, dll, dlm; | 119 | unsigned char lcr, dll, dlm; |
120 | unsigned int quot; | 120 | unsigned int quot; |
121 | 121 | ||
122 | lcr = serial_in(port, UART_LCR); | 122 | lcr = serial8250_early_in(port, UART_LCR); |
123 | serial_out(port, UART_LCR, lcr | UART_LCR_DLAB); | 123 | serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB); |
124 | dll = serial_in(port, UART_DLL); | 124 | dll = serial8250_early_in(port, UART_DLL); |
125 | dlm = serial_in(port, UART_DLM); | 125 | dlm = serial8250_early_in(port, UART_DLM); |
126 | serial_out(port, UART_LCR, lcr); | 126 | serial8250_early_out(port, UART_LCR, lcr); |
127 | 127 | ||
128 | quot = (dlm << 8) | dll; | 128 | quot = (dlm << 8) | dll; |
129 | return (port->uartclk / 16) / quot; | 129 | return (port->uartclk / 16) / quot; |
@@ -135,17 +135,17 @@ static void __init init_port(struct early_serial8250_device *device) | |||
135 | unsigned int divisor; | 135 | unsigned int divisor; |
136 | unsigned char c; | 136 | unsigned char c; |
137 | 137 | ||
138 | serial_out(port, UART_LCR, 0x3); /* 8n1 */ | 138 | serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */ |
139 | serial_out(port, UART_IER, 0); /* no interrupt */ | 139 | serial8250_early_out(port, UART_IER, 0); /* no interrupt */ |
140 | serial_out(port, UART_FCR, 0); /* no fifo */ | 140 | serial8250_early_out(port, UART_FCR, 0); /* no fifo */ |
141 | serial_out(port, UART_MCR, 0x3); /* DTR + RTS */ | 141 | serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */ |
142 | 142 | ||
143 | divisor = port->uartclk / (16 * device->baud); | 143 | divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); |
144 | c = serial_in(port, UART_LCR); | 144 | c = serial8250_early_in(port, UART_LCR); |
145 | serial_out(port, UART_LCR, c | UART_LCR_DLAB); | 145 | serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); |
146 | serial_out(port, UART_DLL, divisor & 0xff); | 146 | serial8250_early_out(port, UART_DLL, divisor & 0xff); |
147 | serial_out(port, UART_DLM, (divisor >> 8) & 0xff); | 147 | serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); |
148 | serial_out(port, UART_LCR, c & ~UART_LCR_DLAB); | 148 | serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); |
149 | } | 149 | } |
150 | 150 | ||
151 | static int __init parse_options(struct early_serial8250_device *device, | 151 | static int __init parse_options(struct early_serial8250_device *device, |
diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c index 3a0363e7f3a7..916cc19fbbda 100644 --- a/drivers/tty/serial/8250/8250_em.c +++ b/drivers/tty/serial/8250/8250_em.c | |||
@@ -89,7 +89,7 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value) | |||
89 | serial_out(up, UART_DLM_EM, value >> 8 & 0xff); | 89 | serial_out(up, UART_DLM_EM, value >> 8 & 0xff); |
90 | } | 90 | } |
91 | 91 | ||
92 | static int __devinit serial8250_em_probe(struct platform_device *pdev) | 92 | static int serial8250_em_probe(struct platform_device *pdev) |
93 | { | 93 | { |
94 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 94 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
95 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 95 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
@@ -152,7 +152,7 @@ static int __devinit serial8250_em_probe(struct platform_device *pdev) | |||
152 | return ret; | 152 | return ret; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int __devexit serial8250_em_remove(struct platform_device *pdev) | 155 | static int serial8250_em_remove(struct platform_device *pdev) |
156 | { | 156 | { |
157 | struct serial8250_em_priv *priv = platform_get_drvdata(pdev); | 157 | struct serial8250_em_priv *priv = platform_get_drvdata(pdev); |
158 | 158 | ||
@@ -163,7 +163,7 @@ static int __devexit serial8250_em_remove(struct platform_device *pdev) | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | static const struct of_device_id serial8250_em_dt_ids[] __devinitconst = { | 166 | static const struct of_device_id serial8250_em_dt_ids[] = { |
167 | { .compatible = "renesas,em-uart", }, | 167 | { .compatible = "renesas,em-uart", }, |
168 | {}, | 168 | {}, |
169 | }; | 169 | }; |
@@ -176,7 +176,7 @@ static struct platform_driver serial8250_em_platform_driver = { | |||
176 | .owner = THIS_MODULE, | 176 | .owner = THIS_MODULE, |
177 | }, | 177 | }, |
178 | .probe = serial8250_em_probe, | 178 | .probe = serial8250_em_probe, |
179 | .remove = __devexit_p(serial8250_em_remove), | 179 | .remove = serial8250_em_remove, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | module_platform_driver(serial8250_em_platform_driver); | 182 | module_platform_driver(serial8250_em_platform_driver); |
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index f3d0edf46644..5bdaf271d395 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c | |||
@@ -36,9 +36,9 @@ static struct hp300_port *hp300_ports; | |||
36 | 36 | ||
37 | #ifdef CONFIG_HPDCA | 37 | #ifdef CONFIG_HPDCA |
38 | 38 | ||
39 | static int __devinit hpdca_init_one(struct dio_dev *d, | 39 | static int hpdca_init_one(struct dio_dev *d, |
40 | const struct dio_device_id *ent); | 40 | const struct dio_device_id *ent); |
41 | static void __devexit hpdca_remove_one(struct dio_dev *d); | 41 | static void hpdca_remove_one(struct dio_dev *d); |
42 | 42 | ||
43 | static struct dio_device_id hpdca_dio_tbl[] = { | 43 | static struct dio_device_id hpdca_dio_tbl[] = { |
44 | { DIO_ID_DCA0 }, | 44 | { DIO_ID_DCA0 }, |
@@ -52,7 +52,7 @@ static struct dio_driver hpdca_driver = { | |||
52 | .name = "hpdca", | 52 | .name = "hpdca", |
53 | .id_table = hpdca_dio_tbl, | 53 | .id_table = hpdca_dio_tbl, |
54 | .probe = hpdca_init_one, | 54 | .probe = hpdca_init_one, |
55 | .remove = __devexit_p(hpdca_remove_one), | 55 | .remove = hpdca_remove_one, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | #endif | 58 | #endif |
@@ -159,7 +159,7 @@ int __init hp300_setup_serial_console(void) | |||
159 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ | 159 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ |
160 | 160 | ||
161 | #ifdef CONFIG_HPDCA | 161 | #ifdef CONFIG_HPDCA |
162 | static int __devinit hpdca_init_one(struct dio_dev *d, | 162 | static int hpdca_init_one(struct dio_dev *d, |
163 | const struct dio_device_id *ent) | 163 | const struct dio_device_id *ent) |
164 | { | 164 | { |
165 | struct uart_8250_port uart; | 165 | struct uart_8250_port uart; |
@@ -288,7 +288,7 @@ static int __init hp300_8250_init(void) | |||
288 | } | 288 | } |
289 | 289 | ||
290 | #ifdef CONFIG_HPDCA | 290 | #ifdef CONFIG_HPDCA |
291 | static void __devexit hpdca_remove_one(struct dio_dev *d) | 291 | static void hpdca_remove_one(struct dio_dev *d) |
292 | { | 292 | { |
293 | int line; | 293 | int line; |
294 | 294 | ||
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 17b7d26abf41..26b9dc012ed0 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -288,7 +288,7 @@ static int pci_plx9050_init(struct pci_dev *dev) | |||
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
290 | 290 | ||
291 | static void __devexit pci_plx9050_exit(struct pci_dev *dev) | 291 | static void pci_plx9050_exit(struct pci_dev *dev) |
292 | { | 292 | { |
293 | u8 __iomem *p; | 293 | u8 __iomem *p; |
294 | 294 | ||
@@ -313,7 +313,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev) | |||
313 | #define NI8420_INT_ENABLE_REG 0x38 | 313 | #define NI8420_INT_ENABLE_REG 0x38 |
314 | #define NI8420_INT_ENABLE_BIT 0x2000 | 314 | #define NI8420_INT_ENABLE_BIT 0x2000 |
315 | 315 | ||
316 | static void __devexit pci_ni8420_exit(struct pci_dev *dev) | 316 | static void pci_ni8420_exit(struct pci_dev *dev) |
317 | { | 317 | { |
318 | void __iomem *p; | 318 | void __iomem *p; |
319 | unsigned long base, len; | 319 | unsigned long base, len; |
@@ -345,7 +345,7 @@ static void __devexit pci_ni8420_exit(struct pci_dev *dev) | |||
345 | 345 | ||
346 | #define MITE_LCIMR2_CLR_CPU_IE (1 << 30) | 346 | #define MITE_LCIMR2_CLR_CPU_IE (1 << 30) |
347 | 347 | ||
348 | static void __devexit pci_ni8430_exit(struct pci_dev *dev) | 348 | static void pci_ni8430_exit(struct pci_dev *dev) |
349 | { | 349 | { |
350 | void __iomem *p; | 350 | void __iomem *p; |
351 | unsigned long base, len; | 351 | unsigned long base, len; |
@@ -422,7 +422,7 @@ static int sbs_init(struct pci_dev *dev) | |||
422 | * Disables the global interrupt of PMC-OctalPro | 422 | * Disables the global interrupt of PMC-OctalPro |
423 | */ | 423 | */ |
424 | 424 | ||
425 | static void __devexit sbs_exit(struct pci_dev *dev) | 425 | static void sbs_exit(struct pci_dev *dev) |
426 | { | 426 | { |
427 | u8 __iomem *p; | 427 | u8 __iomem *p; |
428 | 428 | ||
@@ -991,7 +991,7 @@ static int pci_ite887x_init(struct pci_dev *dev) | |||
991 | return ret; | 991 | return ret; |
992 | } | 992 | } |
993 | 993 | ||
994 | static void __devexit pci_ite887x_exit(struct pci_dev *dev) | 994 | static void pci_ite887x_exit(struct pci_dev *dev) |
995 | { | 995 | { |
996 | u32 ioport; | 996 | u32 ioport; |
997 | /* the ioport is bit 0-15 in POSIO0R */ | 997 | /* the ioport is bit 0-15 in POSIO0R */ |
@@ -1068,7 +1068,7 @@ ce4100_serial_setup(struct serial_private *priv, | |||
1068 | { | 1068 | { |
1069 | int ret; | 1069 | int ret; |
1070 | 1070 | ||
1071 | ret = setup_port(priv, port, 0, 0, board->reg_shift); | 1071 | ret = setup_port(priv, port, idx, 0, board->reg_shift); |
1072 | port->port.iotype = UPIO_MEM32; | 1072 | port->port.iotype = UPIO_MEM32; |
1073 | port->port.type = PORT_XSCALE; | 1073 | port->port.type = PORT_XSCALE; |
1074 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1074 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
@@ -1165,6 +1165,94 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static int | 1167 | static int |
1168 | pci_xr17v35x_setup(struct serial_private *priv, | ||
1169 | const struct pciserial_board *board, | ||
1170 | struct uart_8250_port *port, int idx) | ||
1171 | { | ||
1172 | u8 __iomem *p; | ||
1173 | |||
1174 | p = pci_ioremap_bar(priv->dev, 0); | ||
1175 | if (p == NULL) | ||
1176 | return -ENOMEM; | ||
1177 | |||
1178 | port->port.flags |= UPF_EXAR_EFR; | ||
1179 | |||
1180 | /* | ||
1181 | * Setup Multipurpose Input/Output pins. | ||
1182 | */ | ||
1183 | if (idx == 0) { | ||
1184 | writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/ | ||
1185 | writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/ | ||
1186 | writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/ | ||
1187 | writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/ | ||
1188 | writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/ | ||
1189 | writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/ | ||
1190 | writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/ | ||
1191 | writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/ | ||
1192 | writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/ | ||
1193 | writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/ | ||
1194 | writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/ | ||
1195 | writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/ | ||
1196 | } | ||
1197 | writeb(0x00, p + UART_EXAR_8XMODE); | ||
1198 | writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); | ||
1199 | writeb(128, p + UART_EXAR_TXTRG); | ||
1200 | writeb(128, p + UART_EXAR_RXTRG); | ||
1201 | iounmap(p); | ||
1202 | |||
1203 | return pci_default_setup(priv, board, port, idx); | ||
1204 | } | ||
1205 | |||
1206 | #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 | ||
1207 | #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 | ||
1208 | #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a | ||
1209 | #define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b | ||
1210 | |||
1211 | static int | ||
1212 | pci_fastcom335_setup(struct serial_private *priv, | ||
1213 | const struct pciserial_board *board, | ||
1214 | struct uart_8250_port *port, int idx) | ||
1215 | { | ||
1216 | u8 __iomem *p; | ||
1217 | |||
1218 | p = pci_ioremap_bar(priv->dev, 0); | ||
1219 | if (p == NULL) | ||
1220 | return -ENOMEM; | ||
1221 | |||
1222 | port->port.flags |= UPF_EXAR_EFR; | ||
1223 | |||
1224 | /* | ||
1225 | * Setup Multipurpose Input/Output pins. | ||
1226 | */ | ||
1227 | if (idx == 0) { | ||
1228 | switch (priv->dev->device) { | ||
1229 | case PCI_DEVICE_ID_COMMTECH_4222PCI335: | ||
1230 | case PCI_DEVICE_ID_COMMTECH_4224PCI335: | ||
1231 | writeb(0x78, p + 0x90); /* MPIOLVL[7:0] */ | ||
1232 | writeb(0x00, p + 0x92); /* MPIOINV[7:0] */ | ||
1233 | writeb(0x00, p + 0x93); /* MPIOSEL[7:0] */ | ||
1234 | break; | ||
1235 | case PCI_DEVICE_ID_COMMTECH_2324PCI335: | ||
1236 | case PCI_DEVICE_ID_COMMTECH_2328PCI335: | ||
1237 | writeb(0x00, p + 0x90); /* MPIOLVL[7:0] */ | ||
1238 | writeb(0xc0, p + 0x92); /* MPIOINV[7:0] */ | ||
1239 | writeb(0xc0, p + 0x93); /* MPIOSEL[7:0] */ | ||
1240 | break; | ||
1241 | } | ||
1242 | writeb(0x00, p + 0x8f); /* MPIOINT[7:0] */ | ||
1243 | writeb(0x00, p + 0x91); /* MPIO3T[7:0] */ | ||
1244 | writeb(0x00, p + 0x94); /* MPIOOD[7:0] */ | ||
1245 | } | ||
1246 | writeb(0x00, p + UART_EXAR_8XMODE); | ||
1247 | writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); | ||
1248 | writeb(32, p + UART_EXAR_TXTRG); | ||
1249 | writeb(32, p + UART_EXAR_RXTRG); | ||
1250 | iounmap(p); | ||
1251 | |||
1252 | return pci_default_setup(priv, board, port, idx); | ||
1253 | } | ||
1254 | |||
1255 | static int | ||
1168 | pci_wch_ch353_setup(struct serial_private *priv, | 1256 | pci_wch_ch353_setup(struct serial_private *priv, |
1169 | const struct pciserial_board *board, | 1257 | const struct pciserial_board *board, |
1170 | struct uart_8250_port *port, int idx) | 1258 | struct uart_8250_port *port, int idx) |
@@ -1213,6 +1301,10 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1213 | #define PCI_VENDOR_ID_AGESTAR 0x5372 | 1301 | #define PCI_VENDOR_ID_AGESTAR 0x5372 |
1214 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 | 1302 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 |
1215 | #define PCI_VENDOR_ID_ASIX 0x9710 | 1303 | #define PCI_VENDOR_ID_ASIX 0x9710 |
1304 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0019 | ||
1305 | #define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 | ||
1306 | #define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 | ||
1307 | |||
1216 | 1308 | ||
1217 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1309 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1218 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1310 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1314,7 +1406,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1314 | .subdevice = PCI_ANY_ID, | 1406 | .subdevice = PCI_ANY_ID, |
1315 | .init = pci_ite887x_init, | 1407 | .init = pci_ite887x_init, |
1316 | .setup = pci_default_setup, | 1408 | .setup = pci_default_setup, |
1317 | .exit = __devexit_p(pci_ite887x_exit), | 1409 | .exit = pci_ite887x_exit, |
1318 | }, | 1410 | }, |
1319 | /* | 1411 | /* |
1320 | * National Instruments | 1412 | * National Instruments |
@@ -1326,7 +1418,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1326 | .subdevice = PCI_ANY_ID, | 1418 | .subdevice = PCI_ANY_ID, |
1327 | .init = pci_ni8420_init, | 1419 | .init = pci_ni8420_init, |
1328 | .setup = pci_default_setup, | 1420 | .setup = pci_default_setup, |
1329 | .exit = __devexit_p(pci_ni8420_exit), | 1421 | .exit = pci_ni8420_exit, |
1330 | }, | 1422 | }, |
1331 | { | 1423 | { |
1332 | .vendor = PCI_VENDOR_ID_NI, | 1424 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1335,7 +1427,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1335 | .subdevice = PCI_ANY_ID, | 1427 | .subdevice = PCI_ANY_ID, |
1336 | .init = pci_ni8420_init, | 1428 | .init = pci_ni8420_init, |
1337 | .setup = pci_default_setup, | 1429 | .setup = pci_default_setup, |
1338 | .exit = __devexit_p(pci_ni8420_exit), | 1430 | .exit = pci_ni8420_exit, |
1339 | }, | 1431 | }, |
1340 | { | 1432 | { |
1341 | .vendor = PCI_VENDOR_ID_NI, | 1433 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1344,7 +1436,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1344 | .subdevice = PCI_ANY_ID, | 1436 | .subdevice = PCI_ANY_ID, |
1345 | .init = pci_ni8420_init, | 1437 | .init = pci_ni8420_init, |
1346 | .setup = pci_default_setup, | 1438 | .setup = pci_default_setup, |
1347 | .exit = __devexit_p(pci_ni8420_exit), | 1439 | .exit = pci_ni8420_exit, |
1348 | }, | 1440 | }, |
1349 | { | 1441 | { |
1350 | .vendor = PCI_VENDOR_ID_NI, | 1442 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1353,7 +1445,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1353 | .subdevice = PCI_ANY_ID, | 1445 | .subdevice = PCI_ANY_ID, |
1354 | .init = pci_ni8420_init, | 1446 | .init = pci_ni8420_init, |
1355 | .setup = pci_default_setup, | 1447 | .setup = pci_default_setup, |
1356 | .exit = __devexit_p(pci_ni8420_exit), | 1448 | .exit = pci_ni8420_exit, |
1357 | }, | 1449 | }, |
1358 | { | 1450 | { |
1359 | .vendor = PCI_VENDOR_ID_NI, | 1451 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1362,7 +1454,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1362 | .subdevice = PCI_ANY_ID, | 1454 | .subdevice = PCI_ANY_ID, |
1363 | .init = pci_ni8420_init, | 1455 | .init = pci_ni8420_init, |
1364 | .setup = pci_default_setup, | 1456 | .setup = pci_default_setup, |
1365 | .exit = __devexit_p(pci_ni8420_exit), | 1457 | .exit = pci_ni8420_exit, |
1366 | }, | 1458 | }, |
1367 | { | 1459 | { |
1368 | .vendor = PCI_VENDOR_ID_NI, | 1460 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1371,7 +1463,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1371 | .subdevice = PCI_ANY_ID, | 1463 | .subdevice = PCI_ANY_ID, |
1372 | .init = pci_ni8420_init, | 1464 | .init = pci_ni8420_init, |
1373 | .setup = pci_default_setup, | 1465 | .setup = pci_default_setup, |
1374 | .exit = __devexit_p(pci_ni8420_exit), | 1466 | .exit = pci_ni8420_exit, |
1375 | }, | 1467 | }, |
1376 | { | 1468 | { |
1377 | .vendor = PCI_VENDOR_ID_NI, | 1469 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1380,7 +1472,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1380 | .subdevice = PCI_ANY_ID, | 1472 | .subdevice = PCI_ANY_ID, |
1381 | .init = pci_ni8420_init, | 1473 | .init = pci_ni8420_init, |
1382 | .setup = pci_default_setup, | 1474 | .setup = pci_default_setup, |
1383 | .exit = __devexit_p(pci_ni8420_exit), | 1475 | .exit = pci_ni8420_exit, |
1384 | }, | 1476 | }, |
1385 | { | 1477 | { |
1386 | .vendor = PCI_VENDOR_ID_NI, | 1478 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1389,7 +1481,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1389 | .subdevice = PCI_ANY_ID, | 1481 | .subdevice = PCI_ANY_ID, |
1390 | .init = pci_ni8420_init, | 1482 | .init = pci_ni8420_init, |
1391 | .setup = pci_default_setup, | 1483 | .setup = pci_default_setup, |
1392 | .exit = __devexit_p(pci_ni8420_exit), | 1484 | .exit = pci_ni8420_exit, |
1393 | }, | 1485 | }, |
1394 | { | 1486 | { |
1395 | .vendor = PCI_VENDOR_ID_NI, | 1487 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1398,7 +1490,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1398 | .subdevice = PCI_ANY_ID, | 1490 | .subdevice = PCI_ANY_ID, |
1399 | .init = pci_ni8420_init, | 1491 | .init = pci_ni8420_init, |
1400 | .setup = pci_default_setup, | 1492 | .setup = pci_default_setup, |
1401 | .exit = __devexit_p(pci_ni8420_exit), | 1493 | .exit = pci_ni8420_exit, |
1402 | }, | 1494 | }, |
1403 | { | 1495 | { |
1404 | .vendor = PCI_VENDOR_ID_NI, | 1496 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1407,7 +1499,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1407 | .subdevice = PCI_ANY_ID, | 1499 | .subdevice = PCI_ANY_ID, |
1408 | .init = pci_ni8420_init, | 1500 | .init = pci_ni8420_init, |
1409 | .setup = pci_default_setup, | 1501 | .setup = pci_default_setup, |
1410 | .exit = __devexit_p(pci_ni8420_exit), | 1502 | .exit = pci_ni8420_exit, |
1411 | }, | 1503 | }, |
1412 | { | 1504 | { |
1413 | .vendor = PCI_VENDOR_ID_NI, | 1505 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1416,7 +1508,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1416 | .subdevice = PCI_ANY_ID, | 1508 | .subdevice = PCI_ANY_ID, |
1417 | .init = pci_ni8420_init, | 1509 | .init = pci_ni8420_init, |
1418 | .setup = pci_default_setup, | 1510 | .setup = pci_default_setup, |
1419 | .exit = __devexit_p(pci_ni8420_exit), | 1511 | .exit = pci_ni8420_exit, |
1420 | }, | 1512 | }, |
1421 | { | 1513 | { |
1422 | .vendor = PCI_VENDOR_ID_NI, | 1514 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1425,7 +1517,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1425 | .subdevice = PCI_ANY_ID, | 1517 | .subdevice = PCI_ANY_ID, |
1426 | .init = pci_ni8420_init, | 1518 | .init = pci_ni8420_init, |
1427 | .setup = pci_default_setup, | 1519 | .setup = pci_default_setup, |
1428 | .exit = __devexit_p(pci_ni8420_exit), | 1520 | .exit = pci_ni8420_exit, |
1429 | }, | 1521 | }, |
1430 | { | 1522 | { |
1431 | .vendor = PCI_VENDOR_ID_NI, | 1523 | .vendor = PCI_VENDOR_ID_NI, |
@@ -1434,7 +1526,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1434 | .subdevice = PCI_ANY_ID, | 1526 | .subdevice = PCI_ANY_ID, |
1435 | .init = pci_ni8430_init, | 1527 | .init = pci_ni8430_init, |
1436 | .setup = pci_ni8430_setup, | 1528 | .setup = pci_ni8430_setup, |
1437 | .exit = __devexit_p(pci_ni8430_exit), | 1529 | .exit = pci_ni8430_exit, |
1438 | }, | 1530 | }, |
1439 | /* | 1531 | /* |
1440 | * Panacom | 1532 | * Panacom |
@@ -1446,7 +1538,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1446 | .subdevice = PCI_ANY_ID, | 1538 | .subdevice = PCI_ANY_ID, |
1447 | .init = pci_plx9050_init, | 1539 | .init = pci_plx9050_init, |
1448 | .setup = pci_default_setup, | 1540 | .setup = pci_default_setup, |
1449 | .exit = __devexit_p(pci_plx9050_exit), | 1541 | .exit = pci_plx9050_exit, |
1450 | }, | 1542 | }, |
1451 | { | 1543 | { |
1452 | .vendor = PCI_VENDOR_ID_PANACOM, | 1544 | .vendor = PCI_VENDOR_ID_PANACOM, |
@@ -1455,7 +1547,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1455 | .subdevice = PCI_ANY_ID, | 1547 | .subdevice = PCI_ANY_ID, |
1456 | .init = pci_plx9050_init, | 1548 | .init = pci_plx9050_init, |
1457 | .setup = pci_default_setup, | 1549 | .setup = pci_default_setup, |
1458 | .exit = __devexit_p(pci_plx9050_exit), | 1550 | .exit = pci_plx9050_exit, |
1459 | }, | 1551 | }, |
1460 | /* | 1552 | /* |
1461 | * PLX | 1553 | * PLX |
@@ -1474,7 +1566,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1474 | .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055, | 1566 | .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055, |
1475 | .init = pci_plx9050_init, | 1567 | .init = pci_plx9050_init, |
1476 | .setup = pci_default_setup, | 1568 | .setup = pci_default_setup, |
1477 | .exit = __devexit_p(pci_plx9050_exit), | 1569 | .exit = pci_plx9050_exit, |
1478 | }, | 1570 | }, |
1479 | { | 1571 | { |
1480 | .vendor = PCI_VENDOR_ID_PLX, | 1572 | .vendor = PCI_VENDOR_ID_PLX, |
@@ -1483,7 +1575,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1483 | .subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2, | 1575 | .subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2, |
1484 | .init = pci_plx9050_init, | 1576 | .init = pci_plx9050_init, |
1485 | .setup = pci_default_setup, | 1577 | .setup = pci_default_setup, |
1486 | .exit = __devexit_p(pci_plx9050_exit), | 1578 | .exit = pci_plx9050_exit, |
1487 | }, | 1579 | }, |
1488 | { | 1580 | { |
1489 | .vendor = PCI_VENDOR_ID_PLX, | 1581 | .vendor = PCI_VENDOR_ID_PLX, |
@@ -1492,7 +1584,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1492 | .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584, | 1584 | .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584, |
1493 | .init = pci_plx9050_init, | 1585 | .init = pci_plx9050_init, |
1494 | .setup = pci_default_setup, | 1586 | .setup = pci_default_setup, |
1495 | .exit = __devexit_p(pci_plx9050_exit), | 1587 | .exit = pci_plx9050_exit, |
1496 | }, | 1588 | }, |
1497 | { | 1589 | { |
1498 | .vendor = PCI_VENDOR_ID_PLX, | 1590 | .vendor = PCI_VENDOR_ID_PLX, |
@@ -1501,7 +1593,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1501 | .subdevice = PCI_DEVICE_ID_PLX_ROMULUS, | 1593 | .subdevice = PCI_DEVICE_ID_PLX_ROMULUS, |
1502 | .init = pci_plx9050_init, | 1594 | .init = pci_plx9050_init, |
1503 | .setup = pci_default_setup, | 1595 | .setup = pci_default_setup, |
1504 | .exit = __devexit_p(pci_plx9050_exit), | 1596 | .exit = pci_plx9050_exit, |
1505 | }, | 1597 | }, |
1506 | /* | 1598 | /* |
1507 | * SBS Technologies, Inc., PMC-OCTALPRO 232 | 1599 | * SBS Technologies, Inc., PMC-OCTALPRO 232 |
@@ -1513,7 +1605,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1513 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO232, | 1605 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO232, |
1514 | .init = sbs_init, | 1606 | .init = sbs_init, |
1515 | .setup = sbs_setup, | 1607 | .setup = sbs_setup, |
1516 | .exit = __devexit_p(sbs_exit), | 1608 | .exit = sbs_exit, |
1517 | }, | 1609 | }, |
1518 | /* | 1610 | /* |
1519 | * SBS Technologies, Inc., PMC-OCTALPRO 422 | 1611 | * SBS Technologies, Inc., PMC-OCTALPRO 422 |
@@ -1525,7 +1617,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1525 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO422, | 1617 | .subdevice = PCI_SUBDEVICE_ID_OCTPRO422, |
1526 | .init = sbs_init, | 1618 | .init = sbs_init, |
1527 | .setup = sbs_setup, | 1619 | .setup = sbs_setup, |
1528 | .exit = __devexit_p(sbs_exit), | 1620 | .exit = sbs_exit, |
1529 | }, | 1621 | }, |
1530 | /* | 1622 | /* |
1531 | * SBS Technologies, Inc., P-Octal 232 | 1623 | * SBS Technologies, Inc., P-Octal 232 |
@@ -1537,7 +1629,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1537 | .subdevice = PCI_SUBDEVICE_ID_POCTAL232, | 1629 | .subdevice = PCI_SUBDEVICE_ID_POCTAL232, |
1538 | .init = sbs_init, | 1630 | .init = sbs_init, |
1539 | .setup = sbs_setup, | 1631 | .setup = sbs_setup, |
1540 | .exit = __devexit_p(sbs_exit), | 1632 | .exit = sbs_exit, |
1541 | }, | 1633 | }, |
1542 | /* | 1634 | /* |
1543 | * SBS Technologies, Inc., P-Octal 422 | 1635 | * SBS Technologies, Inc., P-Octal 422 |
@@ -1549,7 +1641,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1549 | .subdevice = PCI_SUBDEVICE_ID_POCTAL422, | 1641 | .subdevice = PCI_SUBDEVICE_ID_POCTAL422, |
1550 | .init = sbs_init, | 1642 | .init = sbs_init, |
1551 | .setup = sbs_setup, | 1643 | .setup = sbs_setup, |
1552 | .exit = __devexit_p(sbs_exit), | 1644 | .exit = sbs_exit, |
1553 | }, | 1645 | }, |
1554 | /* | 1646 | /* |
1555 | * SIIG cards - these may be called via parport_serial | 1647 | * SIIG cards - these may be called via parport_serial |
@@ -1622,6 +1714,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1622 | .subdevice = PCI_ANY_ID, | 1714 | .subdevice = PCI_ANY_ID, |
1623 | .setup = pci_xr17c154_setup, | 1715 | .setup = pci_xr17c154_setup, |
1624 | }, | 1716 | }, |
1717 | { | ||
1718 | .vendor = PCI_VENDOR_ID_EXAR, | ||
1719 | .device = PCI_DEVICE_ID_EXAR_XR17V352, | ||
1720 | .subvendor = PCI_ANY_ID, | ||
1721 | .subdevice = PCI_ANY_ID, | ||
1722 | .setup = pci_xr17v35x_setup, | ||
1723 | }, | ||
1724 | { | ||
1725 | .vendor = PCI_VENDOR_ID_EXAR, | ||
1726 | .device = PCI_DEVICE_ID_EXAR_XR17V354, | ||
1727 | .subvendor = PCI_ANY_ID, | ||
1728 | .subdevice = PCI_ANY_ID, | ||
1729 | .setup = pci_xr17v35x_setup, | ||
1730 | }, | ||
1731 | { | ||
1732 | .vendor = PCI_VENDOR_ID_EXAR, | ||
1733 | .device = PCI_DEVICE_ID_EXAR_XR17V358, | ||
1734 | .subvendor = PCI_ANY_ID, | ||
1735 | .subdevice = PCI_ANY_ID, | ||
1736 | .setup = pci_xr17v35x_setup, | ||
1737 | }, | ||
1625 | /* | 1738 | /* |
1626 | * Xircom cards | 1739 | * Xircom cards |
1627 | */ | 1740 | */ |
@@ -1788,6 +1901,59 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1788 | .setup = pci_asix_setup, | 1901 | .setup = pci_asix_setup, |
1789 | }, | 1902 | }, |
1790 | /* | 1903 | /* |
1904 | * Commtech, Inc. Fastcom adapters | ||
1905 | * | ||
1906 | */ | ||
1907 | { | ||
1908 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1909 | .device = PCI_DEVICE_ID_COMMTECH_4222PCI335, | ||
1910 | .subvendor = PCI_ANY_ID, | ||
1911 | .subdevice = PCI_ANY_ID, | ||
1912 | .setup = pci_fastcom335_setup, | ||
1913 | }, | ||
1914 | { | ||
1915 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1916 | .device = PCI_DEVICE_ID_COMMTECH_4224PCI335, | ||
1917 | .subvendor = PCI_ANY_ID, | ||
1918 | .subdevice = PCI_ANY_ID, | ||
1919 | .setup = pci_fastcom335_setup, | ||
1920 | }, | ||
1921 | { | ||
1922 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1923 | .device = PCI_DEVICE_ID_COMMTECH_2324PCI335, | ||
1924 | .subvendor = PCI_ANY_ID, | ||
1925 | .subdevice = PCI_ANY_ID, | ||
1926 | .setup = pci_fastcom335_setup, | ||
1927 | }, | ||
1928 | { | ||
1929 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1930 | .device = PCI_DEVICE_ID_COMMTECH_2328PCI335, | ||
1931 | .subvendor = PCI_ANY_ID, | ||
1932 | .subdevice = PCI_ANY_ID, | ||
1933 | .setup = pci_fastcom335_setup, | ||
1934 | }, | ||
1935 | { | ||
1936 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1937 | .device = PCI_DEVICE_ID_COMMTECH_4222PCIE, | ||
1938 | .subvendor = PCI_ANY_ID, | ||
1939 | .subdevice = PCI_ANY_ID, | ||
1940 | .setup = pci_xr17v35x_setup, | ||
1941 | }, | ||
1942 | { | ||
1943 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1944 | .device = PCI_DEVICE_ID_COMMTECH_4224PCIE, | ||
1945 | .subvendor = PCI_ANY_ID, | ||
1946 | .subdevice = PCI_ANY_ID, | ||
1947 | .setup = pci_xr17v35x_setup, | ||
1948 | }, | ||
1949 | { | ||
1950 | .vendor = PCI_VENDOR_ID_COMMTECH, | ||
1951 | .device = PCI_DEVICE_ID_COMMTECH_4228PCIE, | ||
1952 | .subvendor = PCI_ANY_ID, | ||
1953 | .subdevice = PCI_ANY_ID, | ||
1954 | .setup = pci_xr17v35x_setup, | ||
1955 | }, | ||
1956 | /* | ||
1791 | * Default "match everything" terminator entry | 1957 | * Default "match everything" terminator entry |
1792 | */ | 1958 | */ |
1793 | { | 1959 | { |
@@ -1863,6 +2029,10 @@ enum pci_board_num_t { | |||
1863 | 2029 | ||
1864 | pbn_b0_4_1152000, | 2030 | pbn_b0_4_1152000, |
1865 | 2031 | ||
2032 | pbn_b0_2_1152000_200, | ||
2033 | pbn_b0_4_1152000_200, | ||
2034 | pbn_b0_8_1152000_200, | ||
2035 | |||
1866 | pbn_b0_2_1843200, | 2036 | pbn_b0_2_1843200, |
1867 | pbn_b0_4_1843200, | 2037 | pbn_b0_4_1843200, |
1868 | 2038 | ||
@@ -1962,6 +2132,9 @@ enum pci_board_num_t { | |||
1962 | pbn_exar_XR17C152, | 2132 | pbn_exar_XR17C152, |
1963 | pbn_exar_XR17C154, | 2133 | pbn_exar_XR17C154, |
1964 | pbn_exar_XR17C158, | 2134 | pbn_exar_XR17C158, |
2135 | pbn_exar_XR17V352, | ||
2136 | pbn_exar_XR17V354, | ||
2137 | pbn_exar_XR17V358, | ||
1965 | pbn_exar_ibm_saturn, | 2138 | pbn_exar_ibm_saturn, |
1966 | pbn_pasemi_1682M, | 2139 | pbn_pasemi_1682M, |
1967 | pbn_ni8430_2, | 2140 | pbn_ni8430_2, |
@@ -1987,7 +2160,7 @@ enum pci_board_num_t { | |||
1987 | * see first lines of serial_in() and serial_out() in 8250.c | 2160 | * see first lines of serial_in() and serial_out() in 8250.c |
1988 | */ | 2161 | */ |
1989 | 2162 | ||
1990 | static struct pciserial_board pci_boards[] __devinitdata = { | 2163 | static struct pciserial_board pci_boards[] = { |
1991 | [pbn_default] = { | 2164 | [pbn_default] = { |
1992 | .flags = FL_BASE0, | 2165 | .flags = FL_BASE0, |
1993 | .num_ports = 1, | 2166 | .num_ports = 1, |
@@ -2057,6 +2230,27 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2057 | .uart_offset = 8, | 2230 | .uart_offset = 8, |
2058 | }, | 2231 | }, |
2059 | 2232 | ||
2233 | [pbn_b0_2_1152000_200] = { | ||
2234 | .flags = FL_BASE0, | ||
2235 | .num_ports = 2, | ||
2236 | .base_baud = 1152000, | ||
2237 | .uart_offset = 0x200, | ||
2238 | }, | ||
2239 | |||
2240 | [pbn_b0_4_1152000_200] = { | ||
2241 | .flags = FL_BASE0, | ||
2242 | .num_ports = 4, | ||
2243 | .base_baud = 1152000, | ||
2244 | .uart_offset = 0x200, | ||
2245 | }, | ||
2246 | |||
2247 | [pbn_b0_8_1152000_200] = { | ||
2248 | .flags = FL_BASE0, | ||
2249 | .num_ports = 2, | ||
2250 | .base_baud = 1152000, | ||
2251 | .uart_offset = 0x200, | ||
2252 | }, | ||
2253 | |||
2060 | [pbn_b0_2_1843200] = { | 2254 | [pbn_b0_2_1843200] = { |
2061 | .flags = FL_BASE0, | 2255 | .flags = FL_BASE0, |
2062 | .num_ports = 2, | 2256 | .num_ports = 2, |
@@ -2580,6 +2774,30 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2580 | .base_baud = 921600, | 2774 | .base_baud = 921600, |
2581 | .uart_offset = 0x200, | 2775 | .uart_offset = 0x200, |
2582 | }, | 2776 | }, |
2777 | [pbn_exar_XR17V352] = { | ||
2778 | .flags = FL_BASE0, | ||
2779 | .num_ports = 2, | ||
2780 | .base_baud = 7812500, | ||
2781 | .uart_offset = 0x400, | ||
2782 | .reg_shift = 0, | ||
2783 | .first_offset = 0, | ||
2784 | }, | ||
2785 | [pbn_exar_XR17V354] = { | ||
2786 | .flags = FL_BASE0, | ||
2787 | .num_ports = 4, | ||
2788 | .base_baud = 7812500, | ||
2789 | .uart_offset = 0x400, | ||
2790 | .reg_shift = 0, | ||
2791 | .first_offset = 0, | ||
2792 | }, | ||
2793 | [pbn_exar_XR17V358] = { | ||
2794 | .flags = FL_BASE0, | ||
2795 | .num_ports = 8, | ||
2796 | .base_baud = 7812500, | ||
2797 | .uart_offset = 0x400, | ||
2798 | .reg_shift = 0, | ||
2799 | .first_offset = 0, | ||
2800 | }, | ||
2583 | [pbn_exar_ibm_saturn] = { | 2801 | [pbn_exar_ibm_saturn] = { |
2584 | .flags = FL_BASE0, | 2802 | .flags = FL_BASE0, |
2585 | .num_ports = 1, | 2803 | .num_ports = 1, |
@@ -2658,8 +2876,8 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2658 | .first_offset = 0x1000, | 2876 | .first_offset = 0x1000, |
2659 | }, | 2877 | }, |
2660 | [pbn_ce4100_1_115200] = { | 2878 | [pbn_ce4100_1_115200] = { |
2661 | .flags = FL_BASE0, | 2879 | .flags = FL_BASE_BARS, |
2662 | .num_ports = 1, | 2880 | .num_ports = 2, |
2663 | .base_baud = 921600, | 2881 | .base_baud = 921600, |
2664 | .reg_shift = 2, | 2882 | .reg_shift = 2, |
2665 | }, | 2883 | }, |
@@ -2691,7 +2909,7 @@ static const struct pci_device_id blacklist[] = { | |||
2691 | * guess what the configuration might be, based on the pitiful PCI | 2909 | * guess what the configuration might be, based on the pitiful PCI |
2692 | * serial specs. Returns 0 on success, 1 on failure. | 2910 | * serial specs. Returns 0 on success, 1 on failure. |
2693 | */ | 2911 | */ |
2694 | static int __devinit | 2912 | static int |
2695 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | 2913 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) |
2696 | { | 2914 | { |
2697 | const struct pci_device_id *bldev; | 2915 | const struct pci_device_id *bldev; |
@@ -2917,7 +3135,7 @@ EXPORT_SYMBOL_GPL(pciserial_resume_ports); | |||
2917 | * Probe one serial board. Unfortunately, there is no rhyme nor reason | 3135 | * Probe one serial board. Unfortunately, there is no rhyme nor reason |
2918 | * to the arrangement of serial ports on a PCI card. | 3136 | * to the arrangement of serial ports on a PCI card. |
2919 | */ | 3137 | */ |
2920 | static int __devinit | 3138 | static int |
2921 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | 3139 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) |
2922 | { | 3140 | { |
2923 | struct pci_serial_quirk *quirk; | 3141 | struct pci_serial_quirk *quirk; |
@@ -2988,7 +3206,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2988 | return rc; | 3206 | return rc; |
2989 | } | 3207 | } |
2990 | 3208 | ||
2991 | static void __devexit pciserial_remove_one(struct pci_dev *dev) | 3209 | static void pciserial_remove_one(struct pci_dev *dev) |
2992 | { | 3210 | { |
2993 | struct serial_private *priv = pci_get_drvdata(dev); | 3211 | struct serial_private *priv = pci_get_drvdata(dev); |
2994 | 3212 | ||
@@ -3826,6 +4044,21 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3826 | PCI_ANY_ID, PCI_ANY_ID, | 4044 | PCI_ANY_ID, PCI_ANY_ID, |
3827 | 0, | 4045 | 0, |
3828 | 0, pbn_exar_XR17C158 }, | 4046 | 0, pbn_exar_XR17C158 }, |
4047 | /* | ||
4048 | * Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs | ||
4049 | */ | ||
4050 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352, | ||
4051 | PCI_ANY_ID, PCI_ANY_ID, | ||
4052 | 0, | ||
4053 | 0, pbn_exar_XR17V352 }, | ||
4054 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354, | ||
4055 | PCI_ANY_ID, PCI_ANY_ID, | ||
4056 | 0, | ||
4057 | 0, pbn_exar_XR17V354 }, | ||
4058 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358, | ||
4059 | PCI_ANY_ID, PCI_ANY_ID, | ||
4060 | 0, | ||
4061 | 0, pbn_exar_XR17V358 }, | ||
3829 | 4062 | ||
3830 | /* | 4063 | /* |
3831 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) | 4064 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) |
@@ -4257,6 +4490,38 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
4257 | 0, 0, pbn_b0_bt_2_115200 }, | 4490 | 0, 0, pbn_b0_bt_2_115200 }, |
4258 | 4491 | ||
4259 | /* | 4492 | /* |
4493 | * Commtech, Inc. Fastcom adapters | ||
4494 | */ | ||
4495 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335, | ||
4496 | PCI_ANY_ID, PCI_ANY_ID, | ||
4497 | 0, | ||
4498 | 0, pbn_b0_2_1152000_200 }, | ||
4499 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335, | ||
4500 | PCI_ANY_ID, PCI_ANY_ID, | ||
4501 | 0, | ||
4502 | 0, pbn_b0_4_1152000_200 }, | ||
4503 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335, | ||
4504 | PCI_ANY_ID, PCI_ANY_ID, | ||
4505 | 0, | ||
4506 | 0, pbn_b0_4_1152000_200 }, | ||
4507 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335, | ||
4508 | PCI_ANY_ID, PCI_ANY_ID, | ||
4509 | 0, | ||
4510 | 0, pbn_b0_8_1152000_200 }, | ||
4511 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE, | ||
4512 | PCI_ANY_ID, PCI_ANY_ID, | ||
4513 | 0, | ||
4514 | 0, pbn_exar_XR17V352 }, | ||
4515 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE, | ||
4516 | PCI_ANY_ID, PCI_ANY_ID, | ||
4517 | 0, | ||
4518 | 0, pbn_exar_XR17V354 }, | ||
4519 | { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE, | ||
4520 | PCI_ANY_ID, PCI_ANY_ID, | ||
4521 | 0, | ||
4522 | 0, pbn_exar_XR17V358 }, | ||
4523 | |||
4524 | /* | ||
4260 | * These entries match devices with class COMMUNICATION_SERIAL, | 4525 | * These entries match devices with class COMMUNICATION_SERIAL, |
4261 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 4526 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
4262 | */ | 4527 | */ |
@@ -4323,7 +4588,7 @@ static const struct pci_error_handlers serial8250_err_handler = { | |||
4323 | static struct pci_driver serial_pci_driver = { | 4588 | static struct pci_driver serial_pci_driver = { |
4324 | .name = "serial", | 4589 | .name = "serial", |
4325 | .probe = pciserial_init_one, | 4590 | .probe = pciserial_init_one, |
4326 | .remove = __devexit_p(pciserial_remove_one), | 4591 | .remove = pciserial_remove_one, |
4327 | #ifdef CONFIG_PM | 4592 | #ifdef CONFIG_PM |
4328 | .suspend = pciserial_suspend_one, | 4593 | .suspend = pciserial_suspend_one, |
4329 | .resume = pciserial_resume_one, | 4594 | .resume = pciserial_resume_one, |
@@ -4332,18 +4597,7 @@ static struct pci_driver serial_pci_driver = { | |||
4332 | .err_handler = &serial8250_err_handler, | 4597 | .err_handler = &serial8250_err_handler, |
4333 | }; | 4598 | }; |
4334 | 4599 | ||
4335 | static int __init serial8250_pci_init(void) | 4600 | module_pci_driver(serial_pci_driver); |
4336 | { | ||
4337 | return pci_register_driver(&serial_pci_driver); | ||
4338 | } | ||
4339 | |||
4340 | static void __exit serial8250_pci_exit(void) | ||
4341 | { | ||
4342 | pci_unregister_driver(&serial_pci_driver); | ||
4343 | } | ||
4344 | |||
4345 | module_init(serial8250_pci_init); | ||
4346 | module_exit(serial8250_pci_exit); | ||
4347 | 4601 | ||
4348 | MODULE_LICENSE("GPL"); | 4602 | MODULE_LICENSE("GPL"); |
4349 | MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); | 4603 | MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); |
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index f8ee25001dd0..35d9ab95c5cb 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c | |||
@@ -370,14 +370,14 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
370 | 370 | ||
371 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); | 371 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); |
372 | 372 | ||
373 | static char *modem_names[] __devinitdata = { | 373 | static char *modem_names[] = { |
374 | "MODEM", "Modem", "modem", "FAX", "Fax", "fax", | 374 | "MODEM", "Modem", "modem", "FAX", "Fax", "fax", |
375 | "56K", "56k", "K56", "33.6", "28.8", "14.4", | 375 | "56K", "56k", "K56", "33.6", "28.8", "14.4", |
376 | "33,600", "28,800", "14,400", "33.600", "28.800", "14.400", | 376 | "33,600", "28,800", "14,400", "33.600", "28.800", "14.400", |
377 | "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL | 377 | "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL |
378 | }; | 378 | }; |
379 | 379 | ||
380 | static int __devinit check_name(char *name) | 380 | static int check_name(char *name) |
381 | { | 381 | { |
382 | char **tmp; | 382 | char **tmp; |
383 | 383 | ||
@@ -388,7 +388,7 @@ static int __devinit check_name(char *name) | |||
388 | return 0; | 388 | return 0; |
389 | } | 389 | } |
390 | 390 | ||
391 | static int __devinit check_resources(struct pnp_dev *dev) | 391 | static int check_resources(struct pnp_dev *dev) |
392 | { | 392 | { |
393 | resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8}; | 393 | resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8}; |
394 | int i; | 394 | int i; |
@@ -412,7 +412,7 @@ static int __devinit check_resources(struct pnp_dev *dev) | |||
412 | * PnP modems, alternatively we must hardcode all modems in pnp_devices[] | 412 | * PnP modems, alternatively we must hardcode all modems in pnp_devices[] |
413 | * table. | 413 | * table. |
414 | */ | 414 | */ |
415 | static int __devinit serial_pnp_guess_board(struct pnp_dev *dev) | 415 | static int serial_pnp_guess_board(struct pnp_dev *dev) |
416 | { | 416 | { |
417 | if (!(check_name(pnp_dev_name(dev)) || | 417 | if (!(check_name(pnp_dev_name(dev)) || |
418 | (dev->card && check_name(dev->card->name)))) | 418 | (dev->card && check_name(dev->card->name)))) |
@@ -424,7 +424,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev) | |||
424 | return -ENODEV; | 424 | return -ENODEV; |
425 | } | 425 | } |
426 | 426 | ||
427 | static int __devinit | 427 | static int |
428 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | 428 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) |
429 | { | 429 | { |
430 | struct uart_8250_port uart; | 430 | struct uart_8250_port uart; |
@@ -476,7 +476,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
476 | return 0; | 476 | return 0; |
477 | } | 477 | } |
478 | 478 | ||
479 | static void __devexit serial_pnp_remove(struct pnp_dev *dev) | 479 | static void serial_pnp_remove(struct pnp_dev *dev) |
480 | { | 480 | { |
481 | long line = (long)pnp_get_drvdata(dev); | 481 | long line = (long)pnp_get_drvdata(dev); |
482 | if (line) | 482 | if (line) |
@@ -511,7 +511,7 @@ static int serial_pnp_resume(struct pnp_dev *dev) | |||
511 | static struct pnp_driver serial_pnp_driver = { | 511 | static struct pnp_driver serial_pnp_driver = { |
512 | .name = "serial", | 512 | .name = "serial", |
513 | .probe = serial_pnp_probe, | 513 | .probe = serial_pnp_probe, |
514 | .remove = __devexit_p(serial_pnp_remove), | 514 | .remove = serial_pnp_remove, |
515 | .suspend = serial_pnp_suspend, | 515 | .suspend = serial_pnp_suspend, |
516 | .resume = serial_pnp_resume, | 516 | .resume = serial_pnp_resume, |
517 | .id_table = pnp_dev_table, | 517 | .id_table = pnp_dev_table, |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2a53be5f010d..59c23d038106 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -93,7 +93,7 @@ config SERIAL_SB1250_DUART_CONSOLE | |||
93 | 93 | ||
94 | config SERIAL_ATMEL | 94 | config SERIAL_ATMEL |
95 | bool "AT91 / AT32 on-chip serial port support" | 95 | bool "AT91 / AT32 on-chip serial port support" |
96 | depends on (ARM && ARCH_AT91) || AVR32 | 96 | depends on ARCH_AT91 || AVR32 |
97 | select SERIAL_CORE | 97 | select SERIAL_CORE |
98 | help | 98 | help |
99 | This enables the driver for the on-chip UARTs of the Atmel | 99 | This enables the driver for the on-chip UARTs of the Atmel |
@@ -198,7 +198,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
198 | 198 | ||
199 | config SERIAL_SAMSUNG | 199 | config SERIAL_SAMSUNG |
200 | tristate "Samsung SoC serial support" | 200 | tristate "Samsung SoC serial support" |
201 | depends on ARM && PLAT_SAMSUNG | 201 | depends on PLAT_SAMSUNG |
202 | select SERIAL_CORE | 202 | select SERIAL_CORE |
203 | help | 203 | help |
204 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, | 204 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, |
@@ -208,14 +208,14 @@ config SERIAL_SAMSUNG | |||
208 | 208 | ||
209 | config SERIAL_SAMSUNG_UARTS_4 | 209 | config SERIAL_SAMSUNG_UARTS_4 |
210 | bool | 210 | bool |
211 | depends on ARM && PLAT_SAMSUNG | 211 | depends on PLAT_SAMSUNG |
212 | default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) | 212 | default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) |
213 | help | 213 | help |
214 | Internal node for the common case of 4 Samsung compatible UARTs | 214 | Internal node for the common case of 4 Samsung compatible UARTs |
215 | 215 | ||
216 | config SERIAL_SAMSUNG_UARTS | 216 | config SERIAL_SAMSUNG_UARTS |
217 | int | 217 | int |
218 | depends on ARM && PLAT_SAMSUNG | 218 | depends on PLAT_SAMSUNG |
219 | default 6 if ARCH_S5P6450 | 219 | default 6 if ARCH_S5P6450 |
220 | default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 | 220 | default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 |
221 | default 3 | 221 | default 3 |
@@ -249,7 +249,7 @@ config SERIAL_SAMSUNG_CONSOLE | |||
249 | 249 | ||
250 | config SERIAL_SIRFSOC | 250 | config SERIAL_SIRFSOC |
251 | tristate "SiRF SoC Platform Serial port support" | 251 | tristate "SiRF SoC Platform Serial port support" |
252 | depends on ARM && ARCH_PRIMA2 | 252 | depends on ARCH_PRIMA2 |
253 | select SERIAL_CORE | 253 | select SERIAL_CORE |
254 | help | 254 | help |
255 | Support for the on-chip UART on the CSR SiRFprimaII series, | 255 | Support for the on-chip UART on the CSR SiRFprimaII series, |
@@ -347,7 +347,7 @@ config SERIAL_ZS_CONSOLE | |||
347 | 347 | ||
348 | config SERIAL_21285 | 348 | config SERIAL_21285 |
349 | tristate "DC21285 serial port support" | 349 | tristate "DC21285 serial port support" |
350 | depends on ARM && FOOTBRIDGE | 350 | depends on FOOTBRIDGE |
351 | select SERIAL_CORE | 351 | select SERIAL_CORE |
352 | help | 352 | help |
353 | If you have a machine based on a 21285 (Footbridge) StrongARM(R)/ | 353 | If you have a machine based on a 21285 (Footbridge) StrongARM(R)/ |
@@ -371,7 +371,7 @@ config SERIAL_21285_CONSOLE | |||
371 | 371 | ||
372 | config SERIAL_MPSC | 372 | config SERIAL_MPSC |
373 | bool "Marvell MPSC serial port support" | 373 | bool "Marvell MPSC serial port support" |
374 | depends on PPC32 && MV64X60 | 374 | depends on MV64X60 |
375 | select SERIAL_CORE | 375 | select SERIAL_CORE |
376 | help | 376 | help |
377 | Say Y here if you want to use the Marvell MPSC serial controller. | 377 | Say Y here if you want to use the Marvell MPSC serial controller. |
@@ -408,7 +408,7 @@ config SERIAL_PXA_CONSOLE | |||
408 | 408 | ||
409 | config SERIAL_SA1100 | 409 | config SERIAL_SA1100 |
410 | bool "SA1100 serial port support" | 410 | bool "SA1100 serial port support" |
411 | depends on ARM && ARCH_SA1100 | 411 | depends on ARCH_SA1100 |
412 | select SERIAL_CORE | 412 | select SERIAL_CORE |
413 | help | 413 | help |
414 | If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you | 414 | If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you |
@@ -716,7 +716,7 @@ config SERIAL_SH_SCI_DMA | |||
716 | 716 | ||
717 | config SERIAL_PNX8XXX | 717 | config SERIAL_PNX8XXX |
718 | bool "Enable PNX8XXX SoCs' UART Support" | 718 | bool "Enable PNX8XXX SoCs' UART Support" |
719 | depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) | 719 | depends on SOC_PNX8550 || SOC_PNX833X |
720 | select SERIAL_CORE | 720 | select SERIAL_CORE |
721 | help | 721 | help |
722 | If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 | 722 | If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 |
@@ -1013,7 +1013,7 @@ config SERIAL_SGI_IOC3 | |||
1013 | 1013 | ||
1014 | config SERIAL_MSM | 1014 | config SERIAL_MSM |
1015 | bool "MSM on-chip serial port support" | 1015 | bool "MSM on-chip serial port support" |
1016 | depends on ARM && ARCH_MSM | 1016 | depends on ARCH_MSM |
1017 | select SERIAL_CORE | 1017 | select SERIAL_CORE |
1018 | 1018 | ||
1019 | config SERIAL_MSM_CONSOLE | 1019 | config SERIAL_MSM_CONSOLE |
@@ -1035,7 +1035,7 @@ config SERIAL_MSM_HS | |||
1035 | 1035 | ||
1036 | config SERIAL_VT8500 | 1036 | config SERIAL_VT8500 |
1037 | bool "VIA VT8500 on-chip serial port support" | 1037 | bool "VIA VT8500 on-chip serial port support" |
1038 | depends on ARM && ARCH_VT8500 | 1038 | depends on ARCH_VT8500 |
1039 | select SERIAL_CORE | 1039 | select SERIAL_CORE |
1040 | 1040 | ||
1041 | config SERIAL_VT8500_CONSOLE | 1041 | config SERIAL_VT8500_CONSOLE |
@@ -1045,7 +1045,7 @@ config SERIAL_VT8500_CONSOLE | |||
1045 | 1045 | ||
1046 | config SERIAL_NETX | 1046 | config SERIAL_NETX |
1047 | tristate "NetX serial port support" | 1047 | tristate "NetX serial port support" |
1048 | depends on ARM && ARCH_NETX | 1048 | depends on ARCH_NETX |
1049 | select SERIAL_CORE | 1049 | select SERIAL_CORE |
1050 | help | 1050 | help |
1051 | If you have a machine based on a Hilscher NetX SoC you | 1051 | If you have a machine based on a Hilscher NetX SoC you |
@@ -1376,6 +1376,7 @@ config SERIAL_MXS_AUART_CONSOLE | |||
1376 | 1376 | ||
1377 | config SERIAL_XILINX_PS_UART | 1377 | config SERIAL_XILINX_PS_UART |
1378 | tristate "Xilinx PS UART support" | 1378 | tristate "Xilinx PS UART support" |
1379 | depends on OF | ||
1379 | select SERIAL_CORE | 1380 | select SERIAL_CORE |
1380 | help | 1381 | help |
1381 | This driver supports the Xilinx PS UART port. | 1382 | This driver supports the Xilinx PS UART port. |
@@ -1423,4 +1424,27 @@ config SERIAL_EFM32_UART_CONSOLE | |||
1423 | depends on SERIAL_EFM32_UART=y | 1424 | depends on SERIAL_EFM32_UART=y |
1424 | select SERIAL_CORE_CONSOLE | 1425 | select SERIAL_CORE_CONSOLE |
1425 | 1426 | ||
1427 | config SERIAL_ARC | ||
1428 | tristate "ARC UART driver support" | ||
1429 | select SERIAL_CORE | ||
1430 | help | ||
1431 | Driver for on-chip UART for ARC(Synopsys) for the legacy | ||
1432 | FPGA Boards (ML50x/ARCAngel4) | ||
1433 | |||
1434 | config SERIAL_ARC_CONSOLE | ||
1435 | bool "Console on ARC UART" | ||
1436 | depends on SERIAL_ARC=y | ||
1437 | select SERIAL_CORE_CONSOLE | ||
1438 | help | ||
1439 | Enable system Console on ARC UART | ||
1440 | |||
1441 | config SERIAL_ARC_NR_PORTS | ||
1442 | int "Number of ARC UART ports" | ||
1443 | depends on SERIAL_ARC | ||
1444 | range 1 3 | ||
1445 | default "1" | ||
1446 | help | ||
1447 | Set this to the number of serial ports you want the driver | ||
1448 | to support. | ||
1449 | |||
1426 | endmenu | 1450 | endmenu |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 4f694dafa719..df1b998c436b 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -82,3 +82,4 @@ obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | |||
82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o | 82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o |
83 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o | 83 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o |
84 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o | 84 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o |
85 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o | ||
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 530181e49f6b..872f14ae43d2 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -406,7 +406,7 @@ static struct uart_driver altera_jtaguart_driver = { | |||
406 | .cons = ALTERA_JTAGUART_CONSOLE, | 406 | .cons = ALTERA_JTAGUART_CONSOLE, |
407 | }; | 407 | }; |
408 | 408 | ||
409 | static int __devinit altera_jtaguart_probe(struct platform_device *pdev) | 409 | static int altera_jtaguart_probe(struct platform_device *pdev) |
410 | { | 410 | { |
411 | struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data; | 411 | struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data; |
412 | struct uart_port *port; | 412 | struct uart_port *port; |
@@ -453,7 +453,7 @@ static int __devinit altera_jtaguart_probe(struct platform_device *pdev) | |||
453 | return 0; | 453 | return 0; |
454 | } | 454 | } |
455 | 455 | ||
456 | static int __devexit altera_jtaguart_remove(struct platform_device *pdev) | 456 | static int altera_jtaguart_remove(struct platform_device *pdev) |
457 | { | 457 | { |
458 | struct uart_port *port; | 458 | struct uart_port *port; |
459 | int i = pdev->id; | 459 | int i = pdev->id; |
@@ -477,7 +477,7 @@ MODULE_DEVICE_TABLE(of, altera_jtaguart_match); | |||
477 | 477 | ||
478 | static struct platform_driver altera_jtaguart_platform_driver = { | 478 | static struct platform_driver altera_jtaguart_platform_driver = { |
479 | .probe = altera_jtaguart_probe, | 479 | .probe = altera_jtaguart_probe, |
480 | .remove = __devexit_p(altera_jtaguart_remove), | 480 | .remove = altera_jtaguart_remove, |
481 | .driver = { | 481 | .driver = { |
482 | .name = DRV_NAME, | 482 | .name = DRV_NAME, |
483 | .owner = THIS_MODULE, | 483 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 15d80b9fb303..684a0808e1c7 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -532,7 +532,7 @@ static int altera_uart_get_of_uartclk(struct platform_device *pdev, | |||
532 | } | 532 | } |
533 | #endif /* CONFIG_OF */ | 533 | #endif /* CONFIG_OF */ |
534 | 534 | ||
535 | static int __devinit altera_uart_probe(struct platform_device *pdev) | 535 | static int altera_uart_probe(struct platform_device *pdev) |
536 | { | 536 | { |
537 | struct altera_uart_platform_uart *platp = pdev->dev.platform_data; | 537 | struct altera_uart_platform_uart *platp = pdev->dev.platform_data; |
538 | struct uart_port *port; | 538 | struct uart_port *port; |
@@ -598,7 +598,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
598 | return 0; | 598 | return 0; |
599 | } | 599 | } |
600 | 600 | ||
601 | static int __devexit altera_uart_remove(struct platform_device *pdev) | 601 | static int altera_uart_remove(struct platform_device *pdev) |
602 | { | 602 | { |
603 | struct uart_port *port = platform_get_drvdata(pdev); | 603 | struct uart_port *port = platform_get_drvdata(pdev); |
604 | 604 | ||
@@ -621,7 +621,7 @@ MODULE_DEVICE_TABLE(of, altera_uart_match); | |||
621 | 621 | ||
622 | static struct platform_driver altera_uart_platform_driver = { | 622 | static struct platform_driver altera_uart_platform_driver = { |
623 | .probe = altera_uart_probe, | 623 | .probe = altera_uart_probe, |
624 | .remove = __devexit_p(altera_uart_remove), | 624 | .remove = altera_uart_remove, |
625 | .driver = { | 625 | .driver = { |
626 | .name = DRV_NAME, | 626 | .name = DRV_NAME, |
627 | .owner = THIS_MODULE, | 627 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d7e1edec50b5..7fca4022a8b2 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -56,8 +56,7 @@ | |||
56 | #include <linux/of_device.h> | 56 | #include <linux/of_device.h> |
57 | #include <linux/pinctrl/consumer.h> | 57 | #include <linux/pinctrl/consumer.h> |
58 | #include <linux/sizes.h> | 58 | #include <linux/sizes.h> |
59 | 59 | #include <linux/io.h> | |
60 | #include <asm/io.h> | ||
61 | 60 | ||
62 | #define UART_NR 14 | 61 | #define UART_NR 14 |
63 | 62 | ||
@@ -1973,7 +1972,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
1973 | goto out; | 1972 | goto out; |
1974 | } | 1973 | } |
1975 | 1974 | ||
1976 | uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); | 1975 | uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port), |
1976 | GFP_KERNEL); | ||
1977 | if (uap == NULL) { | 1977 | if (uap == NULL) { |
1978 | ret = -ENOMEM; | 1978 | ret = -ENOMEM; |
1979 | goto out; | 1979 | goto out; |
@@ -1981,16 +1981,17 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
1981 | 1981 | ||
1982 | i = pl011_probe_dt_alias(i, &dev->dev); | 1982 | i = pl011_probe_dt_alias(i, &dev->dev); |
1983 | 1983 | ||
1984 | base = ioremap(dev->res.start, resource_size(&dev->res)); | 1984 | base = devm_ioremap(&dev->dev, dev->res.start, |
1985 | resource_size(&dev->res)); | ||
1985 | if (!base) { | 1986 | if (!base) { |
1986 | ret = -ENOMEM; | 1987 | ret = -ENOMEM; |
1987 | goto free; | 1988 | goto out; |
1988 | } | 1989 | } |
1989 | 1990 | ||
1990 | uap->pinctrl = devm_pinctrl_get(&dev->dev); | 1991 | uap->pinctrl = devm_pinctrl_get(&dev->dev); |
1991 | if (IS_ERR(uap->pinctrl)) { | 1992 | if (IS_ERR(uap->pinctrl)) { |
1992 | ret = PTR_ERR(uap->pinctrl); | 1993 | ret = PTR_ERR(uap->pinctrl); |
1993 | goto unmap; | 1994 | goto out; |
1994 | } | 1995 | } |
1995 | uap->pins_default = pinctrl_lookup_state(uap->pinctrl, | 1996 | uap->pins_default = pinctrl_lookup_state(uap->pinctrl, |
1996 | PINCTRL_STATE_DEFAULT); | 1997 | PINCTRL_STATE_DEFAULT); |
@@ -2002,10 +2003,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
2002 | if (IS_ERR(uap->pins_sleep)) | 2003 | if (IS_ERR(uap->pins_sleep)) |
2003 | dev_dbg(&dev->dev, "could not get sleep pinstate\n"); | 2004 | dev_dbg(&dev->dev, "could not get sleep pinstate\n"); |
2004 | 2005 | ||
2005 | uap->clk = clk_get(&dev->dev, NULL); | 2006 | uap->clk = devm_clk_get(&dev->dev, NULL); |
2006 | if (IS_ERR(uap->clk)) { | 2007 | if (IS_ERR(uap->clk)) { |
2007 | ret = PTR_ERR(uap->clk); | 2008 | ret = PTR_ERR(uap->clk); |
2008 | goto unmap; | 2009 | goto out; |
2009 | } | 2010 | } |
2010 | 2011 | ||
2011 | uap->vendor = vendor; | 2012 | uap->vendor = vendor; |
@@ -2038,11 +2039,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
2038 | amba_set_drvdata(dev, NULL); | 2039 | amba_set_drvdata(dev, NULL); |
2039 | amba_ports[i] = NULL; | 2040 | amba_ports[i] = NULL; |
2040 | pl011_dma_remove(uap); | 2041 | pl011_dma_remove(uap); |
2041 | clk_put(uap->clk); | ||
2042 | unmap: | ||
2043 | iounmap(base); | ||
2044 | free: | ||
2045 | kfree(uap); | ||
2046 | } | 2042 | } |
2047 | out: | 2043 | out: |
2048 | return ret; | 2044 | return ret; |
@@ -2062,9 +2058,6 @@ static int pl011_remove(struct amba_device *dev) | |||
2062 | amba_ports[i] = NULL; | 2058 | amba_ports[i] = NULL; |
2063 | 2059 | ||
2064 | pl011_dma_remove(uap); | 2060 | pl011_dma_remove(uap); |
2065 | iounmap(uap->port.membase); | ||
2066 | clk_put(uap->clk); | ||
2067 | kfree(uap); | ||
2068 | return 0; | 2061 | return 0; |
2069 | } | 2062 | } |
2070 | 2063 | ||
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 7162f70d9260..59ae2b53e765 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c | |||
@@ -554,7 +554,7 @@ static struct uart_driver grlib_apbuart_driver = { | |||
554 | /* OF Platform Driver */ | 554 | /* OF Platform Driver */ |
555 | /* ======================================================================== */ | 555 | /* ======================================================================== */ |
556 | 556 | ||
557 | static int __devinit apbuart_probe(struct platform_device *op) | 557 | static int apbuart_probe(struct platform_device *op) |
558 | { | 558 | { |
559 | int i; | 559 | int i; |
560 | struct uart_port *port = NULL; | 560 | struct uart_port *port = NULL; |
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index e4f60e2b87f3..505c490c0b44 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c | |||
@@ -25,11 +25,19 @@ | |||
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
27 | 27 | ||
28 | #include <asm/div64.h> | ||
29 | |||
28 | #include <asm/mach-ath79/ar933x_uart.h> | 30 | #include <asm/mach-ath79/ar933x_uart.h> |
29 | #include <asm/mach-ath79/ar933x_uart_platform.h> | 31 | #include <asm/mach-ath79/ar933x_uart_platform.h> |
30 | 32 | ||
31 | #define DRIVER_NAME "ar933x-uart" | 33 | #define DRIVER_NAME "ar933x-uart" |
32 | 34 | ||
35 | #define AR933X_UART_MAX_SCALE 0xff | ||
36 | #define AR933X_UART_MAX_STEP 0xffff | ||
37 | |||
38 | #define AR933X_UART_MIN_BAUD 300 | ||
39 | #define AR933X_UART_MAX_BAUD 3000000 | ||
40 | |||
33 | #define AR933X_DUMMY_STATUS_RD 0x01 | 41 | #define AR933X_DUMMY_STATUS_RD 0x01 |
34 | 42 | ||
35 | static struct uart_driver ar933x_uart_driver; | 43 | static struct uart_driver ar933x_uart_driver; |
@@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_driver; | |||
37 | struct ar933x_uart_port { | 45 | struct ar933x_uart_port { |
38 | struct uart_port port; | 46 | struct uart_port port; |
39 | unsigned int ier; /* shadow Interrupt Enable Register */ | 47 | unsigned int ier; /* shadow Interrupt Enable Register */ |
48 | unsigned int min_baud; | ||
49 | unsigned int max_baud; | ||
40 | }; | 50 | }; |
41 | 51 | ||
42 | static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, | 52 | static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, |
@@ -162,6 +172,57 @@ static void ar933x_uart_enable_ms(struct uart_port *port) | |||
162 | { | 172 | { |
163 | } | 173 | } |
164 | 174 | ||
175 | /* | ||
176 | * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17)) | ||
177 | */ | ||
178 | static unsigned long ar933x_uart_get_baud(unsigned int clk, | ||
179 | unsigned int scale, | ||
180 | unsigned int step) | ||
181 | { | ||
182 | u64 t; | ||
183 | u32 div; | ||
184 | |||
185 | div = (2 << 16) * (scale + 1); | ||
186 | t = clk; | ||
187 | t *= step; | ||
188 | t += (div / 2); | ||
189 | do_div(t, div); | ||
190 | |||
191 | return t; | ||
192 | } | ||
193 | |||
194 | static void ar933x_uart_get_scale_step(unsigned int clk, | ||
195 | unsigned int baud, | ||
196 | unsigned int *scale, | ||
197 | unsigned int *step) | ||
198 | { | ||
199 | unsigned int tscale; | ||
200 | long min_diff; | ||
201 | |||
202 | *scale = 0; | ||
203 | *step = 0; | ||
204 | |||
205 | min_diff = baud; | ||
206 | for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) { | ||
207 | u64 tstep; | ||
208 | int diff; | ||
209 | |||
210 | tstep = baud * (tscale + 1); | ||
211 | tstep *= (2 << 16); | ||
212 | do_div(tstep, clk); | ||
213 | |||
214 | if (tstep > AR933X_UART_MAX_STEP) | ||
215 | break; | ||
216 | |||
217 | diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud); | ||
218 | if (diff < min_diff) { | ||
219 | min_diff = diff; | ||
220 | *scale = tscale; | ||
221 | *step = tstep; | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
165 | static void ar933x_uart_set_termios(struct uart_port *port, | 226 | static void ar933x_uart_set_termios(struct uart_port *port, |
166 | struct ktermios *new, | 227 | struct ktermios *new, |
167 | struct ktermios *old) | 228 | struct ktermios *old) |
@@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
169 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | 230 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; |
170 | unsigned int cs; | 231 | unsigned int cs; |
171 | unsigned long flags; | 232 | unsigned long flags; |
172 | unsigned int baud, scale; | 233 | unsigned int baud, scale, step; |
173 | 234 | ||
174 | /* Only CS8 is supported */ | 235 | /* Only CS8 is supported */ |
175 | new->c_cflag &= ~CSIZE; | 236 | new->c_cflag &= ~CSIZE; |
@@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
191 | /* Mark/space parity is not supported */ | 252 | /* Mark/space parity is not supported */ |
192 | new->c_cflag &= ~CMSPAR; | 253 | new->c_cflag &= ~CMSPAR; |
193 | 254 | ||
194 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | 255 | baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud); |
195 | scale = (port->uartclk / (16 * baud)) - 1; | 256 | ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step); |
196 | 257 | ||
197 | /* | 258 | /* |
198 | * Ok, we're now changing the port state. Do it with | 259 | * Ok, we're now changing the port state. Do it with |
@@ -200,6 +261,10 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
200 | */ | 261 | */ |
201 | spin_lock_irqsave(&up->port.lock, flags); | 262 | spin_lock_irqsave(&up->port.lock, flags); |
202 | 263 | ||
264 | /* disable the UART */ | ||
265 | ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, | ||
266 | AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S); | ||
267 | |||
203 | /* Update the per-port timeout. */ | 268 | /* Update the per-port timeout. */ |
204 | uart_update_timeout(port, new->c_cflag, baud); | 269 | uart_update_timeout(port, new->c_cflag, baud); |
205 | 270 | ||
@@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
210 | up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; | 275 | up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; |
211 | 276 | ||
212 | ar933x_uart_write(up, AR933X_UART_CLOCK_REG, | 277 | ar933x_uart_write(up, AR933X_UART_CLOCK_REG, |
213 | scale << AR933X_UART_CLOCK_SCALE_S | 8192); | 278 | scale << AR933X_UART_CLOCK_SCALE_S | step); |
214 | 279 | ||
215 | /* setup configuration register */ | 280 | /* setup configuration register */ |
216 | ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); | 281 | ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); |
@@ -219,6 +284,11 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
219 | ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, | 284 | ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, |
220 | AR933X_UART_CS_HOST_INT_EN); | 285 | AR933X_UART_CS_HOST_INT_EN); |
221 | 286 | ||
287 | /* reenable the UART */ | ||
288 | ar933x_uart_rmw(up, AR933X_UART_CS_REG, | ||
289 | AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S, | ||
290 | AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S); | ||
291 | |||
222 | spin_unlock_irqrestore(&up->port.lock, flags); | 292 | spin_unlock_irqrestore(&up->port.lock, flags); |
223 | 293 | ||
224 | if (tty_termios_baud_rate(new)) | 294 | if (tty_termios_baud_rate(new)) |
@@ -401,6 +471,8 @@ static void ar933x_uart_config_port(struct uart_port *port, int flags) | |||
401 | static int ar933x_uart_verify_port(struct uart_port *port, | 471 | static int ar933x_uart_verify_port(struct uart_port *port, |
402 | struct serial_struct *ser) | 472 | struct serial_struct *ser) |
403 | { | 473 | { |
474 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
475 | |||
404 | if (ser->type != PORT_UNKNOWN && | 476 | if (ser->type != PORT_UNKNOWN && |
405 | ser->type != PORT_AR933X) | 477 | ser->type != PORT_AR933X) |
406 | return -EINVAL; | 478 | return -EINVAL; |
@@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struct uart_port *port, | |||
408 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 480 | if (ser->irq < 0 || ser->irq >= NR_IRQS) |
409 | return -EINVAL; | 481 | return -EINVAL; |
410 | 482 | ||
411 | if (ser->baud_base < 28800) | 483 | if (ser->baud_base < up->min_baud || |
484 | ser->baud_base > up->max_baud) | ||
412 | return -EINVAL; | 485 | return -EINVAL; |
413 | 486 | ||
414 | return 0; | 487 | return 0; |
@@ -554,13 +627,14 @@ static struct uart_driver ar933x_uart_driver = { | |||
554 | .cons = AR933X_SERIAL_CONSOLE, | 627 | .cons = AR933X_SERIAL_CONSOLE, |
555 | }; | 628 | }; |
556 | 629 | ||
557 | static int __devinit ar933x_uart_probe(struct platform_device *pdev) | 630 | static int ar933x_uart_probe(struct platform_device *pdev) |
558 | { | 631 | { |
559 | struct ar933x_uart_platform_data *pdata; | 632 | struct ar933x_uart_platform_data *pdata; |
560 | struct ar933x_uart_port *up; | 633 | struct ar933x_uart_port *up; |
561 | struct uart_port *port; | 634 | struct uart_port *port; |
562 | struct resource *mem_res; | 635 | struct resource *mem_res; |
563 | struct resource *irq_res; | 636 | struct resource *irq_res; |
637 | unsigned int baud; | ||
564 | int id; | 638 | int id; |
565 | int ret; | 639 | int ret; |
566 | 640 | ||
@@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(struct platform_device *pdev) | |||
611 | port->fifosize = AR933X_UART_FIFO_SIZE; | 685 | port->fifosize = AR933X_UART_FIFO_SIZE; |
612 | port->ops = &ar933x_uart_ops; | 686 | port->ops = &ar933x_uart_ops; |
613 | 687 | ||
688 | baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1); | ||
689 | up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD); | ||
690 | |||
691 | baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); | ||
692 | up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); | ||
693 | |||
614 | ar933x_uart_add_console_port(up); | 694 | ar933x_uart_add_console_port(up); |
615 | 695 | ||
616 | ret = uart_add_one_port(&ar933x_uart_driver, &up->port); | 696 | ret = uart_add_one_port(&ar933x_uart_driver, &up->port); |
@@ -627,7 +707,7 @@ err_free_up: | |||
627 | return ret; | 707 | return ret; |
628 | } | 708 | } |
629 | 709 | ||
630 | static int __devexit ar933x_uart_remove(struct platform_device *pdev) | 710 | static int ar933x_uart_remove(struct platform_device *pdev) |
631 | { | 711 | { |
632 | struct ar933x_uart_port *up; | 712 | struct ar933x_uart_port *up; |
633 | 713 | ||
@@ -645,7 +725,7 @@ static int __devexit ar933x_uart_remove(struct platform_device *pdev) | |||
645 | 725 | ||
646 | static struct platform_driver ar933x_uart_platform_driver = { | 726 | static struct platform_driver ar933x_uart_platform_driver = { |
647 | .probe = ar933x_uart_probe, | 727 | .probe = ar933x_uart_probe, |
648 | .remove = __devexit_p(ar933x_uart_remove), | 728 | .remove = ar933x_uart_remove, |
649 | .driver = { | 729 | .driver = { |
650 | .name = DRIVER_NAME, | 730 | .name = DRIVER_NAME, |
651 | .owner = THIS_MODULE, | 731 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c new file mode 100644 index 000000000000..3e0b3fac6a0e --- /dev/null +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -0,0 +1,746 @@ | |||
1 | /* | ||
2 | * ARC On-Chip(fpga) UART Driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * vineetg: July 10th 2012 | ||
11 | * -Decoupled the driver from arch/arc | ||
12 | * +Using platform_get_resource() for irq/membase (thx to bfin_uart.c) | ||
13 | * +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx) | ||
14 | * | ||
15 | * Vineetg: Aug 21st 2010 | ||
16 | * -Is uart_tx_stopped() not done in tty write path as it has already been | ||
17 | * taken care of, in serial core | ||
18 | * | ||
19 | * Vineetg: Aug 18th 2010 | ||
20 | * -New Serial Core based ARC UART driver | ||
21 | * -Derived largely from blackfin driver albiet with some major tweaks | ||
22 | * | ||
23 | * TODO: | ||
24 | * -check if sysreq works | ||
25 | */ | ||
26 | |||
27 | #if defined(CONFIG_SERIAL_ARC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
28 | #define SUPPORT_SYSRQ | ||
29 | #endif | ||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/serial.h> | ||
33 | #include <linux/console.h> | ||
34 | #include <linux/sysrq.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/tty.h> | ||
37 | #include <linux/tty_flip.h> | ||
38 | #include <linux/serial_core.h> | ||
39 | #include <linux/io.h> | ||
40 | |||
41 | /************************************* | ||
42 | * ARC UART Hardware Specs | ||
43 | ************************************/ | ||
44 | #define ARC_UART_TX_FIFO_SIZE 1 | ||
45 | |||
46 | /* | ||
47 | * UART Register set (this is not a Standards Compliant IP) | ||
48 | * Also each reg is Word aligned, but only 8 bits wide | ||
49 | */ | ||
50 | #define R_ID0 0 | ||
51 | #define R_ID1 4 | ||
52 | #define R_ID2 8 | ||
53 | #define R_ID3 12 | ||
54 | #define R_DATA 16 | ||
55 | #define R_STS 20 | ||
56 | #define R_BAUDL 24 | ||
57 | #define R_BAUDH 28 | ||
58 | |||
59 | /* Bits for UART Status Reg (R/W) */ | ||
60 | #define RXIENB 0x04 /* Receive Interrupt Enable */ | ||
61 | #define TXIENB 0x40 /* Transmit Interrupt Enable */ | ||
62 | |||
63 | #define RXEMPTY 0x20 /* Receive FIFO Empty: No char receivede */ | ||
64 | #define TXEMPTY 0x80 /* Transmit FIFO Empty, thus char can be written into */ | ||
65 | |||
66 | #define RXFULL 0x08 /* Receive FIFO full */ | ||
67 | #define RXFULL1 0x10 /* Receive FIFO has space for 1 char (tot space=4) */ | ||
68 | |||
69 | #define RXFERR 0x01 /* Frame Error: Stop Bit not detected */ | ||
70 | #define RXOERR 0x02 /* OverFlow Err: Char recv but RXFULL still set */ | ||
71 | |||
72 | /* Uart bit fiddling helpers: lowest level */ | ||
73 | #define RBASE(uart, reg) (uart->port.membase + reg) | ||
74 | #define UART_REG_SET(u, r, v) writeb((v), RBASE(u, r)) | ||
75 | #define UART_REG_GET(u, r) readb(RBASE(u, r)) | ||
76 | |||
77 | #define UART_REG_OR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) | (v)) | ||
78 | #define UART_REG_CLR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) & ~(v)) | ||
79 | |||
80 | /* Uart bit fiddling helpers: API level */ | ||
81 | #define UART_SET_DATA(uart, val) UART_REG_SET(uart, R_DATA, val) | ||
82 | #define UART_GET_DATA(uart) UART_REG_GET(uart, R_DATA) | ||
83 | |||
84 | #define UART_SET_BAUDH(uart, val) UART_REG_SET(uart, R_BAUDH, val) | ||
85 | #define UART_SET_BAUDL(uart, val) UART_REG_SET(uart, R_BAUDL, val) | ||
86 | |||
87 | #define UART_CLR_STATUS(uart, val) UART_REG_CLR(uart, R_STS, val) | ||
88 | #define UART_GET_STATUS(uart) UART_REG_GET(uart, R_STS) | ||
89 | |||
90 | #define UART_ALL_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB|TXIENB) | ||
91 | #define UART_RX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB) | ||
92 | #define UART_TX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, TXIENB) | ||
93 | |||
94 | #define UART_ALL_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB|TXIENB) | ||
95 | #define UART_RX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB) | ||
96 | #define UART_TX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, TXIENB) | ||
97 | |||
98 | #define ARC_SERIAL_DEV_NAME "ttyARC" | ||
99 | |||
100 | struct arc_uart_port { | ||
101 | struct uart_port port; | ||
102 | unsigned long baud; | ||
103 | int is_emulated; /* H/w vs. Instruction Set Simulator */ | ||
104 | }; | ||
105 | |||
106 | #define to_arc_port(uport) container_of(uport, struct arc_uart_port, port) | ||
107 | |||
108 | static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS]; | ||
109 | |||
110 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | ||
111 | static struct console arc_console; | ||
112 | #endif | ||
113 | |||
114 | #define DRIVER_NAME "arc-uart" | ||
115 | |||
116 | static struct uart_driver arc_uart_driver = { | ||
117 | .owner = THIS_MODULE, | ||
118 | .driver_name = DRIVER_NAME, | ||
119 | .dev_name = ARC_SERIAL_DEV_NAME, | ||
120 | .major = 0, | ||
121 | .minor = 0, | ||
122 | .nr = CONFIG_SERIAL_ARC_NR_PORTS, | ||
123 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | ||
124 | .cons = &arc_console, | ||
125 | #endif | ||
126 | }; | ||
127 | |||
128 | static void arc_serial_stop_rx(struct uart_port *port) | ||
129 | { | ||
130 | struct arc_uart_port *uart = to_arc_port(port); | ||
131 | |||
132 | UART_RX_IRQ_DISABLE(uart); | ||
133 | } | ||
134 | |||
135 | static void arc_serial_stop_tx(struct uart_port *port) | ||
136 | { | ||
137 | struct arc_uart_port *uart = to_arc_port(port); | ||
138 | |||
139 | while (!(UART_GET_STATUS(uart) & TXEMPTY)) | ||
140 | cpu_relax(); | ||
141 | |||
142 | UART_TX_IRQ_DISABLE(uart); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Return TIOCSER_TEMT when transmitter is not busy. | ||
147 | */ | ||
148 | static unsigned int arc_serial_tx_empty(struct uart_port *port) | ||
149 | { | ||
150 | struct arc_uart_port *uart = to_arc_port(port); | ||
151 | unsigned int stat; | ||
152 | |||
153 | stat = UART_GET_STATUS(uart); | ||
154 | if (stat & TXEMPTY) | ||
155 | return TIOCSER_TEMT; | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Driver internal routine, used by both tty(serial core) as well as tx-isr | ||
162 | * -Called under spinlock in either cases | ||
163 | * -also tty->stopped / tty->hw_stopped has already been checked | ||
164 | * = by uart_start( ) before calling us | ||
165 | * = tx_ist checks that too before calling | ||
166 | */ | ||
167 | static void arc_serial_tx_chars(struct arc_uart_port *uart) | ||
168 | { | ||
169 | struct circ_buf *xmit = &uart->port.state->xmit; | ||
170 | int sent = 0; | ||
171 | unsigned char ch; | ||
172 | |||
173 | if (unlikely(uart->port.x_char)) { | ||
174 | UART_SET_DATA(uart, uart->port.x_char); | ||
175 | uart->port.icount.tx++; | ||
176 | uart->port.x_char = 0; | ||
177 | sent = 1; | ||
178 | } else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */ | ||
179 | ch = xmit->buf[xmit->tail]; | ||
180 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
181 | uart->port.icount.tx++; | ||
182 | while (!(UART_GET_STATUS(uart) & TXEMPTY)) | ||
183 | cpu_relax(); | ||
184 | UART_SET_DATA(uart, ch); | ||
185 | sent = 1; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * If num chars in xmit buffer are too few, ask tty layer for more. | ||
190 | * By Hard ISR to schedule processing in software interrupt part | ||
191 | */ | ||
192 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
193 | uart_write_wakeup(&uart->port); | ||
194 | |||
195 | if (sent) | ||
196 | UART_TX_IRQ_ENABLE(uart); | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * port is locked and interrupts are disabled | ||
201 | * uart_start( ) calls us under the port spinlock irqsave | ||
202 | */ | ||
203 | static void arc_serial_start_tx(struct uart_port *port) | ||
204 | { | ||
205 | struct arc_uart_port *uart = to_arc_port(port); | ||
206 | |||
207 | arc_serial_tx_chars(uart); | ||
208 | } | ||
209 | |||
210 | static void arc_serial_rx_chars(struct arc_uart_port *uart) | ||
211 | { | ||
212 | struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port); | ||
213 | unsigned int status, ch, flg = 0; | ||
214 | |||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | /* | ||
219 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact | ||
220 | * is very subtle. Here's how ... | ||
221 | * Upon getting a RX-Intr, such that RX-EMPTY=0, meaning data available, | ||
222 | * driver reads the DATA Reg and keeps doing that in a loop, until | ||
223 | * RX-EMPTY=1. Multiple chars being avail, with a single Interrupt, | ||
224 | * before RX-EMPTY=0, implies some sort of buffering going on in the | ||
225 | * controller, which is indeed the Rx-FIFO. | ||
226 | */ | ||
227 | while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) { | ||
228 | |||
229 | ch = UART_GET_DATA(uart); | ||
230 | uart->port.icount.rx++; | ||
231 | |||
232 | if (unlikely(status & (RXOERR | RXFERR))) { | ||
233 | if (status & RXOERR) { | ||
234 | uart->port.icount.overrun++; | ||
235 | flg = TTY_OVERRUN; | ||
236 | UART_CLR_STATUS(uart, RXOERR); | ||
237 | } | ||
238 | |||
239 | if (status & RXFERR) { | ||
240 | uart->port.icount.frame++; | ||
241 | flg = TTY_FRAME; | ||
242 | UART_CLR_STATUS(uart, RXFERR); | ||
243 | } | ||
244 | } else | ||
245 | flg = TTY_NORMAL; | ||
246 | |||
247 | if (unlikely(uart_handle_sysrq_char(&uart->port, ch))) | ||
248 | goto done; | ||
249 | |||
250 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); | ||
251 | |||
252 | done: | ||
253 | tty_flip_buffer_push(tty); | ||
254 | } | ||
255 | |||
256 | tty_kref_put(tty); | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * A note on the Interrupt handling state machine of this driver | ||
261 | * | ||
262 | * kernel printk writes funnel thru the console driver framework and in order | ||
263 | * to keep things simple as well as efficient, it writes to UART in polled | ||
264 | * mode, in one shot, and exits. | ||
265 | * | ||
266 | * OTOH, Userland output (via tty layer), uses interrupt based writes as there | ||
267 | * can be undeterministic delay between char writes. | ||
268 | * | ||
269 | * Thus Rx-interrupts are always enabled, while tx-interrupts are by default | ||
270 | * disabled. | ||
271 | * | ||
272 | * When tty has some data to send out, serial core calls driver's start_tx | ||
273 | * which | ||
274 | * -checks-if-tty-buffer-has-char-to-send | ||
275 | * -writes-data-to-uart | ||
276 | * -enable-tx-intr | ||
277 | * | ||
278 | * Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt. | ||
279 | * The first thing Tx ISR does is disable further Tx interrupts (as this could | ||
280 | * be the last char to send, before settling down into the quiet polled mode). | ||
281 | * It then calls the exact routine used by tty layer write to send out any | ||
282 | * more char in tty buffer. In case of sending, it re-enables Tx-intr. In case | ||
283 | * of no data, it remains disabled. | ||
284 | * This is how the transmit state machine is dynamically switched on/off | ||
285 | */ | ||
286 | |||
287 | static irqreturn_t arc_serial_isr(int irq, void *dev_id) | ||
288 | { | ||
289 | struct arc_uart_port *uart = dev_id; | ||
290 | unsigned int status; | ||
291 | |||
292 | status = UART_GET_STATUS(uart); | ||
293 | |||
294 | /* | ||
295 | * Single IRQ for both Rx (data available) Tx (room available) Interrupt | ||
296 | * notifications from the UART Controller. | ||
297 | * To demultiplex between the two, we check the relevant bits | ||
298 | */ | ||
299 | if ((status & RXIENB) && !(status & RXEMPTY)) { | ||
300 | |||
301 | /* already in ISR, no need of xx_irqsave */ | ||
302 | spin_lock(&uart->port.lock); | ||
303 | arc_serial_rx_chars(uart); | ||
304 | spin_unlock(&uart->port.lock); | ||
305 | } | ||
306 | |||
307 | if ((status & TXIENB) && (status & TXEMPTY)) { | ||
308 | |||
309 | /* Unconditionally disable further Tx-Interrupts. | ||
310 | * will be enabled by tx_chars() if needed. | ||
311 | */ | ||
312 | UART_TX_IRQ_DISABLE(uart); | ||
313 | |||
314 | spin_lock(&uart->port.lock); | ||
315 | |||
316 | if (!uart_tx_stopped(&uart->port)) | ||
317 | arc_serial_tx_chars(uart); | ||
318 | |||
319 | spin_unlock(&uart->port.lock); | ||
320 | } | ||
321 | |||
322 | return IRQ_HANDLED; | ||
323 | } | ||
324 | |||
325 | static unsigned int arc_serial_get_mctrl(struct uart_port *port) | ||
326 | { | ||
327 | /* | ||
328 | * Pretend we have a Modem status reg and following bits are | ||
329 | * always set, to satify the serial core state machine | ||
330 | * (DSR) Data Set Ready | ||
331 | * (CTS) Clear To Send | ||
332 | * (CAR) Carrier Detect | ||
333 | */ | ||
334 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
335 | } | ||
336 | |||
337 | static void arc_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
338 | { | ||
339 | /* MCR not present */ | ||
340 | } | ||
341 | |||
342 | /* Enable Modem Status Interrupts */ | ||
343 | |||
344 | static void arc_serial_enable_ms(struct uart_port *port) | ||
345 | { | ||
346 | /* MSR not present */ | ||
347 | } | ||
348 | |||
349 | static void arc_serial_break_ctl(struct uart_port *port, int break_state) | ||
350 | { | ||
351 | /* ARC UART doesn't support sending Break signal */ | ||
352 | } | ||
353 | |||
354 | static int arc_serial_startup(struct uart_port *port) | ||
355 | { | ||
356 | struct arc_uart_port *uart = to_arc_port(port); | ||
357 | |||
358 | /* Before we hook up the ISR, Disable all UART Interrupts */ | ||
359 | UART_ALL_IRQ_DISABLE(uart); | ||
360 | |||
361 | if (request_irq(uart->port.irq, arc_serial_isr, 0, "arc uart rx-tx", | ||
362 | uart)) { | ||
363 | dev_warn(uart->port.dev, "Unable to attach ARC UART intr\n"); | ||
364 | return -EBUSY; | ||
365 | } | ||
366 | |||
367 | UART_RX_IRQ_ENABLE(uart); /* Only Rx IRQ enabled to begin with */ | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /* This is not really needed */ | ||
373 | static void arc_serial_shutdown(struct uart_port *port) | ||
374 | { | ||
375 | struct arc_uart_port *uart = to_arc_port(port); | ||
376 | free_irq(uart->port.irq, uart); | ||
377 | } | ||
378 | |||
379 | static void | ||
380 | arc_serial_set_termios(struct uart_port *port, struct ktermios *new, | ||
381 | struct ktermios *old) | ||
382 | { | ||
383 | struct arc_uart_port *uart = to_arc_port(port); | ||
384 | unsigned int baud, uartl, uarth, hw_val; | ||
385 | unsigned long flags; | ||
386 | |||
387 | /* | ||
388 | * Use the generic handler so that any specially encoded baud rates | ||
389 | * such as SPD_xx flags or "%B0" can be handled | ||
390 | * Max Baud I suppose will not be more than current 115K * 4 | ||
391 | * Formula for ARC UART is: hw-val = ((CLK/(BAUD*4)) -1) | ||
392 | * spread over two 8-bit registers | ||
393 | */ | ||
394 | baud = uart_get_baud_rate(port, new, old, 0, 460800); | ||
395 | |||
396 | hw_val = port->uartclk / (uart->baud * 4) - 1; | ||
397 | uartl = hw_val & 0xFF; | ||
398 | uarth = (hw_val >> 8) & 0xFF; | ||
399 | |||
400 | /* | ||
401 | * UART ISS(Instruction Set simulator) emulation has a subtle bug: | ||
402 | * A existing value of Baudh = 0 is used as a indication to startup | ||
403 | * it's internal state machine. | ||
404 | * Thus if baudh is set to 0, 2 times, it chokes. | ||
405 | * This happens with BAUD=115200 and the formaula above | ||
406 | * Until that is fixed, when running on ISS, we will set baudh to !0 | ||
407 | */ | ||
408 | if (uart->is_emulated) | ||
409 | uarth = 1; | ||
410 | |||
411 | spin_lock_irqsave(&port->lock, flags); | ||
412 | |||
413 | UART_ALL_IRQ_DISABLE(uart); | ||
414 | |||
415 | UART_SET_BAUDL(uart, uartl); | ||
416 | UART_SET_BAUDH(uart, uarth); | ||
417 | |||
418 | UART_RX_IRQ_ENABLE(uart); | ||
419 | |||
420 | /* | ||
421 | * UART doesn't support Parity/Hardware Flow Control; | ||
422 | * Only supports 8N1 character size | ||
423 | */ | ||
424 | new->c_cflag &= ~(CMSPAR|CRTSCTS|CSIZE); | ||
425 | new->c_cflag |= CS8; | ||
426 | |||
427 | if (old) | ||
428 | tty_termios_copy_hw(new, old); | ||
429 | |||
430 | /* Don't rewrite B0 */ | ||
431 | if (tty_termios_baud_rate(new)) | ||
432 | tty_termios_encode_baud_rate(new, baud, baud); | ||
433 | |||
434 | uart_update_timeout(port, new->c_cflag, baud); | ||
435 | |||
436 | spin_unlock_irqrestore(&port->lock, flags); | ||
437 | } | ||
438 | |||
439 | static const char *arc_serial_type(struct uart_port *port) | ||
440 | { | ||
441 | struct arc_uart_port *uart = to_arc_port(port); | ||
442 | |||
443 | return uart->port.type == PORT_ARC ? DRIVER_NAME : NULL; | ||
444 | } | ||
445 | |||
446 | static void arc_serial_release_port(struct uart_port *port) | ||
447 | { | ||
448 | } | ||
449 | |||
450 | static int arc_serial_request_port(struct uart_port *port) | ||
451 | { | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Verify the new serial_struct (for TIOCSSERIAL). | ||
457 | */ | ||
458 | static int | ||
459 | arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
460 | { | ||
461 | if (port->type != PORT_UNKNOWN && ser->type != PORT_ARC) | ||
462 | return -EINVAL; | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Configure/autoconfigure the port. | ||
469 | */ | ||
470 | static void arc_serial_config_port(struct uart_port *port, int flags) | ||
471 | { | ||
472 | struct arc_uart_port *uart = to_arc_port(port); | ||
473 | |||
474 | if (flags & UART_CONFIG_TYPE) | ||
475 | uart->port.type = PORT_ARC; | ||
476 | } | ||
477 | |||
478 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_ARC_CONSOLE) | ||
479 | |||
480 | static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr) | ||
481 | { | ||
482 | struct arc_uart_port *uart = to_arc_port(port); | ||
483 | |||
484 | while (!(UART_GET_STATUS(uart) & TXEMPTY)) | ||
485 | cpu_relax(); | ||
486 | |||
487 | UART_SET_DATA(uart, chr); | ||
488 | } | ||
489 | #endif | ||
490 | |||
491 | #ifdef CONFIG_CONSOLE_POLL | ||
492 | static int arc_serial_poll_getchar(struct uart_port *port) | ||
493 | { | ||
494 | struct arc_uart_port *uart = to_arc_port(port); | ||
495 | unsigned char chr; | ||
496 | |||
497 | while (!(UART_GET_STATUS(uart) & RXEMPTY)) | ||
498 | cpu_relax(); | ||
499 | |||
500 | chr = UART_GET_DATA(uart); | ||
501 | return chr; | ||
502 | } | ||
503 | #endif | ||
504 | |||
505 | static struct uart_ops arc_serial_pops = { | ||
506 | .tx_empty = arc_serial_tx_empty, | ||
507 | .set_mctrl = arc_serial_set_mctrl, | ||
508 | .get_mctrl = arc_serial_get_mctrl, | ||
509 | .stop_tx = arc_serial_stop_tx, | ||
510 | .start_tx = arc_serial_start_tx, | ||
511 | .stop_rx = arc_serial_stop_rx, | ||
512 | .enable_ms = arc_serial_enable_ms, | ||
513 | .break_ctl = arc_serial_break_ctl, | ||
514 | .startup = arc_serial_startup, | ||
515 | .shutdown = arc_serial_shutdown, | ||
516 | .set_termios = arc_serial_set_termios, | ||
517 | .type = arc_serial_type, | ||
518 | .release_port = arc_serial_release_port, | ||
519 | .request_port = arc_serial_request_port, | ||
520 | .config_port = arc_serial_config_port, | ||
521 | .verify_port = arc_serial_verify_port, | ||
522 | #ifdef CONFIG_CONSOLE_POLL | ||
523 | .poll_put_char = arc_serial_poll_putchar, | ||
524 | .poll_get_char = arc_serial_poll_getchar, | ||
525 | #endif | ||
526 | }; | ||
527 | |||
528 | static int | ||
529 | arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | ||
530 | { | ||
531 | struct resource *res, *res2; | ||
532 | unsigned long *plat_data; | ||
533 | |||
534 | if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) { | ||
535 | dev_err(&pdev->dev, "Wrong uart platform device id.\n"); | ||
536 | return -ENOENT; | ||
537 | } | ||
538 | |||
539 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); | ||
540 | uart->baud = plat_data[0]; | ||
541 | |||
542 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
543 | if (!res) | ||
544 | return -ENODEV; | ||
545 | |||
546 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
547 | if (!res2) | ||
548 | return -ENODEV; | ||
549 | |||
550 | uart->port.mapbase = res->start; | ||
551 | uart->port.membase = ioremap_nocache(res->start, resource_size(res)); | ||
552 | if (!uart->port.membase) | ||
553 | /* No point of dev_err since UART itself is hosed here */ | ||
554 | return -ENXIO; | ||
555 | |||
556 | uart->port.irq = res2->start; | ||
557 | uart->port.dev = &pdev->dev; | ||
558 | uart->port.iotype = UPIO_MEM; | ||
559 | uart->port.flags = UPF_BOOT_AUTOCONF; | ||
560 | uart->port.line = pdev->id; | ||
561 | uart->port.ops = &arc_serial_pops; | ||
562 | |||
563 | uart->port.uartclk = plat_data[1]; | ||
564 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; | ||
565 | |||
566 | /* | ||
567 | * uart_insert_char( ) uses it in decideding whether to ignore a | ||
568 | * char or not. Explicitly setting it here, removes the subtelty | ||
569 | */ | ||
570 | uart->port.ignore_status_mask = 0; | ||
571 | |||
572 | /* Real Hardware vs. emulated to work around a bug */ | ||
573 | uart->is_emulated = !!plat_data[2]; | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | ||
579 | |||
580 | static int arc_serial_console_setup(struct console *co, char *options) | ||
581 | { | ||
582 | struct uart_port *port; | ||
583 | int baud = 115200; | ||
584 | int bits = 8; | ||
585 | int parity = 'n'; | ||
586 | int flow = 'n'; | ||
587 | |||
588 | if (co->index < 0 || co->index >= CONFIG_SERIAL_ARC_NR_PORTS) | ||
589 | return -ENODEV; | ||
590 | |||
591 | /* | ||
592 | * The uart port backing the console (e.g. ttyARC1) might not have been | ||
593 | * init yet. If so, defer the console setup to after the port. | ||
594 | */ | ||
595 | port = &arc_uart_ports[co->index].port; | ||
596 | if (!port->membase) | ||
597 | return -ENODEV; | ||
598 | |||
599 | if (options) | ||
600 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
601 | |||
602 | /* | ||
603 | * Serial core will call port->ops->set_termios( ) | ||
604 | * which will set the baud reg | ||
605 | */ | ||
606 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
607 | } | ||
608 | |||
609 | static void arc_serial_console_putchar(struct uart_port *port, int ch) | ||
610 | { | ||
611 | arc_serial_poll_putchar(port, (unsigned char)ch); | ||
612 | } | ||
613 | |||
614 | /* | ||
615 | * Interrupts are disabled on entering | ||
616 | */ | ||
617 | static void arc_serial_console_write(struct console *co, const char *s, | ||
618 | unsigned int count) | ||
619 | { | ||
620 | struct uart_port *port = &arc_uart_ports[co->index].port; | ||
621 | unsigned long flags; | ||
622 | |||
623 | spin_lock_irqsave(&port->lock, flags); | ||
624 | uart_console_write(port, s, count, arc_serial_console_putchar); | ||
625 | spin_unlock_irqrestore(&port->lock, flags); | ||
626 | } | ||
627 | |||
628 | static struct console arc_console = { | ||
629 | .name = ARC_SERIAL_DEV_NAME, | ||
630 | .write = arc_serial_console_write, | ||
631 | .device = uart_console_device, | ||
632 | .setup = arc_serial_console_setup, | ||
633 | .flags = CON_PRINTBUFFER, | ||
634 | .index = -1, | ||
635 | .data = &arc_uart_driver | ||
636 | }; | ||
637 | |||
638 | static __init void early_serial_write(struct console *con, const char *s, | ||
639 | unsigned int n) | ||
640 | { | ||
641 | struct uart_port *port = &arc_uart_ports[con->index].port; | ||
642 | unsigned int i; | ||
643 | |||
644 | for (i = 0; i < n; i++, s++) { | ||
645 | if (*s == '\n') | ||
646 | arc_serial_poll_putchar(port, '\r'); | ||
647 | arc_serial_poll_putchar(port, *s); | ||
648 | } | ||
649 | } | ||
650 | |||
651 | static struct __initdata console arc_early_serial_console = { | ||
652 | .name = "early_ARCuart", | ||
653 | .write = early_serial_write, | ||
654 | .flags = CON_PRINTBUFFER | CON_BOOT, | ||
655 | .index = -1 | ||
656 | }; | ||
657 | |||
658 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | ||
659 | { | ||
660 | arc_early_serial_console.index = pdev->id; | ||
661 | |||
662 | arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); | ||
663 | |||
664 | arc_serial_console_setup(&arc_early_serial_console, NULL); | ||
665 | |||
666 | register_console(&arc_early_serial_console); | ||
667 | return 0; | ||
668 | } | ||
669 | #else | ||
670 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | ||
671 | { | ||
672 | return -ENODEV; | ||
673 | } | ||
674 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | ||
675 | |||
676 | static int arc_serial_probe(struct platform_device *pdev) | ||
677 | { | ||
678 | struct arc_uart_port *uart; | ||
679 | int rc; | ||
680 | |||
681 | if (is_early_platform_device(pdev)) | ||
682 | return arc_serial_probe_earlyprintk(pdev); | ||
683 | |||
684 | uart = &arc_uart_ports[pdev->id]; | ||
685 | rc = arc_uart_init_one(pdev, uart); | ||
686 | if (rc) | ||
687 | return rc; | ||
688 | |||
689 | return uart_add_one_port(&arc_uart_driver, &uart->port); | ||
690 | } | ||
691 | |||
692 | static int arc_serial_remove(struct platform_device *pdev) | ||
693 | { | ||
694 | /* This will never be called */ | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static struct platform_driver arc_platform_driver = { | ||
699 | .probe = arc_serial_probe, | ||
700 | .remove = arc_serial_remove, | ||
701 | .driver = { | ||
702 | .name = DRIVER_NAME, | ||
703 | .owner = THIS_MODULE, | ||
704 | }, | ||
705 | }; | ||
706 | |||
707 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | ||
708 | /* | ||
709 | * Register an early platform driver of "earlyprintk" class. | ||
710 | * ARCH platform code installs the driver and probes the early devices | ||
711 | * The installation could rely on user specifying earlyprintk=xyx in cmd line | ||
712 | * or it could be done independently, for all "earlyprintk" class drivers. | ||
713 | * [see arch/arc/plat-arcfpga/platform.c] | ||
714 | */ | ||
715 | early_platform_init("earlyprintk", &arc_platform_driver); | ||
716 | |||
717 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | ||
718 | |||
719 | static int __init arc_serial_init(void) | ||
720 | { | ||
721 | int ret; | ||
722 | |||
723 | ret = uart_register_driver(&arc_uart_driver); | ||
724 | if (ret) | ||
725 | return ret; | ||
726 | |||
727 | ret = platform_driver_register(&arc_platform_driver); | ||
728 | if (ret) | ||
729 | uart_unregister_driver(&arc_uart_driver); | ||
730 | |||
731 | return ret; | ||
732 | } | ||
733 | |||
734 | static void __exit arc_serial_exit(void) | ||
735 | { | ||
736 | platform_driver_unregister(&arc_platform_driver); | ||
737 | uart_unregister_driver(&arc_uart_driver); | ||
738 | } | ||
739 | |||
740 | module_init(arc_serial_init); | ||
741 | module_exit(arc_serial_exit); | ||
742 | |||
743 | MODULE_LICENSE("GPL"); | ||
744 | MODULE_ALIAS("plat-arcfpga/uart"); | ||
745 | MODULE_AUTHOR("Vineet Gupta"); | ||
746 | MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver"); | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 65f891be12d1..b95886c1198d 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -1424,7 +1424,7 @@ static struct uart_ops atmel_pops = { | |||
1424 | #endif | 1424 | #endif |
1425 | }; | 1425 | }; |
1426 | 1426 | ||
1427 | static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port, | 1427 | static void atmel_of_init_port(struct atmel_uart_port *atmel_port, |
1428 | struct device_node *np) | 1428 | struct device_node *np) |
1429 | { | 1429 | { |
1430 | u32 rs485_delay[2]; | 1430 | u32 rs485_delay[2]; |
@@ -1459,7 +1459,7 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port, | |||
1459 | /* | 1459 | /* |
1460 | * Configure the port from the platform device resource info. | 1460 | * Configure the port from the platform device resource info. |
1461 | */ | 1461 | */ |
1462 | static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | 1462 | static void atmel_init_port(struct atmel_uart_port *atmel_port, |
1463 | struct platform_device *pdev) | 1463 | struct platform_device *pdev) |
1464 | { | 1464 | { |
1465 | struct uart_port *port = &atmel_port->uart; | 1465 | struct uart_port *port = &atmel_port->uart; |
@@ -1767,7 +1767,7 @@ static int atmel_serial_resume(struct platform_device *pdev) | |||
1767 | #define atmel_serial_resume NULL | 1767 | #define atmel_serial_resume NULL |
1768 | #endif | 1768 | #endif |
1769 | 1769 | ||
1770 | static int __devinit atmel_serial_probe(struct platform_device *pdev) | 1770 | static int atmel_serial_probe(struct platform_device *pdev) |
1771 | { | 1771 | { |
1772 | struct atmel_uart_port *port; | 1772 | struct atmel_uart_port *port; |
1773 | struct device_node *np = pdev->dev.of_node; | 1773 | struct device_node *np = pdev->dev.of_node; |
@@ -1859,7 +1859,7 @@ err: | |||
1859 | return ret; | 1859 | return ret; |
1860 | } | 1860 | } |
1861 | 1861 | ||
1862 | static int __devexit atmel_serial_remove(struct platform_device *pdev) | 1862 | static int atmel_serial_remove(struct platform_device *pdev) |
1863 | { | 1863 | { |
1864 | struct uart_port *port = platform_get_drvdata(pdev); | 1864 | struct uart_port *port = platform_get_drvdata(pdev); |
1865 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1865 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
@@ -1884,7 +1884,7 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev) | |||
1884 | 1884 | ||
1885 | static struct platform_driver atmel_serial_driver = { | 1885 | static struct platform_driver atmel_serial_driver = { |
1886 | .probe = atmel_serial_probe, | 1886 | .probe = atmel_serial_probe, |
1887 | .remove = __devexit_p(atmel_serial_remove), | 1887 | .remove = atmel_serial_remove, |
1888 | .suspend = atmel_serial_suspend, | 1888 | .suspend = atmel_serial_suspend, |
1889 | .resume = atmel_serial_resume, | 1889 | .resume = atmel_serial_resume, |
1890 | .driver = { | 1890 | .driver = { |
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index c0b68b9cad91..c76a226080f2 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c | |||
@@ -801,7 +801,7 @@ static struct uart_driver bcm_uart_driver = { | |||
801 | /* | 801 | /* |
802 | * platform driver probe/remove callback | 802 | * platform driver probe/remove callback |
803 | */ | 803 | */ |
804 | static int __devinit bcm_uart_probe(struct platform_device *pdev) | 804 | static int bcm_uart_probe(struct platform_device *pdev) |
805 | { | 805 | { |
806 | struct resource *res_mem, *res_irq; | 806 | struct resource *res_mem, *res_irq; |
807 | struct uart_port *port; | 807 | struct uart_port *port; |
@@ -848,7 +848,7 @@ static int __devinit bcm_uart_probe(struct platform_device *pdev) | |||
848 | return 0; | 848 | return 0; |
849 | } | 849 | } |
850 | 850 | ||
851 | static int __devexit bcm_uart_remove(struct platform_device *pdev) | 851 | static int bcm_uart_remove(struct platform_device *pdev) |
852 | { | 852 | { |
853 | struct uart_port *port; | 853 | struct uart_port *port; |
854 | 854 | ||
@@ -865,7 +865,7 @@ static int __devexit bcm_uart_remove(struct platform_device *pdev) | |||
865 | */ | 865 | */ |
866 | static struct platform_driver bcm_uart_platform_driver = { | 866 | static struct platform_driver bcm_uart_platform_driver = { |
867 | .probe = bcm_uart_probe, | 867 | .probe = bcm_uart_probe, |
868 | .remove = __devexit_p(bcm_uart_remove), | 868 | .remove = bcm_uart_remove, |
869 | .driver = { | 869 | .driver = { |
870 | .owner = THIS_MODULE, | 870 | .owner = THIS_MODULE, |
871 | .name = "bcm63xx_uart", | 871 | .name = "bcm63xx_uart", |
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index 7fbc3a08f10d..f5d117379b60 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c | |||
@@ -740,7 +740,7 @@ static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = { | |||
740 | }; | 740 | }; |
741 | #endif | 741 | #endif |
742 | 742 | ||
743 | static int __devinit sport_uart_probe(struct platform_device *pdev) | 743 | static int sport_uart_probe(struct platform_device *pdev) |
744 | { | 744 | { |
745 | struct resource *res; | 745 | struct resource *res; |
746 | struct sport_uart_port *sport; | 746 | struct sport_uart_port *sport; |
@@ -850,7 +850,7 @@ out_error_free_mem: | |||
850 | return ret; | 850 | return ret; |
851 | } | 851 | } |
852 | 852 | ||
853 | static int __devexit sport_uart_remove(struct platform_device *pdev) | 853 | static int sport_uart_remove(struct platform_device *pdev) |
854 | { | 854 | { |
855 | struct sport_uart_port *sport = platform_get_drvdata(pdev); | 855 | struct sport_uart_port *sport = platform_get_drvdata(pdev); |
856 | 856 | ||
@@ -871,7 +871,7 @@ static int __devexit sport_uart_remove(struct platform_device *pdev) | |||
871 | 871 | ||
872 | static struct platform_driver sport_uart_driver = { | 872 | static struct platform_driver sport_uart_driver = { |
873 | .probe = sport_uart_probe, | 873 | .probe = sport_uart_probe, |
874 | .remove = __devexit_p(sport_uart_remove), | 874 | .remove = sport_uart_remove, |
875 | .driver = { | 875 | .driver = { |
876 | .name = DRV_NAME, | 876 | .name = DRV_NAME, |
877 | #ifdef CONFIG_PM | 877 | #ifdef CONFIG_PM |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 9242d56ba267..e6a008f4939f 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | 477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) |
478 | { | 478 | { |
479 | int x_pos, pos; | 479 | int x_pos, pos; |
480 | unsigned long flags; | ||
480 | 481 | ||
481 | dma_disable_irq_nosync(uart->rx_dma_channel); | 482 | spin_lock_irqsave(&uart->rx_lock, flags); |
482 | spin_lock_bh(&uart->rx_lock); | ||
483 | 483 | ||
484 | /* 2D DMA RX buffer ring is used. Because curr_y_count and | 484 | /* 2D DMA RX buffer ring is used. Because curr_y_count and |
485 | * curr_x_count can't be read as an atomic operation, | 485 | * curr_x_count can't be read as an atomic operation, |
@@ -510,8 +510,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
510 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; | 510 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; |
511 | } | 511 | } |
512 | 512 | ||
513 | spin_unlock_bh(&uart->rx_lock); | 513 | spin_unlock_irqrestore(&uart->rx_lock, flags); |
514 | dma_enable_irq(uart->rx_dma_channel); | ||
515 | 514 | ||
516 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 515 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
517 | } | 516 | } |
@@ -800,6 +799,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
800 | unsigned long flags; | 799 | unsigned long flags; |
801 | unsigned int baud, quot; | 800 | unsigned int baud, quot; |
802 | unsigned int ier, lcr = 0; | 801 | unsigned int ier, lcr = 0; |
802 | unsigned long timeout; | ||
803 | 803 | ||
804 | switch (termios->c_cflag & CSIZE) { | 804 | switch (termios->c_cflag & CSIZE) { |
805 | case CS8: | 805 | case CS8: |
@@ -869,6 +869,14 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
869 | 869 | ||
870 | UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); | 870 | UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); |
871 | 871 | ||
872 | /* Wait till the transfer buffer is empty */ | ||
873 | timeout = jiffies + msecs_to_jiffies(10); | ||
874 | while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT)) | ||
875 | if (time_after(jiffies, timeout)) { | ||
876 | dev_warn(port->dev, "timeout waiting for TX buffer empty\n"); | ||
877 | break; | ||
878 | } | ||
879 | |||
872 | /* Disable UART */ | 880 | /* Disable UART */ |
873 | ier = UART_GET_IER(uart); | 881 | ier = UART_GET_IER(uart); |
874 | UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN); | 882 | UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN); |
@@ -1390,7 +1398,7 @@ out_error_free_mem: | |||
1390 | return ret; | 1398 | return ret; |
1391 | } | 1399 | } |
1392 | 1400 | ||
1393 | static int __devexit bfin_serial_remove(struct platform_device *pdev) | 1401 | static int bfin_serial_remove(struct platform_device *pdev) |
1394 | { | 1402 | { |
1395 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); | 1403 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); |
1396 | 1404 | ||
@@ -1410,7 +1418,7 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev) | |||
1410 | 1418 | ||
1411 | static struct platform_driver bfin_serial_driver = { | 1419 | static struct platform_driver bfin_serial_driver = { |
1412 | .probe = bfin_serial_probe, | 1420 | .probe = bfin_serial_probe, |
1413 | .remove = __devexit_p(bfin_serial_remove), | 1421 | .remove = bfin_serial_remove, |
1414 | .suspend = bfin_serial_suspend, | 1422 | .suspend = bfin_serial_suspend, |
1415 | .resume = bfin_serial_resume, | 1423 | .resume = bfin_serial_resume, |
1416 | .driver = { | 1424 | .driver = { |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index d0f719fafc84..3fd2526d121e 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -10,15 +10,6 @@ | |||
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | 13 | */ |
23 | 14 | ||
24 | #if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 15 | #if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
@@ -26,172 +17,169 @@ | |||
26 | #endif | 17 | #endif |
27 | 18 | ||
28 | #include <linux/module.h> | 19 | #include <linux/module.h> |
29 | #include <linux/ioport.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/console.h> | ||
32 | #include <linux/sysrq.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | #include <linux/device.h> | 20 | #include <linux/device.h> |
35 | #include <linux/tty.h> | 21 | #include <linux/console.h> |
36 | #include <linux/tty_flip.h> | ||
37 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
38 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
39 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/clk.h> | ||
26 | #include <linux/tty.h> | ||
27 | #include <linux/tty_flip.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/platform_device.h> | ||
40 | 30 | ||
41 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
42 | #include <asm/irq.h> | ||
43 | |||
44 | #define UART_NR 2 | ||
45 | |||
46 | #define SERIAL_CLPS711X_MAJOR 204 | ||
47 | #define SERIAL_CLPS711X_MINOR 40 | ||
48 | #define SERIAL_CLPS711X_NR UART_NR | ||
49 | |||
50 | /* | ||
51 | * We use the relevant SYSCON register as a base address for these ports. | ||
52 | */ | ||
53 | #define UBRLCR(port) ((port)->iobase + UBRLCR1 - SYSCON1) | ||
54 | #define UARTDR(port) ((port)->iobase + UARTDR1 - SYSCON1) | ||
55 | #define SYSFLG(port) ((port)->iobase + SYSFLG1 - SYSCON1) | ||
56 | #define SYSCON(port) ((port)->iobase + SYSCON1 - SYSCON1) | ||
57 | |||
58 | #define TX_IRQ(port) ((port)->irq) | ||
59 | #define RX_IRQ(port) ((port)->irq + 1) | ||
60 | 32 | ||
61 | #define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR) | 33 | #define UART_CLPS711X_NAME "uart-clps711x" |
62 | 34 | #define UART_CLPS711X_NR 2 | |
63 | #define tx_enabled(port) ((port)->unused[0]) | 35 | #define UART_CLPS711X_MAJOR 204 |
36 | #define UART_CLPS711X_MINOR 40 | ||
37 | |||
38 | #define UBRLCR(port) ((port)->line ? UBRLCR2 : UBRLCR1) | ||
39 | #define UARTDR(port) ((port)->line ? UARTDR2 : UARTDR1) | ||
40 | #define SYSFLG(port) ((port)->line ? SYSFLG2 : SYSFLG1) | ||
41 | #define SYSCON(port) ((port)->line ? SYSCON2 : SYSCON1) | ||
42 | #define TX_IRQ(port) ((port)->line ? IRQ_UTXINT2 : IRQ_UTXINT1) | ||
43 | #define RX_IRQ(port) ((port)->line ? IRQ_URXINT2 : IRQ_URXINT1) | ||
44 | |||
45 | struct clps711x_port { | ||
46 | struct uart_driver uart; | ||
47 | struct clk *uart_clk; | ||
48 | struct uart_port port[UART_CLPS711X_NR]; | ||
49 | int tx_enabled[UART_CLPS711X_NR]; | ||
50 | #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE | ||
51 | struct console console; | ||
52 | #endif | ||
53 | }; | ||
64 | 54 | ||
65 | static void clps711xuart_stop_tx(struct uart_port *port) | 55 | static void uart_clps711x_stop_tx(struct uart_port *port) |
66 | { | 56 | { |
67 | if (tx_enabled(port)) { | 57 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
58 | |||
59 | if (s->tx_enabled[port->line]) { | ||
68 | disable_irq(TX_IRQ(port)); | 60 | disable_irq(TX_IRQ(port)); |
69 | tx_enabled(port) = 0; | 61 | s->tx_enabled[port->line] = 0; |
70 | } | 62 | } |
71 | } | 63 | } |
72 | 64 | ||
73 | static void clps711xuart_start_tx(struct uart_port *port) | 65 | static void uart_clps711x_start_tx(struct uart_port *port) |
74 | { | 66 | { |
75 | if (!tx_enabled(port)) { | 67 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
68 | |||
69 | if (!s->tx_enabled[port->line]) { | ||
76 | enable_irq(TX_IRQ(port)); | 70 | enable_irq(TX_IRQ(port)); |
77 | tx_enabled(port) = 1; | 71 | s->tx_enabled[port->line] = 1; |
78 | } | 72 | } |
79 | } | 73 | } |
80 | 74 | ||
81 | static void clps711xuart_stop_rx(struct uart_port *port) | 75 | static void uart_clps711x_stop_rx(struct uart_port *port) |
82 | { | 76 | { |
83 | disable_irq(RX_IRQ(port)); | 77 | disable_irq(RX_IRQ(port)); |
84 | } | 78 | } |
85 | 79 | ||
86 | static void clps711xuart_enable_ms(struct uart_port *port) | 80 | static void uart_clps711x_enable_ms(struct uart_port *port) |
87 | { | 81 | { |
82 | /* Do nothing */ | ||
88 | } | 83 | } |
89 | 84 | ||
90 | static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) | 85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) |
91 | { | 86 | { |
92 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
93 | struct tty_struct *tty = port->state->port.tty; | 88 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); |
94 | unsigned int status, ch, flg; | 89 | unsigned int status, ch, flg; |
95 | 90 | ||
96 | status = clps_readl(SYSFLG(port)); | 91 | if (!tty) |
97 | while (!(status & SYSFLG_URXFE)) { | 92 | return IRQ_HANDLED; |
98 | ch = clps_readl(UARTDR(port)); | ||
99 | 93 | ||
100 | port->icount.rx++; | 94 | for (;;) { |
95 | status = clps_readl(SYSFLG(port)); | ||
96 | if (status & SYSFLG_URXFE) | ||
97 | break; | ||
98 | |||
99 | ch = clps_readw(UARTDR(port)); | ||
100 | status = ch & (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR); | ||
101 | ch &= 0xff; | ||
101 | 102 | ||
103 | port->icount.rx++; | ||
102 | flg = TTY_NORMAL; | 104 | flg = TTY_NORMAL; |
103 | 105 | ||
104 | /* | 106 | if (unlikely(status)) { |
105 | * Note that the error handling code is | 107 | if (status & UARTDR_PARERR) |
106 | * out of the main execution path | ||
107 | */ | ||
108 | if (unlikely(ch & UART_ANY_ERR)) { | ||
109 | if (ch & UARTDR_PARERR) | ||
110 | port->icount.parity++; | 108 | port->icount.parity++; |
111 | else if (ch & UARTDR_FRMERR) | 109 | else if (status & UARTDR_FRMERR) |
112 | port->icount.frame++; | 110 | port->icount.frame++; |
113 | if (ch & UARTDR_OVERR) | 111 | else if (status & UARTDR_OVERR) |
114 | port->icount.overrun++; | 112 | port->icount.overrun++; |
115 | 113 | ||
116 | ch &= port->read_status_mask; | 114 | status &= port->read_status_mask; |
117 | 115 | ||
118 | if (ch & UARTDR_PARERR) | 116 | if (status & UARTDR_PARERR) |
119 | flg = TTY_PARITY; | 117 | flg = TTY_PARITY; |
120 | else if (ch & UARTDR_FRMERR) | 118 | else if (status & UARTDR_FRMERR) |
121 | flg = TTY_FRAME; | 119 | flg = TTY_FRAME; |
122 | 120 | else if (status & UARTDR_OVERR) | |
123 | #ifdef SUPPORT_SYSRQ | 121 | flg = TTY_OVERRUN; |
124 | port->sysrq = 0; | ||
125 | #endif | ||
126 | } | 122 | } |
127 | 123 | ||
128 | if (uart_handle_sysrq_char(port, ch)) | 124 | if (uart_handle_sysrq_char(port, ch)) |
129 | goto ignore_char; | 125 | continue; |
130 | 126 | ||
131 | /* | 127 | if (status & port->ignore_status_mask) |
132 | * CHECK: does overrun affect the current character? | 128 | continue; |
133 | * ASSUMPTION: it does not. | ||
134 | */ | ||
135 | uart_insert_char(port, ch, UARTDR_OVERR, ch, flg); | ||
136 | 129 | ||
137 | ignore_char: | 130 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); |
138 | status = clps_readl(SYSFLG(port)); | ||
139 | } | 131 | } |
132 | |||
140 | tty_flip_buffer_push(tty); | 133 | tty_flip_buffer_push(tty); |
134 | |||
135 | tty_kref_put(tty); | ||
136 | |||
141 | return IRQ_HANDLED; | 137 | return IRQ_HANDLED; |
142 | } | 138 | } |
143 | 139 | ||
144 | static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) | 140 | static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id) |
145 | { | 141 | { |
146 | struct uart_port *port = dev_id; | 142 | struct uart_port *port = dev_id; |
143 | struct clps711x_port *s = dev_get_drvdata(port->dev); | ||
147 | struct circ_buf *xmit = &port->state->xmit; | 144 | struct circ_buf *xmit = &port->state->xmit; |
148 | int count; | ||
149 | 145 | ||
150 | if (port->x_char) { | 146 | if (port->x_char) { |
151 | clps_writel(port->x_char, UARTDR(port)); | 147 | clps_writew(port->x_char, UARTDR(port)); |
152 | port->icount.tx++; | 148 | port->icount.tx++; |
153 | port->x_char = 0; | 149 | port->x_char = 0; |
154 | return IRQ_HANDLED; | 150 | return IRQ_HANDLED; |
155 | } | 151 | } |
156 | 152 | ||
157 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 153 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
158 | goto disable_tx_irq; | 154 | disable_irq_nosync(TX_IRQ(port)); |
155 | s->tx_enabled[port->line] = 0; | ||
156 | return IRQ_HANDLED; | ||
157 | } | ||
159 | 158 | ||
160 | count = port->fifosize >> 1; | 159 | while (!uart_circ_empty(xmit)) { |
161 | do { | 160 | clps_writew(xmit->buf[xmit->tail], UARTDR(port)); |
162 | clps_writel(xmit->buf[xmit->tail], UARTDR(port)); | ||
163 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 161 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
164 | port->icount.tx++; | 162 | port->icount.tx++; |
165 | if (uart_circ_empty(xmit)) | 163 | if (clps_readl(SYSFLG(port) & SYSFLG_UTXFF)) |
166 | break; | 164 | break; |
167 | } while (--count > 0); | 165 | } |
168 | 166 | ||
169 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 167 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
170 | uart_write_wakeup(port); | 168 | uart_write_wakeup(port); |
171 | 169 | ||
172 | if (uart_circ_empty(xmit)) { | ||
173 | disable_tx_irq: | ||
174 | disable_irq_nosync(TX_IRQ(port)); | ||
175 | tx_enabled(port) = 0; | ||
176 | } | ||
177 | |||
178 | return IRQ_HANDLED; | 170 | return IRQ_HANDLED; |
179 | } | 171 | } |
180 | 172 | ||
181 | static unsigned int clps711xuart_tx_empty(struct uart_port *port) | 173 | static unsigned int uart_clps711x_tx_empty(struct uart_port *port) |
182 | { | 174 | { |
183 | unsigned int status = clps_readl(SYSFLG(port)); | 175 | return (clps_readl(SYSFLG(port) & SYSFLG_UBUSY)) ? 0 : TIOCSER_TEMT; |
184 | return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT; | ||
185 | } | 176 | } |
186 | 177 | ||
187 | static unsigned int clps711xuart_get_mctrl(struct uart_port *port) | 178 | static unsigned int uart_clps711x_get_mctrl(struct uart_port *port) |
188 | { | 179 | { |
189 | unsigned int port_addr; | 180 | unsigned int status, result = 0; |
190 | unsigned int result = 0; | ||
191 | unsigned int status; | ||
192 | 181 | ||
193 | port_addr = SYSFLG(port); | 182 | if (port->line == 0) { |
194 | if (port_addr == SYSFLG1) { | ||
195 | status = clps_readl(SYSFLG1); | 183 | status = clps_readl(SYSFLG1); |
196 | if (status & SYSFLG1_DCD) | 184 | if (status & SYSFLG1_DCD) |
197 | result |= TIOCM_CAR; | 185 | result |= TIOCM_CAR; |
@@ -199,104 +187,86 @@ static unsigned int clps711xuart_get_mctrl(struct uart_port *port) | |||
199 | result |= TIOCM_DSR; | 187 | result |= TIOCM_DSR; |
200 | if (status & SYSFLG1_CTS) | 188 | if (status & SYSFLG1_CTS) |
201 | result |= TIOCM_CTS; | 189 | result |= TIOCM_CTS; |
202 | } | 190 | } else |
191 | result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | ||
203 | 192 | ||
204 | return result; | 193 | return result; |
205 | } | 194 | } |
206 | 195 | ||
207 | static void | 196 | static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl) |
208 | clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl) | ||
209 | { | 197 | { |
198 | /* Do nothing */ | ||
210 | } | 199 | } |
211 | 200 | ||
212 | static void clps711xuart_break_ctl(struct uart_port *port, int break_state) | 201 | static void uart_clps711x_break_ctl(struct uart_port *port, int break_state) |
213 | { | 202 | { |
214 | unsigned long flags; | 203 | unsigned long flags; |
215 | unsigned int ubrlcr; | 204 | unsigned int ubrlcr; |
216 | 205 | ||
217 | spin_lock_irqsave(&port->lock, flags); | 206 | spin_lock_irqsave(&port->lock, flags); |
207 | |||
218 | ubrlcr = clps_readl(UBRLCR(port)); | 208 | ubrlcr = clps_readl(UBRLCR(port)); |
219 | if (break_state == -1) | 209 | if (break_state) |
220 | ubrlcr |= UBRLCR_BREAK; | 210 | ubrlcr |= UBRLCR_BREAK; |
221 | else | 211 | else |
222 | ubrlcr &= ~UBRLCR_BREAK; | 212 | ubrlcr &= ~UBRLCR_BREAK; |
223 | clps_writel(ubrlcr, UBRLCR(port)); | 213 | clps_writel(ubrlcr, UBRLCR(port)); |
214 | |||
224 | spin_unlock_irqrestore(&port->lock, flags); | 215 | spin_unlock_irqrestore(&port->lock, flags); |
225 | } | 216 | } |
226 | 217 | ||
227 | static int clps711xuart_startup(struct uart_port *port) | 218 | static int uart_clps711x_startup(struct uart_port *port) |
228 | { | 219 | { |
229 | unsigned int syscon; | 220 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
230 | int retval; | 221 | int ret; |
231 | 222 | ||
232 | tx_enabled(port) = 1; | 223 | s->tx_enabled[port->line] = 1; |
233 | 224 | /* Allocate the IRQs */ | |
234 | /* | 225 | ret = devm_request_irq(port->dev, TX_IRQ(port), uart_clps711x_int_tx, |
235 | * Allocate the IRQs | 226 | 0, UART_CLPS711X_NAME " TX", port); |
236 | */ | 227 | if (ret) |
237 | retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0, | 228 | return ret; |
238 | "clps711xuart_tx", port); | 229 | |
239 | if (retval) | 230 | ret = devm_request_irq(port->dev, RX_IRQ(port), uart_clps711x_int_rx, |
240 | return retval; | 231 | 0, UART_CLPS711X_NAME " RX", port); |
241 | 232 | if (ret) { | |
242 | retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0, | 233 | devm_free_irq(port->dev, TX_IRQ(port), port); |
243 | "clps711xuart_rx", port); | 234 | return ret; |
244 | if (retval) { | ||
245 | free_irq(TX_IRQ(port), port); | ||
246 | return retval; | ||
247 | } | 235 | } |
248 | 236 | ||
249 | /* | 237 | /* Disable break */ |
250 | * enable the port | 238 | clps_writel(clps_readl(UBRLCR(port)) & ~UBRLCR_BREAK, UBRLCR(port)); |
251 | */ | 239 | |
252 | syscon = clps_readl(SYSCON(port)); | 240 | /* Enable the port */ |
253 | syscon |= SYSCON_UARTEN; | 241 | clps_writel(clps_readl(SYSCON(port)) | SYSCON_UARTEN, SYSCON(port)); |
254 | clps_writel(syscon, SYSCON(port)); | ||
255 | 242 | ||
256 | return 0; | 243 | return 0; |
257 | } | 244 | } |
258 | 245 | ||
259 | static void clps711xuart_shutdown(struct uart_port *port) | 246 | static void uart_clps711x_shutdown(struct uart_port *port) |
260 | { | 247 | { |
261 | unsigned int ubrlcr, syscon; | 248 | /* Free the interrupts */ |
249 | devm_free_irq(port->dev, TX_IRQ(port), port); | ||
250 | devm_free_irq(port->dev, RX_IRQ(port), port); | ||
262 | 251 | ||
263 | /* | 252 | /* Disable the port */ |
264 | * Free the interrupt | 253 | clps_writel(clps_readl(SYSCON(port)) & ~SYSCON_UARTEN, SYSCON(port)); |
265 | */ | ||
266 | free_irq(TX_IRQ(port), port); /* TX interrupt */ | ||
267 | free_irq(RX_IRQ(port), port); /* RX interrupt */ | ||
268 | |||
269 | /* | ||
270 | * disable the port | ||
271 | */ | ||
272 | syscon = clps_readl(SYSCON(port)); | ||
273 | syscon &= ~SYSCON_UARTEN; | ||
274 | clps_writel(syscon, SYSCON(port)); | ||
275 | |||
276 | /* | ||
277 | * disable break condition and fifos | ||
278 | */ | ||
279 | ubrlcr = clps_readl(UBRLCR(port)); | ||
280 | ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK); | ||
281 | clps_writel(ubrlcr, UBRLCR(port)); | ||
282 | } | 254 | } |
283 | 255 | ||
284 | static void | 256 | static void uart_clps711x_set_termios(struct uart_port *port, |
285 | clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, | 257 | struct ktermios *termios, |
286 | struct ktermios *old) | 258 | struct ktermios *old) |
287 | { | 259 | { |
288 | unsigned int ubrlcr, baud, quot; | 260 | unsigned int ubrlcr, baud, quot; |
289 | unsigned long flags; | 261 | unsigned long flags; |
290 | 262 | ||
291 | /* | 263 | /* Mask termios capabilities we don't support */ |
292 | * We don't implement CREAD. | 264 | termios->c_cflag &= ~CMSPAR; |
293 | */ | 265 | termios->c_iflag &= ~(BRKINT | IGNBRK); |
294 | termios->c_cflag |= CREAD; | ||
295 | 266 | ||
296 | /* | 267 | /* Ask the core to calculate the divisor for us */ |
297 | * Ask the core to calculate the divisor for us. | 268 | baud = uart_get_baud_rate(port, termios, old, port->uartclk / 4096, |
298 | */ | 269 | port->uartclk / 16); |
299 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | ||
300 | quot = uart_get_divisor(port, baud); | 270 | quot = uart_get_divisor(port, baud); |
301 | 271 | ||
302 | switch (termios->c_cflag & CSIZE) { | 272 | switch (termios->c_cflag & CSIZE) { |
@@ -309,160 +279,117 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, | |||
309 | case CS7: | 279 | case CS7: |
310 | ubrlcr = UBRLCR_WRDLEN7; | 280 | ubrlcr = UBRLCR_WRDLEN7; |
311 | break; | 281 | break; |
312 | default: // CS8 | 282 | case CS8: |
283 | default: | ||
313 | ubrlcr = UBRLCR_WRDLEN8; | 284 | ubrlcr = UBRLCR_WRDLEN8; |
314 | break; | 285 | break; |
315 | } | 286 | } |
287 | |||
316 | if (termios->c_cflag & CSTOPB) | 288 | if (termios->c_cflag & CSTOPB) |
317 | ubrlcr |= UBRLCR_XSTOP; | 289 | ubrlcr |= UBRLCR_XSTOP; |
290 | |||
318 | if (termios->c_cflag & PARENB) { | 291 | if (termios->c_cflag & PARENB) { |
319 | ubrlcr |= UBRLCR_PRTEN; | 292 | ubrlcr |= UBRLCR_PRTEN; |
320 | if (!(termios->c_cflag & PARODD)) | 293 | if (!(termios->c_cflag & PARODD)) |
321 | ubrlcr |= UBRLCR_EVENPRT; | 294 | ubrlcr |= UBRLCR_EVENPRT; |
322 | } | 295 | } |
323 | if (port->fifosize > 1) | ||
324 | ubrlcr |= UBRLCR_FIFOEN; | ||
325 | 296 | ||
326 | spin_lock_irqsave(&port->lock, flags); | 297 | /* Enable FIFO */ |
298 | ubrlcr |= UBRLCR_FIFOEN; | ||
327 | 299 | ||
328 | /* | 300 | spin_lock_irqsave(&port->lock, flags); |
329 | * Update the per-port timeout. | ||
330 | */ | ||
331 | uart_update_timeout(port, termios->c_cflag, baud); | ||
332 | 301 | ||
302 | /* Set read status mask */ | ||
333 | port->read_status_mask = UARTDR_OVERR; | 303 | port->read_status_mask = UARTDR_OVERR; |
334 | if (termios->c_iflag & INPCK) | 304 | if (termios->c_iflag & INPCK) |
335 | port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR; | 305 | port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR; |
336 | 306 | ||
337 | /* | 307 | /* Set status ignore mask */ |
338 | * Characters to ignore | ||
339 | */ | ||
340 | port->ignore_status_mask = 0; | 308 | port->ignore_status_mask = 0; |
341 | if (termios->c_iflag & IGNPAR) | 309 | if (!(termios->c_cflag & CREAD)) |
342 | port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR; | 310 | port->ignore_status_mask |= UARTDR_OVERR | UARTDR_PARERR | |
343 | if (termios->c_iflag & IGNBRK) { | 311 | UARTDR_FRMERR; |
344 | /* | ||
345 | * If we're ignoring parity and break indicators, | ||
346 | * ignore overruns to (for real raw support). | ||
347 | */ | ||
348 | if (termios->c_iflag & IGNPAR) | ||
349 | port->ignore_status_mask |= UARTDR_OVERR; | ||
350 | } | ||
351 | 312 | ||
352 | quot -= 1; | 313 | uart_update_timeout(port, termios->c_cflag, baud); |
353 | 314 | ||
354 | clps_writel(ubrlcr | quot, UBRLCR(port)); | 315 | clps_writel(ubrlcr | (quot - 1), UBRLCR(port)); |
355 | 316 | ||
356 | spin_unlock_irqrestore(&port->lock, flags); | 317 | spin_unlock_irqrestore(&port->lock, flags); |
357 | } | 318 | } |
358 | 319 | ||
359 | static const char *clps711xuart_type(struct uart_port *port) | 320 | static const char *uart_clps711x_type(struct uart_port *port) |
360 | { | 321 | { |
361 | return port->type == PORT_CLPS711X ? "CLPS711x" : NULL; | 322 | return (port->type == PORT_CLPS711X) ? "CLPS711X" : NULL; |
362 | } | 323 | } |
363 | 324 | ||
364 | /* | 325 | static void uart_clps711x_config_port(struct uart_port *port, int flags) |
365 | * Configure/autoconfigure the port. | ||
366 | */ | ||
367 | static void clps711xuart_config_port(struct uart_port *port, int flags) | ||
368 | { | 326 | { |
369 | if (flags & UART_CONFIG_TYPE) | 327 | if (flags & UART_CONFIG_TYPE) |
370 | port->type = PORT_CLPS711X; | 328 | port->type = PORT_CLPS711X; |
371 | } | 329 | } |
372 | 330 | ||
373 | static void clps711xuart_release_port(struct uart_port *port) | 331 | static void uart_clps711x_release_port(struct uart_port *port) |
374 | { | 332 | { |
333 | /* Do nothing */ | ||
375 | } | 334 | } |
376 | 335 | ||
377 | static int clps711xuart_request_port(struct uart_port *port) | 336 | static int uart_clps711x_request_port(struct uart_port *port) |
378 | { | 337 | { |
338 | /* Do nothing */ | ||
379 | return 0; | 339 | return 0; |
380 | } | 340 | } |
381 | 341 | ||
382 | static struct uart_ops clps711x_pops = { | 342 | static const struct uart_ops uart_clps711x_ops = { |
383 | .tx_empty = clps711xuart_tx_empty, | 343 | .tx_empty = uart_clps711x_tx_empty, |
384 | .set_mctrl = clps711xuart_set_mctrl_null, | 344 | .set_mctrl = uart_clps711x_set_mctrl, |
385 | .get_mctrl = clps711xuart_get_mctrl, | 345 | .get_mctrl = uart_clps711x_get_mctrl, |
386 | .stop_tx = clps711xuart_stop_tx, | 346 | .stop_tx = uart_clps711x_stop_tx, |
387 | .start_tx = clps711xuart_start_tx, | 347 | .start_tx = uart_clps711x_start_tx, |
388 | .stop_rx = clps711xuart_stop_rx, | 348 | .stop_rx = uart_clps711x_stop_rx, |
389 | .enable_ms = clps711xuart_enable_ms, | 349 | .enable_ms = uart_clps711x_enable_ms, |
390 | .break_ctl = clps711xuart_break_ctl, | 350 | .break_ctl = uart_clps711x_break_ctl, |
391 | .startup = clps711xuart_startup, | 351 | .startup = uart_clps711x_startup, |
392 | .shutdown = clps711xuart_shutdown, | 352 | .shutdown = uart_clps711x_shutdown, |
393 | .set_termios = clps711xuart_set_termios, | 353 | .set_termios = uart_clps711x_set_termios, |
394 | .type = clps711xuart_type, | 354 | .type = uart_clps711x_type, |
395 | .config_port = clps711xuart_config_port, | 355 | .config_port = uart_clps711x_config_port, |
396 | .release_port = clps711xuart_release_port, | 356 | .release_port = uart_clps711x_release_port, |
397 | .request_port = clps711xuart_request_port, | 357 | .request_port = uart_clps711x_request_port, |
398 | }; | ||
399 | |||
400 | static struct uart_port clps711x_ports[UART_NR] = { | ||
401 | { | ||
402 | .iobase = SYSCON1, | ||
403 | .irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */ | ||
404 | .uartclk = 3686400, | ||
405 | .fifosize = 16, | ||
406 | .ops = &clps711x_pops, | ||
407 | .line = 0, | ||
408 | .flags = UPF_BOOT_AUTOCONF, | ||
409 | }, | ||
410 | { | ||
411 | .iobase = SYSCON2, | ||
412 | .irq = IRQ_UTXINT2, /* IRQ_URXINT2 */ | ||
413 | .uartclk = 3686400, | ||
414 | .fifosize = 16, | ||
415 | .ops = &clps711x_pops, | ||
416 | .line = 1, | ||
417 | .flags = UPF_BOOT_AUTOCONF, | ||
418 | } | ||
419 | }; | 358 | }; |
420 | 359 | ||
421 | #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE | 360 | #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE |
422 | static void clps711xuart_console_putchar(struct uart_port *port, int ch) | 361 | static void uart_clps711x_console_putchar(struct uart_port *port, int ch) |
423 | { | 362 | { |
424 | while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) | 363 | while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) |
425 | barrier(); | 364 | barrier(); |
426 | clps_writel(ch, UARTDR(port)); | 365 | |
366 | clps_writew(ch, UARTDR(port)); | ||
427 | } | 367 | } |
428 | 368 | ||
429 | /* | 369 | static void uart_clps711x_console_write(struct console *co, const char *c, |
430 | * Print a string to the serial port trying not to disturb | 370 | unsigned n) |
431 | * any possible real use of the port... | ||
432 | * | ||
433 | * The console_lock must be held when we get here. | ||
434 | * | ||
435 | * Note that this is called with interrupts already disabled | ||
436 | */ | ||
437 | static void | ||
438 | clps711xuart_console_write(struct console *co, const char *s, | ||
439 | unsigned int count) | ||
440 | { | 371 | { |
441 | struct uart_port *port = clps711x_ports + co->index; | 372 | struct clps711x_port *s = (struct clps711x_port *)co->data; |
442 | unsigned int status, syscon; | 373 | struct uart_port *port = &s->port[co->index]; |
374 | u32 syscon; | ||
443 | 375 | ||
444 | /* | 376 | /* Ensure that the port is enabled */ |
445 | * Ensure that the port is enabled. | ||
446 | */ | ||
447 | syscon = clps_readl(SYSCON(port)); | 377 | syscon = clps_readl(SYSCON(port)); |
448 | clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); | 378 | clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); |
449 | 379 | ||
450 | uart_console_write(port, s, count, clps711xuart_console_putchar); | 380 | uart_console_write(port, c, n, uart_clps711x_console_putchar); |
451 | 381 | ||
452 | /* | 382 | /* Wait for transmitter to become empty */ |
453 | * Finally, wait for transmitter to become empty | 383 | while (clps_readl(SYSFLG(port)) & SYSFLG_UBUSY) |
454 | * and restore the uart state. | 384 | barrier(); |
455 | */ | ||
456 | do { | ||
457 | status = clps_readl(SYSFLG(port)); | ||
458 | } while (status & SYSFLG_UBUSY); | ||
459 | 385 | ||
386 | /* Restore the uart state */ | ||
460 | clps_writel(syscon, SYSCON(port)); | 387 | clps_writel(syscon, SYSCON(port)); |
461 | } | 388 | } |
462 | 389 | ||
463 | static void __init | 390 | static void uart_clps711x_console_get_options(struct uart_port *port, |
464 | clps711xuart_console_get_options(struct uart_port *port, int *baud, | 391 | int *baud, int *parity, |
465 | int *parity, int *bits) | 392 | int *bits) |
466 | { | 393 | { |
467 | if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) { | 394 | if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) { |
468 | unsigned int ubrlcr, quot; | 395 | unsigned int ubrlcr, quot; |
@@ -487,92 +414,124 @@ clps711xuart_console_get_options(struct uart_port *port, int *baud, | |||
487 | } | 414 | } |
488 | } | 415 | } |
489 | 416 | ||
490 | static int __init clps711xuart_console_setup(struct console *co, char *options) | 417 | static int uart_clps711x_console_setup(struct console *co, char *options) |
491 | { | 418 | { |
492 | struct uart_port *port; | 419 | int baud = 38400, bits = 8, parity = 'n', flow = 'n'; |
493 | int baud = 38400; | 420 | struct clps711x_port *s = (struct clps711x_port *)co->data; |
494 | int bits = 8; | 421 | struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0]; |
495 | int parity = 'n'; | ||
496 | int flow = 'n'; | ||
497 | |||
498 | /* | ||
499 | * Check whether an invalid uart number has been specified, and | ||
500 | * if so, search for the first available port that does have | ||
501 | * console support. | ||
502 | */ | ||
503 | port = uart_get_console(clps711x_ports, UART_NR, co); | ||
504 | 422 | ||
505 | if (options) | 423 | if (options) |
506 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 424 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
507 | else | 425 | else |
508 | clps711xuart_console_get_options(port, &baud, &parity, &bits); | 426 | uart_clps711x_console_get_options(port, &baud, &parity, &bits); |
509 | 427 | ||
510 | return uart_set_options(port, co, baud, parity, bits, flow); | 428 | return uart_set_options(port, co, baud, parity, bits, flow); |
511 | } | 429 | } |
430 | #endif | ||
512 | 431 | ||
513 | static struct uart_driver clps711x_reg; | 432 | static int uart_clps711x_probe(struct platform_device *pdev) |
514 | static struct console clps711x_console = { | ||
515 | .name = "ttyCL", | ||
516 | .write = clps711xuart_console_write, | ||
517 | .device = uart_console_device, | ||
518 | .setup = clps711xuart_console_setup, | ||
519 | .flags = CON_PRINTBUFFER, | ||
520 | .index = -1, | ||
521 | .data = &clps711x_reg, | ||
522 | }; | ||
523 | |||
524 | static int __init clps711xuart_console_init(void) | ||
525 | { | 433 | { |
526 | register_console(&clps711x_console); | 434 | struct clps711x_port *s; |
527 | return 0; | 435 | int ret, i; |
528 | } | 436 | |
529 | console_initcall(clps711xuart_console_init); | 437 | s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL); |
438 | if (!s) { | ||
439 | dev_err(&pdev->dev, "Error allocating port structure\n"); | ||
440 | return -ENOMEM; | ||
441 | } | ||
442 | platform_set_drvdata(pdev, s); | ||
530 | 443 | ||
531 | #define CLPS711X_CONSOLE &clps711x_console | 444 | s->uart_clk = devm_clk_get(&pdev->dev, "uart"); |
532 | #else | 445 | if (IS_ERR(s->uart_clk)) { |
533 | #define CLPS711X_CONSOLE NULL | 446 | dev_err(&pdev->dev, "Can't get UART clocks\n"); |
447 | ret = PTR_ERR(s->uart_clk); | ||
448 | goto err_out; | ||
449 | } | ||
450 | |||
451 | s->uart.owner = THIS_MODULE; | ||
452 | s->uart.dev_name = "ttyCL"; | ||
453 | s->uart.major = UART_CLPS711X_MAJOR; | ||
454 | s->uart.minor = UART_CLPS711X_MINOR; | ||
455 | s->uart.nr = UART_CLPS711X_NR; | ||
456 | #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE | ||
457 | s->uart.cons = &s->console; | ||
458 | s->uart.cons->device = uart_console_device; | ||
459 | s->uart.cons->write = uart_clps711x_console_write; | ||
460 | s->uart.cons->setup = uart_clps711x_console_setup; | ||
461 | s->uart.cons->flags = CON_PRINTBUFFER; | ||
462 | s->uart.cons->index = -1; | ||
463 | s->uart.cons->data = s; | ||
464 | strcpy(s->uart.cons->name, "ttyCL"); | ||
534 | #endif | 465 | #endif |
466 | ret = uart_register_driver(&s->uart); | ||
467 | if (ret) { | ||
468 | dev_err(&pdev->dev, "Registering UART driver failed\n"); | ||
469 | devm_clk_put(&pdev->dev, s->uart_clk); | ||
470 | goto err_out; | ||
471 | } | ||
535 | 472 | ||
536 | static struct uart_driver clps711x_reg = { | 473 | for (i = 0; i < UART_CLPS711X_NR; i++) { |
537 | .driver_name = "ttyCL", | 474 | s->port[i].line = i; |
538 | .dev_name = "ttyCL", | 475 | s->port[i].dev = &pdev->dev; |
539 | .major = SERIAL_CLPS711X_MAJOR, | 476 | s->port[i].irq = TX_IRQ(&s->port[i]); |
540 | .minor = SERIAL_CLPS711X_MINOR, | 477 | s->port[i].iobase = SYSCON(&s->port[i]); |
541 | .nr = UART_NR, | 478 | s->port[i].type = PORT_CLPS711X; |
479 | s->port[i].fifosize = 16; | ||
480 | s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; | ||
481 | s->port[i].uartclk = clk_get_rate(s->uart_clk); | ||
482 | s->port[i].ops = &uart_clps711x_ops; | ||
483 | WARN_ON(uart_add_one_port(&s->uart, &s->port[i])); | ||
484 | } | ||
542 | 485 | ||
543 | .cons = CLPS711X_CONSOLE, | 486 | return 0; |
544 | }; | ||
545 | 487 | ||
546 | static int __init clps711xuart_init(void) | 488 | err_out: |
547 | { | 489 | platform_set_drvdata(pdev, NULL); |
548 | int ret, i; | ||
549 | 490 | ||
550 | printk(KERN_INFO "Serial: CLPS711x driver\n"); | 491 | return ret; |
492 | } | ||
551 | 493 | ||
552 | ret = uart_register_driver(&clps711x_reg); | 494 | static int uart_clps711x_remove(struct platform_device *pdev) |
553 | if (ret) | 495 | { |
554 | return ret; | 496 | struct clps711x_port *s = platform_get_drvdata(pdev); |
497 | int i; | ||
555 | 498 | ||
556 | for (i = 0; i < UART_NR; i++) | 499 | for (i = 0; i < UART_CLPS711X_NR; i++) |
557 | uart_add_one_port(&clps711x_reg, &clps711x_ports[i]); | 500 | uart_remove_one_port(&s->uart, &s->port[i]); |
501 | |||
502 | devm_clk_put(&pdev->dev, s->uart_clk); | ||
503 | uart_unregister_driver(&s->uart); | ||
504 | platform_set_drvdata(pdev, NULL); | ||
558 | 505 | ||
559 | return 0; | 506 | return 0; |
560 | } | 507 | } |
561 | 508 | ||
562 | static void __exit clps711xuart_exit(void) | 509 | static struct platform_driver clps711x_uart_driver = { |
563 | { | 510 | .driver = { |
564 | int i; | 511 | .name = UART_CLPS711X_NAME, |
512 | .owner = THIS_MODULE, | ||
513 | }, | ||
514 | .probe = uart_clps711x_probe, | ||
515 | .remove = uart_clps711x_remove, | ||
516 | }; | ||
517 | module_platform_driver(clps711x_uart_driver); | ||
565 | 518 | ||
566 | for (i = 0; i < UART_NR; i++) | 519 | static struct platform_device clps711x_uart_device = { |
567 | uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]); | 520 | .name = UART_CLPS711X_NAME, |
521 | }; | ||
568 | 522 | ||
569 | uart_unregister_driver(&clps711x_reg); | 523 | static int __init uart_clps711x_init(void) |
524 | { | ||
525 | return platform_device_register(&clps711x_uart_device); | ||
570 | } | 526 | } |
527 | module_init(uart_clps711x_init); | ||
571 | 528 | ||
572 | module_init(clps711xuart_init); | 529 | static void __exit uart_clps711x_exit(void) |
573 | module_exit(clps711xuart_exit); | 530 | { |
531 | platform_device_unregister(&clps711x_uart_device); | ||
532 | } | ||
533 | module_exit(uart_clps711x_exit); | ||
574 | 534 | ||
575 | MODULE_AUTHOR("Deep Blue Solutions Ltd"); | 535 | MODULE_AUTHOR("Deep Blue Solutions Ltd"); |
576 | MODULE_DESCRIPTION("CLPS-711x generic serial driver"); | 536 | MODULE_DESCRIPTION("CLPS711X serial driver"); |
577 | MODULE_LICENSE("GPL"); | 537 | MODULE_LICENSE("GPL"); |
578 | MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR); | ||
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index d0dd9194cecc..ad0caf176808 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c | |||
@@ -1373,7 +1373,7 @@ static struct uart_driver cpm_reg = { | |||
1373 | 1373 | ||
1374 | static int probe_index; | 1374 | static int probe_index; |
1375 | 1375 | ||
1376 | static int __devinit cpm_uart_probe(struct platform_device *ofdev) | 1376 | static int cpm_uart_probe(struct platform_device *ofdev) |
1377 | { | 1377 | { |
1378 | int index = probe_index++; | 1378 | int index = probe_index++; |
1379 | struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; | 1379 | struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; |
@@ -1396,7 +1396,7 @@ static int __devinit cpm_uart_probe(struct platform_device *ofdev) | |||
1396 | return uart_add_one_port(&cpm_reg, &pinfo->port); | 1396 | return uart_add_one_port(&cpm_reg, &pinfo->port); |
1397 | } | 1397 | } |
1398 | 1398 | ||
1399 | static int __devexit cpm_uart_remove(struct platform_device *ofdev) | 1399 | static int cpm_uart_remove(struct platform_device *ofdev) |
1400 | { | 1400 | { |
1401 | struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev); | 1401 | struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev); |
1402 | return uart_remove_one_port(&cpm_reg, &pinfo->port); | 1402 | return uart_remove_one_port(&cpm_reg, &pinfo->port); |
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index 615e46470491..a8cbb2670521 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -690,7 +690,7 @@ static int efm32_uart_probe_dt(struct platform_device *pdev, | |||
690 | 690 | ||
691 | } | 691 | } |
692 | 692 | ||
693 | static int __devinit efm32_uart_probe(struct platform_device *pdev) | 693 | static int efm32_uart_probe(struct platform_device *pdev) |
694 | { | 694 | { |
695 | struct efm32_uart_port *efm_port; | 695 | struct efm32_uart_port *efm_port; |
696 | struct resource *res; | 696 | struct resource *res; |
@@ -764,7 +764,7 @@ err_get_base: | |||
764 | return ret; | 764 | return ret; |
765 | } | 765 | } |
766 | 766 | ||
767 | static int __devexit efm32_uart_remove(struct platform_device *pdev) | 767 | static int efm32_uart_remove(struct platform_device *pdev) |
768 | { | 768 | { |
769 | struct efm32_uart_port *efm_port = platform_get_drvdata(pdev); | 769 | struct efm32_uart_port *efm_port = platform_get_drvdata(pdev); |
770 | 770 | ||
@@ -791,7 +791,7 @@ MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids); | |||
791 | 791 | ||
792 | static struct platform_driver efm32_uart_driver = { | 792 | static struct platform_driver efm32_uart_driver = { |
793 | .probe = efm32_uart_probe, | 793 | .probe = efm32_uart_probe, |
794 | .remove = __devexit_p(efm32_uart_remove), | 794 | .remove = efm32_uart_remove, |
795 | 795 | ||
796 | .driver = { | 796 | .driver = { |
797 | .name = DRIVER_NAME, | 797 | .name = DRIVER_NAME, |
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index defc4e3393a3..6197a69adb4d 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c | |||
@@ -175,7 +175,7 @@ static void free_port_memory(struct icom_port *icom_port) | |||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | static int __devinit get_port_memory(struct icom_port *icom_port) | 178 | static int get_port_memory(struct icom_port *icom_port) |
179 | { | 179 | { |
180 | int index; | 180 | int index; |
181 | unsigned long stgAddr; | 181 | unsigned long stgAddr; |
@@ -1314,7 +1314,7 @@ static struct uart_driver icom_uart_driver = { | |||
1314 | .cons = ICOM_CONSOLE, | 1314 | .cons = ICOM_CONSOLE, |
1315 | }; | 1315 | }; |
1316 | 1316 | ||
1317 | static int __devinit icom_init_ports(struct icom_adapter *icom_adapter) | 1317 | static int icom_init_ports(struct icom_adapter *icom_adapter) |
1318 | { | 1318 | { |
1319 | u32 subsystem_id = icom_adapter->subsystem_id; | 1319 | u32 subsystem_id = icom_adapter->subsystem_id; |
1320 | int i; | 1320 | int i; |
@@ -1381,7 +1381,7 @@ static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *i | |||
1381 | 0x8024 + 2 - 2 * (icom_port->port - 2); | 1381 | 0x8024 + 2 - 2 * (icom_port->port - 2); |
1382 | } | 1382 | } |
1383 | } | 1383 | } |
1384 | static int __devinit icom_load_ports(struct icom_adapter *icom_adapter) | 1384 | static int icom_load_ports(struct icom_adapter *icom_adapter) |
1385 | { | 1385 | { |
1386 | struct icom_port *icom_port; | 1386 | struct icom_port *icom_port; |
1387 | int port_num; | 1387 | int port_num; |
@@ -1407,7 +1407,7 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter) | |||
1407 | return 0; | 1407 | return 0; |
1408 | } | 1408 | } |
1409 | 1409 | ||
1410 | static int __devinit icom_alloc_adapter(struct icom_adapter | 1410 | static int icom_alloc_adapter(struct icom_adapter |
1411 | **icom_adapter_ref) | 1411 | **icom_adapter_ref) |
1412 | { | 1412 | { |
1413 | int adapter_count = 0; | 1413 | int adapter_count = 0; |
@@ -1487,7 +1487,7 @@ static void icom_kref_release(struct kref *kref) | |||
1487 | icom_remove_adapter(icom_adapter); | 1487 | icom_remove_adapter(icom_adapter); |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | static int __devinit icom_probe(struct pci_dev *dev, | 1490 | static int icom_probe(struct pci_dev *dev, |
1491 | const struct pci_device_id *ent) | 1491 | const struct pci_device_id *ent) |
1492 | { | 1492 | { |
1493 | int index; | 1493 | int index; |
@@ -1596,7 +1596,7 @@ probe_exit0: | |||
1596 | return retval; | 1596 | return retval; |
1597 | } | 1597 | } |
1598 | 1598 | ||
1599 | static void __devexit icom_remove(struct pci_dev *dev) | 1599 | static void icom_remove(struct pci_dev *dev) |
1600 | { | 1600 | { |
1601 | struct icom_adapter *icom_adapter; | 1601 | struct icom_adapter *icom_adapter; |
1602 | struct list_head *tmp; | 1602 | struct list_head *tmp; |
@@ -1617,7 +1617,7 @@ static struct pci_driver icom_pci_driver = { | |||
1617 | .name = ICOM_DRIVER_NAME, | 1617 | .name = ICOM_DRIVER_NAME, |
1618 | .id_table = icom_pci_table, | 1618 | .id_table = icom_pci_table, |
1619 | .probe = icom_probe, | 1619 | .probe = icom_probe, |
1620 | .remove = __devexit_p(icom_remove), | 1620 | .remove = icom_remove, |
1621 | }; | 1621 | }; |
1622 | 1622 | ||
1623 | static int __init icom_init(void) | 1623 | static int __init icom_init(void) |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 5b9bc19ed134..675d94ab0aff 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -60,20 +60,27 @@ | |||
60 | #include <linux/pm_runtime.h> | 60 | #include <linux/pm_runtime.h> |
61 | #include <linux/spi/ifx_modem.h> | 61 | #include <linux/spi/ifx_modem.h> |
62 | #include <linux/delay.h> | 62 | #include <linux/delay.h> |
63 | #include <linux/reboot.h> | ||
63 | 64 | ||
64 | #include "ifx6x60.h" | 65 | #include "ifx6x60.h" |
65 | 66 | ||
66 | #define IFX_SPI_MORE_MASK 0x10 | 67 | #define IFX_SPI_MORE_MASK 0x10 |
67 | #define IFX_SPI_MORE_BIT 12 /* bit position in u16 */ | 68 | #define IFX_SPI_MORE_BIT 4 /* bit position in u8 */ |
68 | #define IFX_SPI_CTS_BIT 13 /* bit position in u16 */ | 69 | #define IFX_SPI_CTS_BIT 6 /* bit position in u8 */ |
69 | #define IFX_SPI_MODE SPI_MODE_1 | 70 | #define IFX_SPI_MODE SPI_MODE_1 |
70 | #define IFX_SPI_TTY_ID 0 | 71 | #define IFX_SPI_TTY_ID 0 |
71 | #define IFX_SPI_TIMEOUT_SEC 2 | 72 | #define IFX_SPI_TIMEOUT_SEC 2 |
72 | #define IFX_SPI_HEADER_0 (-1) | 73 | #define IFX_SPI_HEADER_0 (-1) |
73 | #define IFX_SPI_HEADER_F (-2) | 74 | #define IFX_SPI_HEADER_F (-2) |
74 | 75 | ||
76 | #define PO_POST_DELAY 200 | ||
77 | #define IFX_MDM_RST_PMU 4 | ||
78 | |||
75 | /* forward reference */ | 79 | /* forward reference */ |
76 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev); | 80 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev); |
81 | static int ifx_modem_reboot_callback(struct notifier_block *nfb, | ||
82 | unsigned long event, void *data); | ||
83 | static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev); | ||
77 | 84 | ||
78 | /* local variables */ | 85 | /* local variables */ |
79 | static int spi_bpw = 16; /* 8, 16 or 32 bit word length */ | 86 | static int spi_bpw = 16; /* 8, 16 or 32 bit word length */ |
@@ -81,6 +88,29 @@ static struct tty_driver *tty_drv; | |||
81 | static struct ifx_spi_device *saved_ifx_dev; | 88 | static struct ifx_spi_device *saved_ifx_dev; |
82 | static struct lock_class_key ifx_spi_key; | 89 | static struct lock_class_key ifx_spi_key; |
83 | 90 | ||
91 | static struct notifier_block ifx_modem_reboot_notifier_block = { | ||
92 | .notifier_call = ifx_modem_reboot_callback, | ||
93 | }; | ||
94 | |||
95 | static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev) | ||
96 | { | ||
97 | gpio_set_value(IFX_MDM_RST_PMU, 1); | ||
98 | msleep(PO_POST_DELAY); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int ifx_modem_reboot_callback(struct notifier_block *nfb, | ||
104 | unsigned long event, void *data) | ||
105 | { | ||
106 | if (saved_ifx_dev) | ||
107 | ifx_modem_power_off(saved_ifx_dev); | ||
108 | else | ||
109 | pr_warn("no ifx modem active;\n"); | ||
110 | |||
111 | return NOTIFY_OK; | ||
112 | } | ||
113 | |||
84 | /* GPIO/GPE settings */ | 114 | /* GPIO/GPE settings */ |
85 | 115 | ||
86 | /** | 116 | /** |
@@ -152,26 +182,67 @@ ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val) | |||
152 | } | 182 | } |
153 | 183 | ||
154 | /** | 184 | /** |
155 | * swap_buf | 185 | * swap_buf_8 |
156 | * @buf: our buffer | 186 | * @buf: our buffer |
157 | * @len : number of bytes (not words) in the buffer | 187 | * @len : number of bytes (not words) in the buffer |
158 | * @end: end of buffer | 188 | * @end: end of buffer |
159 | * | 189 | * |
160 | * Swap the contents of a buffer into big endian format | 190 | * Swap the contents of a buffer into big endian format |
161 | */ | 191 | */ |
162 | static inline void swap_buf(u16 *buf, int len, void *end) | 192 | static inline void swap_buf_8(unsigned char *buf, int len, void *end) |
193 | { | ||
194 | /* don't swap buffer if SPI word width is 8 bits */ | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * swap_buf_16 | ||
200 | * @buf: our buffer | ||
201 | * @len : number of bytes (not words) in the buffer | ||
202 | * @end: end of buffer | ||
203 | * | ||
204 | * Swap the contents of a buffer into big endian format | ||
205 | */ | ||
206 | static inline void swap_buf_16(unsigned char *buf, int len, void *end) | ||
163 | { | 207 | { |
164 | int n; | 208 | int n; |
165 | 209 | ||
210 | u16 *buf_16 = (u16 *)buf; | ||
166 | len = ((len + 1) >> 1); | 211 | len = ((len + 1) >> 1); |
167 | if ((void *)&buf[len] > end) { | 212 | if ((void *)&buf_16[len] > end) { |
168 | pr_err("swap_buf: swap exceeds boundary (%p > %p)!", | 213 | pr_err("swap_buf_16: swap exceeds boundary (%p > %p)!", |
169 | &buf[len], end); | 214 | &buf_16[len], end); |
215 | return; | ||
216 | } | ||
217 | for (n = 0; n < len; n++) { | ||
218 | *buf_16 = cpu_to_be16(*buf_16); | ||
219 | buf_16++; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * swap_buf_32 | ||
225 | * @buf: our buffer | ||
226 | * @len : number of bytes (not words) in the buffer | ||
227 | * @end: end of buffer | ||
228 | * | ||
229 | * Swap the contents of a buffer into big endian format | ||
230 | */ | ||
231 | static inline void swap_buf_32(unsigned char *buf, int len, void *end) | ||
232 | { | ||
233 | int n; | ||
234 | |||
235 | u32 *buf_32 = (u32 *)buf; | ||
236 | len = (len + 3) >> 2; | ||
237 | |||
238 | if ((void *)&buf_32[len] > end) { | ||
239 | pr_err("swap_buf_32: swap exceeds boundary (%p > %p)!\n", | ||
240 | &buf_32[len], end); | ||
170 | return; | 241 | return; |
171 | } | 242 | } |
172 | for (n = 0; n < len; n++) { | 243 | for (n = 0; n < len; n++) { |
173 | *buf = cpu_to_be16(*buf); | 244 | *buf_32 = cpu_to_be32(*buf_32); |
174 | buf++; | 245 | buf_32++; |
175 | } | 246 | } |
176 | } | 247 | } |
177 | 248 | ||
@@ -190,9 +261,7 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev) | |||
190 | if (!val) { | 261 | if (!val) { |
191 | if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING, | 262 | if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING, |
192 | &ifx_dev->flags)) { | 263 | &ifx_dev->flags)) { |
193 | ifx_dev->spi_timer.expires = | 264 | mod_timer(&ifx_dev->spi_timer,jiffies + IFX_SPI_TIMEOUT_SEC*HZ); |
194 | jiffies + IFX_SPI_TIMEOUT_SEC*HZ; | ||
195 | add_timer(&ifx_dev->spi_timer); | ||
196 | 265 | ||
197 | } | 266 | } |
198 | } | 267 | } |
@@ -449,7 +518,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) | |||
449 | tx_count-IFX_SPI_HEADER_OVERHEAD, | 518 | tx_count-IFX_SPI_HEADER_OVERHEAD, |
450 | ifx_dev->spi_more); | 519 | ifx_dev->spi_more); |
451 | /* swap actual data in the buffer */ | 520 | /* swap actual data in the buffer */ |
452 | swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count, | 521 | ifx_dev->swap_buf((ifx_dev->tx_buffer), tx_count, |
453 | &ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]); | 522 | &ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]); |
454 | return tx_count; | 523 | return tx_count; |
455 | } | 524 | } |
@@ -469,9 +538,17 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, | |||
469 | { | 538 | { |
470 | struct ifx_spi_device *ifx_dev = tty->driver_data; | 539 | struct ifx_spi_device *ifx_dev = tty->driver_data; |
471 | unsigned char *tmp_buf = (unsigned char *)buf; | 540 | unsigned char *tmp_buf = (unsigned char *)buf; |
472 | int tx_count = kfifo_in_locked(&ifx_dev->tx_fifo, tmp_buf, count, | 541 | unsigned long flags; |
473 | &ifx_dev->fifo_lock); | 542 | bool is_fifo_empty; |
474 | mrdy_assert(ifx_dev); | 543 | int tx_count; |
544 | |||
545 | spin_lock_irqsave(&ifx_dev->fifo_lock, flags); | ||
546 | is_fifo_empty = kfifo_is_empty(&ifx_dev->tx_fifo); | ||
547 | tx_count = kfifo_in(&ifx_dev->tx_fifo, tmp_buf, count); | ||
548 | spin_unlock_irqrestore(&ifx_dev->fifo_lock, flags); | ||
549 | if (is_fifo_empty) | ||
550 | mrdy_assert(ifx_dev); | ||
551 | |||
475 | return tx_count; | 552 | return tx_count; |
476 | } | 553 | } |
477 | 554 | ||
@@ -530,12 +607,19 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) | |||
530 | /* clear any old data; can't do this in 'close' */ | 607 | /* clear any old data; can't do this in 'close' */ |
531 | kfifo_reset(&ifx_dev->tx_fifo); | 608 | kfifo_reset(&ifx_dev->tx_fifo); |
532 | 609 | ||
610 | /* clear any flag which may be set in port shutdown procedure */ | ||
611 | clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags); | ||
612 | clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags); | ||
613 | |||
533 | /* put port data into this tty */ | 614 | /* put port data into this tty */ |
534 | tty->driver_data = ifx_dev; | 615 | tty->driver_data = ifx_dev; |
535 | 616 | ||
536 | /* allows flip string push from int context */ | 617 | /* allows flip string push from int context */ |
537 | tty->low_latency = 1; | 618 | tty->low_latency = 1; |
538 | 619 | ||
620 | /* set flag to allows data transfer */ | ||
621 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); | ||
622 | |||
539 | return 0; | 623 | return 0; |
540 | } | 624 | } |
541 | 625 | ||
@@ -551,6 +635,7 @@ static void ifx_port_shutdown(struct tty_port *port) | |||
551 | struct ifx_spi_device *ifx_dev = | 635 | struct ifx_spi_device *ifx_dev = |
552 | container_of(port, struct ifx_spi_device, tty_port); | 636 | container_of(port, struct ifx_spi_device, tty_port); |
553 | 637 | ||
638 | clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); | ||
554 | mrdy_set_low(ifx_dev); | 639 | mrdy_set_low(ifx_dev); |
555 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); | 640 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); |
556 | tasklet_kill(&ifx_dev->io_work_tasklet); | 641 | tasklet_kill(&ifx_dev->io_work_tasklet); |
@@ -617,7 +702,7 @@ static void ifx_spi_complete(void *ctx) | |||
617 | 702 | ||
618 | if (!ifx_dev->spi_msg.status) { | 703 | if (!ifx_dev->spi_msg.status) { |
619 | /* check header validity, get comm flags */ | 704 | /* check header validity, get comm flags */ |
620 | swap_buf((u16 *)ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD, | 705 | ifx_dev->swap_buf(ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD, |
621 | &ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]); | 706 | &ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]); |
622 | decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer, | 707 | decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer, |
623 | &length, &more, &cts); | 708 | &length, &more, &cts); |
@@ -636,7 +721,8 @@ static void ifx_spi_complete(void *ctx) | |||
636 | 721 | ||
637 | actual_length = min((unsigned int)length, | 722 | actual_length = min((unsigned int)length, |
638 | ifx_dev->spi_msg.actual_length); | 723 | ifx_dev->spi_msg.actual_length); |
639 | swap_buf((u16 *)(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD), | 724 | ifx_dev->swap_buf( |
725 | (ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD), | ||
640 | actual_length, | 726 | actual_length, |
641 | &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]); | 727 | &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]); |
642 | ifx_spi_insert_flip_string( | 728 | ifx_spi_insert_flip_string( |
@@ -705,7 +791,8 @@ static void ifx_spi_io(unsigned long data) | |||
705 | int retval; | 791 | int retval; |
706 | struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; | 792 | struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; |
707 | 793 | ||
708 | if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) { | 794 | if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) && |
795 | test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) { | ||
709 | if (ifx_dev->gpio.unack_srdy_int_nb > 0) | 796 | if (ifx_dev->gpio.unack_srdy_int_nb > 0) |
710 | ifx_dev->gpio.unack_srdy_int_nb--; | 797 | ifx_dev->gpio.unack_srdy_int_nb--; |
711 | 798 | ||
@@ -773,6 +860,7 @@ static void ifx_spi_free_port(struct ifx_spi_device *ifx_dev) | |||
773 | { | 860 | { |
774 | if (ifx_dev->tty_dev) | 861 | if (ifx_dev->tty_dev) |
775 | tty_unregister_device(tty_drv, ifx_dev->minor); | 862 | tty_unregister_device(tty_drv, ifx_dev->minor); |
863 | tty_port_destroy(&ifx_dev->tty_port); | ||
776 | kfifo_free(&ifx_dev->tx_fifo); | 864 | kfifo_free(&ifx_dev->tx_fifo); |
777 | } | 865 | } |
778 | 866 | ||
@@ -806,10 +894,12 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) | |||
806 | dev_dbg(&ifx_dev->spi_dev->dev, | 894 | dev_dbg(&ifx_dev->spi_dev->dev, |
807 | "%s: registering tty device failed", __func__); | 895 | "%s: registering tty device failed", __func__); |
808 | ret = PTR_ERR(ifx_dev->tty_dev); | 896 | ret = PTR_ERR(ifx_dev->tty_dev); |
809 | goto error_ret; | 897 | goto error_port; |
810 | } | 898 | } |
811 | return 0; | 899 | return 0; |
812 | 900 | ||
901 | error_port: | ||
902 | tty_port_destroy(pport); | ||
813 | error_ret: | 903 | error_ret: |
814 | ifx_spi_free_port(ifx_dev); | 904 | ifx_spi_free_port(ifx_dev); |
815 | return ret; | 905 | return ret; |
@@ -826,7 +916,7 @@ error_ret: | |||
826 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev) | 916 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev) |
827 | { | 917 | { |
828 | if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) { | 918 | if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) { |
829 | del_timer_sync(&ifx_dev->spi_timer); | 919 | del_timer(&ifx_dev->spi_timer); |
830 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); | 920 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); |
831 | } | 921 | } |
832 | 922 | ||
@@ -1001,6 +1091,14 @@ static int ifx_spi_spi_probe(struct spi_device *spi) | |||
1001 | return -ENODEV; | 1091 | return -ENODEV; |
1002 | } | 1092 | } |
1003 | 1093 | ||
1094 | /* init swap_buf function according to word width configuration */ | ||
1095 | if (spi->bits_per_word == 32) | ||
1096 | ifx_dev->swap_buf = swap_buf_32; | ||
1097 | else if (spi->bits_per_word == 16) | ||
1098 | ifx_dev->swap_buf = swap_buf_16; | ||
1099 | else | ||
1100 | ifx_dev->swap_buf = swap_buf_8; | ||
1101 | |||
1004 | /* ensure SPI protocol flags are initialized to enable transfer */ | 1102 | /* ensure SPI protocol flags are initialized to enable transfer */ |
1005 | ifx_dev->spi_more = 0; | 1103 | ifx_dev->spi_more = 0; |
1006 | ifx_dev->spi_slave_cts = 0; | 1104 | ifx_dev->spi_slave_cts = 0; |
@@ -1219,6 +1317,9 @@ static int ifx_spi_spi_remove(struct spi_device *spi) | |||
1219 | 1317 | ||
1220 | static void ifx_spi_spi_shutdown(struct spi_device *spi) | 1318 | static void ifx_spi_spi_shutdown(struct spi_device *spi) |
1221 | { | 1319 | { |
1320 | struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi); | ||
1321 | |||
1322 | ifx_modem_power_off(ifx_dev); | ||
1222 | } | 1323 | } |
1223 | 1324 | ||
1224 | /* | 1325 | /* |
@@ -1338,7 +1439,7 @@ static struct spi_driver ifx_spi_driver = { | |||
1338 | .owner = THIS_MODULE}, | 1439 | .owner = THIS_MODULE}, |
1339 | .probe = ifx_spi_spi_probe, | 1440 | .probe = ifx_spi_spi_probe, |
1340 | .shutdown = ifx_spi_spi_shutdown, | 1441 | .shutdown = ifx_spi_spi_shutdown, |
1341 | .remove = __devexit_p(ifx_spi_spi_remove), | 1442 | .remove = ifx_spi_spi_remove, |
1342 | .suspend = ifx_spi_spi_suspend, | 1443 | .suspend = ifx_spi_spi_suspend, |
1343 | .resume = ifx_spi_spi_resume, | 1444 | .resume = ifx_spi_spi_resume, |
1344 | .id_table = ifx_id_table | 1445 | .id_table = ifx_id_table |
@@ -1354,7 +1455,9 @@ static void __exit ifx_spi_exit(void) | |||
1354 | { | 1455 | { |
1355 | /* unregister */ | 1456 | /* unregister */ |
1356 | tty_unregister_driver(tty_drv); | 1457 | tty_unregister_driver(tty_drv); |
1458 | put_tty_driver(tty_drv); | ||
1357 | spi_unregister_driver((void *)&ifx_spi_driver); | 1459 | spi_unregister_driver((void *)&ifx_spi_driver); |
1460 | unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); | ||
1358 | } | 1461 | } |
1359 | 1462 | ||
1360 | /** | 1463 | /** |
@@ -1389,16 +1492,31 @@ static int __init ifx_spi_init(void) | |||
1389 | if (result) { | 1492 | if (result) { |
1390 | pr_err("%s: tty_register_driver failed(%d)", | 1493 | pr_err("%s: tty_register_driver failed(%d)", |
1391 | DRVNAME, result); | 1494 | DRVNAME, result); |
1392 | put_tty_driver(tty_drv); | 1495 | goto err_free_tty; |
1393 | return result; | ||
1394 | } | 1496 | } |
1395 | 1497 | ||
1396 | result = spi_register_driver((void *)&ifx_spi_driver); | 1498 | result = spi_register_driver((void *)&ifx_spi_driver); |
1397 | if (result) { | 1499 | if (result) { |
1398 | pr_err("%s: spi_register_driver failed(%d)", | 1500 | pr_err("%s: spi_register_driver failed(%d)", |
1399 | DRVNAME, result); | 1501 | DRVNAME, result); |
1400 | tty_unregister_driver(tty_drv); | 1502 | goto err_unreg_tty; |
1401 | } | 1503 | } |
1504 | |||
1505 | result = register_reboot_notifier(&ifx_modem_reboot_notifier_block); | ||
1506 | if (result) { | ||
1507 | pr_err("%s: register ifx modem reboot notifier failed(%d)", | ||
1508 | DRVNAME, result); | ||
1509 | goto err_unreg_spi; | ||
1510 | } | ||
1511 | |||
1512 | return 0; | ||
1513 | err_unreg_spi: | ||
1514 | spi_unregister_driver((void *)&ifx_spi_driver); | ||
1515 | err_unreg_tty: | ||
1516 | tty_unregister_driver(tty_drv); | ||
1517 | err_free_tty: | ||
1518 | put_tty_driver(tty_drv); | ||
1519 | |||
1402 | return result; | 1520 | return result; |
1403 | } | 1521 | } |
1404 | 1522 | ||
diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index e8464baf9e75..4fbddc297839 100644 --- a/drivers/tty/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #define IFX_SPI_STATE_IO_IN_PROGRESS 1 | 41 | #define IFX_SPI_STATE_IO_IN_PROGRESS 1 |
42 | #define IFX_SPI_STATE_IO_READY 2 | 42 | #define IFX_SPI_STATE_IO_READY 2 |
43 | #define IFX_SPI_STATE_TIMER_PENDING 3 | 43 | #define IFX_SPI_STATE_TIMER_PENDING 3 |
44 | #define IFX_SPI_STATE_IO_AVAILABLE 4 | ||
44 | 45 | ||
45 | /* flow control bitfields */ | 46 | /* flow control bitfields */ |
46 | #define IFX_SPI_DCD 0 | 47 | #define IFX_SPI_DCD 0 |
@@ -124,6 +125,7 @@ struct ifx_spi_device { | |||
124 | #define MR_INPROGRESS 1 | 125 | #define MR_INPROGRESS 1 |
125 | #define MR_COMPLETE 2 | 126 | #define MR_COMPLETE 2 |
126 | wait_queue_head_t mdm_reset_wait; | 127 | wait_queue_head_t mdm_reset_wait; |
128 | void (*swap_buf)(unsigned char *buf, int len, void *end); | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | #endif /* _IFX6X60_H */ | 131 | #endif /* _IFX6X60_H */ |
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index 5ac52898a0bb..d8f1d1d54471 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
@@ -2010,7 +2010,7 @@ static int ioc3uart_remove(struct ioc3_submodule *is, | |||
2010 | * @idd: ioc3 driver data for this card | 2010 | * @idd: ioc3 driver data for this card |
2011 | */ | 2011 | */ |
2012 | 2012 | ||
2013 | static int __devinit | 2013 | static int |
2014 | ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) | 2014 | ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) |
2015 | { | 2015 | { |
2016 | struct pci_dev *pdev = idd->pdev; | 2016 | struct pci_dev *pdev = idd->pdev; |
diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 529bec6edaf8..844d5e4eb1aa 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h | |||
@@ -57,9 +57,11 @@ enum { | |||
57 | DBG_CARR = 0x10000, | 57 | DBG_CARR = 0x10000, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define jsm_printk(nlevel, klevel, pdev, fmt, args...) \ | 60 | #define jsm_dbg(nlevel, pdev, fmt, ...) \ |
61 | if ((DBG_##nlevel & jsm_debug)) \ | 61 | do { \ |
62 | dev_printk(KERN_##klevel, pdev->dev, fmt, ## args) | 62 | if (DBG_##nlevel & jsm_debug) \ |
63 | dev_dbg(pdev->dev, fmt, ##__VA_ARGS__); \ | ||
64 | } while (0) | ||
63 | 65 | ||
64 | #define MAXLINES 256 | 66 | #define MAXLINES 256 |
65 | #define MAXPORTS 8 | 67 | #define MAXPORTS 8 |
diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 5ab3c3b595e4..a47d882d6743 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c | |||
@@ -64,7 +64,7 @@ int jsm_debug; | |||
64 | module_param(jsm_debug, int, 0); | 64 | module_param(jsm_debug, int, 0); |
65 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); | 65 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); |
66 | 66 | ||
67 | static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 67 | static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
68 | { | 68 | { |
69 | int rc = 0; | 69 | int rc = 0; |
70 | struct jsm_board *brd; | 70 | struct jsm_board *brd; |
@@ -107,8 +107,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
107 | 107 | ||
108 | brd->irq = pdev->irq; | 108 | brd->irq = pdev->irq; |
109 | 109 | ||
110 | jsm_printk(INIT, INFO, &brd->pci_dev, | 110 | jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n"); |
111 | "jsm_found_board - NEO adapter\n"); | ||
112 | 111 | ||
113 | /* get the PCI Base Address Registers */ | 112 | /* get the PCI Base Address Registers */ |
114 | brd->membase = pci_resource_start(pdev, 0); | 113 | brd->membase = pci_resource_start(pdev, 0); |
@@ -179,7 +178,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
179 | return rc; | 178 | return rc; |
180 | } | 179 | } |
181 | 180 | ||
182 | static void __devexit jsm_remove_one(struct pci_dev *pdev) | 181 | static void jsm_remove_one(struct pci_dev *pdev) |
183 | { | 182 | { |
184 | struct jsm_board *brd = pci_get_drvdata(pdev); | 183 | struct jsm_board *brd = pci_get_drvdata(pdev); |
185 | int i = 0; | 184 | int i = 0; |
@@ -218,7 +217,7 @@ static struct pci_driver jsm_driver = { | |||
218 | .name = "jsm", | 217 | .name = "jsm", |
219 | .id_table = jsm_pci_tbl, | 218 | .id_table = jsm_pci_tbl, |
220 | .probe = jsm_probe_one, | 219 | .probe = jsm_probe_one, |
221 | .remove = __devexit_p(jsm_remove_one), | 220 | .remove = jsm_remove_one, |
222 | .err_handler = &jsm_err_handler, | 221 | .err_handler = &jsm_err_handler, |
223 | }; | 222 | }; |
224 | 223 | ||
diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 81dfafa11b0b..dfaf48826417 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c | |||
@@ -52,7 +52,7 @@ static void neo_set_cts_flow_control(struct jsm_channel *ch) | |||
52 | ier = readb(&ch->ch_neo_uart->ier); | 52 | ier = readb(&ch->ch_neo_uart->ier); |
53 | efr = readb(&ch->ch_neo_uart->efr); | 53 | efr = readb(&ch->ch_neo_uart->efr); |
54 | 54 | ||
55 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n"); | 55 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n"); |
56 | 56 | ||
57 | /* Turn on auto CTS flow control */ | 57 | /* Turn on auto CTS flow control */ |
58 | ier |= (UART_17158_IER_CTSDSR); | 58 | ier |= (UART_17158_IER_CTSDSR); |
@@ -83,7 +83,7 @@ static void neo_set_rts_flow_control(struct jsm_channel *ch) | |||
83 | ier = readb(&ch->ch_neo_uart->ier); | 83 | ier = readb(&ch->ch_neo_uart->ier); |
84 | efr = readb(&ch->ch_neo_uart->efr); | 84 | efr = readb(&ch->ch_neo_uart->efr); |
85 | 85 | ||
86 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n"); | 86 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n"); |
87 | 87 | ||
88 | /* Turn on auto RTS flow control */ | 88 | /* Turn on auto RTS flow control */ |
89 | ier |= (UART_17158_IER_RTSDTR); | 89 | ier |= (UART_17158_IER_RTSDTR); |
@@ -123,7 +123,7 @@ static void neo_set_ixon_flow_control(struct jsm_channel *ch) | |||
123 | ier = readb(&ch->ch_neo_uart->ier); | 123 | ier = readb(&ch->ch_neo_uart->ier); |
124 | efr = readb(&ch->ch_neo_uart->efr); | 124 | efr = readb(&ch->ch_neo_uart->efr); |
125 | 125 | ||
126 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n"); | 126 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n"); |
127 | 127 | ||
128 | /* Turn off auto CTS flow control */ | 128 | /* Turn off auto CTS flow control */ |
129 | ier &= ~(UART_17158_IER_CTSDSR); | 129 | ier &= ~(UART_17158_IER_CTSDSR); |
@@ -160,7 +160,7 @@ static void neo_set_ixoff_flow_control(struct jsm_channel *ch) | |||
160 | ier = readb(&ch->ch_neo_uart->ier); | 160 | ier = readb(&ch->ch_neo_uart->ier); |
161 | efr = readb(&ch->ch_neo_uart->efr); | 161 | efr = readb(&ch->ch_neo_uart->efr); |
162 | 162 | ||
163 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n"); | 163 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n"); |
164 | 164 | ||
165 | /* Turn off auto RTS flow control */ | 165 | /* Turn off auto RTS flow control */ |
166 | ier &= ~(UART_17158_IER_RTSDTR); | 166 | ier &= ~(UART_17158_IER_RTSDTR); |
@@ -198,7 +198,7 @@ static void neo_set_no_input_flow_control(struct jsm_channel *ch) | |||
198 | ier = readb(&ch->ch_neo_uart->ier); | 198 | ier = readb(&ch->ch_neo_uart->ier); |
199 | efr = readb(&ch->ch_neo_uart->efr); | 199 | efr = readb(&ch->ch_neo_uart->efr); |
200 | 200 | ||
201 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n"); | 201 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n"); |
202 | 202 | ||
203 | /* Turn off auto RTS flow control */ | 203 | /* Turn off auto RTS flow control */ |
204 | ier &= ~(UART_17158_IER_RTSDTR); | 204 | ier &= ~(UART_17158_IER_RTSDTR); |
@@ -237,7 +237,7 @@ static void neo_set_no_output_flow_control(struct jsm_channel *ch) | |||
237 | ier = readb(&ch->ch_neo_uart->ier); | 237 | ier = readb(&ch->ch_neo_uart->ier); |
238 | efr = readb(&ch->ch_neo_uart->efr); | 238 | efr = readb(&ch->ch_neo_uart->efr); |
239 | 239 | ||
240 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n"); | 240 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n"); |
241 | 241 | ||
242 | /* Turn off auto CTS flow control */ | 242 | /* Turn off auto CTS flow control */ |
243 | ier &= ~(UART_17158_IER_CTSDSR); | 243 | ier &= ~(UART_17158_IER_CTSDSR); |
@@ -276,7 +276,7 @@ static inline void neo_set_new_start_stop_chars(struct jsm_channel *ch) | |||
276 | if (ch->ch_c_cflag & CRTSCTS) | 276 | if (ch->ch_c_cflag & CRTSCTS) |
277 | return; | 277 | return; |
278 | 278 | ||
279 | jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "start\n"); | 279 | jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "start\n"); |
280 | 280 | ||
281 | /* Tell UART what start/stop chars it should be looking for */ | 281 | /* Tell UART what start/stop chars it should be looking for */ |
282 | writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1); | 282 | writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1); |
@@ -455,7 +455,7 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch) | |||
455 | * I hope thats okay with everyone? Yes? Good. | 455 | * I hope thats okay with everyone? Yes? Good. |
456 | */ | 456 | */ |
457 | while (qleft < 1) { | 457 | while (qleft < 1) { |
458 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 458 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
459 | "Queue full, dropping DATA:%x LSR:%x\n", | 459 | "Queue full, dropping DATA:%x LSR:%x\n", |
460 | ch->ch_rqueue[tail], ch->ch_equeue[tail]); | 460 | ch->ch_rqueue[tail], ch->ch_equeue[tail]); |
461 | 461 | ||
@@ -467,8 +467,8 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch) | |||
467 | memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1); | 467 | memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1); |
468 | ch->ch_equeue[head] = (u8) linestatus; | 468 | ch->ch_equeue[head] = (u8) linestatus; |
469 | 469 | ||
470 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 470 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "DATA/LSR pair: %x %x\n", |
471 | "DATA/LSR pair: %x %x\n", ch->ch_rqueue[head], ch->ch_equeue[head]); | 471 | ch->ch_rqueue[head], ch->ch_equeue[head]); |
472 | 472 | ||
473 | /* Ditch any remaining linestatus value. */ | 473 | /* Ditch any remaining linestatus value. */ |
474 | linestatus = 0; | 474 | linestatus = 0; |
@@ -521,8 +521,8 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) | |||
521 | ch->ch_cached_lsr &= ~(UART_LSR_THRE); | 521 | ch->ch_cached_lsr &= ~(UART_LSR_THRE); |
522 | 522 | ||
523 | writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx); | 523 | writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx); |
524 | jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev, | 524 | jsm_dbg(WRITE, &ch->ch_bd->pci_dev, |
525 | "Tx data: %x\n", circ->buf[circ->tail]); | 525 | "Tx data: %x\n", circ->buf[circ->tail]); |
526 | circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1); | 526 | circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1); |
527 | ch->ch_txcount++; | 527 | ch->ch_txcount++; |
528 | } | 528 | } |
@@ -575,8 +575,9 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals) | |||
575 | { | 575 | { |
576 | u8 msignals = signals; | 576 | u8 msignals = signals; |
577 | 577 | ||
578 | jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev, | 578 | jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, |
579 | "neo_parse_modem: port: %d msignals: %x\n", ch->ch_portnum, msignals); | 579 | "neo_parse_modem: port: %d msignals: %x\n", |
580 | ch->ch_portnum, msignals); | ||
580 | 581 | ||
581 | /* Scrub off lower bits. They signify delta's, which I don't care about */ | 582 | /* Scrub off lower bits. They signify delta's, which I don't care about */ |
582 | /* Keep DDCD and DDSR though */ | 583 | /* Keep DDCD and DDSR though */ |
@@ -606,8 +607,8 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals) | |||
606 | else | 607 | else |
607 | ch->ch_mistat &= ~UART_MSR_CTS; | 608 | ch->ch_mistat &= ~UART_MSR_CTS; |
608 | 609 | ||
609 | jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev, | 610 | jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, |
610 | "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", | 611 | "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", |
611 | ch->ch_portnum, | 612 | ch->ch_portnum, |
612 | !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), | 613 | !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), |
613 | !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), | 614 | !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), |
@@ -649,8 +650,8 @@ static void neo_flush_uart_write(struct jsm_channel *ch) | |||
649 | /* Check to see if the UART feels it completely flushed the FIFO. */ | 650 | /* Check to see if the UART feels it completely flushed the FIFO. */ |
650 | tmp = readb(&ch->ch_neo_uart->isr_fcr); | 651 | tmp = readb(&ch->ch_neo_uart->isr_fcr); |
651 | if (tmp & 4) { | 652 | if (tmp & 4) { |
652 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, | 653 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, |
653 | "Still flushing TX UART... i: %d\n", i); | 654 | "Still flushing TX UART... i: %d\n", i); |
654 | udelay(10); | 655 | udelay(10); |
655 | } | 656 | } |
656 | else | 657 | else |
@@ -681,8 +682,8 @@ static void neo_flush_uart_read(struct jsm_channel *ch) | |||
681 | /* Check to see if the UART feels it completely flushed the FIFO. */ | 682 | /* Check to see if the UART feels it completely flushed the FIFO. */ |
682 | tmp = readb(&ch->ch_neo_uart->isr_fcr); | 683 | tmp = readb(&ch->ch_neo_uart->isr_fcr); |
683 | if (tmp & 2) { | 684 | if (tmp & 2) { |
684 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, | 685 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, |
685 | "Still flushing RX UART... i: %d\n", i); | 686 | "Still flushing RX UART... i: %d\n", i); |
686 | udelay(10); | 687 | udelay(10); |
687 | } | 688 | } |
688 | else | 689 | else |
@@ -705,8 +706,9 @@ static void neo_clear_break(struct jsm_channel *ch, int force) | |||
705 | writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); | 706 | writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); |
706 | 707 | ||
707 | ch->ch_flags &= ~(CH_BREAK_SENDING); | 708 | ch->ch_flags &= ~(CH_BREAK_SENDING); |
708 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, | 709 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, |
709 | "clear break Finishing UART_LCR_SBC! finished: %lx\n", jiffies); | 710 | "clear break Finishing UART_LCR_SBC! finished: %lx\n", |
711 | jiffies); | ||
710 | 712 | ||
711 | /* flush write operation */ | 713 | /* flush write operation */ |
712 | neo_pci_posting_flush(ch->ch_bd); | 714 | neo_pci_posting_flush(ch->ch_bd); |
@@ -748,8 +750,8 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) | |||
748 | */ | 750 | */ |
749 | isr &= ~(UART_17158_IIR_FIFO_ENABLED); | 751 | isr &= ~(UART_17158_IIR_FIFO_ENABLED); |
750 | 752 | ||
751 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 753 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d isr: %x\n", |
752 | "%s:%d isr: %x\n", __FILE__, __LINE__, isr); | 754 | __FILE__, __LINE__, isr); |
753 | 755 | ||
754 | if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) { | 756 | if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) { |
755 | /* Read data from uart -> queue */ | 757 | /* Read data from uart -> queue */ |
@@ -772,8 +774,9 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) | |||
772 | if (isr & UART_17158_IIR_XONXOFF) { | 774 | if (isr & UART_17158_IIR_XONXOFF) { |
773 | cause = readb(&ch->ch_neo_uart->xoffchar1); | 775 | cause = readb(&ch->ch_neo_uart->xoffchar1); |
774 | 776 | ||
775 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 777 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
776 | "Port %d. Got ISR_XONXOFF: cause:%x\n", port, cause); | 778 | "Port %d. Got ISR_XONXOFF: cause:%x\n", |
779 | port, cause); | ||
777 | 780 | ||
778 | /* | 781 | /* |
779 | * Since the UART detected either an XON or | 782 | * Since the UART detected either an XON or |
@@ -786,17 +789,19 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) | |||
786 | if (brd->channels[port]->ch_flags & CH_STOP) { | 789 | if (brd->channels[port]->ch_flags & CH_STOP) { |
787 | ch->ch_flags &= ~(CH_STOP); | 790 | ch->ch_flags &= ~(CH_STOP); |
788 | } | 791 | } |
789 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 792 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
790 | "Port %d. XON detected in incoming data\n", port); | 793 | "Port %d. XON detected in incoming data\n", |
794 | port); | ||
791 | } | 795 | } |
792 | else if (cause == UART_17158_XOFF_DETECT) { | 796 | else if (cause == UART_17158_XOFF_DETECT) { |
793 | if (!(brd->channels[port]->ch_flags & CH_STOP)) { | 797 | if (!(brd->channels[port]->ch_flags & CH_STOP)) { |
794 | ch->ch_flags |= CH_STOP; | 798 | ch->ch_flags |= CH_STOP; |
795 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 799 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
796 | "Setting CH_STOP\n"); | 800 | "Setting CH_STOP\n"); |
797 | } | 801 | } |
798 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 802 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
799 | "Port: %d. XOFF detected in incoming data\n", port); | 803 | "Port: %d. XOFF detected in incoming data\n", |
804 | port); | ||
800 | } | 805 | } |
801 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 806 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
802 | } | 807 | } |
@@ -825,8 +830,8 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) | |||
825 | } | 830 | } |
826 | 831 | ||
827 | /* Parse any modem signal changes */ | 832 | /* Parse any modem signal changes */ |
828 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 833 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
829 | "MOD_STAT: sending to parse_modem_sigs\n"); | 834 | "MOD_STAT: sending to parse_modem_sigs\n"); |
830 | neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); | 835 | neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); |
831 | } | 836 | } |
832 | } | 837 | } |
@@ -849,8 +854,8 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) | |||
849 | 854 | ||
850 | linestatus = readb(&ch->ch_neo_uart->lsr); | 855 | linestatus = readb(&ch->ch_neo_uart->lsr); |
851 | 856 | ||
852 | jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, | 857 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d port: %d linestatus: %x\n", |
853 | "%s:%d port: %d linestatus: %x\n", __FILE__, __LINE__, port, linestatus); | 858 | __FILE__, __LINE__, port, linestatus); |
854 | 859 | ||
855 | ch->ch_cached_lsr |= linestatus; | 860 | ch->ch_cached_lsr |= linestatus; |
856 | 861 | ||
@@ -869,7 +874,7 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) | |||
869 | *to do the special RX+LSR read for this FIFO load. | 874 | *to do the special RX+LSR read for this FIFO load. |
870 | */ | 875 | */ |
871 | if (linestatus & UART_17158_RX_FIFO_DATA_ERROR) | 876 | if (linestatus & UART_17158_RX_FIFO_DATA_ERROR) |
872 | jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, | 877 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
873 | "%s:%d Port: %d Got an RX error, need to parse LSR\n", | 878 | "%s:%d Port: %d Got an RX error, need to parse LSR\n", |
874 | __FILE__, __LINE__, port); | 879 | __FILE__, __LINE__, port); |
875 | 880 | ||
@@ -880,20 +885,21 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) | |||
880 | 885 | ||
881 | if (linestatus & UART_LSR_PE) { | 886 | if (linestatus & UART_LSR_PE) { |
882 | ch->ch_err_parity++; | 887 | ch->ch_err_parity++; |
883 | jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, | 888 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d. PAR ERR!\n", |
884 | "%s:%d Port: %d. PAR ERR!\n", __FILE__, __LINE__, port); | 889 | __FILE__, __LINE__, port); |
885 | } | 890 | } |
886 | 891 | ||
887 | if (linestatus & UART_LSR_FE) { | 892 | if (linestatus & UART_LSR_FE) { |
888 | ch->ch_err_frame++; | 893 | ch->ch_err_frame++; |
889 | jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, | 894 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d. FRM ERR!\n", |
890 | "%s:%d Port: %d. FRM ERR!\n", __FILE__, __LINE__, port); | 895 | __FILE__, __LINE__, port); |
891 | } | 896 | } |
892 | 897 | ||
893 | if (linestatus & UART_LSR_BI) { | 898 | if (linestatus & UART_LSR_BI) { |
894 | ch->ch_err_break++; | 899 | ch->ch_err_break++; |
895 | jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, | 900 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
896 | "%s:%d Port: %d. BRK INTR!\n", __FILE__, __LINE__, port); | 901 | "%s:%d Port: %d. BRK INTR!\n", |
902 | __FILE__, __LINE__, port); | ||
897 | } | 903 | } |
898 | 904 | ||
899 | if (linestatus & UART_LSR_OE) { | 905 | if (linestatus & UART_LSR_OE) { |
@@ -904,8 +910,9 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) | |||
904 | * Probably we should eventually have an orun stat in our driver... | 910 | * Probably we should eventually have an orun stat in our driver... |
905 | */ | 911 | */ |
906 | ch->ch_err_overrun++; | 912 | ch->ch_err_overrun++; |
907 | jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, | 913 | jsm_dbg(INTR, &ch->ch_bd->pci_dev, |
908 | "%s:%d Port: %d. Rx Overrun!\n", __FILE__, __LINE__, port); | 914 | "%s:%d Port: %d. Rx Overrun!\n", |
915 | __FILE__, __LINE__, port); | ||
909 | } | 916 | } |
910 | 917 | ||
911 | if (linestatus & UART_LSR_THRE) { | 918 | if (linestatus & UART_LSR_THRE) { |
@@ -1128,11 +1135,11 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) | |||
1128 | */ | 1135 | */ |
1129 | uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET); | 1136 | uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET); |
1130 | 1137 | ||
1131 | jsm_printk(INTR, INFO, &brd->pci_dev, | 1138 | jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n", |
1132 | "%s:%d uart_poll: %x\n", __FILE__, __LINE__, uart_poll); | 1139 | __FILE__, __LINE__, uart_poll); |
1133 | 1140 | ||
1134 | if (!uart_poll) { | 1141 | if (!uart_poll) { |
1135 | jsm_printk(INTR, INFO, &brd->pci_dev, | 1142 | jsm_dbg(INTR, &brd->pci_dev, |
1136 | "Kernel interrupted to me, but no pending interrupts...\n"); | 1143 | "Kernel interrupted to me, but no pending interrupts...\n"); |
1137 | spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); | 1144 | spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); |
1138 | return IRQ_NONE; | 1145 | return IRQ_NONE; |
@@ -1158,15 +1165,15 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) | |||
1158 | continue; | 1165 | continue; |
1159 | } | 1166 | } |
1160 | 1167 | ||
1161 | jsm_printk(INTR, INFO, &brd->pci_dev, | 1168 | jsm_dbg(INTR, &brd->pci_dev, "%s:%d port: %x type: %x\n", |
1162 | "%s:%d port: %x type: %x\n", __FILE__, __LINE__, port, type); | 1169 | __FILE__, __LINE__, port, type); |
1163 | 1170 | ||
1164 | /* Remove this port + type from uart_poll */ | 1171 | /* Remove this port + type from uart_poll */ |
1165 | uart_poll &= ~(jsm_offset_table[port]); | 1172 | uart_poll &= ~(jsm_offset_table[port]); |
1166 | 1173 | ||
1167 | if (!type) { | 1174 | if (!type) { |
1168 | /* If no type, just ignore it, and move onto next port */ | 1175 | /* If no type, just ignore it, and move onto next port */ |
1169 | jsm_printk(INTR, ERR, &brd->pci_dev, | 1176 | jsm_dbg(INTR, &brd->pci_dev, |
1170 | "Interrupt with no type! port: %d\n", port); | 1177 | "Interrupt with no type! port: %d\n", port); |
1171 | continue; | 1178 | continue; |
1172 | } | 1179 | } |
@@ -1231,15 +1238,16 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) | |||
1231 | * these once and awhile. | 1238 | * these once and awhile. |
1232 | * Its harmless, just ignore it and move on. | 1239 | * Its harmless, just ignore it and move on. |
1233 | */ | 1240 | */ |
1234 | jsm_printk(INTR, ERR, &brd->pci_dev, | 1241 | jsm_dbg(INTR, &brd->pci_dev, |
1235 | "%s:%d Unknown Interrupt type: %x\n", __FILE__, __LINE__, type); | 1242 | "%s:%d Unknown Interrupt type: %x\n", |
1243 | __FILE__, __LINE__, type); | ||
1236 | continue; | 1244 | continue; |
1237 | } | 1245 | } |
1238 | } | 1246 | } |
1239 | 1247 | ||
1240 | spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); | 1248 | spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); |
1241 | 1249 | ||
1242 | jsm_printk(INTR, INFO, &brd->pci_dev, "finish.\n"); | 1250 | jsm_dbg(INTR, &brd->pci_dev, "finish\n"); |
1243 | return IRQ_HANDLED; | 1251 | return IRQ_HANDLED; |
1244 | } | 1252 | } |
1245 | 1253 | ||
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 71397961773c..4c00c5550b1a 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -43,7 +43,7 @@ static inline int jsm_get_mstat(struct jsm_channel *ch) | |||
43 | unsigned char mstat; | 43 | unsigned char mstat; |
44 | unsigned result; | 44 | unsigned result; |
45 | 45 | ||
46 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "start\n"); | 46 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "start\n"); |
47 | 47 | ||
48 | mstat = (ch->ch_mostat | ch->ch_mistat); | 48 | mstat = (ch->ch_mostat | ch->ch_mistat); |
49 | 49 | ||
@@ -62,7 +62,7 @@ static inline int jsm_get_mstat(struct jsm_channel *ch) | |||
62 | if (mstat & UART_MSR_DCD) | 62 | if (mstat & UART_MSR_DCD) |
63 | result |= TIOCM_CD; | 63 | result |= TIOCM_CD; |
64 | 64 | ||
65 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); | 65 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); |
66 | return result; | 66 | return result; |
67 | } | 67 | } |
68 | 68 | ||
@@ -79,14 +79,14 @@ static unsigned int jsm_tty_get_mctrl(struct uart_port *port) | |||
79 | int result; | 79 | int result; |
80 | struct jsm_channel *channel = (struct jsm_channel *)port; | 80 | struct jsm_channel *channel = (struct jsm_channel *)port; |
81 | 81 | ||
82 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); | 82 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
83 | 83 | ||
84 | result = jsm_get_mstat(channel); | 84 | result = jsm_get_mstat(channel); |
85 | 85 | ||
86 | if (result < 0) | 86 | if (result < 0) |
87 | return -ENXIO; | 87 | return -ENXIO; |
88 | 88 | ||
89 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); | 89 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); |
90 | 90 | ||
91 | return result; | 91 | return result; |
92 | } | 92 | } |
@@ -100,7 +100,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
100 | { | 100 | { |
101 | struct jsm_channel *channel = (struct jsm_channel *)port; | 101 | struct jsm_channel *channel = (struct jsm_channel *)port; |
102 | 102 | ||
103 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); | 103 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
104 | 104 | ||
105 | if (mctrl & TIOCM_RTS) | 105 | if (mctrl & TIOCM_RTS) |
106 | channel->ch_mostat |= UART_MCR_RTS; | 106 | channel->ch_mostat |= UART_MCR_RTS; |
@@ -114,7 +114,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
114 | 114 | ||
115 | channel->ch_bd->bd_ops->assert_modem_signals(channel); | 115 | channel->ch_bd->bd_ops->assert_modem_signals(channel); |
116 | 116 | ||
117 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); | 117 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); |
118 | udelay(10); | 118 | udelay(10); |
119 | } | 119 | } |
120 | 120 | ||
@@ -135,23 +135,23 @@ static void jsm_tty_start_tx(struct uart_port *port) | |||
135 | { | 135 | { |
136 | struct jsm_channel *channel = (struct jsm_channel *)port; | 136 | struct jsm_channel *channel = (struct jsm_channel *)port; |
137 | 137 | ||
138 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); | 138 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
139 | 139 | ||
140 | channel->ch_flags &= ~(CH_STOP); | 140 | channel->ch_flags &= ~(CH_STOP); |
141 | jsm_tty_write(port); | 141 | jsm_tty_write(port); |
142 | 142 | ||
143 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); | 143 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); |
144 | } | 144 | } |
145 | 145 | ||
146 | static void jsm_tty_stop_tx(struct uart_port *port) | 146 | static void jsm_tty_stop_tx(struct uart_port *port) |
147 | { | 147 | { |
148 | struct jsm_channel *channel = (struct jsm_channel *)port; | 148 | struct jsm_channel *channel = (struct jsm_channel *)port; |
149 | 149 | ||
150 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); | 150 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
151 | 151 | ||
152 | channel->ch_flags |= (CH_STOP); | 152 | channel->ch_flags |= (CH_STOP); |
153 | 153 | ||
154 | jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); | 154 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); |
155 | } | 155 | } |
156 | 156 | ||
157 | static void jsm_tty_send_xchar(struct uart_port *port, char ch) | 157 | static void jsm_tty_send_xchar(struct uart_port *port, char ch) |
@@ -216,16 +216,16 @@ static int jsm_tty_open(struct uart_port *port) | |||
216 | if (!channel->ch_rqueue) { | 216 | if (!channel->ch_rqueue) { |
217 | channel->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL); | 217 | channel->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL); |
218 | if (!channel->ch_rqueue) { | 218 | if (!channel->ch_rqueue) { |
219 | jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev, | 219 | jsm_dbg(INIT, &channel->ch_bd->pci_dev, |
220 | "unable to allocate read queue buf"); | 220 | "unable to allocate read queue buf\n"); |
221 | return -ENOMEM; | 221 | return -ENOMEM; |
222 | } | 222 | } |
223 | } | 223 | } |
224 | if (!channel->ch_equeue) { | 224 | if (!channel->ch_equeue) { |
225 | channel->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL); | 225 | channel->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL); |
226 | if (!channel->ch_equeue) { | 226 | if (!channel->ch_equeue) { |
227 | jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev, | 227 | jsm_dbg(INIT, &channel->ch_bd->pci_dev, |
228 | "unable to allocate error queue buf"); | 228 | "unable to allocate error queue buf\n"); |
229 | return -ENOMEM; | 229 | return -ENOMEM; |
230 | } | 230 | } |
231 | } | 231 | } |
@@ -234,7 +234,7 @@ static int jsm_tty_open(struct uart_port *port) | |||
234 | /* | 234 | /* |
235 | * Initialize if neither terminal is open. | 235 | * Initialize if neither terminal is open. |
236 | */ | 236 | */ |
237 | jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, | 237 | jsm_dbg(OPEN, &channel->ch_bd->pci_dev, |
238 | "jsm_open: initializing channel in open...\n"); | 238 | "jsm_open: initializing channel in open...\n"); |
239 | 239 | ||
240 | /* | 240 | /* |
@@ -270,7 +270,7 @@ static int jsm_tty_open(struct uart_port *port) | |||
270 | 270 | ||
271 | channel->ch_open_count++; | 271 | channel->ch_open_count++; |
272 | 272 | ||
273 | jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, "finish\n"); | 273 | jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n"); |
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
@@ -280,7 +280,7 @@ static void jsm_tty_close(struct uart_port *port) | |||
280 | struct ktermios *ts; | 280 | struct ktermios *ts; |
281 | struct jsm_channel *channel = (struct jsm_channel *)port; | 281 | struct jsm_channel *channel = (struct jsm_channel *)port; |
282 | 282 | ||
283 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); | 283 | jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "start\n"); |
284 | 284 | ||
285 | bd = channel->ch_bd; | 285 | bd = channel->ch_bd; |
286 | ts = &port->state->port.tty->termios; | 286 | ts = &port->state->port.tty->termios; |
@@ -293,7 +293,7 @@ static void jsm_tty_close(struct uart_port *port) | |||
293 | * If we have HUPCL set, lower DTR and RTS | 293 | * If we have HUPCL set, lower DTR and RTS |
294 | */ | 294 | */ |
295 | if (channel->ch_c_cflag & HUPCL) { | 295 | if (channel->ch_c_cflag & HUPCL) { |
296 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, | 296 | jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, |
297 | "Close. HUPCL set, dropping DTR/RTS\n"); | 297 | "Close. HUPCL set, dropping DTR/RTS\n"); |
298 | 298 | ||
299 | /* Drop RTS/DTR */ | 299 | /* Drop RTS/DTR */ |
@@ -304,7 +304,7 @@ static void jsm_tty_close(struct uart_port *port) | |||
304 | /* Turn off UART interrupts for this port */ | 304 | /* Turn off UART interrupts for this port */ |
305 | channel->ch_bd->bd_ops->uart_off(channel); | 305 | channel->ch_bd->bd_ops->uart_off(channel); |
306 | 306 | ||
307 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "finish\n"); | 307 | jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "finish\n"); |
308 | } | 308 | } |
309 | 309 | ||
310 | static void jsm_tty_set_termios(struct uart_port *port, | 310 | static void jsm_tty_set_termios(struct uart_port *port, |
@@ -371,7 +371,7 @@ static struct uart_ops jsm_ops = { | |||
371 | * Init the tty subsystem. Called once per board after board has been | 371 | * Init the tty subsystem. Called once per board after board has been |
372 | * downloaded and init'ed. | 372 | * downloaded and init'ed. |
373 | */ | 373 | */ |
374 | int __devinit jsm_tty_init(struct jsm_board *brd) | 374 | int jsm_tty_init(struct jsm_board *brd) |
375 | { | 375 | { |
376 | int i; | 376 | int i; |
377 | void __iomem *vaddr; | 377 | void __iomem *vaddr; |
@@ -380,7 +380,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd) | |||
380 | if (!brd) | 380 | if (!brd) |
381 | return -ENXIO; | 381 | return -ENXIO; |
382 | 382 | ||
383 | jsm_printk(INIT, INFO, &brd->pci_dev, "start\n"); | 383 | jsm_dbg(INIT, &brd->pci_dev, "start\n"); |
384 | 384 | ||
385 | /* | 385 | /* |
386 | * Initialize board structure elements. | 386 | * Initialize board structure elements. |
@@ -401,9 +401,9 @@ int __devinit jsm_tty_init(struct jsm_board *brd) | |||
401 | */ | 401 | */ |
402 | brd->channels[i] = kzalloc(sizeof(struct jsm_channel), GFP_KERNEL); | 402 | brd->channels[i] = kzalloc(sizeof(struct jsm_channel), GFP_KERNEL); |
403 | if (!brd->channels[i]) { | 403 | if (!brd->channels[i]) { |
404 | jsm_printk(CORE, ERR, &brd->pci_dev, | 404 | jsm_dbg(CORE, &brd->pci_dev, |
405 | "%s:%d Unable to allocate memory for channel struct\n", | 405 | "%s:%d Unable to allocate memory for channel struct\n", |
406 | __FILE__, __LINE__); | 406 | __FILE__, __LINE__); |
407 | } | 407 | } |
408 | } | 408 | } |
409 | } | 409 | } |
@@ -431,7 +431,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd) | |||
431 | init_waitqueue_head(&ch->ch_flags_wait); | 431 | init_waitqueue_head(&ch->ch_flags_wait); |
432 | } | 432 | } |
433 | 433 | ||
434 | jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); | 434 | jsm_dbg(INIT, &brd->pci_dev, "finish\n"); |
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | 437 | ||
@@ -444,7 +444,7 @@ int jsm_uart_port_init(struct jsm_board *brd) | |||
444 | if (!brd) | 444 | if (!brd) |
445 | return -ENXIO; | 445 | return -ENXIO; |
446 | 446 | ||
447 | jsm_printk(INIT, INFO, &brd->pci_dev, "start\n"); | 447 | jsm_dbg(INIT, &brd->pci_dev, "start\n"); |
448 | 448 | ||
449 | /* | 449 | /* |
450 | * Initialize board structure elements. | 450 | * Initialize board structure elements. |
@@ -481,7 +481,7 @@ int jsm_uart_port_init(struct jsm_board *brd) | |||
481 | printk(KERN_INFO "jsm: Port %d added\n", i); | 481 | printk(KERN_INFO "jsm: Port %d added\n", i); |
482 | } | 482 | } |
483 | 483 | ||
484 | jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); | 484 | jsm_dbg(INIT, &brd->pci_dev, "finish\n"); |
485 | return 0; | 485 | return 0; |
486 | } | 486 | } |
487 | 487 | ||
@@ -493,7 +493,7 @@ int jsm_remove_uart_port(struct jsm_board *brd) | |||
493 | if (!brd) | 493 | if (!brd) |
494 | return -ENXIO; | 494 | return -ENXIO; |
495 | 495 | ||
496 | jsm_printk(INIT, INFO, &brd->pci_dev, "start\n"); | 496 | jsm_dbg(INIT, &brd->pci_dev, "start\n"); |
497 | 497 | ||
498 | /* | 498 | /* |
499 | * Initialize board structure elements. | 499 | * Initialize board structure elements. |
@@ -513,7 +513,7 @@ int jsm_remove_uart_port(struct jsm_board *brd) | |||
513 | uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port); | 513 | uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port); |
514 | } | 514 | } |
515 | 515 | ||
516 | jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); | 516 | jsm_dbg(INIT, &brd->pci_dev, "finish\n"); |
517 | return 0; | 517 | return 0; |
518 | } | 518 | } |
519 | 519 | ||
@@ -531,7 +531,7 @@ void jsm_input(struct jsm_channel *ch) | |||
531 | int s = 0; | 531 | int s = 0; |
532 | int i = 0; | 532 | int i = 0; |
533 | 533 | ||
534 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); | 534 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n"); |
535 | 535 | ||
536 | if (!ch) | 536 | if (!ch) |
537 | return; | 537 | return; |
@@ -560,7 +560,7 @@ void jsm_input(struct jsm_channel *ch) | |||
560 | return; | 560 | return; |
561 | } | 561 | } |
562 | 562 | ||
563 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); | 563 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n"); |
564 | 564 | ||
565 | /* | 565 | /* |
566 | *If the device is not open, or CREAD is off, flush | 566 | *If the device is not open, or CREAD is off, flush |
@@ -569,8 +569,9 @@ void jsm_input(struct jsm_channel *ch) | |||
569 | if (!tp || | 569 | if (!tp || |
570 | !(tp->termios.c_cflag & CREAD) ) { | 570 | !(tp->termios.c_cflag & CREAD) ) { |
571 | 571 | ||
572 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 572 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
573 | "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); | 573 | "input. dropping %d bytes on port %d...\n", |
574 | data_len, ch->ch_portnum); | ||
574 | ch->ch_r_head = tail; | 575 | ch->ch_r_head = tail; |
575 | 576 | ||
576 | /* Force queue flow control to be released, if needed */ | 577 | /* Force queue flow control to be released, if needed */ |
@@ -585,17 +586,17 @@ void jsm_input(struct jsm_channel *ch) | |||
585 | */ | 586 | */ |
586 | if (ch->ch_flags & CH_STOPI) { | 587 | if (ch->ch_flags & CH_STOPI) { |
587 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 588 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
588 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 589 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
589 | "Port %d throttled, not reading any data. head: %x tail: %x\n", | 590 | "Port %d throttled, not reading any data. head: %x tail: %x\n", |
590 | ch->ch_portnum, head, tail); | 591 | ch->ch_portnum, head, tail); |
591 | return; | 592 | return; |
592 | } | 593 | } |
593 | 594 | ||
594 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n"); | 595 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); |
595 | 596 | ||
596 | if (data_len <= 0) { | 597 | if (data_len <= 0) { |
597 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 598 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
598 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); | 599 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "jsm_input 1\n"); |
599 | return; | 600 | return; |
600 | } | 601 | } |
601 | 602 | ||
@@ -653,7 +654,7 @@ void jsm_input(struct jsm_channel *ch) | |||
653 | /* Tell the tty layer its okay to "eat" the data now */ | 654 | /* Tell the tty layer its okay to "eat" the data now */ |
654 | tty_flip_buffer_push(tp); | 655 | tty_flip_buffer_push(tp); |
655 | 656 | ||
656 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); | 657 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); |
657 | } | 658 | } |
658 | 659 | ||
659 | static void jsm_carrier(struct jsm_channel *ch) | 660 | static void jsm_carrier(struct jsm_channel *ch) |
@@ -663,7 +664,7 @@ static void jsm_carrier(struct jsm_channel *ch) | |||
663 | int virt_carrier = 0; | 664 | int virt_carrier = 0; |
664 | int phys_carrier = 0; | 665 | int phys_carrier = 0; |
665 | 666 | ||
666 | jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, "start\n"); | 667 | jsm_dbg(CARR, &ch->ch_bd->pci_dev, "start\n"); |
667 | if (!ch) | 668 | if (!ch) |
668 | return; | 669 | return; |
669 | 670 | ||
@@ -673,16 +674,16 @@ static void jsm_carrier(struct jsm_channel *ch) | |||
673 | return; | 674 | return; |
674 | 675 | ||
675 | if (ch->ch_mistat & UART_MSR_DCD) { | 676 | if (ch->ch_mistat & UART_MSR_DCD) { |
676 | jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, | 677 | jsm_dbg(CARR, &ch->ch_bd->pci_dev, "mistat: %x D_CD: %x\n", |
677 | "mistat: %x D_CD: %x\n", ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD); | 678 | ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD); |
678 | phys_carrier = 1; | 679 | phys_carrier = 1; |
679 | } | 680 | } |
680 | 681 | ||
681 | if (ch->ch_c_cflag & CLOCAL) | 682 | if (ch->ch_c_cflag & CLOCAL) |
682 | virt_carrier = 1; | 683 | virt_carrier = 1; |
683 | 684 | ||
684 | jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, | 685 | jsm_dbg(CARR, &ch->ch_bd->pci_dev, "DCD: physical: %d virt: %d\n", |
685 | "DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier); | 686 | phys_carrier, virt_carrier); |
686 | 687 | ||
687 | /* | 688 | /* |
688 | * Test for a VIRTUAL carrier transition to HIGH. | 689 | * Test for a VIRTUAL carrier transition to HIGH. |
@@ -694,8 +695,7 @@ static void jsm_carrier(struct jsm_channel *ch) | |||
694 | * for carrier in the open routine. | 695 | * for carrier in the open routine. |
695 | */ | 696 | */ |
696 | 697 | ||
697 | jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, | 698 | jsm_dbg(CARR, &ch->ch_bd->pci_dev, "carrier: virt DCD rose\n"); |
698 | "carrier: virt DCD rose\n"); | ||
699 | 699 | ||
700 | if (waitqueue_active(&(ch->ch_flags_wait))) | 700 | if (waitqueue_active(&(ch->ch_flags_wait))) |
701 | wake_up_interruptible(&ch->ch_flags_wait); | 701 | wake_up_interruptible(&ch->ch_flags_wait); |
@@ -711,7 +711,7 @@ static void jsm_carrier(struct jsm_channel *ch) | |||
711 | * for carrier in the open routine. | 711 | * for carrier in the open routine. |
712 | */ | 712 | */ |
713 | 713 | ||
714 | jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, | 714 | jsm_dbg(CARR, &ch->ch_bd->pci_dev, |
715 | "carrier: physical DCD rose\n"); | 715 | "carrier: physical DCD rose\n"); |
716 | 716 | ||
717 | if (waitqueue_active(&(ch->ch_flags_wait))) | 717 | if (waitqueue_active(&(ch->ch_flags_wait))) |
@@ -790,8 +790,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) | |||
790 | if(!(ch->ch_flags & CH_RECEIVER_OFF)) { | 790 | if(!(ch->ch_flags & CH_RECEIVER_OFF)) { |
791 | bd_ops->disable_receiver(ch); | 791 | bd_ops->disable_receiver(ch); |
792 | ch->ch_flags |= (CH_RECEIVER_OFF); | 792 | ch->ch_flags |= (CH_RECEIVER_OFF); |
793 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 793 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
794 | "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", | 794 | "Internal queue hit hilevel mark (%d)! Turning off interrupts\n", |
795 | qleft); | 795 | qleft); |
796 | } | 796 | } |
797 | } | 797 | } |
@@ -800,8 +800,9 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) | |||
800 | if (ch->ch_stops_sent <= MAX_STOPS_SENT) { | 800 | if (ch->ch_stops_sent <= MAX_STOPS_SENT) { |
801 | bd_ops->send_stop_character(ch); | 801 | bd_ops->send_stop_character(ch); |
802 | ch->ch_stops_sent++; | 802 | ch->ch_stops_sent++; |
803 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 803 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
804 | "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); | 804 | "Sending stop char! Times sent: %x\n", |
805 | ch->ch_stops_sent); | ||
805 | } | 806 | } |
806 | } | 807 | } |
807 | } | 808 | } |
@@ -827,8 +828,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) | |||
827 | if (ch->ch_flags & CH_RECEIVER_OFF) { | 828 | if (ch->ch_flags & CH_RECEIVER_OFF) { |
828 | bd_ops->enable_receiver(ch); | 829 | bd_ops->enable_receiver(ch); |
829 | ch->ch_flags &= ~(CH_RECEIVER_OFF); | 830 | ch->ch_flags &= ~(CH_RECEIVER_OFF); |
830 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 831 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
831 | "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", | 832 | "Internal queue hit lowlevel mark (%d)! Turning on interrupts\n", |
832 | qleft); | 833 | qleft); |
833 | } | 834 | } |
834 | } | 835 | } |
@@ -836,7 +837,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) | |||
836 | else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { | 837 | else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { |
837 | ch->ch_stops_sent = 0; | 838 | ch->ch_stops_sent = 0; |
838 | bd_ops->send_start_character(ch); | 839 | bd_ops->send_start_character(ch); |
839 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); | 840 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
841 | "Sending start char!\n"); | ||
840 | } | 842 | } |
841 | } | 843 | } |
842 | } | 844 | } |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index d185247ba1aa..6ac2b797a764 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c | |||
@@ -266,6 +266,7 @@ static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty) | |||
266 | } | 266 | } |
267 | return 0; | 267 | return 0; |
268 | err: | 268 | err: |
269 | tty_port_destroy(&priv->port); | ||
269 | kfree(priv); | 270 | kfree(priv); |
270 | return ret; | 271 | return ret; |
271 | } | 272 | } |
@@ -275,6 +276,7 @@ static void kgdb_nmi_tty_cleanup(struct tty_struct *tty) | |||
275 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; | 276 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; |
276 | 277 | ||
277 | tty->driver_data = NULL; | 278 | tty->driver_data = NULL; |
279 | tty_port_destroy(&priv->port); | ||
278 | kfree(priv); | 280 | kfree(priv); |
279 | } | 281 | } |
280 | 282 | ||
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index ba3af3bf6d43..0e86bff3fe2a 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c | |||
@@ -686,7 +686,7 @@ static struct uart_ops serial_lpc32xx_pops = { | |||
686 | /* | 686 | /* |
687 | * Register a set of serial devices attached to a platform device | 687 | * Register a set of serial devices attached to a platform device |
688 | */ | 688 | */ |
689 | static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev) | 689 | static int serial_hs_lpc32xx_probe(struct platform_device *pdev) |
690 | { | 690 | { |
691 | struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered]; | 691 | struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered]; |
692 | int ret = 0; | 692 | int ret = 0; |
@@ -740,7 +740,7 @@ static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev) | |||
740 | /* | 740 | /* |
741 | * Remove serial ports registered against a platform device. | 741 | * Remove serial ports registered against a platform device. |
742 | */ | 742 | */ |
743 | static int __devexit serial_hs_lpc32xx_remove(struct platform_device *pdev) | 743 | static int serial_hs_lpc32xx_remove(struct platform_device *pdev) |
744 | { | 744 | { |
745 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | 745 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); |
746 | 746 | ||
@@ -783,7 +783,7 @@ MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids); | |||
783 | 783 | ||
784 | static struct platform_driver serial_hs_lpc32xx_driver = { | 784 | static struct platform_driver serial_hs_lpc32xx_driver = { |
785 | .probe = serial_hs_lpc32xx_probe, | 785 | .probe = serial_hs_lpc32xx_probe, |
786 | .remove = __devexit_p(serial_hs_lpc32xx_remove), | 786 | .remove = serial_hs_lpc32xx_remove, |
787 | .suspend = serial_hs_lpc32xx_suspend, | 787 | .suspend = serial_hs_lpc32xx_suspend, |
788 | .resume = serial_hs_lpc32xx_resume, | 788 | .resume = serial_hs_lpc32xx_resume, |
789 | .driver = { | 789 | .driver = { |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 0f24486be532..7ce3197087bb 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -742,7 +742,7 @@ static struct uart_driver max3100_uart_driver = { | |||
742 | }; | 742 | }; |
743 | static int uart_driver_registered; | 743 | static int uart_driver_registered; |
744 | 744 | ||
745 | static int __devinit max3100_probe(struct spi_device *spi) | 745 | static int max3100_probe(struct spi_device *spi) |
746 | { | 746 | { |
747 | int i, retval; | 747 | int i, retval; |
748 | struct plat_max3100 *pdata; | 748 | struct plat_max3100 *pdata; |
@@ -818,7 +818,7 @@ static int __devinit max3100_probe(struct spi_device *spi) | |||
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | static int __devexit max3100_remove(struct spi_device *spi) | 821 | static int max3100_remove(struct spi_device *spi) |
822 | { | 822 | { |
823 | struct max3100_port *s = dev_get_drvdata(&spi->dev); | 823 | struct max3100_port *s = dev_get_drvdata(&spi->dev); |
824 | int i; | 824 | int i; |
@@ -907,7 +907,7 @@ static struct spi_driver max3100_driver = { | |||
907 | }, | 907 | }, |
908 | 908 | ||
909 | .probe = max3100_probe, | 909 | .probe = max3100_probe, |
910 | .remove = __devexit_p(max3100_remove), | 910 | .remove = max3100_remove, |
911 | .suspend = max3100_suspend, | 911 | .suspend = max3100_suspend, |
912 | .resume = max3100_resume, | 912 | .resume = max3100_resume, |
913 | }; | 913 | }; |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 1ab1d2c66de4..a801f6872cad 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -378,7 +378,7 @@ static void max310x_wait_pll(struct max310x_port *s) | |||
378 | } | 378 | } |
379 | } | 379 | } |
380 | 380 | ||
381 | static int __devinit max310x_update_best_err(unsigned long f, long *besterr) | 381 | static int max310x_update_best_err(unsigned long f, long *besterr) |
382 | { | 382 | { |
383 | /* Use baudrate 115200 for calculate error */ | 383 | /* Use baudrate 115200 for calculate error */ |
384 | long err = f % (115200 * 16); | 384 | long err = f % (115200 * 16); |
@@ -391,7 +391,7 @@ static int __devinit max310x_update_best_err(unsigned long f, long *besterr) | |||
391 | return 1; | 391 | return 1; |
392 | } | 392 | } |
393 | 393 | ||
394 | static int __devinit max310x_set_ref_clk(struct max310x_port *s) | 394 | static int max310x_set_ref_clk(struct max310x_port *s) |
395 | { | 395 | { |
396 | unsigned int div, clksrc, pllcfg = 0; | 396 | unsigned int div, clksrc, pllcfg = 0; |
397 | long besterr = -1; | 397 | long besterr = -1; |
@@ -995,7 +995,7 @@ static struct max310x_pdata generic_plat_data = { | |||
995 | .frequency = 26000000, | 995 | .frequency = 26000000, |
996 | }; | 996 | }; |
997 | 997 | ||
998 | static int __devinit max310x_probe(struct spi_device *spi) | 998 | static int max310x_probe(struct spi_device *spi) |
999 | { | 999 | { |
1000 | struct max310x_port *s; | 1000 | struct max310x_port *s; |
1001 | struct device *dev = &spi->dev; | 1001 | struct device *dev = &spi->dev; |
@@ -1178,6 +1178,7 @@ static int __devinit max310x_probe(struct spi_device *spi) | |||
1178 | s->gpio.set = max310x_gpio_set; | 1178 | s->gpio.set = max310x_gpio_set; |
1179 | s->gpio.base = pdata->gpio_base; | 1179 | s->gpio.base = pdata->gpio_base; |
1180 | s->gpio.ngpio = s->nr_gpio; | 1180 | s->gpio.ngpio = s->nr_gpio; |
1181 | s->gpio.can_sleep = 1; | ||
1181 | if (gpiochip_add(&s->gpio)) { | 1182 | if (gpiochip_add(&s->gpio)) { |
1182 | /* Indicate that we should not call gpiochip_remove */ | 1183 | /* Indicate that we should not call gpiochip_remove */ |
1183 | s->gpio.base = 0; | 1184 | s->gpio.base = 0; |
@@ -1202,7 +1203,7 @@ err_out: | |||
1202 | return ret; | 1203 | return ret; |
1203 | } | 1204 | } |
1204 | 1205 | ||
1205 | static int __devexit max310x_remove(struct spi_device *spi) | 1206 | static int max310x_remove(struct spi_device *spi) |
1206 | { | 1207 | { |
1207 | struct device *dev = &spi->dev; | 1208 | struct device *dev = &spi->dev; |
1208 | struct max310x_port *s = dev_get_drvdata(dev); | 1209 | struct max310x_port *s = dev_get_drvdata(dev); |
@@ -1249,7 +1250,7 @@ static struct spi_driver max310x_driver = { | |||
1249 | .owner = THIS_MODULE, | 1250 | .owner = THIS_MODULE, |
1250 | }, | 1251 | }, |
1251 | .probe = max310x_probe, | 1252 | .probe = max310x_probe, |
1252 | .remove = __devexit_p(max310x_remove), | 1253 | .remove = max310x_remove, |
1253 | .suspend = max310x_suspend, | 1254 | .suspend = max310x_suspend, |
1254 | .resume = max310x_resume, | 1255 | .resume = max310x_resume, |
1255 | .id_table = max310x_id_table, | 1256 | .id_table = max310x_id_table, |
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 9afca093d6ec..fcd56ab6053f 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -571,7 +571,7 @@ static struct uart_driver mcf_driver = { | |||
571 | 571 | ||
572 | /****************************************************************************/ | 572 | /****************************************************************************/ |
573 | 573 | ||
574 | static int __devinit mcf_probe(struct platform_device *pdev) | 574 | static int mcf_probe(struct platform_device *pdev) |
575 | { | 575 | { |
576 | struct mcf_platform_uart *platp = pdev->dev.platform_data; | 576 | struct mcf_platform_uart *platp = pdev->dev.platform_data; |
577 | struct uart_port *port; | 577 | struct uart_port *port; |
@@ -599,7 +599,7 @@ static int __devinit mcf_probe(struct platform_device *pdev) | |||
599 | 599 | ||
600 | /****************************************************************************/ | 600 | /****************************************************************************/ |
601 | 601 | ||
602 | static int __devexit mcf_remove(struct platform_device *pdev) | 602 | static int mcf_remove(struct platform_device *pdev) |
603 | { | 603 | { |
604 | struct uart_port *port; | 604 | struct uart_port *port; |
605 | int i; | 605 | int i; |
@@ -617,7 +617,7 @@ static int __devexit mcf_remove(struct platform_device *pdev) | |||
617 | 617 | ||
618 | static struct platform_driver mcf_platform_driver = { | 618 | static struct platform_driver mcf_platform_driver = { |
619 | .probe = mcf_probe, | 619 | .probe = mcf_probe, |
620 | .remove = __devexit_p(mcf_remove), | 620 | .remove = mcf_remove, |
621 | .driver = { | 621 | .driver = { |
622 | .name = "mcfuart", | 622 | .name = "mcfuart", |
623 | .owner = THIS_MODULE, | 623 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index c4b50af46c44..2c01344dc332 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/serial_mfd.h> | 36 | #include <linux/serial_mfd.h> |
37 | #include <linux/dma-mapping.h> | 37 | #include <linux/dma-mapping.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/nmi.h> | ||
39 | #include <linux/io.h> | 40 | #include <linux/io.h> |
40 | #include <linux/debugfs.h> | 41 | #include <linux/debugfs.h> |
41 | #include <linux/pm_runtime.h> | 42 | #include <linux/pm_runtime.h> |
@@ -1113,6 +1114,8 @@ serial_hsu_console_write(struct console *co, const char *s, unsigned int count) | |||
1113 | unsigned int ier; | 1114 | unsigned int ier; |
1114 | int locked = 1; | 1115 | int locked = 1; |
1115 | 1116 | ||
1117 | touch_nmi_watchdog(); | ||
1118 | |||
1116 | local_irq_save(flags); | 1119 | local_irq_save(flags); |
1117 | if (up->port.sysrq) | 1120 | if (up->port.sysrq) |
1118 | locked = 0; | 1121 | locked = 0; |
@@ -1456,7 +1459,7 @@ static void serial_hsu_remove(struct pci_dev *pdev) | |||
1456 | } | 1459 | } |
1457 | 1460 | ||
1458 | /* First 3 are UART ports, and the 4th is the DMA */ | 1461 | /* First 3 are UART ports, and the 4th is the DMA */ |
1459 | static const struct pci_device_id pci_ids[] __devinitconst = { | 1462 | static const struct pci_device_id pci_ids[] = { |
1460 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, | 1463 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, |
1461 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, | 1464 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, |
1462 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, | 1465 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, |
@@ -1468,7 +1471,7 @@ static struct pci_driver hsu_pci_driver = { | |||
1468 | .name = "HSU serial", | 1471 | .name = "HSU serial", |
1469 | .id_table = pci_ids, | 1472 | .id_table = pci_ids, |
1470 | .probe = serial_hsu_probe, | 1473 | .probe = serial_hsu_probe, |
1471 | .remove = __devexit_p(serial_hsu_remove), | 1474 | .remove = serial_hsu_remove, |
1472 | .suspend = serial_hsu_suspend, | 1475 | .suspend = serial_hsu_suspend, |
1473 | .resume = serial_hsu_resume, | 1476 | .resume = serial_hsu_resume, |
1474 | .driver = { | 1477 | .driver = { |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 8cf577008ad7..7c23c4f4c58d 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -1308,7 +1308,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = { | |||
1308 | {}, | 1308 | {}, |
1309 | }; | 1309 | }; |
1310 | 1310 | ||
1311 | static int __devinit mpc52xx_uart_of_probe(struct platform_device *op) | 1311 | static int mpc52xx_uart_of_probe(struct platform_device *op) |
1312 | { | 1312 | { |
1313 | int idx = -1; | 1313 | int idx = -1; |
1314 | unsigned int uartclk; | 1314 | unsigned int uartclk; |
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index df2a2240a3ae..58734d7e746d 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c | |||
@@ -773,7 +773,7 @@ static int serial_m3110_resume(struct spi_device *spi) | |||
773 | #define serial_m3110_resume NULL | 773 | #define serial_m3110_resume NULL |
774 | #endif | 774 | #endif |
775 | 775 | ||
776 | static int __devinit serial_m3110_probe(struct spi_device *spi) | 776 | static int serial_m3110_probe(struct spi_device *spi) |
777 | { | 777 | { |
778 | struct uart_max3110 *max; | 778 | struct uart_max3110 *max; |
779 | void *buffer; | 779 | void *buffer; |
@@ -855,7 +855,7 @@ err_get_page: | |||
855 | return ret; | 855 | return ret; |
856 | } | 856 | } |
857 | 857 | ||
858 | static int __devexit serial_m3110_remove(struct spi_device *dev) | 858 | static int serial_m3110_remove(struct spi_device *dev) |
859 | { | 859 | { |
860 | struct uart_max3110 *max = spi_get_drvdata(dev); | 860 | struct uart_max3110 *max = spi_get_drvdata(dev); |
861 | 861 | ||
@@ -879,7 +879,7 @@ static struct spi_driver uart_max3110_driver = { | |||
879 | .owner = THIS_MODULE, | 879 | .owner = THIS_MODULE, |
880 | }, | 880 | }, |
881 | .probe = serial_m3110_probe, | 881 | .probe = serial_m3110_probe, |
882 | .remove = __devexit_p(serial_m3110_remove), | 882 | .remove = serial_m3110_remove, |
883 | .suspend = serial_m3110_suspend, | 883 | .suspend = serial_m3110_suspend, |
884 | .resume = serial_m3110_resume, | 884 | .resume = serial_m3110_resume, |
885 | }; | 885 | }; |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 033e0bc9ebab..95fd39be2934 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -917,7 +917,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
917 | return uart_add_one_port(&msm_uart_driver, port); | 917 | return uart_add_one_port(&msm_uart_driver, port); |
918 | } | 918 | } |
919 | 919 | ||
920 | static int __devexit msm_serial_remove(struct platform_device *pdev) | 920 | static int msm_serial_remove(struct platform_device *pdev) |
921 | { | 921 | { |
922 | struct msm_port *msm_port = platform_get_drvdata(pdev); | 922 | struct msm_port *msm_port = platform_get_drvdata(pdev); |
923 | 923 | ||
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index fca13dc73e23..1fa92284ade0 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c | |||
@@ -401,7 +401,7 @@ static int msm_hs_request_port(struct uart_port *port) | |||
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | static int __devexit msm_hs_remove(struct platform_device *pdev) | 404 | static int msm_hs_remove(struct platform_device *pdev) |
405 | { | 405 | { |
406 | 406 | ||
407 | struct msm_hs_port *msm_uport; | 407 | struct msm_hs_port *msm_uport; |
@@ -1521,7 +1521,7 @@ err_msm_hs_init_clk: | |||
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | /* Initialize tx and rx data structures */ | 1523 | /* Initialize tx and rx data structures */ |
1524 | static int __devinit uartdm_init_port(struct uart_port *uport) | 1524 | static int uartdm_init_port(struct uart_port *uport) |
1525 | { | 1525 | { |
1526 | int ret = 0; | 1526 | int ret = 0; |
1527 | struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); | 1527 | struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); |
@@ -1614,7 +1614,7 @@ err_tx_command_ptr_ptr: | |||
1614 | return ret; | 1614 | return ret; |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | static int __devinit msm_hs_probe(struct platform_device *pdev) | 1617 | static int msm_hs_probe(struct platform_device *pdev) |
1618 | { | 1618 | { |
1619 | int ret; | 1619 | int ret; |
1620 | struct uart_port *uport; | 1620 | struct uart_port *uport; |
@@ -1838,7 +1838,7 @@ static const struct dev_pm_ops msm_hs_dev_pm_ops = { | |||
1838 | 1838 | ||
1839 | static struct platform_driver msm_serial_hs_platform_driver = { | 1839 | static struct platform_driver msm_serial_hs_platform_driver = { |
1840 | .probe = msm_hs_probe, | 1840 | .probe = msm_hs_probe, |
1841 | .remove = __devexit_p(msm_hs_remove), | 1841 | .remove = msm_hs_remove, |
1842 | .driver = { | 1842 | .driver = { |
1843 | .name = "msm_serial_hs", | 1843 | .name = "msm_serial_hs", |
1844 | .owner = THIS_MODULE, | 1844 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 7ea8a263fd9e..e2775b6df5a5 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c | |||
@@ -520,7 +520,7 @@ static int __init mux_probe(struct parisc_device *dev) | |||
520 | return 0; | 520 | return 0; |
521 | } | 521 | } |
522 | 522 | ||
523 | static int __devexit mux_remove(struct parisc_device *dev) | 523 | static int mux_remove(struct parisc_device *dev) |
524 | { | 524 | { |
525 | int i, j; | 525 | int i, j; |
526 | int port_count = (long)dev_get_drvdata(&dev->dev); | 526 | int port_count = (long)dev_get_drvdata(&dev->dev); |
@@ -571,14 +571,14 @@ static struct parisc_driver builtin_serial_mux_driver = { | |||
571 | .name = "builtin_serial_mux", | 571 | .name = "builtin_serial_mux", |
572 | .id_table = builtin_mux_tbl, | 572 | .id_table = builtin_mux_tbl, |
573 | .probe = mux_probe, | 573 | .probe = mux_probe, |
574 | .remove = __devexit_p(mux_remove), | 574 | .remove = mux_remove, |
575 | }; | 575 | }; |
576 | 576 | ||
577 | static struct parisc_driver serial_mux_driver = { | 577 | static struct parisc_driver serial_mux_driver = { |
578 | .name = "serial_mux", | 578 | .name = "serial_mux", |
579 | .id_table = mux_tbl, | 579 | .id_table = mux_tbl, |
580 | .probe = mux_probe, | 580 | .probe = mux_probe, |
581 | .remove = __devexit_p(mux_remove), | 581 | .remove = mux_remove, |
582 | }; | 582 | }; |
583 | 583 | ||
584 | /** | 584 | /** |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 6db3baa39a97..6db23b035efe 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/pinctrl/consumer.h> | 35 | #include <linux/pinctrl/consumer.h> |
36 | #include <linux/of_device.h> | 36 | #include <linux/of_device.h> |
37 | #include <linux/dma-mapping.h> | ||
38 | #include <linux/fsl/mxs-dma.h> | ||
37 | 39 | ||
38 | #include <asm/cacheflush.h> | 40 | #include <asm/cacheflush.h> |
39 | 41 | ||
@@ -71,6 +73,15 @@ | |||
71 | 73 | ||
72 | #define AUART_CTRL0_SFTRST (1 << 31) | 74 | #define AUART_CTRL0_SFTRST (1 << 31) |
73 | #define AUART_CTRL0_CLKGATE (1 << 30) | 75 | #define AUART_CTRL0_CLKGATE (1 << 30) |
76 | #define AUART_CTRL0_RXTO_ENABLE (1 << 27) | ||
77 | #define AUART_CTRL0_RXTIMEOUT(v) (((v) & 0x7ff) << 16) | ||
78 | #define AUART_CTRL0_XFER_COUNT(v) ((v) & 0xffff) | ||
79 | |||
80 | #define AUART_CTRL1_XFER_COUNT(v) ((v) & 0xffff) | ||
81 | |||
82 | #define AUART_CTRL2_DMAONERR (1 << 26) | ||
83 | #define AUART_CTRL2_TXDMAE (1 << 25) | ||
84 | #define AUART_CTRL2_RXDMAE (1 << 24) | ||
74 | 85 | ||
75 | #define AUART_CTRL2_CTSEN (1 << 15) | 86 | #define AUART_CTRL2_CTSEN (1 << 15) |
76 | #define AUART_CTRL2_RTSEN (1 << 14) | 87 | #define AUART_CTRL2_RTSEN (1 << 14) |
@@ -111,29 +122,170 @@ | |||
111 | #define AUART_STAT_BERR (1 << 18) | 122 | #define AUART_STAT_BERR (1 << 18) |
112 | #define AUART_STAT_PERR (1 << 17) | 123 | #define AUART_STAT_PERR (1 << 17) |
113 | #define AUART_STAT_FERR (1 << 16) | 124 | #define AUART_STAT_FERR (1 << 16) |
125 | #define AUART_STAT_RXCOUNT_MASK 0xffff | ||
114 | 126 | ||
115 | static struct uart_driver auart_driver; | 127 | static struct uart_driver auart_driver; |
116 | 128 | ||
129 | enum mxs_auart_type { | ||
130 | IMX23_AUART, | ||
131 | IMX28_AUART, | ||
132 | }; | ||
133 | |||
117 | struct mxs_auart_port { | 134 | struct mxs_auart_port { |
118 | struct uart_port port; | 135 | struct uart_port port; |
119 | 136 | ||
120 | unsigned int flags; | 137 | #define MXS_AUART_DMA_CONFIG 0x1 |
138 | #define MXS_AUART_DMA_ENABLED 0x2 | ||
139 | #define MXS_AUART_DMA_TX_SYNC 2 /* bit 2 */ | ||
140 | #define MXS_AUART_DMA_RX_READY 3 /* bit 3 */ | ||
141 | unsigned long flags; | ||
121 | unsigned int ctrl; | 142 | unsigned int ctrl; |
143 | enum mxs_auart_type devtype; | ||
122 | 144 | ||
123 | unsigned int irq; | 145 | unsigned int irq; |
124 | 146 | ||
125 | struct clk *clk; | 147 | struct clk *clk; |
126 | struct device *dev; | 148 | struct device *dev; |
149 | |||
150 | /* for DMA */ | ||
151 | struct mxs_dma_data dma_data; | ||
152 | int dma_channel_rx, dma_channel_tx; | ||
153 | int dma_irq_rx, dma_irq_tx; | ||
154 | int dma_channel; | ||
155 | |||
156 | struct scatterlist tx_sgl; | ||
157 | struct dma_chan *tx_dma_chan; | ||
158 | void *tx_dma_buf; | ||
159 | |||
160 | struct scatterlist rx_sgl; | ||
161 | struct dma_chan *rx_dma_chan; | ||
162 | void *rx_dma_buf; | ||
163 | }; | ||
164 | |||
165 | static struct platform_device_id mxs_auart_devtype[] = { | ||
166 | { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, | ||
167 | { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, | ||
168 | { /* sentinel */ } | ||
169 | }; | ||
170 | MODULE_DEVICE_TABLE(platform, mxs_auart_devtype); | ||
171 | |||
172 | static struct of_device_id mxs_auart_dt_ids[] = { | ||
173 | { | ||
174 | .compatible = "fsl,imx28-auart", | ||
175 | .data = &mxs_auart_devtype[IMX28_AUART] | ||
176 | }, { | ||
177 | .compatible = "fsl,imx23-auart", | ||
178 | .data = &mxs_auart_devtype[IMX23_AUART] | ||
179 | }, { /* sentinel */ } | ||
127 | }; | 180 | }; |
181 | MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); | ||
182 | |||
183 | static inline int is_imx28_auart(struct mxs_auart_port *s) | ||
184 | { | ||
185 | return s->devtype == IMX28_AUART; | ||
186 | } | ||
187 | |||
188 | static inline bool auart_dma_enabled(struct mxs_auart_port *s) | ||
189 | { | ||
190 | return s->flags & MXS_AUART_DMA_ENABLED; | ||
191 | } | ||
128 | 192 | ||
129 | static void mxs_auart_stop_tx(struct uart_port *u); | 193 | static void mxs_auart_stop_tx(struct uart_port *u); |
130 | 194 | ||
131 | #define to_auart_port(u) container_of(u, struct mxs_auart_port, port) | 195 | #define to_auart_port(u) container_of(u, struct mxs_auart_port, port) |
132 | 196 | ||
133 | static inline void mxs_auart_tx_chars(struct mxs_auart_port *s) | 197 | static void mxs_auart_tx_chars(struct mxs_auart_port *s); |
198 | |||
199 | static void dma_tx_callback(void *param) | ||
134 | { | 200 | { |
201 | struct mxs_auart_port *s = param; | ||
135 | struct circ_buf *xmit = &s->port.state->xmit; | 202 | struct circ_buf *xmit = &s->port.state->xmit; |
136 | 203 | ||
204 | dma_unmap_sg(s->dev, &s->tx_sgl, 1, DMA_TO_DEVICE); | ||
205 | |||
206 | /* clear the bit used to serialize the DMA tx. */ | ||
207 | clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags); | ||
208 | smp_mb__after_clear_bit(); | ||
209 | |||
210 | /* wake up the possible processes. */ | ||
211 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
212 | uart_write_wakeup(&s->port); | ||
213 | |||
214 | mxs_auart_tx_chars(s); | ||
215 | } | ||
216 | |||
217 | static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size) | ||
218 | { | ||
219 | struct dma_async_tx_descriptor *desc; | ||
220 | struct scatterlist *sgl = &s->tx_sgl; | ||
221 | struct dma_chan *channel = s->tx_dma_chan; | ||
222 | u32 pio; | ||
223 | |||
224 | /* [1] : send PIO. Note, the first pio word is CTRL1. */ | ||
225 | pio = AUART_CTRL1_XFER_COUNT(size); | ||
226 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio, | ||
227 | 1, DMA_TRANS_NONE, 0); | ||
228 | if (!desc) { | ||
229 | dev_err(s->dev, "step 1 error\n"); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | /* [2] : set DMA buffer. */ | ||
234 | sg_init_one(sgl, s->tx_dma_buf, size); | ||
235 | dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE); | ||
236 | desc = dmaengine_prep_slave_sg(channel, sgl, | ||
237 | 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
238 | if (!desc) { | ||
239 | dev_err(s->dev, "step 2 error\n"); | ||
240 | return -EINVAL; | ||
241 | } | ||
242 | |||
243 | /* [3] : submit the DMA */ | ||
244 | desc->callback = dma_tx_callback; | ||
245 | desc->callback_param = s; | ||
246 | dmaengine_submit(desc); | ||
247 | dma_async_issue_pending(channel); | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static void mxs_auart_tx_chars(struct mxs_auart_port *s) | ||
252 | { | ||
253 | struct circ_buf *xmit = &s->port.state->xmit; | ||
254 | |||
255 | if (auart_dma_enabled(s)) { | ||
256 | int i = 0; | ||
257 | int size; | ||
258 | void *buffer = s->tx_dma_buf; | ||
259 | |||
260 | if (test_and_set_bit(MXS_AUART_DMA_TX_SYNC, &s->flags)) | ||
261 | return; | ||
262 | |||
263 | while (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { | ||
264 | size = min_t(u32, UART_XMIT_SIZE - i, | ||
265 | CIRC_CNT_TO_END(xmit->head, | ||
266 | xmit->tail, | ||
267 | UART_XMIT_SIZE)); | ||
268 | memcpy(buffer + i, xmit->buf + xmit->tail, size); | ||
269 | xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1); | ||
270 | |||
271 | i += size; | ||
272 | if (i >= UART_XMIT_SIZE) | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | if (uart_tx_stopped(&s->port)) | ||
277 | mxs_auart_stop_tx(&s->port); | ||
278 | |||
279 | if (i) { | ||
280 | mxs_auart_dma_tx(s, i); | ||
281 | } else { | ||
282 | clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags); | ||
283 | smp_mb__after_clear_bit(); | ||
284 | } | ||
285 | return; | ||
286 | } | ||
287 | |||
288 | |||
137 | while (!(readl(s->port.membase + AUART_STAT) & | 289 | while (!(readl(s->port.membase + AUART_STAT) & |
138 | AUART_STAT_TXFF)) { | 290 | AUART_STAT_TXFF)) { |
139 | if (s->port.x_char) { | 291 | if (s->port.x_char) { |
@@ -287,10 +439,159 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u) | |||
287 | return mctrl; | 439 | return mctrl; |
288 | } | 440 | } |
289 | 441 | ||
442 | static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param) | ||
443 | { | ||
444 | struct mxs_auart_port *s = param; | ||
445 | |||
446 | if (!mxs_dma_is_apbx(chan)) | ||
447 | return false; | ||
448 | |||
449 | if (s->dma_channel == chan->chan_id) { | ||
450 | chan->private = &s->dma_data; | ||
451 | return true; | ||
452 | } | ||
453 | return false; | ||
454 | } | ||
455 | |||
456 | static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); | ||
457 | static void dma_rx_callback(void *arg) | ||
458 | { | ||
459 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; | ||
460 | struct tty_struct *tty = s->port.state->port.tty; | ||
461 | int count; | ||
462 | u32 stat; | ||
463 | |||
464 | dma_unmap_sg(s->dev, &s->rx_sgl, 1, DMA_FROM_DEVICE); | ||
465 | |||
466 | stat = readl(s->port.membase + AUART_STAT); | ||
467 | stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR | | ||
468 | AUART_STAT_PERR | AUART_STAT_FERR); | ||
469 | |||
470 | count = stat & AUART_STAT_RXCOUNT_MASK; | ||
471 | tty_insert_flip_string(tty, s->rx_dma_buf, count); | ||
472 | |||
473 | writel(stat, s->port.membase + AUART_STAT); | ||
474 | tty_flip_buffer_push(tty); | ||
475 | |||
476 | /* start the next DMA for RX. */ | ||
477 | mxs_auart_dma_prep_rx(s); | ||
478 | } | ||
479 | |||
480 | static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s) | ||
481 | { | ||
482 | struct dma_async_tx_descriptor *desc; | ||
483 | struct scatterlist *sgl = &s->rx_sgl; | ||
484 | struct dma_chan *channel = s->rx_dma_chan; | ||
485 | u32 pio[1]; | ||
486 | |||
487 | /* [1] : send PIO */ | ||
488 | pio[0] = AUART_CTRL0_RXTO_ENABLE | ||
489 | | AUART_CTRL0_RXTIMEOUT(0x80) | ||
490 | | AUART_CTRL0_XFER_COUNT(UART_XMIT_SIZE); | ||
491 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, | ||
492 | 1, DMA_TRANS_NONE, 0); | ||
493 | if (!desc) { | ||
494 | dev_err(s->dev, "step 1 error\n"); | ||
495 | return -EINVAL; | ||
496 | } | ||
497 | |||
498 | /* [2] : send DMA request */ | ||
499 | sg_init_one(sgl, s->rx_dma_buf, UART_XMIT_SIZE); | ||
500 | dma_map_sg(s->dev, sgl, 1, DMA_FROM_DEVICE); | ||
501 | desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_DEV_TO_MEM, | ||
502 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
503 | if (!desc) { | ||
504 | dev_err(s->dev, "step 2 error\n"); | ||
505 | return -1; | ||
506 | } | ||
507 | |||
508 | /* [3] : submit the DMA, but do not issue it. */ | ||
509 | desc->callback = dma_rx_callback; | ||
510 | desc->callback_param = s; | ||
511 | dmaengine_submit(desc); | ||
512 | dma_async_issue_pending(channel); | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s) | ||
517 | { | ||
518 | if (s->tx_dma_chan) { | ||
519 | dma_release_channel(s->tx_dma_chan); | ||
520 | s->tx_dma_chan = NULL; | ||
521 | } | ||
522 | if (s->rx_dma_chan) { | ||
523 | dma_release_channel(s->rx_dma_chan); | ||
524 | s->rx_dma_chan = NULL; | ||
525 | } | ||
526 | |||
527 | kfree(s->tx_dma_buf); | ||
528 | kfree(s->rx_dma_buf); | ||
529 | s->tx_dma_buf = NULL; | ||
530 | s->rx_dma_buf = NULL; | ||
531 | } | ||
532 | |||
533 | static void mxs_auart_dma_exit(struct mxs_auart_port *s) | ||
534 | { | ||
535 | |||
536 | writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR, | ||
537 | s->port.membase + AUART_CTRL2_CLR); | ||
538 | |||
539 | mxs_auart_dma_exit_channel(s); | ||
540 | s->flags &= ~MXS_AUART_DMA_ENABLED; | ||
541 | clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags); | ||
542 | clear_bit(MXS_AUART_DMA_RX_READY, &s->flags); | ||
543 | } | ||
544 | |||
545 | static int mxs_auart_dma_init(struct mxs_auart_port *s) | ||
546 | { | ||
547 | dma_cap_mask_t mask; | ||
548 | |||
549 | if (auart_dma_enabled(s)) | ||
550 | return 0; | ||
551 | |||
552 | /* We do not get the right DMA channels. */ | ||
553 | if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1) | ||
554 | return -EINVAL; | ||
555 | |||
556 | /* init for RX */ | ||
557 | dma_cap_zero(mask); | ||
558 | dma_cap_set(DMA_SLAVE, mask); | ||
559 | s->dma_channel = s->dma_channel_rx; | ||
560 | s->dma_data.chan_irq = s->dma_irq_rx; | ||
561 | s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s); | ||
562 | if (!s->rx_dma_chan) | ||
563 | goto err_out; | ||
564 | s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); | ||
565 | if (!s->rx_dma_buf) | ||
566 | goto err_out; | ||
567 | |||
568 | /* init for TX */ | ||
569 | s->dma_channel = s->dma_channel_tx; | ||
570 | s->dma_data.chan_irq = s->dma_irq_tx; | ||
571 | s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s); | ||
572 | if (!s->tx_dma_chan) | ||
573 | goto err_out; | ||
574 | s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); | ||
575 | if (!s->tx_dma_buf) | ||
576 | goto err_out; | ||
577 | |||
578 | /* set the flags */ | ||
579 | s->flags |= MXS_AUART_DMA_ENABLED; | ||
580 | dev_dbg(s->dev, "enabled the DMA support."); | ||
581 | |||
582 | return 0; | ||
583 | |||
584 | err_out: | ||
585 | mxs_auart_dma_exit_channel(s); | ||
586 | return -EINVAL; | ||
587 | |||
588 | } | ||
589 | |||
290 | static void mxs_auart_settermios(struct uart_port *u, | 590 | static void mxs_auart_settermios(struct uart_port *u, |
291 | struct ktermios *termios, | 591 | struct ktermios *termios, |
292 | struct ktermios *old) | 592 | struct ktermios *old) |
293 | { | 593 | { |
594 | struct mxs_auart_port *s = to_auart_port(u); | ||
294 | u32 bm, ctrl, ctrl2, div; | 595 | u32 bm, ctrl, ctrl2, div; |
295 | unsigned int cflag, baud; | 596 | unsigned int cflag, baud; |
296 | 597 | ||
@@ -362,10 +663,23 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
362 | ctrl |= AUART_LINECTRL_STP2; | 663 | ctrl |= AUART_LINECTRL_STP2; |
363 | 664 | ||
364 | /* figure out the hardware flow control settings */ | 665 | /* figure out the hardware flow control settings */ |
365 | if (cflag & CRTSCTS) | 666 | if (cflag & CRTSCTS) { |
667 | /* | ||
668 | * The DMA has a bug(see errata:2836) in mx23. | ||
669 | * So we can not implement the DMA for auart in mx23, | ||
670 | * we can only implement the DMA support for auart | ||
671 | * in mx28. | ||
672 | */ | ||
673 | if (is_imx28_auart(s) && (s->flags & MXS_AUART_DMA_CONFIG)) { | ||
674 | if (!mxs_auart_dma_init(s)) | ||
675 | /* enable DMA tranfer */ | ||
676 | ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | ||
677 | | AUART_CTRL2_DMAONERR; | ||
678 | } | ||
366 | ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; | 679 | ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; |
367 | else | 680 | } else { |
368 | ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); | 681 | ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); |
682 | } | ||
369 | 683 | ||
370 | /* set baud rate */ | 684 | /* set baud rate */ |
371 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); | 685 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); |
@@ -377,6 +691,19 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
377 | writel(ctrl2, u->membase + AUART_CTRL2); | 691 | writel(ctrl2, u->membase + AUART_CTRL2); |
378 | 692 | ||
379 | uart_update_timeout(u, termios->c_cflag, baud); | 693 | uart_update_timeout(u, termios->c_cflag, baud); |
694 | |||
695 | /* prepare for the DMA RX. */ | ||
696 | if (auart_dma_enabled(s) && | ||
697 | !test_and_set_bit(MXS_AUART_DMA_RX_READY, &s->flags)) { | ||
698 | if (!mxs_auart_dma_prep_rx(s)) { | ||
699 | /* Disable the normal RX interrupt. */ | ||
700 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN, | ||
701 | u->membase + AUART_INTR_CLR); | ||
702 | } else { | ||
703 | mxs_auart_dma_exit(s); | ||
704 | dev_err(s->dev, "We can not start up the DMA.\n"); | ||
705 | } | ||
706 | } | ||
380 | } | 707 | } |
381 | 708 | ||
382 | static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | 709 | static irqreturn_t mxs_auart_irq_handle(int irq, void *context) |
@@ -395,7 +722,8 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | |||
395 | } | 722 | } |
396 | 723 | ||
397 | if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) { | 724 | if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) { |
398 | mxs_auart_rx_chars(s); | 725 | if (!auart_dma_enabled(s)) |
726 | mxs_auart_rx_chars(s); | ||
399 | istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS); | 727 | istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS); |
400 | } | 728 | } |
401 | 729 | ||
@@ -455,6 +783,9 @@ static void mxs_auart_shutdown(struct uart_port *u) | |||
455 | { | 783 | { |
456 | struct mxs_auart_port *s = to_auart_port(u); | 784 | struct mxs_auart_port *s = to_auart_port(u); |
457 | 785 | ||
786 | if (auart_dma_enabled(s)) | ||
787 | mxs_auart_dma_exit(s); | ||
788 | |||
458 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); | 789 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); |
459 | 790 | ||
460 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, | 791 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, |
@@ -688,6 +1019,7 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, | |||
688 | struct platform_device *pdev) | 1019 | struct platform_device *pdev) |
689 | { | 1020 | { |
690 | struct device_node *np = pdev->dev.of_node; | 1021 | struct device_node *np = pdev->dev.of_node; |
1022 | u32 dma_channel[2]; | ||
691 | int ret; | 1023 | int ret; |
692 | 1024 | ||
693 | if (!np) | 1025 | if (!np) |
@@ -701,11 +1033,27 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, | |||
701 | } | 1033 | } |
702 | s->port.line = ret; | 1034 | s->port.line = ret; |
703 | 1035 | ||
1036 | s->dma_irq_rx = platform_get_irq(pdev, 1); | ||
1037 | s->dma_irq_tx = platform_get_irq(pdev, 2); | ||
1038 | |||
1039 | ret = of_property_read_u32_array(np, "fsl,auart-dma-channel", | ||
1040 | dma_channel, 2); | ||
1041 | if (ret == 0) { | ||
1042 | s->dma_channel_rx = dma_channel[0]; | ||
1043 | s->dma_channel_tx = dma_channel[1]; | ||
1044 | |||
1045 | s->flags |= MXS_AUART_DMA_CONFIG; | ||
1046 | } else { | ||
1047 | s->dma_channel_rx = -1; | ||
1048 | s->dma_channel_tx = -1; | ||
1049 | } | ||
704 | return 0; | 1050 | return 0; |
705 | } | 1051 | } |
706 | 1052 | ||
707 | static int __devinit mxs_auart_probe(struct platform_device *pdev) | 1053 | static int mxs_auart_probe(struct platform_device *pdev) |
708 | { | 1054 | { |
1055 | const struct of_device_id *of_id = | ||
1056 | of_match_device(mxs_auart_dt_ids, &pdev->dev); | ||
709 | struct mxs_auart_port *s; | 1057 | struct mxs_auart_port *s; |
710 | u32 version; | 1058 | u32 version; |
711 | int ret = 0; | 1059 | int ret = 0; |
@@ -730,6 +1078,11 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) | |||
730 | goto out_free; | 1078 | goto out_free; |
731 | } | 1079 | } |
732 | 1080 | ||
1081 | if (of_id) { | ||
1082 | pdev->id_entry = of_id->data; | ||
1083 | s->devtype = pdev->id_entry->driver_data; | ||
1084 | } | ||
1085 | |||
733 | s->clk = clk_get(&pdev->dev, NULL); | 1086 | s->clk = clk_get(&pdev->dev, NULL); |
734 | if (IS_ERR(s->clk)) { | 1087 | if (IS_ERR(s->clk)) { |
735 | ret = PTR_ERR(s->clk); | 1088 | ret = PTR_ERR(s->clk); |
@@ -751,7 +1104,6 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) | |||
751 | s->port.type = PORT_IMX; | 1104 | s->port.type = PORT_IMX; |
752 | s->port.dev = s->dev = get_device(&pdev->dev); | 1105 | s->port.dev = s->dev = get_device(&pdev->dev); |
753 | 1106 | ||
754 | s->flags = 0; | ||
755 | s->ctrl = 0; | 1107 | s->ctrl = 0; |
756 | 1108 | ||
757 | s->irq = platform_get_irq(pdev, 0); | 1109 | s->irq = platform_get_irq(pdev, 0); |
@@ -789,7 +1141,7 @@ out: | |||
789 | return ret; | 1141 | return ret; |
790 | } | 1142 | } |
791 | 1143 | ||
792 | static int __devexit mxs_auart_remove(struct platform_device *pdev) | 1144 | static int mxs_auart_remove(struct platform_device *pdev) |
793 | { | 1145 | { |
794 | struct mxs_auart_port *s = platform_get_drvdata(pdev); | 1146 | struct mxs_auart_port *s = platform_get_drvdata(pdev); |
795 | 1147 | ||
@@ -805,15 +1157,9 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev) | |||
805 | return 0; | 1157 | return 0; |
806 | } | 1158 | } |
807 | 1159 | ||
808 | static struct of_device_id mxs_auart_dt_ids[] = { | ||
809 | { .compatible = "fsl,imx23-auart", }, | ||
810 | { /* sentinel */ } | ||
811 | }; | ||
812 | MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); | ||
813 | |||
814 | static struct platform_driver mxs_auart_driver = { | 1160 | static struct platform_driver mxs_auart_driver = { |
815 | .probe = mxs_auart_probe, | 1161 | .probe = mxs_auart_probe, |
816 | .remove = __devexit_p(mxs_auart_remove), | 1162 | .remove = mxs_auart_remove, |
817 | .driver = { | 1163 | .driver = { |
818 | .name = "mxs-auart", | 1164 | .name = "mxs-auart", |
819 | .owner = THIS_MODULE, | 1165 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index df443b908ca3..e7cae1c2d7d2 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <linux/of_serial.h> | 21 | #include <linux/of_serial.h> |
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/nwpserial.h> | 23 | #include <linux/nwpserial.h> |
24 | #include <linux/clk.h> | ||
24 | 25 | ||
25 | struct of_serial_info { | 26 | struct of_serial_info { |
27 | struct clk *clk; | ||
26 | int type; | 28 | int type; |
27 | int line; | 29 | int line; |
28 | }; | 30 | }; |
@@ -50,8 +52,9 @@ EXPORT_SYMBOL_GPL(tegra_serial_handle_break); | |||
50 | /* | 52 | /* |
51 | * Fill a struct uart_port for a given device node | 53 | * Fill a struct uart_port for a given device node |
52 | */ | 54 | */ |
53 | static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | 55 | static int of_platform_serial_setup(struct platform_device *ofdev, |
54 | int type, struct uart_port *port) | 56 | int type, struct uart_port *port, |
57 | struct of_serial_info *info) | ||
55 | { | 58 | { |
56 | struct resource resource; | 59 | struct resource resource; |
57 | struct device_node *np = ofdev->dev.of_node; | 60 | struct device_node *np = ofdev->dev.of_node; |
@@ -60,8 +63,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | |||
60 | 63 | ||
61 | memset(port, 0, sizeof *port); | 64 | memset(port, 0, sizeof *port); |
62 | if (of_property_read_u32(np, "clock-frequency", &clk)) { | 65 | if (of_property_read_u32(np, "clock-frequency", &clk)) { |
63 | dev_warn(&ofdev->dev, "no clock-frequency property set\n"); | 66 | |
64 | return -ENODEV; | 67 | /* Get clk rate through clk driver if present */ |
68 | info->clk = clk_get(&ofdev->dev, NULL); | ||
69 | if (IS_ERR(info->clk)) { | ||
70 | dev_warn(&ofdev->dev, | ||
71 | "clk or clock-frequency not defined\n"); | ||
72 | return PTR_ERR(info->clk); | ||
73 | } | ||
74 | |||
75 | clk_prepare_enable(info->clk); | ||
76 | clk = clk_get_rate(info->clk); | ||
65 | } | 77 | } |
66 | /* If current-speed was set, then try not to change it. */ | 78 | /* If current-speed was set, then try not to change it. */ |
67 | if (of_property_read_u32(np, "current-speed", &spd) == 0) | 79 | if (of_property_read_u32(np, "current-speed", &spd) == 0) |
@@ -70,7 +82,7 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | |||
70 | ret = of_address_to_resource(np, 0, &resource); | 82 | ret = of_address_to_resource(np, 0, &resource); |
71 | if (ret) { | 83 | if (ret) { |
72 | dev_warn(&ofdev->dev, "invalid address\n"); | 84 | dev_warn(&ofdev->dev, "invalid address\n"); |
73 | return ret; | 85 | goto out; |
74 | } | 86 | } |
75 | 87 | ||
76 | spin_lock_init(&port->lock); | 88 | spin_lock_init(&port->lock); |
@@ -97,7 +109,8 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | |||
97 | default: | 109 | default: |
98 | dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", | 110 | dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", |
99 | prop); | 111 | prop); |
100 | return -EINVAL; | 112 | ret = -EINVAL; |
113 | goto out; | ||
101 | } | 114 | } |
102 | } | 115 | } |
103 | 116 | ||
@@ -115,13 +128,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | |||
115 | port->handle_break = tegra_serial_handle_break; | 128 | port->handle_break = tegra_serial_handle_break; |
116 | 129 | ||
117 | return 0; | 130 | return 0; |
131 | out: | ||
132 | if (info->clk) | ||
133 | clk_disable_unprepare(info->clk); | ||
134 | return ret; | ||
118 | } | 135 | } |
119 | 136 | ||
120 | /* | 137 | /* |
121 | * Try to register a serial port | 138 | * Try to register a serial port |
122 | */ | 139 | */ |
123 | static struct of_device_id of_platform_serial_table[]; | 140 | static struct of_device_id of_platform_serial_table[]; |
124 | static int __devinit of_platform_serial_probe(struct platform_device *ofdev) | 141 | static int of_platform_serial_probe(struct platform_device *ofdev) |
125 | { | 142 | { |
126 | const struct of_device_id *match; | 143 | const struct of_device_id *match; |
127 | struct of_serial_info *info; | 144 | struct of_serial_info *info; |
@@ -141,7 +158,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) | |||
141 | return -ENOMEM; | 158 | return -ENOMEM; |
142 | 159 | ||
143 | port_type = (unsigned long)match->data; | 160 | port_type = (unsigned long)match->data; |
144 | ret = of_platform_serial_setup(ofdev, port_type, &port); | 161 | ret = of_platform_serial_setup(ofdev, port_type, &port, info); |
145 | if (ret) | 162 | if (ret) |
146 | goto out; | 163 | goto out; |
147 | 164 | ||
@@ -204,6 +221,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev) | |||
204 | /* need to add code for these */ | 221 | /* need to add code for these */ |
205 | break; | 222 | break; |
206 | } | 223 | } |
224 | |||
225 | if (info->clk) | ||
226 | clk_disable_unprepare(info->clk); | ||
207 | kfree(info); | 227 | kfree(info); |
208 | return 0; | 228 | return 0; |
209 | } | 229 | } |
@@ -211,7 +231,7 @@ static int of_platform_serial_remove(struct platform_device *ofdev) | |||
211 | /* | 231 | /* |
212 | * A few common types, add more as needed. | 232 | * A few common types, add more as needed. |
213 | */ | 233 | */ |
214 | static struct of_device_id __devinitdata of_platform_serial_table[] = { | 234 | static struct of_device_id of_platform_serial_table[] = { |
215 | { .compatible = "ns8250", .data = (void *)PORT_8250, }, | 235 | { .compatible = "ns8250", .data = (void *)PORT_8250, }, |
216 | { .compatible = "ns16450", .data = (void *)PORT_16450, }, | 236 | { .compatible = "ns16450", .data = (void *)PORT_16450, }, |
217 | { .compatible = "ns16550a", .data = (void *)PORT_16550A, }, | 237 | { .compatible = "ns16550a", .data = (void *)PORT_16550A, }, |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 6d3d26a607b9..b538e2e4ae5b 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -96,7 +96,7 @@ struct uart_omap_port { | |||
96 | unsigned char msr_saved_flags; | 96 | unsigned char msr_saved_flags; |
97 | char name[20]; | 97 | char name[20]; |
98 | unsigned long port_activity; | 98 | unsigned long port_activity; |
99 | u32 context_loss_cnt; | 99 | int context_loss_cnt; |
100 | u32 errata; | 100 | u32 errata; |
101 | u8 wakeups_enabled; | 101 | u8 wakeups_enabled; |
102 | unsigned int irq_pending:1; | 102 | unsigned int irq_pending:1; |
@@ -702,11 +702,7 @@ serial_omap_configure_xonxoff | |||
702 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | 702 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); |
703 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 703 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
704 | serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); | 704 | serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); |
705 | /* Enable special char function UARTi.EFR_REG[5] and | 705 | |
706 | * load the new software flow control mode IXON or IXOFF | ||
707 | * and restore the UARTi.EFR_REG[4] ENHANCED_EN value. | ||
708 | */ | ||
709 | serial_out(up, UART_EFR, up->efr | UART_EFR_SCD); | ||
710 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 706 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
711 | 707 | ||
712 | serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); | 708 | serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); |
@@ -1081,7 +1077,7 @@ out: | |||
1081 | 1077 | ||
1082 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | 1078 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE |
1083 | 1079 | ||
1084 | static struct uart_omap_port *serial_omap_console_ports[4]; | 1080 | static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS]; |
1085 | 1081 | ||
1086 | static struct uart_driver serial_omap_reg; | 1082 | static struct uart_driver serial_omap_reg; |
1087 | 1083 | ||
@@ -1242,7 +1238,7 @@ static int serial_omap_resume(struct device *dev) | |||
1242 | } | 1238 | } |
1243 | #endif | 1239 | #endif |
1244 | 1240 | ||
1245 | static void __devinit omap_serial_fill_features_erratas(struct uart_omap_port *up) | 1241 | static void omap_serial_fill_features_erratas(struct uart_omap_port *up) |
1246 | { | 1242 | { |
1247 | u32 mvr, scheme; | 1243 | u32 mvr, scheme; |
1248 | u16 revision, major, minor; | 1244 | u16 revision, major, minor; |
@@ -1295,7 +1291,7 @@ static void __devinit omap_serial_fill_features_erratas(struct uart_omap_port *u | |||
1295 | } | 1291 | } |
1296 | } | 1292 | } |
1297 | 1293 | ||
1298 | static __devinit struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | 1294 | static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) |
1299 | { | 1295 | { |
1300 | struct omap_uart_port_info *omap_up_info; | 1296 | struct omap_uart_port_info *omap_up_info; |
1301 | 1297 | ||
@@ -1308,7 +1304,7 @@ static __devinit struct omap_uart_port_info *of_get_uart_port_info(struct device | |||
1308 | return omap_up_info; | 1304 | return omap_up_info; |
1309 | } | 1305 | } |
1310 | 1306 | ||
1311 | static int __devinit serial_omap_probe(struct platform_device *pdev) | 1307 | static int serial_omap_probe(struct platform_device *pdev) |
1312 | { | 1308 | { |
1313 | struct uart_omap_port *up; | 1309 | struct uart_omap_port *up; |
1314 | struct resource *mem, *irq; | 1310 | struct resource *mem, *irq; |
@@ -1445,7 +1441,7 @@ err_port_line: | |||
1445 | return ret; | 1441 | return ret; |
1446 | } | 1442 | } |
1447 | 1443 | ||
1448 | static int __devexit serial_omap_remove(struct platform_device *dev) | 1444 | static int serial_omap_remove(struct platform_device *dev) |
1449 | { | 1445 | { |
1450 | struct uart_omap_port *up = platform_get_drvdata(dev); | 1446 | struct uart_omap_port *up = platform_get_drvdata(dev); |
1451 | 1447 | ||
@@ -1556,11 +1552,15 @@ static int serial_omap_runtime_resume(struct device *dev) | |||
1556 | { | 1552 | { |
1557 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1553 | struct uart_omap_port *up = dev_get_drvdata(dev); |
1558 | 1554 | ||
1559 | u32 loss_cnt = serial_omap_get_context_loss_count(up); | 1555 | int loss_cnt = serial_omap_get_context_loss_count(up); |
1560 | 1556 | ||
1561 | if (up->context_loss_cnt != loss_cnt) | 1557 | if (loss_cnt < 0) { |
1558 | dev_err(dev, "serial_omap_get_context_loss_count failed : %d\n", | ||
1559 | loss_cnt); | ||
1562 | serial_omap_restore_context(up); | 1560 | serial_omap_restore_context(up); |
1563 | 1561 | } else if (up->context_loss_cnt != loss_cnt) { | |
1562 | serial_omap_restore_context(up); | ||
1563 | } | ||
1564 | up->latency = up->calc_latency; | 1564 | up->latency = up->calc_latency; |
1565 | schedule_work(&up->qos_work); | 1565 | schedule_work(&up->qos_work); |
1566 | 1566 | ||
@@ -1586,7 +1586,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match); | |||
1586 | 1586 | ||
1587 | static struct platform_driver serial_omap_driver = { | 1587 | static struct platform_driver serial_omap_driver = { |
1588 | .probe = serial_omap_probe, | 1588 | .probe = serial_omap_probe, |
1589 | .remove = __devexit_p(serial_omap_remove), | 1589 | .remove = serial_omap_remove, |
1590 | .driver = { | 1590 | .driver = { |
1591 | .name = DRIVER_NAME, | 1591 | .name = DRIVER_NAME, |
1592 | .pm = &serial_omap_dev_pm_ops, | 1592 | .pm = &serial_omap_dev_pm_ops, |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 4cd6c2381528..8318925fbf6b 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -1839,7 +1839,7 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { | |||
1839 | {0,}, | 1839 | {0,}, |
1840 | }; | 1840 | }; |
1841 | 1841 | ||
1842 | static int __devinit pch_uart_pci_probe(struct pci_dev *pdev, | 1842 | static int pch_uart_pci_probe(struct pci_dev *pdev, |
1843 | const struct pci_device_id *id) | 1843 | const struct pci_device_id *id) |
1844 | { | 1844 | { |
1845 | int ret; | 1845 | int ret; |
@@ -1869,7 +1869,7 @@ static struct pci_driver pch_uart_pci_driver = { | |||
1869 | .name = "pch_uart", | 1869 | .name = "pch_uart", |
1870 | .id_table = pch_uart_pci_id, | 1870 | .id_table = pch_uart_pci_id, |
1871 | .probe = pch_uart_pci_probe, | 1871 | .probe = pch_uart_pci_probe, |
1872 | .remove = __devexit_p(pch_uart_pci_remove), | 1872 | .remove = pch_uart_pci_remove, |
1873 | .suspend = pch_uart_pci_suspend, | 1873 | .suspend = pch_uart_pci_suspend, |
1874 | .resume = pch_uart_pci_resume, | 1874 | .resume = pch_uart_pci_resume, |
1875 | }; | 1875 | }; |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 9033fc6e0e4e..2764828251f5 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -705,6 +705,57 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
705 | clk_disable_unprepare(up->clk); | 705 | clk_disable_unprepare(up->clk); |
706 | } | 706 | } |
707 | 707 | ||
708 | #ifdef CONFIG_CONSOLE_POLL | ||
709 | /* | ||
710 | * Console polling routines for writing and reading from the uart while | ||
711 | * in an interrupt or debug context. | ||
712 | */ | ||
713 | |||
714 | static int serial_pxa_get_poll_char(struct uart_port *port) | ||
715 | { | ||
716 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; | ||
717 | unsigned char lsr = serial_in(up, UART_LSR); | ||
718 | |||
719 | while (!(lsr & UART_LSR_DR)) | ||
720 | lsr = serial_in(up, UART_LSR); | ||
721 | |||
722 | return serial_in(up, UART_RX); | ||
723 | } | ||
724 | |||
725 | |||
726 | static void serial_pxa_put_poll_char(struct uart_port *port, | ||
727 | unsigned char c) | ||
728 | { | ||
729 | unsigned int ier; | ||
730 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; | ||
731 | |||
732 | /* | ||
733 | * First save the IER then disable the interrupts | ||
734 | */ | ||
735 | ier = serial_in(up, UART_IER); | ||
736 | serial_out(up, UART_IER, UART_IER_UUE); | ||
737 | |||
738 | wait_for_xmitr(up); | ||
739 | /* | ||
740 | * Send the character out. | ||
741 | * If a LF, also do CR... | ||
742 | */ | ||
743 | serial_out(up, UART_TX, c); | ||
744 | if (c == 10) { | ||
745 | wait_for_xmitr(up); | ||
746 | serial_out(up, UART_TX, 13); | ||
747 | } | ||
748 | |||
749 | /* | ||
750 | * Finally, wait for transmitter to become empty | ||
751 | * and restore the IER | ||
752 | */ | ||
753 | wait_for_xmitr(up); | ||
754 | serial_out(up, UART_IER, ier); | ||
755 | } | ||
756 | |||
757 | #endif /* CONFIG_CONSOLE_POLL */ | ||
758 | |||
708 | static int __init | 759 | static int __init |
709 | serial_pxa_console_setup(struct console *co, char *options) | 760 | serial_pxa_console_setup(struct console *co, char *options) |
710 | { | 761 | { |
@@ -759,6 +810,10 @@ struct uart_ops serial_pxa_pops = { | |||
759 | .request_port = serial_pxa_request_port, | 810 | .request_port = serial_pxa_request_port, |
760 | .config_port = serial_pxa_config_port, | 811 | .config_port = serial_pxa_config_port, |
761 | .verify_port = serial_pxa_verify_port, | 812 | .verify_port = serial_pxa_verify_port, |
813 | #ifdef CONFIG_CONSOLE_POLL | ||
814 | .poll_get_char = serial_pxa_get_poll_char, | ||
815 | .poll_put_char = serial_pxa_put_poll_char, | ||
816 | #endif | ||
762 | }; | 817 | }; |
763 | 818 | ||
764 | static struct uart_driver serial_pxa_reg = { | 819 | static struct uart_driver serial_pxa_reg = { |
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 2ca5959ec3fa..da56c8a0fdc9 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c | |||
@@ -637,7 +637,7 @@ static void __init sa1100_init_ports(void) | |||
637 | PPSR |= PPC_TXD1 | PPC_TXD3; | 637 | PPSR |= PPC_TXD1 | PPC_TXD3; |
638 | } | 638 | } |
639 | 639 | ||
640 | void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns) | 640 | void sa1100_register_uart_fns(struct sa1100_port_fns *fns) |
641 | { | 641 | { |
642 | if (fns->get_mctrl) | 642 | if (fns->get_mctrl) |
643 | sa1100_pops.get_mctrl = fns->get_mctrl; | 643 | sa1100_pops.get_mctrl = fns->get_mctrl; |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 7f04717176aa..fb0e0f0bed0e 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -223,8 +223,11 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
223 | struct uart_port *port = &ourport->port; | 223 | struct uart_port *port = &ourport->port; |
224 | struct tty_struct *tty = port->state->port.tty; | 224 | struct tty_struct *tty = port->state->port.tty; |
225 | unsigned int ufcon, ch, flag, ufstat, uerstat; | 225 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
226 | unsigned long flags; | ||
226 | int max_count = 64; | 227 | int max_count = 64; |
227 | 228 | ||
229 | spin_lock_irqsave(&port->lock, flags); | ||
230 | |||
228 | while (max_count-- > 0) { | 231 | while (max_count-- > 0) { |
229 | ufcon = rd_regl(port, S3C2410_UFCON); | 232 | ufcon = rd_regl(port, S3C2410_UFCON); |
230 | ufstat = rd_regl(port, S3C2410_UFSTAT); | 233 | ufstat = rd_regl(port, S3C2410_UFSTAT); |
@@ -299,6 +302,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
299 | tty_flip_buffer_push(tty); | 302 | tty_flip_buffer_push(tty); |
300 | 303 | ||
301 | out: | 304 | out: |
305 | spin_unlock_irqrestore(&port->lock, flags); | ||
302 | return IRQ_HANDLED; | 306 | return IRQ_HANDLED; |
303 | } | 307 | } |
304 | 308 | ||
@@ -307,8 +311,11 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) | |||
307 | struct s3c24xx_uart_port *ourport = id; | 311 | struct s3c24xx_uart_port *ourport = id; |
308 | struct uart_port *port = &ourport->port; | 312 | struct uart_port *port = &ourport->port; |
309 | struct circ_buf *xmit = &port->state->xmit; | 313 | struct circ_buf *xmit = &port->state->xmit; |
314 | unsigned long flags; | ||
310 | int count = 256; | 315 | int count = 256; |
311 | 316 | ||
317 | spin_lock_irqsave(&port->lock, flags); | ||
318 | |||
312 | if (port->x_char) { | 319 | if (port->x_char) { |
313 | wr_regb(port, S3C2410_UTXH, port->x_char); | 320 | wr_regb(port, S3C2410_UTXH, port->x_char); |
314 | port->icount.tx++; | 321 | port->icount.tx++; |
@@ -336,13 +343,17 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) | |||
336 | port->icount.tx++; | 343 | port->icount.tx++; |
337 | } | 344 | } |
338 | 345 | ||
339 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 346 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { |
347 | spin_unlock(&port->lock); | ||
340 | uart_write_wakeup(port); | 348 | uart_write_wakeup(port); |
349 | spin_lock(&port->lock); | ||
350 | } | ||
341 | 351 | ||
342 | if (uart_circ_empty(xmit)) | 352 | if (uart_circ_empty(xmit)) |
343 | s3c24xx_serial_stop_tx(port); | 353 | s3c24xx_serial_stop_tx(port); |
344 | 354 | ||
345 | out: | 355 | out: |
356 | spin_unlock_irqrestore(&port->lock, flags); | ||
346 | return IRQ_HANDLED; | 357 | return IRQ_HANDLED; |
347 | } | 358 | } |
348 | 359 | ||
@@ -352,10 +363,8 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id) | |||
352 | struct s3c24xx_uart_port *ourport = id; | 363 | struct s3c24xx_uart_port *ourport = id; |
353 | struct uart_port *port = &ourport->port; | 364 | struct uart_port *port = &ourport->port; |
354 | unsigned int pend = rd_regl(port, S3C64XX_UINTP); | 365 | unsigned int pend = rd_regl(port, S3C64XX_UINTP); |
355 | unsigned long flags; | ||
356 | irqreturn_t ret = IRQ_HANDLED; | 366 | irqreturn_t ret = IRQ_HANDLED; |
357 | 367 | ||
358 | spin_lock_irqsave(&port->lock, flags); | ||
359 | if (pend & S3C64XX_UINTM_RXD_MSK) { | 368 | if (pend & S3C64XX_UINTM_RXD_MSK) { |
360 | ret = s3c24xx_serial_rx_chars(irq, id); | 369 | ret = s3c24xx_serial_rx_chars(irq, id); |
361 | wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK); | 370 | wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK); |
@@ -364,7 +373,6 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id) | |||
364 | ret = s3c24xx_serial_tx_chars(irq, id); | 373 | ret = s3c24xx_serial_tx_chars(irq, id); |
365 | wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK); | 374 | wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK); |
366 | } | 375 | } |
367 | spin_unlock_irqrestore(&port->lock, flags); | ||
368 | return ret; | 376 | return ret; |
369 | } | 377 | } |
370 | 378 | ||
@@ -530,16 +538,16 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, | |||
530 | switch (level) { | 538 | switch (level) { |
531 | case 3: | 539 | case 3: |
532 | if (!IS_ERR(ourport->baudclk)) | 540 | if (!IS_ERR(ourport->baudclk)) |
533 | clk_disable(ourport->baudclk); | 541 | clk_disable_unprepare(ourport->baudclk); |
534 | 542 | ||
535 | clk_disable(ourport->clk); | 543 | clk_disable_unprepare(ourport->clk); |
536 | break; | 544 | break; |
537 | 545 | ||
538 | case 0: | 546 | case 0: |
539 | clk_enable(ourport->clk); | 547 | clk_prepare_enable(ourport->clk); |
540 | 548 | ||
541 | if (!IS_ERR(ourport->baudclk)) | 549 | if (!IS_ERR(ourport->baudclk)) |
542 | clk_enable(ourport->baudclk); | 550 | clk_prepare_enable(ourport->baudclk); |
543 | 551 | ||
544 | break; | 552 | break; |
545 | default: | 553 | default: |
@@ -713,11 +721,11 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
713 | s3c24xx_serial_setsource(port, clk_sel); | 721 | s3c24xx_serial_setsource(port, clk_sel); |
714 | 722 | ||
715 | if (!IS_ERR(ourport->baudclk)) { | 723 | if (!IS_ERR(ourport->baudclk)) { |
716 | clk_disable(ourport->baudclk); | 724 | clk_disable_unprepare(ourport->baudclk); |
717 | ourport->baudclk = ERR_PTR(-EINVAL); | 725 | ourport->baudclk = ERR_PTR(-EINVAL); |
718 | } | 726 | } |
719 | 727 | ||
720 | clk_enable(clk); | 728 | clk_prepare_enable(clk); |
721 | 729 | ||
722 | ourport->baudclk = clk; | 730 | ourport->baudclk = clk; |
723 | ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; | 731 | ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; |
@@ -1256,7 +1264,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) | |||
1256 | return ret; | 1264 | return ret; |
1257 | } | 1265 | } |
1258 | 1266 | ||
1259 | static int __devexit s3c24xx_serial_remove(struct platform_device *dev) | 1267 | static int s3c24xx_serial_remove(struct platform_device *dev) |
1260 | { | 1268 | { |
1261 | struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); | 1269 | struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); |
1262 | 1270 | ||
@@ -1287,9 +1295,9 @@ static int s3c24xx_serial_resume(struct device *dev) | |||
1287 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 1295 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
1288 | 1296 | ||
1289 | if (port) { | 1297 | if (port) { |
1290 | clk_enable(ourport->clk); | 1298 | clk_prepare_enable(ourport->clk); |
1291 | s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port)); | 1299 | s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port)); |
1292 | clk_disable(ourport->clk); | 1300 | clk_disable_unprepare(ourport->clk); |
1293 | 1301 | ||
1294 | uart_resume_port(&s3c24xx_uart_drv, port); | 1302 | uart_resume_port(&s3c24xx_uart_drv, port); |
1295 | } | 1303 | } |
@@ -1701,6 +1709,16 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids); | |||
1701 | 1709 | ||
1702 | #ifdef CONFIG_OF | 1710 | #ifdef CONFIG_OF |
1703 | static const struct of_device_id s3c24xx_uart_dt_match[] = { | 1711 | static const struct of_device_id s3c24xx_uart_dt_match[] = { |
1712 | { .compatible = "samsung,s3c2410-uart", | ||
1713 | .data = (void *)S3C2410_SERIAL_DRV_DATA }, | ||
1714 | { .compatible = "samsung,s3c2412-uart", | ||
1715 | .data = (void *)S3C2412_SERIAL_DRV_DATA }, | ||
1716 | { .compatible = "samsung,s3c2440-uart", | ||
1717 | .data = (void *)S3C2440_SERIAL_DRV_DATA }, | ||
1718 | { .compatible = "samsung,s3c6400-uart", | ||
1719 | .data = (void *)S3C6400_SERIAL_DRV_DATA }, | ||
1720 | { .compatible = "samsung,s5pv210-uart", | ||
1721 | .data = (void *)S5PV210_SERIAL_DRV_DATA }, | ||
1704 | { .compatible = "samsung,exynos4210-uart", | 1722 | { .compatible = "samsung,exynos4210-uart", |
1705 | .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, | 1723 | .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, |
1706 | {}, | 1724 | {}, |
@@ -1712,7 +1730,7 @@ MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); | |||
1712 | 1730 | ||
1713 | static struct platform_driver samsung_serial_driver = { | 1731 | static struct platform_driver samsung_serial_driver = { |
1714 | .probe = s3c24xx_serial_probe, | 1732 | .probe = s3c24xx_serial_probe, |
1715 | .remove = __devexit_p(s3c24xx_serial_remove), | 1733 | .remove = s3c24xx_serial_remove, |
1716 | .id_table = s3c24xx_serial_driver_ids, | 1734 | .id_table = s3c24xx_serial_driver_ids, |
1717 | .driver = { | 1735 | .driver = { |
1718 | .name = "samsung-uart", | 1736 | .name = "samsung-uart", |
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index 9d664242b312..aced1dd923d8 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
@@ -621,7 +621,7 @@ static u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos) | |||
621 | return bit ? (1 << (bit - 1)) : 0; | 621 | return bit ? (1 << (bit - 1)) : 0; |
622 | } | 622 | } |
623 | 623 | ||
624 | static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up, | 624 | static void sc26xx_init_masks(struct uart_sc26xx_port *up, |
625 | int line, unsigned int data) | 625 | int line, unsigned int data) |
626 | { | 626 | { |
627 | up->dtr_mask[line] = sc26xx_flags2mask(data, 0); | 627 | up->dtr_mask[line] = sc26xx_flags2mask(data, 0); |
@@ -632,7 +632,7 @@ static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up, | |||
632 | up->ri_mask[line] = sc26xx_flags2mask(data, 20); | 632 | up->ri_mask[line] = sc26xx_flags2mask(data, 20); |
633 | } | 633 | } |
634 | 634 | ||
635 | static int __devinit sc26xx_probe(struct platform_device *dev) | 635 | static int sc26xx_probe(struct platform_device *dev) |
636 | { | 636 | { |
637 | struct resource *res; | 637 | struct resource *res; |
638 | struct uart_sc26xx_port *up; | 638 | struct uart_sc26xx_port *up; |
@@ -733,7 +733,7 @@ static int __exit sc26xx_driver_remove(struct platform_device *dev) | |||
733 | 733 | ||
734 | static struct platform_driver sc26xx_driver = { | 734 | static struct platform_driver sc26xx_driver = { |
735 | .probe = sc26xx_probe, | 735 | .probe = sc26xx_probe, |
736 | .remove = __devexit_p(sc26xx_driver_remove), | 736 | .remove = sc26xx_driver_remove, |
737 | .driver = { | 737 | .driver = { |
738 | .name = "SC26xx", | 738 | .name = "SC26xx", |
739 | .owner = THIS_MODULE, | 739 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index e821068cd95b..418b495e3233 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -740,7 +740,7 @@ static int sccnxp_console_setup(struct console *co, char *options) | |||
740 | } | 740 | } |
741 | #endif | 741 | #endif |
742 | 742 | ||
743 | static int __devinit sccnxp_probe(struct platform_device *pdev) | 743 | static int sccnxp_probe(struct platform_device *pdev) |
744 | { | 744 | { |
745 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 745 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
746 | int chiptype = pdev->id_entry->driver_data; | 746 | int chiptype = pdev->id_entry->driver_data; |
@@ -943,7 +943,7 @@ err_out: | |||
943 | return ret; | 943 | return ret; |
944 | } | 944 | } |
945 | 945 | ||
946 | static int __devexit sccnxp_remove(struct platform_device *pdev) | 946 | static int sccnxp_remove(struct platform_device *pdev) |
947 | { | 947 | { |
948 | int i; | 948 | int i; |
949 | struct sccnxp_port *s = platform_get_drvdata(pdev); | 949 | struct sccnxp_port *s = platform_get_drvdata(pdev); |
@@ -981,7 +981,7 @@ static struct platform_driver sccnxp_uart_driver = { | |||
981 | .owner = THIS_MODULE, | 981 | .owner = THIS_MODULE, |
982 | }, | 982 | }, |
983 | .probe = sccnxp_probe, | 983 | .probe = sccnxp_probe, |
984 | .remove = __devexit_p(sccnxp_remove), | 984 | .remove = sccnxp_remove, |
985 | .id_table = sccnxp_id_table, | 985 | .id_table = sccnxp_id_table, |
986 | }; | 986 | }; |
987 | module_platform_driver(sccnxp_uart_driver); | 987 | module_platform_driver(sccnxp_uart_driver); |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0fcfd98a9566..fb5aa42fde7e 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -634,10 +634,10 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
634 | uart_set_mctrl(port, TIOCM_RTS); | 634 | uart_set_mctrl(port, TIOCM_RTS); |
635 | } | 635 | } |
636 | 636 | ||
637 | static void uart_get_info(struct tty_port *port, | 637 | static void do_uart_get_info(struct tty_port *port, |
638 | struct uart_state *state, | ||
639 | struct serial_struct *retinfo) | 638 | struct serial_struct *retinfo) |
640 | { | 639 | { |
640 | struct uart_state *state = container_of(port, struct uart_state, port); | ||
641 | struct uart_port *uport = state->uart_port; | 641 | struct uart_port *uport = state->uart_port; |
642 | 642 | ||
643 | memset(retinfo, 0, sizeof(*retinfo)); | 643 | memset(retinfo, 0, sizeof(*retinfo)); |
@@ -662,17 +662,21 @@ static void uart_get_info(struct tty_port *port, | |||
662 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; | 662 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; |
663 | } | 663 | } |
664 | 664 | ||
665 | static int uart_get_info_user(struct uart_state *state, | 665 | static void uart_get_info(struct tty_port *port, |
666 | struct serial_struct __user *retinfo) | 666 | struct serial_struct *retinfo) |
667 | { | 667 | { |
668 | struct tty_port *port = &state->port; | ||
669 | struct serial_struct tmp; | ||
670 | |||
671 | /* Ensure the state we copy is consistent and no hardware changes | 668 | /* Ensure the state we copy is consistent and no hardware changes |
672 | occur as we go */ | 669 | occur as we go */ |
673 | mutex_lock(&port->mutex); | 670 | mutex_lock(&port->mutex); |
674 | uart_get_info(port, state, &tmp); | 671 | do_uart_get_info(port, retinfo); |
675 | mutex_unlock(&port->mutex); | 672 | mutex_unlock(&port->mutex); |
673 | } | ||
674 | |||
675 | static int uart_get_info_user(struct tty_port *port, | ||
676 | struct serial_struct __user *retinfo) | ||
677 | { | ||
678 | struct serial_struct tmp; | ||
679 | uart_get_info(port, &tmp); | ||
676 | 680 | ||
677 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 681 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
678 | return -EFAULT; | 682 | return -EFAULT; |
@@ -1131,7 +1135,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
1131 | */ | 1135 | */ |
1132 | switch (cmd) { | 1136 | switch (cmd) { |
1133 | case TIOCGSERIAL: | 1137 | case TIOCGSERIAL: |
1134 | ret = uart_get_info_user(state, uarg); | 1138 | ret = uart_get_info_user(port, uarg); |
1135 | break; | 1139 | break; |
1136 | 1140 | ||
1137 | case TIOCSSERIAL: | 1141 | case TIOCSSERIAL: |
@@ -2293,6 +2297,8 @@ int uart_register_driver(struct uart_driver *drv) | |||
2293 | if (retval >= 0) | 2297 | if (retval >= 0) |
2294 | return retval; | 2298 | return retval; |
2295 | 2299 | ||
2300 | for (i = 0; i < drv->nr; i++) | ||
2301 | tty_port_destroy(&drv->state[i].port); | ||
2296 | put_tty_driver(normal); | 2302 | put_tty_driver(normal); |
2297 | out_kfree: | 2303 | out_kfree: |
2298 | kfree(drv->state); | 2304 | kfree(drv->state); |
@@ -2312,8 +2318,12 @@ out: | |||
2312 | void uart_unregister_driver(struct uart_driver *drv) | 2318 | void uart_unregister_driver(struct uart_driver *drv) |
2313 | { | 2319 | { |
2314 | struct tty_driver *p = drv->tty_driver; | 2320 | struct tty_driver *p = drv->tty_driver; |
2321 | unsigned int i; | ||
2322 | |||
2315 | tty_unregister_driver(p); | 2323 | tty_unregister_driver(p); |
2316 | put_tty_driver(p); | 2324 | put_tty_driver(p); |
2325 | for (i = 0; i < drv->nr; i++) | ||
2326 | tty_port_destroy(&drv->state[i].port); | ||
2317 | kfree(drv->state); | 2327 | kfree(drv->state); |
2318 | drv->state = NULL; | 2328 | drv->state = NULL; |
2319 | drv->tty_driver = NULL; | 2329 | drv->tty_driver = NULL; |
@@ -2329,21 +2339,166 @@ struct tty_driver *uart_console_device(struct console *co, int *index) | |||
2329 | static ssize_t uart_get_attr_uartclk(struct device *dev, | 2339 | static ssize_t uart_get_attr_uartclk(struct device *dev, |
2330 | struct device_attribute *attr, char *buf) | 2340 | struct device_attribute *attr, char *buf) |
2331 | { | 2341 | { |
2332 | int ret; | 2342 | struct serial_struct tmp; |
2333 | struct tty_port *port = dev_get_drvdata(dev); | 2343 | struct tty_port *port = dev_get_drvdata(dev); |
2334 | struct uart_state *state = container_of(port, struct uart_state, port); | ||
2335 | 2344 | ||
2336 | mutex_lock(&state->port.mutex); | 2345 | uart_get_info(port, &tmp); |
2337 | ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); | 2346 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16); |
2338 | mutex_unlock(&state->port.mutex); | 2347 | } |
2339 | 2348 | ||
2340 | return ret; | 2349 | static ssize_t uart_get_attr_type(struct device *dev, |
2350 | struct device_attribute *attr, char *buf) | ||
2351 | { | ||
2352 | struct serial_struct tmp; | ||
2353 | struct tty_port *port = dev_get_drvdata(dev); | ||
2354 | |||
2355 | uart_get_info(port, &tmp); | ||
2356 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.type); | ||
2357 | } | ||
2358 | static ssize_t uart_get_attr_line(struct device *dev, | ||
2359 | struct device_attribute *attr, char *buf) | ||
2360 | { | ||
2361 | struct serial_struct tmp; | ||
2362 | struct tty_port *port = dev_get_drvdata(dev); | ||
2363 | |||
2364 | uart_get_info(port, &tmp); | ||
2365 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.line); | ||
2366 | } | ||
2367 | |||
2368 | static ssize_t uart_get_attr_port(struct device *dev, | ||
2369 | struct device_attribute *attr, char *buf) | ||
2370 | { | ||
2371 | struct serial_struct tmp; | ||
2372 | struct tty_port *port = dev_get_drvdata(dev); | ||
2373 | unsigned long ioaddr; | ||
2374 | |||
2375 | uart_get_info(port, &tmp); | ||
2376 | ioaddr = tmp.port; | ||
2377 | if (HIGH_BITS_OFFSET) | ||
2378 | ioaddr |= (unsigned long)tmp.port_high << HIGH_BITS_OFFSET; | ||
2379 | return snprintf(buf, PAGE_SIZE, "0x%lX\n", ioaddr); | ||
2341 | } | 2380 | } |
2342 | 2381 | ||
2382 | static ssize_t uart_get_attr_irq(struct device *dev, | ||
2383 | struct device_attribute *attr, char *buf) | ||
2384 | { | ||
2385 | struct serial_struct tmp; | ||
2386 | struct tty_port *port = dev_get_drvdata(dev); | ||
2387 | |||
2388 | uart_get_info(port, &tmp); | ||
2389 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.irq); | ||
2390 | } | ||
2391 | |||
2392 | static ssize_t uart_get_attr_flags(struct device *dev, | ||
2393 | struct device_attribute *attr, char *buf) | ||
2394 | { | ||
2395 | struct serial_struct tmp; | ||
2396 | struct tty_port *port = dev_get_drvdata(dev); | ||
2397 | |||
2398 | uart_get_info(port, &tmp); | ||
2399 | return snprintf(buf, PAGE_SIZE, "0x%X\n", tmp.flags); | ||
2400 | } | ||
2401 | |||
2402 | static ssize_t uart_get_attr_xmit_fifo_size(struct device *dev, | ||
2403 | struct device_attribute *attr, char *buf) | ||
2404 | { | ||
2405 | struct serial_struct tmp; | ||
2406 | struct tty_port *port = dev_get_drvdata(dev); | ||
2407 | |||
2408 | uart_get_info(port, &tmp); | ||
2409 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.xmit_fifo_size); | ||
2410 | } | ||
2411 | |||
2412 | |||
2413 | static ssize_t uart_get_attr_close_delay(struct device *dev, | ||
2414 | struct device_attribute *attr, char *buf) | ||
2415 | { | ||
2416 | struct serial_struct tmp; | ||
2417 | struct tty_port *port = dev_get_drvdata(dev); | ||
2418 | |||
2419 | uart_get_info(port, &tmp); | ||
2420 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.close_delay); | ||
2421 | } | ||
2422 | |||
2423 | |||
2424 | static ssize_t uart_get_attr_closing_wait(struct device *dev, | ||
2425 | struct device_attribute *attr, char *buf) | ||
2426 | { | ||
2427 | struct serial_struct tmp; | ||
2428 | struct tty_port *port = dev_get_drvdata(dev); | ||
2429 | |||
2430 | uart_get_info(port, &tmp); | ||
2431 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.closing_wait); | ||
2432 | } | ||
2433 | |||
2434 | static ssize_t uart_get_attr_custom_divisor(struct device *dev, | ||
2435 | struct device_attribute *attr, char *buf) | ||
2436 | { | ||
2437 | struct serial_struct tmp; | ||
2438 | struct tty_port *port = dev_get_drvdata(dev); | ||
2439 | |||
2440 | uart_get_info(port, &tmp); | ||
2441 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.custom_divisor); | ||
2442 | } | ||
2443 | |||
2444 | static ssize_t uart_get_attr_io_type(struct device *dev, | ||
2445 | struct device_attribute *attr, char *buf) | ||
2446 | { | ||
2447 | struct serial_struct tmp; | ||
2448 | struct tty_port *port = dev_get_drvdata(dev); | ||
2449 | |||
2450 | uart_get_info(port, &tmp); | ||
2451 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.io_type); | ||
2452 | } | ||
2453 | |||
2454 | static ssize_t uart_get_attr_iomem_base(struct device *dev, | ||
2455 | struct device_attribute *attr, char *buf) | ||
2456 | { | ||
2457 | struct serial_struct tmp; | ||
2458 | struct tty_port *port = dev_get_drvdata(dev); | ||
2459 | |||
2460 | uart_get_info(port, &tmp); | ||
2461 | return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)tmp.iomem_base); | ||
2462 | } | ||
2463 | |||
2464 | static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, | ||
2465 | struct device_attribute *attr, char *buf) | ||
2466 | { | ||
2467 | struct serial_struct tmp; | ||
2468 | struct tty_port *port = dev_get_drvdata(dev); | ||
2469 | |||
2470 | uart_get_info(port, &tmp); | ||
2471 | return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift); | ||
2472 | } | ||
2473 | |||
2474 | static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL); | ||
2475 | static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL); | ||
2476 | static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL); | ||
2477 | static DEVICE_ATTR(irq, S_IRUSR | S_IRGRP, uart_get_attr_irq, NULL); | ||
2478 | static DEVICE_ATTR(flags, S_IRUSR | S_IRGRP, uart_get_attr_flags, NULL); | ||
2479 | static DEVICE_ATTR(xmit_fifo_size, S_IRUSR | S_IRGRP, uart_get_attr_xmit_fifo_size, NULL); | ||
2343 | static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); | 2480 | static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); |
2481 | static DEVICE_ATTR(close_delay, S_IRUSR | S_IRGRP, uart_get_attr_close_delay, NULL); | ||
2482 | static DEVICE_ATTR(closing_wait, S_IRUSR | S_IRGRP, uart_get_attr_closing_wait, NULL); | ||
2483 | static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divisor, NULL); | ||
2484 | static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL); | ||
2485 | static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL); | ||
2486 | static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL); | ||
2344 | 2487 | ||
2345 | static struct attribute *tty_dev_attrs[] = { | 2488 | static struct attribute *tty_dev_attrs[] = { |
2489 | &dev_attr_type.attr, | ||
2490 | &dev_attr_line.attr, | ||
2491 | &dev_attr_port.attr, | ||
2492 | &dev_attr_irq.attr, | ||
2493 | &dev_attr_flags.attr, | ||
2494 | &dev_attr_xmit_fifo_size.attr, | ||
2346 | &dev_attr_uartclk.attr, | 2495 | &dev_attr_uartclk.attr, |
2496 | &dev_attr_close_delay.attr, | ||
2497 | &dev_attr_closing_wait.attr, | ||
2498 | &dev_attr_custom_divisor.attr, | ||
2499 | &dev_attr_io_type.attr, | ||
2500 | &dev_attr_iomem_base.attr, | ||
2501 | &dev_attr_iomem_reg_shift.attr, | ||
2347 | NULL, | 2502 | NULL, |
2348 | }; | 2503 | }; |
2349 | 2504 | ||
@@ -2356,6 +2511,7 @@ static const struct attribute_group *tty_dev_attr_groups[] = { | |||
2356 | NULL | 2511 | NULL |
2357 | }; | 2512 | }; |
2358 | 2513 | ||
2514 | |||
2359 | /** | 2515 | /** |
2360 | * uart_add_one_port - attach a driver-defined port structure | 2516 | * uart_add_one_port - attach a driver-defined port structure |
2361 | * @drv: pointer to the uart low level driver structure for this port | 2517 | * @drv: pointer to the uart low level driver structure for this port |
diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 6ae2a58d62f2..b52b21aeb250 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c | |||
@@ -1030,7 +1030,7 @@ static DEFINE_MUTEX(serial_txx9_mutex); | |||
1030 | * | 1030 | * |
1031 | * On success the port is ready to use and the line number is returned. | 1031 | * On success the port is ready to use and the line number is returned. |
1032 | */ | 1032 | */ |
1033 | static int __devinit serial_txx9_register_port(struct uart_port *port) | 1033 | static int serial_txx9_register_port(struct uart_port *port) |
1034 | { | 1034 | { |
1035 | int i; | 1035 | int i; |
1036 | struct uart_txx9_port *uart; | 1036 | struct uart_txx9_port *uart; |
@@ -1078,7 +1078,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port) | |||
1078 | * Remove one serial port. This may not be called from interrupt | 1078 | * Remove one serial port. This may not be called from interrupt |
1079 | * context. We hand the port back to the our control. | 1079 | * context. We hand the port back to the our control. |
1080 | */ | 1080 | */ |
1081 | static void __devexit serial_txx9_unregister_port(int line) | 1081 | static void serial_txx9_unregister_port(int line) |
1082 | { | 1082 | { |
1083 | struct uart_txx9_port *uart = &serial_txx9_ports[line]; | 1083 | struct uart_txx9_port *uart = &serial_txx9_ports[line]; |
1084 | 1084 | ||
@@ -1096,7 +1096,7 @@ static void __devexit serial_txx9_unregister_port(int line) | |||
1096 | /* | 1096 | /* |
1097 | * Register a set of serial devices attached to a platform device. | 1097 | * Register a set of serial devices attached to a platform device. |
1098 | */ | 1098 | */ |
1099 | static int __devinit serial_txx9_probe(struct platform_device *dev) | 1099 | static int serial_txx9_probe(struct platform_device *dev) |
1100 | { | 1100 | { |
1101 | struct uart_port *p = dev->dev.platform_data; | 1101 | struct uart_port *p = dev->dev.platform_data; |
1102 | struct uart_port port; | 1102 | struct uart_port port; |
@@ -1126,7 +1126,7 @@ static int __devinit serial_txx9_probe(struct platform_device *dev) | |||
1126 | /* | 1126 | /* |
1127 | * Remove serial ports registered against a platform device. | 1127 | * Remove serial ports registered against a platform device. |
1128 | */ | 1128 | */ |
1129 | static int __devexit serial_txx9_remove(struct platform_device *dev) | 1129 | static int serial_txx9_remove(struct platform_device *dev) |
1130 | { | 1130 | { |
1131 | int i; | 1131 | int i; |
1132 | 1132 | ||
@@ -1171,7 +1171,7 @@ static int serial_txx9_resume(struct platform_device *dev) | |||
1171 | 1171 | ||
1172 | static struct platform_driver serial_txx9_plat_driver = { | 1172 | static struct platform_driver serial_txx9_plat_driver = { |
1173 | .probe = serial_txx9_probe, | 1173 | .probe = serial_txx9_probe, |
1174 | .remove = __devexit_p(serial_txx9_remove), | 1174 | .remove = serial_txx9_remove, |
1175 | #ifdef CONFIG_PM | 1175 | #ifdef CONFIG_PM |
1176 | .suspend = serial_txx9_suspend, | 1176 | .suspend = serial_txx9_suspend, |
1177 | .resume = serial_txx9_resume, | 1177 | .resume = serial_txx9_resume, |
@@ -1187,7 +1187,7 @@ static struct platform_driver serial_txx9_plat_driver = { | |||
1187 | * Probe one serial board. Unfortunately, there is no rhyme nor reason | 1187 | * Probe one serial board. Unfortunately, there is no rhyme nor reason |
1188 | * to the arrangement of serial ports on a PCI card. | 1188 | * to the arrangement of serial ports on a PCI card. |
1189 | */ | 1189 | */ |
1190 | static int __devinit | 1190 | static int |
1191 | pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | 1191 | pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent) |
1192 | { | 1192 | { |
1193 | struct uart_port port; | 1193 | struct uart_port port; |
@@ -1217,7 +1217,7 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1217 | return 0; | 1217 | return 0; |
1218 | } | 1218 | } |
1219 | 1219 | ||
1220 | static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev) | 1220 | static void pciserial_txx9_remove_one(struct pci_dev *dev) |
1221 | { | 1221 | { |
1222 | struct uart_txx9_port *up = pci_get_drvdata(dev); | 1222 | struct uart_txx9_port *up = pci_get_drvdata(dev); |
1223 | 1223 | ||
@@ -1261,7 +1261,7 @@ static const struct pci_device_id serial_txx9_pci_tbl[] = { | |||
1261 | static struct pci_driver serial_txx9_pci_driver = { | 1261 | static struct pci_driver serial_txx9_pci_driver = { |
1262 | .name = "serial_txx9", | 1262 | .name = "serial_txx9", |
1263 | .probe = pciserial_txx9_init_one, | 1263 | .probe = pciserial_txx9_init_one, |
1264 | .remove = __devexit_p(pciserial_txx9_remove_one), | 1264 | .remove = pciserial_txx9_remove_one, |
1265 | #ifdef CONFIG_PM | 1265 | #ifdef CONFIG_PM |
1266 | .suspend = pciserial_txx9_suspend_one, | 1266 | .suspend = pciserial_txx9_suspend_one, |
1267 | .resume = pciserial_txx9_resume_one, | 1267 | .resume = pciserial_txx9_resume_one, |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 6ee59001d61d..61477567423f 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -99,12 +99,6 @@ struct sci_port { | |||
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | struct notifier_block freq_transition; | 101 | struct notifier_block freq_transition; |
102 | |||
103 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
104 | unsigned short saved_smr; | ||
105 | unsigned short saved_fcr; | ||
106 | unsigned char saved_brr; | ||
107 | #endif | ||
108 | }; | 102 | }; |
109 | 103 | ||
110 | /* Function prototypes */ | 104 | /* Function prototypes */ |
@@ -202,9 +196,9 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
202 | [SCxSR] = { 0x14, 16 }, | 196 | [SCxSR] = { 0x14, 16 }, |
203 | [SCxRDR] = { 0x60, 8 }, | 197 | [SCxRDR] = { 0x60, 8 }, |
204 | [SCFCR] = { 0x18, 16 }, | 198 | [SCFCR] = { 0x18, 16 }, |
205 | [SCFDR] = { 0x1c, 16 }, | 199 | [SCFDR] = sci_reg_invalid, |
206 | [SCTFDR] = sci_reg_invalid, | 200 | [SCTFDR] = { 0x38, 16 }, |
207 | [SCRFDR] = sci_reg_invalid, | 201 | [SCRFDR] = { 0x3c, 16 }, |
208 | [SCSPTR] = sci_reg_invalid, | 202 | [SCSPTR] = sci_reg_invalid, |
209 | [SCLSR] = sci_reg_invalid, | 203 | [SCLSR] = sci_reg_invalid, |
210 | }, | 204 | }, |
@@ -491,7 +485,7 @@ static int sci_txfill(struct uart_port *port) | |||
491 | 485 | ||
492 | reg = sci_getreg(port, SCTFDR); | 486 | reg = sci_getreg(port, SCTFDR); |
493 | if (reg->size) | 487 | if (reg->size) |
494 | return serial_port_in(port, SCTFDR) & 0xff; | 488 | return serial_port_in(port, SCTFDR) & ((port->fifosize << 1) - 1); |
495 | 489 | ||
496 | reg = sci_getreg(port, SCFDR); | 490 | reg = sci_getreg(port, SCFDR); |
497 | if (reg->size) | 491 | if (reg->size) |
@@ -511,7 +505,7 @@ static int sci_rxfill(struct uart_port *port) | |||
511 | 505 | ||
512 | reg = sci_getreg(port, SCRFDR); | 506 | reg = sci_getreg(port, SCRFDR); |
513 | if (reg->size) | 507 | if (reg->size) |
514 | return serial_port_in(port, SCRFDR) & 0xff; | 508 | return serial_port_in(port, SCRFDR) & ((port->fifosize << 1) - 1); |
515 | 509 | ||
516 | reg = sci_getreg(port, SCFDR); | 510 | reg = sci_getreg(port, SCFDR); |
517 | if (reg->size) | 511 | if (reg->size) |
@@ -1132,7 +1126,7 @@ static const char *sci_gpio_str(unsigned int index) | |||
1132 | return sci_gpio_names[index]; | 1126 | return sci_gpio_names[index]; |
1133 | } | 1127 | } |
1134 | 1128 | ||
1135 | static void __devinit sci_init_gpios(struct sci_port *port) | 1129 | static void sci_init_gpios(struct sci_port *port) |
1136 | { | 1130 | { |
1137 | struct uart_port *up = &port->port; | 1131 | struct uart_port *up = &port->port; |
1138 | int i; | 1132 | int i; |
@@ -1749,22 +1743,21 @@ static inline void sci_free_dma(struct uart_port *port) | |||
1749 | static int sci_startup(struct uart_port *port) | 1743 | static int sci_startup(struct uart_port *port) |
1750 | { | 1744 | { |
1751 | struct sci_port *s = to_sci_port(port); | 1745 | struct sci_port *s = to_sci_port(port); |
1746 | unsigned long flags; | ||
1752 | int ret; | 1747 | int ret; |
1753 | 1748 | ||
1754 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1749 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
1755 | 1750 | ||
1756 | pm_runtime_put_noidle(port->dev); | ||
1757 | |||
1758 | sci_port_enable(s); | ||
1759 | |||
1760 | ret = sci_request_irq(s); | 1751 | ret = sci_request_irq(s); |
1761 | if (unlikely(ret < 0)) | 1752 | if (unlikely(ret < 0)) |
1762 | return ret; | 1753 | return ret; |
1763 | 1754 | ||
1764 | sci_request_dma(port); | 1755 | sci_request_dma(port); |
1765 | 1756 | ||
1757 | spin_lock_irqsave(&port->lock, flags); | ||
1766 | sci_start_tx(port); | 1758 | sci_start_tx(port); |
1767 | sci_start_rx(port); | 1759 | sci_start_rx(port); |
1760 | spin_unlock_irqrestore(&port->lock, flags); | ||
1768 | 1761 | ||
1769 | return 0; | 1762 | return 0; |
1770 | } | 1763 | } |
@@ -1772,18 +1765,17 @@ static int sci_startup(struct uart_port *port) | |||
1772 | static void sci_shutdown(struct uart_port *port) | 1765 | static void sci_shutdown(struct uart_port *port) |
1773 | { | 1766 | { |
1774 | struct sci_port *s = to_sci_port(port); | 1767 | struct sci_port *s = to_sci_port(port); |
1768 | unsigned long flags; | ||
1775 | 1769 | ||
1776 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1770 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
1777 | 1771 | ||
1772 | spin_lock_irqsave(&port->lock, flags); | ||
1778 | sci_stop_rx(port); | 1773 | sci_stop_rx(port); |
1779 | sci_stop_tx(port); | 1774 | sci_stop_tx(port); |
1775 | spin_unlock_irqrestore(&port->lock, flags); | ||
1780 | 1776 | ||
1781 | sci_free_dma(port); | 1777 | sci_free_dma(port); |
1782 | sci_free_irq(s); | 1778 | sci_free_irq(s); |
1783 | |||
1784 | sci_port_disable(s); | ||
1785 | |||
1786 | pm_runtime_get_noresume(port->dev); | ||
1787 | } | 1779 | } |
1788 | 1780 | ||
1789 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | 1781 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, |
@@ -1829,7 +1821,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1829 | { | 1821 | { |
1830 | struct sci_port *s = to_sci_port(port); | 1822 | struct sci_port *s = to_sci_port(port); |
1831 | struct plat_sci_reg *reg; | 1823 | struct plat_sci_reg *reg; |
1832 | unsigned int baud, smr_val, max_baud; | 1824 | unsigned int baud, smr_val, max_baud, cks; |
1833 | int t = -1; | 1825 | int t = -1; |
1834 | 1826 | ||
1835 | /* | 1827 | /* |
@@ -1863,21 +1855,18 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1863 | 1855 | ||
1864 | uart_update_timeout(port, termios->c_cflag, baud); | 1856 | uart_update_timeout(port, termios->c_cflag, baud); |
1865 | 1857 | ||
1866 | serial_port_out(port, SCSMR, smr_val); | 1858 | for (cks = 0; t >= 256 && cks <= 3; cks++) |
1867 | 1859 | t >>= 2; | |
1868 | dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, | ||
1869 | s->cfg->scscr); | ||
1870 | 1860 | ||
1871 | if (t > 0) { | 1861 | dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", |
1872 | if (t >= 256) { | 1862 | __func__, smr_val, cks, t, s->cfg->scscr); |
1873 | serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1); | ||
1874 | t >>= 2; | ||
1875 | } else | ||
1876 | serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3); | ||
1877 | 1863 | ||
1864 | if (t >= 0) { | ||
1865 | serial_port_out(port, SCSMR, (smr_val & ~3) | cks); | ||
1878 | serial_port_out(port, SCBRR, t); | 1866 | serial_port_out(port, SCBRR, t); |
1879 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ | 1867 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ |
1880 | } | 1868 | } else |
1869 | serial_port_out(port, SCSMR, smr_val); | ||
1881 | 1870 | ||
1882 | sci_init_pins(port, termios->c_cflag); | 1871 | sci_init_pins(port, termios->c_cflag); |
1883 | 1872 | ||
@@ -1932,6 +1921,21 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1932 | sci_port_disable(s); | 1921 | sci_port_disable(s); |
1933 | } | 1922 | } |
1934 | 1923 | ||
1924 | static void sci_pm(struct uart_port *port, unsigned int state, | ||
1925 | unsigned int oldstate) | ||
1926 | { | ||
1927 | struct sci_port *sci_port = to_sci_port(port); | ||
1928 | |||
1929 | switch (state) { | ||
1930 | case 3: | ||
1931 | sci_port_disable(sci_port); | ||
1932 | break; | ||
1933 | default: | ||
1934 | sci_port_enable(sci_port); | ||
1935 | break; | ||
1936 | } | ||
1937 | } | ||
1938 | |||
1935 | static const char *sci_type(struct uart_port *port) | 1939 | static const char *sci_type(struct uart_port *port) |
1936 | { | 1940 | { |
1937 | switch (port->type) { | 1941 | switch (port->type) { |
@@ -2053,6 +2057,7 @@ static struct uart_ops sci_uart_ops = { | |||
2053 | .startup = sci_startup, | 2057 | .startup = sci_startup, |
2054 | .shutdown = sci_shutdown, | 2058 | .shutdown = sci_shutdown, |
2055 | .set_termios = sci_set_termios, | 2059 | .set_termios = sci_set_termios, |
2060 | .pm = sci_pm, | ||
2056 | .type = sci_type, | 2061 | .type = sci_type, |
2057 | .release_port = sci_release_port, | 2062 | .release_port = sci_release_port, |
2058 | .request_port = sci_request_port, | 2063 | .request_port = sci_request_port, |
@@ -2064,7 +2069,7 @@ static struct uart_ops sci_uart_ops = { | |||
2064 | #endif | 2069 | #endif |
2065 | }; | 2070 | }; |
2066 | 2071 | ||
2067 | static int __devinit sci_init_single(struct platform_device *dev, | 2072 | static int sci_init_single(struct platform_device *dev, |
2068 | struct sci_port *sci_port, | 2073 | struct sci_port *sci_port, |
2069 | unsigned int index, | 2074 | unsigned int index, |
2070 | struct plat_sci_port *p) | 2075 | struct plat_sci_port *p) |
@@ -2121,8 +2126,6 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
2121 | 2126 | ||
2122 | sci_init_gpios(sci_port); | 2127 | sci_init_gpios(sci_port); |
2123 | 2128 | ||
2124 | pm_runtime_irq_safe(&dev->dev); | ||
2125 | pm_runtime_get_noresume(&dev->dev); | ||
2126 | pm_runtime_enable(&dev->dev); | 2129 | pm_runtime_enable(&dev->dev); |
2127 | } | 2130 | } |
2128 | 2131 | ||
@@ -2206,9 +2209,21 @@ static void serial_console_write(struct console *co, const char *s, | |||
2206 | { | 2209 | { |
2207 | struct sci_port *sci_port = &sci_ports[co->index]; | 2210 | struct sci_port *sci_port = &sci_ports[co->index]; |
2208 | struct uart_port *port = &sci_port->port; | 2211 | struct uart_port *port = &sci_port->port; |
2209 | unsigned short bits; | 2212 | unsigned short bits, ctrl; |
2213 | unsigned long flags; | ||
2214 | int locked = 1; | ||
2215 | |||
2216 | local_irq_save(flags); | ||
2217 | if (port->sysrq) | ||
2218 | locked = 0; | ||
2219 | else if (oops_in_progress) | ||
2220 | locked = spin_trylock(&port->lock); | ||
2221 | else | ||
2222 | spin_lock(&port->lock); | ||
2210 | 2223 | ||
2211 | sci_port_enable(sci_port); | 2224 | /* first save the SCSCR then disable the interrupts */ |
2225 | ctrl = serial_port_in(port, SCSCR); | ||
2226 | serial_port_out(port, SCSCR, sci_port->cfg->scscr); | ||
2212 | 2227 | ||
2213 | uart_console_write(port, s, count, serial_console_putchar); | 2228 | uart_console_write(port, s, count, serial_console_putchar); |
2214 | 2229 | ||
@@ -2217,10 +2232,15 @@ static void serial_console_write(struct console *co, const char *s, | |||
2217 | while ((serial_port_in(port, SCxSR) & bits) != bits) | 2232 | while ((serial_port_in(port, SCxSR) & bits) != bits) |
2218 | cpu_relax(); | 2233 | cpu_relax(); |
2219 | 2234 | ||
2220 | sci_port_disable(sci_port); | 2235 | /* restore the SCSCR */ |
2236 | serial_port_out(port, SCSCR, ctrl); | ||
2237 | |||
2238 | if (locked) | ||
2239 | spin_unlock(&port->lock); | ||
2240 | local_irq_restore(flags); | ||
2221 | } | 2241 | } |
2222 | 2242 | ||
2223 | static int __devinit serial_console_setup(struct console *co, char *options) | 2243 | static int serial_console_setup(struct console *co, char *options) |
2224 | { | 2244 | { |
2225 | struct sci_port *sci_port; | 2245 | struct sci_port *sci_port; |
2226 | struct uart_port *port; | 2246 | struct uart_port *port; |
@@ -2249,13 +2269,9 @@ static int __devinit serial_console_setup(struct console *co, char *options) | |||
2249 | if (unlikely(ret != 0)) | 2269 | if (unlikely(ret != 0)) |
2250 | return ret; | 2270 | return ret; |
2251 | 2271 | ||
2252 | sci_port_enable(sci_port); | ||
2253 | |||
2254 | if (options) | 2272 | if (options) |
2255 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 2273 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
2256 | 2274 | ||
2257 | sci_port_disable(sci_port); | ||
2258 | |||
2259 | return uart_set_options(port, co, baud, parity, bits, flow); | 2275 | return uart_set_options(port, co, baud, parity, bits, flow); |
2260 | } | 2276 | } |
2261 | 2277 | ||
@@ -2278,7 +2294,7 @@ static struct console early_serial_console = { | |||
2278 | 2294 | ||
2279 | static char early_serial_buf[32]; | 2295 | static char early_serial_buf[32]; |
2280 | 2296 | ||
2281 | static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | 2297 | static int sci_probe_earlyprintk(struct platform_device *pdev) |
2282 | { | 2298 | { |
2283 | struct plat_sci_port *cfg = pdev->dev.platform_data; | 2299 | struct plat_sci_port *cfg = pdev->dev.platform_data; |
2284 | 2300 | ||
@@ -2298,57 +2314,15 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | |||
2298 | return 0; | 2314 | return 0; |
2299 | } | 2315 | } |
2300 | 2316 | ||
2301 | #define uart_console(port) ((port)->cons->index == (port)->line) | ||
2302 | |||
2303 | static int sci_runtime_suspend(struct device *dev) | ||
2304 | { | ||
2305 | struct sci_port *sci_port = dev_get_drvdata(dev); | ||
2306 | struct uart_port *port = &sci_port->port; | ||
2307 | |||
2308 | if (uart_console(port)) { | ||
2309 | struct plat_sci_reg *reg; | ||
2310 | |||
2311 | sci_port->saved_smr = serial_port_in(port, SCSMR); | ||
2312 | sci_port->saved_brr = serial_port_in(port, SCBRR); | ||
2313 | |||
2314 | reg = sci_getreg(port, SCFCR); | ||
2315 | if (reg->size) | ||
2316 | sci_port->saved_fcr = serial_port_in(port, SCFCR); | ||
2317 | else | ||
2318 | sci_port->saved_fcr = 0; | ||
2319 | } | ||
2320 | return 0; | ||
2321 | } | ||
2322 | |||
2323 | static int sci_runtime_resume(struct device *dev) | ||
2324 | { | ||
2325 | struct sci_port *sci_port = dev_get_drvdata(dev); | ||
2326 | struct uart_port *port = &sci_port->port; | ||
2327 | |||
2328 | if (uart_console(port)) { | ||
2329 | sci_reset(port); | ||
2330 | serial_port_out(port, SCSMR, sci_port->saved_smr); | ||
2331 | serial_port_out(port, SCBRR, sci_port->saved_brr); | ||
2332 | |||
2333 | if (sci_port->saved_fcr) | ||
2334 | serial_port_out(port, SCFCR, sci_port->saved_fcr); | ||
2335 | |||
2336 | serial_port_out(port, SCSCR, sci_port->cfg->scscr); | ||
2337 | } | ||
2338 | return 0; | ||
2339 | } | ||
2340 | |||
2341 | #define SCI_CONSOLE (&serial_console) | 2317 | #define SCI_CONSOLE (&serial_console) |
2342 | 2318 | ||
2343 | #else | 2319 | #else |
2344 | static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | 2320 | static inline int sci_probe_earlyprintk(struct platform_device *pdev) |
2345 | { | 2321 | { |
2346 | return -EINVAL; | 2322 | return -EINVAL; |
2347 | } | 2323 | } |
2348 | 2324 | ||
2349 | #define SCI_CONSOLE NULL | 2325 | #define SCI_CONSOLE NULL |
2350 | #define sci_runtime_suspend NULL | ||
2351 | #define sci_runtime_resume NULL | ||
2352 | 2326 | ||
2353 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 2327 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
2354 | 2328 | ||
@@ -2379,7 +2353,7 @@ static int sci_remove(struct platform_device *dev) | |||
2379 | return 0; | 2353 | return 0; |
2380 | } | 2354 | } |
2381 | 2355 | ||
2382 | static int __devinit sci_probe_single(struct platform_device *dev, | 2356 | static int sci_probe_single(struct platform_device *dev, |
2383 | unsigned int index, | 2357 | unsigned int index, |
2384 | struct plat_sci_port *p, | 2358 | struct plat_sci_port *p, |
2385 | struct sci_port *sciport) | 2359 | struct sci_port *sciport) |
@@ -2409,7 +2383,7 @@ static int __devinit sci_probe_single(struct platform_device *dev, | |||
2409 | return 0; | 2383 | return 0; |
2410 | } | 2384 | } |
2411 | 2385 | ||
2412 | static int __devinit sci_probe(struct platform_device *dev) | 2386 | static int sci_probe(struct platform_device *dev) |
2413 | { | 2387 | { |
2414 | struct plat_sci_port *p = dev->dev.platform_data; | 2388 | struct plat_sci_port *p = dev->dev.platform_data; |
2415 | struct sci_port *sp = &sci_ports[dev->id]; | 2389 | struct sci_port *sp = &sci_ports[dev->id]; |
@@ -2466,8 +2440,6 @@ static int sci_resume(struct device *dev) | |||
2466 | } | 2440 | } |
2467 | 2441 | ||
2468 | static const struct dev_pm_ops sci_dev_pm_ops = { | 2442 | static const struct dev_pm_ops sci_dev_pm_ops = { |
2469 | .runtime_suspend = sci_runtime_suspend, | ||
2470 | .runtime_resume = sci_runtime_resume, | ||
2471 | .suspend = sci_suspend, | 2443 | .suspend = sci_suspend, |
2472 | .resume = sci_resume, | 2444 | .resume = sci_resume, |
2473 | }; | 2445 | }; |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index a9e2bd1ab534..5da5cb962769 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -727,7 +727,7 @@ static int sirfsoc_uart_resume(struct platform_device *pdev) | |||
727 | return 0; | 727 | return 0; |
728 | } | 728 | } |
729 | 729 | ||
730 | static struct of_device_id sirfsoc_uart_ids[] __devinitdata = { | 730 | static struct of_device_id sirfsoc_uart_ids[] = { |
731 | { .compatible = "sirf,prima2-uart", }, | 731 | { .compatible = "sirf,prima2-uart", }, |
732 | {} | 732 | {} |
733 | }; | 733 | }; |
@@ -735,7 +735,7 @@ MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); | |||
735 | 735 | ||
736 | static struct platform_driver sirfsoc_uart_driver = { | 736 | static struct platform_driver sirfsoc_uart_driver = { |
737 | .probe = sirfsoc_uart_probe, | 737 | .probe = sirfsoc_uart_probe, |
738 | .remove = __devexit_p(sirfsoc_uart_remove), | 738 | .remove = sirfsoc_uart_remove, |
739 | .suspend = sirfsoc_uart_suspend, | 739 | .suspend = sirfsoc_uart_suspend, |
740 | .resume = sirfsoc_uart_resume, | 740 | .resume = sirfsoc_uart_resume, |
741 | .driver = { | 741 | .driver = { |
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 505961cfd934..b9bf9c53f7fd 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
@@ -519,7 +519,7 @@ static struct console sunhv_console = { | |||
519 | .data = &sunhv_reg, | 519 | .data = &sunhv_reg, |
520 | }; | 520 | }; |
521 | 521 | ||
522 | static int __devinit hv_probe(struct platform_device *op) | 522 | static int hv_probe(struct platform_device *op) |
523 | { | 523 | { |
524 | struct uart_port *port; | 524 | struct uart_port *port; |
525 | unsigned long minor; | 525 | unsigned long minor; |
@@ -598,7 +598,7 @@ out_free_port: | |||
598 | return err; | 598 | return err; |
599 | } | 599 | } |
600 | 600 | ||
601 | static int __devexit hv_remove(struct platform_device *dev) | 601 | static int hv_remove(struct platform_device *dev) |
602 | { | 602 | { |
603 | struct uart_port *port = dev_get_drvdata(&dev->dev); | 603 | struct uart_port *port = dev_get_drvdata(&dev->dev); |
604 | 604 | ||
@@ -636,7 +636,7 @@ static struct platform_driver hv_driver = { | |||
636 | .of_match_table = hv_match, | 636 | .of_match_table = hv_match, |
637 | }, | 637 | }, |
638 | .probe = hv_probe, | 638 | .probe = hv_probe, |
639 | .remove = __devexit_p(hv_remove), | 639 | .remove = hv_remove, |
640 | }; | 640 | }; |
641 | 641 | ||
642 | static int __init sunhv_init(void) | 642 | static int __init sunhv_init(void) |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index f0d93eb7e6ec..bd8b3b634103 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -954,7 +954,7 @@ static inline struct console *SUNSAB_CONSOLE(void) | |||
954 | #define sunsab_console_init() do { } while (0) | 954 | #define sunsab_console_init() do { } while (0) |
955 | #endif | 955 | #endif |
956 | 956 | ||
957 | static int __devinit sunsab_init_one(struct uart_sunsab_port *up, | 957 | static int sunsab_init_one(struct uart_sunsab_port *up, |
958 | struct platform_device *op, | 958 | struct platform_device *op, |
959 | unsigned long offset, | 959 | unsigned long offset, |
960 | int line) | 960 | int line) |
@@ -1007,7 +1007,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, | |||
1007 | return 0; | 1007 | return 0; |
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | static int __devinit sab_probe(struct platform_device *op) | 1010 | static int sab_probe(struct platform_device *op) |
1011 | { | 1011 | { |
1012 | static int inst; | 1012 | static int inst; |
1013 | struct uart_sunsab_port *up; | 1013 | struct uart_sunsab_port *up; |
@@ -1063,7 +1063,7 @@ out: | |||
1063 | return err; | 1063 | return err; |
1064 | } | 1064 | } |
1065 | 1065 | ||
1066 | static int __devexit sab_remove(struct platform_device *op) | 1066 | static int sab_remove(struct platform_device *op) |
1067 | { | 1067 | { |
1068 | struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); | 1068 | struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); |
1069 | 1069 | ||
@@ -1100,7 +1100,7 @@ static struct platform_driver sab_driver = { | |||
1100 | .of_match_table = sab_match, | 1100 | .of_match_table = sab_match, |
1101 | }, | 1101 | }, |
1102 | .probe = sab_probe, | 1102 | .probe = sab_probe, |
1103 | .remove = __devexit_p(sab_remove), | 1103 | .remove = sab_remove, |
1104 | }; | 1104 | }; |
1105 | 1105 | ||
1106 | static int __init sunsab_init(void) | 1106 | static int __init sunsab_init(void) |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index b97913dcdbff..220da3f9724f 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
@@ -1185,7 +1185,7 @@ static struct uart_driver sunsu_reg = { | |||
1185 | .major = TTY_MAJOR, | 1185 | .major = TTY_MAJOR, |
1186 | }; | 1186 | }; |
1187 | 1187 | ||
1188 | static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up) | 1188 | static int sunsu_kbd_ms_init(struct uart_sunsu_port *up) |
1189 | { | 1189 | { |
1190 | int quot, baud; | 1190 | int quot, baud; |
1191 | #ifdef CONFIG_SERIO | 1191 | #ifdef CONFIG_SERIO |
@@ -1391,7 +1391,7 @@ static inline struct console *SUNSU_CONSOLE(void) | |||
1391 | #define sunsu_serial_console_init() do { } while (0) | 1391 | #define sunsu_serial_console_init() do { } while (0) |
1392 | #endif | 1392 | #endif |
1393 | 1393 | ||
1394 | static enum su_type __devinit su_get_type(struct device_node *dp) | 1394 | static enum su_type su_get_type(struct device_node *dp) |
1395 | { | 1395 | { |
1396 | struct device_node *ap = of_find_node_by_path("/aliases"); | 1396 | struct device_node *ap = of_find_node_by_path("/aliases"); |
1397 | 1397 | ||
@@ -1412,7 +1412,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp) | |||
1412 | return SU_PORT_PORT; | 1412 | return SU_PORT_PORT; |
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | static int __devinit su_probe(struct platform_device *op) | 1415 | static int su_probe(struct platform_device *op) |
1416 | { | 1416 | { |
1417 | static int inst; | 1417 | static int inst; |
1418 | struct device_node *dp = op->dev.of_node; | 1418 | struct device_node *dp = op->dev.of_node; |
@@ -1503,7 +1503,7 @@ out_unmap: | |||
1503 | return err; | 1503 | return err; |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | static int __devexit su_remove(struct platform_device *op) | 1506 | static int su_remove(struct platform_device *op) |
1507 | { | 1507 | { |
1508 | struct uart_sunsu_port *up = dev_get_drvdata(&op->dev); | 1508 | struct uart_sunsu_port *up = dev_get_drvdata(&op->dev); |
1509 | bool kbdms = false; | 1509 | bool kbdms = false; |
@@ -1556,7 +1556,7 @@ static struct platform_driver su_driver = { | |||
1556 | .of_match_table = su_match, | 1556 | .of_match_table = su_match, |
1557 | }, | 1557 | }, |
1558 | .probe = su_probe, | 1558 | .probe = su_probe, |
1559 | .remove = __devexit_p(su_remove), | 1559 | .remove = su_remove, |
1560 | }; | 1560 | }; |
1561 | 1561 | ||
1562 | static int __init sunsu_init(void) | 1562 | static int __init sunsu_init(void) |
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index babd9470982b..aef4fab957c3 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
@@ -1282,7 +1282,7 @@ static inline struct console *SUNZILOG_CONSOLE(void) | |||
1282 | #define SUNZILOG_CONSOLE() (NULL) | 1282 | #define SUNZILOG_CONSOLE() (NULL) |
1283 | #endif | 1283 | #endif |
1284 | 1284 | ||
1285 | static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up) | 1285 | static void sunzilog_init_kbdms(struct uart_sunzilog_port *up) |
1286 | { | 1286 | { |
1287 | int baud, brg; | 1287 | int baud, brg; |
1288 | 1288 | ||
@@ -1302,7 +1302,7 @@ static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up) | |||
1302 | } | 1302 | } |
1303 | 1303 | ||
1304 | #ifdef CONFIG_SERIO | 1304 | #ifdef CONFIG_SERIO |
1305 | static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up) | 1305 | static void sunzilog_register_serio(struct uart_sunzilog_port *up) |
1306 | { | 1306 | { |
1307 | struct serio *serio = &up->serio; | 1307 | struct serio *serio = &up->serio; |
1308 | 1308 | ||
@@ -1331,7 +1331,7 @@ static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up) | |||
1331 | } | 1331 | } |
1332 | #endif | 1332 | #endif |
1333 | 1333 | ||
1334 | static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | 1334 | static void sunzilog_init_hw(struct uart_sunzilog_port *up) |
1335 | { | 1335 | { |
1336 | struct zilog_channel __iomem *channel; | 1336 | struct zilog_channel __iomem *channel; |
1337 | unsigned long flags; | 1337 | unsigned long flags; |
@@ -1400,7 +1400,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1400 | 1400 | ||
1401 | static int zilog_irq; | 1401 | static int zilog_irq; |
1402 | 1402 | ||
1403 | static int __devinit zs_probe(struct platform_device *op) | 1403 | static int zs_probe(struct platform_device *op) |
1404 | { | 1404 | { |
1405 | static int kbm_inst, uart_inst; | 1405 | static int kbm_inst, uart_inst; |
1406 | int inst; | 1406 | int inst; |
@@ -1507,7 +1507,7 @@ static int __devinit zs_probe(struct platform_device *op) | |||
1507 | return 0; | 1507 | return 0; |
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | static void __devexit zs_remove_one(struct uart_sunzilog_port *up) | 1510 | static void zs_remove_one(struct uart_sunzilog_port *up) |
1511 | { | 1511 | { |
1512 | if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) { | 1512 | if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) { |
1513 | #ifdef CONFIG_SERIO | 1513 | #ifdef CONFIG_SERIO |
@@ -1517,7 +1517,7 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up) | |||
1517 | uart_remove_one_port(&sunzilog_reg, &up->port); | 1517 | uart_remove_one_port(&sunzilog_reg, &up->port); |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | static int __devexit zs_remove(struct platform_device *op) | 1520 | static int zs_remove(struct platform_device *op) |
1521 | { | 1521 | { |
1522 | struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev); | 1522 | struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev); |
1523 | struct zilog_layout __iomem *regs; | 1523 | struct zilog_layout __iomem *regs; |
@@ -1548,7 +1548,7 @@ static struct platform_driver zs_driver = { | |||
1548 | .of_match_table = zs_match, | 1548 | .of_match_table = zs_match, |
1549 | }, | 1549 | }, |
1550 | .probe = zs_probe, | 1550 | .probe = zs_probe, |
1551 | .remove = __devexit_p(zs_remove), | 1551 | .remove = zs_remove, |
1552 | }; | 1552 | }; |
1553 | 1553 | ||
1554 | static int __init sunzilog_init(void) | 1554 | static int __init sunzilog_init(void) |
diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 70f97491d8f2..5be0d68feceb 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c | |||
@@ -426,7 +426,7 @@ static struct uart_driver timbuart_driver = { | |||
426 | .nr = 1 | 426 | .nr = 1 |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static int __devinit timbuart_probe(struct platform_device *dev) | 429 | static int timbuart_probe(struct platform_device *dev) |
430 | { | 430 | { |
431 | int err, irq; | 431 | int err, irq; |
432 | struct timbuart_port *uart; | 432 | struct timbuart_port *uart; |
@@ -492,7 +492,7 @@ err_mem: | |||
492 | return err; | 492 | return err; |
493 | } | 493 | } |
494 | 494 | ||
495 | static int __devexit timbuart_remove(struct platform_device *dev) | 495 | static int timbuart_remove(struct platform_device *dev) |
496 | { | 496 | { |
497 | struct timbuart_port *uart = platform_get_drvdata(dev); | 497 | struct timbuart_port *uart = platform_get_drvdata(dev); |
498 | 498 | ||
@@ -510,7 +510,7 @@ static struct platform_driver timbuart_platform_driver = { | |||
510 | .owner = THIS_MODULE, | 510 | .owner = THIS_MODULE, |
511 | }, | 511 | }, |
512 | .probe = timbuart_probe, | 512 | .probe = timbuart_probe, |
513 | .remove = __devexit_p(timbuart_remove), | 513 | .remove = timbuart_remove, |
514 | }; | 514 | }; |
515 | 515 | ||
516 | module_platform_driver(timbuart_platform_driver); | 516 | module_platform_driver(timbuart_platform_driver); |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 6579ffdd8e9b..89eee43c4e2d 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -408,7 +408,7 @@ static void ulite_console_write(struct console *co, const char *s, | |||
408 | spin_unlock_irqrestore(&port->lock, flags); | 408 | spin_unlock_irqrestore(&port->lock, flags); |
409 | } | 409 | } |
410 | 410 | ||
411 | static int __devinit ulite_console_setup(struct console *co, char *options) | 411 | static int ulite_console_setup(struct console *co, char *options) |
412 | { | 412 | { |
413 | struct uart_port *port; | 413 | struct uart_port *port; |
414 | int baud = 9600; | 414 | int baud = 9600; |
@@ -486,7 +486,7 @@ static struct uart_driver ulite_uart_driver = { | |||
486 | * | 486 | * |
487 | * Returns: 0 on success, <0 otherwise | 487 | * Returns: 0 on success, <0 otherwise |
488 | */ | 488 | */ |
489 | static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) | 489 | static int ulite_assign(struct device *dev, int id, u32 base, int irq) |
490 | { | 490 | { |
491 | struct uart_port *port; | 491 | struct uart_port *port; |
492 | int rc; | 492 | int rc; |
@@ -542,7 +542,7 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) | |||
542 | * | 542 | * |
543 | * @dev: pointer to device structure | 543 | * @dev: pointer to device structure |
544 | */ | 544 | */ |
545 | static int __devexit ulite_release(struct device *dev) | 545 | static int ulite_release(struct device *dev) |
546 | { | 546 | { |
547 | struct uart_port *port = dev_get_drvdata(dev); | 547 | struct uart_port *port = dev_get_drvdata(dev); |
548 | int rc = 0; | 548 | int rc = 0; |
@@ -562,7 +562,7 @@ static int __devexit ulite_release(struct device *dev) | |||
562 | 562 | ||
563 | #if defined(CONFIG_OF) | 563 | #if defined(CONFIG_OF) |
564 | /* Match table for of_platform binding */ | 564 | /* Match table for of_platform binding */ |
565 | static struct of_device_id ulite_of_match[] __devinitdata = { | 565 | static struct of_device_id ulite_of_match[] = { |
566 | { .compatible = "xlnx,opb-uartlite-1.00.b", }, | 566 | { .compatible = "xlnx,opb-uartlite-1.00.b", }, |
567 | { .compatible = "xlnx,xps-uartlite-1.00.a", }, | 567 | { .compatible = "xlnx,xps-uartlite-1.00.a", }, |
568 | {} | 568 | {} |
@@ -570,7 +570,7 @@ static struct of_device_id ulite_of_match[] __devinitdata = { | |||
570 | MODULE_DEVICE_TABLE(of, ulite_of_match); | 570 | MODULE_DEVICE_TABLE(of, ulite_of_match); |
571 | #endif /* CONFIG_OF */ | 571 | #endif /* CONFIG_OF */ |
572 | 572 | ||
573 | static int __devinit ulite_probe(struct platform_device *pdev) | 573 | static int ulite_probe(struct platform_device *pdev) |
574 | { | 574 | { |
575 | struct resource *res, *res2; | 575 | struct resource *res, *res2; |
576 | int id = pdev->id; | 576 | int id = pdev->id; |
@@ -593,7 +593,7 @@ static int __devinit ulite_probe(struct platform_device *pdev) | |||
593 | return ulite_assign(&pdev->dev, id, res->start, res2->start); | 593 | return ulite_assign(&pdev->dev, id, res->start, res2->start); |
594 | } | 594 | } |
595 | 595 | ||
596 | static int __devexit ulite_remove(struct platform_device *pdev) | 596 | static int ulite_remove(struct platform_device *pdev) |
597 | { | 597 | { |
598 | return ulite_release(&pdev->dev); | 598 | return ulite_release(&pdev->dev); |
599 | } | 599 | } |
@@ -603,7 +603,7 @@ MODULE_ALIAS("platform:uartlite"); | |||
603 | 603 | ||
604 | static struct platform_driver ulite_platform_driver = { | 604 | static struct platform_driver ulite_platform_driver = { |
605 | .probe = ulite_probe, | 605 | .probe = ulite_probe, |
606 | .remove = __devexit_p(ulite_remove), | 606 | .remove = ulite_remove, |
607 | .driver = { | 607 | .driver = { |
608 | .owner = THIS_MODULE, | 608 | .owner = THIS_MODULE, |
609 | .name = "uartlite", | 609 | .name = "uartlite", |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index cf0d9485ec08..62ee0166bc65 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
@@ -823,7 +823,7 @@ static struct console siu_console = { | |||
823 | .data = &siu_uart_driver, | 823 | .data = &siu_uart_driver, |
824 | }; | 824 | }; |
825 | 825 | ||
826 | static int __devinit siu_console_init(void) | 826 | static int siu_console_init(void) |
827 | { | 827 | { |
828 | struct uart_port *port; | 828 | struct uart_port *port; |
829 | int i; | 829 | int i; |
@@ -867,7 +867,7 @@ static struct uart_driver siu_uart_driver = { | |||
867 | .cons = SERIAL_VR41XX_CONSOLE, | 867 | .cons = SERIAL_VR41XX_CONSOLE, |
868 | }; | 868 | }; |
869 | 869 | ||
870 | static int __devinit siu_probe(struct platform_device *dev) | 870 | static int siu_probe(struct platform_device *dev) |
871 | { | 871 | { |
872 | struct uart_port *port; | 872 | struct uart_port *port; |
873 | int num, i, retval; | 873 | int num, i, retval; |
@@ -901,7 +901,7 @@ static int __devinit siu_probe(struct platform_device *dev) | |||
901 | return 0; | 901 | return 0; |
902 | } | 902 | } |
903 | 903 | ||
904 | static int __devexit siu_remove(struct platform_device *dev) | 904 | static int siu_remove(struct platform_device *dev) |
905 | { | 905 | { |
906 | struct uart_port *port; | 906 | struct uart_port *port; |
907 | int i; | 907 | int i; |
@@ -952,7 +952,7 @@ static int siu_resume(struct platform_device *dev) | |||
952 | 952 | ||
953 | static struct platform_driver siu_device_driver = { | 953 | static struct platform_driver siu_device_driver = { |
954 | .probe = siu_probe, | 954 | .probe = siu_probe, |
955 | .remove = __devexit_p(siu_remove), | 955 | .remove = siu_remove, |
956 | .suspend = siu_suspend, | 956 | .suspend = siu_suspend, |
957 | .resume = siu_resume, | 957 | .resume = siu_resume, |
958 | .driver = { | 958 | .driver = { |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 205d4cf4a063..8fd181436a6b 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -554,7 +554,7 @@ static struct uart_driver vt8500_uart_driver = { | |||
554 | .cons = VT8500_CONSOLE, | 554 | .cons = VT8500_CONSOLE, |
555 | }; | 555 | }; |
556 | 556 | ||
557 | static int __devinit vt8500_serial_probe(struct platform_device *pdev) | 557 | static int vt8500_serial_probe(struct platform_device *pdev) |
558 | { | 558 | { |
559 | struct vt8500_port *vt8500_port; | 559 | struct vt8500_port *vt8500_port; |
560 | struct resource *mmres, *irqres; | 560 | struct resource *mmres, *irqres; |
@@ -567,10 +567,6 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev) | |||
567 | if (!mmres || !irqres) | 567 | if (!mmres || !irqres) |
568 | return -ENODEV; | 568 | return -ENODEV; |
569 | 569 | ||
570 | vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); | ||
571 | if (!vt8500_port) | ||
572 | return -ENOMEM; | ||
573 | |||
574 | if (np) | 570 | if (np) |
575 | port = of_alias_get_id(np, "serial"); | 571 | port = of_alias_get_id(np, "serial"); |
576 | if (port > VT8500_MAX_PORTS) | 572 | if (port > VT8500_MAX_PORTS) |
@@ -593,6 +589,10 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev) | |||
593 | return -EBUSY; | 589 | return -EBUSY; |
594 | } | 590 | } |
595 | 591 | ||
592 | vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); | ||
593 | if (!vt8500_port) | ||
594 | return -ENOMEM; | ||
595 | |||
596 | vt8500_port->uart.type = PORT_VT8500; | 596 | vt8500_port->uart.type = PORT_VT8500; |
597 | vt8500_port->uart.iotype = UPIO_MEM; | 597 | vt8500_port->uart.iotype = UPIO_MEM; |
598 | vt8500_port->uart.mapbase = mmres->start; | 598 | vt8500_port->uart.mapbase = mmres->start; |
@@ -634,7 +634,7 @@ err: | |||
634 | return ret; | 634 | return ret; |
635 | } | 635 | } |
636 | 636 | ||
637 | static int __devexit vt8500_serial_remove(struct platform_device *pdev) | 637 | static int vt8500_serial_remove(struct platform_device *pdev) |
638 | { | 638 | { |
639 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); | 639 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); |
640 | 640 | ||
@@ -652,7 +652,7 @@ static const struct of_device_id wmt_dt_ids[] = { | |||
652 | 652 | ||
653 | static struct platform_driver vt8500_platform_driver = { | 653 | static struct platform_driver vt8500_platform_driver = { |
654 | .probe = vt8500_serial_probe, | 654 | .probe = vt8500_serial_probe, |
655 | .remove = __devexit_p(vt8500_serial_remove), | 655 | .remove = vt8500_serial_remove, |
656 | .driver = { | 656 | .driver = { |
657 | .name = "vt8500_serial", | 657 | .name = "vt8500_serial", |
658 | .owner = THIS_MODULE, | 658 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index b627363352e5..9ab910370c56 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -939,22 +939,18 @@ static struct uart_driver xuartps_uart_driver = { | |||
939 | * | 939 | * |
940 | * Returns 0 on success, negative error otherwise | 940 | * Returns 0 on success, negative error otherwise |
941 | **/ | 941 | **/ |
942 | static int __devinit xuartps_probe(struct platform_device *pdev) | 942 | static int xuartps_probe(struct platform_device *pdev) |
943 | { | 943 | { |
944 | int rc; | 944 | int rc; |
945 | struct uart_port *port; | 945 | struct uart_port *port; |
946 | struct resource *res, *res2; | 946 | struct resource *res, *res2; |
947 | int clk = 0; | 947 | int clk = 0; |
948 | 948 | ||
949 | #ifdef CONFIG_OF | ||
950 | const unsigned int *prop; | 949 | const unsigned int *prop; |
951 | 950 | ||
952 | prop = of_get_property(pdev->dev.of_node, "clock", NULL); | 951 | prop = of_get_property(pdev->dev.of_node, "clock", NULL); |
953 | if (prop) | 952 | if (prop) |
954 | clk = be32_to_cpup(prop); | 953 | clk = be32_to_cpup(prop); |
955 | #else | ||
956 | clk = *((unsigned int *)(pdev->dev.platform_data)); | ||
957 | #endif | ||
958 | if (!clk) { | 954 | if (!clk) { |
959 | dev_err(&pdev->dev, "no clock specified\n"); | 955 | dev_err(&pdev->dev, "no clock specified\n"); |
960 | return -ENODEV; | 956 | return -ENODEV; |
@@ -1001,7 +997,7 @@ static int __devinit xuartps_probe(struct platform_device *pdev) | |||
1001 | * | 997 | * |
1002 | * Returns 0 on success, negative error otherwise | 998 | * Returns 0 on success, negative error otherwise |
1003 | **/ | 999 | **/ |
1004 | static int __devexit xuartps_remove(struct platform_device *pdev) | 1000 | static int xuartps_remove(struct platform_device *pdev) |
1005 | { | 1001 | { |
1006 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 1002 | struct uart_port *port = dev_get_drvdata(&pdev->dev); |
1007 | int rc = 0; | 1003 | int rc = 0; |
@@ -1044,16 +1040,11 @@ static int xuartps_resume(struct platform_device *pdev) | |||
1044 | } | 1040 | } |
1045 | 1041 | ||
1046 | /* Match table for of_platform binding */ | 1042 | /* Match table for of_platform binding */ |
1047 | 1043 | static struct of_device_id xuartps_of_match[] = { | |
1048 | #ifdef CONFIG_OF | ||
1049 | static struct of_device_id xuartps_of_match[] __devinitdata = { | ||
1050 | { .compatible = "xlnx,xuartps", }, | 1044 | { .compatible = "xlnx,xuartps", }, |
1051 | {} | 1045 | {} |
1052 | }; | 1046 | }; |
1053 | MODULE_DEVICE_TABLE(of, xuartps_of_match); | 1047 | MODULE_DEVICE_TABLE(of, xuartps_of_match); |
1054 | #else | ||
1055 | #define xuartps_of_match NULL | ||
1056 | #endif | ||
1057 | 1048 | ||
1058 | static struct platform_driver xuartps_platform_driver = { | 1049 | static struct platform_driver xuartps_platform_driver = { |
1059 | .probe = xuartps_probe, /* Probe method */ | 1050 | .probe = xuartps_probe, /* Probe method */ |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 70e3a525bc82..9e071f6985f6 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -898,7 +898,7 @@ static struct pci_driver synclink_pci_driver = { | |||
898 | .name = "synclink", | 898 | .name = "synclink", |
899 | .id_table = synclink_pci_tbl, | 899 | .id_table = synclink_pci_tbl, |
900 | .probe = synclink_init_one, | 900 | .probe = synclink_init_one, |
901 | .remove = __devexit_p(synclink_remove_one), | 901 | .remove = synclink_remove_one, |
902 | }; | 902 | }; |
903 | 903 | ||
904 | static struct tty_driver *serial_driver; | 904 | static struct tty_driver *serial_driver; |
@@ -4425,6 +4425,7 @@ static void synclink_cleanup(void) | |||
4425 | mgsl_release_resources(info); | 4425 | mgsl_release_resources(info); |
4426 | tmp = info; | 4426 | tmp = info; |
4427 | info = info->next_device; | 4427 | info = info->next_device; |
4428 | tty_port_destroy(&tmp->port); | ||
4428 | kfree(tmp); | 4429 | kfree(tmp); |
4429 | } | 4430 | } |
4430 | 4431 | ||
@@ -8064,7 +8065,7 @@ static void hdlcdev_exit(struct mgsl_struct *info) | |||
8064 | #endif /* CONFIG_HDLC */ | 8065 | #endif /* CONFIG_HDLC */ |
8065 | 8066 | ||
8066 | 8067 | ||
8067 | static int __devinit synclink_init_one (struct pci_dev *dev, | 8068 | static int synclink_init_one (struct pci_dev *dev, |
8068 | const struct pci_device_id *ent) | 8069 | const struct pci_device_id *ent) |
8069 | { | 8070 | { |
8070 | struct mgsl_struct *info; | 8071 | struct mgsl_struct *info; |
@@ -8116,7 +8117,7 @@ static int __devinit synclink_init_one (struct pci_dev *dev, | |||
8116 | return 0; | 8117 | return 0; |
8117 | } | 8118 | } |
8118 | 8119 | ||
8119 | static void __devexit synclink_remove_one (struct pci_dev *dev) | 8120 | static void synclink_remove_one (struct pci_dev *dev) |
8120 | { | 8121 | { |
8121 | } | 8122 | } |
8122 | 8123 | ||
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index b38e954eedd3..aba1e59f4a88 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -110,7 +110,7 @@ static struct pci_driver pci_driver = { | |||
110 | .name = "synclink_gt", | 110 | .name = "synclink_gt", |
111 | .id_table = pci_table, | 111 | .id_table = pci_table, |
112 | .probe = init_one, | 112 | .probe = init_one, |
113 | .remove = __devexit_p(remove_one), | 113 | .remove = remove_one, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static bool pci_registered; | 116 | static bool pci_registered; |
@@ -3645,8 +3645,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3645 | for (i=0; i < port_count; ++i) { | 3645 | for (i=0; i < port_count; ++i) { |
3646 | port_array[i] = alloc_dev(adapter_num, i, pdev); | 3646 | port_array[i] = alloc_dev(adapter_num, i, pdev); |
3647 | if (port_array[i] == NULL) { | 3647 | if (port_array[i] == NULL) { |
3648 | for (--i; i >= 0; --i) | 3648 | for (--i; i >= 0; --i) { |
3649 | tty_port_destroy(&port_array[i]->port); | ||
3649 | kfree(port_array[i]); | 3650 | kfree(port_array[i]); |
3651 | } | ||
3650 | return; | 3652 | return; |
3651 | } | 3653 | } |
3652 | } | 3654 | } |
@@ -3696,7 +3698,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3696 | } | 3698 | } |
3697 | } | 3699 | } |
3698 | 3700 | ||
3699 | static int __devinit init_one(struct pci_dev *dev, | 3701 | static int init_one(struct pci_dev *dev, |
3700 | const struct pci_device_id *ent) | 3702 | const struct pci_device_id *ent) |
3701 | { | 3703 | { |
3702 | if (pci_enable_device(dev)) { | 3704 | if (pci_enable_device(dev)) { |
@@ -3708,7 +3710,7 @@ static int __devinit init_one(struct pci_dev *dev, | |||
3708 | return 0; | 3710 | return 0; |
3709 | } | 3711 | } |
3710 | 3712 | ||
3711 | static void __devexit remove_one(struct pci_dev *dev) | 3713 | static void remove_one(struct pci_dev *dev) |
3712 | { | 3714 | { |
3713 | } | 3715 | } |
3714 | 3716 | ||
@@ -3773,6 +3775,7 @@ static void slgt_cleanup(void) | |||
3773 | release_resources(info); | 3775 | release_resources(info); |
3774 | tmp = info; | 3776 | tmp = info; |
3775 | info = info->next_device; | 3777 | info = info->next_device; |
3778 | tty_port_destroy(&tmp->port); | ||
3776 | kfree(tmp); | 3779 | kfree(tmp); |
3777 | } | 3780 | } |
3778 | 3781 | ||
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index f17d9f3d84a2..fd43fb6f7cee 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -492,7 +492,7 @@ static struct pci_driver synclinkmp_pci_driver = { | |||
492 | .name = "synclinkmp", | 492 | .name = "synclinkmp", |
493 | .id_table = synclinkmp_pci_tbl, | 493 | .id_table = synclinkmp_pci_tbl, |
494 | .probe = synclinkmp_init_one, | 494 | .probe = synclinkmp_init_one, |
495 | .remove = __devexit_p(synclinkmp_remove_one), | 495 | .remove = synclinkmp_remove_one, |
496 | }; | 496 | }; |
497 | 497 | ||
498 | 498 | ||
@@ -3843,8 +3843,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3843 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { | 3843 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { |
3844 | port_array[port] = alloc_dev(adapter_num,port,pdev); | 3844 | port_array[port] = alloc_dev(adapter_num,port,pdev); |
3845 | if( port_array[port] == NULL ) { | 3845 | if( port_array[port] == NULL ) { |
3846 | for ( --port; port >= 0; --port ) | 3846 | for (--port; port >= 0; --port) { |
3847 | tty_port_destroy(&port_array[port]->port); | ||
3847 | kfree(port_array[port]); | 3848 | kfree(port_array[port]); |
3849 | } | ||
3848 | return; | 3850 | return; |
3849 | } | 3851 | } |
3850 | } | 3852 | } |
@@ -3953,6 +3955,7 @@ static void synclinkmp_cleanup(void) | |||
3953 | } | 3955 | } |
3954 | tmp = info; | 3956 | tmp = info; |
3955 | info = info->next_device; | 3957 | info = info->next_device; |
3958 | tty_port_destroy(&tmp->port); | ||
3956 | kfree(tmp); | 3959 | kfree(tmp); |
3957 | } | 3960 | } |
3958 | 3961 | ||
@@ -5592,7 +5595,7 @@ static void write_control_reg(SLMP_INFO * info) | |||
5592 | } | 5595 | } |
5593 | 5596 | ||
5594 | 5597 | ||
5595 | static int __devinit synclinkmp_init_one (struct pci_dev *dev, | 5598 | static int synclinkmp_init_one (struct pci_dev *dev, |
5596 | const struct pci_device_id *ent) | 5599 | const struct pci_device_id *ent) |
5597 | { | 5600 | { |
5598 | if (pci_enable_device(dev)) { | 5601 | if (pci_enable_device(dev)) { |
@@ -5603,6 +5606,6 @@ static int __devinit synclinkmp_init_one (struct pci_dev *dev, | |||
5603 | return 0; | 5606 | return 0; |
5604 | } | 5607 | } |
5605 | 5608 | ||
5606 | static void __devexit synclinkmp_remove_one (struct pci_dev *dev) | 5609 | static void synclinkmp_remove_one (struct pci_dev *dev) |
5607 | { | 5610 | { |
5608 | } | 5611 | } |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 16ee6cee07da..b3c4a250ff86 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
@@ -346,7 +346,8 @@ static struct sysrq_key_op sysrq_term_op = { | |||
346 | 346 | ||
347 | static void moom_callback(struct work_struct *ignored) | 347 | static void moom_callback(struct work_struct *ignored) |
348 | { | 348 | { |
349 | out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL, true); | 349 | out_of_memory(node_zonelist(first_online_node, GFP_KERNEL), GFP_KERNEL, |
350 | 0, NULL, true); | ||
350 | } | 351 | } |
351 | 352 | ||
352 | static DECLARE_WORK(moom_work, moom_callback); | 353 | static DECLARE_WORK(moom_work, moom_callback); |
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index b0b39b823ccf..6953dc82850c 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c | |||
@@ -23,7 +23,7 @@ struct tty_audit_buf { | |||
23 | }; | 23 | }; |
24 | 24 | ||
25 | static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, | 25 | static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, |
26 | int icanon) | 26 | unsigned icanon) |
27 | { | 27 | { |
28 | struct tty_audit_buf *buf; | 28 | struct tty_audit_buf *buf; |
29 | 29 | ||
@@ -239,7 +239,8 @@ int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid) | |||
239 | * if TTY auditing is disabled or out of memory. Otherwise, return a new | 239 | * if TTY auditing is disabled or out of memory. Otherwise, return a new |
240 | * reference to the buffer. | 240 | * reference to the buffer. |
241 | */ | 241 | */ |
242 | static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) | 242 | static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, |
243 | unsigned icanon) | ||
243 | { | 244 | { |
244 | struct tty_audit_buf *buf, *buf2; | 245 | struct tty_audit_buf *buf, *buf2; |
245 | 246 | ||
@@ -257,7 +258,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) | |||
257 | 258 | ||
258 | buf2 = tty_audit_buf_alloc(tty->driver->major, | 259 | buf2 = tty_audit_buf_alloc(tty->driver->major, |
259 | tty->driver->minor_start + tty->index, | 260 | tty->driver->minor_start + tty->index, |
260 | tty->icanon); | 261 | icanon); |
261 | if (buf2 == NULL) { | 262 | if (buf2 == NULL) { |
262 | audit_log_lost("out of memory in TTY auditing"); | 263 | audit_log_lost("out of memory in TTY auditing"); |
263 | return NULL; | 264 | return NULL; |
@@ -287,7 +288,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) | |||
287 | * Audit @data of @size from @tty, if necessary. | 288 | * Audit @data of @size from @tty, if necessary. |
288 | */ | 289 | */ |
289 | void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | 290 | void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, |
290 | size_t size) | 291 | size_t size, unsigned icanon) |
291 | { | 292 | { |
292 | struct tty_audit_buf *buf; | 293 | struct tty_audit_buf *buf; |
293 | int major, minor; | 294 | int major, minor; |
@@ -299,7 +300,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
299 | && tty->driver->subtype == PTY_TYPE_MASTER) | 300 | && tty->driver->subtype == PTY_TYPE_MASTER) |
300 | return; | 301 | return; |
301 | 302 | ||
302 | buf = tty_audit_buf_get(tty); | 303 | buf = tty_audit_buf_get(tty, icanon); |
303 | if (!buf) | 304 | if (!buf) |
304 | return; | 305 | return; |
305 | 306 | ||
@@ -307,11 +308,11 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
307 | major = tty->driver->major; | 308 | major = tty->driver->major; |
308 | minor = tty->driver->minor_start + tty->index; | 309 | minor = tty->driver->minor_start + tty->index; |
309 | if (buf->major != major || buf->minor != minor | 310 | if (buf->major != major || buf->minor != minor |
310 | || buf->icanon != tty->icanon) { | 311 | || buf->icanon != icanon) { |
311 | tty_audit_buf_push_current(buf); | 312 | tty_audit_buf_push_current(buf); |
312 | buf->major = major; | 313 | buf->major = major; |
313 | buf->minor = minor; | 314 | buf->minor = minor; |
314 | buf->icanon = tty->icanon; | 315 | buf->icanon = icanon; |
315 | } | 316 | } |
316 | do { | 317 | do { |
317 | size_t run; | 318 | size_t run; |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 91e326ffe7db..45d916198f78 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -27,19 +27,21 @@ | |||
27 | * Locking: none | 27 | * Locking: none |
28 | */ | 28 | */ |
29 | 29 | ||
30 | void tty_buffer_free_all(struct tty_struct *tty) | 30 | void tty_buffer_free_all(struct tty_port *port) |
31 | { | 31 | { |
32 | struct tty_bufhead *buf = &port->buf; | ||
32 | struct tty_buffer *thead; | 33 | struct tty_buffer *thead; |
33 | while ((thead = tty->buf.head) != NULL) { | 34 | |
34 | tty->buf.head = thead->next; | 35 | while ((thead = buf->head) != NULL) { |
36 | buf->head = thead->next; | ||
35 | kfree(thead); | 37 | kfree(thead); |
36 | } | 38 | } |
37 | while ((thead = tty->buf.free) != NULL) { | 39 | while ((thead = buf->free) != NULL) { |
38 | tty->buf.free = thead->next; | 40 | buf->free = thead->next; |
39 | kfree(thead); | 41 | kfree(thead); |
40 | } | 42 | } |
41 | tty->buf.tail = NULL; | 43 | buf->tail = NULL; |
42 | tty->buf.memory_used = 0; | 44 | buf->memory_used = 0; |
43 | } | 45 | } |
44 | 46 | ||
45 | /** | 47 | /** |
@@ -54,11 +56,11 @@ void tty_buffer_free_all(struct tty_struct *tty) | |||
54 | * Locking: Caller must hold tty->buf.lock | 56 | * Locking: Caller must hold tty->buf.lock |
55 | */ | 57 | */ |
56 | 58 | ||
57 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | 59 | static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) |
58 | { | 60 | { |
59 | struct tty_buffer *p; | 61 | struct tty_buffer *p; |
60 | 62 | ||
61 | if (tty->buf.memory_used + size > 65536) | 63 | if (port->buf.memory_used + size > 65536) |
62 | return NULL; | 64 | return NULL; |
63 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | 65 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); |
64 | if (p == NULL) | 66 | if (p == NULL) |
@@ -70,7 +72,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | |||
70 | p->read = 0; | 72 | p->read = 0; |
71 | p->char_buf_ptr = (char *)(p->data); | 73 | p->char_buf_ptr = (char *)(p->data); |
72 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | 74 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; |
73 | tty->buf.memory_used += size; | 75 | port->buf.memory_used += size; |
74 | return p; | 76 | return p; |
75 | } | 77 | } |
76 | 78 | ||
@@ -85,17 +87,19 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | |||
85 | * Locking: Caller must hold tty->buf.lock | 87 | * Locking: Caller must hold tty->buf.lock |
86 | */ | 88 | */ |
87 | 89 | ||
88 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | 90 | static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b) |
89 | { | 91 | { |
92 | struct tty_bufhead *buf = &port->buf; | ||
93 | |||
90 | /* Dumb strategy for now - should keep some stats */ | 94 | /* Dumb strategy for now - should keep some stats */ |
91 | tty->buf.memory_used -= b->size; | 95 | buf->memory_used -= b->size; |
92 | WARN_ON(tty->buf.memory_used < 0); | 96 | WARN_ON(buf->memory_used < 0); |
93 | 97 | ||
94 | if (b->size >= 512) | 98 | if (b->size >= 512) |
95 | kfree(b); | 99 | kfree(b); |
96 | else { | 100 | else { |
97 | b->next = tty->buf.free; | 101 | b->next = buf->free; |
98 | tty->buf.free = b; | 102 | buf->free = b; |
99 | } | 103 | } |
100 | } | 104 | } |
101 | 105 | ||
@@ -110,15 +114,16 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | |||
110 | * Locking: Caller must hold tty->buf.lock | 114 | * Locking: Caller must hold tty->buf.lock |
111 | */ | 115 | */ |
112 | 116 | ||
113 | static void __tty_buffer_flush(struct tty_struct *tty) | 117 | static void __tty_buffer_flush(struct tty_port *port) |
114 | { | 118 | { |
119 | struct tty_bufhead *buf = &port->buf; | ||
115 | struct tty_buffer *thead; | 120 | struct tty_buffer *thead; |
116 | 121 | ||
117 | while ((thead = tty->buf.head) != NULL) { | 122 | while ((thead = buf->head) != NULL) { |
118 | tty->buf.head = thead->next; | 123 | buf->head = thead->next; |
119 | tty_buffer_free(tty, thead); | 124 | tty_buffer_free(port, thead); |
120 | } | 125 | } |
121 | tty->buf.tail = NULL; | 126 | buf->tail = NULL; |
122 | } | 127 | } |
123 | 128 | ||
124 | /** | 129 | /** |
@@ -134,21 +139,24 @@ static void __tty_buffer_flush(struct tty_struct *tty) | |||
134 | 139 | ||
135 | void tty_buffer_flush(struct tty_struct *tty) | 140 | void tty_buffer_flush(struct tty_struct *tty) |
136 | { | 141 | { |
142 | struct tty_port *port = tty->port; | ||
143 | struct tty_bufhead *buf = &port->buf; | ||
137 | unsigned long flags; | 144 | unsigned long flags; |
138 | spin_lock_irqsave(&tty->buf.lock, flags); | 145 | |
146 | spin_lock_irqsave(&buf->lock, flags); | ||
139 | 147 | ||
140 | /* If the data is being pushed to the tty layer then we can't | 148 | /* If the data is being pushed to the tty layer then we can't |
141 | process it here. Instead set a flag and the flush_to_ldisc | 149 | process it here. Instead set a flag and the flush_to_ldisc |
142 | path will process the flush request before it exits */ | 150 | path will process the flush request before it exits */ |
143 | if (test_bit(TTY_FLUSHING, &tty->flags)) { | 151 | if (test_bit(TTYP_FLUSHING, &port->iflags)) { |
144 | set_bit(TTY_FLUSHPENDING, &tty->flags); | 152 | set_bit(TTYP_FLUSHPENDING, &port->iflags); |
145 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 153 | spin_unlock_irqrestore(&buf->lock, flags); |
146 | wait_event(tty->read_wait, | 154 | wait_event(tty->read_wait, |
147 | test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); | 155 | test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); |
148 | return; | 156 | return; |
149 | } else | 157 | } else |
150 | __tty_buffer_flush(tty); | 158 | __tty_buffer_flush(port); |
151 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 159 | spin_unlock_irqrestore(&buf->lock, flags); |
152 | } | 160 | } |
153 | 161 | ||
154 | /** | 162 | /** |
@@ -163,9 +171,9 @@ void tty_buffer_flush(struct tty_struct *tty) | |||
163 | * Locking: Caller must hold tty->buf.lock | 171 | * Locking: Caller must hold tty->buf.lock |
164 | */ | 172 | */ |
165 | 173 | ||
166 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | 174 | static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size) |
167 | { | 175 | { |
168 | struct tty_buffer **tbh = &tty->buf.free; | 176 | struct tty_buffer **tbh = &port->buf.free; |
169 | while ((*tbh) != NULL) { | 177 | while ((*tbh) != NULL) { |
170 | struct tty_buffer *t = *tbh; | 178 | struct tty_buffer *t = *tbh; |
171 | if (t->size >= size) { | 179 | if (t->size >= size) { |
@@ -174,14 +182,14 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | |||
174 | t->used = 0; | 182 | t->used = 0; |
175 | t->commit = 0; | 183 | t->commit = 0; |
176 | t->read = 0; | 184 | t->read = 0; |
177 | tty->buf.memory_used += t->size; | 185 | port->buf.memory_used += t->size; |
178 | return t; | 186 | return t; |
179 | } | 187 | } |
180 | tbh = &((*tbh)->next); | 188 | tbh = &((*tbh)->next); |
181 | } | 189 | } |
182 | /* Round the buffer size out */ | 190 | /* Round the buffer size out */ |
183 | size = (size + 0xFF) & ~0xFF; | 191 | size = (size + 0xFF) & ~0xFF; |
184 | return tty_buffer_alloc(tty, size); | 192 | return tty_buffer_alloc(port, size); |
185 | /* Should possibly check if this fails for the largest buffer we | 193 | /* Should possibly check if this fails for the largest buffer we |
186 | have queued and recycle that ? */ | 194 | have queued and recycle that ? */ |
187 | } | 195 | } |
@@ -192,29 +200,31 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | |||
192 | * | 200 | * |
193 | * Make at least size bytes of linear space available for the tty | 201 | * Make at least size bytes of linear space available for the tty |
194 | * buffer. If we fail return the size we managed to find. | 202 | * buffer. If we fail return the size we managed to find. |
195 | * Locking: Caller must hold tty->buf.lock | 203 | * Locking: Caller must hold port->buf.lock |
196 | */ | 204 | */ |
197 | static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) | 205 | static int __tty_buffer_request_room(struct tty_port *port, size_t size) |
198 | { | 206 | { |
207 | struct tty_bufhead *buf = &port->buf; | ||
199 | struct tty_buffer *b, *n; | 208 | struct tty_buffer *b, *n; |
200 | int left; | 209 | int left; |
201 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | 210 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to |
202 | remove this conditional if its worth it. This would be invisible | 211 | remove this conditional if its worth it. This would be invisible |
203 | to the callers */ | 212 | to the callers */ |
204 | if ((b = tty->buf.tail) != NULL) | 213 | b = buf->tail; |
214 | if (b != NULL) | ||
205 | left = b->size - b->used; | 215 | left = b->size - b->used; |
206 | else | 216 | else |
207 | left = 0; | 217 | left = 0; |
208 | 218 | ||
209 | if (left < size) { | 219 | if (left < size) { |
210 | /* This is the slow path - looking for new buffers to use */ | 220 | /* This is the slow path - looking for new buffers to use */ |
211 | if ((n = tty_buffer_find(tty, size)) != NULL) { | 221 | if ((n = tty_buffer_find(port, size)) != NULL) { |
212 | if (b != NULL) { | 222 | if (b != NULL) { |
213 | b->next = n; | 223 | b->next = n; |
214 | b->commit = b->used; | 224 | b->commit = b->used; |
215 | } else | 225 | } else |
216 | tty->buf.head = n; | 226 | buf->head = n; |
217 | tty->buf.tail = n; | 227 | buf->tail = n; |
218 | } else | 228 | } else |
219 | size = left; | 229 | size = left; |
220 | } | 230 | } |
@@ -231,16 +241,17 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
231 | * Make at least size bytes of linear space available for the tty | 241 | * Make at least size bytes of linear space available for the tty |
232 | * buffer. If we fail return the size we managed to find. | 242 | * buffer. If we fail return the size we managed to find. |
233 | * | 243 | * |
234 | * Locking: Takes tty->buf.lock | 244 | * Locking: Takes port->buf.lock |
235 | */ | 245 | */ |
236 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | 246 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) |
237 | { | 247 | { |
248 | struct tty_port *port = tty->port; | ||
238 | unsigned long flags; | 249 | unsigned long flags; |
239 | int length; | 250 | int length; |
240 | 251 | ||
241 | spin_lock_irqsave(&tty->buf.lock, flags); | 252 | spin_lock_irqsave(&port->buf.lock, flags); |
242 | length = __tty_buffer_request_room(tty, size); | 253 | length = __tty_buffer_request_room(port, size); |
243 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 254 | spin_unlock_irqrestore(&port->buf.lock, flags); |
244 | return length; | 255 | return length; |
245 | } | 256 | } |
246 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 257 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
@@ -255,12 +266,13 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); | |||
255 | * Queue a series of bytes to the tty buffering. All the characters | 266 | * Queue a series of bytes to the tty buffering. All the characters |
256 | * passed are marked with the supplied flag. Returns the number added. | 267 | * passed are marked with the supplied flag. Returns the number added. |
257 | * | 268 | * |
258 | * Locking: Called functions may take tty->buf.lock | 269 | * Locking: Called functions may take port->buf.lock |
259 | */ | 270 | */ |
260 | 271 | ||
261 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, | 272 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, |
262 | const unsigned char *chars, char flag, size_t size) | 273 | const unsigned char *chars, char flag, size_t size) |
263 | { | 274 | { |
275 | struct tty_bufhead *buf = &tty->port->buf; | ||
264 | int copied = 0; | 276 | int copied = 0; |
265 | do { | 277 | do { |
266 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 278 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
@@ -268,18 +280,18 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, | |||
268 | unsigned long flags; | 280 | unsigned long flags; |
269 | struct tty_buffer *tb; | 281 | struct tty_buffer *tb; |
270 | 282 | ||
271 | spin_lock_irqsave(&tty->buf.lock, flags); | 283 | spin_lock_irqsave(&buf->lock, flags); |
272 | space = __tty_buffer_request_room(tty, goal); | 284 | space = __tty_buffer_request_room(tty->port, goal); |
273 | tb = tty->buf.tail; | 285 | tb = buf->tail; |
274 | /* If there is no space then tb may be NULL */ | 286 | /* If there is no space then tb may be NULL */ |
275 | if (unlikely(space == 0)) { | 287 | if (unlikely(space == 0)) { |
276 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 288 | spin_unlock_irqrestore(&buf->lock, flags); |
277 | break; | 289 | break; |
278 | } | 290 | } |
279 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 291 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
280 | memset(tb->flag_buf_ptr + tb->used, flag, space); | 292 | memset(tb->flag_buf_ptr + tb->used, flag, space); |
281 | tb->used += space; | 293 | tb->used += space; |
282 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 294 | spin_unlock_irqrestore(&buf->lock, flags); |
283 | copied += space; | 295 | copied += space; |
284 | chars += space; | 296 | chars += space; |
285 | /* There is a small chance that we need to split the data over | 297 | /* There is a small chance that we need to split the data over |
@@ -300,12 +312,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); | |||
300 | * the flags array indicates the status of the character. Returns the | 312 | * the flags array indicates the status of the character. Returns the |
301 | * number added. | 313 | * number added. |
302 | * | 314 | * |
303 | * Locking: Called functions may take tty->buf.lock | 315 | * Locking: Called functions may take port->buf.lock |
304 | */ | 316 | */ |
305 | 317 | ||
306 | int tty_insert_flip_string_flags(struct tty_struct *tty, | 318 | int tty_insert_flip_string_flags(struct tty_struct *tty, |
307 | const unsigned char *chars, const char *flags, size_t size) | 319 | const unsigned char *chars, const char *flags, size_t size) |
308 | { | 320 | { |
321 | struct tty_bufhead *buf = &tty->port->buf; | ||
309 | int copied = 0; | 322 | int copied = 0; |
310 | do { | 323 | do { |
311 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 324 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
@@ -313,18 +326,18 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, | |||
313 | unsigned long __flags; | 326 | unsigned long __flags; |
314 | struct tty_buffer *tb; | 327 | struct tty_buffer *tb; |
315 | 328 | ||
316 | spin_lock_irqsave(&tty->buf.lock, __flags); | 329 | spin_lock_irqsave(&buf->lock, __flags); |
317 | space = __tty_buffer_request_room(tty, goal); | 330 | space = __tty_buffer_request_room(tty->port, goal); |
318 | tb = tty->buf.tail; | 331 | tb = buf->tail; |
319 | /* If there is no space then tb may be NULL */ | 332 | /* If there is no space then tb may be NULL */ |
320 | if (unlikely(space == 0)) { | 333 | if (unlikely(space == 0)) { |
321 | spin_unlock_irqrestore(&tty->buf.lock, __flags); | 334 | spin_unlock_irqrestore(&buf->lock, __flags); |
322 | break; | 335 | break; |
323 | } | 336 | } |
324 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 337 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
325 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | 338 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); |
326 | tb->used += space; | 339 | tb->used += space; |
327 | spin_unlock_irqrestore(&tty->buf.lock, __flags); | 340 | spin_unlock_irqrestore(&buf->lock, __flags); |
328 | copied += space; | 341 | copied += space; |
329 | chars += space; | 342 | chars += space; |
330 | flags += space; | 343 | flags += space; |
@@ -342,18 +355,23 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); | |||
342 | * Takes any pending buffers and transfers their ownership to the | 355 | * Takes any pending buffers and transfers their ownership to the |
343 | * ldisc side of the queue. It then schedules those characters for | 356 | * ldisc side of the queue. It then schedules those characters for |
344 | * processing by the line discipline. | 357 | * processing by the line discipline. |
358 | * Note that this function can only be used when the low_latency flag | ||
359 | * is unset. Otherwise the workqueue won't be flushed. | ||
345 | * | 360 | * |
346 | * Locking: Takes tty->buf.lock | 361 | * Locking: Takes port->buf.lock |
347 | */ | 362 | */ |
348 | 363 | ||
349 | void tty_schedule_flip(struct tty_struct *tty) | 364 | void tty_schedule_flip(struct tty_struct *tty) |
350 | { | 365 | { |
366 | struct tty_bufhead *buf = &tty->port->buf; | ||
351 | unsigned long flags; | 367 | unsigned long flags; |
352 | spin_lock_irqsave(&tty->buf.lock, flags); | 368 | WARN_ON(tty->low_latency); |
353 | if (tty->buf.tail != NULL) | 369 | |
354 | tty->buf.tail->commit = tty->buf.tail->used; | 370 | spin_lock_irqsave(&buf->lock, flags); |
355 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 371 | if (buf->tail != NULL) |
356 | schedule_work(&tty->buf.work); | 372 | buf->tail->commit = buf->tail->used; |
373 | spin_unlock_irqrestore(&buf->lock, flags); | ||
374 | schedule_work(&buf->work); | ||
357 | } | 375 | } |
358 | EXPORT_SYMBOL(tty_schedule_flip); | 376 | EXPORT_SYMBOL(tty_schedule_flip); |
359 | 377 | ||
@@ -369,26 +387,27 @@ EXPORT_SYMBOL(tty_schedule_flip); | |||
369 | * that need their own block copy routines into the buffer. There is no | 387 | * that need their own block copy routines into the buffer. There is no |
370 | * guarantee the buffer is a DMA target! | 388 | * guarantee the buffer is a DMA target! |
371 | * | 389 | * |
372 | * Locking: May call functions taking tty->buf.lock | 390 | * Locking: May call functions taking port->buf.lock |
373 | */ | 391 | */ |
374 | 392 | ||
375 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | 393 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, |
376 | size_t size) | 394 | size_t size) |
377 | { | 395 | { |
396 | struct tty_bufhead *buf = &tty->port->buf; | ||
378 | int space; | 397 | int space; |
379 | unsigned long flags; | 398 | unsigned long flags; |
380 | struct tty_buffer *tb; | 399 | struct tty_buffer *tb; |
381 | 400 | ||
382 | spin_lock_irqsave(&tty->buf.lock, flags); | 401 | spin_lock_irqsave(&buf->lock, flags); |
383 | space = __tty_buffer_request_room(tty, size); | 402 | space = __tty_buffer_request_room(tty->port, size); |
384 | 403 | ||
385 | tb = tty->buf.tail; | 404 | tb = buf->tail; |
386 | if (likely(space)) { | 405 | if (likely(space)) { |
387 | *chars = tb->char_buf_ptr + tb->used; | 406 | *chars = tb->char_buf_ptr + tb->used; |
388 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | 407 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); |
389 | tb->used += space; | 408 | tb->used += space; |
390 | } | 409 | } |
391 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 410 | spin_unlock_irqrestore(&buf->lock, flags); |
392 | return space; | 411 | return space; |
393 | } | 412 | } |
394 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 413 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
@@ -406,26 +425,27 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | |||
406 | * that need their own block copy routines into the buffer. There is no | 425 | * that need their own block copy routines into the buffer. There is no |
407 | * guarantee the buffer is a DMA target! | 426 | * guarantee the buffer is a DMA target! |
408 | * | 427 | * |
409 | * Locking: May call functions taking tty->buf.lock | 428 | * Locking: May call functions taking port->buf.lock |
410 | */ | 429 | */ |
411 | 430 | ||
412 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | 431 | int tty_prepare_flip_string_flags(struct tty_struct *tty, |
413 | unsigned char **chars, char **flags, size_t size) | 432 | unsigned char **chars, char **flags, size_t size) |
414 | { | 433 | { |
434 | struct tty_bufhead *buf = &tty->port->buf; | ||
415 | int space; | 435 | int space; |
416 | unsigned long __flags; | 436 | unsigned long __flags; |
417 | struct tty_buffer *tb; | 437 | struct tty_buffer *tb; |
418 | 438 | ||
419 | spin_lock_irqsave(&tty->buf.lock, __flags); | 439 | spin_lock_irqsave(&buf->lock, __flags); |
420 | space = __tty_buffer_request_room(tty, size); | 440 | space = __tty_buffer_request_room(tty->port, size); |
421 | 441 | ||
422 | tb = tty->buf.tail; | 442 | tb = buf->tail; |
423 | if (likely(space)) { | 443 | if (likely(space)) { |
424 | *chars = tb->char_buf_ptr + tb->used; | 444 | *chars = tb->char_buf_ptr + tb->used; |
425 | *flags = tb->flag_buf_ptr + tb->used; | 445 | *flags = tb->flag_buf_ptr + tb->used; |
426 | tb->used += space; | 446 | tb->used += space; |
427 | } | 447 | } |
428 | spin_unlock_irqrestore(&tty->buf.lock, __flags); | 448 | spin_unlock_irqrestore(&buf->lock, __flags); |
429 | return space; | 449 | return space; |
430 | } | 450 | } |
431 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | 451 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); |
@@ -446,20 +466,25 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | |||
446 | 466 | ||
447 | static void flush_to_ldisc(struct work_struct *work) | 467 | static void flush_to_ldisc(struct work_struct *work) |
448 | { | 468 | { |
449 | struct tty_struct *tty = | 469 | struct tty_port *port = container_of(work, struct tty_port, buf.work); |
450 | container_of(work, struct tty_struct, buf.work); | 470 | struct tty_bufhead *buf = &port->buf; |
471 | struct tty_struct *tty; | ||
451 | unsigned long flags; | 472 | unsigned long flags; |
452 | struct tty_ldisc *disc; | 473 | struct tty_ldisc *disc; |
453 | 474 | ||
475 | tty = port->itty; | ||
476 | if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n")) | ||
477 | return; | ||
478 | |||
454 | disc = tty_ldisc_ref(tty); | 479 | disc = tty_ldisc_ref(tty); |
455 | if (disc == NULL) /* !TTY_LDISC */ | 480 | if (disc == NULL) /* !TTY_LDISC */ |
456 | return; | 481 | return; |
457 | 482 | ||
458 | spin_lock_irqsave(&tty->buf.lock, flags); | 483 | spin_lock_irqsave(&buf->lock, flags); |
459 | 484 | ||
460 | if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { | 485 | if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) { |
461 | struct tty_buffer *head; | 486 | struct tty_buffer *head; |
462 | while ((head = tty->buf.head) != NULL) { | 487 | while ((head = buf->head) != NULL) { |
463 | int count; | 488 | int count; |
464 | char *char_buf; | 489 | char *char_buf; |
465 | unsigned char *flag_buf; | 490 | unsigned char *flag_buf; |
@@ -468,14 +493,14 @@ static void flush_to_ldisc(struct work_struct *work) | |||
468 | if (!count) { | 493 | if (!count) { |
469 | if (head->next == NULL) | 494 | if (head->next == NULL) |
470 | break; | 495 | break; |
471 | tty->buf.head = head->next; | 496 | buf->head = head->next; |
472 | tty_buffer_free(tty, head); | 497 | tty_buffer_free(port, head); |
473 | continue; | 498 | continue; |
474 | } | 499 | } |
475 | /* Ldisc or user is trying to flush the buffers | 500 | /* Ldisc or user is trying to flush the buffers |
476 | we are feeding to the ldisc, stop feeding the | 501 | we are feeding to the ldisc, stop feeding the |
477 | line discipline as we want to empty the queue */ | 502 | line discipline as we want to empty the queue */ |
478 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | 503 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) |
479 | break; | 504 | break; |
480 | if (!tty->receive_room) | 505 | if (!tty->receive_room) |
481 | break; | 506 | break; |
@@ -484,22 +509,22 @@ static void flush_to_ldisc(struct work_struct *work) | |||
484 | char_buf = head->char_buf_ptr + head->read; | 509 | char_buf = head->char_buf_ptr + head->read; |
485 | flag_buf = head->flag_buf_ptr + head->read; | 510 | flag_buf = head->flag_buf_ptr + head->read; |
486 | head->read += count; | 511 | head->read += count; |
487 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 512 | spin_unlock_irqrestore(&buf->lock, flags); |
488 | disc->ops->receive_buf(tty, char_buf, | 513 | disc->ops->receive_buf(tty, char_buf, |
489 | flag_buf, count); | 514 | flag_buf, count); |
490 | spin_lock_irqsave(&tty->buf.lock, flags); | 515 | spin_lock_irqsave(&buf->lock, flags); |
491 | } | 516 | } |
492 | clear_bit(TTY_FLUSHING, &tty->flags); | 517 | clear_bit(TTYP_FLUSHING, &port->iflags); |
493 | } | 518 | } |
494 | 519 | ||
495 | /* We may have a deferred request to flush the input buffer, | 520 | /* We may have a deferred request to flush the input buffer, |
496 | if so pull the chain under the lock and empty the queue */ | 521 | if so pull the chain under the lock and empty the queue */ |
497 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { | 522 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { |
498 | __tty_buffer_flush(tty); | 523 | __tty_buffer_flush(port); |
499 | clear_bit(TTY_FLUSHPENDING, &tty->flags); | 524 | clear_bit(TTYP_FLUSHPENDING, &port->iflags); |
500 | wake_up(&tty->read_wait); | 525 | wake_up(&tty->read_wait); |
501 | } | 526 | } |
502 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 527 | spin_unlock_irqrestore(&buf->lock, flags); |
503 | 528 | ||
504 | tty_ldisc_deref(disc); | 529 | tty_ldisc_deref(disc); |
505 | } | 530 | } |
@@ -514,7 +539,8 @@ static void flush_to_ldisc(struct work_struct *work) | |||
514 | */ | 539 | */ |
515 | void tty_flush_to_ldisc(struct tty_struct *tty) | 540 | void tty_flush_to_ldisc(struct tty_struct *tty) |
516 | { | 541 | { |
517 | flush_work(&tty->buf.work); | 542 | if (!tty->low_latency) |
543 | flush_work(&tty->port->buf.work); | ||
518 | } | 544 | } |
519 | 545 | ||
520 | /** | 546 | /** |
@@ -532,16 +558,18 @@ void tty_flush_to_ldisc(struct tty_struct *tty) | |||
532 | 558 | ||
533 | void tty_flip_buffer_push(struct tty_struct *tty) | 559 | void tty_flip_buffer_push(struct tty_struct *tty) |
534 | { | 560 | { |
561 | struct tty_bufhead *buf = &tty->port->buf; | ||
535 | unsigned long flags; | 562 | unsigned long flags; |
536 | spin_lock_irqsave(&tty->buf.lock, flags); | 563 | |
537 | if (tty->buf.tail != NULL) | 564 | spin_lock_irqsave(&buf->lock, flags); |
538 | tty->buf.tail->commit = tty->buf.tail->used; | 565 | if (buf->tail != NULL) |
539 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 566 | buf->tail->commit = buf->tail->used; |
567 | spin_unlock_irqrestore(&buf->lock, flags); | ||
540 | 568 | ||
541 | if (tty->low_latency) | 569 | if (tty->low_latency) |
542 | flush_to_ldisc(&tty->buf.work); | 570 | flush_to_ldisc(&buf->work); |
543 | else | 571 | else |
544 | schedule_work(&tty->buf.work); | 572 | schedule_work(&buf->work); |
545 | } | 573 | } |
546 | EXPORT_SYMBOL(tty_flip_buffer_push); | 574 | EXPORT_SYMBOL(tty_flip_buffer_push); |
547 | 575 | ||
@@ -555,13 +583,15 @@ EXPORT_SYMBOL(tty_flip_buffer_push); | |||
555 | * Locking: none | 583 | * Locking: none |
556 | */ | 584 | */ |
557 | 585 | ||
558 | void tty_buffer_init(struct tty_struct *tty) | 586 | void tty_buffer_init(struct tty_port *port) |
559 | { | 587 | { |
560 | spin_lock_init(&tty->buf.lock); | 588 | struct tty_bufhead *buf = &port->buf; |
561 | tty->buf.head = NULL; | 589 | |
562 | tty->buf.tail = NULL; | 590 | spin_lock_init(&buf->lock); |
563 | tty->buf.free = NULL; | 591 | buf->head = NULL; |
564 | tty->buf.memory_used = 0; | 592 | buf->tail = NULL; |
565 | INIT_WORK(&tty->buf.work, flush_to_ldisc); | 593 | buf->free = NULL; |
594 | buf->memory_used = 0; | ||
595 | INIT_WORK(&buf->work, flush_to_ldisc); | ||
566 | } | 596 | } |
567 | 597 | ||
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 2ea176b2280e..da9fde850754 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -186,7 +186,6 @@ void free_tty_struct(struct tty_struct *tty) | |||
186 | if (tty->dev) | 186 | if (tty->dev) |
187 | put_device(tty->dev); | 187 | put_device(tty->dev); |
188 | kfree(tty->write_buf); | 188 | kfree(tty->write_buf); |
189 | tty_buffer_free_all(tty); | ||
190 | tty->magic = 0xDEADDEAD; | 189 | tty->magic = 0xDEADDEAD; |
191 | kfree(tty); | 190 | kfree(tty); |
192 | } | 191 | } |
@@ -237,7 +236,7 @@ void tty_free_file(struct file *file) | |||
237 | } | 236 | } |
238 | 237 | ||
239 | /* Delete file from its tty */ | 238 | /* Delete file from its tty */ |
240 | void tty_del_file(struct file *file) | 239 | static void tty_del_file(struct file *file) |
241 | { | 240 | { |
242 | struct tty_file_private *priv = file->private_data; | 241 | struct tty_file_private *priv = file->private_data; |
243 | 242 | ||
@@ -555,7 +554,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
555 | * tasklist_lock to walk task list for hangup event | 554 | * tasklist_lock to walk task list for hangup event |
556 | * ->siglock to protect ->signal/->sighand | 555 | * ->siglock to protect ->signal/->sighand |
557 | */ | 556 | */ |
558 | void __tty_hangup(struct tty_struct *tty) | 557 | static void __tty_hangup(struct tty_struct *tty) |
559 | { | 558 | { |
560 | struct file *cons_filp = NULL; | 559 | struct file *cons_filp = NULL; |
561 | struct file *filp, *f = NULL; | 560 | struct file *filp, *f = NULL; |
@@ -1417,6 +1416,8 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1417 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", | 1416 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", |
1418 | __func__, tty->driver->name); | 1417 | __func__, tty->driver->name); |
1419 | 1418 | ||
1419 | tty->port->itty = tty; | ||
1420 | |||
1420 | /* | 1421 | /* |
1421 | * Structures all installed ... call the ldisc open routines. | 1422 | * Structures all installed ... call the ldisc open routines. |
1422 | * If we fail here just call release_tty to clean up. No need | 1423 | * If we fail here just call release_tty to clean up. No need |
@@ -1552,6 +1553,7 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1552 | tty->ops->shutdown(tty); | 1553 | tty->ops->shutdown(tty); |
1553 | tty_free_termios(tty); | 1554 | tty_free_termios(tty); |
1554 | tty_driver_remove_tty(tty->driver, tty); | 1555 | tty_driver_remove_tty(tty->driver, tty); |
1556 | tty->port->itty = NULL; | ||
1555 | 1557 | ||
1556 | if (tty->link) | 1558 | if (tty->link) |
1557 | tty_kref_put(tty->link); | 1559 | tty_kref_put(tty->link); |
@@ -1625,7 +1627,6 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1625 | struct tty_struct *tty = file_tty(filp); | 1627 | struct tty_struct *tty = file_tty(filp); |
1626 | struct tty_struct *o_tty; | 1628 | struct tty_struct *o_tty; |
1627 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1629 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1628 | int devpts; | ||
1629 | int idx; | 1630 | int idx; |
1630 | char buf[64]; | 1631 | char buf[64]; |
1631 | 1632 | ||
@@ -1640,7 +1641,6 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1640 | idx = tty->index; | 1641 | idx = tty->index; |
1641 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1642 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1642 | tty->driver->subtype == PTY_TYPE_MASTER); | 1643 | tty->driver->subtype == PTY_TYPE_MASTER); |
1643 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | ||
1644 | /* Review: parallel close */ | 1644 | /* Review: parallel close */ |
1645 | o_tty = tty->link; | 1645 | o_tty = tty->link; |
1646 | 1646 | ||
@@ -1799,9 +1799,6 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1799 | release_tty(tty, idx); | 1799 | release_tty(tty, idx); |
1800 | mutex_unlock(&tty_mutex); | 1800 | mutex_unlock(&tty_mutex); |
1801 | 1801 | ||
1802 | /* Make this pty number available for reallocation */ | ||
1803 | if (devpts) | ||
1804 | devpts_kill_index(inode, idx); | ||
1805 | return 0; | 1802 | return 0; |
1806 | } | 1803 | } |
1807 | 1804 | ||
@@ -2690,6 +2687,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2690 | case TIOCNXCL: | 2687 | case TIOCNXCL: |
2691 | clear_bit(TTY_EXCLUSIVE, &tty->flags); | 2688 | clear_bit(TTY_EXCLUSIVE, &tty->flags); |
2692 | return 0; | 2689 | return 0; |
2690 | case TIOCGEXCL: | ||
2691 | { | ||
2692 | int excl = test_bit(TTY_EXCLUSIVE, &tty->flags); | ||
2693 | return put_user(excl, (int __user *)p); | ||
2694 | } | ||
2693 | case TIOCNOTTY: | 2695 | case TIOCNOTTY: |
2694 | if (current->signal->tty != tty) | 2696 | if (current->signal->tty != tty) |
2695 | return -ENOTTY; | 2697 | return -ENOTTY; |
@@ -2937,19 +2939,13 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2937 | tty_ldisc_init(tty); | 2939 | tty_ldisc_init(tty); |
2938 | tty->session = NULL; | 2940 | tty->session = NULL; |
2939 | tty->pgrp = NULL; | 2941 | tty->pgrp = NULL; |
2940 | tty->overrun_time = jiffies; | ||
2941 | tty_buffer_init(tty); | ||
2942 | mutex_init(&tty->legacy_mutex); | 2942 | mutex_init(&tty->legacy_mutex); |
2943 | mutex_init(&tty->termios_mutex); | 2943 | mutex_init(&tty->termios_mutex); |
2944 | mutex_init(&tty->ldisc_mutex); | 2944 | mutex_init(&tty->ldisc_mutex); |
2945 | init_waitqueue_head(&tty->write_wait); | 2945 | init_waitqueue_head(&tty->write_wait); |
2946 | init_waitqueue_head(&tty->read_wait); | 2946 | init_waitqueue_head(&tty->read_wait); |
2947 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 2947 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
2948 | mutex_init(&tty->atomic_read_lock); | ||
2949 | mutex_init(&tty->atomic_write_lock); | 2948 | mutex_init(&tty->atomic_write_lock); |
2950 | mutex_init(&tty->output_lock); | ||
2951 | mutex_init(&tty->echo_lock); | ||
2952 | spin_lock_init(&tty->read_lock); | ||
2953 | spin_lock_init(&tty->ctrl_lock); | 2949 | spin_lock_init(&tty->ctrl_lock); |
2954 | INIT_LIST_HEAD(&tty->tty_files); | 2950 | INIT_LIST_HEAD(&tty->tty_files); |
2955 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 2951 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 12b1fa0f4f86..8481b29d5b3a 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -1118,7 +1118,6 @@ EXPORT_SYMBOL_GPL(tty_perform_flush); | |||
1118 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | 1118 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
1119 | unsigned int cmd, unsigned long arg) | 1119 | unsigned int cmd, unsigned long arg) |
1120 | { | 1120 | { |
1121 | unsigned long flags; | ||
1122 | int retval; | 1121 | int retval; |
1123 | 1122 | ||
1124 | switch (cmd) { | 1123 | switch (cmd) { |
@@ -1153,26 +1152,6 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | |||
1153 | return 0; | 1152 | return 0; |
1154 | case TCFLSH: | 1153 | case TCFLSH: |
1155 | return tty_perform_flush(tty, arg); | 1154 | return tty_perform_flush(tty, arg); |
1156 | case TIOCPKT: | ||
1157 | { | ||
1158 | int pktmode; | ||
1159 | |||
1160 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY || | ||
1161 | tty->driver->subtype != PTY_TYPE_MASTER) | ||
1162 | return -ENOTTY; | ||
1163 | if (get_user(pktmode, (int __user *) arg)) | ||
1164 | return -EFAULT; | ||
1165 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1166 | if (pktmode) { | ||
1167 | if (!tty->packet) { | ||
1168 | tty->packet = 1; | ||
1169 | tty->link->ctrl_status = 0; | ||
1170 | } | ||
1171 | } else | ||
1172 | tty->packet = 0; | ||
1173 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1174 | return 0; | ||
1175 | } | ||
1176 | default: | 1155 | default: |
1177 | /* Try the mode commands */ | 1156 | /* Try the mode commands */ |
1178 | return tty_mode_ioctl(tty, file, cmd, arg); | 1157 | return tty_mode_ioctl(tty, file, cmd, arg); |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 0f2a2c5e704c..c5782294e532 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * callers who will do ldisc lookups and cannot sleep. | 26 | * callers who will do ldisc lookups and cannot sleep. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | static DEFINE_SPINLOCK(tty_ldisc_lock); | 29 | static DEFINE_RAW_SPINLOCK(tty_ldisc_lock); |
30 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 30 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
31 | /* Line disc dispatch table */ | 31 | /* Line disc dispatch table */ |
32 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; | 32 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; |
@@ -49,21 +49,21 @@ static void put_ldisc(struct tty_ldisc *ld) | |||
49 | * If this is the last user, free the ldisc, and | 49 | * If this is the last user, free the ldisc, and |
50 | * release the ldisc ops. | 50 | * release the ldisc ops. |
51 | * | 51 | * |
52 | * We really want an "atomic_dec_and_lock_irqsave()", | 52 | * We really want an "atomic_dec_and_raw_lock_irqsave()", |
53 | * but we don't have it, so this does it by hand. | 53 | * but we don't have it, so this does it by hand. |
54 | */ | 54 | */ |
55 | local_irq_save(flags); | 55 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
56 | if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) { | 56 | if (atomic_dec_and_test(&ld->users)) { |
57 | struct tty_ldisc_ops *ldo = ld->ops; | 57 | struct tty_ldisc_ops *ldo = ld->ops; |
58 | 58 | ||
59 | ldo->refcount--; | 59 | ldo->refcount--; |
60 | module_put(ldo->owner); | 60 | module_put(ldo->owner); |
61 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 61 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
62 | 62 | ||
63 | kfree(ld); | 63 | kfree(ld); |
64 | return; | 64 | return; |
65 | } | 65 | } |
66 | local_irq_restore(flags); | 66 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
67 | wake_up(&ld->wq_idle); | 67 | wake_up(&ld->wq_idle); |
68 | } | 68 | } |
69 | 69 | ||
@@ -88,11 +88,11 @@ int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc) | |||
88 | if (disc < N_TTY || disc >= NR_LDISCS) | 88 | if (disc < N_TTY || disc >= NR_LDISCS) |
89 | return -EINVAL; | 89 | return -EINVAL; |
90 | 90 | ||
91 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 91 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
92 | tty_ldiscs[disc] = new_ldisc; | 92 | tty_ldiscs[disc] = new_ldisc; |
93 | new_ldisc->num = disc; | 93 | new_ldisc->num = disc; |
94 | new_ldisc->refcount = 0; | 94 | new_ldisc->refcount = 0; |
95 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 95 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
96 | 96 | ||
97 | return ret; | 97 | return ret; |
98 | } | 98 | } |
@@ -118,12 +118,12 @@ int tty_unregister_ldisc(int disc) | |||
118 | if (disc < N_TTY || disc >= NR_LDISCS) | 118 | if (disc < N_TTY || disc >= NR_LDISCS) |
119 | return -EINVAL; | 119 | return -EINVAL; |
120 | 120 | ||
121 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 121 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
122 | if (tty_ldiscs[disc]->refcount) | 122 | if (tty_ldiscs[disc]->refcount) |
123 | ret = -EBUSY; | 123 | ret = -EBUSY; |
124 | else | 124 | else |
125 | tty_ldiscs[disc] = NULL; | 125 | tty_ldiscs[disc] = NULL; |
126 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 126 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
127 | 127 | ||
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
@@ -134,7 +134,7 @@ static struct tty_ldisc_ops *get_ldops(int disc) | |||
134 | unsigned long flags; | 134 | unsigned long flags; |
135 | struct tty_ldisc_ops *ldops, *ret; | 135 | struct tty_ldisc_ops *ldops, *ret; |
136 | 136 | ||
137 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 137 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
138 | ret = ERR_PTR(-EINVAL); | 138 | ret = ERR_PTR(-EINVAL); |
139 | ldops = tty_ldiscs[disc]; | 139 | ldops = tty_ldiscs[disc]; |
140 | if (ldops) { | 140 | if (ldops) { |
@@ -144,7 +144,7 @@ static struct tty_ldisc_ops *get_ldops(int disc) | |||
144 | ret = ldops; | 144 | ret = ldops; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 147 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
148 | return ret; | 148 | return ret; |
149 | } | 149 | } |
150 | 150 | ||
@@ -152,10 +152,10 @@ static void put_ldops(struct tty_ldisc_ops *ldops) | |||
152 | { | 152 | { |
153 | unsigned long flags; | 153 | unsigned long flags; |
154 | 154 | ||
155 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 155 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
156 | ldops->refcount--; | 156 | ldops->refcount--; |
157 | module_put(ldops->owner); | 157 | module_put(ldops->owner); |
158 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 158 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
159 | } | 159 | } |
160 | 160 | ||
161 | /** | 161 | /** |
@@ -287,11 +287,11 @@ static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty) | |||
287 | unsigned long flags; | 287 | unsigned long flags; |
288 | struct tty_ldisc *ld; | 288 | struct tty_ldisc *ld; |
289 | 289 | ||
290 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 290 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
291 | ld = NULL; | 291 | ld = NULL; |
292 | if (test_bit(TTY_LDISC, &tty->flags)) | 292 | if (test_bit(TTY_LDISC, &tty->flags)) |
293 | ld = get_ldisc(tty->ldisc); | 293 | ld = get_ldisc(tty->ldisc); |
294 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 294 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
295 | return ld; | 295 | return ld; |
296 | } | 296 | } |
297 | 297 | ||
@@ -512,7 +512,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
512 | static int tty_ldisc_halt(struct tty_struct *tty) | 512 | static int tty_ldisc_halt(struct tty_struct *tty) |
513 | { | 513 | { |
514 | clear_bit(TTY_LDISC, &tty->flags); | 514 | clear_bit(TTY_LDISC, &tty->flags); |
515 | return cancel_work_sync(&tty->buf.work); | 515 | return cancel_work_sync(&tty->port->buf.work); |
516 | } | 516 | } |
517 | 517 | ||
518 | /** | 518 | /** |
@@ -525,7 +525,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) | |||
525 | { | 525 | { |
526 | flush_work(&tty->hangup_work); | 526 | flush_work(&tty->hangup_work); |
527 | flush_work(&tty->SAK_work); | 527 | flush_work(&tty->SAK_work); |
528 | flush_work(&tty->buf.work); | 528 | flush_work(&tty->port->buf.work); |
529 | } | 529 | } |
530 | 530 | ||
531 | /** | 531 | /** |
@@ -704,9 +704,9 @@ enable: | |||
704 | /* Restart the work queue in case no characters kick it off. Safe if | 704 | /* Restart the work queue in case no characters kick it off. Safe if |
705 | already running */ | 705 | already running */ |
706 | if (work) | 706 | if (work) |
707 | schedule_work(&tty->buf.work); | 707 | schedule_work(&tty->port->buf.work); |
708 | if (o_work) | 708 | if (o_work) |
709 | schedule_work(&o_tty->buf.work); | 709 | schedule_work(&o_tty->port->buf.work); |
710 | mutex_unlock(&tty->ldisc_mutex); | 710 | mutex_unlock(&tty->ldisc_mutex); |
711 | tty_unlock(tty); | 711 | tty_unlock(tty); |
712 | return retval; | 712 | return retval; |
@@ -817,7 +817,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
817 | */ | 817 | */ |
818 | clear_bit(TTY_LDISC, &tty->flags); | 818 | clear_bit(TTY_LDISC, &tty->flags); |
819 | tty_unlock(tty); | 819 | tty_unlock(tty); |
820 | cancel_work_sync(&tty->buf.work); | 820 | cancel_work_sync(&tty->port->buf.work); |
821 | mutex_unlock(&tty->ldisc_mutex); | 821 | mutex_unlock(&tty->ldisc_mutex); |
822 | retry: | 822 | retry: |
823 | tty_lock(tty); | 823 | tty_lock(tty); |
@@ -897,6 +897,11 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) | |||
897 | 897 | ||
898 | static void tty_ldisc_kill(struct tty_struct *tty) | 898 | static void tty_ldisc_kill(struct tty_struct *tty) |
899 | { | 899 | { |
900 | /* There cannot be users from userspace now. But there still might be | ||
901 | * drivers holding a reference via tty_ldisc_ref. Do not steal them the | ||
902 | * ldisc until they are done. */ | ||
903 | tty_ldisc_wait_idle(tty, MAX_SCHEDULE_TIMEOUT); | ||
904 | |||
900 | mutex_lock(&tty->ldisc_mutex); | 905 | mutex_lock(&tty->ldisc_mutex); |
901 | /* | 906 | /* |
902 | * Now kill off the ldisc | 907 | * Now kill off the ldisc |
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 67feac9e6ebb..2e41abebbcba 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
@@ -19,7 +19,7 @@ static void __lockfunc tty_lock_nested(struct tty_struct *tty, | |||
19 | unsigned int subclass) | 19 | unsigned int subclass) |
20 | { | 20 | { |
21 | if (tty->magic != TTY_MAGIC) { | 21 | if (tty->magic != TTY_MAGIC) { |
22 | printk(KERN_ERR "L Bad %p\n", tty); | 22 | pr_err("L Bad %p\n", tty); |
23 | WARN_ON(1); | 23 | WARN_ON(1); |
24 | return; | 24 | return; |
25 | } | 25 | } |
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(tty_lock); | |||
36 | void __lockfunc tty_unlock(struct tty_struct *tty) | 36 | void __lockfunc tty_unlock(struct tty_struct *tty) |
37 | { | 37 | { |
38 | if (tty->magic != TTY_MAGIC) { | 38 | if (tty->magic != TTY_MAGIC) { |
39 | printk(KERN_ERR "U Bad %p\n", tty); | 39 | pr_err("U Bad %p\n", tty); |
40 | WARN_ON(1); | 40 | WARN_ON(1); |
41 | return; | 41 | return; |
42 | } | 42 | } |
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index d7bdd8d0c23f..b7ff59d3db88 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
@@ -21,6 +21,7 @@ | |||
21 | void tty_port_init(struct tty_port *port) | 21 | void tty_port_init(struct tty_port *port) |
22 | { | 22 | { |
23 | memset(port, 0, sizeof(*port)); | 23 | memset(port, 0, sizeof(*port)); |
24 | tty_buffer_init(port); | ||
24 | init_waitqueue_head(&port->open_wait); | 25 | init_waitqueue_head(&port->open_wait); |
25 | init_waitqueue_head(&port->close_wait); | 26 | init_waitqueue_head(&port->close_wait); |
26 | init_waitqueue_head(&port->delta_msr_wait); | 27 | init_waitqueue_head(&port->delta_msr_wait); |
@@ -121,12 +122,27 @@ void tty_port_free_xmit_buf(struct tty_port *port) | |||
121 | } | 122 | } |
122 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | 123 | EXPORT_SYMBOL(tty_port_free_xmit_buf); |
123 | 124 | ||
125 | /** | ||
126 | * tty_port_destroy -- destroy inited port | ||
127 | * @port: tty port to be doestroyed | ||
128 | * | ||
129 | * When a port was initialized using tty_port_init, one has to destroy the | ||
130 | * port by this function. Either indirectly by using tty_port refcounting | ||
131 | * (tty_port_put) or directly if refcounting is not used. | ||
132 | */ | ||
133 | void tty_port_destroy(struct tty_port *port) | ||
134 | { | ||
135 | tty_buffer_free_all(port); | ||
136 | } | ||
137 | EXPORT_SYMBOL(tty_port_destroy); | ||
138 | |||
124 | static void tty_port_destructor(struct kref *kref) | 139 | static void tty_port_destructor(struct kref *kref) |
125 | { | 140 | { |
126 | struct tty_port *port = container_of(kref, struct tty_port, kref); | 141 | struct tty_port *port = container_of(kref, struct tty_port, kref); |
127 | if (port->xmit_buf) | 142 | if (port->xmit_buf) |
128 | free_page((unsigned long)port->xmit_buf); | 143 | free_page((unsigned long)port->xmit_buf); |
129 | if (port->ops->destruct) | 144 | tty_port_destroy(port); |
145 | if (port->ops && port->ops->destruct) | ||
130 | port->ops->destruct(port); | 146 | port->ops->destruct(port); |
131 | else | 147 | else |
132 | kfree(port); | 148 | kfree(port); |
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 2aaa0c228409..248381b30722 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
@@ -410,10 +410,8 @@ static void con_release_unimap(struct uni_pagedir *p) | |||
410 | kfree(p->inverse_translations[i]); | 410 | kfree(p->inverse_translations[i]); |
411 | p->inverse_translations[i] = NULL; | 411 | p->inverse_translations[i] = NULL; |
412 | } | 412 | } |
413 | if (p->inverse_trans_unicode) { | 413 | kfree(p->inverse_trans_unicode); |
414 | kfree(p->inverse_trans_unicode); | 414 | p->inverse_trans_unicode = NULL; |
415 | p->inverse_trans_unicode = NULL; | ||
416 | } | ||
417 | } | 415 | } |
418 | 416 | ||
419 | /* Caller must hold the console lock */ | 417 | /* Caller must hold the console lock */ |
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 8e9b4be97a2d..60b7b6926059 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
@@ -341,15 +341,11 @@ int paste_selection(struct tty_struct *tty) | |||
341 | struct tty_ldisc *ld; | 341 | struct tty_ldisc *ld; |
342 | DECLARE_WAITQUEUE(wait, current); | 342 | DECLARE_WAITQUEUE(wait, current); |
343 | 343 | ||
344 | |||
345 | console_lock(); | 344 | console_lock(); |
346 | poke_blanked_console(); | 345 | poke_blanked_console(); |
347 | console_unlock(); | 346 | console_unlock(); |
348 | 347 | ||
349 | /* FIXME: wtf is this supposed to achieve ? */ | 348 | ld = tty_ldisc_ref_wait(tty); |
350 | ld = tty_ldisc_ref(tty); | ||
351 | if (!ld) | ||
352 | ld = tty_ldisc_ref_wait(tty); | ||
353 | 349 | ||
354 | /* FIXME: this is completely unsafe */ | 350 | /* FIXME: this is completely unsafe */ |
355 | add_wait_queue(&vc->paste_wait, &wait); | 351 | add_wait_queue(&vc->paste_wait, &wait); |
@@ -361,8 +357,7 @@ int paste_selection(struct tty_struct *tty) | |||
361 | } | 357 | } |
362 | count = sel_buffer_lth - pasted; | 358 | count = sel_buffer_lth - pasted; |
363 | count = min(count, tty->receive_room); | 359 | count = min(count, tty->receive_room); |
364 | tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, | 360 | ld->ops->receive_buf(tty, sel_buffer + pasted, NULL, count); |
365 | NULL, count); | ||
366 | pasted += count; | 361 | pasted += count; |
367 | } | 362 | } |
368 | remove_wait_queue(&vc->paste_wait, &wait); | 363 | remove_wait_queue(&vc->paste_wait, &wait); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4e0d0c3734b3..8fd89687d068 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -779,6 +779,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
779 | con_set_default_unimap(vc); | 779 | con_set_default_unimap(vc); |
780 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); | 780 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
781 | if (!vc->vc_screenbuf) { | 781 | if (!vc->vc_screenbuf) { |
782 | tty_port_destroy(&vc->port); | ||
782 | kfree(vc); | 783 | kfree(vc); |
783 | vc_cons[currcons].d = NULL; | 784 | vc_cons[currcons].d = NULL; |
784 | return -ENOMEM; | 785 | return -ENOMEM; |
@@ -999,8 +1000,10 @@ void vc_deallocate(unsigned int currcons) | |||
999 | put_pid(vc->vt_pid); | 1000 | put_pid(vc->vt_pid); |
1000 | module_put(vc->vc_sw->owner); | 1001 | module_put(vc->vc_sw->owner); |
1001 | kfree(vc->vc_screenbuf); | 1002 | kfree(vc->vc_screenbuf); |
1002 | if (currcons >= MIN_NR_CONSOLES) | 1003 | if (currcons >= MIN_NR_CONSOLES) { |
1004 | tty_port_destroy(&vc->port); | ||
1003 | kfree(vc); | 1005 | kfree(vc); |
1006 | } | ||
1004 | vc_cons[currcons].d = NULL; | 1007 | vc_cons[currcons].d = NULL; |
1005 | } | 1008 | } |
1006 | } | 1009 | } |
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index b841f56d2e66..98ff1735eafc 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/console.h> | 25 | #include <linux/console.h> |
26 | #include <linux/consolemap.h> | 26 | #include <linux/consolemap.h> |
27 | #include <linux/signal.h> | 27 | #include <linux/signal.h> |
28 | #include <linux/suspend.h> | ||
28 | #include <linux/timex.h> | 29 | #include <linux/timex.h> |
29 | 30 | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index f1739526820f..d0f95482f40e 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -1145,8 +1145,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count) | |||
1145 | 1145 | ||
1146 | return status; | 1146 | return status; |
1147 | fail: | 1147 | fail: |
1148 | while (count--) | 1148 | while (count--) { |
1149 | tty_port_destroy(&ports[count].port->port); | ||
1149 | kfree(ports[count].port); | 1150 | kfree(ports[count].port); |
1151 | } | ||
1150 | put_tty_driver(gs_tty_driver); | 1152 | put_tty_driver(gs_tty_driver); |
1151 | gs_tty_driver = NULL; | 1153 | gs_tty_driver = NULL; |
1152 | return status; | 1154 | return status; |
@@ -1200,6 +1202,7 @@ void gserial_cleanup(void) | |||
1200 | 1202 | ||
1201 | WARN_ON(port->port_usb != NULL); | 1203 | WARN_ON(port->port_usb != NULL); |
1202 | 1204 | ||
1205 | tty_port_destroy(&port->port); | ||
1203 | kfree(port); | 1206 | kfree(port); |
1204 | } | 1207 | } |
1205 | n_ports = 0; | 1208 | n_ports = 0; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 73b8e0569164..64bda135ba7e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -597,6 +597,7 @@ static void port_release(struct device *dev) | |||
597 | kfifo_free(&port->write_fifo); | 597 | kfifo_free(&port->write_fifo); |
598 | kfree(port->interrupt_in_buffer); | 598 | kfree(port->interrupt_in_buffer); |
599 | kfree(port->interrupt_out_buffer); | 599 | kfree(port->interrupt_out_buffer); |
600 | tty_port_destroy(&port->port); | ||
600 | kfree(port); | 601 | kfree(port); |
601 | } | 602 | } |
602 | 603 | ||