TTY/Serial merge for 3.8-rc1
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> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlDHhgwACgkQMUfUDdst+ynI6wCcC+YeBwncnoWHvwLAJOwAZpUL bysAn28o780/lOsTzp3P1Qcjvo69nldo =hN/g -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
c6bd5bcc49
|
@ -26,3 +26,115 @@ Description:
|
||||||
UART port in serial_core, that is bound to TTY like ttyS0.
|
UART port in serial_core, that is bound to TTY like ttyS0.
|
||||||
uartclk = 16 * baud_base
|
uartclk = 16 * baud_base
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/type
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Shows the current tty type for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/line
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Shows the current tty line number for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/port
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Shows the current tty port I/O address for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/irq
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Shows the current primary interrupt for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/flags
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the tty port status flags for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/xmit_fifo_size
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the transmit FIFO size for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/close_delay
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the closing delay time for this port in ms.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/closing_wait
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the close wait time for this port in ms.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/custom_divisor
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the custom divisor if any that is set on this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/io_type
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the I/O type that is to be used with the iomem base
|
||||||
|
address.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/iomem_base
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
The I/O memory base for this port.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
||||||
|
What: /sys/class/tty/ttyS0/iomem_reg_shift
|
||||||
|
Date: October 2012
|
||||||
|
Contact: Alan Cox <alan@linux.intel.com>
|
||||||
|
Description:
|
||||||
|
Show the register shift indicating the spacing to be used
|
||||||
|
for accesses on this iomem address.
|
||||||
|
|
||||||
|
These sysfs values expose the TIOCGSERIAL interface via
|
||||||
|
sysfs rather than via ioctls.
|
||||||
|
|
|
@ -6,11 +6,19 @@ Required properties:
|
||||||
- reg : Address and length of the register set for the device
|
- reg : Address and length of the register set for the device
|
||||||
- interrupts : Should contain the auart interrupt numbers
|
- interrupts : Should contain the auart interrupt numbers
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other
|
||||||
|
is for TX. If you add this property, it also means that you
|
||||||
|
will enable the DMA support for the auart.
|
||||||
|
Note: due to the hardware bug in imx23(see errata : 2836),
|
||||||
|
only the imx28 can enable the DMA support for the auart.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
auart0: serial@8006a000 {
|
auart0: serial@8006a000 {
|
||||||
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
|
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
|
||||||
reg = <0x8006a000 0x2000>;
|
reg = <0x8006a000 0x2000>;
|
||||||
interrupts = <112 70 71>;
|
interrupts = <112 70 71>;
|
||||||
|
fsl,auart-dma-channel = <8 9>;
|
||||||
};
|
};
|
||||||
|
|
||||||
Note: Each auart port should have an alias correctly numbered in "aliases"
|
Note: Each auart port should have an alias correctly numbered in "aliases"
|
||||||
|
|
|
@ -14,7 +14,10 @@ Required properties:
|
||||||
- "serial" if the port type is unknown.
|
- "serial" if the port type is unknown.
|
||||||
- reg : offset and length of the register set for the device.
|
- reg : offset and length of the register set for the device.
|
||||||
- interrupts : should contain uart interrupt.
|
- interrupts : should contain uart interrupt.
|
||||||
- clock-frequency : the input clock frequency for the UART.
|
- clock-frequency : the input clock frequency for the UART
|
||||||
|
or
|
||||||
|
clocks phandle to refer to the clk used as per Documentation/devicetree
|
||||||
|
/bindings/clock/clock-bindings.txt
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- current-speed : the current active speed of the UART.
|
- current-speed : the current active speed of the UART.
|
||||||
|
|
|
@ -7430,6 +7430,7 @@ K: ^Subject:.*(?i)trivial
|
||||||
|
|
||||||
TTY LAYER
|
TTY LAYER
|
||||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
M: Jiri Slaby <jslaby@suse.cz>
|
||||||
S: Supported
|
S: Supported
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
|
||||||
F: drivers/tty/
|
F: drivers/tty/
|
||||||
|
|
|
@ -95,6 +95,9 @@
|
||||||
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
||||||
#define TIOCVHANGUP 0x5437
|
#define TIOCVHANGUP 0x5437
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
#define TIOCSERCONFIG 0x5453
|
#define TIOCSERCONFIG 0x5453
|
||||||
#define TIOCSERGWILD 0x5454
|
#define TIOCSERGWILD 0x5454
|
||||||
|
|
|
@ -205,7 +205,6 @@ static const struct tty_operations srmcons_ops = {
|
||||||
static int __init
|
static int __init
|
||||||
srmcons_init(void)
|
srmcons_init(void)
|
||||||
{
|
{
|
||||||
tty_port_init(&srmcons_singleton.port);
|
|
||||||
setup_timer(&srmcons_singleton.timer, srmcons_receive_chars,
|
setup_timer(&srmcons_singleton.timer, srmcons_receive_chars,
|
||||||
(unsigned long)&srmcons_singleton);
|
(unsigned long)&srmcons_singleton);
|
||||||
if (srm_is_registered_console) {
|
if (srm_is_registered_console) {
|
||||||
|
@ -215,6 +214,9 @@ srmcons_init(void)
|
||||||
driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES);
|
driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES);
|
||||||
if (!driver)
|
if (!driver)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
tty_port_init(&srmcons_singleton.port);
|
||||||
|
|
||||||
driver->driver_name = "srm";
|
driver->driver_name = "srm";
|
||||||
driver->name = "srm";
|
driver->name = "srm";
|
||||||
driver->major = 0; /* dynamic */
|
driver->major = 0; /* dynamic */
|
||||||
|
@ -227,6 +229,7 @@ srmcons_init(void)
|
||||||
err = tty_register_driver(driver);
|
err = tty_register_driver(driver);
|
||||||
if (err) {
|
if (err) {
|
||||||
put_tty_driver(driver);
|
put_tty_driver(driver);
|
||||||
|
tty_port_destroy(&srmcons_singleton.port);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
srmcons_driver = driver;
|
srmcons_driver = driver;
|
||||||
|
|
|
@ -799,6 +799,7 @@
|
||||||
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
|
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
|
||||||
reg = <0x8006a000 0x2000>;
|
reg = <0x8006a000 0x2000>;
|
||||||
interrupts = <112 70 71>;
|
interrupts = <112 70 71>;
|
||||||
|
fsl,auart-dma-channel = <8 9>;
|
||||||
clocks = <&clks 45>;
|
clocks = <&clks 45>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
|
@ -109,15 +109,6 @@
|
||||||
#define OMAP5UART4 OMAP4UART4
|
#define OMAP5UART4 OMAP4UART4
|
||||||
#define ZOOM_UART 95 /* Only on zoom2/3 */
|
#define ZOOM_UART 95 /* Only on zoom2/3 */
|
||||||
|
|
||||||
/* This is only used by 8250.c for omap1510 */
|
|
||||||
#define is_omap_port(pt) ({int __ret = 0; \
|
|
||||||
if ((pt)->port.mapbase == OMAP1_UART1_BASE || \
|
|
||||||
(pt)->port.mapbase == OMAP1_UART2_BASE || \
|
|
||||||
(pt)->port.mapbase == OMAP1_UART3_BASE) \
|
|
||||||
__ret = 1; \
|
|
||||||
__ret; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
struct omap_board_data;
|
struct omap_board_data;
|
||||||
|
|
|
@ -555,6 +555,7 @@ static int __init simrs_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
err_free_tty:
|
err_free_tty:
|
||||||
put_tty_driver(hp_simserial_driver);
|
put_tty_driver(hp_simserial_driver);
|
||||||
|
tty_port_destroy(&state->port);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,6 @@ static int __init nfcon_init(void)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
tty_port_init(&nfcon_tty_port);
|
|
||||||
|
|
||||||
stderr_id = nf_get_id("NF_STDERR");
|
stderr_id = nf_get_id("NF_STDERR");
|
||||||
if (!stderr_id)
|
if (!stderr_id)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -130,6 +128,8 @@ static int __init nfcon_init(void)
|
||||||
if (!nfcon_tty_driver)
|
if (!nfcon_tty_driver)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
tty_port_init(&nfcon_tty_port);
|
||||||
|
|
||||||
nfcon_tty_driver->driver_name = "nfcon";
|
nfcon_tty_driver->driver_name = "nfcon";
|
||||||
nfcon_tty_driver->name = "nfcon";
|
nfcon_tty_driver->name = "nfcon";
|
||||||
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||||
|
@ -143,6 +143,7 @@ static int __init nfcon_init(void)
|
||||||
if (res) {
|
if (res) {
|
||||||
pr_err("failed to register nfcon tty driver\n");
|
pr_err("failed to register nfcon tty driver\n");
|
||||||
put_tty_driver(nfcon_tty_driver);
|
put_tty_driver(nfcon_tty_driver);
|
||||||
|
tty_port_destroy(&nfcon_tty_port);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ static void __exit nfcon_exit(void)
|
||||||
unregister_console(&nf_console);
|
unregister_console(&nf_console);
|
||||||
tty_unregister_driver(nfcon_tty_driver);
|
tty_unregister_driver(nfcon_tty_driver);
|
||||||
put_tty_driver(nfcon_tty_driver);
|
put_tty_driver(nfcon_tty_driver);
|
||||||
|
tty_port_destroy(&nfcon_tty_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(nfcon_init);
|
module_init(nfcon_init);
|
||||||
|
|
|
@ -86,6 +86,9 @@
|
||||||
#define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */
|
#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */
|
||||||
#define TIOCVHANGUP 0x5437
|
#define TIOCVHANGUP 0x5437
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
/* I hope the range from 0x5480 on is free ... */
|
/* I hope the range from 0x5480 on is free ... */
|
||||||
#define TIOCSCTTY 0x5480 /* become controlling tty */
|
#define TIOCSCTTY 0x5480 /* become controlling tty */
|
||||||
|
|
|
@ -55,6 +55,9 @@
|
||||||
#define TIOCGDEV _IOR('T',0x32, int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T',0x32, int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
||||||
#define TIOCVHANGUP 0x5437
|
#define TIOCVHANGUP 0x5437
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
||||||
#define FIOCLEX 0x5451
|
#define FIOCLEX 0x5451
|
||||||
|
|
|
@ -186,13 +186,13 @@ static int __init pdc_console_tty_driver_init(void)
|
||||||
printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
|
printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
|
||||||
pdc_cons.flags &= ~CON_BOOT;
|
pdc_cons.flags &= ~CON_BOOT;
|
||||||
|
|
||||||
tty_port_init(&tty_port);
|
|
||||||
|
|
||||||
pdc_console_tty_driver = alloc_tty_driver(1);
|
pdc_console_tty_driver = alloc_tty_driver(1);
|
||||||
|
|
||||||
if (!pdc_console_tty_driver)
|
if (!pdc_console_tty_driver)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
tty_port_init(&tty_port);
|
||||||
|
|
||||||
pdc_console_tty_driver->driver_name = "pdc_cons";
|
pdc_console_tty_driver->driver_name = "pdc_cons";
|
||||||
pdc_console_tty_driver->name = "ttyB";
|
pdc_console_tty_driver->name = "ttyB";
|
||||||
pdc_console_tty_driver->major = MUX_MAJOR;
|
pdc_console_tty_driver->major = MUX_MAJOR;
|
||||||
|
@ -207,6 +207,7 @@ static int __init pdc_console_tty_driver_init(void)
|
||||||
err = tty_register_driver(pdc_console_tty_driver);
|
err = tty_register_driver(pdc_console_tty_driver);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
|
printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
|
||||||
|
tty_port_destroy(&tty_port);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,9 @@
|
||||||
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
||||||
#define TIOCVHANGUP 0x5437
|
#define TIOCVHANGUP 0x5437
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
#define TIOCSERCONFIG 0x5453
|
#define TIOCSERCONFIG 0x5453
|
||||||
#define TIOCSERGWILD 0x5454
|
#define TIOCSERGWILD 0x5454
|
||||||
|
|
|
@ -88,6 +88,9 @@
|
||||||
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
||||||
#define TIOCVHANGUP _IO('T', 0x37)
|
#define TIOCVHANGUP _IO('T', 0x37)
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
#define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */
|
#define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */
|
||||||
#define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */
|
#define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#define TCSETSF2 _IOW('T', 15, struct termios2)
|
#define TCSETSF2 _IOW('T', 15, struct termios2)
|
||||||
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCVHANGUP _IO('T', 0x37)
|
#define TIOCVHANGUP _IO('T', 0x37)
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
/* Note that all the ioctls that are not available in Linux have a
|
/* Note that all the ioctls that are not available in Linux have a
|
||||||
* double underscore on the front to: a) avoid some programs to
|
* double underscore on the front to: a) avoid some programs to
|
||||||
|
|
|
@ -83,21 +83,8 @@ static const struct chan_ops not_configged_ops = {
|
||||||
|
|
||||||
static void tty_receive_char(struct tty_struct *tty, char ch)
|
static void tty_receive_char(struct tty_struct *tty, char ch)
|
||||||
{
|
{
|
||||||
if (tty == NULL)
|
if (tty)
|
||||||
return;
|
tty_insert_flip_char(tty, ch, TTY_NORMAL);
|
||||||
|
|
||||||
if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
|
|
||||||
if (ch == STOP_CHAR(tty)) {
|
|
||||||
stop_tty(tty);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (ch == START_CHAR(tty)) {
|
|
||||||
start_tty(tty);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tty_insert_flip_char(tty, ch, TTY_NORMAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_one_chan(struct chan *chan)
|
static int open_one_chan(struct chan *chan)
|
||||||
|
|
|
@ -584,6 +584,8 @@ int register_lines(struct line_driver *line_driver,
|
||||||
printk(KERN_ERR "register_lines : can't register %s driver\n",
|
printk(KERN_ERR "register_lines : can't register %s driver\n",
|
||||||
line_driver->name);
|
line_driver->name);
|
||||||
put_tty_driver(driver);
|
put_tty_driver(driver);
|
||||||
|
for (i = 0; i < nlines; i++)
|
||||||
|
tty_port_destroy(&lines[i].port);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,11 @@ static void ce4100_serial_fixup(int port, struct uart_port *up,
|
||||||
up->membase =
|
up->membase =
|
||||||
(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
|
(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
|
||||||
up->membase += up->mapbase & ~PAGE_MASK;
|
up->membase += up->mapbase & ~PAGE_MASK;
|
||||||
|
up->mapbase += port * 0x100;
|
||||||
|
up->membase += port * 0x100;
|
||||||
up->iotype = UPIO_MEM32;
|
up->iotype = UPIO_MEM32;
|
||||||
up->regshift = 2;
|
up->regshift = 2;
|
||||||
|
up->irq = 4;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
up->iobase = 0;
|
up->iobase = 0;
|
||||||
|
|
|
@ -101,6 +101,9 @@
|
||||||
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
|
||||||
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
|
||||||
#define TIOCVHANGUP _IO('T', 0x37)
|
#define TIOCVHANGUP _IO('T', 0x37)
|
||||||
|
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
|
||||||
|
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
|
||||||
|
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
|
||||||
|
|
||||||
#define TIOCSERCONFIG _IO('T', 83)
|
#define TIOCSERCONFIG _IO('T', 83)
|
||||||
#define TIOCSERGWILD _IOR('T', 84, int)
|
#define TIOCSERGWILD _IOR('T', 84, int)
|
||||||
|
|
|
@ -221,6 +221,7 @@ static __exit void rs_exit(void)
|
||||||
printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
|
printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
|
||||||
error);
|
error);
|
||||||
put_tty_driver(serial_driver);
|
put_tty_driver(serial_driver);
|
||||||
|
tty_port_destroy(&serial_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -270,15 +270,10 @@ static int hci_uart_send_frame(struct sk_buff *skb)
|
||||||
*/
|
*/
|
||||||
static int hci_uart_tty_open(struct tty_struct *tty)
|
static int hci_uart_tty_open(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
struct hci_uart *hu = (void *) tty->disc_data;
|
struct hci_uart *hu;
|
||||||
|
|
||||||
BT_DBG("tty %p", tty);
|
BT_DBG("tty %p", tty);
|
||||||
|
|
||||||
/* FIXME: This btw is bogus, nothing requires the old ldisc to clear
|
|
||||||
the pointer */
|
|
||||||
if (hu)
|
|
||||||
return -EEXIST;
|
|
||||||
|
|
||||||
/* Error if the tty has no write op instead of leaving an exploitable
|
/* Error if the tty has no write op instead of leaving an exploitable
|
||||||
hole */
|
hole */
|
||||||
if (tty->ops->write == NULL)
|
if (tty->ops->write == NULL)
|
||||||
|
|
|
@ -549,8 +549,10 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
||||||
/* Initialize the struct pcmcia_device structure */
|
/* Initialize the struct pcmcia_device structure */
|
||||||
|
|
||||||
ret = mgslpc_config(link);
|
ret = mgslpc_config(link);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
tty_port_destroy(&info->port);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
mgslpc_add_device(info);
|
mgslpc_add_device(info);
|
||||||
|
|
||||||
|
@ -2757,6 +2759,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info)
|
||||||
hdlcdev_exit(info);
|
hdlcdev_exit(info);
|
||||||
#endif
|
#endif
|
||||||
release_resources(info);
|
release_resources(info);
|
||||||
|
tty_port_destroy(&info->port);
|
||||||
kfree(info);
|
kfree(info);
|
||||||
mgslpc_device_count--;
|
mgslpc_device_count--;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -179,7 +179,6 @@ static int __init ttyprintk_init(void)
|
||||||
{
|
{
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
tty_port_init(&tpk_port.port);
|
|
||||||
tpk_port.port.ops = &null_ops;
|
tpk_port.port.ops = &null_ops;
|
||||||
mutex_init(&tpk_port.port_write_mutex);
|
mutex_init(&tpk_port.port_write_mutex);
|
||||||
|
|
||||||
|
@ -190,6 +189,8 @@ static int __init ttyprintk_init(void)
|
||||||
if (IS_ERR(ttyprintk_driver))
|
if (IS_ERR(ttyprintk_driver))
|
||||||
return PTR_ERR(ttyprintk_driver);
|
return PTR_ERR(ttyprintk_driver);
|
||||||
|
|
||||||
|
tty_port_init(&tpk_port.port);
|
||||||
|
|
||||||
ttyprintk_driver->driver_name = "ttyprintk";
|
ttyprintk_driver->driver_name = "ttyprintk";
|
||||||
ttyprintk_driver->name = "ttyprintk";
|
ttyprintk_driver->name = "ttyprintk";
|
||||||
ttyprintk_driver->major = TTYAUX_MAJOR;
|
ttyprintk_driver->major = TTYAUX_MAJOR;
|
||||||
|
@ -211,6 +212,7 @@ static int __init ttyprintk_init(void)
|
||||||
error:
|
error:
|
||||||
tty_unregister_driver(ttyprintk_driver);
|
tty_unregister_driver(ttyprintk_driver);
|
||||||
put_tty_driver(ttyprintk_driver);
|
put_tty_driver(ttyprintk_driver);
|
||||||
|
tty_port_destroy(&tpk_port.port);
|
||||||
ttyprintk_driver = NULL;
|
ttyprintk_driver = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,6 +415,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
|
||||||
tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL);
|
tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL);
|
||||||
if (IS_ERR(tty_dev)) {
|
if (IS_ERR(tty_dev)) {
|
||||||
dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
|
dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
|
||||||
|
tty_port_destroy(&channel->tty_port);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dev_set_drvdata(tty_dev, channel);
|
dev_set_drvdata(tty_dev, channel);
|
||||||
|
@ -700,6 +701,7 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
|
||||||
struct ipoctal_channel *channel = &ipoctal->channel[i];
|
struct ipoctal_channel *channel = &ipoctal->channel[i];
|
||||||
tty_unregister_device(ipoctal->tty_drv, i);
|
tty_unregister_device(ipoctal->tty_drv, i);
|
||||||
tty_port_free_xmit_buf(&channel->tty_port);
|
tty_port_free_xmit_buf(&channel->tty_port);
|
||||||
|
tty_port_destroy(&channel->tty_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
tty_unregister_driver(ipoctal->tty_drv);
|
tty_unregister_driver(ipoctal->tty_drv);
|
||||||
|
|
|
@ -77,8 +77,6 @@ struct ackqueue_entry {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct capiminor {
|
struct capiminor {
|
||||||
struct kref kref;
|
|
||||||
|
|
||||||
unsigned int minor;
|
unsigned int minor;
|
||||||
|
|
||||||
struct capi20_appl *ap;
|
struct capi20_appl *ap;
|
||||||
|
@ -190,7 +188,20 @@ static void capiminor_del_all_ack(struct capiminor *mp)
|
||||||
|
|
||||||
/* -------- struct capiminor ---------------------------------------- */
|
/* -------- struct capiminor ---------------------------------------- */
|
||||||
|
|
||||||
static const struct tty_port_operations capiminor_port_ops; /* we have none */
|
static void capiminor_destroy(struct tty_port *port)
|
||||||
|
{
|
||||||
|
struct capiminor *mp = container_of(port, struct capiminor, port);
|
||||||
|
|
||||||
|
kfree_skb(mp->outskb);
|
||||||
|
skb_queue_purge(&mp->inqueue);
|
||||||
|
skb_queue_purge(&mp->outqueue);
|
||||||
|
capiminor_del_all_ack(mp);
|
||||||
|
kfree(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct tty_port_operations capiminor_port_ops = {
|
||||||
|
.destruct = capiminor_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
|
static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
|
||||||
{
|
{
|
||||||
|
@ -204,8 +215,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
kref_init(&mp->kref);
|
|
||||||
|
|
||||||
mp->ap = ap;
|
mp->ap = ap;
|
||||||
mp->ncci = ncci;
|
mp->ncci = ncci;
|
||||||
INIT_LIST_HEAD(&mp->ackqueue);
|
INIT_LIST_HEAD(&mp->ackqueue);
|
||||||
|
@ -247,21 +256,10 @@ err_out2:
|
||||||
spin_unlock(&capiminors_lock);
|
spin_unlock(&capiminors_lock);
|
||||||
|
|
||||||
err_out1:
|
err_out1:
|
||||||
kfree(mp);
|
tty_port_put(&mp->port);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capiminor_destroy(struct kref *kref)
|
|
||||||
{
|
|
||||||
struct capiminor *mp = container_of(kref, struct capiminor, kref);
|
|
||||||
|
|
||||||
kfree_skb(mp->outskb);
|
|
||||||
skb_queue_purge(&mp->inqueue);
|
|
||||||
skb_queue_purge(&mp->outqueue);
|
|
||||||
capiminor_del_all_ack(mp);
|
|
||||||
kfree(mp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct capiminor *capiminor_get(unsigned int minor)
|
static struct capiminor *capiminor_get(unsigned int minor)
|
||||||
{
|
{
|
||||||
struct capiminor *mp;
|
struct capiminor *mp;
|
||||||
|
@ -269,7 +267,7 @@ static struct capiminor *capiminor_get(unsigned int minor)
|
||||||
spin_lock(&capiminors_lock);
|
spin_lock(&capiminors_lock);
|
||||||
mp = capiminors[minor];
|
mp = capiminors[minor];
|
||||||
if (mp)
|
if (mp)
|
||||||
kref_get(&mp->kref);
|
tty_port_get(&mp->port);
|
||||||
spin_unlock(&capiminors_lock);
|
spin_unlock(&capiminors_lock);
|
||||||
|
|
||||||
return mp;
|
return mp;
|
||||||
|
@ -277,7 +275,7 @@ static struct capiminor *capiminor_get(unsigned int minor)
|
||||||
|
|
||||||
static inline void capiminor_put(struct capiminor *mp)
|
static inline void capiminor_put(struct capiminor *mp)
|
||||||
{
|
{
|
||||||
kref_put(&mp->kref, capiminor_destroy);
|
tty_port_put(&mp->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capiminor_free(struct capiminor *mp)
|
static void capiminor_free(struct capiminor *mp)
|
||||||
|
|
|
@ -507,6 +507,7 @@ void gigaset_freecs(struct cardstate *cs)
|
||||||
gig_dbg(DEBUG_INIT, "clearing at_state");
|
gig_dbg(DEBUG_INIT, "clearing at_state");
|
||||||
clear_at_state(&cs->at_state);
|
clear_at_state(&cs->at_state);
|
||||||
dealloc_temp_at_states(cs);
|
dealloc_temp_at_states(cs);
|
||||||
|
tty_port_destroy(&cs->port);
|
||||||
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 0: /* error in basic setup */
|
case 0: /* error in basic setup */
|
||||||
|
|
|
@ -1849,6 +1849,8 @@ err_unregister:
|
||||||
kfree(info->fax);
|
kfree(info->fax);
|
||||||
#endif
|
#endif
|
||||||
kfree(info->port.xmit_buf - 4);
|
kfree(info->port.xmit_buf - 4);
|
||||||
|
info->port.xmit_buf = NULL;
|
||||||
|
tty_port_destroy(&info->port);
|
||||||
}
|
}
|
||||||
tty_unregister_driver(m->tty_modem);
|
tty_unregister_driver(m->tty_modem);
|
||||||
err:
|
err:
|
||||||
|
@ -1870,6 +1872,8 @@ isdn_tty_exit(void)
|
||||||
kfree(info->fax);
|
kfree(info->fax);
|
||||||
#endif
|
#endif
|
||||||
kfree(info->port.xmit_buf - 4);
|
kfree(info->port.xmit_buf - 4);
|
||||||
|
info->port.xmit_buf = NULL;
|
||||||
|
tty_port_destroy(&info->port);
|
||||||
}
|
}
|
||||||
tty_unregister_driver(dev->mdm.tty_modem);
|
tty_unregister_driver(dev->mdm.tty_modem);
|
||||||
put_tty_driver(dev->mdm.tty_modem);
|
put_tty_driver(dev->mdm.tty_modem);
|
||||||
|
|
|
@ -882,11 +882,14 @@ err:
|
||||||
static void pti_pci_remove(struct pci_dev *pdev)
|
static void pti_pci_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct pti_dev *drv_data = pci_get_drvdata(pdev);
|
struct pti_dev *drv_data = pci_get_drvdata(pdev);
|
||||||
|
unsigned int a;
|
||||||
|
|
||||||
unregister_console(&pti_console);
|
unregister_console(&pti_console);
|
||||||
|
|
||||||
tty_unregister_device(pti_tty_driver, 0);
|
for (a = 0; a < PTITTY_MINOR_NUM; a++) {
|
||||||
tty_unregister_device(pti_tty_driver, 1);
|
tty_unregister_device(pti_tty_driver, a);
|
||||||
|
tty_port_destroy(&drv_data->port[a]);
|
||||||
|
}
|
||||||
|
|
||||||
iounmap(drv_data->pti_ioaddr);
|
iounmap(drv_data->pti_ioaddr);
|
||||||
pci_set_drvdata(pdev, NULL);
|
pci_set_drvdata(pdev, NULL);
|
||||||
|
|
|
@ -66,8 +66,6 @@ struct uart_icount {
|
||||||
|
|
||||||
struct sdio_uart_port {
|
struct sdio_uart_port {
|
||||||
struct tty_port port;
|
struct tty_port port;
|
||||||
struct kref kref;
|
|
||||||
struct tty_struct *tty;
|
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
struct sdio_func *func;
|
struct sdio_func *func;
|
||||||
struct mutex func_lock;
|
struct mutex func_lock;
|
||||||
|
@ -93,7 +91,6 @@ static int sdio_uart_add_port(struct sdio_uart_port *port)
|
||||||
{
|
{
|
||||||
int index, ret = -EBUSY;
|
int index, ret = -EBUSY;
|
||||||
|
|
||||||
kref_init(&port->kref);
|
|
||||||
mutex_init(&port->func_lock);
|
mutex_init(&port->func_lock);
|
||||||
spin_lock_init(&port->write_lock);
|
spin_lock_init(&port->write_lock);
|
||||||
if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
|
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)
|
||||||
spin_lock(&sdio_uart_table_lock);
|
spin_lock(&sdio_uart_table_lock);
|
||||||
port = sdio_uart_table[index];
|
port = sdio_uart_table[index];
|
||||||
if (port)
|
if (port)
|
||||||
kref_get(&port->kref);
|
tty_port_get(&port->port);
|
||||||
spin_unlock(&sdio_uart_table_lock);
|
spin_unlock(&sdio_uart_table_lock);
|
||||||
|
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdio_uart_port_destroy(struct kref *kref)
|
|
||||||
{
|
|
||||||
struct sdio_uart_port *port =
|
|
||||||
container_of(kref, struct sdio_uart_port, kref);
|
|
||||||
kfifo_free(&port->xmit_fifo);
|
|
||||||
kfree(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sdio_uart_port_put(struct sdio_uart_port *port)
|
static void sdio_uart_port_put(struct sdio_uart_port *port)
|
||||||
{
|
{
|
||||||
kref_put(&port->kref, sdio_uart_port_destroy);
|
tty_port_put(&port->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdio_uart_port_remove(struct sdio_uart_port *port)
|
static void sdio_uart_port_remove(struct sdio_uart_port *port)
|
||||||
|
@ -737,6 +726,14 @@ static void sdio_uart_shutdown(struct tty_port *tport)
|
||||||
sdio_uart_release_func(port);
|
sdio_uart_release_func(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sdio_uart_port_destroy(struct tty_port *tport)
|
||||||
|
{
|
||||||
|
struct sdio_uart_port *port =
|
||||||
|
container_of(tport, struct sdio_uart_port, port);
|
||||||
|
kfifo_free(&port->xmit_fifo);
|
||||||
|
kfree(port);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sdio_uart_install - install method
|
* sdio_uart_install - install method
|
||||||
* @driver: the driver in use (sdio_uart in our case)
|
* @driver: the driver in use (sdio_uart in our case)
|
||||||
|
@ -1045,6 +1042,7 @@ static const struct tty_port_operations sdio_uart_port_ops = {
|
||||||
.carrier_raised = uart_carrier_raised,
|
.carrier_raised = uart_carrier_raised,
|
||||||
.shutdown = sdio_uart_shutdown,
|
.shutdown = sdio_uart_shutdown,
|
||||||
.activate = sdio_uart_activate,
|
.activate = sdio_uart_activate,
|
||||||
|
.destruct = sdio_uart_port_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct tty_operations sdio_uart_ops = {
|
static const struct tty_operations sdio_uart_ops = {
|
||||||
|
|
|
@ -2274,6 +2274,7 @@ static void hso_serial_common_free(struct hso_serial *serial)
|
||||||
/* unlink and free TX URB */
|
/* unlink and free TX URB */
|
||||||
usb_free_urb(serial->tx_urb);
|
usb_free_urb(serial->tx_urb);
|
||||||
kfree(serial->tx_data);
|
kfree(serial->tx_data);
|
||||||
|
tty_port_destroy(&serial->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
|
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,
|
||||||
int minor;
|
int minor;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
tty_port_init(&serial->port);
|
||||||
|
|
||||||
minor = get_free_serial_index();
|
minor = get_free_serial_index();
|
||||||
if (minor < 0)
|
if (minor < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
tty_port_init(&serial->port);
|
|
||||||
|
|
||||||
/* register our minor number */
|
/* register our minor number */
|
||||||
serial->parent->dev = tty_port_register_device(&serial->port, tty_drv,
|
serial->parent->dev = tty_port_register_device(&serial->port, tty_drv,
|
||||||
minor, &serial->parent->interface->dev);
|
minor, &serial->parent->interface->dev);
|
||||||
|
|
|
@ -677,6 +677,7 @@ static void raw3215_free_info(struct raw3215_info *raw)
|
||||||
{
|
{
|
||||||
kfree(raw->inbuf);
|
kfree(raw->inbuf);
|
||||||
kfree(raw->buffer);
|
kfree(raw->buffer);
|
||||||
|
tty_port_destroy(&raw->port);
|
||||||
kfree(raw);
|
kfree(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,7 +547,6 @@ sclp_tty_init(void)
|
||||||
sclp_tty_tolower = 1;
|
sclp_tty_tolower = 1;
|
||||||
}
|
}
|
||||||
sclp_tty_chars_count = 0;
|
sclp_tty_chars_count = 0;
|
||||||
tty_port_init(&sclp_port);
|
|
||||||
|
|
||||||
rc = sclp_register(&sclp_input_event);
|
rc = sclp_register(&sclp_input_event);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -555,6 +554,8 @@ sclp_tty_init(void)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tty_port_init(&sclp_port);
|
||||||
|
|
||||||
driver->driver_name = "sclp_line";
|
driver->driver_name = "sclp_line";
|
||||||
driver->name = "sclp_line";
|
driver->name = "sclp_line";
|
||||||
driver->major = TTY_MAJOR;
|
driver->major = TTY_MAJOR;
|
||||||
|
@ -571,6 +572,7 @@ sclp_tty_init(void)
|
||||||
rc = tty_register_driver(driver);
|
rc = tty_register_driver(driver);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
put_tty_driver(driver);
|
put_tty_driver(driver);
|
||||||
|
tty_port_destroy(&sclp_port);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
sclp_tty_driver = driver;
|
sclp_tty_driver = driver;
|
||||||
|
|
|
@ -615,6 +615,7 @@ static void __init __sclp_vt220_cleanup(void)
|
||||||
return;
|
return;
|
||||||
sclp_unregister(&sclp_vt220_register);
|
sclp_unregister(&sclp_vt220_register);
|
||||||
__sclp_vt220_free_pages();
|
__sclp_vt220_free_pages();
|
||||||
|
tty_port_destroy(&sclp_vt220_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate buffer pages and register with sclp core. Controlled by init
|
/* Allocate buffer pages and register with sclp core. Controlled by init
|
||||||
|
@ -650,6 +651,7 @@ out:
|
||||||
if (rc) {
|
if (rc) {
|
||||||
__sclp_vt220_free_pages();
|
__sclp_vt220_free_pages();
|
||||||
sclp_vt220_init_count--;
|
sclp_vt220_init_count--;
|
||||||
|
tty_port_destroy(&sclp_vt220_port);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -722,6 +722,7 @@ out_pages:
|
||||||
while (pages--)
|
while (pages--)
|
||||||
free_pages((unsigned long) tp->freemem_pages[pages], 0);
|
free_pages((unsigned long) tp->freemem_pages[pages], 0);
|
||||||
kfree(tp->freemem_pages);
|
kfree(tp->freemem_pages);
|
||||||
|
tty_port_destroy(&tp->port);
|
||||||
out_tp:
|
out_tp:
|
||||||
kfree(tp);
|
kfree(tp);
|
||||||
out_err:
|
out_err:
|
||||||
|
@ -744,6 +745,7 @@ tty3270_free_view(struct tty3270 *tp)
|
||||||
for (pages = 0; pages < TTY3270_STRING_PAGES; pages++)
|
for (pages = 0; pages < TTY3270_STRING_PAGES; pages++)
|
||||||
free_pages((unsigned long) tp->freemem_pages[pages], 0);
|
free_pages((unsigned long) tp->freemem_pages[pages], 0);
|
||||||
kfree(tp->freemem_pages);
|
kfree(tp->freemem_pages);
|
||||||
|
tty_port_destroy(&tp->port);
|
||||||
kfree(tp);
|
kfree(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ source "drivers/staging/imx-drm/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/dgrp/Kconfig"
|
source "drivers/staging/dgrp/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/staging/sb105x/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/fwserial/Kconfig"
|
source "drivers/staging/fwserial/Kconfig"
|
||||||
|
|
||||||
endif # STAGING
|
endif # STAGING
|
||||||
|
|
|
@ -61,4 +61,5 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
|
||||||
obj-$(CONFIG_CED1401) += ced1401/
|
obj-$(CONFIG_CED1401) += ced1401/
|
||||||
obj-$(CONFIG_DRM_IMX) += imx-drm/
|
obj-$(CONFIG_DRM_IMX) += imx-drm/
|
||||||
obj-$(CONFIG_DGRP) += dgrp/
|
obj-$(CONFIG_DGRP) += dgrp/
|
||||||
|
obj-$(CONFIG_SB105X) += sb105x/
|
||||||
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
|
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
|
||||||
|
|
|
@ -1140,8 +1140,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count)
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
fail:
|
fail:
|
||||||
while (count--)
|
while (count--) {
|
||||||
|
tty_port_destroy(&ports[count].port->port);
|
||||||
kfree(ports[count].port);
|
kfree(ports[count].port);
|
||||||
|
}
|
||||||
put_tty_driver(gs_tty_driver);
|
put_tty_driver(gs_tty_driver);
|
||||||
gs_tty_driver = NULL;
|
gs_tty_driver = NULL;
|
||||||
return status;
|
return status;
|
||||||
|
@ -1195,6 +1197,7 @@ void gserial_cleanup(void)
|
||||||
|
|
||||||
WARN_ON(port->port_usb != NULL);
|
WARN_ON(port->port_usb != NULL);
|
||||||
|
|
||||||
|
tty_port_destroy(&port->port);
|
||||||
kfree(port);
|
kfree(port);
|
||||||
}
|
}
|
||||||
n_ports = 0;
|
n_ports = 0;
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
* All global storage allocation.
|
* All global storage allocation.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
extern int dgrp_rawreadok; /* Allow raw writing of input */
|
|
||||||
extern int dgrp_register_cudevices; /* enable legacy cu devices */
|
extern int dgrp_register_cudevices; /* enable legacy cu devices */
|
||||||
extern int dgrp_register_prdevices; /* enable transparent print devices */
|
extern int dgrp_register_prdevices; /* enable transparent print devices */
|
||||||
extern int dgrp_poll_tick; /* Poll interval - in ms */
|
extern int dgrp_poll_tick; /* Poll interval - in ms */
|
||||||
|
|
|
@ -39,14 +39,10 @@ MODULE_VERSION(DIGI_VERSION);
|
||||||
struct list_head nd_struct_list;
|
struct list_head nd_struct_list;
|
||||||
struct dgrp_poll_data dgrp_poll_data;
|
struct dgrp_poll_data dgrp_poll_data;
|
||||||
|
|
||||||
int dgrp_rawreadok = 1; /* Bypass flipbuf on input */
|
|
||||||
int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */
|
int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */
|
||||||
int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */
|
int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */
|
||||||
int dgrp_poll_tick = 20; /* Poll interval - in ms */
|
int dgrp_poll_tick = 20; /* Poll interval - in ms */
|
||||||
|
|
||||||
module_param_named(rawreadok, dgrp_rawreadok, int, 0644);
|
|
||||||
MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input");
|
|
||||||
|
|
||||||
module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644);
|
module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644);
|
||||||
MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices");
|
MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices");
|
||||||
|
|
||||||
|
|
|
@ -151,20 +151,15 @@ static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf,
|
||||||
* Copys the rbuf to the flipbuf and sends to line discipline.
|
* Copys the rbuf to the flipbuf and sends to line discipline.
|
||||||
* Sends input buffer data to the line discipline.
|
* Sends input buffer data to the line discipline.
|
||||||
*
|
*
|
||||||
* There are several modes to consider here:
|
|
||||||
* rawreadok, tty->real_raw, and IF_PARMRK
|
|
||||||
*/
|
*/
|
||||||
static void dgrp_input(struct ch_struct *ch)
|
static void dgrp_input(struct ch_struct *ch)
|
||||||
{
|
{
|
||||||
struct nd_struct *nd;
|
struct nd_struct *nd;
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
int remain;
|
|
||||||
int data_len;
|
int data_len;
|
||||||
int len;
|
int len;
|
||||||
int flip_len;
|
|
||||||
int tty_count;
|
int tty_count;
|
||||||
ulong lock_flags;
|
ulong lock_flags;
|
||||||
struct tty_ldisc *ld;
|
|
||||||
u8 *myflipbuf;
|
u8 *myflipbuf;
|
||||||
u8 *myflipflagbuf;
|
u8 *myflipflagbuf;
|
||||||
|
|
||||||
|
@ -212,37 +207,11 @@ static void dgrp_input(struct ch_struct *ch)
|
||||||
|
|
||||||
spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
|
spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
|
||||||
|
|
||||||
/* Decide how much data we can send into the tty layer */
|
|
||||||
if (dgrp_rawreadok && tty->real_raw)
|
|
||||||
flip_len = MYFLIPLEN;
|
|
||||||
else
|
|
||||||
flip_len = TTY_FLIPBUF_SIZE;
|
|
||||||
|
|
||||||
/* data_len should be the number of chars that we read in */
|
/* data_len should be the number of chars that we read in */
|
||||||
data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;
|
data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;
|
||||||
remain = data_len;
|
|
||||||
|
|
||||||
/* len is the amount of data we are going to transfer here */
|
/* len is the amount of data we are going to transfer here */
|
||||||
len = min(data_len, flip_len);
|
len = tty_buffer_request_room(tty, data_len);
|
||||||
|
|
||||||
/* take into consideration length of ldisc */
|
|
||||||
len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt);
|
|
||||||
|
|
||||||
ld = tty_ldisc_ref(tty);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we were unable to get a reference to the ld,
|
|
||||||
* don't flush our buffer, and act like the ld doesn't
|
|
||||||
* have any space to put the data right now.
|
|
||||||
*/
|
|
||||||
if (!ld) {
|
|
||||||
len = 0;
|
|
||||||
} else if (!ld->ops->receive_buf) {
|
|
||||||
spin_lock_irqsave(&nd->nd_lock, lock_flags);
|
|
||||||
ch->ch_rout = ch->ch_rin;
|
|
||||||
spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check DPA flow control */
|
/* Check DPA flow control */
|
||||||
if ((nd->nd_dpa_debug) &&
|
if ((nd->nd_dpa_debug) &&
|
||||||
|
@ -254,42 +223,22 @@ static void dgrp_input(struct ch_struct *ch)
|
||||||
|
|
||||||
dgrp_read_data_block(ch, myflipbuf, len);
|
dgrp_read_data_block(ch, myflipbuf, len);
|
||||||
|
|
||||||
/*
|
if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
|
||||||
* In high performance mode, we don't have to update
|
parity_scan(ch, myflipbuf, myflipflagbuf, &len);
|
||||||
* flag_buf or any of the counts or pointers into flip buf.
|
else
|
||||||
*/
|
memset(myflipflagbuf, TTY_NORMAL, len);
|
||||||
if (!dgrp_rawreadok || !tty->real_raw) {
|
|
||||||
if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
|
|
||||||
parity_scan(ch, myflipbuf, myflipflagbuf, &len);
|
|
||||||
else
|
|
||||||
memset(myflipflagbuf, TTY_NORMAL, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((nd->nd_dpa_debug) &&
|
if ((nd->nd_dpa_debug) &&
|
||||||
(nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
|
(nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
|
||||||
dgrp_dpa_data(nd, 1, myflipbuf, len);
|
dgrp_dpa_data(nd, 1, myflipbuf, len);
|
||||||
|
|
||||||
/*
|
tty_insert_flip_string_flags(tty, myflipbuf,
|
||||||
* If we're doing raw reads, jam it right into the
|
myflipflagbuf, len);
|
||||||
* line disc bypassing the flip buffers.
|
tty_flip_buffer_push(tty);
|
||||||
*/
|
|
||||||
if (dgrp_rawreadok && tty->real_raw)
|
|
||||||
ld->ops->receive_buf(tty, myflipbuf, NULL, len);
|
|
||||||
else {
|
|
||||||
len = tty_buffer_request_room(tty, len);
|
|
||||||
tty_insert_flip_string_flags(tty, myflipbuf,
|
|
||||||
myflipflagbuf, len);
|
|
||||||
|
|
||||||
/* Tell the tty layer its okay to "eat" the data now */
|
|
||||||
tty_flip_buffer_push(tty);
|
|
||||||
}
|
|
||||||
|
|
||||||
ch->ch_rxcount += len;
|
ch->ch_rxcount += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ld)
|
|
||||||
tty_ldisc_deref(ld);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wake up any sleepers (maybe dgrp close) that might be waiting
|
* Wake up any sleepers (maybe dgrp close) that might be waiting
|
||||||
* for a channel flag state change.
|
* for a channel flag state change.
|
||||||
|
@ -2549,7 +2498,7 @@ data:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fabricate and insert a data packet header to
|
* Fabricate and insert a data packet header to
|
||||||
* preceed the remaining data when it comes in.
|
* preced the remaining data when it comes in.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (remain < plen) {
|
if (remain < plen) {
|
||||||
|
@ -2718,7 +2667,7 @@ data:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle delayed response arrival preceeding
|
* Handle delayed response arrival preceding
|
||||||
* the open response we are waiting for.
|
* the open response we are waiting for.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3556,7 +3505,7 @@ void dgrp_poll_handler(unsigned long arg)
|
||||||
/*
|
/*
|
||||||
* Decrement statistics. These are only for use with
|
* Decrement statistics. These are only for use with
|
||||||
* KME, so don't worry that the operations are done
|
* KME, so don't worry that the operations are done
|
||||||
* unlocked, and so the results are occassionally wrong.
|
* unlocked, and so the results are occasionally wrong.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nd->nd_read_count -= (nd->nd_read_count +
|
nd->nd_read_count -= (nd->nd_read_count +
|
||||||
|
|
|
@ -629,8 +629,6 @@ static int info_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
seq_printf(m, "version: %s\n", DIGI_VERSION);
|
seq_printf(m, "version: %s\n", DIGI_VERSION);
|
||||||
seq_puts(m, "register_with_sysfs: 1\n");
|
seq_puts(m, "register_with_sysfs: 1\n");
|
||||||
seq_printf(m, "rawreadok: 0x%08x\t(%d)\n",
|
|
||||||
dgrp_rawreadok, dgrp_rawreadok);
|
|
||||||
seq_printf(m, "pollrate: 0x%08x\t(%d)\n",
|
seq_printf(m, "pollrate: 0x%08x\t(%d)\n",
|
||||||
dgrp_poll_tick, dgrp_poll_tick);
|
dgrp_poll_tick, dgrp_poll_tick);
|
||||||
|
|
||||||
|
@ -754,6 +752,8 @@ static int dgrp_add_id(long id)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* FIXME this guy should free the tty driver stored in nd and destroy
|
||||||
|
* all channel ports */
|
||||||
error_out:
|
error_out:
|
||||||
kfree(nd);
|
kfree(nd);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -54,23 +54,6 @@ static DEVICE_ATTR(register_with_sysfs, 0400,
|
||||||
dgrp_class_register_with_sysfs_show, NULL);
|
dgrp_class_register_with_sysfs_show, NULL);
|
||||||
|
|
||||||
|
|
||||||
static ssize_t dgrp_class_rawreadok_show(struct device *c,
|
|
||||||
struct device_attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok);
|
|
||||||
}
|
|
||||||
static ssize_t dgrp_class_rawreadok_store(struct device *c,
|
|
||||||
struct device_attribute *attr,
|
|
||||||
const char *buf, size_t count)
|
|
||||||
{
|
|
||||||
sscanf(buf, "0x%x\n", &dgrp_rawreadok);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show,
|
|
||||||
dgrp_class_rawreadok_store);
|
|
||||||
|
|
||||||
|
|
||||||
static ssize_t dgrp_class_pollrate_show(struct device *c,
|
static ssize_t dgrp_class_pollrate_show(struct device *c,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
|
@ -90,7 +73,6 @@ static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
|
||||||
|
|
||||||
static struct attribute *dgrp_sysfs_global_settings_entries[] = {
|
static struct attribute *dgrp_sysfs_global_settings_entries[] = {
|
||||||
&dev_attr_pollrate.attr,
|
&dev_attr_pollrate.attr,
|
||||||
&dev_attr_rawreadok.attr,
|
|
||||||
&dev_attr_register_with_sysfs.attr,
|
&dev_attr_register_with_sysfs.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -432,7 +432,7 @@ static void drp_param(struct ch_struct *ch)
|
||||||
/*
|
/*
|
||||||
* From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE}
|
* From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE}
|
||||||
* is defined for the terminal device file, and the value
|
* is defined for the terminal device file, and the value
|
||||||
* of one of the changable special control characters (see
|
* of one of the changeable special control characters (see
|
||||||
* 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be
|
* 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be
|
||||||
* disabled, that is, no input data shall be recognized as
|
* disabled, that is, no input data shall be recognized as
|
||||||
* the disabled special character."
|
* the disabled special character."
|
||||||
|
@ -2265,9 +2265,7 @@ static int get_modem_info(struct ch_struct *ch, unsigned int *value)
|
||||||
| ((mlast & DM_RI) ? TIOCM_RNG : 0)
|
| ((mlast & DM_RI) ? TIOCM_RNG : 0)
|
||||||
| ((mlast & DM_DSR) ? TIOCM_DSR : 0)
|
| ((mlast & DM_DSR) ? TIOCM_DSR : 0)
|
||||||
| ((mlast & DM_CTS) ? TIOCM_CTS : 0);
|
| ((mlast & DM_CTS) ? TIOCM_CTS : 0);
|
||||||
put_user(mlast, (unsigned int __user *) value);
|
return put_user(mlast, (unsigned int __user *) value);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2285,7 +2283,8 @@ static int set_modem_info(struct ch_struct *ch, unsigned int command,
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
get_user(arg, (unsigned int __user *) value);
|
if (get_user(arg, (unsigned int __user *) value))
|
||||||
|
return -EFAULT;
|
||||||
mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
|
mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
|
||||||
| ((arg & TIOCM_DTR) ? DM_DTR : 0);
|
| ((arg & TIOCM_DTR) ? DM_DTR : 0);
|
||||||
|
|
||||||
|
@ -2684,7 +2683,7 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
|
||||||
- looking at the tty_ioctl code, these command all call our
|
- looking at the tty_ioctl code, these command all call our
|
||||||
tty_set_termios at the driver's end, when a TCSETA* is sent,
|
tty_set_termios at the driver's end, when a TCSETA* is sent,
|
||||||
it is expecting the tty to have a termio structure,
|
it is expecting the tty to have a termio structure,
|
||||||
NOT a termios stucture. These two structures differ in size
|
NOT a termios structure. These two structures differ in size
|
||||||
and the tty_ioctl code does a conversion before processing them both.
|
and the tty_ioctl code does a conversion before processing them both.
|
||||||
- we should treat the TCSETAW TCSETAF ioctls the same, and let
|
- we should treat the TCSETAW TCSETAF ioctls the same, and let
|
||||||
the tty_ioctl code do the conversion stuff.
|
the tty_ioctl code do the conversion stuff.
|
||||||
|
@ -2836,17 +2835,16 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIGI_GETCUSTOMBAUD:
|
case DIGI_GETCUSTOMBAUD:
|
||||||
rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int));
|
if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg))
|
||||||
if (rc == 0)
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIGI_SETCUSTOMBAUD:
|
case DIGI_SETCUSTOMBAUD:
|
||||||
{
|
{
|
||||||
int new_rate;
|
int new_rate;
|
||||||
|
|
||||||
get_user(new_rate, (unsigned int __user *) arg);
|
if (get_user(new_rate, (unsigned int __user *) arg))
|
||||||
|
return -EFAULT;
|
||||||
dgrp_set_custom_speed(ch, new_rate);
|
dgrp_set_custom_speed(ch, new_rate);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -2981,7 +2979,7 @@ static void dgrp_tty_start(struct tty_struct *tty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stop the reciever
|
* Stop the receiver
|
||||||
*/
|
*/
|
||||||
static void dgrp_tty_input_stop(struct tty_struct *tty)
|
static void dgrp_tty_input_stop(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
|
@ -3104,6 +3102,7 @@ static void dgrp_tty_hangup(struct tty_struct *tty)
|
||||||
void
|
void
|
||||||
dgrp_tty_uninit(struct nd_struct *nd)
|
dgrp_tty_uninit(struct nd_struct *nd)
|
||||||
{
|
{
|
||||||
|
unsigned int i;
|
||||||
char id[3];
|
char id[3];
|
||||||
|
|
||||||
ID_TO_CHAR(nd->nd_ID, id);
|
ID_TO_CHAR(nd->nd_ID, id);
|
||||||
|
@ -3137,6 +3136,8 @@ dgrp_tty_uninit(struct nd_struct *nd)
|
||||||
put_tty_driver(nd->nd_xprint_ttdriver);
|
put_tty_driver(nd->nd_xprint_ttdriver);
|
||||||
nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
|
nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < CHAN_MAX; i++)
|
||||||
|
tty_port_destroy(&nd->nd_chan[i].port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3320,7 +3321,6 @@ dgrp_tty_init(struct nd_struct *nd)
|
||||||
init_waitqueue_head(&(ch->ch_pun.un_open_wait));
|
init_waitqueue_head(&(ch->ch_pun.un_open_wait));
|
||||||
init_waitqueue_head(&(ch->ch_pun.un_close_wait));
|
init_waitqueue_head(&(ch->ch_pun.un_close_wait));
|
||||||
tty_port_init(&ch->port);
|
tty_port_init(&ch->port);
|
||||||
tty_port_init(&ch->port);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -939,14 +939,9 @@ static void fwserial_destroy(struct kref *kref)
|
||||||
|
|
||||||
mutex_lock(&port_table_lock);
|
mutex_lock(&port_table_lock);
|
||||||
for (j = 0; j < num_ports; ++i, ++j) {
|
for (j = 0; j < num_ports; ++i, ++j) {
|
||||||
static bool once;
|
port_table_corrupt |= port_table[i] != ports[j];
|
||||||
int corrupt = port_table[i] != ports[j];
|
WARN_ONCE(port_table_corrupt, "port_table[%d]: %p != ports[%d]: %p",
|
||||||
if (corrupt && !once) {
|
i, port_table[i], j, ports[j]);
|
||||||
WARN(corrupt, "port_table[%d]: %p != ports[%d]: %p",
|
|
||||||
i, port_table[i], j, ports[j]);
|
|
||||||
once = true;
|
|
||||||
port_table_corrupt = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
port_table[i] = NULL;
|
port_table[i] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -954,7 +949,7 @@ static void fwserial_destroy(struct kref *kref)
|
||||||
|
|
||||||
for (j = 0; j < num_ports; ++j) {
|
for (j = 0; j < num_ports; ++j) {
|
||||||
fw_core_remove_address_handler(&ports[j]->rx_handler);
|
fw_core_remove_address_handler(&ports[j]->rx_handler);
|
||||||
dma_fifo_free(&ports[j]->tx_fifo);
|
tty_port_destroy(&ports[j]->port);
|
||||||
kfree(ports[j]);
|
kfree(ports[j]);
|
||||||
}
|
}
|
||||||
kfree(serial);
|
kfree(serial);
|
||||||
|
@ -2369,8 +2364,10 @@ unregister_ttys:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
free_ports:
|
free_ports:
|
||||||
for (--i; i >= 0; --i)
|
for (--i; i >= 0; --i) {
|
||||||
|
tty_port_destroy(&serial->ports[i]->port);
|
||||||
kfree(serial->ports[i]);
|
kfree(serial->ports[i]);
|
||||||
|
}
|
||||||
kfree(serial);
|
kfree(serial);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
config SB105X
|
||||||
|
tristate "SystemBase PCI Multiport UART"
|
||||||
|
select SERIAL_CORE
|
||||||
|
depends on PCI
|
||||||
|
help
|
||||||
|
A driver for the SystemBase Multi-2/PCI serial card
|
||||||
|
|
||||||
|
To compile this driver a module, choose M here: the module
|
||||||
|
will be called "sb105x".
|
|
@ -0,0 +1,3 @@
|
||||||
|
obj-$(CONFIG_SB105X) += sb105x.o
|
||||||
|
|
||||||
|
sb105x-y := sb_pci_mp.o
|
|
@ -0,0 +1,295 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SB105X_UART.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 systembase
|
||||||
|
*
|
||||||
|
* UART registers.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UART_SB105X_H
|
||||||
|
#define UART_SB105X_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* option register
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Device Infomation Register */
|
||||||
|
#define MP_OPTR_DIR0 0x04 /* port0 ~ port8 */
|
||||||
|
#define MP_OPTR_DIR1 0x05 /* port8 ~ port15 */
|
||||||
|
#define MP_OPTR_DIR2 0x06 /* port16 ~ port23 */
|
||||||
|
#define MP_OPTR_DIR3 0x07 /* port24 ~ port31 */
|
||||||
|
|
||||||
|
#define DIR_UART_16C550 0
|
||||||
|
#define DIR_UART_16C1050 1
|
||||||
|
#define DIR_UART_16C1050A 2
|
||||||
|
|
||||||
|
#define DIR_CLK_1843200 0x0 /* input clock 1843200 Hz */
|
||||||
|
#define DIR_CLK_3686400 0x1 /* input clock 3686400 Hz */
|
||||||
|
#define DIR_CLK_7372800 0x2 /* input clock 7372800 Hz */
|
||||||
|
#define DIR_CLK_14745600 0x3 /* input clock 14745600 Hz */
|
||||||
|
#define DIR_CLK_29491200 0x4 /* input clock 29491200 Hz */
|
||||||
|
#define DIR_CLK_58985400 0x5 /* input clock 58985400 Hz */
|
||||||
|
|
||||||
|
/* Interface Information Register */
|
||||||
|
#define MP_OPTR_IIR0 0x08 /* port0 ~ port8 */
|
||||||
|
#define MP_OPTR_IIR1 0x09 /* port8 ~ port15 */
|
||||||
|
#define MP_OPTR_IIR2 0x0A /* port16 ~ port23 */
|
||||||
|
#define MP_OPTR_IIR3 0x0B /* port24 ~ port31 */
|
||||||
|
|
||||||
|
#define IIR_RS232 0x00 /* RS232 type */
|
||||||
|
#define IIR_RS422 0x10 /* RS422 type */
|
||||||
|
#define IIR_RS485 0x20 /* RS485 type */
|
||||||
|
#define IIR_UNKNOWN 0x30 /* unknown type */
|
||||||
|
|
||||||
|
/* Interrrupt Mask Register */
|
||||||
|
#define MP_OPTR_IMR0 0x0C /* port0 ~ port8 */
|
||||||
|
#define MP_OPTR_IMR1 0x0D /* port8 ~ port15 */
|
||||||
|
#define MP_OPTR_IMR2 0x0E /* port16 ~ port23 */
|
||||||
|
#define MP_OPTR_IMR3 0x0F /* port24 ~ port31 */
|
||||||
|
|
||||||
|
/* Interrupt Poll Register */
|
||||||
|
#define MP_OPTR_IPR0 0x10 /* port0 ~ port8 */
|
||||||
|
#define MP_OPTR_IPR1 0x11 /* port8 ~ port15 */
|
||||||
|
#define MP_OPTR_IPR2 0x12 /* port16 ~ port23 */
|
||||||
|
#define MP_OPTR_IPR3 0x13 /* port24 ~ port31 */
|
||||||
|
|
||||||
|
/* General Purpose Output Control Register */
|
||||||
|
#define MP_OPTR_GPOCR 0x20
|
||||||
|
|
||||||
|
/* General Purpose Output Data Register */
|
||||||
|
#define MP_OPTR_GPODR 0x21
|
||||||
|
|
||||||
|
/* Parallel Additional Function Register */
|
||||||
|
#define MP_OPTR_PAFR 0x23
|
||||||
|
|
||||||
|
/*
|
||||||
|
* systembase 16c105x UART register
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAGE_0 0
|
||||||
|
#define PAGE_1 1
|
||||||
|
#define PAGE_2 2
|
||||||
|
#define PAGE_3 3
|
||||||
|
#define PAGE_4 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ******************************************************************
|
||||||
|
* * DLAB=0 =============== Page 0 Registers *
|
||||||
|
* ******************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SB105X_RX 0 /* In: Receive buffer */
|
||||||
|
#define SB105X_TX 0 /* Out: Transmit buffer */
|
||||||
|
|
||||||
|
#define SB105X_IER 1 /* Out: Interrupt Enable Register */
|
||||||
|
|
||||||
|
#define SB105X_IER_CTSI 0x80 /* CTS# Interrupt Enable (Requires EFR[4] = 1) */
|
||||||
|
#define SB105X_IER_RTSI 0x40 /* RTS# Interrupt Enable (Requires EFR[4] = 1) */
|
||||||
|
#define SB105X_IER_XOI 0x20 /* Xoff Interrupt Enable (Requires EFR[4] = 1) */
|
||||||
|
#define SB105X_IER_SME 0x10 /* Sleep Mode Enable (Requires EFR[4] = 1) */
|
||||||
|
#define SB105X_IER_MSI 0x08 /* Enable Modem status interrupt */
|
||||||
|
#define SB105X_IER_RLSI 0x04 /* Enable receiver line status interrupt */
|
||||||
|
#define SB105X_IER_THRI 0x02 /* Enable Transmitter holding register int. */
|
||||||
|
#define SB105X_IER_RDI 0x01 /* Enable receiver data interrupt */
|
||||||
|
|
||||||
|
#define SB105X_ISR 2 /* In: Interrupt ID Register */
|
||||||
|
|
||||||
|
#define SB105X_ISR_NOINT 0x01 /* No interrupts pending */
|
||||||
|
#define SB105X_ISR_RLSI 0x06 /* Receiver line status interrupt (Priority = 1)*/
|
||||||
|
#define SB105X_ISR_RDAI 0x0c /* Receive Data Available interrupt */
|
||||||
|
#define SB105X_ISR_CTII 0x04 /* Character Timeout Indication interrupt */
|
||||||
|
#define SB105X_ISR_THRI 0x02 /* Transmitter holding register empty */
|
||||||
|
#define SB105X_ISR_MSI 0x00 /* Modem status interrupt */
|
||||||
|
#define SB105X_ISR_RXCI 0x10 /* Receive Xoff or Special Character interrupt */
|
||||||
|
#define SB105X_ISR_RCSI 0x20 /* RTS#, CTS# status interrupt during Auto RTS/CTS flow control */
|
||||||
|
|
||||||
|
#define SB105X_FCR 2 /* Out: FIFO Control Register */
|
||||||
|
|
||||||
|
#define SB105X_FCR_FEN 0x01 /* FIFO Enable */
|
||||||
|
#define SB105X_FCR_RXFR 0x02 /* RX FIFO Reset */
|
||||||
|
#define SB105X_FCR_TXFR 0x04 /* TX FIFO Reset */
|
||||||
|
#define SB105X_FCR_DMS 0x08 /* DMA Mode Select */
|
||||||
|
|
||||||
|
#define SB105X_FCR_RTR08 0x00 /* Receice Trigger Level set at 8 */
|
||||||
|
#define SB105X_FCR_RTR16 0x40 /* Receice Trigger Level set at 16 */
|
||||||
|
#define SB105X_FCR_RTR56 0x80 /* Receice Trigger Level set at 56 */
|
||||||
|
#define SB105X_FCR_RTR60 0xc0 /* Receice Trigger Level set at 60 */
|
||||||
|
#define SB105X_FCR_TTR08 0x00 /* Transmit Trigger Level set at 8 */
|
||||||
|
#define SB105X_FCR_TTR16 0x10 /* Transmit Trigger Level set at 16 */
|
||||||
|
#define SB105X_FCR_TTR32 0x20 /* Transmit Trigger Level set at 32 */
|
||||||
|
#define SB105X_FCR_TTR56 0x30 /* Transmit Trigger Level set at 56 */
|
||||||
|
|
||||||
|
#define SB105X_LCR 3 /* Out: Line Control Register */
|
||||||
|
/*
|
||||||
|
* * Note: if the word length is 5 bits (SB105X_LCR_WLEN5), then setting
|
||||||
|
* * SB105X_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
|
||||||
|
*/
|
||||||
|
#define SB105X_LCR_DLAB 0x80 /* Divisor Latch Enable */
|
||||||
|
#define SB105X_LCR_SBC 0x40 /* Break Enable*/
|
||||||
|
#define SB105X_LCR_SPAR 0x20 /* Set Stick parity */
|
||||||
|
#define SB105X_LCR_EPAR 0x10 /* Even parity select */
|
||||||
|
#define SB105X_LCR_PAREN 0x08 /* Parity Enable */
|
||||||
|
#define SB105X_LCR_STOP 0x04 /* Stop bits: 0->1 bit, 1->2 bits, 1 and SB105X_LCR_WLEN5 -> 1.5 bit */
|
||||||
|
#define SB105X_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
|
||||||
|
#define SB105X_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
|
||||||
|
#define SB105X_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
|
||||||
|
#define SB105X_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
|
||||||
|
|
||||||
|
#define SB105X_LCR_BF 0xBF
|
||||||
|
|
||||||
|
#define SB105X_MCR 4 /* Out: Modem Control Register */
|
||||||
|
#define SB105X_MCR_CPS 0x80 /* Clock Prescaler Select */
|
||||||
|
#define SB105X_MCR_P2S 0x40 /* Page 2 Select /Xoff Re-Transmit Access Enable */
|
||||||
|
#define SB105X_MCR_XOA 0x20 /* Xon Any Enable */
|
||||||
|
#define SB105X_MCR_ILB 0x10 /* Internal Loopback Enable */
|
||||||
|
#define SB105X_MCR_OUT2 0x08 /* Out2/Interrupt Output Enable*/
|
||||||
|
#define SB105X_MCR_OUT1 0x04 /* Out1/Interrupt Output Enable */
|
||||||
|
#define SB105X_MCR_RTS 0x02 /* RTS# Output */
|
||||||
|
#define SB105X_MCR_DTR 0x01 /* DTR# Output */
|
||||||
|
|
||||||
|
#define SB105X_LSR 5 /* In: Line Status Register */
|
||||||
|
#define SB105X_LSR_RFEI 0x80 /* Receive FIFO data error Indicator */
|
||||||
|
#define SB105X_LSR_TEMI 0x40 /* THR and TSR Empty Indicator */
|
||||||
|
#define SB105X_LSR_THRE 0x20 /* THR Empty Indicator */
|
||||||
|
#define SB105X_LSR_BII 0x10 /* Break interrupt indicator */
|
||||||
|
#define SB105X_LSR_FEI 0x08 /* Frame error indicator */
|
||||||
|
#define SB105X_LSR_PEI 0x04 /* Parity error indicator */
|
||||||
|
#define SB105X_LSR_OEI 0x02 /* Overrun error indicator */
|
||||||
|
#define SB105X_LSR_RDRI 0x01 /* Receive data ready Indicator*/
|
||||||
|
|
||||||
|
#define SB105X_MSR 6 /* In: Modem Status Register */
|
||||||
|
#define SB105X_MSR_DCD 0x80 /* Data Carrier Detect */
|
||||||
|
#define SB105X_MSR_RI 0x40 /* Ring Indicator */
|
||||||
|
#define SB105X_MSR_DSR 0x20 /* Data Set Ready */
|
||||||
|
#define SB105X_MSR_CTS 0x10 /* Clear to Send */
|
||||||
|
#define SB105X_MSR_DDCD 0x08 /* Delta DCD */
|
||||||
|
#define SB105X_MSR_DRI 0x04 /* Delta ring indicator */
|
||||||
|
#define SB105X_MSR_DDSR 0x02 /* Delta DSR */
|
||||||
|
#define SB105X_MSR_DCTS 0x01 /* Delta CTS */
|
||||||
|
|
||||||
|
#define SB105XA_MDR 6 /* Out: Multi Drop mode Register */
|
||||||
|
#define SB105XA_MDR_NPS 0x08 /* 9th Bit Polarity Select */
|
||||||
|
#define SB105XA_MDR_AME 0x02 /* Auto Multi-drop Enable */
|
||||||
|
#define SB105XA_MDR_MDE 0x01 /* Multi Drop Enable */
|
||||||
|
|
||||||
|
#define SB105X_SPR 7 /* I/O: Scratch Register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLAB=1
|
||||||
|
*/
|
||||||
|
#define SB105X_DLL 0 /* Out: Divisor Latch Low */
|
||||||
|
#define SB105X_DLM 1 /* Out: Divisor Latch High */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ******************************************************************
|
||||||
|
* * DLAB(LCR[7]) = 0 , MCR[6] = 1 ============= Page 2 Registers *
|
||||||
|
* ******************************************************************
|
||||||
|
*/
|
||||||
|
#define SB105X_GICR 1 /* Global Interrupt Control Register */
|
||||||
|
#define SB105X_GICR_GIM 0x01 /* Global Interrupt Mask */
|
||||||
|
|
||||||
|
#define SB105X_GISR 2 /* Global Interrupt Status Register */
|
||||||
|
#define SB105X_GISR_MGICR0 0x80 /* Mirror the content of GICR[0] */
|
||||||
|
#define SB105X_GISR_CS3IS 0x08 /* SB105X of CS3# Interrupt Status */
|
||||||
|
#define SB105X_GISR_CS2IS 0x04 /* SB105X of CS2# Interrupt Status */
|
||||||
|
#define SB105X_GISR_CS1IS 0x02 /* SB105X of CS1# Interrupt Status */
|
||||||
|
#define SB105X_GISR_CS0IS 0x01 /* SB105X of CS0# Interrupt Status */
|
||||||
|
|
||||||
|
#define SB105X_TFCR 5 /* Transmit FIFO Count Register */
|
||||||
|
|
||||||
|
#define SB105X_RFCR 6 /* Receive FIFO Count Register */
|
||||||
|
|
||||||
|
#define SB105X_FSR 7 /* Flow Control Status Register */
|
||||||
|
#define SB105X_FSR_THFS 0x20 /* Transmit Hardware Flow Control Status */
|
||||||
|
#define SB105X_FSR_TSFS 0x10 /* Transmit Software Flow Control Status */
|
||||||
|
#define SB105X_FSR_RHFS 0x02 /* Receive Hardware Flow Control Status */
|
||||||
|
#define SB105X_FSR_RSFS 0x01 /* Receive Software Flow Control Status */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ******************************************************************
|
||||||
|
* * LCR = 0xBF, PSR[0] = 0 ============= Page 3 Registers *
|
||||||
|
* ******************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SB105X_PSR 0 /* Page Select Register */
|
||||||
|
#define SB105X_PSR_P3KEY 0xA4 /* Page 3 Select Key */
|
||||||
|
#define SB105X_PSR_P4KEY 0xA5 /* Page 5 Select Key */
|
||||||
|
|
||||||
|
#define SB105X_ATR 1 /* Auto Toggle Control Register */
|
||||||
|
#define SB105X_ATR_RPS 0x80 /* RXEN Polarity Select */
|
||||||
|
#define SB105X_ATR_RCMS 0x40 /* RXEN Control Mode Select */
|
||||||
|
#define SB105X_ATR_TPS 0x20 /* TXEN Polarity Select */
|
||||||
|
#define SB105X_ATR_TCMS 0x10 /* TXEN Control Mode Select */
|
||||||
|
#define SB105X_ATR_ATDIS 0x00 /* Auto Toggle is disabled */
|
||||||
|
#define SB105X_ATR_ART 0x01 /* RTS#/TXEN pin operates as TXEN */
|
||||||
|
#define SB105X_ATR_ADT 0x02 /* DTR#/TXEN pin operates as TXEN */
|
||||||
|
#define SB105X_ATR_A80 0x03 /* only in 80 pin use */
|
||||||
|
|
||||||
|
#define SB105X_EFR 2 /* (Auto) Enhanced Feature Register */
|
||||||
|
#define SB105X_EFR_ACTS 0x80 /* Auto-CTS Flow Control Enable */
|
||||||
|
#define SB105X_EFR_ARTS 0x40 /* Auto-RTS Flow Control Enable */
|
||||||
|
#define SB105X_EFR_SCD 0x20 /* Special Character Detect */
|
||||||
|
#define SB105X_EFR_EFBEN 0x10 /* Enhanced Function Bits Enable */
|
||||||
|
|
||||||
|
#define SB105X_XON1 4 /* Xon1 Character Register */
|
||||||
|
#define SB105X_XON2 5 /* Xon2 Character Register */
|
||||||
|
#define SB105X_XOFF1 6 /* Xoff1 Character Register */
|
||||||
|
#define SB105X_XOFF2 7 /* Xoff2 Character Register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ******************************************************************
|
||||||
|
* * LCR = 0xBF, PSR[0] = 1 ============ Page 4 Registers *
|
||||||
|
* ******************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SB105X_AFR 1 /* Additional Feature Register */
|
||||||
|
#define SB105X_AFR_GIPS 0x20 /* Global Interrupt Polarity Select */
|
||||||
|
#define SB105X_AFR_GIEN 0x10 /* Global Interrupt Enable */
|
||||||
|
#define SB105X_AFR_AFEN 0x01 /* 256-byte FIFO Enable */
|
||||||
|
|
||||||
|
#define SB105X_XRCR 2 /* Xoff Re-transmit Count Register */
|
||||||
|
#define SB105X_XRCR_NRC1 0x00 /* Transmits Xoff Character whenever the number of received data is 1 during XOFF status */
|
||||||
|
#define SB105X_XRCR_NRC4 0x01 /* Transmits Xoff Character whenever the number of received data is 4 during XOFF status */
|
||||||
|
#define SB105X_XRCR_NRC8 0x02 /* Transmits Xoff Character whenever the number of received data is 8 during XOFF status */
|
||||||
|
#define SB105X_XRCR_NRC16 0x03 /* Transmits Xoff Character whenever the number of received data is 16 during XOFF status */
|
||||||
|
|
||||||
|
#define SB105X_TTR 4 /* Transmit FIFO Trigger Level Register */
|
||||||
|
#define SB105X_RTR 5 /* Receive FIFO Trigger Level Register */
|
||||||
|
#define SB105X_FUR 6 /* Flow Control Upper Threshold Register */
|
||||||
|
#define SB105X_FLR 7 /* Flow Control Lower Threshold Register */
|
||||||
|
|
||||||
|
|
||||||
|
/* page 0 */
|
||||||
|
|
||||||
|
#define SB105X_GET_CHAR(port) inb((port)->iobase + SB105X_RX)
|
||||||
|
#define SB105X_GET_IER(port) inb((port)->iobase + SB105X_IER)
|
||||||
|
#define SB105X_GET_ISR(port) inb((port)->iobase + SB105X_ISR)
|
||||||
|
#define SB105X_GET_LCR(port) inb((port)->iobase + SB105X_LCR)
|
||||||
|
#define SB105X_GET_MCR(port) inb((port)->iobase + SB105X_MCR)
|
||||||
|
#define SB105X_GET_LSR(port) inb((port)->iobase + SB105X_LSR)
|
||||||
|
#define SB105X_GET_MSR(port) inb((port)->iobase + SB105X_MSR)
|
||||||
|
#define SB105X_GET_SPR(port) inb((port)->iobase + SB105X_SPR)
|
||||||
|
|
||||||
|
#define SB105X_PUT_CHAR(port,v) outb((v),(port)->iobase + SB105X_TX )
|
||||||
|
#define SB105X_PUT_IER(port,v) outb((v),(port)->iobase + SB105X_IER )
|
||||||
|
#define SB105X_PUT_FCR(port,v) outb((v),(port)->iobase + SB105X_FCR )
|
||||||
|
#define SB105X_PUT_LCR(port,v) outb((v),(port)->iobase + SB105X_LCR )
|
||||||
|
#define SB105X_PUT_MCR(port,v) outb((v),(port)->iobase + SB105X_MCR )
|
||||||
|
#define SB105X_PUT_SPR(port,v) outb((v),(port)->iobase + SB105X_SPR )
|
||||||
|
|
||||||
|
|
||||||
|
/* page 1 */
|
||||||
|
#define SB105X_GET_REG(port,reg) inb((port)->iobase + (reg))
|
||||||
|
#define SB105X_PUT_REG(port,reg,v) outb((v),(port)->iobase + (reg))
|
||||||
|
|
||||||
|
/* page 2 */
|
||||||
|
|
||||||
|
#define SB105X_PUT_PSR(port,v) outb((v),(port)->iobase + SB105X_PSR )
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,293 @@
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/signal.h>
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <linux/tty_flip.h>
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#include <linux/serial_reg.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
|
#include <linux/tty_driver.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/circ_buf.h>
|
||||||
|
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/segment.h>
|
||||||
|
#include <asm/serial.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/parport.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/poll.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MP_TERMIOS ktermios
|
||||||
|
|
||||||
|
#include "sb_mp_register.h"
|
||||||
|
#include "sb_ser_core.h"
|
||||||
|
|
||||||
|
#define DRIVER_VERSION "1.1"
|
||||||
|
#define DRIVER_DATE "2012/01/05"
|
||||||
|
#define DRIVER_AUTHOR "SYSTEMBASE<tech@sysbas.com>"
|
||||||
|
#define DRIVER_DESC "SystemBase PCI/PCIe Multiport Core"
|
||||||
|
|
||||||
|
#define SB_TTY_MP_MAJOR 54
|
||||||
|
#define PCI_VENDOR_ID_MULTIPORT 0x14A1
|
||||||
|
|
||||||
|
#define PCI_DEVICE_ID_MP1 0x4d01
|
||||||
|
#define PCI_DEVICE_ID_MP2 0x4d02
|
||||||
|
#define PCI_DEVICE_ID_MP4 0x4d04
|
||||||
|
#define PCI_DEVICE_ID_MP4A 0x4d54
|
||||||
|
#define PCI_DEVICE_ID_MP6 0x4d06
|
||||||
|
#define PCI_DEVICE_ID_MP6A 0x4d56
|
||||||
|
#define PCI_DEVICE_ID_MP8 0x4d08
|
||||||
|
#define PCI_DEVICE_ID_MP32 0x4d32
|
||||||
|
/* Parallel port */
|
||||||
|
#define PCI_DEVICE_ID_MP1P 0x4301
|
||||||
|
#define PCI_DEVICE_ID_MP2S1P 0x4303
|
||||||
|
|
||||||
|
#define PCIE_DEVICE_ID_MP1 0x4501
|
||||||
|
#define PCIE_DEVICE_ID_MP2 0x4502
|
||||||
|
#define PCIE_DEVICE_ID_MP4 0x4504
|
||||||
|
#define PCIE_DEVICE_ID_MP8 0x4508
|
||||||
|
#define PCIE_DEVICE_ID_MP32 0x4532
|
||||||
|
|
||||||
|
#define PCIE_DEVICE_ID_MP1E 0x4e01
|
||||||
|
#define PCIE_DEVICE_ID_MP2E 0x4e02
|
||||||
|
#define PCIE_DEVICE_ID_MP2B 0x4b02
|
||||||
|
#define PCIE_DEVICE_ID_MP4B 0x4b04
|
||||||
|
#define PCIE_DEVICE_ID_MP8B 0x4b08
|
||||||
|
|
||||||
|
#define PCI_DEVICE_ID_GT_MP4 0x0004
|
||||||
|
#define PCI_DEVICE_ID_GT_MP4A 0x0054
|
||||||
|
#define PCI_DEVICE_ID_GT_MP6 0x0006
|
||||||
|
#define PCI_DEVICE_ID_GT_MP6A 0x0056
|
||||||
|
#define PCI_DEVICE_ID_GT_MP8 0x0008
|
||||||
|
#define PCI_DEVICE_ID_GT_MP32 0x0032
|
||||||
|
|
||||||
|
#define PCIE_DEVICE_ID_GT_MP1 0x1501
|
||||||
|
#define PCIE_DEVICE_ID_GT_MP2 0x1502
|
||||||
|
#define PCIE_DEVICE_ID_GT_MP4 0x1504
|
||||||
|
#define PCIE_DEVICE_ID_GT_MP8 0x1508
|
||||||
|
#define PCIE_DEVICE_ID_GT_MP32 0x1532
|
||||||
|
|
||||||
|
#define PCI_DEVICE_ID_MP4M 0x4604 //modem
|
||||||
|
|
||||||
|
#define MAX_MP_DEV 8
|
||||||
|
#define BD_MAX_PORT 32 /* Max serial port in one board */
|
||||||
|
#define MAX_MP_PORT 256 /* Max serial port in one PC */
|
||||||
|
|
||||||
|
#define PORT_16C105XA 3
|
||||||
|
#define PORT_16C105X 2
|
||||||
|
#define PORT_16C55X 1
|
||||||
|
|
||||||
|
#define ENABLE 1
|
||||||
|
#define DISABLE 0
|
||||||
|
|
||||||
|
/* ioctls */
|
||||||
|
#define TIOCGNUMOFPORT 0x545F
|
||||||
|
#define TIOCSMULTIECHO 0x5440
|
||||||
|
#define TIOCSPTPNOECHO 0x5441
|
||||||
|
|
||||||
|
#define TIOCGOPTIONREG 0x5461
|
||||||
|
#define TIOCGDISABLEIRQ 0x5462
|
||||||
|
#define TIOCGENABLEIRQ 0x5463
|
||||||
|
#define TIOCGSOFTRESET 0x5464
|
||||||
|
#define TIOCGSOFTRESETR 0x5465
|
||||||
|
#define TIOCGREGINFO 0x5466
|
||||||
|
#define TIOCGGETLSR 0x5467
|
||||||
|
#define TIOCGGETDEVID 0x5468
|
||||||
|
#define TIOCGGETBDNO 0x5469
|
||||||
|
#define TIOCGGETINTERFACE 0x546A
|
||||||
|
#define TIOCGGETREV 0x546B
|
||||||
|
#define TIOCGGETNRPORTS 0x546C
|
||||||
|
#define TIOCGGETPORTTYPE 0x546D
|
||||||
|
#define GETDEEPFIFO 0x54AA
|
||||||
|
#define SETDEEPFIFO 0x54AB
|
||||||
|
#define SETFCR 0x54BA
|
||||||
|
#define SETTTR 0x54B1
|
||||||
|
#define SETRTR 0x54B2
|
||||||
|
#define GETTTR 0x54B3
|
||||||
|
#define GETRTR 0x54B4
|
||||||
|
|
||||||
|
/* multi-drop mode related ioctl commands */
|
||||||
|
#define TIOCSMULTIDROP 0x5470
|
||||||
|
#define TIOCSMDADDR 0x5471
|
||||||
|
#define TIOCGMDADDR 0x5472
|
||||||
|
#define TIOCSENDADDR 0x5473
|
||||||
|
|
||||||
|
|
||||||
|
/* serial interface */
|
||||||
|
#define RS232 1
|
||||||
|
#define RS422PTP 2
|
||||||
|
#define RS422MD 3
|
||||||
|
#define RS485NE 4
|
||||||
|
#define RS485ECHO 5
|
||||||
|
|
||||||
|
#define serial_inp(up, offset) serial_in(up, offset)
|
||||||
|
#define serial_outp(up, offset, value) serial_out(up, offset, value)
|
||||||
|
|
||||||
|
#define PASS_LIMIT 256
|
||||||
|
#define is_real_interrupt(irq) ((irq) != 0)
|
||||||
|
|
||||||
|
#define PROBE_ANY (~0)
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(mp_mutex);
|
||||||
|
#define MP_MUTEX_LOCK(x) mutex_lock(&(x))
|
||||||
|
#define MP_MUTEX_UNLOCK(x) mutex_unlock(&(x))
|
||||||
|
#define MP_STATE_LOCK(x) mutex_lock(&((x)->mutex))
|
||||||
|
#define MP_STATE_UNLOCK(x) mutex_unlock(&((x)->mutex))
|
||||||
|
|
||||||
|
|
||||||
|
#define UART_LSR_SPECIAL 0x1E
|
||||||
|
|
||||||
|
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
|
||||||
|
#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
|
||||||
|
|
||||||
|
|
||||||
|
//#define MP_DEBUG 1
|
||||||
|
#undef MP_DEBUG
|
||||||
|
|
||||||
|
#ifdef MP_DEBUG
|
||||||
|
#define DPRINTK(x...) printk(x)
|
||||||
|
#else
|
||||||
|
#define DPRINTK(x...) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MP_DEBUG
|
||||||
|
#define DEBUG_AUTOCONF(fmt...) printk(fmt)
|
||||||
|
#else
|
||||||
|
#define DEBUG_AUTOCONF(fmt...) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MP_DEBUG
|
||||||
|
#define DEBUG_INTR(fmt...) printk(fmt)
|
||||||
|
#else
|
||||||
|
#define DEBUG_INTR(fmt...) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
|
||||||
|
#define SERIAL_INLINE
|
||||||
|
#endif
|
||||||
|
#ifdef SERIAL_INLINE
|
||||||
|
#define _INLINE_ inline
|
||||||
|
#else
|
||||||
|
#define _INLINE_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TYPE_POLL 1
|
||||||
|
#define TYPE_INTERRUPT 2
|
||||||
|
|
||||||
|
|
||||||
|
struct mp_device_t {
|
||||||
|
unsigned short device_id;
|
||||||
|
unsigned char revision;
|
||||||
|
char *name;
|
||||||
|
unsigned long uart_access_addr;
|
||||||
|
unsigned long option_reg_addr;
|
||||||
|
unsigned long reserved_addr[4];
|
||||||
|
int irq;
|
||||||
|
int nr_ports;
|
||||||
|
int poll_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct mppcibrd {
|
||||||
|
char *name;
|
||||||
|
unsigned short vendor_id;
|
||||||
|
unsigned short device_id;
|
||||||
|
} mppcibrd_t;
|
||||||
|
|
||||||
|
static mppcibrd_t mp_pciboards[] = {
|
||||||
|
|
||||||
|
{ "Multi-1 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1} ,
|
||||||
|
{ "Multi-2 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2} ,
|
||||||
|
{ "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4} ,
|
||||||
|
{ "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4A} ,
|
||||||
|
{ "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6} ,
|
||||||
|
{ "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6A} ,
|
||||||
|
{ "Multi-8 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP8} ,
|
||||||
|
{ "Multi-32 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP32} ,
|
||||||
|
|
||||||
|
{ "Multi-1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1P} ,
|
||||||
|
{ "Multi-2S1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2S1P} ,
|
||||||
|
|
||||||
|
{ "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4} ,
|
||||||
|
{ "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4A} ,
|
||||||
|
{ "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6} ,
|
||||||
|
{ "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6A} ,
|
||||||
|
{ "Multi-8(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP8} ,
|
||||||
|
{ "Multi-32(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP32} ,
|
||||||
|
|
||||||
|
{ "Multi-1 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1} ,
|
||||||
|
{ "Multi-2 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2} ,
|
||||||
|
{ "Multi-4 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4} ,
|
||||||
|
{ "Multi-8 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8} ,
|
||||||
|
{ "Multi-32 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP32} ,
|
||||||
|
|
||||||
|
{ "Multi-1 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1E} ,
|
||||||
|
{ "Multi-2 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2E} ,
|
||||||
|
{ "Multi-2 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2B} ,
|
||||||
|
{ "Multi-4 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4B} ,
|
||||||
|
{ "Multi-8 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8B} ,
|
||||||
|
|
||||||
|
{ "Multi-1(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP1} ,
|
||||||
|
{ "Multi-2(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP2} ,
|
||||||
|
{ "Multi-4(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP4} ,
|
||||||
|
{ "Multi-8(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP8} ,
|
||||||
|
{ "Multi-32(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP32} ,
|
||||||
|
|
||||||
|
{ "Multi-4M PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4M} ,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mp_port {
|
||||||
|
struct sb_uart_port port;
|
||||||
|
|
||||||
|
struct timer_list timer; /* "no irq" timer */
|
||||||
|
struct list_head list; /* ports on this IRQ */
|
||||||
|
unsigned int capabilities; /* port capabilities */
|
||||||
|
unsigned short rev;
|
||||||
|
unsigned char acr;
|
||||||
|
unsigned char ier;
|
||||||
|
unsigned char lcr;
|
||||||
|
unsigned char mcr;
|
||||||
|
unsigned char mcr_mask; /* mask of user bits */
|
||||||
|
unsigned char mcr_force; /* mask of forced bits */
|
||||||
|
unsigned char lsr_break_flag;
|
||||||
|
|
||||||
|
void (*pm)(struct sb_uart_port *port,
|
||||||
|
unsigned int state, unsigned int old);
|
||||||
|
struct mp_device_t *device;
|
||||||
|
unsigned long interface_config_addr;
|
||||||
|
unsigned long option_base_addr;
|
||||||
|
unsigned char interface;
|
||||||
|
unsigned char poll_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct irq_info {
|
||||||
|
spinlock_t lock;
|
||||||
|
struct list_head *head;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sb105x_uart_config {
|
||||||
|
char *name;
|
||||||
|
int dfl_xmit_fifo_size;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct sb105x_uart_config uart_config[] = {
|
||||||
|
{ "unknown", 1, 0 },
|
||||||
|
{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
|
||||||
|
{ "SB16C1050", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
|
||||||
|
{ "SB16C1050A", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,368 @@
|
||||||
|
#include <linux/wait.h>
|
||||||
|
|
||||||
|
#define UART_CONFIG_TYPE (1 << 0)
|
||||||
|
#define UART_CONFIG_IRQ (1 << 1)
|
||||||
|
#define UPIO_PORT (0)
|
||||||
|
#define UPIO_HUB6 (1)
|
||||||
|
#define UPIO_MEM (2)
|
||||||
|
#define UPIO_MEM32 (3)
|
||||||
|
#define UPIO_AU (4) /* Au1x00 type IO */
|
||||||
|
#define UPIO_TSI (5) /* Tsi108/109 type IO */
|
||||||
|
#define UPF_FOURPORT (1 << 1)
|
||||||
|
#define UPF_SAK (1 << 2)
|
||||||
|
#define UPF_SPD_MASK (0x1030)
|
||||||
|
#define UPF_SPD_HI (0x0010)
|
||||||
|
#define UPF_SPD_VHI (0x0020)
|
||||||
|
#define UPF_SPD_CUST (0x0030)
|
||||||
|
#define UPF_SPD_SHI (0x1000)
|
||||||
|
#define UPF_SPD_WARP (0x1010)
|
||||||
|
#define UPF_SKIP_TEST (1 << 6)
|
||||||
|
#define UPF_AUTO_IRQ (1 << 7)
|
||||||
|
#define UPF_HARDPPS_CD (1 << 11)
|
||||||
|
#define UPF_LOW_LATENCY (1 << 13)
|
||||||
|
#define UPF_BUGGY_UART (1 << 14)
|
||||||
|
#define UPF_MAGIC_MULTIPLIER (1 << 16)
|
||||||
|
#define UPF_CONS_FLOW (1 << 23)
|
||||||
|
#define UPF_SHARE_IRQ (1 << 24)
|
||||||
|
#define UPF_BOOT_AUTOCONF (1 << 28)
|
||||||
|
#define UPF_DEAD (1 << 30)
|
||||||
|
#define UPF_IOREMAP (1 << 31)
|
||||||
|
#define UPF_CHANGE_MASK (0x17fff)
|
||||||
|
#define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY)
|
||||||
|
#define USF_CLOSING_WAIT_INF (0)
|
||||||
|
#define USF_CLOSING_WAIT_NONE (~0U)
|
||||||
|
|
||||||
|
#define UART_XMIT_SIZE PAGE_SIZE
|
||||||
|
|
||||||
|
#define UIF_CHECK_CD (1 << 25)
|
||||||
|
#define UIF_CTS_FLOW (1 << 26)
|
||||||
|
#define UIF_NORMAL_ACTIVE (1 << 29)
|
||||||
|
#define UIF_INITIALIZED (1 << 31)
|
||||||
|
#define UIF_SUSPENDED (1 << 30)
|
||||||
|
|
||||||
|
#define WAKEUP_CHARS 256
|
||||||
|
|
||||||
|
#define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
|
||||||
|
#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
|
||||||
|
|
||||||
|
#define uart_circ_chars_pending(circ) \
|
||||||
|
(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
|
||||||
|
|
||||||
|
#define uart_circ_chars_free(circ) \
|
||||||
|
(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
|
||||||
|
|
||||||
|
#define uart_tx_stopped(port) \
|
||||||
|
((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
|
||||||
|
|
||||||
|
#define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \
|
||||||
|
(cflag) & CRTSCTS || \
|
||||||
|
!((cflag) & CLOCAL))
|
||||||
|
|
||||||
|
|
||||||
|
struct sb_uart_port;
|
||||||
|
struct sb_uart_info;
|
||||||
|
struct serial_struct;
|
||||||
|
struct device;
|
||||||
|
|
||||||
|
struct sb_uart_ops {
|
||||||
|
unsigned int (*tx_empty)(struct sb_uart_port *);
|
||||||
|
void (*set_mctrl)(struct sb_uart_port *, unsigned int mctrl);
|
||||||
|
unsigned int (*get_mctrl)(struct sb_uart_port *);
|
||||||
|
void (*stop_tx)(struct sb_uart_port *);
|
||||||
|
void (*start_tx)(struct sb_uart_port *);
|
||||||
|
void (*send_xchar)(struct sb_uart_port *, char ch);
|
||||||
|
void (*stop_rx)(struct sb_uart_port *);
|
||||||
|
void (*enable_ms)(struct sb_uart_port *);
|
||||||
|
void (*break_ctl)(struct sb_uart_port *, int ctl);
|
||||||
|
int (*startup)(struct sb_uart_port *);
|
||||||
|
void (*shutdown)(struct sb_uart_port *);
|
||||||
|
void (*set_termios)(struct sb_uart_port *, struct MP_TERMIOS *new,
|
||||||
|
struct MP_TERMIOS *old);
|
||||||
|
void (*pm)(struct sb_uart_port *, unsigned int state,
|
||||||
|
unsigned int oldstate);
|
||||||
|
int (*set_wake)(struct sb_uart_port *, unsigned int state);
|
||||||
|
|
||||||
|
const char *(*type)(struct sb_uart_port *);
|
||||||
|
|
||||||
|
void (*release_port)(struct sb_uart_port *);
|
||||||
|
|
||||||
|
int (*request_port)(struct sb_uart_port *);
|
||||||
|
void (*config_port)(struct sb_uart_port *, int);
|
||||||
|
int (*verify_port)(struct sb_uart_port *, struct serial_struct *);
|
||||||
|
int (*ioctl)(struct sb_uart_port *, unsigned int, unsigned long);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct sb_uart_icount {
|
||||||
|
__u32 cts;
|
||||||
|
__u32 dsr;
|
||||||
|
__u32 rng;
|
||||||
|
__u32 dcd;
|
||||||
|
__u32 rx;
|
||||||
|
__u32 tx;
|
||||||
|
__u32 frame;
|
||||||
|
__u32 overrun;
|
||||||
|
__u32 parity;
|
||||||
|
__u32 brk;
|
||||||
|
__u32 buf_overrun;
|
||||||
|
};
|
||||||
|
typedef unsigned int upf_t;
|
||||||
|
|
||||||
|
struct sb_uart_port {
|
||||||
|
spinlock_t lock; /* port lock */
|
||||||
|
unsigned int iobase; /* in/out[bwl] */
|
||||||
|
unsigned char __iomem *membase; /* read/write[bwl] */
|
||||||
|
unsigned int irq; /* irq number */
|
||||||
|
unsigned int uartclk; /* base uart clock */
|
||||||
|
unsigned int fifosize; /* tx fifo size */
|
||||||
|
unsigned char x_char; /* xon/xoff char */
|
||||||
|
unsigned char regshift; /* reg offset shift */
|
||||||
|
unsigned char iotype; /* io access style */
|
||||||
|
unsigned char unused1;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int read_status_mask; /* driver specific */
|
||||||
|
unsigned int ignore_status_mask; /* driver specific */
|
||||||
|
struct sb_uart_info *info; /* pointer to parent info */
|
||||||
|
struct sb_uart_icount icount; /* statistics */
|
||||||
|
|
||||||
|
struct console *cons; /* struct console, if any */
|
||||||
|
#ifdef CONFIG_SERIAL_CORE_CONSOLE
|
||||||
|
unsigned long sysrq; /* sysrq timeout */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
upf_t flags;
|
||||||
|
|
||||||
|
unsigned int mctrl; /* current modem ctrl settings */
|
||||||
|
unsigned int timeout; /* character-based timeout */
|
||||||
|
unsigned int type; /* port type */
|
||||||
|
const struct sb_uart_ops *ops;
|
||||||
|
unsigned int custom_divisor;
|
||||||
|
unsigned int line; /* port index */
|
||||||
|
unsigned long mapbase; /* for ioremap */
|
||||||
|
struct device *dev; /* parent device */
|
||||||
|
unsigned char hub6; /* this should be in the 8250 driver */
|
||||||
|
unsigned char unused[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define mdmode unused[2]
|
||||||
|
#define MDMODE_ADDR 0x1
|
||||||
|
#define MDMODE_ENABLE 0x2
|
||||||
|
#define MDMODE_AUTO 0x4
|
||||||
|
#define MDMODE_ADDRSEND 0x8
|
||||||
|
|
||||||
|
struct sb_uart_state {
|
||||||
|
unsigned int close_delay; /* msec */
|
||||||
|
unsigned int closing_wait; /* msec */
|
||||||
|
|
||||||
|
|
||||||
|
int count;
|
||||||
|
int pm_state;
|
||||||
|
struct sb_uart_info *info;
|
||||||
|
struct sb_uart_port *port;
|
||||||
|
|
||||||
|
struct mutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unsigned int uif_t;
|
||||||
|
|
||||||
|
struct sb_uart_info {
|
||||||
|
struct tty_struct *tty;
|
||||||
|
struct circ_buf xmit;
|
||||||
|
uif_t flags;
|
||||||
|
|
||||||
|
int blocked_open;
|
||||||
|
|
||||||
|
struct tasklet_struct tlet;
|
||||||
|
|
||||||
|
wait_queue_head_t open_wait;
|
||||||
|
wait_queue_head_t delta_msr_wait;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct module;
|
||||||
|
struct tty_driver;
|
||||||
|
|
||||||
|
struct uart_driver {
|
||||||
|
struct module *owner;
|
||||||
|
const char *driver_name;
|
||||||
|
const char *dev_name;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
int nr;
|
||||||
|
struct console *cons;
|
||||||
|
|
||||||
|
struct sb_uart_state *state;
|
||||||
|
struct tty_driver *tty_driver;
|
||||||
|
};
|
||||||
|
|
||||||
|
void sb_uart_write_wakeup(struct sb_uart_port *port)
|
||||||
|
{
|
||||||
|
struct sb_uart_info *info = port->info;
|
||||||
|
tasklet_schedule(&info->tlet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sb_uart_update_timeout(struct sb_uart_port *port, unsigned int cflag,
|
||||||
|
unsigned int baud)
|
||||||
|
{
|
||||||
|
unsigned int bits;
|
||||||
|
|
||||||
|
switch (cflag & CSIZE)
|
||||||
|
{
|
||||||
|
case CS5:
|
||||||
|
bits = 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CS6:
|
||||||
|
bits = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CS7:
|
||||||
|
bits = 9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bits = 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cflag & CSTOPB)
|
||||||
|
{
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cflag & PARENB)
|
||||||
|
{
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = bits * port->fifosize;
|
||||||
|
|
||||||
|
port->timeout = (HZ * bits) / baud + HZ/50;
|
||||||
|
}
|
||||||
|
unsigned int sb_uart_get_baud_rate(struct sb_uart_port *port, struct MP_TERMIOS *termios,
|
||||||
|
struct MP_TERMIOS *old, unsigned int min,
|
||||||
|
unsigned int max)
|
||||||
|
{
|
||||||
|
unsigned int try, baud, altbaud = 38400;
|
||||||
|
upf_t flags = port->flags & UPF_SPD_MASK;
|
||||||
|
|
||||||
|
if (flags == UPF_SPD_HI)
|
||||||
|
altbaud = 57600;
|
||||||
|
if (flags == UPF_SPD_VHI)
|
||||||
|
altbaud = 115200;
|
||||||
|
if (flags == UPF_SPD_SHI)
|
||||||
|
altbaud = 230400;
|
||||||
|
if (flags == UPF_SPD_WARP)
|
||||||
|
altbaud = 460800;
|
||||||
|
|
||||||
|
for (try = 0; try < 2; try++) {
|
||||||
|
|
||||||
|
switch (termios->c_cflag & (CBAUD | CBAUDEX))
|
||||||
|
{
|
||||||
|
case B921600 : baud = 921600; break;
|
||||||
|
case B460800 : baud = 460800; break;
|
||||||
|
case B230400 : baud = 230400; break;
|
||||||
|
case B115200 : baud = 115200; break;
|
||||||
|
case B57600 : baud = 57600; break;
|
||||||
|
case B38400 : baud = 38400; break;
|
||||||
|
case B19200 : baud = 19200; break;
|
||||||
|
case B9600 : baud = 9600; break;
|
||||||
|
case B4800 : baud = 4800; break;
|
||||||
|
case B2400 : baud = 2400; break;
|
||||||
|
case B1800 : baud = 1800; break;
|
||||||
|
case B1200 : baud = 1200; break;
|
||||||
|
case B600 : baud = 600; break;
|
||||||
|
case B300 : baud = 300; break;
|
||||||
|
case B200 : baud = 200; break;
|
||||||
|
case B150 : baud = 150; break;
|
||||||
|
case B134 : baud = 134; break;
|
||||||
|
case B110 : baud = 110; break;
|
||||||
|
case B75 : baud = 75; break;
|
||||||
|
case B50 : baud = 50; break;
|
||||||
|
default : baud = 9600; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baud == 38400)
|
||||||
|
baud = altbaud;
|
||||||
|
|
||||||
|
if (baud == 0)
|
||||||
|
baud = 9600;
|
||||||
|
|
||||||
|
if (baud >= min && baud <= max)
|
||||||
|
return baud;
|
||||||
|
|
||||||
|
termios->c_cflag &= ~CBAUD;
|
||||||
|
if (old) {
|
||||||
|
termios->c_cflag |= old->c_cflag & CBAUD;
|
||||||
|
old = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
termios->c_cflag |= B9600;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unsigned int sb_uart_get_divisor(struct sb_uart_port *port, unsigned int baud)
|
||||||
|
{
|
||||||
|
unsigned int quot;
|
||||||
|
|
||||||
|
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
|
||||||
|
quot = port->custom_divisor;
|
||||||
|
else
|
||||||
|
quot = (port->uartclk + (8 * baud)) / (16 * baud);
|
||||||
|
|
||||||
|
return quot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline int sb_uart_handle_break(struct sb_uart_port *port)
|
||||||
|
{
|
||||||
|
struct sb_uart_info *info = port->info;
|
||||||
|
|
||||||
|
if (port->flags & UPF_SAK)
|
||||||
|
do_SAK(info->tty);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sb_uart_handle_dcd_change(struct sb_uart_port *port, unsigned int status)
|
||||||
|
{
|
||||||
|
struct sb_uart_info *info = port->info;
|
||||||
|
|
||||||
|
port->icount.dcd++;
|
||||||
|
|
||||||
|
if (info->flags & UIF_CHECK_CD) {
|
||||||
|
if (status)
|
||||||
|
wake_up_interruptible(&info->open_wait);
|
||||||
|
else if (info->tty)
|
||||||
|
tty_hangup(info->tty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sb_uart_handle_cts_change(struct sb_uart_port *port, unsigned int status)
|
||||||
|
{
|
||||||
|
struct sb_uart_info *info = port->info;
|
||||||
|
struct tty_struct *tty = info->tty;
|
||||||
|
|
||||||
|
port->icount.cts++;
|
||||||
|
|
||||||
|
if (info->flags & UIF_CTS_FLOW) {
|
||||||
|
if (tty->hw_stopped) {
|
||||||
|
if (status) {
|
||||||
|
tty->hw_stopped = 0;
|
||||||
|
port->ops->start_tx(port);
|
||||||
|
sb_uart_write_wakeup(port);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!status) {
|
||||||
|
tty->hw_stopped = 1;
|
||||||
|
port->ops->stop_tx(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1771,6 +1771,7 @@ fail_free_irq:
|
||||||
fail_unregister:
|
fail_unregister:
|
||||||
tty_unregister_driver(serial_driver);
|
tty_unregister_driver(serial_driver);
|
||||||
fail_put_tty_driver:
|
fail_put_tty_driver:
|
||||||
|
tty_port_destroy(&state->tport);
|
||||||
put_tty_driver(serial_driver);
|
put_tty_driver(serial_driver);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -1785,6 +1786,7 @@ static int __exit amiga_serial_remove(struct platform_device *pdev)
|
||||||
printk("SERIAL: failed to unregister serial driver (%d)\n",
|
printk("SERIAL: failed to unregister serial driver (%d)\n",
|
||||||
error);
|
error);
|
||||||
put_tty_driver(serial_driver);
|
put_tty_driver(serial_driver);
|
||||||
|
tty_port_destroy(&state->tport);
|
||||||
|
|
||||||
free_irq(IRQ_AMIGA_TBE, state);
|
free_irq(IRQ_AMIGA_TBE, state);
|
||||||
free_irq(IRQ_AMIGA_RBF, state);
|
free_irq(IRQ_AMIGA_RBF, state);
|
||||||
|
|
|
@ -240,8 +240,6 @@ static int __init bfin_jc_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tty_port_init(&port);
|
|
||||||
|
|
||||||
bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME);
|
bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME);
|
||||||
if (IS_ERR(bfin_jc_kthread))
|
if (IS_ERR(bfin_jc_kthread))
|
||||||
return PTR_ERR(bfin_jc_kthread);
|
return PTR_ERR(bfin_jc_kthread);
|
||||||
|
@ -257,6 +255,8 @@ static int __init bfin_jc_init(void)
|
||||||
if (!bfin_jc_driver)
|
if (!bfin_jc_driver)
|
||||||
goto err_driver;
|
goto err_driver;
|
||||||
|
|
||||||
|
tty_port_init(&port);
|
||||||
|
|
||||||
bfin_jc_driver->driver_name = DRV_NAME;
|
bfin_jc_driver->driver_name = DRV_NAME;
|
||||||
bfin_jc_driver->name = DEV_NAME;
|
bfin_jc_driver->name = DEV_NAME;
|
||||||
bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||||
|
@ -274,6 +274,7 @@ static int __init bfin_jc_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
tty_port_destroy(&port);
|
||||||
put_tty_driver(bfin_jc_driver);
|
put_tty_driver(bfin_jc_driver);
|
||||||
err_driver:
|
err_driver:
|
||||||
kfree(bfin_jc_write_buf.buf);
|
kfree(bfin_jc_write_buf.buf);
|
||||||
|
@ -289,6 +290,7 @@ static void __exit bfin_jc_exit(void)
|
||||||
kfree(bfin_jc_write_buf.buf);
|
kfree(bfin_jc_write_buf.buf);
|
||||||
tty_unregister_driver(bfin_jc_driver);
|
tty_unregister_driver(bfin_jc_driver);
|
||||||
put_tty_driver(bfin_jc_driver);
|
put_tty_driver(bfin_jc_driver);
|
||||||
|
tty_port_destroy(&port);
|
||||||
}
|
}
|
||||||
module_exit(bfin_jc_exit);
|
module_exit(bfin_jc_exit);
|
||||||
|
|
||||||
|
|
|
@ -3099,7 +3099,7 @@ static const struct tty_port_operations cyz_port_ops = {
|
||||||
* ---------------------------------------------------------------------
|
* ---------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int __devinit cy_init_card(struct cyclades_card *cinfo)
|
static int cy_init_card(struct cyclades_card *cinfo)
|
||||||
{
|
{
|
||||||
struct cyclades_port *info;
|
struct cyclades_port *info;
|
||||||
unsigned int channel, port;
|
unsigned int channel, port;
|
||||||
|
@ -3196,7 +3196,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
|
||||||
|
|
||||||
/* initialize chips on Cyclom-Y card -- return number of valid
|
/* initialize chips on Cyclom-Y card -- return number of valid
|
||||||
chips (which is number of ports/4) */
|
chips (which is number of ports/4) */
|
||||||
static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
|
static unsigned short cyy_init_card(void __iomem *true_base_addr,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
unsigned int chip_number;
|
unsigned int chip_number;
|
||||||
|
@ -3405,7 +3405,7 @@ static int __init cy_detect_isa(void)
|
||||||
} /* cy_detect_isa */
|
} /* cy_detect_isa */
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
|
static inline int cyc_isfwstr(const char *str, unsigned int size)
|
||||||
{
|
{
|
||||||
unsigned int a;
|
unsigned int a;
|
||||||
|
|
||||||
|
@ -3420,7 +3420,7 @@ static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
|
static inline void cyz_fpga_copy(void __iomem *fpga, const u8 *data,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
for (; size > 0; size--) {
|
for (; size > 0; size--) {
|
||||||
|
@ -3429,7 +3429,7 @@ static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devinit plx_init(struct pci_dev *pdev, int irq,
|
static void plx_init(struct pci_dev *pdev, int irq,
|
||||||
struct RUNTIME_9060 __iomem *addr)
|
struct RUNTIME_9060 __iomem *addr)
|
||||||
{
|
{
|
||||||
/* Reset PLX */
|
/* Reset PLX */
|
||||||
|
@ -3449,7 +3449,7 @@ static void __devinit plx_init(struct pci_dev *pdev, int irq,
|
||||||
pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
|
pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit __cyz_load_fw(const struct firmware *fw,
|
static int __cyz_load_fw(const struct firmware *fw,
|
||||||
const char *name, const u32 mailbox, void __iomem *base,
|
const char *name, const u32 mailbox, void __iomem *base,
|
||||||
void __iomem *fpga)
|
void __iomem *fpga)
|
||||||
{
|
{
|
||||||
|
@ -3526,7 +3526,7 @@ static int __devinit __cyz_load_fw(const struct firmware *fw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
|
static int cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
|
||||||
struct RUNTIME_9060 __iomem *ctl_addr, int irq)
|
struct RUNTIME_9060 __iomem *ctl_addr, int irq)
|
||||||
{
|
{
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
|
@ -3692,7 +3692,7 @@ err:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit cy_pci_probe(struct pci_dev *pdev,
|
static int cy_pci_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
struct cyclades_card *card;
|
struct cyclades_card *card;
|
||||||
|
@ -3931,10 +3931,10 @@ err:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit cy_pci_remove(struct pci_dev *pdev)
|
static void cy_pci_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct cyclades_card *cinfo = pci_get_drvdata(pdev);
|
struct cyclades_card *cinfo = pci_get_drvdata(pdev);
|
||||||
unsigned int i;
|
unsigned int i, channel;
|
||||||
|
|
||||||
/* non-Z with old PLX */
|
/* non-Z with old PLX */
|
||||||
if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
|
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)
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
|
||||||
cinfo->base_addr = NULL;
|
cinfo->base_addr = NULL;
|
||||||
for (i = cinfo->first_line; i < cinfo->first_line +
|
for (channel = 0, i = cinfo->first_line; i < cinfo->first_line +
|
||||||
cinfo->nports; i++)
|
cinfo->nports; i++, channel++) {
|
||||||
tty_unregister_device(cy_serial_driver, i);
|
tty_unregister_device(cy_serial_driver, i);
|
||||||
|
tty_port_destroy(&cinfo->ports[channel].port);
|
||||||
|
}
|
||||||
cinfo->nports = 0;
|
cinfo->nports = 0;
|
||||||
kfree(cinfo->ports);
|
kfree(cinfo->ports);
|
||||||
}
|
}
|
||||||
|
@ -3971,7 +3973,7 @@ static struct pci_driver cy_pci_driver = {
|
||||||
.name = "cyclades",
|
.name = "cyclades",
|
||||||
.id_table = cy_pci_dev_id,
|
.id_table = cy_pci_dev_id,
|
||||||
.probe = cy_pci_probe,
|
.probe = cy_pci_probe,
|
||||||
.remove = __devexit_p(cy_pci_remove)
|
.remove = cy_pci_remove
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -699,7 +699,7 @@ static const struct tty_port_operations ehv_bc_tty_port_ops = {
|
||||||
.shutdown = ehv_bc_tty_port_shutdown,
|
.shutdown = ehv_bc_tty_port_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit ehv_bc_tty_probe(struct platform_device *pdev)
|
static int ehv_bc_tty_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct ehv_bc_data *bc;
|
struct ehv_bc_data *bc;
|
||||||
|
@ -757,6 +757,7 @@ static int __devinit ehv_bc_tty_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
tty_port_destroy(&bc->port);
|
||||||
irq_dispose_mapping(bc->tx_irq);
|
irq_dispose_mapping(bc->tx_irq);
|
||||||
irq_dispose_mapping(bc->rx_irq);
|
irq_dispose_mapping(bc->rx_irq);
|
||||||
|
|
||||||
|
@ -770,6 +771,7 @@ static int ehv_bc_tty_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
tty_unregister_device(ehv_bc_driver, bc - bcs);
|
tty_unregister_device(ehv_bc_driver, bc - bcs);
|
||||||
|
|
||||||
|
tty_port_destroy(&bc->port);
|
||||||
irq_dispose_mapping(bc->tx_irq);
|
irq_dispose_mapping(bc->tx_irq);
|
||||||
irq_dispose_mapping(bc->rx_irq);
|
irq_dispose_mapping(bc->rx_irq);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
static const char hvc_opal_name[] = "hvc_opal";
|
static const char hvc_opal_name[] = "hvc_opal";
|
||||||
|
|
||||||
static struct of_device_id hvc_opal_match[] __devinitdata = {
|
static struct of_device_id hvc_opal_match[] = {
|
||||||
{ .name = "serial", .compatible = "ibm,opal-console-raw" },
|
{ .name = "serial", .compatible = "ibm,opal-console-raw" },
|
||||||
{ .name = "serial", .compatible = "ibm,opal-console-hvsi" },
|
{ .name = "serial", .compatible = "ibm,opal-console-hvsi" },
|
||||||
{ },
|
{ },
|
||||||
|
@ -161,7 +161,7 @@ static const struct hv_ops hvc_opal_hvsi_ops = {
|
||||||
.tiocmset = hvc_opal_hvsi_tiocmset,
|
.tiocmset = hvc_opal_hvsi_tiocmset,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit hvc_opal_probe(struct platform_device *dev)
|
static int hvc_opal_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
const struct hv_ops *ops;
|
const struct hv_ops *ops;
|
||||||
struct hvc_struct *hp;
|
struct hvc_struct *hp;
|
||||||
|
@ -222,7 +222,7 @@ static int __devinit hvc_opal_probe(struct platform_device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit hvc_opal_remove(struct platform_device *dev)
|
static int hvc_opal_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct hvc_struct *hp = dev_get_drvdata(&dev->dev);
|
struct hvc_struct *hp = dev_get_drvdata(&dev->dev);
|
||||||
int rc, termno;
|
int rc, termno;
|
||||||
|
@ -239,7 +239,7 @@ static int __devexit hvc_opal_remove(struct platform_device *dev)
|
||||||
|
|
||||||
static struct platform_driver hvc_opal_driver = {
|
static struct platform_driver hvc_opal_driver = {
|
||||||
.probe = hvc_opal_probe,
|
.probe = hvc_opal_probe,
|
||||||
.remove = __devexit_p(hvc_opal_remove),
|
.remove = hvc_opal_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = hvc_opal_name,
|
.name = hvc_opal_name,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
static const char hvc_driver_name[] = "hvc_console";
|
static const char hvc_driver_name[] = "hvc_console";
|
||||||
|
|
||||||
static struct vio_device_id hvc_driver_table[] __devinitdata = {
|
static struct vio_device_id hvc_driver_table[] = {
|
||||||
{"serial", "hvterm1"},
|
{"serial", "hvterm1"},
|
||||||
#ifndef HVC_OLD_HVSI
|
#ifndef HVC_OLD_HVSI
|
||||||
{"serial", "hvterm-protocol"},
|
{"serial", "hvterm-protocol"},
|
||||||
|
@ -293,7 +293,7 @@ static int udbg_hvc_getc(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
|
static int hvc_vio_probe(struct vio_dev *vdev,
|
||||||
const struct vio_device_id *id)
|
const struct vio_device_id *id)
|
||||||
{
|
{
|
||||||
const struct hv_ops *ops;
|
const struct hv_ops *ops;
|
||||||
|
@ -362,7 +362,7 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit hvc_vio_remove(struct vio_dev *vdev)
|
static int hvc_vio_remove(struct vio_dev *vdev)
|
||||||
{
|
{
|
||||||
struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
|
struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
|
||||||
int rc, termno;
|
int rc, termno;
|
||||||
|
|
|
@ -422,7 +422,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit xencons_probe(struct xenbus_device *dev,
|
static int xencons_probe(struct xenbus_device *dev,
|
||||||
const struct xenbus_device_id *id)
|
const struct xenbus_device_id *id)
|
||||||
{
|
{
|
||||||
int ret, devid;
|
int ret, devid;
|
||||||
|
|
|
@ -330,12 +330,12 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp);
|
||||||
static void hvcs_close(struct tty_struct *tty, struct file *filp);
|
static void hvcs_close(struct tty_struct *tty, struct file *filp);
|
||||||
static void hvcs_hangup(struct tty_struct * tty);
|
static void hvcs_hangup(struct tty_struct * tty);
|
||||||
|
|
||||||
static int __devinit hvcs_probe(struct vio_dev *dev,
|
static int hvcs_probe(struct vio_dev *dev,
|
||||||
const struct vio_device_id *id);
|
const struct vio_device_id *id);
|
||||||
static int __devexit hvcs_remove(struct vio_dev *dev);
|
static int hvcs_remove(struct vio_dev *dev);
|
||||||
static int __init hvcs_module_init(void);
|
static int __init hvcs_module_init(void);
|
||||||
static void __exit hvcs_module_exit(void);
|
static void __exit hvcs_module_exit(void);
|
||||||
static int __devinit hvcs_initialize(void);
|
static int hvcs_initialize(void);
|
||||||
|
|
||||||
#define HVCS_SCHED_READ 0x00000001
|
#define HVCS_SCHED_READ 0x00000001
|
||||||
#define HVCS_QUICK_READ 0x00000002
|
#define HVCS_QUICK_READ 0x00000002
|
||||||
|
@ -676,7 +676,7 @@ static int khvcsd(void *unused)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vio_device_id hvcs_driver_table[] __devinitdata= {
|
static struct vio_device_id hvcs_driver_table[] = {
|
||||||
{"serial-server", "hvterm2"},
|
{"serial-server", "hvterm2"},
|
||||||
{ "", "" }
|
{ "", "" }
|
||||||
};
|
};
|
||||||
|
@ -756,7 +756,7 @@ static int hvcs_get_index(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit hvcs_probe(
|
static int hvcs_probe(
|
||||||
struct vio_dev *dev,
|
struct vio_dev *dev,
|
||||||
const struct vio_device_id *id)
|
const struct vio_device_id *id)
|
||||||
{
|
{
|
||||||
|
@ -835,7 +835,7 @@ static int __devinit hvcs_probe(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit hvcs_remove(struct vio_dev *dev)
|
static int hvcs_remove(struct vio_dev *dev)
|
||||||
{
|
{
|
||||||
struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
|
struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -874,7 +874,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
|
||||||
static struct vio_driver hvcs_vio_driver = {
|
static struct vio_driver hvcs_vio_driver = {
|
||||||
.id_table = hvcs_driver_table,
|
.id_table = hvcs_driver_table,
|
||||||
.probe = hvcs_probe,
|
.probe = hvcs_probe,
|
||||||
.remove = __devexit_p(hvcs_remove),
|
.remove = hvcs_remove,
|
||||||
.name = hvcs_driver_name,
|
.name = hvcs_driver_name,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1478,7 +1478,7 @@ static void hvcs_free_index_list(void)
|
||||||
hvcs_index_count = 0;
|
hvcs_index_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit hvcs_initialize(void)
|
static int hvcs_initialize(void)
|
||||||
{
|
{
|
||||||
int rc, num_ttys_to_alloc;
|
int rc, num_ttys_to_alloc;
|
||||||
|
|
||||||
|
@ -1496,8 +1496,10 @@ static int __devinit hvcs_initialize(void)
|
||||||
num_ttys_to_alloc = hvcs_parm_num_devs;
|
num_ttys_to_alloc = hvcs_parm_num_devs;
|
||||||
|
|
||||||
hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc);
|
hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc);
|
||||||
if (!hvcs_tty_driver)
|
if (!hvcs_tty_driver) {
|
||||||
|
mutex_unlock(&hvcs_init_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
|
if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
|
|
|
@ -1218,6 +1218,7 @@ static int __init hvsi_console_init(void)
|
||||||
if (hp->virq == 0) {
|
if (hp->virq == 0) {
|
||||||
printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
|
printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
|
||||||
__func__, irq[0]);
|
__func__, irq[0]);
|
||||||
|
tty_port_destroy(&hp->port);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,6 +352,8 @@ static struct sk_buff *ipw_packet_received_skb(unsigned char *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
skb = dev_alloc_skb(length + 4);
|
skb = dev_alloc_skb(length + 4);
|
||||||
|
if (skb == NULL)
|
||||||
|
return NULL;
|
||||||
skb_reserve(skb, 2);
|
skb_reserve(skb, 2);
|
||||||
memcpy(skb_put(skb, length), data, length);
|
memcpy(skb_put(skb, length), data, length);
|
||||||
|
|
||||||
|
@ -397,7 +399,8 @@ void ipwireless_network_packet_received(struct ipw_network *network,
|
||||||
|
|
||||||
/* Send the data to the ppp_generic module. */
|
/* Send the data to the ppp_generic module. */
|
||||||
skb = ipw_packet_received_skb(data, length);
|
skb = ipw_packet_received_skb(data, length);
|
||||||
ppp_input(network->ppp_channel, skb);
|
if (skb)
|
||||||
|
ppp_input(network->ppp_channel, skb);
|
||||||
} else
|
} else
|
||||||
spin_unlock_irqrestore(&network->lock,
|
spin_unlock_irqrestore(&network->lock,
|
||||||
flags);
|
flags);
|
||||||
|
|
|
@ -566,6 +566,7 @@ void ipwireless_tty_free(struct ipw_tty *tty)
|
||||||
ipwireless_disassociate_network_ttys(network,
|
ipwireless_disassociate_network_ttys(network,
|
||||||
ttyj->channel_idx);
|
ttyj->channel_idx);
|
||||||
tty_unregister_device(ipw_tty_driver, j);
|
tty_unregister_device(ipw_tty_driver, j);
|
||||||
|
tty_port_destroy(&ttyj->port);
|
||||||
ttys[j] = NULL;
|
ttys[j] = NULL;
|
||||||
mutex_unlock(&ttyj->ipw_tty_mutex);
|
mutex_unlock(&ttyj->ipw_tty_mutex);
|
||||||
kfree(ttyj);
|
kfree(ttyj);
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
|
static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
|
||||||
static void __devexit isicom_remove(struct pci_dev *);
|
static void isicom_remove(struct pci_dev *);
|
||||||
|
|
||||||
static struct pci_device_id isicom_pci_tbl[] = {
|
static struct pci_device_id isicom_pci_tbl[] = {
|
||||||
{ PCI_DEVICE(VENDOR_ID, 0x2028) },
|
{ PCI_DEVICE(VENDOR_ID, 0x2028) },
|
||||||
|
@ -168,7 +168,7 @@ static struct pci_driver isicom_driver = {
|
||||||
.name = "isicom",
|
.name = "isicom",
|
||||||
.id_table = isicom_pci_tbl,
|
.id_table = isicom_pci_tbl,
|
||||||
.probe = isicom_probe,
|
.probe = isicom_probe,
|
||||||
.remove = __devexit_p(isicom_remove)
|
.remove = isicom_remove
|
||||||
};
|
};
|
||||||
|
|
||||||
static int prev_card = 3; /* start servicing isi_card[0] */
|
static int prev_card = 3; /* start servicing isi_card[0] */
|
||||||
|
@ -603,7 +603,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
|
||||||
if (tty_port_cts_enabled(&port->port)) {
|
if (tty_port_cts_enabled(&port->port)) {
|
||||||
if (tty->hw_stopped) {
|
if (tty->hw_stopped) {
|
||||||
if (header & ISI_CTS) {
|
if (header & ISI_CTS) {
|
||||||
port->port.tty->hw_stopped = 0;
|
tty->hw_stopped = 0;
|
||||||
/* start tx ing */
|
/* start tx ing */
|
||||||
port->status |= (ISI_TXOK
|
port->status |= (ISI_TXOK
|
||||||
| ISI_CTS);
|
| ISI_CTS);
|
||||||
|
@ -1307,7 +1307,7 @@ static const struct tty_port_operations isicom_port_ops = {
|
||||||
.shutdown = isicom_shutdown,
|
.shutdown = isicom_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit reset_card(struct pci_dev *pdev,
|
static int reset_card(struct pci_dev *pdev,
|
||||||
const unsigned int card, unsigned int *signature)
|
const unsigned int card, unsigned int *signature)
|
||||||
{
|
{
|
||||||
struct isi_board *board = pci_get_drvdata(pdev);
|
struct isi_board *board = pci_get_drvdata(pdev);
|
||||||
|
@ -1368,7 +1368,7 @@ end:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit load_firmware(struct pci_dev *pdev,
|
static int load_firmware(struct pci_dev *pdev,
|
||||||
const unsigned int index, const unsigned int signature)
|
const unsigned int index, const unsigned int signature)
|
||||||
{
|
{
|
||||||
struct isi_board *board = pci_get_drvdata(pdev);
|
struct isi_board *board = pci_get_drvdata(pdev);
|
||||||
|
@ -1548,7 +1548,7 @@ end:
|
||||||
*/
|
*/
|
||||||
static unsigned int card_count;
|
static unsigned int card_count;
|
||||||
|
|
||||||
static int __devinit isicom_probe(struct pci_dev *pdev,
|
static int isicom_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
unsigned int uninitialized_var(signature), index;
|
unsigned int uninitialized_var(signature), index;
|
||||||
|
@ -1610,10 +1610,15 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto errunri;
|
goto errunri;
|
||||||
|
|
||||||
for (index = 0; index < board->port_count; index++)
|
for (index = 0; index < board->port_count; index++) {
|
||||||
tty_port_register_device(&board->ports[index].port,
|
struct tty_port *tport = &board->ports[index].port;
|
||||||
isicom_normal, board->index * 16 + index,
|
tty_port_init(tport);
|
||||||
&pdev->dev);
|
tport->ops = &isicom_port_ops;
|
||||||
|
tport->close_delay = 50 * HZ/100;
|
||||||
|
tport->closing_wait = 3000 * HZ/100;
|
||||||
|
tty_port_register_device(tport, isicom_normal,
|
||||||
|
board->index * 16 + index, &pdev->dev);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1630,13 +1635,15 @@ err:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit isicom_remove(struct pci_dev *pdev)
|
static void isicom_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct isi_board *board = pci_get_drvdata(pdev);
|
struct isi_board *board = pci_get_drvdata(pdev);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < board->port_count; i++)
|
for (i = 0; i < board->port_count; i++) {
|
||||||
tty_unregister_device(isicom_normal, board->index * 16 + i);
|
tty_unregister_device(isicom_normal, board->index * 16 + i);
|
||||||
|
tty_port_destroy(&board->ports[i].port);
|
||||||
|
}
|
||||||
|
|
||||||
free_irq(board->irq, board);
|
free_irq(board->irq, board);
|
||||||
pci_release_region(pdev, 3);
|
pci_release_region(pdev, 3);
|
||||||
|
@ -1655,13 +1662,9 @@ static int __init isicom_init(void)
|
||||||
isi_card[idx].ports = port;
|
isi_card[idx].ports = port;
|
||||||
spin_lock_init(&isi_card[idx].card_lock);
|
spin_lock_init(&isi_card[idx].card_lock);
|
||||||
for (channel = 0; channel < 16; channel++, port++) {
|
for (channel = 0; channel < 16; channel++, port++) {
|
||||||
tty_port_init(&port->port);
|
|
||||||
port->port.ops = &isicom_port_ops;
|
|
||||||
port->magic = ISICOM_MAGIC;
|
port->magic = ISICOM_MAGIC;
|
||||||
port->card = &isi_card[idx];
|
port->card = &isi_card[idx];
|
||||||
port->channel = channel;
|
port->channel = channel;
|
||||||
port->port.close_delay = 50 * HZ/100;
|
|
||||||
port->port.closing_wait = 3000 * HZ/100;
|
|
||||||
port->status = 0;
|
port->status = 0;
|
||||||
/* . . . */
|
/* . . . */
|
||||||
}
|
}
|
||||||
|
|
|
@ -895,6 +895,8 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_free:
|
err_free:
|
||||||
|
for (i = 0; i < MAX_PORTS_PER_BOARD; i++)
|
||||||
|
tty_port_destroy(&brd->ports[i].port);
|
||||||
kfree(brd->ports);
|
kfree(brd->ports);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -919,6 +921,8 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
|
||||||
tty_kref_put(tty);
|
tty_kref_put(tty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (a = 0; a < MAX_PORTS_PER_BOARD; a++)
|
||||||
|
tty_port_destroy(&brd->ports[a].port);
|
||||||
while (1) {
|
while (1) {
|
||||||
opened = 0;
|
opened = 0;
|
||||||
for (a = 0; a < brd->numPorts; a++)
|
for (a = 0; a < brd->numPorts; a++)
|
||||||
|
@ -941,7 +945,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static int __devinit moxa_pci_probe(struct pci_dev *pdev,
|
static int moxa_pci_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
struct moxa_board_conf *board;
|
struct moxa_board_conf *board;
|
||||||
|
@ -1016,7 +1020,7 @@ err:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit moxa_pci_remove(struct pci_dev *pdev)
|
static void moxa_pci_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct moxa_board_conf *brd = pci_get_drvdata(pdev);
|
struct moxa_board_conf *brd = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -1029,7 +1033,7 @@ static struct pci_driver moxa_pci_driver = {
|
||||||
.name = "moxa",
|
.name = "moxa",
|
||||||
.id_table = moxa_pcibrds,
|
.id_table = moxa_pcibrds,
|
||||||
.probe = moxa_pci_probe,
|
.probe = moxa_pci_probe,
|
||||||
.remove = __devexit_p(moxa_pci_remove)
|
.remove = moxa_pci_remove
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
|
|
||||||
|
@ -1370,7 +1374,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
|
||||||
p->DCDState = dcd;
|
p->DCDState = dcd;
|
||||||
spin_unlock_irqrestore(&p->port.lock, flags);
|
spin_unlock_irqrestore(&p->port.lock, flags);
|
||||||
tty = tty_port_tty_get(&p->port);
|
tty = tty_port_tty_get(&p->port);
|
||||||
if (tty && C_CLOCAL(tty) && !dcd)
|
if (tty && !C_CLOCAL(tty) && !dcd)
|
||||||
tty_hangup(tty);
|
tty_hangup(tty);
|
||||||
tty_kref_put(tty);
|
tty_kref_put(tty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,7 +487,7 @@ static void mxser_disable_must_rx_software_flow_control(unsigned long baseio)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static int __devinit CheckIsMoxaMust(unsigned long io)
|
static int CheckIsMoxaMust(unsigned long io)
|
||||||
{
|
{
|
||||||
u8 oldmcr, hwid;
|
u8 oldmcr, hwid;
|
||||||
int i;
|
int i;
|
||||||
|
@ -2369,7 +2369,7 @@ static void mxser_release_ISA_res(struct mxser_board *brd)
|
||||||
mxser_release_vector(brd);
|
mxser_release_vector(brd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit mxser_initbrd(struct mxser_board *brd,
|
static int mxser_initbrd(struct mxser_board *brd,
|
||||||
struct pci_dev *pdev)
|
struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct mxser_port *info;
|
struct mxser_port *info;
|
||||||
|
@ -2411,14 +2411,27 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
|
||||||
|
|
||||||
retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
|
retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
|
||||||
brd);
|
brd);
|
||||||
if (retval)
|
if (retval) {
|
||||||
|
for (i = 0; i < brd->info->nports; i++)
|
||||||
|
tty_port_destroy(&brd->ports[i].port);
|
||||||
printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
|
printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
|
||||||
"conflict with another device.\n",
|
"conflict with another device.\n",
|
||||||
brd->info->name, brd->irq);
|
brd->info->name, brd->irq);
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mxser_board_remove(struct mxser_board *brd)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < brd->info->nports; i++) {
|
||||||
|
tty_unregister_device(mxvar_sdriver, brd->idx + i);
|
||||||
|
tty_port_destroy(&brd->ports[i].port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
|
static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
|
||||||
{
|
{
|
||||||
int id, i, bits, ret;
|
int id, i, bits, ret;
|
||||||
|
@ -2534,7 +2547,7 @@ err_irqconflict:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit mxser_probe(struct pci_dev *pdev,
|
static int mxser_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
|
@ -2645,14 +2658,12 @@ err:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit mxser_remove(struct pci_dev *pdev)
|
static void mxser_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
struct mxser_board *brd = pci_get_drvdata(pdev);
|
struct mxser_board *brd = pci_get_drvdata(pdev);
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < brd->info->nports; i++)
|
mxser_board_remove(brd);
|
||||||
tty_unregister_device(mxvar_sdriver, brd->idx + i);
|
|
||||||
|
|
||||||
free_irq(pdev->irq, brd);
|
free_irq(pdev->irq, brd);
|
||||||
pci_release_region(pdev, 2);
|
pci_release_region(pdev, 2);
|
||||||
|
@ -2666,7 +2677,7 @@ static struct pci_driver mxser_driver = {
|
||||||
.name = "mxser",
|
.name = "mxser",
|
||||||
.id_table = mxser_pcibrds,
|
.id_table = mxser_pcibrds,
|
||||||
.probe = mxser_probe,
|
.probe = mxser_probe,
|
||||||
.remove = __devexit_p(mxser_remove)
|
.remove = mxser_remove
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init mxser_module_init(void)
|
static int __init mxser_module_init(void)
|
||||||
|
@ -2748,15 +2759,13 @@ err_put:
|
||||||
|
|
||||||
static void __exit mxser_module_exit(void)
|
static void __exit mxser_module_exit(void)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i;
|
||||||
|
|
||||||
pci_unregister_driver(&mxser_driver);
|
pci_unregister_driver(&mxser_driver);
|
||||||
|
|
||||||
for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */
|
for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */
|
||||||
if (mxser_boards[i].info != NULL)
|
if (mxser_boards[i].info != NULL)
|
||||||
for (j = 0; j < mxser_boards[i].info->nports; j++)
|
mxser_board_remove(&mxser_boards[i]);
|
||||||
tty_unregister_device(mxvar_sdriver,
|
|
||||||
mxser_boards[i].idx + j);
|
|
||||||
tty_unregister_driver(mxvar_sdriver);
|
tty_unregister_driver(mxvar_sdriver);
|
||||||
put_tty_driver(mxvar_sdriver);
|
put_tty_driver(mxvar_sdriver);
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,6 @@ struct gsm_dlci {
|
||||||
#define DLCI_OPENING 1 /* Sending SABM not seen UA */
|
#define DLCI_OPENING 1 /* Sending SABM not seen UA */
|
||||||
#define DLCI_OPEN 2 /* SABM/UA complete */
|
#define DLCI_OPEN 2 /* SABM/UA complete */
|
||||||
#define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */
|
#define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */
|
||||||
struct kref ref; /* freed from port or mux close */
|
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
|
|
||||||
/* Link layer */
|
/* Link layer */
|
||||||
|
@ -1635,7 +1634,6 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
|
||||||
if (dlci == NULL)
|
if (dlci == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
spin_lock_init(&dlci->lock);
|
spin_lock_init(&dlci->lock);
|
||||||
kref_init(&dlci->ref);
|
|
||||||
mutex_init(&dlci->mutex);
|
mutex_init(&dlci->mutex);
|
||||||
dlci->fifo = &dlci->_fifo;
|
dlci->fifo = &dlci->_fifo;
|
||||||
if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
|
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)
|
||||||
*
|
*
|
||||||
* Can sleep.
|
* Can sleep.
|
||||||
*/
|
*/
|
||||||
static void gsm_dlci_free(struct kref *ref)
|
static void gsm_dlci_free(struct tty_port *port)
|
||||||
{
|
{
|
||||||
struct gsm_dlci *dlci = container_of(ref, struct gsm_dlci, ref);
|
struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
|
||||||
|
|
||||||
del_timer_sync(&dlci->t1);
|
del_timer_sync(&dlci->t1);
|
||||||
dlci->gsm->dlci[dlci->addr] = NULL;
|
dlci->gsm->dlci[dlci->addr] = NULL;
|
||||||
|
@ -1683,12 +1681,12 @@ static void gsm_dlci_free(struct kref *ref)
|
||||||
|
|
||||||
static inline void dlci_get(struct gsm_dlci *dlci)
|
static inline void dlci_get(struct gsm_dlci *dlci)
|
||||||
{
|
{
|
||||||
kref_get(&dlci->ref);
|
tty_port_get(&dlci->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dlci_put(struct gsm_dlci *dlci)
|
static inline void dlci_put(struct gsm_dlci *dlci)
|
||||||
{
|
{
|
||||||
kref_put(&dlci->ref, gsm_dlci_free);
|
tty_port_put(&dlci->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2874,6 +2872,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff)
|
||||||
static const struct tty_port_operations gsm_port_ops = {
|
static const struct tty_port_operations gsm_port_ops = {
|
||||||
.carrier_raised = gsm_carrier_raised,
|
.carrier_raised = gsm_carrier_raised,
|
||||||
.dtr_rts = gsm_dtr_rts,
|
.dtr_rts = gsm_dtr_rts,
|
||||||
|
.destruct = gsm_dlci_free,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty)
|
static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -400,7 +400,7 @@ struct buffer {
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = {
|
static const struct pci_device_id nozomi_pci_tbl[] = {
|
||||||
{PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */
|
{PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
@ -1360,7 +1360,7 @@ static void remove_sysfs_files(struct nozomi *dc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for one device */
|
/* Allocate memory for one device */
|
||||||
static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
static int nozomi_card_init(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
resource_size_t start;
|
resource_size_t start;
|
||||||
|
@ -1479,6 +1479,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
||||||
if (IS_ERR(tty_dev)) {
|
if (IS_ERR(tty_dev)) {
|
||||||
ret = PTR_ERR(tty_dev);
|
ret = PTR_ERR(tty_dev);
|
||||||
dev_err(&pdev->dev, "Could not allocate tty?\n");
|
dev_err(&pdev->dev, "Could not allocate tty?\n");
|
||||||
|
tty_port_destroy(&port->port);
|
||||||
goto err_free_tty;
|
goto err_free_tty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1486,8 +1487,10 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_tty:
|
err_free_tty:
|
||||||
for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
|
for (i = 0; i < MAX_PORT; ++i) {
|
||||||
tty_unregister_device(ntty_driver, i);
|
tty_unregister_device(ntty_driver, dc->index_start + i);
|
||||||
|
tty_port_destroy(&dc->port[i].port);
|
||||||
|
}
|
||||||
err_free_kfifo:
|
err_free_kfifo:
|
||||||
for (i = 0; i < MAX_PORT; i++)
|
for (i = 0; i < MAX_PORT; i++)
|
||||||
kfifo_free(&dc->port[i].fifo_ul);
|
kfifo_free(&dc->port[i].fifo_ul);
|
||||||
|
@ -1504,7 +1507,7 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit tty_exit(struct nozomi *dc)
|
static void tty_exit(struct nozomi *dc)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -1520,12 +1523,14 @@ static void __devexit tty_exit(struct nozomi *dc)
|
||||||
complete off a hangup method ? */
|
complete off a hangup method ? */
|
||||||
while (dc->open_ttys)
|
while (dc->open_ttys)
|
||||||
msleep(1);
|
msleep(1);
|
||||||
for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
|
for (i = 0; i < MAX_PORT; ++i) {
|
||||||
tty_unregister_device(ntty_driver, i);
|
tty_unregister_device(ntty_driver, dc->index_start + i);
|
||||||
|
tty_port_destroy(&dc->port[i].port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deallocate memory for one device */
|
/* Deallocate memory for one device */
|
||||||
static void __devexit nozomi_card_exit(struct pci_dev *pdev)
|
static void nozomi_card_exit(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct ctrl_ul ctrl;
|
struct ctrl_ul ctrl;
|
||||||
|
@ -1903,7 +1908,7 @@ static struct pci_driver nozomi_driver = {
|
||||||
.name = NOZOMI_NAME,
|
.name = NOZOMI_NAME,
|
||||||
.id_table = nozomi_pci_tbl,
|
.id_table = nozomi_pci_tbl,
|
||||||
.probe = nozomi_card_init,
|
.probe = nozomi_card_init,
|
||||||
.remove = __devexit_p(nozomi_card_exit),
|
.remove = nozomi_card_exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int nozomi_init(void)
|
static __init int nozomi_init(void)
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
* Added support for a Unix98-style ptmx device.
|
* Added support for a Unix98-style ptmx device.
|
||||||
* -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
|
* -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
|
||||||
*
|
*
|
||||||
* When reading this code see also fs/devpts. In particular note that the
|
|
||||||
* driver_data field is used by the devpts side as a binding to the devpts
|
|
||||||
* inode.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
|
||||||
#ifdef CONFIG_UNIX98_PTYS
|
#ifdef CONFIG_UNIX98_PTYS
|
||||||
if (tty->driver == ptm_driver) {
|
if (tty->driver == ptm_driver) {
|
||||||
mutex_lock(&devpts_mutex);
|
mutex_lock(&devpts_mutex);
|
||||||
devpts_pty_kill(tty->link);
|
devpts_pty_kill(tty->link->driver_data);
|
||||||
mutex_unlock(&devpts_mutex);
|
mutex_unlock(&devpts_mutex);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty)
|
||||||
|
|
||||||
static int pty_space(struct tty_struct *to)
|
static int pty_space(struct tty_struct *to)
|
||||||
{
|
{
|
||||||
int n = 8192 - to->buf.memory_used;
|
int n = 8192 - to->port->buf.memory_used;
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return 0;
|
return 0;
|
||||||
return n;
|
return n;
|
||||||
|
@ -174,6 +171,41 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pty_get_lock(struct tty_struct *tty, int __user *arg)
|
||||||
|
{
|
||||||
|
int locked = test_bit(TTY_PTY_LOCK, &tty->flags);
|
||||||
|
return put_user(locked, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the packet mode on a pty */
|
||||||
|
static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int pktmode;
|
||||||
|
|
||||||
|
if (get_user(pktmode, arg))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tty->ctrl_lock, flags);
|
||||||
|
if (pktmode) {
|
||||||
|
if (!tty->packet) {
|
||||||
|
tty->packet = 1;
|
||||||
|
tty->link->ctrl_status = 0;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
tty->packet = 0;
|
||||||
|
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the packet mode of a pty */
|
||||||
|
static int pty_get_pktmode(struct tty_struct *tty, int __user *arg)
|
||||||
|
{
|
||||||
|
int pktmode = tty->packet;
|
||||||
|
return put_user(pktmode, arg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send a signal to the slave */
|
/* Send a signal to the slave */
|
||||||
static int pty_signal(struct tty_struct *tty, int sig)
|
static int pty_signal(struct tty_struct *tty, int sig)
|
||||||
{
|
{
|
||||||
|
@ -245,7 +277,7 @@ static void pty_set_termios(struct tty_struct *tty,
|
||||||
* peform a terminal resize correctly
|
* peform a terminal resize correctly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int pty_resize(struct tty_struct *tty, struct winsize *ws)
|
static int pty_resize(struct tty_struct *tty, struct winsize *ws)
|
||||||
{
|
{
|
||||||
struct pid *pgrp, *rpgrp;
|
struct pid *pgrp, *rpgrp;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -348,6 +380,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
|
||||||
tty_port_init(ports[1]);
|
tty_port_init(ports[1]);
|
||||||
o_tty->port = ports[0];
|
o_tty->port = ports[0];
|
||||||
tty->port = ports[1];
|
tty->port = ports[1];
|
||||||
|
o_tty->port->itty = o_tty;
|
||||||
|
|
||||||
tty_driver_kref_get(driver);
|
tty_driver_kref_get(driver);
|
||||||
tty->count++;
|
tty->count++;
|
||||||
|
@ -366,9 +399,16 @@ err:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this is called once with whichever end is closed last */
|
||||||
|
static void pty_unix98_shutdown(struct tty_struct *tty)
|
||||||
|
{
|
||||||
|
devpts_kill_index(tty->driver_data, tty->index);
|
||||||
|
}
|
||||||
|
|
||||||
static void pty_cleanup(struct tty_struct *tty)
|
static void pty_cleanup(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
kfree(tty->port);
|
tty->port->itty = NULL;
|
||||||
|
tty_port_put(tty->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Traditional BSD devices */
|
/* Traditional BSD devices */
|
||||||
|
@ -393,6 +433,12 @@ static int pty_bsd_ioctl(struct tty_struct *tty,
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
|
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
|
||||||
return pty_set_lock(tty, (int __user *) arg);
|
return pty_set_lock(tty, (int __user *) arg);
|
||||||
|
case TIOCGPTLCK: /* Get PT Lock status */
|
||||||
|
return pty_get_lock(tty, (int __user *)arg);
|
||||||
|
case TIOCPKT: /* Set PT packet mode */
|
||||||
|
return pty_set_pktmode(tty, (int __user *)arg);
|
||||||
|
case TIOCGPKT: /* Get PT packet mode */
|
||||||
|
return pty_get_pktmode(tty, (int __user *)arg);
|
||||||
case TIOCSIG: /* Send signal to other side of pty */
|
case TIOCSIG: /* Send signal to other side of pty */
|
||||||
return pty_signal(tty, (int) arg);
|
return pty_signal(tty, (int) arg);
|
||||||
}
|
}
|
||||||
|
@ -507,6 +553,12 @@ static int pty_unix98_ioctl(struct tty_struct *tty,
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
|
case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
|
||||||
return pty_set_lock(tty, (int __user *)arg);
|
return pty_set_lock(tty, (int __user *)arg);
|
||||||
|
case TIOCGPTLCK: /* Get PT Lock status */
|
||||||
|
return pty_get_lock(tty, (int __user *)arg);
|
||||||
|
case TIOCPKT: /* Set PT packet mode */
|
||||||
|
return pty_set_pktmode(tty, (int __user *)arg);
|
||||||
|
case TIOCGPKT: /* Get PT packet mode */
|
||||||
|
return pty_get_pktmode(tty, (int __user *)arg);
|
||||||
case TIOCGPTN: /* Get PT Number */
|
case TIOCGPTN: /* Get PT Number */
|
||||||
return put_user(tty->index, (unsigned int __user *)arg);
|
return put_user(tty->index, (unsigned int __user *)arg);
|
||||||
case TIOCSIG: /* Send signal to other side of pty */
|
case TIOCSIG: /* Send signal to other side of pty */
|
||||||
|
@ -547,7 +599,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
|
|
||||||
mutex_lock(&devpts_mutex);
|
mutex_lock(&devpts_mutex);
|
||||||
tty = devpts_get_tty(pts_inode, idx);
|
tty = devpts_get_priv(pts_inode);
|
||||||
mutex_unlock(&devpts_mutex);
|
mutex_unlock(&devpts_mutex);
|
||||||
/* Master must be open before slave */
|
/* Master must be open before slave */
|
||||||
if (!tty)
|
if (!tty)
|
||||||
|
@ -581,6 +633,7 @@ static const struct tty_operations ptm_unix98_ops = {
|
||||||
.set_termios = pty_set_termios,
|
.set_termios = pty_set_termios,
|
||||||
.ioctl = pty_unix98_ioctl,
|
.ioctl = pty_unix98_ioctl,
|
||||||
.resize = pty_resize,
|
.resize = pty_resize,
|
||||||
|
.shutdown = pty_unix98_shutdown,
|
||||||
.cleanup = pty_cleanup
|
.cleanup = pty_cleanup
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -596,6 +649,7 @@ static const struct tty_operations pty_unix98_ops = {
|
||||||
.chars_in_buffer = pty_chars_in_buffer,
|
.chars_in_buffer = pty_chars_in_buffer,
|
||||||
.unthrottle = pty_unthrottle,
|
.unthrottle = pty_unthrottle,
|
||||||
.set_termios = pty_set_termios,
|
.set_termios = pty_set_termios,
|
||||||
|
.shutdown = pty_unix98_shutdown,
|
||||||
.cleanup = pty_cleanup,
|
.cleanup = pty_cleanup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -614,6 +668,7 @@ static const struct tty_operations pty_unix98_ops = {
|
||||||
static int ptmx_open(struct inode *inode, struct file *filp)
|
static int ptmx_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
|
struct inode *slave_inode;
|
||||||
int retval;
|
int retval;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
@ -650,15 +705,21 @@ static int ptmx_open(struct inode *inode, struct file *filp)
|
||||||
|
|
||||||
tty_add_file(tty, filp);
|
tty_add_file(tty, filp);
|
||||||
|
|
||||||
retval = devpts_pty_new(inode, tty->link);
|
slave_inode = devpts_pty_new(inode,
|
||||||
if (retval)
|
MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index,
|
||||||
|
tty->link);
|
||||||
|
if (IS_ERR(slave_inode)) {
|
||||||
|
retval = PTR_ERR(slave_inode);
|
||||||
goto err_release;
|
goto err_release;
|
||||||
|
}
|
||||||
|
|
||||||
retval = ptm_driver->ops->open(tty, filp);
|
retval = ptm_driver->ops->open(tty, filp);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto err_release;
|
goto err_release;
|
||||||
|
|
||||||
tty_unlock(tty);
|
tty_unlock(tty);
|
||||||
|
tty->driver_data = inode;
|
||||||
|
tty->link->driver_data = slave_inode;
|
||||||
return 0;
|
return 0;
|
||||||
err_release:
|
err_release:
|
||||||
tty_unlock(tty);
|
tty_unlock(tty);
|
||||||
|
|
|
@ -673,6 +673,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
|
||||||
if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
|
if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
|
||||||
printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
|
printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
|
||||||
board, aiop, chan);
|
board, aiop, chan);
|
||||||
|
tty_port_destroy(&info->port);
|
||||||
kfree(info);
|
kfree(info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1757,7 +1758,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
|
|
||||||
static struct pci_device_id __devinitdata __used rocket_pci_ids[] = {
|
static struct pci_device_id __used rocket_pci_ids[] = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -2357,6 +2358,7 @@ static void rp_cleanup_module(void)
|
||||||
for (i = 0; i < MAX_RP_PORTS; i++)
|
for (i = 0; i < MAX_RP_PORTS; i++)
|
||||||
if (rp_table[i]) {
|
if (rp_table[i]) {
|
||||||
tty_unregister_device(rocket_driver, i);
|
tty_unregister_device(rocket_driver, i);
|
||||||
|
tty_port_destroy(&rp_table[i]->port);
|
||||||
kfree(rp_table[i]);
|
kfree(rp_table[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1225,6 +1225,8 @@ rs68328_init(void)
|
||||||
|
|
||||||
if (tty_register_driver(serial_driver)) {
|
if (tty_register_driver(serial_driver)) {
|
||||||
put_tty_driver(serial_driver);
|
put_tty_driver(serial_driver);
|
||||||
|
for (i = 0; i < NR_PORTS; i++)
|
||||||
|
tty_port_destroy(&m68k_soft[i].tport);
|
||||||
printk(KERN_ERR "Couldn't register serial driver\n");
|
printk(KERN_ERR "Couldn't register serial driver\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,7 +280,17 @@ static const struct serial8250_config uart_config[] = {
|
||||||
.fifo_size = 64,
|
.fifo_size = 64,
|
||||||
.tx_loadsz = 64,
|
.tx_loadsz = 64,
|
||||||
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
|
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
|
||||||
.flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
|
.flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
|
||||||
|
UART_CAP_SLEEP,
|
||||||
|
},
|
||||||
|
[PORT_XR17V35X] = {
|
||||||
|
.name = "XR17V35X",
|
||||||
|
.fifo_size = 256,
|
||||||
|
.tx_loadsz = 256,
|
||||||
|
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 |
|
||||||
|
UART_FCR_T_TRIG_11,
|
||||||
|
.flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
|
||||||
|
UART_CAP_SLEEP,
|
||||||
},
|
},
|
||||||
[PORT_LPC3220] = {
|
[PORT_LPC3220] = {
|
||||||
.name = "LPC3220",
|
.name = "LPC3220",
|
||||||
|
@ -455,6 +465,7 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serial8250_default_handle_irq(struct uart_port *port);
|
static int serial8250_default_handle_irq(struct uart_port *port);
|
||||||
|
static int exar_handle_irq(struct uart_port *port);
|
||||||
|
|
||||||
static void set_io_from_upio(struct uart_port *p)
|
static void set_io_from_upio(struct uart_port *p)
|
||||||
{
|
{
|
||||||
|
@ -574,6 +585,19 @@ EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
|
||||||
*/
|
*/
|
||||||
static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
|
static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Exar UARTs have a SLEEP register that enables or disables
|
||||||
|
* each UART to enter sleep mode separately. On the XR17V35x the
|
||||||
|
* register is accessible to each UART at the UART_EXAR_SLEEP
|
||||||
|
* offset but the UART channel may only write to the corresponding
|
||||||
|
* bit.
|
||||||
|
*/
|
||||||
|
if ((p->port.type == PORT_XR17V35X) ||
|
||||||
|
(p->port.type == PORT_XR17D15X)) {
|
||||||
|
serial_out(p, UART_EXAR_SLEEP, 0xff);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->capabilities & UART_CAP_SLEEP) {
|
if (p->capabilities & UART_CAP_SLEEP) {
|
||||||
if (p->capabilities & UART_CAP_EFR) {
|
if (p->capabilities & UART_CAP_EFR) {
|
||||||
serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
|
serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
|
||||||
|
@ -881,6 +905,27 @@ static void autoconfig_16550a(struct uart_8250_port *up)
|
||||||
up->port.type = PORT_16550A;
|
up->port.type = PORT_16550A;
|
||||||
up->capabilities |= UART_CAP_FIFO;
|
up->capabilities |= UART_CAP_FIFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XR17V35x UARTs have an extra divisor register, DLD
|
||||||
|
* that gets enabled with when DLAB is set which will
|
||||||
|
* cause the device to incorrectly match and assign
|
||||||
|
* port type to PORT_16650. The EFR for this UART is
|
||||||
|
* found at offset 0x09. Instead check the Deice ID (DVID)
|
||||||
|
* register for a 2, 4 or 8 port UART.
|
||||||
|
*/
|
||||||
|
if (up->port.flags & UPF_EXAR_EFR) {
|
||||||
|
status1 = serial_in(up, UART_EXAR_DVID);
|
||||||
|
if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) {
|
||||||
|
DEBUG_AUTOCONF("Exar XR17V35x ");
|
||||||
|
up->port.type = PORT_XR17V35X;
|
||||||
|
up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
|
||||||
|
UART_CAP_SLEEP;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for presence of the EFR when DLAB is set.
|
* Check for presence of the EFR when DLAB is set.
|
||||||
* Only ST16C650V1 UARTs pass this test.
|
* Only ST16C650V1 UARTs pass this test.
|
||||||
|
@ -1013,8 +1058,12 @@ static void autoconfig_16550a(struct uart_8250_port *up)
|
||||||
* Exar uarts have EFR in a weird location
|
* Exar uarts have EFR in a weird location
|
||||||
*/
|
*/
|
||||||
if (up->port.flags & UPF_EXAR_EFR) {
|
if (up->port.flags & UPF_EXAR_EFR) {
|
||||||
|
DEBUG_AUTOCONF("Exar XR17D15x ");
|
||||||
up->port.type = PORT_XR17D15X;
|
up->port.type = PORT_XR17D15X;
|
||||||
up->capabilities |= UART_CAP_AFE | UART_CAP_EFR;
|
up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
|
||||||
|
UART_CAP_SLEEP;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1515,6 +1564,31 @@ static int serial8250_default_handle_irq(struct uart_port *port)
|
||||||
return serial8250_handle_irq(port, iir);
|
return serial8250_handle_irq(port, iir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These Exar UARTs have an extra interrupt indicator that could
|
||||||
|
* fire for a few unimplemented interrupts. One of which is a
|
||||||
|
* wakeup event when coming out of sleep. Put this here just
|
||||||
|
* to be on the safe side that these interrupts don't go unhandled.
|
||||||
|
*/
|
||||||
|
static int exar_handle_irq(struct uart_port *port)
|
||||||
|
{
|
||||||
|
unsigned char int0, int1, int2, int3;
|
||||||
|
unsigned int iir = serial_port_in(port, UART_IIR);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = serial8250_handle_irq(port, iir);
|
||||||
|
|
||||||
|
if ((port->type == PORT_XR17V35X) ||
|
||||||
|
(port->type == PORT_XR17D15X)) {
|
||||||
|
int0 = serial_port_in(port, 0x80);
|
||||||
|
int1 = serial_port_in(port, 0x81);
|
||||||
|
int2 = serial_port_in(port, 0x82);
|
||||||
|
int3 = serial_port_in(port, 0x83);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the serial driver's interrupt routine.
|
* This is the serial driver's interrupt routine.
|
||||||
*
|
*
|
||||||
|
@ -2349,16 +2423,14 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||||
serial_port_out(port, UART_EFR, efr);
|
serial_port_out(port, UART_EFR, efr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_OMAP1
|
|
||||||
/* Workaround to enable 115200 baud on OMAP1510 internal ports */
|
/* Workaround to enable 115200 baud on OMAP1510 internal ports */
|
||||||
if (cpu_is_omap1510() && is_omap_port(up)) {
|
if (is_omap1510_8250(up)) {
|
||||||
if (baud == 115200) {
|
if (baud == 115200) {
|
||||||
quot = 1;
|
quot = 1;
|
||||||
serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1);
|
serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1);
|
||||||
} else
|
} else
|
||||||
serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0);
|
serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2,
|
* 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)
|
||||||
{
|
{
|
||||||
if (pt->port.iotype == UPIO_AU)
|
if (pt->port.iotype == UPIO_AU)
|
||||||
return 0x1000;
|
return 0x1000;
|
||||||
#ifdef CONFIG_ARCH_OMAP1
|
if (is_omap1_8250(pt))
|
||||||
if (is_omap_port(pt))
|
|
||||||
return 0x16 << pt->port.regshift;
|
return 0x16 << pt->port.regshift;
|
||||||
#endif
|
|
||||||
return 8 << pt->port.regshift;
|
return 8 << pt->port.regshift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2617,6 +2688,11 @@ static void serial8250_config_port(struct uart_port *port, int flags)
|
||||||
serial8250_release_rsa_resource(up);
|
serial8250_release_rsa_resource(up);
|
||||||
if (port->type == PORT_UNKNOWN)
|
if (port->type == PORT_UNKNOWN)
|
||||||
serial8250_release_std_resource(up);
|
serial8250_release_std_resource(up);
|
||||||
|
|
||||||
|
/* Fixme: probably not the best place for this */
|
||||||
|
if ((port->type == PORT_XR17V35X) ||
|
||||||
|
(port->type == PORT_XR17D15X))
|
||||||
|
port->handle_irq = exar_handle_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -2992,7 +3068,7 @@ void serial8250_resume_port(int line)
|
||||||
* list is terminated with a zero flags entry, which means we expect
|
* list is terminated with a zero flags entry, which means we expect
|
||||||
* all entries to have at least UPF_BOOT_AUTOCONF set.
|
* all entries to have at least UPF_BOOT_AUTOCONF set.
|
||||||
*/
|
*/
|
||||||
static int __devinit serial8250_probe(struct platform_device *dev)
|
static int serial8250_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct plat_serial8250_port *p = dev->dev.platform_data;
|
struct plat_serial8250_port *p = dev->dev.platform_data;
|
||||||
struct uart_8250_port uart;
|
struct uart_8250_port uart;
|
||||||
|
@ -3038,7 +3114,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
|
||||||
/*
|
/*
|
||||||
* Remove serial ports registered against a platform device.
|
* Remove serial ports registered against a platform device.
|
||||||
*/
|
*/
|
||||||
static int __devexit serial8250_remove(struct platform_device *dev)
|
static int serial8250_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -3081,7 +3157,7 @@ static int serial8250_resume(struct platform_device *dev)
|
||||||
|
|
||||||
static struct platform_driver serial8250_isa_driver = {
|
static struct platform_driver serial8250_isa_driver = {
|
||||||
.probe = serial8250_probe,
|
.probe = serial8250_probe,
|
||||||
.remove = __devexit_p(serial8250_remove),
|
.remove = serial8250_remove,
|
||||||
.suspend = serial8250_suspend,
|
.suspend = serial8250_suspend,
|
||||||
.resume = serial8250_resume,
|
.resume = serial8250_resume,
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|
|
@ -106,3 +106,39 @@ static inline int serial8250_pnp_init(void) { return 0; }
|
||||||
static inline void serial8250_pnp_exit(void) { }
|
static inline void serial8250_pnp_exit(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
static inline int is_omap1_8250(struct uart_8250_port *pt)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
switch (pt->port.mapbase) {
|
||||||
|
case OMAP1_UART1_BASE:
|
||||||
|
case OMAP1_UART2_BASE:
|
||||||
|
case OMAP1_UART3_BASE:
|
||||||
|
res = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int is_omap1510_8250(struct uart_8250_port *pt)
|
||||||
|
{
|
||||||
|
if (!cpu_is_omap1510())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return is_omap1_8250(pt);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline int is_omap1_8250(struct uart_8250_port *pt)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline int is_omap1510_8250(struct uart_8250_port *pt)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct serial_card_info {
|
||||||
void __iomem *vaddr;
|
void __iomem *vaddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit
|
static int
|
||||||
serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
|
serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
|
||||||
{
|
{
|
||||||
struct serial_card_info *info;
|
struct serial_card_info *info;
|
||||||
|
@ -80,7 +80,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit serial_card_remove(struct expansion_card *ec)
|
static void serial_card_remove(struct expansion_card *ec)
|
||||||
{
|
{
|
||||||
struct serial_card_info *info = ecard_get_drvdata(ec);
|
struct serial_card_info *info = ecard_get_drvdata(ec);
|
||||||
int i;
|
int i;
|
||||||
|
@ -116,7 +116,7 @@ static const struct ecard_id serial_cids[] = {
|
||||||
|
|
||||||
static struct ecard_driver serial_card_driver = {
|
static struct ecard_driver serial_card_driver = {
|
||||||
.probe = serial_card_probe,
|
.probe = serial_card_probe,
|
||||||
.remove = __devexit_p(serial_card_remove),
|
.remove = serial_card_remove,
|
||||||
.id_table = serial_cids,
|
.id_table = serial_cids,
|
||||||
.drv = {
|
.drv = {
|
||||||
.name = "8250_acorn",
|
.name = "8250_acorn",
|
||||||
|
|
|
@ -87,7 +87,7 @@ static int dw8250_handle_irq(struct uart_port *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit dw8250_probe(struct platform_device *pdev)
|
static int dw8250_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct uart_8250_port uart = {};
|
struct uart_8250_port uart = {};
|
||||||
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
@ -152,7 +152,7 @@ static int __devinit dw8250_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit dw8250_remove(struct platform_device *pdev)
|
static int dw8250_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dw8250_data *data = platform_get_drvdata(pdev);
|
struct dw8250_data *data = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -161,6 +161,29 @@ static int __devexit dw8250_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int dw8250_suspend(struct platform_device *pdev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct dw8250_data *data = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
serial8250_suspend_port(data->line);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dw8250_resume(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct dw8250_data *data = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
serial8250_resume_port(data->line);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define dw8250_suspend NULL
|
||||||
|
#define dw8250_resume NULL
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
static const struct of_device_id dw8250_match[] = {
|
static const struct of_device_id dw8250_match[] = {
|
||||||
{ .compatible = "snps,dw-apb-uart" },
|
{ .compatible = "snps,dw-apb-uart" },
|
||||||
{ /* Sentinel */ }
|
{ /* Sentinel */ }
|
||||||
|
@ -174,7 +197,9 @@ static struct platform_driver dw8250_platform_driver = {
|
||||||
.of_match_table = dw8250_match,
|
.of_match_table = dw8250_match,
|
||||||
},
|
},
|
||||||
.probe = dw8250_probe,
|
.probe = dw8250_probe,
|
||||||
.remove = __devexit_p(dw8250_remove),
|
.remove = dw8250_remove,
|
||||||
|
.suspend = dw8250_suspend,
|
||||||
|
.resume = dw8250_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(dw8250_platform_driver);
|
module_platform_driver(dw8250_platform_driver);
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct early_serial8250_device {
|
||||||
|
|
||||||
static struct early_serial8250_device early_device;
|
static struct early_serial8250_device early_device;
|
||||||
|
|
||||||
static unsigned int __init serial_in(struct uart_port *port, int offset)
|
unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset)
|
||||||
{
|
{
|
||||||
switch (port->iotype) {
|
switch (port->iotype) {
|
||||||
case UPIO_MEM:
|
case UPIO_MEM:
|
||||||
|
@ -62,7 +62,7 @@ static unsigned int __init serial_in(struct uart_port *port, int offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init serial_out(struct uart_port *port, int offset, int value)
|
void __weak __init serial8250_early_out(struct uart_port *port, int offset, int value)
|
||||||
{
|
{
|
||||||
switch (port->iotype) {
|
switch (port->iotype) {
|
||||||
case UPIO_MEM:
|
case UPIO_MEM:
|
||||||
|
@ -84,7 +84,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
status = serial_in(port, UART_LSR);
|
status = serial8250_early_in(port, UART_LSR);
|
||||||
if ((status & BOTH_EMPTY) == BOTH_EMPTY)
|
if ((status & BOTH_EMPTY) == BOTH_EMPTY)
|
||||||
return;
|
return;
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
@ -94,7 +94,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
|
||||||
static void __init serial_putc(struct uart_port *port, int c)
|
static void __init serial_putc(struct uart_port *port, int c)
|
||||||
{
|
{
|
||||||
wait_for_xmitr(port);
|
wait_for_xmitr(port);
|
||||||
serial_out(port, UART_TX, c);
|
serial8250_early_out(port, UART_TX, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init early_serial8250_write(struct console *console,
|
static void __init early_serial8250_write(struct console *console,
|
||||||
|
@ -104,14 +104,14 @@ static void __init early_serial8250_write(struct console *console,
|
||||||
unsigned int ier;
|
unsigned int ier;
|
||||||
|
|
||||||
/* Save the IER and disable interrupts */
|
/* Save the IER and disable interrupts */
|
||||||
ier = serial_in(port, UART_IER);
|
ier = serial8250_early_in(port, UART_IER);
|
||||||
serial_out(port, UART_IER, 0);
|
serial8250_early_out(port, UART_IER, 0);
|
||||||
|
|
||||||
uart_console_write(port, s, count, serial_putc);
|
uart_console_write(port, s, count, serial_putc);
|
||||||
|
|
||||||
/* Wait for transmitter to become empty and restore the IER */
|
/* Wait for transmitter to become empty and restore the IER */
|
||||||
wait_for_xmitr(port);
|
wait_for_xmitr(port);
|
||||||
serial_out(port, UART_IER, ier);
|
serial8250_early_out(port, UART_IER, ier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int __init probe_baud(struct uart_port *port)
|
static unsigned int __init probe_baud(struct uart_port *port)
|
||||||
|
@ -119,11 +119,11 @@ static unsigned int __init probe_baud(struct uart_port *port)
|
||||||
unsigned char lcr, dll, dlm;
|
unsigned char lcr, dll, dlm;
|
||||||
unsigned int quot;
|
unsigned int quot;
|
||||||
|
|
||||||
lcr = serial_in(port, UART_LCR);
|
lcr = serial8250_early_in(port, UART_LCR);
|
||||||
serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
|
serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
|
||||||
dll = serial_in(port, UART_DLL);
|
dll = serial8250_early_in(port, UART_DLL);
|
||||||
dlm = serial_in(port, UART_DLM);
|
dlm = serial8250_early_in(port, UART_DLM);
|
||||||
serial_out(port, UART_LCR, lcr);
|
serial8250_early_out(port, UART_LCR, lcr);
|
||||||
|
|
||||||
quot = (dlm << 8) | dll;
|
quot = (dlm << 8) | dll;
|
||||||
return (port->uartclk / 16) / quot;
|
return (port->uartclk / 16) / quot;
|
||||||
|
@ -135,17 +135,17 @@ static void __init init_port(struct early_serial8250_device *device)
|
||||||
unsigned int divisor;
|
unsigned int divisor;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
serial_out(port, UART_LCR, 0x3); /* 8n1 */
|
serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */
|
||||||
serial_out(port, UART_IER, 0); /* no interrupt */
|
serial8250_early_out(port, UART_IER, 0); /* no interrupt */
|
||||||
serial_out(port, UART_FCR, 0); /* no fifo */
|
serial8250_early_out(port, UART_FCR, 0); /* no fifo */
|
||||||
serial_out(port, UART_MCR, 0x3); /* DTR + RTS */
|
serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */
|
||||||
|
|
||||||
divisor = port->uartclk / (16 * device->baud);
|
divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud);
|
||||||
c = serial_in(port, UART_LCR);
|
c = serial8250_early_in(port, UART_LCR);
|
||||||
serial_out(port, UART_LCR, c | UART_LCR_DLAB);
|
serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB);
|
||||||
serial_out(port, UART_DLL, divisor & 0xff);
|
serial8250_early_out(port, UART_DLL, divisor & 0xff);
|
||||||
serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
|
serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff);
|
||||||
serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
|
serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init parse_options(struct early_serial8250_device *device,
|
static int __init parse_options(struct early_serial8250_device *device,
|
||||||
|
|
|
@ -89,7 +89,7 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
|
||||||
serial_out(up, UART_DLM_EM, value >> 8 & 0xff);
|
serial_out(up, UART_DLM_EM, value >> 8 & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit serial8250_em_probe(struct platform_device *pdev)
|
static int serial8250_em_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||||
|
@ -152,7 +152,7 @@ static int __devinit serial8250_em_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit serial8250_em_remove(struct platform_device *pdev)
|
static int serial8250_em_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
|
struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ static int __devexit serial8250_em_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id serial8250_em_dt_ids[] __devinitconst = {
|
static const struct of_device_id serial8250_em_dt_ids[] = {
|
||||||
{ .compatible = "renesas,em-uart", },
|
{ .compatible = "renesas,em-uart", },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
@ -176,7 +176,7 @@ static struct platform_driver serial8250_em_platform_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.probe = serial8250_em_probe,
|
.probe = serial8250_em_probe,
|
||||||
.remove = __devexit_p(serial8250_em_remove),
|
.remove = serial8250_em_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(serial8250_em_platform_driver);
|
module_platform_driver(serial8250_em_platform_driver);
|
||||||
|
|
|
@ -36,9 +36,9 @@ static struct hp300_port *hp300_ports;
|
||||||
|
|
||||||
#ifdef CONFIG_HPDCA
|
#ifdef CONFIG_HPDCA
|
||||||
|
|
||||||
static int __devinit hpdca_init_one(struct dio_dev *d,
|
static int hpdca_init_one(struct dio_dev *d,
|
||||||
const struct dio_device_id *ent);
|
const struct dio_device_id *ent);
|
||||||
static void __devexit hpdca_remove_one(struct dio_dev *d);
|
static void hpdca_remove_one(struct dio_dev *d);
|
||||||
|
|
||||||
static struct dio_device_id hpdca_dio_tbl[] = {
|
static struct dio_device_id hpdca_dio_tbl[] = {
|
||||||
{ DIO_ID_DCA0 },
|
{ DIO_ID_DCA0 },
|
||||||
|
@ -52,7 +52,7 @@ static struct dio_driver hpdca_driver = {
|
||||||
.name = "hpdca",
|
.name = "hpdca",
|
||||||
.id_table = hpdca_dio_tbl,
|
.id_table = hpdca_dio_tbl,
|
||||||
.probe = hpdca_init_one,
|
.probe = hpdca_init_one,
|
||||||
.remove = __devexit_p(hpdca_remove_one),
|
.remove = hpdca_remove_one,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -159,7 +159,7 @@ int __init hp300_setup_serial_console(void)
|
||||||
#endif /* CONFIG_SERIAL_8250_CONSOLE */
|
#endif /* CONFIG_SERIAL_8250_CONSOLE */
|
||||||
|
|
||||||
#ifdef CONFIG_HPDCA
|
#ifdef CONFIG_HPDCA
|
||||||
static int __devinit hpdca_init_one(struct dio_dev *d,
|
static int hpdca_init_one(struct dio_dev *d,
|
||||||
const struct dio_device_id *ent)
|
const struct dio_device_id *ent)
|
||||||
{
|
{
|
||||||
struct uart_8250_port uart;
|
struct uart_8250_port uart;
|
||||||
|
@ -288,7 +288,7 @@ static int __init hp300_8250_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HPDCA
|
#ifdef CONFIG_HPDCA
|
||||||
static void __devexit hpdca_remove_one(struct dio_dev *d)
|
static void hpdca_remove_one(struct dio_dev *d)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ static int pci_plx9050_init(struct pci_dev *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit pci_plx9050_exit(struct pci_dev *dev)
|
static void pci_plx9050_exit(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
u8 __iomem *p;
|
u8 __iomem *p;
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
|
||||||
#define NI8420_INT_ENABLE_REG 0x38
|
#define NI8420_INT_ENABLE_REG 0x38
|
||||||
#define NI8420_INT_ENABLE_BIT 0x2000
|
#define NI8420_INT_ENABLE_BIT 0x2000
|
||||||
|
|
||||||
static void __devexit pci_ni8420_exit(struct pci_dev *dev)
|
static void pci_ni8420_exit(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
void __iomem *p;
|
void __iomem *p;
|
||||||
unsigned long base, len;
|
unsigned long base, len;
|
||||||
|
@ -345,7 +345,7 @@ static void __devexit pci_ni8420_exit(struct pci_dev *dev)
|
||||||
|
|
||||||
#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
|
#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
|
||||||
|
|
||||||
static void __devexit pci_ni8430_exit(struct pci_dev *dev)
|
static void pci_ni8430_exit(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
void __iomem *p;
|
void __iomem *p;
|
||||||
unsigned long base, len;
|
unsigned long base, len;
|
||||||
|
@ -422,7 +422,7 @@ static int sbs_init(struct pci_dev *dev)
|
||||||
* Disables the global interrupt of PMC-OctalPro
|
* Disables the global interrupt of PMC-OctalPro
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void __devexit sbs_exit(struct pci_dev *dev)
|
static void sbs_exit(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
u8 __iomem *p;
|
u8 __iomem *p;
|
||||||
|
|
||||||
|
@ -991,7 +991,7 @@ static int pci_ite887x_init(struct pci_dev *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit pci_ite887x_exit(struct pci_dev *dev)
|
static void pci_ite887x_exit(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
u32 ioport;
|
u32 ioport;
|
||||||
/* the ioport is bit 0-15 in POSIO0R */
|
/* the ioport is bit 0-15 in POSIO0R */
|
||||||
|
@ -1068,7 +1068,7 @@ ce4100_serial_setup(struct serial_private *priv,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = setup_port(priv, port, 0, 0, board->reg_shift);
|
ret = setup_port(priv, port, idx, 0, board->reg_shift);
|
||||||
port->port.iotype = UPIO_MEM32;
|
port->port.iotype = UPIO_MEM32;
|
||||||
port->port.type = PORT_XSCALE;
|
port->port.type = PORT_XSCALE;
|
||||||
port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
|
port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
|
||||||
|
@ -1164,6 +1164,94 @@ pci_xr17c154_setup(struct serial_private *priv,
|
||||||
return pci_default_setup(priv, board, port, idx);
|
return pci_default_setup(priv, board, port, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pci_xr17v35x_setup(struct serial_private *priv,
|
||||||
|
const struct pciserial_board *board,
|
||||||
|
struct uart_8250_port *port, int idx)
|
||||||
|
{
|
||||||
|
u8 __iomem *p;
|
||||||
|
|
||||||
|
p = pci_ioremap_bar(priv->dev, 0);
|
||||||
|
if (p == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
port->port.flags |= UPF_EXAR_EFR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup Multipurpose Input/Output pins.
|
||||||
|
*/
|
||||||
|
if (idx == 0) {
|
||||||
|
writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/
|
||||||
|
writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/
|
||||||
|
writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/
|
||||||
|
writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/
|
||||||
|
writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/
|
||||||
|
writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/
|
||||||
|
writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/
|
||||||
|
writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/
|
||||||
|
writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/
|
||||||
|
writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/
|
||||||
|
writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/
|
||||||
|
writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/
|
||||||
|
}
|
||||||
|
writeb(0x00, p + UART_EXAR_8XMODE);
|
||||||
|
writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
|
||||||
|
writeb(128, p + UART_EXAR_TXTRG);
|
||||||
|
writeb(128, p + UART_EXAR_RXTRG);
|
||||||
|
iounmap(p);
|
||||||
|
|
||||||
|
return pci_default_setup(priv, board, port, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b
|
||||||
|
|
||||||
|
static int
|
||||||
|
pci_fastcom335_setup(struct serial_private *priv,
|
||||||
|
const struct pciserial_board *board,
|
||||||
|
struct uart_8250_port *port, int idx)
|
||||||
|
{
|
||||||
|
u8 __iomem *p;
|
||||||
|
|
||||||
|
p = pci_ioremap_bar(priv->dev, 0);
|
||||||
|
if (p == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
port->port.flags |= UPF_EXAR_EFR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup Multipurpose Input/Output pins.
|
||||||
|
*/
|
||||||
|
if (idx == 0) {
|
||||||
|
switch (priv->dev->device) {
|
||||||
|
case PCI_DEVICE_ID_COMMTECH_4222PCI335:
|
||||||
|
case PCI_DEVICE_ID_COMMTECH_4224PCI335:
|
||||||
|
writeb(0x78, p + 0x90); /* MPIOLVL[7:0] */
|
||||||
|
writeb(0x00, p + 0x92); /* MPIOINV[7:0] */
|
||||||
|
writeb(0x00, p + 0x93); /* MPIOSEL[7:0] */
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_COMMTECH_2324PCI335:
|
||||||
|
case PCI_DEVICE_ID_COMMTECH_2328PCI335:
|
||||||
|
writeb(0x00, p + 0x90); /* MPIOLVL[7:0] */
|
||||||
|
writeb(0xc0, p + 0x92); /* MPIOINV[7:0] */
|
||||||
|
writeb(0xc0, p + 0x93); /* MPIOSEL[7:0] */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
writeb(0x00, p + 0x8f); /* MPIOINT[7:0] */
|
||||||
|
writeb(0x00, p + 0x91); /* MPIO3T[7:0] */
|
||||||
|
writeb(0x00, p + 0x94); /* MPIOOD[7:0] */
|
||||||
|
}
|
||||||
|
writeb(0x00, p + UART_EXAR_8XMODE);
|
||||||
|
writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
|
||||||
|
writeb(32, p + UART_EXAR_TXTRG);
|
||||||
|
writeb(32, p + UART_EXAR_RXTRG);
|
||||||
|
iounmap(p);
|
||||||
|
|
||||||
|
return pci_default_setup(priv, board, port, idx);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pci_wch_ch353_setup(struct serial_private *priv,
|
pci_wch_ch353_setup(struct serial_private *priv,
|
||||||
const struct pciserial_board *board,
|
const struct pciserial_board *board,
|
||||||
|
@ -1213,6 +1301,10 @@ pci_wch_ch353_setup(struct serial_private *priv,
|
||||||
#define PCI_VENDOR_ID_AGESTAR 0x5372
|
#define PCI_VENDOR_ID_AGESTAR 0x5372
|
||||||
#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
|
#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
|
||||||
#define PCI_VENDOR_ID_ASIX 0x9710
|
#define PCI_VENDOR_ID_ASIX 0x9710
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0019
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020
|
||||||
|
#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021
|
||||||
|
|
||||||
|
|
||||||
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
|
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
|
||||||
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
|
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
|
||||||
|
@ -1314,7 +1406,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ite887x_init,
|
.init = pci_ite887x_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ite887x_exit),
|
.exit = pci_ite887x_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* National Instruments
|
* National Instruments
|
||||||
|
@ -1326,7 +1418,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1335,7 +1427,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1344,7 +1436,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1353,7 +1445,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1362,7 +1454,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1371,7 +1463,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1380,7 +1472,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1389,7 +1481,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1398,7 +1490,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1407,7 +1499,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1416,7 +1508,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1425,7 +1517,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8420_init,
|
.init = pci_ni8420_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_ni8420_exit),
|
.exit = pci_ni8420_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_NI,
|
.vendor = PCI_VENDOR_ID_NI,
|
||||||
|
@ -1434,7 +1526,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_ni8430_init,
|
.init = pci_ni8430_init,
|
||||||
.setup = pci_ni8430_setup,
|
.setup = pci_ni8430_setup,
|
||||||
.exit = __devexit_p(pci_ni8430_exit),
|
.exit = pci_ni8430_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* Panacom
|
* Panacom
|
||||||
|
@ -1446,7 +1538,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_plx9050_init,
|
.init = pci_plx9050_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_plx9050_exit),
|
.exit = pci_plx9050_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_PANACOM,
|
.vendor = PCI_VENDOR_ID_PANACOM,
|
||||||
|
@ -1455,7 +1547,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.init = pci_plx9050_init,
|
.init = pci_plx9050_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_plx9050_exit),
|
.exit = pci_plx9050_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* PLX
|
* PLX
|
||||||
|
@ -1474,7 +1566,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
|
.subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
|
||||||
.init = pci_plx9050_init,
|
.init = pci_plx9050_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_plx9050_exit),
|
.exit = pci_plx9050_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_PLX,
|
.vendor = PCI_VENDOR_ID_PLX,
|
||||||
|
@ -1483,7 +1575,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
|
.subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
|
||||||
.init = pci_plx9050_init,
|
.init = pci_plx9050_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_plx9050_exit),
|
.exit = pci_plx9050_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_PLX,
|
.vendor = PCI_VENDOR_ID_PLX,
|
||||||
|
@ -1492,7 +1584,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
|
.subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
|
||||||
.init = pci_plx9050_init,
|
.init = pci_plx9050_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_plx9050_exit),
|
.exit = pci_plx9050_exit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor = PCI_VENDOR_ID_PLX,
|
.vendor = PCI_VENDOR_ID_PLX,
|
||||||
|
@ -1501,7 +1593,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
|
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
|
||||||
.init = pci_plx9050_init,
|
.init = pci_plx9050_init,
|
||||||
.setup = pci_default_setup,
|
.setup = pci_default_setup,
|
||||||
.exit = __devexit_p(pci_plx9050_exit),
|
.exit = pci_plx9050_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* SBS Technologies, Inc., PMC-OCTALPRO 232
|
* SBS Technologies, Inc., PMC-OCTALPRO 232
|
||||||
|
@ -1513,7 +1605,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_OCTPRO232,
|
.subdevice = PCI_SUBDEVICE_ID_OCTPRO232,
|
||||||
.init = sbs_init,
|
.init = sbs_init,
|
||||||
.setup = sbs_setup,
|
.setup = sbs_setup,
|
||||||
.exit = __devexit_p(sbs_exit),
|
.exit = sbs_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* SBS Technologies, Inc., PMC-OCTALPRO 422
|
* SBS Technologies, Inc., PMC-OCTALPRO 422
|
||||||
|
@ -1525,7 +1617,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_OCTPRO422,
|
.subdevice = PCI_SUBDEVICE_ID_OCTPRO422,
|
||||||
.init = sbs_init,
|
.init = sbs_init,
|
||||||
.setup = sbs_setup,
|
.setup = sbs_setup,
|
||||||
.exit = __devexit_p(sbs_exit),
|
.exit = sbs_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* SBS Technologies, Inc., P-Octal 232
|
* SBS Technologies, Inc., P-Octal 232
|
||||||
|
@ -1537,7 +1629,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_POCTAL232,
|
.subdevice = PCI_SUBDEVICE_ID_POCTAL232,
|
||||||
.init = sbs_init,
|
.init = sbs_init,
|
||||||
.setup = sbs_setup,
|
.setup = sbs_setup,
|
||||||
.exit = __devexit_p(sbs_exit),
|
.exit = sbs_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* SBS Technologies, Inc., P-Octal 422
|
* SBS Technologies, Inc., P-Octal 422
|
||||||
|
@ -1549,7 +1641,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_SUBDEVICE_ID_POCTAL422,
|
.subdevice = PCI_SUBDEVICE_ID_POCTAL422,
|
||||||
.init = sbs_init,
|
.init = sbs_init,
|
||||||
.setup = sbs_setup,
|
.setup = sbs_setup,
|
||||||
.exit = __devexit_p(sbs_exit),
|
.exit = sbs_exit,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
* SIIG cards - these may be called via parport_serial
|
* SIIG cards - these may be called via parport_serial
|
||||||
|
@ -1622,6 +1714,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.setup = pci_xr17c154_setup,
|
.setup = pci_xr17c154_setup,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_EXAR,
|
||||||
|
.device = PCI_DEVICE_ID_EXAR_XR17V352,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_xr17v35x_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_EXAR,
|
||||||
|
.device = PCI_DEVICE_ID_EXAR_XR17V354,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_xr17v35x_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_EXAR,
|
||||||
|
.device = PCI_DEVICE_ID_EXAR_XR17V358,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_xr17v35x_setup,
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
* Xircom cards
|
* Xircom cards
|
||||||
*/
|
*/
|
||||||
|
@ -1787,6 +1900,59 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.setup = pci_asix_setup,
|
.setup = pci_asix_setup,
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
* Commtech, Inc. Fastcom adapters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_4222PCI335,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_fastcom335_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_4224PCI335,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_fastcom335_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_2324PCI335,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_fastcom335_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_2328PCI335,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_fastcom335_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_4222PCIE,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_xr17v35x_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_4224PCIE,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_xr17v35x_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_COMMTECH,
|
||||||
|
.device = PCI_DEVICE_ID_COMMTECH_4228PCIE,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.setup = pci_xr17v35x_setup,
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
* Default "match everything" terminator entry
|
* Default "match everything" terminator entry
|
||||||
*/
|
*/
|
||||||
|
@ -1863,6 +2029,10 @@ enum pci_board_num_t {
|
||||||
|
|
||||||
pbn_b0_4_1152000,
|
pbn_b0_4_1152000,
|
||||||
|
|
||||||
|
pbn_b0_2_1152000_200,
|
||||||
|
pbn_b0_4_1152000_200,
|
||||||
|
pbn_b0_8_1152000_200,
|
||||||
|
|
||||||
pbn_b0_2_1843200,
|
pbn_b0_2_1843200,
|
||||||
pbn_b0_4_1843200,
|
pbn_b0_4_1843200,
|
||||||
|
|
||||||
|
@ -1962,6 +2132,9 @@ enum pci_board_num_t {
|
||||||
pbn_exar_XR17C152,
|
pbn_exar_XR17C152,
|
||||||
pbn_exar_XR17C154,
|
pbn_exar_XR17C154,
|
||||||
pbn_exar_XR17C158,
|
pbn_exar_XR17C158,
|
||||||
|
pbn_exar_XR17V352,
|
||||||
|
pbn_exar_XR17V354,
|
||||||
|
pbn_exar_XR17V358,
|
||||||
pbn_exar_ibm_saturn,
|
pbn_exar_ibm_saturn,
|
||||||
pbn_pasemi_1682M,
|
pbn_pasemi_1682M,
|
||||||
pbn_ni8430_2,
|
pbn_ni8430_2,
|
||||||
|
@ -1987,7 +2160,7 @@ enum pci_board_num_t {
|
||||||
* see first lines of serial_in() and serial_out() in 8250.c
|
* see first lines of serial_in() and serial_out() in 8250.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct pciserial_board pci_boards[] __devinitdata = {
|
static struct pciserial_board pci_boards[] = {
|
||||||
[pbn_default] = {
|
[pbn_default] = {
|
||||||
.flags = FL_BASE0,
|
.flags = FL_BASE0,
|
||||||
.num_ports = 1,
|
.num_ports = 1,
|
||||||
|
@ -2057,6 +2230,27 @@ static struct pciserial_board pci_boards[] __devinitdata = {
|
||||||
.uart_offset = 8,
|
.uart_offset = 8,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[pbn_b0_2_1152000_200] = {
|
||||||
|
.flags = FL_BASE0,
|
||||||
|
.num_ports = 2,
|
||||||
|
.base_baud = 1152000,
|
||||||
|
.uart_offset = 0x200,
|
||||||
|
},
|
||||||
|
|
||||||
|
[pbn_b0_4_1152000_200] = {
|
||||||
|
.flags = FL_BASE0,
|
||||||
|
.num_ports = 4,
|
||||||
|
.base_baud = 1152000,
|
||||||
|
.uart_offset = 0x200,
|
||||||
|
},
|
||||||
|
|
||||||
|
[pbn_b0_8_1152000_200] = {
|
||||||
|
.flags = FL_BASE0,
|
||||||
|
.num_ports = 2,
|
||||||
|
.base_baud = 1152000,
|
||||||
|
.uart_offset = 0x200,
|
||||||
|
},
|
||||||
|
|
||||||
[pbn_b0_2_1843200] = {
|
[pbn_b0_2_1843200] = {
|
||||||
.flags = FL_BASE0,
|
.flags = FL_BASE0,
|
||||||
.num_ports = 2,
|
.num_ports = 2,
|
||||||
|
@ -2580,6 +2774,30 @@ static struct pciserial_board pci_boards[] __devinitdata = {
|
||||||
.base_baud = 921600,
|
.base_baud = 921600,
|
||||||
.uart_offset = 0x200,
|
.uart_offset = 0x200,
|
||||||
},
|
},
|
||||||
|
[pbn_exar_XR17V352] = {
|
||||||
|
.flags = FL_BASE0,
|
||||||
|
.num_ports = 2,
|
||||||
|
.base_baud = 7812500,
|
||||||
|
.uart_offset = 0x400,
|
||||||
|
.reg_shift = 0,
|
||||||
|
.first_offset = 0,
|
||||||
|
},
|
||||||
|
[pbn_exar_XR17V354] = {
|
||||||
|
.flags = FL_BASE0,
|
||||||
|
.num_ports = 4,
|
||||||
|
.base_baud = 7812500,
|
||||||
|
.uart_offset = 0x400,
|
||||||
|
.reg_shift = 0,
|
||||||
|
.first_offset = 0,
|
||||||
|
},
|
||||||
|
[pbn_exar_XR17V358] = {
|
||||||
|
.flags = FL_BASE0,
|
||||||
|
.num_ports = 8,
|
||||||
|
.base_baud = 7812500,
|
||||||
|
.uart_offset = 0x400,
|
||||||
|
.reg_shift = 0,
|
||||||
|
.first_offset = 0,
|
||||||
|
},
|
||||||
[pbn_exar_ibm_saturn] = {
|
[pbn_exar_ibm_saturn] = {
|
||||||
.flags = FL_BASE0,
|
.flags = FL_BASE0,
|
||||||
.num_ports = 1,
|
.num_ports = 1,
|
||||||
|
@ -2658,8 +2876,8 @@ static struct pciserial_board pci_boards[] __devinitdata = {
|
||||||
.first_offset = 0x1000,
|
.first_offset = 0x1000,
|
||||||
},
|
},
|
||||||
[pbn_ce4100_1_115200] = {
|
[pbn_ce4100_1_115200] = {
|
||||||
.flags = FL_BASE0,
|
.flags = FL_BASE_BARS,
|
||||||
.num_ports = 1,
|
.num_ports = 2,
|
||||||
.base_baud = 921600,
|
.base_baud = 921600,
|
||||||
.reg_shift = 2,
|
.reg_shift = 2,
|
||||||
},
|
},
|
||||||
|
@ -2691,7 +2909,7 @@ static const struct pci_device_id blacklist[] = {
|
||||||
* guess what the configuration might be, based on the pitiful PCI
|
* guess what the configuration might be, based on the pitiful PCI
|
||||||
* serial specs. Returns 0 on success, 1 on failure.
|
* serial specs. Returns 0 on success, 1 on failure.
|
||||||
*/
|
*/
|
||||||
static int __devinit
|
static int
|
||||||
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
|
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
|
||||||
{
|
{
|
||||||
const struct pci_device_id *bldev;
|
const struct pci_device_id *bldev;
|
||||||
|
@ -2917,7 +3135,7 @@ EXPORT_SYMBOL_GPL(pciserial_resume_ports);
|
||||||
* Probe one serial board. Unfortunately, there is no rhyme nor reason
|
* Probe one serial board. Unfortunately, there is no rhyme nor reason
|
||||||
* to the arrangement of serial ports on a PCI card.
|
* to the arrangement of serial ports on a PCI card.
|
||||||
*/
|
*/
|
||||||
static int __devinit
|
static int
|
||||||
pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
|
pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
struct pci_serial_quirk *quirk;
|
struct pci_serial_quirk *quirk;
|
||||||
|
@ -2988,7 +3206,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit pciserial_remove_one(struct pci_dev *dev)
|
static void pciserial_remove_one(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
struct serial_private *priv = pci_get_drvdata(dev);
|
struct serial_private *priv = pci_get_drvdata(dev);
|
||||||
|
|
||||||
|
@ -3826,6 +4044,21 @@ static struct pci_device_id serial_pci_tbl[] = {
|
||||||
PCI_ANY_ID, PCI_ANY_ID,
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
0,
|
0,
|
||||||
0, pbn_exar_XR17C158 },
|
0, pbn_exar_XR17C158 },
|
||||||
|
/*
|
||||||
|
* Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs
|
||||||
|
*/
|
||||||
|
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_exar_XR17V352 },
|
||||||
|
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_exar_XR17V354 },
|
||||||
|
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_exar_XR17V358 },
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
|
* Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
|
||||||
|
@ -4256,6 +4489,38 @@ static struct pci_device_id serial_pci_tbl[] = {
|
||||||
PCI_ANY_ID, PCI_ANY_ID,
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
0, 0, pbn_b0_bt_2_115200 },
|
0, 0, pbn_b0_bt_2_115200 },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Commtech, Inc. Fastcom adapters
|
||||||
|
*/
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_b0_2_1152000_200 },
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_b0_4_1152000_200 },
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_b0_4_1152000_200 },
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_b0_8_1152000_200 },
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_exar_XR17V352 },
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_exar_XR17V354 },
|
||||||
|
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID,
|
||||||
|
0,
|
||||||
|
0, pbn_exar_XR17V358 },
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These entries match devices with class COMMUNICATION_SERIAL,
|
* These entries match devices with class COMMUNICATION_SERIAL,
|
||||||
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
|
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
|
||||||
|
@ -4323,7 +4588,7 @@ static const struct pci_error_handlers serial8250_err_handler = {
|
||||||
static struct pci_driver serial_pci_driver = {
|
static struct pci_driver serial_pci_driver = {
|
||||||
.name = "serial",
|
.name = "serial",
|
||||||
.probe = pciserial_init_one,
|
.probe = pciserial_init_one,
|
||||||
.remove = __devexit_p(pciserial_remove_one),
|
.remove = pciserial_remove_one,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.suspend = pciserial_suspend_one,
|
.suspend = pciserial_suspend_one,
|
||||||
.resume = pciserial_resume_one,
|
.resume = pciserial_resume_one,
|
||||||
|
@ -4332,18 +4597,7 @@ static struct pci_driver serial_pci_driver = {
|
||||||
.err_handler = &serial8250_err_handler,
|
.err_handler = &serial8250_err_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init serial8250_pci_init(void)
|
module_pci_driver(serial_pci_driver);
|
||||||
{
|
|
||||||
return pci_register_driver(&serial_pci_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit serial8250_pci_exit(void)
|
|
||||||
{
|
|
||||||
pci_unregister_driver(&serial_pci_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(serial8250_pci_init);
|
|
||||||
module_exit(serial8250_pci_exit);
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
|
MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
|
||||||
|
|
|
@ -370,14 +370,14 @@ static const struct pnp_device_id pnp_dev_table[] = {
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
|
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
|
||||||
|
|
||||||
static char *modem_names[] __devinitdata = {
|
static char *modem_names[] = {
|
||||||
"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
|
"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
|
||||||
"56K", "56k", "K56", "33.6", "28.8", "14.4",
|
"56K", "56k", "K56", "33.6", "28.8", "14.4",
|
||||||
"33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
|
"33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
|
||||||
"33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
|
"33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit check_name(char *name)
|
static int check_name(char *name)
|
||||||
{
|
{
|
||||||
char **tmp;
|
char **tmp;
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ static int __devinit check_name(char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit check_resources(struct pnp_dev *dev)
|
static int check_resources(struct pnp_dev *dev)
|
||||||
{
|
{
|
||||||
resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
|
resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
|
||||||
int i;
|
int i;
|
||||||
|
@ -412,7 +412,7 @@ static int __devinit check_resources(struct pnp_dev *dev)
|
||||||
* PnP modems, alternatively we must hardcode all modems in pnp_devices[]
|
* PnP modems, alternatively we must hardcode all modems in pnp_devices[]
|
||||||
* table.
|
* table.
|
||||||
*/
|
*/
|
||||||
static int __devinit serial_pnp_guess_board(struct pnp_dev *dev)
|
static int serial_pnp_guess_board(struct pnp_dev *dev)
|
||||||
{
|
{
|
||||||
if (!(check_name(pnp_dev_name(dev)) ||
|
if (!(check_name(pnp_dev_name(dev)) ||
|
||||||
(dev->card && check_name(dev->card->name))))
|
(dev->card && check_name(dev->card->name))))
|
||||||
|
@ -424,7 +424,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit
|
static int
|
||||||
serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
|
serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
|
||||||
{
|
{
|
||||||
struct uart_8250_port uart;
|
struct uart_8250_port uart;
|
||||||
|
@ -476,7 +476,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit serial_pnp_remove(struct pnp_dev *dev)
|
static void serial_pnp_remove(struct pnp_dev *dev)
|
||||||
{
|
{
|
||||||
long line = (long)pnp_get_drvdata(dev);
|
long line = (long)pnp_get_drvdata(dev);
|
||||||
if (line)
|
if (line)
|
||||||
|
@ -511,7 +511,7 @@ static int serial_pnp_resume(struct pnp_dev *dev)
|
||||||
static struct pnp_driver serial_pnp_driver = {
|
static struct pnp_driver serial_pnp_driver = {
|
||||||
.name = "serial",
|
.name = "serial",
|
||||||
.probe = serial_pnp_probe,
|
.probe = serial_pnp_probe,
|
||||||
.remove = __devexit_p(serial_pnp_remove),
|
.remove = serial_pnp_remove,
|
||||||
.suspend = serial_pnp_suspend,
|
.suspend = serial_pnp_suspend,
|
||||||
.resume = serial_pnp_resume,
|
.resume = serial_pnp_resume,
|
||||||
.id_table = pnp_dev_table,
|
.id_table = pnp_dev_table,
|
||||||
|
|
|
@ -93,7 +93,7 @@ config SERIAL_SB1250_DUART_CONSOLE
|
||||||
|
|
||||||
config SERIAL_ATMEL
|
config SERIAL_ATMEL
|
||||||
bool "AT91 / AT32 on-chip serial port support"
|
bool "AT91 / AT32 on-chip serial port support"
|
||||||
depends on (ARM && ARCH_AT91) || AVR32
|
depends on ARCH_AT91 || AVR32
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
This enables the driver for the on-chip UARTs of the Atmel
|
This enables the driver for the on-chip UARTs of the Atmel
|
||||||
|
@ -198,7 +198,7 @@ config SERIAL_CLPS711X_CONSOLE
|
||||||
|
|
||||||
config SERIAL_SAMSUNG
|
config SERIAL_SAMSUNG
|
||||||
tristate "Samsung SoC serial support"
|
tristate "Samsung SoC serial support"
|
||||||
depends on ARM && PLAT_SAMSUNG
|
depends on PLAT_SAMSUNG
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
|
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
|
||||||
|
@ -208,14 +208,14 @@ config SERIAL_SAMSUNG
|
||||||
|
|
||||||
config SERIAL_SAMSUNG_UARTS_4
|
config SERIAL_SAMSUNG_UARTS_4
|
||||||
bool
|
bool
|
||||||
depends on ARM && PLAT_SAMSUNG
|
depends on PLAT_SAMSUNG
|
||||||
default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
|
default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
|
||||||
help
|
help
|
||||||
Internal node for the common case of 4 Samsung compatible UARTs
|
Internal node for the common case of 4 Samsung compatible UARTs
|
||||||
|
|
||||||
config SERIAL_SAMSUNG_UARTS
|
config SERIAL_SAMSUNG_UARTS
|
||||||
int
|
int
|
||||||
depends on ARM && PLAT_SAMSUNG
|
depends on PLAT_SAMSUNG
|
||||||
default 6 if ARCH_S5P6450
|
default 6 if ARCH_S5P6450
|
||||||
default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
|
default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
|
||||||
default 3
|
default 3
|
||||||
|
@ -249,7 +249,7 @@ config SERIAL_SAMSUNG_CONSOLE
|
||||||
|
|
||||||
config SERIAL_SIRFSOC
|
config SERIAL_SIRFSOC
|
||||||
tristate "SiRF SoC Platform Serial port support"
|
tristate "SiRF SoC Platform Serial port support"
|
||||||
depends on ARM && ARCH_PRIMA2
|
depends on ARCH_PRIMA2
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
Support for the on-chip UART on the CSR SiRFprimaII series,
|
Support for the on-chip UART on the CSR SiRFprimaII series,
|
||||||
|
@ -347,7 +347,7 @@ config SERIAL_ZS_CONSOLE
|
||||||
|
|
||||||
config SERIAL_21285
|
config SERIAL_21285
|
||||||
tristate "DC21285 serial port support"
|
tristate "DC21285 serial port support"
|
||||||
depends on ARM && FOOTBRIDGE
|
depends on FOOTBRIDGE
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
|
If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
|
||||||
|
@ -371,7 +371,7 @@ config SERIAL_21285_CONSOLE
|
||||||
|
|
||||||
config SERIAL_MPSC
|
config SERIAL_MPSC
|
||||||
bool "Marvell MPSC serial port support"
|
bool "Marvell MPSC serial port support"
|
||||||
depends on PPC32 && MV64X60
|
depends on MV64X60
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
Say Y here if you want to use the Marvell MPSC serial controller.
|
Say Y here if you want to use the Marvell MPSC serial controller.
|
||||||
|
@ -408,7 +408,7 @@ config SERIAL_PXA_CONSOLE
|
||||||
|
|
||||||
config SERIAL_SA1100
|
config SERIAL_SA1100
|
||||||
bool "SA1100 serial port support"
|
bool "SA1100 serial port support"
|
||||||
depends on ARM && ARCH_SA1100
|
depends on ARCH_SA1100
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
|
If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
|
||||||
|
@ -716,7 +716,7 @@ config SERIAL_SH_SCI_DMA
|
||||||
|
|
||||||
config SERIAL_PNX8XXX
|
config SERIAL_PNX8XXX
|
||||||
bool "Enable PNX8XXX SoCs' UART Support"
|
bool "Enable PNX8XXX SoCs' UART Support"
|
||||||
depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
|
depends on SOC_PNX8550 || SOC_PNX833X
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
|
If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
|
||||||
|
@ -1013,7 +1013,7 @@ config SERIAL_SGI_IOC3
|
||||||
|
|
||||||
config SERIAL_MSM
|
config SERIAL_MSM
|
||||||
bool "MSM on-chip serial port support"
|
bool "MSM on-chip serial port support"
|
||||||
depends on ARM && ARCH_MSM
|
depends on ARCH_MSM
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
|
|
||||||
config SERIAL_MSM_CONSOLE
|
config SERIAL_MSM_CONSOLE
|
||||||
|
@ -1035,7 +1035,7 @@ config SERIAL_MSM_HS
|
||||||
|
|
||||||
config SERIAL_VT8500
|
config SERIAL_VT8500
|
||||||
bool "VIA VT8500 on-chip serial port support"
|
bool "VIA VT8500 on-chip serial port support"
|
||||||
depends on ARM && ARCH_VT8500
|
depends on ARCH_VT8500
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
|
|
||||||
config SERIAL_VT8500_CONSOLE
|
config SERIAL_VT8500_CONSOLE
|
||||||
|
@ -1045,7 +1045,7 @@ config SERIAL_VT8500_CONSOLE
|
||||||
|
|
||||||
config SERIAL_NETX
|
config SERIAL_NETX
|
||||||
tristate "NetX serial port support"
|
tristate "NetX serial port support"
|
||||||
depends on ARM && ARCH_NETX
|
depends on ARCH_NETX
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
If you have a machine based on a Hilscher NetX SoC you
|
If you have a machine based on a Hilscher NetX SoC you
|
||||||
|
@ -1376,6 +1376,7 @@ config SERIAL_MXS_AUART_CONSOLE
|
||||||
|
|
||||||
config SERIAL_XILINX_PS_UART
|
config SERIAL_XILINX_PS_UART
|
||||||
tristate "Xilinx PS UART support"
|
tristate "Xilinx PS UART support"
|
||||||
|
depends on OF
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
help
|
help
|
||||||
This driver supports the Xilinx PS UART port.
|
This driver supports the Xilinx PS UART port.
|
||||||
|
@ -1423,4 +1424,27 @@ config SERIAL_EFM32_UART_CONSOLE
|
||||||
depends on SERIAL_EFM32_UART=y
|
depends on SERIAL_EFM32_UART=y
|
||||||
select SERIAL_CORE_CONSOLE
|
select SERIAL_CORE_CONSOLE
|
||||||
|
|
||||||
|
config SERIAL_ARC
|
||||||
|
tristate "ARC UART driver support"
|
||||||
|
select SERIAL_CORE
|
||||||
|
help
|
||||||
|
Driver for on-chip UART for ARC(Synopsys) for the legacy
|
||||||
|
FPGA Boards (ML50x/ARCAngel4)
|
||||||
|
|
||||||
|
config SERIAL_ARC_CONSOLE
|
||||||
|
bool "Console on ARC UART"
|
||||||
|
depends on SERIAL_ARC=y
|
||||||
|
select SERIAL_CORE_CONSOLE
|
||||||
|
help
|
||||||
|
Enable system Console on ARC UART
|
||||||
|
|
||||||
|
config SERIAL_ARC_NR_PORTS
|
||||||
|
int "Number of ARC UART ports"
|
||||||
|
depends on SERIAL_ARC
|
||||||
|
range 1 3
|
||||||
|
default "1"
|
||||||
|
help
|
||||||
|
Set this to the number of serial ports you want the driver
|
||||||
|
to support.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -82,3 +82,4 @@ obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
|
||||||
obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
|
obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
|
||||||
obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o
|
obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o
|
||||||
obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o
|
obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o
|
||||||
|
obj-$(CONFIG_SERIAL_ARC) += arc_uart.o
|
||||||
|
|
|
@ -406,7 +406,7 @@ static struct uart_driver altera_jtaguart_driver = {
|
||||||
.cons = ALTERA_JTAGUART_CONSOLE,
|
.cons = ALTERA_JTAGUART_CONSOLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit altera_jtaguart_probe(struct platform_device *pdev)
|
static int altera_jtaguart_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data;
|
struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data;
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
|
@ -453,7 +453,7 @@ static int __devinit altera_jtaguart_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit altera_jtaguart_remove(struct platform_device *pdev)
|
static int altera_jtaguart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
int i = pdev->id;
|
int i = pdev->id;
|
||||||
|
@ -477,7 +477,7 @@ MODULE_DEVICE_TABLE(of, altera_jtaguart_match);
|
||||||
|
|
||||||
static struct platform_driver altera_jtaguart_platform_driver = {
|
static struct platform_driver altera_jtaguart_platform_driver = {
|
||||||
.probe = altera_jtaguart_probe,
|
.probe = altera_jtaguart_probe,
|
||||||
.remove = __devexit_p(altera_jtaguart_remove),
|
.remove = altera_jtaguart_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|
|
@ -532,7 +532,7 @@ static int altera_uart_get_of_uartclk(struct platform_device *pdev,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OF */
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
static int __devinit altera_uart_probe(struct platform_device *pdev)
|
static int altera_uart_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
|
struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
|
@ -598,7 +598,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit altera_uart_remove(struct platform_device *pdev)
|
static int altera_uart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct uart_port *port = platform_get_drvdata(pdev);
|
struct uart_port *port = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ MODULE_DEVICE_TABLE(of, altera_uart_match);
|
||||||
|
|
||||||
static struct platform_driver altera_uart_platform_driver = {
|
static struct platform_driver altera_uart_platform_driver = {
|
||||||
.probe = altera_uart_probe,
|
.probe = altera_uart_probe,
|
||||||
.remove = __devexit_p(altera_uart_remove),
|
.remove = altera_uart_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|
|
@ -56,8 +56,7 @@
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/consumer.h>
|
#include <linux/pinctrl/consumer.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
|
#include <linux/io.h>
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
#define UART_NR 14
|
#define UART_NR 14
|
||||||
|
|
||||||
|
@ -1973,7 +1972,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
|
uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port),
|
||||||
|
GFP_KERNEL);
|
||||||
if (uap == NULL) {
|
if (uap == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1981,16 +1981,17 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||||
|
|
||||||
i = pl011_probe_dt_alias(i, &dev->dev);
|
i = pl011_probe_dt_alias(i, &dev->dev);
|
||||||
|
|
||||||
base = ioremap(dev->res.start, resource_size(&dev->res));
|
base = devm_ioremap(&dev->dev, dev->res.start,
|
||||||
|
resource_size(&dev->res));
|
||||||
if (!base) {
|
if (!base) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto free;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uap->pinctrl = devm_pinctrl_get(&dev->dev);
|
uap->pinctrl = devm_pinctrl_get(&dev->dev);
|
||||||
if (IS_ERR(uap->pinctrl)) {
|
if (IS_ERR(uap->pinctrl)) {
|
||||||
ret = PTR_ERR(uap->pinctrl);
|
ret = PTR_ERR(uap->pinctrl);
|
||||||
goto unmap;
|
goto out;
|
||||||
}
|
}
|
||||||
uap->pins_default = pinctrl_lookup_state(uap->pinctrl,
|
uap->pins_default = pinctrl_lookup_state(uap->pinctrl,
|
||||||
PINCTRL_STATE_DEFAULT);
|
PINCTRL_STATE_DEFAULT);
|
||||||
|
@ -2002,10 +2003,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||||
if (IS_ERR(uap->pins_sleep))
|
if (IS_ERR(uap->pins_sleep))
|
||||||
dev_dbg(&dev->dev, "could not get sleep pinstate\n");
|
dev_dbg(&dev->dev, "could not get sleep pinstate\n");
|
||||||
|
|
||||||
uap->clk = clk_get(&dev->dev, NULL);
|
uap->clk = devm_clk_get(&dev->dev, NULL);
|
||||||
if (IS_ERR(uap->clk)) {
|
if (IS_ERR(uap->clk)) {
|
||||||
ret = PTR_ERR(uap->clk);
|
ret = PTR_ERR(uap->clk);
|
||||||
goto unmap;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uap->vendor = vendor;
|
uap->vendor = vendor;
|
||||||
|
@ -2038,11 +2039,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||||
amba_set_drvdata(dev, NULL);
|
amba_set_drvdata(dev, NULL);
|
||||||
amba_ports[i] = NULL;
|
amba_ports[i] = NULL;
|
||||||
pl011_dma_remove(uap);
|
pl011_dma_remove(uap);
|
||||||
clk_put(uap->clk);
|
|
||||||
unmap:
|
|
||||||
iounmap(base);
|
|
||||||
free:
|
|
||||||
kfree(uap);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2062,9 +2058,6 @@ static int pl011_remove(struct amba_device *dev)
|
||||||
amba_ports[i] = NULL;
|
amba_ports[i] = NULL;
|
||||||
|
|
||||||
pl011_dma_remove(uap);
|
pl011_dma_remove(uap);
|
||||||
iounmap(uap->port.membase);
|
|
||||||
clk_put(uap->clk);
|
|
||||||
kfree(uap);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -554,7 +554,7 @@ static struct uart_driver grlib_apbuart_driver = {
|
||||||
/* OF Platform Driver */
|
/* OF Platform Driver */
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
|
|
||||||
static int __devinit apbuart_probe(struct platform_device *op)
|
static int apbuart_probe(struct platform_device *op)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct uart_port *port = NULL;
|
struct uart_port *port = NULL;
|
||||||
|
|
|
@ -25,11 +25,19 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
|
||||||
|
#include <asm/div64.h>
|
||||||
|
|
||||||
#include <asm/mach-ath79/ar933x_uart.h>
|
#include <asm/mach-ath79/ar933x_uart.h>
|
||||||
#include <asm/mach-ath79/ar933x_uart_platform.h>
|
#include <asm/mach-ath79/ar933x_uart_platform.h>
|
||||||
|
|
||||||
#define DRIVER_NAME "ar933x-uart"
|
#define DRIVER_NAME "ar933x-uart"
|
||||||
|
|
||||||
|
#define AR933X_UART_MAX_SCALE 0xff
|
||||||
|
#define AR933X_UART_MAX_STEP 0xffff
|
||||||
|
|
||||||
|
#define AR933X_UART_MIN_BAUD 300
|
||||||
|
#define AR933X_UART_MAX_BAUD 3000000
|
||||||
|
|
||||||
#define AR933X_DUMMY_STATUS_RD 0x01
|
#define AR933X_DUMMY_STATUS_RD 0x01
|
||||||
|
|
||||||
static struct uart_driver ar933x_uart_driver;
|
static struct uart_driver ar933x_uart_driver;
|
||||||
|
@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_driver;
|
||||||
struct ar933x_uart_port {
|
struct ar933x_uart_port {
|
||||||
struct uart_port port;
|
struct uart_port port;
|
||||||
unsigned int ier; /* shadow Interrupt Enable Register */
|
unsigned int ier; /* shadow Interrupt Enable Register */
|
||||||
|
unsigned int min_baud;
|
||||||
|
unsigned int max_baud;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
|
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* baudrate = (clk / (scale + 1)) * (step * (1 / 2^17))
|
||||||
|
*/
|
||||||
|
static unsigned long ar933x_uart_get_baud(unsigned int clk,
|
||||||
|
unsigned int scale,
|
||||||
|
unsigned int step)
|
||||||
|
{
|
||||||
|
u64 t;
|
||||||
|
u32 div;
|
||||||
|
|
||||||
|
div = (2 << 16) * (scale + 1);
|
||||||
|
t = clk;
|
||||||
|
t *= step;
|
||||||
|
t += (div / 2);
|
||||||
|
do_div(t, div);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar933x_uart_get_scale_step(unsigned int clk,
|
||||||
|
unsigned int baud,
|
||||||
|
unsigned int *scale,
|
||||||
|
unsigned int *step)
|
||||||
|
{
|
||||||
|
unsigned int tscale;
|
||||||
|
long min_diff;
|
||||||
|
|
||||||
|
*scale = 0;
|
||||||
|
*step = 0;
|
||||||
|
|
||||||
|
min_diff = baud;
|
||||||
|
for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) {
|
||||||
|
u64 tstep;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
tstep = baud * (tscale + 1);
|
||||||
|
tstep *= (2 << 16);
|
||||||
|
do_div(tstep, clk);
|
||||||
|
|
||||||
|
if (tstep > AR933X_UART_MAX_STEP)
|
||||||
|
break;
|
||||||
|
|
||||||
|
diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud);
|
||||||
|
if (diff < min_diff) {
|
||||||
|
min_diff = diff;
|
||||||
|
*scale = tscale;
|
||||||
|
*step = tstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ar933x_uart_set_termios(struct uart_port *port,
|
static void ar933x_uart_set_termios(struct uart_port *port,
|
||||||
struct ktermios *new,
|
struct ktermios *new,
|
||||||
struct ktermios *old)
|
struct ktermios *old)
|
||||||
|
@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(struct uart_port *port,
|
||||||
struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
|
struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
|
||||||
unsigned int cs;
|
unsigned int cs;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int baud, scale;
|
unsigned int baud, scale, step;
|
||||||
|
|
||||||
/* Only CS8 is supported */
|
/* Only CS8 is supported */
|
||||||
new->c_cflag &= ~CSIZE;
|
new->c_cflag &= ~CSIZE;
|
||||||
|
@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(struct uart_port *port,
|
||||||
/* Mark/space parity is not supported */
|
/* Mark/space parity is not supported */
|
||||||
new->c_cflag &= ~CMSPAR;
|
new->c_cflag &= ~CMSPAR;
|
||||||
|
|
||||||
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
|
baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud);
|
||||||
scale = (port->uartclk / (16 * baud)) - 1;
|
ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok, we're now changing the port state. Do it with
|
* 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,
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&up->port.lock, flags);
|
spin_lock_irqsave(&up->port.lock, flags);
|
||||||
|
|
||||||
|
/* disable the UART */
|
||||||
|
ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
|
||||||
|
AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S);
|
||||||
|
|
||||||
/* Update the per-port timeout. */
|
/* Update the per-port timeout. */
|
||||||
uart_update_timeout(port, new->c_cflag, baud);
|
uart_update_timeout(port, new->c_cflag, baud);
|
||||||
|
|
||||||
|
@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(struct uart_port *port,
|
||||||
up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
|
up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
|
||||||
|
|
||||||
ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
|
ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
|
||||||
scale << AR933X_UART_CLOCK_SCALE_S | 8192);
|
scale << AR933X_UART_CLOCK_SCALE_S | step);
|
||||||
|
|
||||||
/* setup configuration register */
|
/* setup configuration register */
|
||||||
ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
|
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,
|
||||||
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
|
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
|
||||||
AR933X_UART_CS_HOST_INT_EN);
|
AR933X_UART_CS_HOST_INT_EN);
|
||||||
|
|
||||||
|
/* reenable the UART */
|
||||||
|
ar933x_uart_rmw(up, AR933X_UART_CS_REG,
|
||||||
|
AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S,
|
||||||
|
AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&up->port.lock, flags);
|
spin_unlock_irqrestore(&up->port.lock, flags);
|
||||||
|
|
||||||
if (tty_termios_baud_rate(new))
|
if (tty_termios_baud_rate(new))
|
||||||
|
@ -401,6 +471,8 @@ static void ar933x_uart_config_port(struct uart_port *port, int flags)
|
||||||
static int ar933x_uart_verify_port(struct uart_port *port,
|
static int ar933x_uart_verify_port(struct uart_port *port,
|
||||||
struct serial_struct *ser)
|
struct serial_struct *ser)
|
||||||
{
|
{
|
||||||
|
struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
|
||||||
|
|
||||||
if (ser->type != PORT_UNKNOWN &&
|
if (ser->type != PORT_UNKNOWN &&
|
||||||
ser->type != PORT_AR933X)
|
ser->type != PORT_AR933X)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struct uart_port *port,
|
||||||
if (ser->irq < 0 || ser->irq >= NR_IRQS)
|
if (ser->irq < 0 || ser->irq >= NR_IRQS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (ser->baud_base < 28800)
|
if (ser->baud_base < up->min_baud ||
|
||||||
|
ser->baud_base > up->max_baud)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -554,13 +627,14 @@ static struct uart_driver ar933x_uart_driver = {
|
||||||
.cons = AR933X_SERIAL_CONSOLE,
|
.cons = AR933X_SERIAL_CONSOLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit ar933x_uart_probe(struct platform_device *pdev)
|
static int ar933x_uart_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct ar933x_uart_platform_data *pdata;
|
struct ar933x_uart_platform_data *pdata;
|
||||||
struct ar933x_uart_port *up;
|
struct ar933x_uart_port *up;
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
struct resource *mem_res;
|
struct resource *mem_res;
|
||||||
struct resource *irq_res;
|
struct resource *irq_res;
|
||||||
|
unsigned int baud;
|
||||||
int id;
|
int id;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(struct platform_device *pdev)
|
||||||
port->fifosize = AR933X_UART_FIFO_SIZE;
|
port->fifosize = AR933X_UART_FIFO_SIZE;
|
||||||
port->ops = &ar933x_uart_ops;
|
port->ops = &ar933x_uart_ops;
|
||||||
|
|
||||||
|
baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
|
||||||
|
up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
|
||||||
|
|
||||||
|
baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
|
||||||
|
up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
|
||||||
|
|
||||||
ar933x_uart_add_console_port(up);
|
ar933x_uart_add_console_port(up);
|
||||||
|
|
||||||
ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
|
ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
|
||||||
|
@ -627,7 +707,7 @@ err_free_up:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit ar933x_uart_remove(struct platform_device *pdev)
|
static int ar933x_uart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct ar933x_uart_port *up;
|
struct ar933x_uart_port *up;
|
||||||
|
|
||||||
|
@ -645,7 +725,7 @@ static int __devexit ar933x_uart_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
static struct platform_driver ar933x_uart_platform_driver = {
|
static struct platform_driver ar933x_uart_platform_driver = {
|
||||||
.probe = ar933x_uart_probe,
|
.probe = ar933x_uart_probe,
|
||||||
.remove = __devexit_p(ar933x_uart_remove),
|
.remove = ar933x_uart_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|
|
@ -0,0 +1,746 @@
|
||||||
|
/*
|
||||||
|
* ARC On-Chip(fpga) UART Driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.com)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* vineetg: July 10th 2012
|
||||||
|
* -Decoupled the driver from arch/arc
|
||||||
|
* +Using platform_get_resource() for irq/membase (thx to bfin_uart.c)
|
||||||
|
* +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx)
|
||||||
|
*
|
||||||
|
* Vineetg: Aug 21st 2010
|
||||||
|
* -Is uart_tx_stopped() not done in tty write path as it has already been
|
||||||
|
* taken care of, in serial core
|
||||||
|
*
|
||||||
|
* Vineetg: Aug 18th 2010
|
||||||
|
* -New Serial Core based ARC UART driver
|
||||||
|
* -Derived largely from blackfin driver albiet with some major tweaks
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* -check if sysreq works
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_SERIAL_ARC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||||
|
#define SUPPORT_SYSRQ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#include <linux/console.h>
|
||||||
|
#include <linux/sysrq.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <linux/tty_flip.h>
|
||||||
|
#include <linux/serial_core.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
* ARC UART Hardware Specs
|
||||||
|
************************************/
|
||||||
|
#define ARC_UART_TX_FIFO_SIZE 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART Register set (this is not a Standards Compliant IP)
|
||||||
|
* Also each reg is Word aligned, but only 8 bits wide
|
||||||
|
*/
|
||||||
|
#define R_ID0 0
|
||||||
|
#define R_ID1 4
|
||||||
|
#define R_ID2 8
|
||||||
|
#define R_ID3 12
|
||||||
|
#define R_DATA 16
|
||||||
|
#define R_STS 20
|
||||||
|
#define R_BAUDL 24
|
||||||
|
#define R_BAUDH 28
|
||||||
|
|
||||||
|
/* Bits for UART Status Reg (R/W) */
|
||||||
|
#define RXIENB 0x04 /* Receive Interrupt Enable */
|
||||||
|
#define TXIENB 0x40 /* Transmit Interrupt Enable */
|
||||||
|
|
||||||
|
#define RXEMPTY 0x20 /* Receive FIFO Empty: No char receivede */
|
||||||
|
#define TXEMPTY 0x80 /* Transmit FIFO Empty, thus char can be written into */
|
||||||
|
|
||||||
|
#define RXFULL 0x08 /* Receive FIFO full */
|
||||||
|
#define RXFULL1 0x10 /* Receive FIFO has space for 1 char (tot space=4) */
|
||||||
|
|
||||||
|
#define RXFERR 0x01 /* Frame Error: Stop Bit not detected */
|
||||||
|
#define RXOERR 0x02 /* OverFlow Err: Char recv but RXFULL still set */
|
||||||
|
|
||||||
|
/* Uart bit fiddling helpers: lowest level */
|
||||||
|
#define RBASE(uart, reg) (uart->port.membase + reg)
|
||||||
|
#define UART_REG_SET(u, r, v) writeb((v), RBASE(u, r))
|
||||||
|
#define UART_REG_GET(u, r) readb(RBASE(u, r))
|
||||||
|
|
||||||
|
#define UART_REG_OR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) | (v))
|
||||||
|
#define UART_REG_CLR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) & ~(v))
|
||||||
|
|
||||||
|
/* Uart bit fiddling helpers: API level */
|
||||||
|
#define UART_SET_DATA(uart, val) UART_REG_SET(uart, R_DATA, val)
|
||||||
|
#define UART_GET_DATA(uart) UART_REG_GET(uart, R_DATA)
|
||||||
|
|
||||||
|
#define UART_SET_BAUDH(uart, val) UART_REG_SET(uart, R_BAUDH, val)
|
||||||
|
#define UART_SET_BAUDL(uart, val) UART_REG_SET(uart, R_BAUDL, val)
|
||||||
|
|
||||||
|
#define UART_CLR_STATUS(uart, val) UART_REG_CLR(uart, R_STS, val)
|
||||||
|
#define UART_GET_STATUS(uart) UART_REG_GET(uart, R_STS)
|
||||||
|
|
||||||
|
#define UART_ALL_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB|TXIENB)
|
||||||
|
#define UART_RX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB)
|
||||||
|
#define UART_TX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, TXIENB)
|
||||||
|
|
||||||
|
#define UART_ALL_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB|TXIENB)
|
||||||
|
#define UART_RX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB)
|
||||||
|
#define UART_TX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, TXIENB)
|
||||||
|
|
||||||
|
#define ARC_SERIAL_DEV_NAME "ttyARC"
|
||||||
|
|
||||||
|
struct arc_uart_port {
|
||||||
|
struct uart_port port;
|
||||||
|
unsigned long baud;
|
||||||
|
int is_emulated; /* H/w vs. Instruction Set Simulator */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_arc_port(uport) container_of(uport, struct arc_uart_port, port)
|
||||||
|
|
||||||
|
static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS];
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_ARC_CONSOLE
|
||||||
|
static struct console arc_console;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DRIVER_NAME "arc-uart"
|
||||||
|
|
||||||
|
static struct uart_driver arc_uart_driver = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.driver_name = DRIVER_NAME,
|
||||||
|
.dev_name = ARC_SERIAL_DEV_NAME,
|
||||||
|
.major = 0,
|
||||||
|
.minor = 0,
|
||||||
|
.nr = CONFIG_SERIAL_ARC_NR_PORTS,
|
||||||
|
#ifdef CONFIG_SERIAL_ARC_CONSOLE
|
||||||
|
.cons = &arc_console,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void arc_serial_stop_rx(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
UART_RX_IRQ_DISABLE(uart);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_serial_stop_tx(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
while (!(UART_GET_STATUS(uart) & TXEMPTY))
|
||||||
|
cpu_relax();
|
||||||
|
|
||||||
|
UART_TX_IRQ_DISABLE(uart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TIOCSER_TEMT when transmitter is not busy.
|
||||||
|
*/
|
||||||
|
static unsigned int arc_serial_tx_empty(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
unsigned int stat;
|
||||||
|
|
||||||
|
stat = UART_GET_STATUS(uart);
|
||||||
|
if (stat & TXEMPTY)
|
||||||
|
return TIOCSER_TEMT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver internal routine, used by both tty(serial core) as well as tx-isr
|
||||||
|
* -Called under spinlock in either cases
|
||||||
|
* -also tty->stopped / tty->hw_stopped has already been checked
|
||||||
|
* = by uart_start( ) before calling us
|
||||||
|
* = tx_ist checks that too before calling
|
||||||
|
*/
|
||||||
|
static void arc_serial_tx_chars(struct arc_uart_port *uart)
|
||||||
|
{
|
||||||
|
struct circ_buf *xmit = &uart->port.state->xmit;
|
||||||
|
int sent = 0;
|
||||||
|
unsigned char ch;
|
||||||
|
|
||||||
|
if (unlikely(uart->port.x_char)) {
|
||||||
|
UART_SET_DATA(uart, uart->port.x_char);
|
||||||
|
uart->port.icount.tx++;
|
||||||
|
uart->port.x_char = 0;
|
||||||
|
sent = 1;
|
||||||
|
} else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */
|
||||||
|
ch = xmit->buf[xmit->tail];
|
||||||
|
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||||
|
uart->port.icount.tx++;
|
||||||
|
while (!(UART_GET_STATUS(uart) & TXEMPTY))
|
||||||
|
cpu_relax();
|
||||||
|
UART_SET_DATA(uart, ch);
|
||||||
|
sent = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If num chars in xmit buffer are too few, ask tty layer for more.
|
||||||
|
* By Hard ISR to schedule processing in software interrupt part
|
||||||
|
*/
|
||||||
|
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||||
|
uart_write_wakeup(&uart->port);
|
||||||
|
|
||||||
|
if (sent)
|
||||||
|
UART_TX_IRQ_ENABLE(uart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* port is locked and interrupts are disabled
|
||||||
|
* uart_start( ) calls us under the port spinlock irqsave
|
||||||
|
*/
|
||||||
|
static void arc_serial_start_tx(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
arc_serial_tx_chars(uart);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_serial_rx_chars(struct arc_uart_port *uart)
|
||||||
|
{
|
||||||
|
struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port);
|
||||||
|
unsigned int status, ch, flg = 0;
|
||||||
|
|
||||||
|
if (!tty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART has 4 deep RX-FIFO. Driver's recongnition of this fact
|
||||||
|
* is very subtle. Here's how ...
|
||||||
|
* Upon getting a RX-Intr, such that RX-EMPTY=0, meaning data available,
|
||||||
|
* driver reads the DATA Reg and keeps doing that in a loop, until
|
||||||
|
* RX-EMPTY=1. Multiple chars being avail, with a single Interrupt,
|
||||||
|
* before RX-EMPTY=0, implies some sort of buffering going on in the
|
||||||
|
* controller, which is indeed the Rx-FIFO.
|
||||||
|
*/
|
||||||
|
while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) {
|
||||||
|
|
||||||
|
ch = UART_GET_DATA(uart);
|
||||||
|
uart->port.icount.rx++;
|
||||||
|
|
||||||
|
if (unlikely(status & (RXOERR | RXFERR))) {
|
||||||
|
if (status & RXOERR) {
|
||||||
|
uart->port.icount.overrun++;
|
||||||
|
flg = TTY_OVERRUN;
|
||||||
|
UART_CLR_STATUS(uart, RXOERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & RXFERR) {
|
||||||
|
uart->port.icount.frame++;
|
||||||
|
flg = TTY_FRAME;
|
||||||
|
UART_CLR_STATUS(uart, RXFERR);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
flg = TTY_NORMAL;
|
||||||
|
|
||||||
|
if (unlikely(uart_handle_sysrq_char(&uart->port, ch)))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
uart_insert_char(&uart->port, status, RXOERR, ch, flg);
|
||||||
|
|
||||||
|
done:
|
||||||
|
tty_flip_buffer_push(tty);
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_kref_put(tty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A note on the Interrupt handling state machine of this driver
|
||||||
|
*
|
||||||
|
* kernel printk writes funnel thru the console driver framework and in order
|
||||||
|
* to keep things simple as well as efficient, it writes to UART in polled
|
||||||
|
* mode, in one shot, and exits.
|
||||||
|
*
|
||||||
|
* OTOH, Userland output (via tty layer), uses interrupt based writes as there
|
||||||
|
* can be undeterministic delay between char writes.
|
||||||
|
*
|
||||||
|
* Thus Rx-interrupts are always enabled, while tx-interrupts are by default
|
||||||
|
* disabled.
|
||||||
|
*
|
||||||
|
* When tty has some data to send out, serial core calls driver's start_tx
|
||||||
|
* which
|
||||||
|
* -checks-if-tty-buffer-has-char-to-send
|
||||||
|
* -writes-data-to-uart
|
||||||
|
* -enable-tx-intr
|
||||||
|
*
|
||||||
|
* Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt.
|
||||||
|
* The first thing Tx ISR does is disable further Tx interrupts (as this could
|
||||||
|
* be the last char to send, before settling down into the quiet polled mode).
|
||||||
|
* It then calls the exact routine used by tty layer write to send out any
|
||||||
|
* more char in tty buffer. In case of sending, it re-enables Tx-intr. In case
|
||||||
|
* of no data, it remains disabled.
|
||||||
|
* This is how the transmit state machine is dynamically switched on/off
|
||||||
|
*/
|
||||||
|
|
||||||
|
static irqreturn_t arc_serial_isr(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = dev_id;
|
||||||
|
unsigned int status;
|
||||||
|
|
||||||
|
status = UART_GET_STATUS(uart);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Single IRQ for both Rx (data available) Tx (room available) Interrupt
|
||||||
|
* notifications from the UART Controller.
|
||||||
|
* To demultiplex between the two, we check the relevant bits
|
||||||
|
*/
|
||||||
|
if ((status & RXIENB) && !(status & RXEMPTY)) {
|
||||||
|
|
||||||
|
/* already in ISR, no need of xx_irqsave */
|
||||||
|
spin_lock(&uart->port.lock);
|
||||||
|
arc_serial_rx_chars(uart);
|
||||||
|
spin_unlock(&uart->port.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status & TXIENB) && (status & TXEMPTY)) {
|
||||||
|
|
||||||
|
/* Unconditionally disable further Tx-Interrupts.
|
||||||
|
* will be enabled by tx_chars() if needed.
|
||||||
|
*/
|
||||||
|
UART_TX_IRQ_DISABLE(uart);
|
||||||
|
|
||||||
|
spin_lock(&uart->port.lock);
|
||||||
|
|
||||||
|
if (!uart_tx_stopped(&uart->port))
|
||||||
|
arc_serial_tx_chars(uart);
|
||||||
|
|
||||||
|
spin_unlock(&uart->port.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int arc_serial_get_mctrl(struct uart_port *port)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Pretend we have a Modem status reg and following bits are
|
||||||
|
* always set, to satify the serial core state machine
|
||||||
|
* (DSR) Data Set Ready
|
||||||
|
* (CTS) Clear To Send
|
||||||
|
* (CAR) Carrier Detect
|
||||||
|
*/
|
||||||
|
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||||
|
{
|
||||||
|
/* MCR not present */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable Modem Status Interrupts */
|
||||||
|
|
||||||
|
static void arc_serial_enable_ms(struct uart_port *port)
|
||||||
|
{
|
||||||
|
/* MSR not present */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_serial_break_ctl(struct uart_port *port, int break_state)
|
||||||
|
{
|
||||||
|
/* ARC UART doesn't support sending Break signal */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_serial_startup(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
/* Before we hook up the ISR, Disable all UART Interrupts */
|
||||||
|
UART_ALL_IRQ_DISABLE(uart);
|
||||||
|
|
||||||
|
if (request_irq(uart->port.irq, arc_serial_isr, 0, "arc uart rx-tx",
|
||||||
|
uart)) {
|
||||||
|
dev_warn(uart->port.dev, "Unable to attach ARC UART intr\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
UART_RX_IRQ_ENABLE(uart); /* Only Rx IRQ enabled to begin with */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is not really needed */
|
||||||
|
static void arc_serial_shutdown(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
free_irq(uart->port.irq, uart);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
arc_serial_set_termios(struct uart_port *port, struct ktermios *new,
|
||||||
|
struct ktermios *old)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
unsigned int baud, uartl, uarth, hw_val;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the generic handler so that any specially encoded baud rates
|
||||||
|
* such as SPD_xx flags or "%B0" can be handled
|
||||||
|
* Max Baud I suppose will not be more than current 115K * 4
|
||||||
|
* Formula for ARC UART is: hw-val = ((CLK/(BAUD*4)) -1)
|
||||||
|
* spread over two 8-bit registers
|
||||||
|
*/
|
||||||
|
baud = uart_get_baud_rate(port, new, old, 0, 460800);
|
||||||
|
|
||||||
|
hw_val = port->uartclk / (uart->baud * 4) - 1;
|
||||||
|
uartl = hw_val & 0xFF;
|
||||||
|
uarth = (hw_val >> 8) & 0xFF;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART ISS(Instruction Set simulator) emulation has a subtle bug:
|
||||||
|
* A existing value of Baudh = 0 is used as a indication to startup
|
||||||
|
* it's internal state machine.
|
||||||
|
* Thus if baudh is set to 0, 2 times, it chokes.
|
||||||
|
* This happens with BAUD=115200 and the formaula above
|
||||||
|
* Until that is fixed, when running on ISS, we will set baudh to !0
|
||||||
|
*/
|
||||||
|
if (uart->is_emulated)
|
||||||
|
uarth = 1;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
|
|
||||||
|
UART_ALL_IRQ_DISABLE(uart);
|
||||||
|
|
||||||
|
UART_SET_BAUDL(uart, uartl);
|
||||||
|
UART_SET_BAUDH(uart, uarth);
|
||||||
|
|
||||||
|
UART_RX_IRQ_ENABLE(uart);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART doesn't support Parity/Hardware Flow Control;
|
||||||
|
* Only supports 8N1 character size
|
||||||
|
*/
|
||||||
|
new->c_cflag &= ~(CMSPAR|CRTSCTS|CSIZE);
|
||||||
|
new->c_cflag |= CS8;
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
tty_termios_copy_hw(new, old);
|
||||||
|
|
||||||
|
/* Don't rewrite B0 */
|
||||||
|
if (tty_termios_baud_rate(new))
|
||||||
|
tty_termios_encode_baud_rate(new, baud, baud);
|
||||||
|
|
||||||
|
uart_update_timeout(port, new->c_cflag, baud);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *arc_serial_type(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
return uart->port.type == PORT_ARC ? DRIVER_NAME : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_serial_release_port(struct uart_port *port)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_serial_request_port(struct uart_port *port)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify the new serial_struct (for TIOCSSERIAL).
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
|
||||||
|
{
|
||||||
|
if (port->type != PORT_UNKNOWN && ser->type != PORT_ARC)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure/autoconfigure the port.
|
||||||
|
*/
|
||||||
|
static void arc_serial_config_port(struct uart_port *port, int flags)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
if (flags & UART_CONFIG_TYPE)
|
||||||
|
uart->port.type = PORT_ARC;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_ARC_CONSOLE)
|
||||||
|
|
||||||
|
static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
|
||||||
|
while (!(UART_GET_STATUS(uart) & TXEMPTY))
|
||||||
|
cpu_relax();
|
||||||
|
|
||||||
|
UART_SET_DATA(uart, chr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
static int arc_serial_poll_getchar(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart = to_arc_port(port);
|
||||||
|
unsigned char chr;
|
||||||
|
|
||||||
|
while (!(UART_GET_STATUS(uart) & RXEMPTY))
|
||||||
|
cpu_relax();
|
||||||
|
|
||||||
|
chr = UART_GET_DATA(uart);
|
||||||
|
return chr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct uart_ops arc_serial_pops = {
|
||||||
|
.tx_empty = arc_serial_tx_empty,
|
||||||
|
.set_mctrl = arc_serial_set_mctrl,
|
||||||
|
.get_mctrl = arc_serial_get_mctrl,
|
||||||
|
.stop_tx = arc_serial_stop_tx,
|
||||||
|
.start_tx = arc_serial_start_tx,
|
||||||
|
.stop_rx = arc_serial_stop_rx,
|
||||||
|
.enable_ms = arc_serial_enable_ms,
|
||||||
|
.break_ctl = arc_serial_break_ctl,
|
||||||
|
.startup = arc_serial_startup,
|
||||||
|
.shutdown = arc_serial_shutdown,
|
||||||
|
.set_termios = arc_serial_set_termios,
|
||||||
|
.type = arc_serial_type,
|
||||||
|
.release_port = arc_serial_release_port,
|
||||||
|
.request_port = arc_serial_request_port,
|
||||||
|
.config_port = arc_serial_config_port,
|
||||||
|
.verify_port = arc_serial_verify_port,
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
.poll_put_char = arc_serial_poll_putchar,
|
||||||
|
.poll_get_char = arc_serial_poll_getchar,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart)
|
||||||
|
{
|
||||||
|
struct resource *res, *res2;
|
||||||
|
unsigned long *plat_data;
|
||||||
|
|
||||||
|
if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) {
|
||||||
|
dev_err(&pdev->dev, "Wrong uart platform device id.\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
plat_data = ((unsigned long *)(pdev->dev.platform_data));
|
||||||
|
uart->baud = plat_data[0];
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||||
|
if (!res2)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
uart->port.mapbase = res->start;
|
||||||
|
uart->port.membase = ioremap_nocache(res->start, resource_size(res));
|
||||||
|
if (!uart->port.membase)
|
||||||
|
/* No point of dev_err since UART itself is hosed here */
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
uart->port.irq = res2->start;
|
||||||
|
uart->port.dev = &pdev->dev;
|
||||||
|
uart->port.iotype = UPIO_MEM;
|
||||||
|
uart->port.flags = UPF_BOOT_AUTOCONF;
|
||||||
|
uart->port.line = pdev->id;
|
||||||
|
uart->port.ops = &arc_serial_pops;
|
||||||
|
|
||||||
|
uart->port.uartclk = plat_data[1];
|
||||||
|
uart->port.fifosize = ARC_UART_TX_FIFO_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uart_insert_char( ) uses it in decideding whether to ignore a
|
||||||
|
* char or not. Explicitly setting it here, removes the subtelty
|
||||||
|
*/
|
||||||
|
uart->port.ignore_status_mask = 0;
|
||||||
|
|
||||||
|
/* Real Hardware vs. emulated to work around a bug */
|
||||||
|
uart->is_emulated = !!plat_data[2];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_ARC_CONSOLE
|
||||||
|
|
||||||
|
static int arc_serial_console_setup(struct console *co, char *options)
|
||||||
|
{
|
||||||
|
struct uart_port *port;
|
||||||
|
int baud = 115200;
|
||||||
|
int bits = 8;
|
||||||
|
int parity = 'n';
|
||||||
|
int flow = 'n';
|
||||||
|
|
||||||
|
if (co->index < 0 || co->index >= CONFIG_SERIAL_ARC_NR_PORTS)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The uart port backing the console (e.g. ttyARC1) might not have been
|
||||||
|
* init yet. If so, defer the console setup to after the port.
|
||||||
|
*/
|
||||||
|
port = &arc_uart_ports[co->index].port;
|
||||||
|
if (!port->membase)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (options)
|
||||||
|
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial core will call port->ops->set_termios( )
|
||||||
|
* which will set the baud reg
|
||||||
|
*/
|
||||||
|
return uart_set_options(port, co, baud, parity, bits, flow);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_serial_console_putchar(struct uart_port *port, int ch)
|
||||||
|
{
|
||||||
|
arc_serial_poll_putchar(port, (unsigned char)ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupts are disabled on entering
|
||||||
|
*/
|
||||||
|
static void arc_serial_console_write(struct console *co, const char *s,
|
||||||
|
unsigned int count)
|
||||||
|
{
|
||||||
|
struct uart_port *port = &arc_uart_ports[co->index].port;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
|
uart_console_write(port, s, count, arc_serial_console_putchar);
|
||||||
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct console arc_console = {
|
||||||
|
.name = ARC_SERIAL_DEV_NAME,
|
||||||
|
.write = arc_serial_console_write,
|
||||||
|
.device = uart_console_device,
|
||||||
|
.setup = arc_serial_console_setup,
|
||||||
|
.flags = CON_PRINTBUFFER,
|
||||||
|
.index = -1,
|
||||||
|
.data = &arc_uart_driver
|
||||||
|
};
|
||||||
|
|
||||||
|
static __init void early_serial_write(struct console *con, const char *s,
|
||||||
|
unsigned int n)
|
||||||
|
{
|
||||||
|
struct uart_port *port = &arc_uart_ports[con->index].port;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++, s++) {
|
||||||
|
if (*s == '\n')
|
||||||
|
arc_serial_poll_putchar(port, '\r');
|
||||||
|
arc_serial_poll_putchar(port, *s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct __initdata console arc_early_serial_console = {
|
||||||
|
.name = "early_ARCuart",
|
||||||
|
.write = early_serial_write,
|
||||||
|
.flags = CON_PRINTBUFFER | CON_BOOT,
|
||||||
|
.index = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
static int arc_serial_probe_earlyprintk(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
arc_early_serial_console.index = pdev->id;
|
||||||
|
|
||||||
|
arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]);
|
||||||
|
|
||||||
|
arc_serial_console_setup(&arc_early_serial_console, NULL);
|
||||||
|
|
||||||
|
register_console(&arc_early_serial_console);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int arc_serial_probe_earlyprintk(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SERIAL_ARC_CONSOLE */
|
||||||
|
|
||||||
|
static int arc_serial_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct arc_uart_port *uart;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (is_early_platform_device(pdev))
|
||||||
|
return arc_serial_probe_earlyprintk(pdev);
|
||||||
|
|
||||||
|
uart = &arc_uart_ports[pdev->id];
|
||||||
|
rc = arc_uart_init_one(pdev, uart);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return uart_add_one_port(&arc_uart_driver, &uart->port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_serial_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
/* This will never be called */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver arc_platform_driver = {
|
||||||
|
.probe = arc_serial_probe,
|
||||||
|
.remove = arc_serial_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_ARC_CONSOLE
|
||||||
|
/*
|
||||||
|
* Register an early platform driver of "earlyprintk" class.
|
||||||
|
* ARCH platform code installs the driver and probes the early devices
|
||||||
|
* The installation could rely on user specifying earlyprintk=xyx in cmd line
|
||||||
|
* or it could be done independently, for all "earlyprintk" class drivers.
|
||||||
|
* [see arch/arc/plat-arcfpga/platform.c]
|
||||||
|
*/
|
||||||
|
early_platform_init("earlyprintk", &arc_platform_driver);
|
||||||
|
|
||||||
|
#endif /* CONFIG_SERIAL_ARC_CONSOLE */
|
||||||
|
|
||||||
|
static int __init arc_serial_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = uart_register_driver(&arc_uart_driver);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = platform_driver_register(&arc_platform_driver);
|
||||||
|
if (ret)
|
||||||
|
uart_unregister_driver(&arc_uart_driver);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit arc_serial_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&arc_platform_driver);
|
||||||
|
uart_unregister_driver(&arc_uart_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(arc_serial_init);
|
||||||
|
module_exit(arc_serial_exit);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_ALIAS("plat-arcfpga/uart");
|
||||||
|
MODULE_AUTHOR("Vineet Gupta");
|
||||||
|
MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");
|
|
@ -1424,7 +1424,7 @@ static struct uart_ops atmel_pops = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
|
static void atmel_of_init_port(struct atmel_uart_port *atmel_port,
|
||||||
struct device_node *np)
|
struct device_node *np)
|
||||||
{
|
{
|
||||||
u32 rs485_delay[2];
|
u32 rs485_delay[2];
|
||||||
|
@ -1459,7 +1459,7 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
|
||||||
/*
|
/*
|
||||||
* Configure the port from the platform device resource info.
|
* Configure the port from the platform device resource info.
|
||||||
*/
|
*/
|
||||||
static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
|
static void atmel_init_port(struct atmel_uart_port *atmel_port,
|
||||||
struct platform_device *pdev)
|
struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct uart_port *port = &atmel_port->uart;
|
struct uart_port *port = &atmel_port->uart;
|
||||||
|
@ -1767,7 +1767,7 @@ static int atmel_serial_resume(struct platform_device *pdev)
|
||||||
#define atmel_serial_resume NULL
|
#define atmel_serial_resume NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __devinit atmel_serial_probe(struct platform_device *pdev)
|
static int atmel_serial_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct atmel_uart_port *port;
|
struct atmel_uart_port *port;
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
@ -1859,7 +1859,7 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit atmel_serial_remove(struct platform_device *pdev)
|
static int atmel_serial_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct uart_port *port = platform_get_drvdata(pdev);
|
struct uart_port *port = platform_get_drvdata(pdev);
|
||||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
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)
|
||||||
|
|
||||||
static struct platform_driver atmel_serial_driver = {
|
static struct platform_driver atmel_serial_driver = {
|
||||||
.probe = atmel_serial_probe,
|
.probe = atmel_serial_probe,
|
||||||
.remove = __devexit_p(atmel_serial_remove),
|
.remove = atmel_serial_remove,
|
||||||
.suspend = atmel_serial_suspend,
|
.suspend = atmel_serial_suspend,
|
||||||
.resume = atmel_serial_resume,
|
.resume = atmel_serial_resume,
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|
|
@ -801,7 +801,7 @@ static struct uart_driver bcm_uart_driver = {
|
||||||
/*
|
/*
|
||||||
* platform driver probe/remove callback
|
* platform driver probe/remove callback
|
||||||
*/
|
*/
|
||||||
static int __devinit bcm_uart_probe(struct platform_device *pdev)
|
static int bcm_uart_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res_mem, *res_irq;
|
struct resource *res_mem, *res_irq;
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
|
@ -848,7 +848,7 @@ static int __devinit bcm_uart_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit bcm_uart_remove(struct platform_device *pdev)
|
static int bcm_uart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ static int __devexit bcm_uart_remove(struct platform_device *pdev)
|
||||||
*/
|
*/
|
||||||
static struct platform_driver bcm_uart_platform_driver = {
|
static struct platform_driver bcm_uart_platform_driver = {
|
||||||
.probe = bcm_uart_probe,
|
.probe = bcm_uart_probe,
|
||||||
.remove = __devexit_p(bcm_uart_remove),
|
.remove = bcm_uart_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "bcm63xx_uart",
|
.name = "bcm63xx_uart",
|
||||||
|
|
|
@ -740,7 +740,7 @@ static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __devinit sport_uart_probe(struct platform_device *pdev)
|
static int sport_uart_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct sport_uart_port *sport;
|
struct sport_uart_port *sport;
|
||||||
|
@ -850,7 +850,7 @@ out_error_free_mem:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit sport_uart_remove(struct platform_device *pdev)
|
static int sport_uart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct sport_uart_port *sport = platform_get_drvdata(pdev);
|
struct sport_uart_port *sport = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -871,7 +871,7 @@ static int __devexit sport_uart_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
static struct platform_driver sport_uart_driver = {
|
static struct platform_driver sport_uart_driver = {
|
||||||
.probe = sport_uart_probe,
|
.probe = sport_uart_probe,
|
||||||
.remove = __devexit_p(sport_uart_remove),
|
.remove = sport_uart_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
|
@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
|
||||||
void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
|
void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
|
||||||
{
|
{
|
||||||
int x_pos, pos;
|
int x_pos, pos;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
dma_disable_irq_nosync(uart->rx_dma_channel);
|
spin_lock_irqsave(&uart->rx_lock, flags);
|
||||||
spin_lock_bh(&uart->rx_lock);
|
|
||||||
|
|
||||||
/* 2D DMA RX buffer ring is used. Because curr_y_count and
|
/* 2D DMA RX buffer ring is used. Because curr_y_count and
|
||||||
* curr_x_count can't be read as an atomic operation,
|
* 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)
|
||||||
uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
|
uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_bh(&uart->rx_lock);
|
spin_unlock_irqrestore(&uart->rx_lock, flags);
|
||||||
dma_enable_irq(uart->rx_dma_channel);
|
|
||||||
|
|
||||||
mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
|
mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
|
||||||
}
|
}
|
||||||
|
@ -800,6 +799,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int baud, quot;
|
unsigned int baud, quot;
|
||||||
unsigned int ier, lcr = 0;
|
unsigned int ier, lcr = 0;
|
||||||
|
unsigned long timeout;
|
||||||
|
|
||||||
switch (termios->c_cflag & CSIZE) {
|
switch (termios->c_cflag & CSIZE) {
|
||||||
case CS8:
|
case CS8:
|
||||||
|
@ -869,6 +869,14 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||||
|
|
||||||
UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
|
UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
|
||||||
|
|
||||||
|
/* Wait till the transfer buffer is empty */
|
||||||
|
timeout = jiffies + msecs_to_jiffies(10);
|
||||||
|
while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT))
|
||||||
|
if (time_after(jiffies, timeout)) {
|
||||||
|
dev_warn(port->dev, "timeout waiting for TX buffer empty\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable UART */
|
/* Disable UART */
|
||||||
ier = UART_GET_IER(uart);
|
ier = UART_GET_IER(uart);
|
||||||
UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
|
UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
|
||||||
|
@ -1390,7 +1398,7 @@ out_error_free_mem:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit bfin_serial_remove(struct platform_device *pdev)
|
static int bfin_serial_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct bfin_serial_port *uart = platform_get_drvdata(pdev);
|
struct bfin_serial_port *uart = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -1410,7 +1418,7 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
static struct platform_driver bfin_serial_driver = {
|
static struct platform_driver bfin_serial_driver = {
|
||||||
.probe = bfin_serial_probe,
|
.probe = bfin_serial_probe,
|
||||||
.remove = __devexit_p(bfin_serial_remove),
|
.remove = bfin_serial_remove,
|
||||||
.suspend = bfin_serial_suspend,
|
.suspend = bfin_serial_suspend,
|
||||||
.resume = bfin_serial_resume,
|
.resume = bfin_serial_resume,
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|
|
@ -10,15 +10,6 @@
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||||
|
@ -26,172 +17,169 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/console.h>
|
|
||||||
#include <linux/sysrq.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/tty.h>
|
#include <linux/console.h>
|
||||||
#include <linux/tty_flip.h>
|
|
||||||
#include <linux/serial_core.h>
|
#include <linux/serial_core.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <linux/tty_flip.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/irq.h>
|
|
||||||
|
|
||||||
#define UART_NR 2
|
#define UART_CLPS711X_NAME "uart-clps711x"
|
||||||
|
#define UART_CLPS711X_NR 2
|
||||||
|
#define UART_CLPS711X_MAJOR 204
|
||||||
|
#define UART_CLPS711X_MINOR 40
|
||||||
|
|
||||||
#define SERIAL_CLPS711X_MAJOR 204
|
#define UBRLCR(port) ((port)->line ? UBRLCR2 : UBRLCR1)
|
||||||
#define SERIAL_CLPS711X_MINOR 40
|
#define UARTDR(port) ((port)->line ? UARTDR2 : UARTDR1)
|
||||||
#define SERIAL_CLPS711X_NR UART_NR
|
#define SYSFLG(port) ((port)->line ? SYSFLG2 : SYSFLG1)
|
||||||
|
#define SYSCON(port) ((port)->line ? SYSCON2 : SYSCON1)
|
||||||
|
#define TX_IRQ(port) ((port)->line ? IRQ_UTXINT2 : IRQ_UTXINT1)
|
||||||
|
#define RX_IRQ(port) ((port)->line ? IRQ_URXINT2 : IRQ_URXINT1)
|
||||||
|
|
||||||
/*
|
struct clps711x_port {
|
||||||
* We use the relevant SYSCON register as a base address for these ports.
|
struct uart_driver uart;
|
||||||
*/
|
struct clk *uart_clk;
|
||||||
#define UBRLCR(port) ((port)->iobase + UBRLCR1 - SYSCON1)
|
struct uart_port port[UART_CLPS711X_NR];
|
||||||
#define UARTDR(port) ((port)->iobase + UARTDR1 - SYSCON1)
|
int tx_enabled[UART_CLPS711X_NR];
|
||||||
#define SYSFLG(port) ((port)->iobase + SYSFLG1 - SYSCON1)
|
#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
|
||||||
#define SYSCON(port) ((port)->iobase + SYSCON1 - SYSCON1)
|
struct console console;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#define TX_IRQ(port) ((port)->irq)
|
static void uart_clps711x_stop_tx(struct uart_port *port)
|
||||||
#define RX_IRQ(port) ((port)->irq + 1)
|
|
||||||
|
|
||||||
#define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR)
|
|
||||||
|
|
||||||
#define tx_enabled(port) ((port)->unused[0])
|
|
||||||
|
|
||||||
static void clps711xuart_stop_tx(struct uart_port *port)
|
|
||||||
{
|
{
|
||||||
if (tx_enabled(port)) {
|
struct clps711x_port *s = dev_get_drvdata(port->dev);
|
||||||
|
|
||||||
|
if (s->tx_enabled[port->line]) {
|
||||||
disable_irq(TX_IRQ(port));
|
disable_irq(TX_IRQ(port));
|
||||||
tx_enabled(port) = 0;
|
s->tx_enabled[port->line] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711xuart_start_tx(struct uart_port *port)
|
static void uart_clps711x_start_tx(struct uart_port *port)
|
||||||
{
|
{
|
||||||
if (!tx_enabled(port)) {
|
struct clps711x_port *s = dev_get_drvdata(port->dev);
|
||||||
|
|
||||||
|
if (!s->tx_enabled[port->line]) {
|
||||||
enable_irq(TX_IRQ(port));
|
enable_irq(TX_IRQ(port));
|
||||||
tx_enabled(port) = 1;
|
s->tx_enabled[port->line] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711xuart_stop_rx(struct uart_port *port)
|
static void uart_clps711x_stop_rx(struct uart_port *port)
|
||||||
{
|
{
|
||||||
disable_irq(RX_IRQ(port));
|
disable_irq(RX_IRQ(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711xuart_enable_ms(struct uart_port *port)
|
static void uart_clps711x_enable_ms(struct uart_port *port)
|
||||||
{
|
{
|
||||||
|
/* Do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
|
static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct uart_port *port = dev_id;
|
struct uart_port *port = dev_id;
|
||||||
struct tty_struct *tty = port->state->port.tty;
|
struct tty_struct *tty = tty_port_tty_get(&port->state->port);
|
||||||
unsigned int status, ch, flg;
|
unsigned int status, ch, flg;
|
||||||
|
|
||||||
status = clps_readl(SYSFLG(port));
|
if (!tty)
|
||||||
while (!(status & SYSFLG_URXFE)) {
|
return IRQ_HANDLED;
|
||||||
ch = clps_readl(UARTDR(port));
|
|
||||||
|
for (;;) {
|
||||||
|
status = clps_readl(SYSFLG(port));
|
||||||
|
if (status & SYSFLG_URXFE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ch = clps_readw(UARTDR(port));
|
||||||
|
status = ch & (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR);
|
||||||
|
ch &= 0xff;
|
||||||
|
|
||||||
port->icount.rx++;
|
port->icount.rx++;
|
||||||
|
|
||||||
flg = TTY_NORMAL;
|
flg = TTY_NORMAL;
|
||||||
|
|
||||||
/*
|
if (unlikely(status)) {
|
||||||
* Note that the error handling code is
|
if (status & UARTDR_PARERR)
|
||||||
* out of the main execution path
|
|
||||||
*/
|
|
||||||
if (unlikely(ch & UART_ANY_ERR)) {
|
|
||||||
if (ch & UARTDR_PARERR)
|
|
||||||
port->icount.parity++;
|
port->icount.parity++;
|
||||||
else if (ch & UARTDR_FRMERR)
|
else if (status & UARTDR_FRMERR)
|
||||||
port->icount.frame++;
|
port->icount.frame++;
|
||||||
if (ch & UARTDR_OVERR)
|
else if (status & UARTDR_OVERR)
|
||||||
port->icount.overrun++;
|
port->icount.overrun++;
|
||||||
|
|
||||||
ch &= port->read_status_mask;
|
status &= port->read_status_mask;
|
||||||
|
|
||||||
if (ch & UARTDR_PARERR)
|
if (status & UARTDR_PARERR)
|
||||||
flg = TTY_PARITY;
|
flg = TTY_PARITY;
|
||||||
else if (ch & UARTDR_FRMERR)
|
else if (status & UARTDR_FRMERR)
|
||||||
flg = TTY_FRAME;
|
flg = TTY_FRAME;
|
||||||
|
else if (status & UARTDR_OVERR)
|
||||||
#ifdef SUPPORT_SYSRQ
|
flg = TTY_OVERRUN;
|
||||||
port->sysrq = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uart_handle_sysrq_char(port, ch))
|
if (uart_handle_sysrq_char(port, ch))
|
||||||
goto ignore_char;
|
continue;
|
||||||
|
|
||||||
/*
|
if (status & port->ignore_status_mask)
|
||||||
* CHECK: does overrun affect the current character?
|
continue;
|
||||||
* ASSUMPTION: it does not.
|
|
||||||
*/
|
|
||||||
uart_insert_char(port, ch, UARTDR_OVERR, ch, flg);
|
|
||||||
|
|
||||||
ignore_char:
|
uart_insert_char(port, status, UARTDR_OVERR, ch, flg);
|
||||||
status = clps_readl(SYSFLG(port));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tty_flip_buffer_push(tty);
|
tty_flip_buffer_push(tty);
|
||||||
|
|
||||||
|
tty_kref_put(tty);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
|
static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct uart_port *port = dev_id;
|
struct uart_port *port = dev_id;
|
||||||
|
struct clps711x_port *s = dev_get_drvdata(port->dev);
|
||||||
struct circ_buf *xmit = &port->state->xmit;
|
struct circ_buf *xmit = &port->state->xmit;
|
||||||
int count;
|
|
||||||
|
|
||||||
if (port->x_char) {
|
if (port->x_char) {
|
||||||
clps_writel(port->x_char, UARTDR(port));
|
clps_writew(port->x_char, UARTDR(port));
|
||||||
port->icount.tx++;
|
port->icount.tx++;
|
||||||
port->x_char = 0;
|
port->x_char = 0;
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
|
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
|
||||||
goto disable_tx_irq;
|
disable_irq_nosync(TX_IRQ(port));
|
||||||
|
s->tx_enabled[port->line] = 0;
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
count = port->fifosize >> 1;
|
while (!uart_circ_empty(xmit)) {
|
||||||
do {
|
clps_writew(xmit->buf[xmit->tail], UARTDR(port));
|
||||||
clps_writel(xmit->buf[xmit->tail], UARTDR(port));
|
|
||||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||||
port->icount.tx++;
|
port->icount.tx++;
|
||||||
if (uart_circ_empty(xmit))
|
if (clps_readl(SYSFLG(port) & SYSFLG_UTXFF))
|
||||||
break;
|
break;
|
||||||
} while (--count > 0);
|
}
|
||||||
|
|
||||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||||
uart_write_wakeup(port);
|
uart_write_wakeup(port);
|
||||||
|
|
||||||
if (uart_circ_empty(xmit)) {
|
|
||||||
disable_tx_irq:
|
|
||||||
disable_irq_nosync(TX_IRQ(port));
|
|
||||||
tx_enabled(port) = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int clps711xuart_tx_empty(struct uart_port *port)
|
static unsigned int uart_clps711x_tx_empty(struct uart_port *port)
|
||||||
{
|
{
|
||||||
unsigned int status = clps_readl(SYSFLG(port));
|
return (clps_readl(SYSFLG(port) & SYSFLG_UBUSY)) ? 0 : TIOCSER_TEMT;
|
||||||
return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
|
static unsigned int uart_clps711x_get_mctrl(struct uart_port *port)
|
||||||
{
|
{
|
||||||
unsigned int port_addr;
|
unsigned int status, result = 0;
|
||||||
unsigned int result = 0;
|
|
||||||
unsigned int status;
|
|
||||||
|
|
||||||
port_addr = SYSFLG(port);
|
if (port->line == 0) {
|
||||||
if (port_addr == SYSFLG1) {
|
|
||||||
status = clps_readl(SYSFLG1);
|
status = clps_readl(SYSFLG1);
|
||||||
if (status & SYSFLG1_DCD)
|
if (status & SYSFLG1_DCD)
|
||||||
result |= TIOCM_CAR;
|
result |= TIOCM_CAR;
|
||||||
|
@ -199,104 +187,86 @@ static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
|
||||||
result |= TIOCM_DSR;
|
result |= TIOCM_DSR;
|
||||||
if (status & SYSFLG1_CTS)
|
if (status & SYSFLG1_CTS)
|
||||||
result |= TIOCM_CTS;
|
result |= TIOCM_CTS;
|
||||||
}
|
} else
|
||||||
|
result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||||
clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
|
|
||||||
{
|
{
|
||||||
|
/* Do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711xuart_break_ctl(struct uart_port *port, int break_state)
|
static void uart_clps711x_break_ctl(struct uart_port *port, int break_state)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int ubrlcr;
|
unsigned int ubrlcr;
|
||||||
|
|
||||||
spin_lock_irqsave(&port->lock, flags);
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
|
|
||||||
ubrlcr = clps_readl(UBRLCR(port));
|
ubrlcr = clps_readl(UBRLCR(port));
|
||||||
if (break_state == -1)
|
if (break_state)
|
||||||
ubrlcr |= UBRLCR_BREAK;
|
ubrlcr |= UBRLCR_BREAK;
|
||||||
else
|
else
|
||||||
ubrlcr &= ~UBRLCR_BREAK;
|
ubrlcr &= ~UBRLCR_BREAK;
|
||||||
clps_writel(ubrlcr, UBRLCR(port));
|
clps_writel(ubrlcr, UBRLCR(port));
|
||||||
|
|
||||||
spin_unlock_irqrestore(&port->lock, flags);
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clps711xuart_startup(struct uart_port *port)
|
static int uart_clps711x_startup(struct uart_port *port)
|
||||||
{
|
{
|
||||||
unsigned int syscon;
|
struct clps711x_port *s = dev_get_drvdata(port->dev);
|
||||||
int retval;
|
int ret;
|
||||||
|
|
||||||
tx_enabled(port) = 1;
|
s->tx_enabled[port->line] = 1;
|
||||||
|
/* Allocate the IRQs */
|
||||||
|
ret = devm_request_irq(port->dev, TX_IRQ(port), uart_clps711x_int_tx,
|
||||||
|
0, UART_CLPS711X_NAME " TX", port);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/*
|
ret = devm_request_irq(port->dev, RX_IRQ(port), uart_clps711x_int_rx,
|
||||||
* Allocate the IRQs
|
0, UART_CLPS711X_NAME " RX", port);
|
||||||
*/
|
if (ret) {
|
||||||
retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0,
|
devm_free_irq(port->dev, TX_IRQ(port), port);
|
||||||
"clps711xuart_tx", port);
|
return ret;
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0,
|
|
||||||
"clps711xuart_rx", port);
|
|
||||||
if (retval) {
|
|
||||||
free_irq(TX_IRQ(port), port);
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Disable break */
|
||||||
* enable the port
|
clps_writel(clps_readl(UBRLCR(port)) & ~UBRLCR_BREAK, UBRLCR(port));
|
||||||
*/
|
|
||||||
syscon = clps_readl(SYSCON(port));
|
/* Enable the port */
|
||||||
syscon |= SYSCON_UARTEN;
|
clps_writel(clps_readl(SYSCON(port)) | SYSCON_UARTEN, SYSCON(port));
|
||||||
clps_writel(syscon, SYSCON(port));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711xuart_shutdown(struct uart_port *port)
|
static void uart_clps711x_shutdown(struct uart_port *port)
|
||||||
{
|
{
|
||||||
unsigned int ubrlcr, syscon;
|
/* Free the interrupts */
|
||||||
|
devm_free_irq(port->dev, TX_IRQ(port), port);
|
||||||
|
devm_free_irq(port->dev, RX_IRQ(port), port);
|
||||||
|
|
||||||
/*
|
/* Disable the port */
|
||||||
* Free the interrupt
|
clps_writel(clps_readl(SYSCON(port)) & ~SYSCON_UARTEN, SYSCON(port));
|
||||||
*/
|
|
||||||
free_irq(TX_IRQ(port), port); /* TX interrupt */
|
|
||||||
free_irq(RX_IRQ(port), port); /* RX interrupt */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* disable the port
|
|
||||||
*/
|
|
||||||
syscon = clps_readl(SYSCON(port));
|
|
||||||
syscon &= ~SYSCON_UARTEN;
|
|
||||||
clps_writel(syscon, SYSCON(port));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* disable break condition and fifos
|
|
||||||
*/
|
|
||||||
ubrlcr = clps_readl(UBRLCR(port));
|
|
||||||
ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK);
|
|
||||||
clps_writel(ubrlcr, UBRLCR(port));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void uart_clps711x_set_termios(struct uart_port *port,
|
||||||
clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios,
|
struct ktermios *termios,
|
||||||
struct ktermios *old)
|
struct ktermios *old)
|
||||||
{
|
{
|
||||||
unsigned int ubrlcr, baud, quot;
|
unsigned int ubrlcr, baud, quot;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/*
|
/* Mask termios capabilities we don't support */
|
||||||
* We don't implement CREAD.
|
termios->c_cflag &= ~CMSPAR;
|
||||||
*/
|
termios->c_iflag &= ~(BRKINT | IGNBRK);
|
||||||
termios->c_cflag |= CREAD;
|
|
||||||
|
|
||||||
/*
|
/* Ask the core to calculate the divisor for us */
|
||||||
* Ask the core to calculate the divisor for us.
|
baud = uart_get_baud_rate(port, termios, old, port->uartclk / 4096,
|
||||||
*/
|
port->uartclk / 16);
|
||||||
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
|
|
||||||
quot = uart_get_divisor(port, baud);
|
quot = uart_get_divisor(port, baud);
|
||||||
|
|
||||||
switch (termios->c_cflag & CSIZE) {
|
switch (termios->c_cflag & CSIZE) {
|
||||||
|
@ -309,160 +279,117 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||||
case CS7:
|
case CS7:
|
||||||
ubrlcr = UBRLCR_WRDLEN7;
|
ubrlcr = UBRLCR_WRDLEN7;
|
||||||
break;
|
break;
|
||||||
default: // CS8
|
case CS8:
|
||||||
|
default:
|
||||||
ubrlcr = UBRLCR_WRDLEN8;
|
ubrlcr = UBRLCR_WRDLEN8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (termios->c_cflag & CSTOPB)
|
if (termios->c_cflag & CSTOPB)
|
||||||
ubrlcr |= UBRLCR_XSTOP;
|
ubrlcr |= UBRLCR_XSTOP;
|
||||||
|
|
||||||
if (termios->c_cflag & PARENB) {
|
if (termios->c_cflag & PARENB) {
|
||||||
ubrlcr |= UBRLCR_PRTEN;
|
ubrlcr |= UBRLCR_PRTEN;
|
||||||
if (!(termios->c_cflag & PARODD))
|
if (!(termios->c_cflag & PARODD))
|
||||||
ubrlcr |= UBRLCR_EVENPRT;
|
ubrlcr |= UBRLCR_EVENPRT;
|
||||||
}
|
}
|
||||||
if (port->fifosize > 1)
|
|
||||||
ubrlcr |= UBRLCR_FIFOEN;
|
/* Enable FIFO */
|
||||||
|
ubrlcr |= UBRLCR_FIFOEN;
|
||||||
|
|
||||||
spin_lock_irqsave(&port->lock, flags);
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
|
|
||||||
/*
|
/* Set read status mask */
|
||||||
* Update the per-port timeout.
|
|
||||||
*/
|
|
||||||
uart_update_timeout(port, termios->c_cflag, baud);
|
|
||||||
|
|
||||||
port->read_status_mask = UARTDR_OVERR;
|
port->read_status_mask = UARTDR_OVERR;
|
||||||
if (termios->c_iflag & INPCK)
|
if (termios->c_iflag & INPCK)
|
||||||
port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR;
|
port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR;
|
||||||
|
|
||||||
/*
|
/* Set status ignore mask */
|
||||||
* Characters to ignore
|
|
||||||
*/
|
|
||||||
port->ignore_status_mask = 0;
|
port->ignore_status_mask = 0;
|
||||||
if (termios->c_iflag & IGNPAR)
|
if (!(termios->c_cflag & CREAD))
|
||||||
port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR;
|
port->ignore_status_mask |= UARTDR_OVERR | UARTDR_PARERR |
|
||||||
if (termios->c_iflag & IGNBRK) {
|
UARTDR_FRMERR;
|
||||||
/*
|
|
||||||
* If we're ignoring parity and break indicators,
|
|
||||||
* ignore overruns to (for real raw support).
|
|
||||||
*/
|
|
||||||
if (termios->c_iflag & IGNPAR)
|
|
||||||
port->ignore_status_mask |= UARTDR_OVERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
quot -= 1;
|
uart_update_timeout(port, termios->c_cflag, baud);
|
||||||
|
|
||||||
clps_writel(ubrlcr | quot, UBRLCR(port));
|
clps_writel(ubrlcr | (quot - 1), UBRLCR(port));
|
||||||
|
|
||||||
spin_unlock_irqrestore(&port->lock, flags);
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *clps711xuart_type(struct uart_port *port)
|
static const char *uart_clps711x_type(struct uart_port *port)
|
||||||
{
|
{
|
||||||
return port->type == PORT_CLPS711X ? "CLPS711x" : NULL;
|
return (port->type == PORT_CLPS711X) ? "CLPS711X" : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void uart_clps711x_config_port(struct uart_port *port, int flags)
|
||||||
* Configure/autoconfigure the port.
|
|
||||||
*/
|
|
||||||
static void clps711xuart_config_port(struct uart_port *port, int flags)
|
|
||||||
{
|
{
|
||||||
if (flags & UART_CONFIG_TYPE)
|
if (flags & UART_CONFIG_TYPE)
|
||||||
port->type = PORT_CLPS711X;
|
port->type = PORT_CLPS711X;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711xuart_release_port(struct uart_port *port)
|
static void uart_clps711x_release_port(struct uart_port *port)
|
||||||
{
|
{
|
||||||
|
/* Do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clps711xuart_request_port(struct uart_port *port)
|
static int uart_clps711x_request_port(struct uart_port *port)
|
||||||
{
|
{
|
||||||
|
/* Do nothing */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct uart_ops clps711x_pops = {
|
static const struct uart_ops uart_clps711x_ops = {
|
||||||
.tx_empty = clps711xuart_tx_empty,
|
.tx_empty = uart_clps711x_tx_empty,
|
||||||
.set_mctrl = clps711xuart_set_mctrl_null,
|
.set_mctrl = uart_clps711x_set_mctrl,
|
||||||
.get_mctrl = clps711xuart_get_mctrl,
|
.get_mctrl = uart_clps711x_get_mctrl,
|
||||||
.stop_tx = clps711xuart_stop_tx,
|
.stop_tx = uart_clps711x_stop_tx,
|
||||||
.start_tx = clps711xuart_start_tx,
|
.start_tx = uart_clps711x_start_tx,
|
||||||
.stop_rx = clps711xuart_stop_rx,
|
.stop_rx = uart_clps711x_stop_rx,
|
||||||
.enable_ms = clps711xuart_enable_ms,
|
.enable_ms = uart_clps711x_enable_ms,
|
||||||
.break_ctl = clps711xuart_break_ctl,
|
.break_ctl = uart_clps711x_break_ctl,
|
||||||
.startup = clps711xuart_startup,
|
.startup = uart_clps711x_startup,
|
||||||
.shutdown = clps711xuart_shutdown,
|
.shutdown = uart_clps711x_shutdown,
|
||||||
.set_termios = clps711xuart_set_termios,
|
.set_termios = uart_clps711x_set_termios,
|
||||||
.type = clps711xuart_type,
|
.type = uart_clps711x_type,
|
||||||
.config_port = clps711xuart_config_port,
|
.config_port = uart_clps711x_config_port,
|
||||||
.release_port = clps711xuart_release_port,
|
.release_port = uart_clps711x_release_port,
|
||||||
.request_port = clps711xuart_request_port,
|
.request_port = uart_clps711x_request_port,
|
||||||
};
|
|
||||||
|
|
||||||
static struct uart_port clps711x_ports[UART_NR] = {
|
|
||||||
{
|
|
||||||
.iobase = SYSCON1,
|
|
||||||
.irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
|
|
||||||
.uartclk = 3686400,
|
|
||||||
.fifosize = 16,
|
|
||||||
.ops = &clps711x_pops,
|
|
||||||
.line = 0,
|
|
||||||
.flags = UPF_BOOT_AUTOCONF,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.iobase = SYSCON2,
|
|
||||||
.irq = IRQ_UTXINT2, /* IRQ_URXINT2 */
|
|
||||||
.uartclk = 3686400,
|
|
||||||
.fifosize = 16,
|
|
||||||
.ops = &clps711x_pops,
|
|
||||||
.line = 1,
|
|
||||||
.flags = UPF_BOOT_AUTOCONF,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
|
#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
|
||||||
static void clps711xuart_console_putchar(struct uart_port *port, int ch)
|
static void uart_clps711x_console_putchar(struct uart_port *port, int ch)
|
||||||
{
|
{
|
||||||
while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF)
|
while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF)
|
||||||
barrier();
|
barrier();
|
||||||
clps_writel(ch, UARTDR(port));
|
|
||||||
|
clps_writew(ch, UARTDR(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void uart_clps711x_console_write(struct console *co, const char *c,
|
||||||
* Print a string to the serial port trying not to disturb
|
unsigned n)
|
||||||
* any possible real use of the port...
|
|
||||||
*
|
|
||||||
* The console_lock must be held when we get here.
|
|
||||||
*
|
|
||||||
* Note that this is called with interrupts already disabled
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
clps711xuart_console_write(struct console *co, const char *s,
|
|
||||||
unsigned int count)
|
|
||||||
{
|
{
|
||||||
struct uart_port *port = clps711x_ports + co->index;
|
struct clps711x_port *s = (struct clps711x_port *)co->data;
|
||||||
unsigned int status, syscon;
|
struct uart_port *port = &s->port[co->index];
|
||||||
|
u32 syscon;
|
||||||
|
|
||||||
/*
|
/* Ensure that the port is enabled */
|
||||||
* Ensure that the port is enabled.
|
|
||||||
*/
|
|
||||||
syscon = clps_readl(SYSCON(port));
|
syscon = clps_readl(SYSCON(port));
|
||||||
clps_writel(syscon | SYSCON_UARTEN, SYSCON(port));
|
clps_writel(syscon | SYSCON_UARTEN, SYSCON(port));
|
||||||
|
|
||||||
uart_console_write(port, s, count, clps711xuart_console_putchar);
|
uart_console_write(port, c, n, uart_clps711x_console_putchar);
|
||||||
|
|
||||||
/*
|
/* Wait for transmitter to become empty */
|
||||||
* Finally, wait for transmitter to become empty
|
while (clps_readl(SYSFLG(port)) & SYSFLG_UBUSY)
|
||||||
* and restore the uart state.
|
barrier();
|
||||||
*/
|
|
||||||
do {
|
|
||||||
status = clps_readl(SYSFLG(port));
|
|
||||||
} while (status & SYSFLG_UBUSY);
|
|
||||||
|
|
||||||
|
/* Restore the uart state */
|
||||||
clps_writel(syscon, SYSCON(port));
|
clps_writel(syscon, SYSCON(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init
|
static void uart_clps711x_console_get_options(struct uart_port *port,
|
||||||
clps711xuart_console_get_options(struct uart_port *port, int *baud,
|
int *baud, int *parity,
|
||||||
int *parity, int *bits)
|
int *bits)
|
||||||
{
|
{
|
||||||
if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) {
|
if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) {
|
||||||
unsigned int ubrlcr, quot;
|
unsigned int ubrlcr, quot;
|
||||||
|
@ -487,92 +414,124 @@ clps711xuart_console_get_options(struct uart_port *port, int *baud,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init clps711xuart_console_setup(struct console *co, char *options)
|
static int uart_clps711x_console_setup(struct console *co, char *options)
|
||||||
{
|
{
|
||||||
struct uart_port *port;
|
int baud = 38400, bits = 8, parity = 'n', flow = 'n';
|
||||||
int baud = 38400;
|
struct clps711x_port *s = (struct clps711x_port *)co->data;
|
||||||
int bits = 8;
|
struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0];
|
||||||
int parity = 'n';
|
|
||||||
int flow = 'n';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether an invalid uart number has been specified, and
|
|
||||||
* if so, search for the first available port that does have
|
|
||||||
* console support.
|
|
||||||
*/
|
|
||||||
port = uart_get_console(clps711x_ports, UART_NR, co);
|
|
||||||
|
|
||||||
if (options)
|
if (options)
|
||||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||||
else
|
else
|
||||||
clps711xuart_console_get_options(port, &baud, &parity, &bits);
|
uart_clps711x_console_get_options(port, &baud, &parity, &bits);
|
||||||
|
|
||||||
return uart_set_options(port, co, baud, parity, bits, flow);
|
return uart_set_options(port, co, baud, parity, bits, flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct uart_driver clps711x_reg;
|
|
||||||
static struct console clps711x_console = {
|
|
||||||
.name = "ttyCL",
|
|
||||||
.write = clps711xuart_console_write,
|
|
||||||
.device = uart_console_device,
|
|
||||||
.setup = clps711xuart_console_setup,
|
|
||||||
.flags = CON_PRINTBUFFER,
|
|
||||||
.index = -1,
|
|
||||||
.data = &clps711x_reg,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init clps711xuart_console_init(void)
|
|
||||||
{
|
|
||||||
register_console(&clps711x_console);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
console_initcall(clps711xuart_console_init);
|
|
||||||
|
|
||||||
#define CLPS711X_CONSOLE &clps711x_console
|
|
||||||
#else
|
|
||||||
#define CLPS711X_CONSOLE NULL
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct uart_driver clps711x_reg = {
|
static int uart_clps711x_probe(struct platform_device *pdev)
|
||||||
.driver_name = "ttyCL",
|
|
||||||
.dev_name = "ttyCL",
|
|
||||||
.major = SERIAL_CLPS711X_MAJOR,
|
|
||||||
.minor = SERIAL_CLPS711X_MINOR,
|
|
||||||
.nr = UART_NR,
|
|
||||||
|
|
||||||
.cons = CLPS711X_CONSOLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init clps711xuart_init(void)
|
|
||||||
{
|
{
|
||||||
|
struct clps711x_port *s;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
printk(KERN_INFO "Serial: CLPS711x driver\n");
|
s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL);
|
||||||
|
if (!s) {
|
||||||
|
dev_err(&pdev->dev, "Error allocating port structure\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
platform_set_drvdata(pdev, s);
|
||||||
|
|
||||||
ret = uart_register_driver(&clps711x_reg);
|
s->uart_clk = devm_clk_get(&pdev->dev, "uart");
|
||||||
if (ret)
|
if (IS_ERR(s->uart_clk)) {
|
||||||
return ret;
|
dev_err(&pdev->dev, "Can't get UART clocks\n");
|
||||||
|
ret = PTR_ERR(s->uart_clk);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < UART_NR; i++)
|
s->uart.owner = THIS_MODULE;
|
||||||
uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
|
s->uart.dev_name = "ttyCL";
|
||||||
|
s->uart.major = UART_CLPS711X_MAJOR;
|
||||||
|
s->uart.minor = UART_CLPS711X_MINOR;
|
||||||
|
s->uart.nr = UART_CLPS711X_NR;
|
||||||
|
#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
|
||||||
|
s->uart.cons = &s->console;
|
||||||
|
s->uart.cons->device = uart_console_device;
|
||||||
|
s->uart.cons->write = uart_clps711x_console_write;
|
||||||
|
s->uart.cons->setup = uart_clps711x_console_setup;
|
||||||
|
s->uart.cons->flags = CON_PRINTBUFFER;
|
||||||
|
s->uart.cons->index = -1;
|
||||||
|
s->uart.cons->data = s;
|
||||||
|
strcpy(s->uart.cons->name, "ttyCL");
|
||||||
|
#endif
|
||||||
|
ret = uart_register_driver(&s->uart);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "Registering UART driver failed\n");
|
||||||
|
devm_clk_put(&pdev->dev, s->uart_clk);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < UART_CLPS711X_NR; i++) {
|
||||||
|
s->port[i].line = i;
|
||||||
|
s->port[i].dev = &pdev->dev;
|
||||||
|
s->port[i].irq = TX_IRQ(&s->port[i]);
|
||||||
|
s->port[i].iobase = SYSCON(&s->port[i]);
|
||||||
|
s->port[i].type = PORT_CLPS711X;
|
||||||
|
s->port[i].fifosize = 16;
|
||||||
|
s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE;
|
||||||
|
s->port[i].uartclk = clk_get_rate(s->uart_clk);
|
||||||
|
s->port[i].ops = &uart_clps711x_ops;
|
||||||
|
WARN_ON(uart_add_one_port(&s->uart, &s->port[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_clps711x_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct clps711x_port *s = platform_get_drvdata(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < UART_CLPS711X_NR; i++)
|
||||||
|
uart_remove_one_port(&s->uart, &s->port[i]);
|
||||||
|
|
||||||
|
devm_clk_put(&pdev->dev, s->uart_clk);
|
||||||
|
uart_unregister_driver(&s->uart);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit clps711xuart_exit(void)
|
static struct platform_driver clps711x_uart_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = UART_CLPS711X_NAME,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
.probe = uart_clps711x_probe,
|
||||||
|
.remove = uart_clps711x_remove,
|
||||||
|
};
|
||||||
|
module_platform_driver(clps711x_uart_driver);
|
||||||
|
|
||||||
|
static struct platform_device clps711x_uart_device = {
|
||||||
|
.name = UART_CLPS711X_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init uart_clps711x_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
return platform_device_register(&clps711x_uart_device);
|
||||||
|
|
||||||
for (i = 0; i < UART_NR; i++)
|
|
||||||
uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]);
|
|
||||||
|
|
||||||
uart_unregister_driver(&clps711x_reg);
|
|
||||||
}
|
}
|
||||||
|
module_init(uart_clps711x_init);
|
||||||
|
|
||||||
module_init(clps711xuart_init);
|
static void __exit uart_clps711x_exit(void)
|
||||||
module_exit(clps711xuart_exit);
|
{
|
||||||
|
platform_device_unregister(&clps711x_uart_device);
|
||||||
|
}
|
||||||
|
module_exit(uart_clps711x_exit);
|
||||||
|
|
||||||
MODULE_AUTHOR("Deep Blue Solutions Ltd");
|
MODULE_AUTHOR("Deep Blue Solutions Ltd");
|
||||||
MODULE_DESCRIPTION("CLPS-711x generic serial driver");
|
MODULE_DESCRIPTION("CLPS711X serial driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR);
|
|
||||||
|
|
|
@ -1373,7 +1373,7 @@ static struct uart_driver cpm_reg = {
|
||||||
|
|
||||||
static int probe_index;
|
static int probe_index;
|
||||||
|
|
||||||
static int __devinit cpm_uart_probe(struct platform_device *ofdev)
|
static int cpm_uart_probe(struct platform_device *ofdev)
|
||||||
{
|
{
|
||||||
int index = probe_index++;
|
int index = probe_index++;
|
||||||
struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
|
struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
|
||||||
|
@ -1396,7 +1396,7 @@ static int __devinit cpm_uart_probe(struct platform_device *ofdev)
|
||||||
return uart_add_one_port(&cpm_reg, &pinfo->port);
|
return uart_add_one_port(&cpm_reg, &pinfo->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit cpm_uart_remove(struct platform_device *ofdev)
|
static int cpm_uart_remove(struct platform_device *ofdev)
|
||||||
{
|
{
|
||||||
struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev);
|
struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev);
|
||||||
return uart_remove_one_port(&cpm_reg, &pinfo->port);
|
return uart_remove_one_port(&cpm_reg, &pinfo->port);
|
||||||
|
|
|
@ -690,7 +690,7 @@ static int efm32_uart_probe_dt(struct platform_device *pdev,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit efm32_uart_probe(struct platform_device *pdev)
|
static int efm32_uart_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct efm32_uart_port *efm_port;
|
struct efm32_uart_port *efm_port;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
@ -764,7 +764,7 @@ err_get_base:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit efm32_uart_remove(struct platform_device *pdev)
|
static int efm32_uart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct efm32_uart_port *efm_port = platform_get_drvdata(pdev);
|
struct efm32_uart_port *efm_port = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
@ -791,7 +791,7 @@ MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids);
|
||||||
|
|
||||||
static struct platform_driver efm32_uart_driver = {
|
static struct platform_driver efm32_uart_driver = {
|
||||||
.probe = efm32_uart_probe,
|
.probe = efm32_uart_probe,
|
||||||
.remove = __devexit_p(efm32_uart_remove),
|
.remove = efm32_uart_remove,
|
||||||
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
|
|
|
@ -175,7 +175,7 @@ static void free_port_memory(struct icom_port *icom_port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit get_port_memory(struct icom_port *icom_port)
|
static int get_port_memory(struct icom_port *icom_port)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
unsigned long stgAddr;
|
unsigned long stgAddr;
|
||||||
|
@ -1314,7 +1314,7 @@ static struct uart_driver icom_uart_driver = {
|
||||||
.cons = ICOM_CONSOLE,
|
.cons = ICOM_CONSOLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
|
static int icom_init_ports(struct icom_adapter *icom_adapter)
|
||||||
{
|
{
|
||||||
u32 subsystem_id = icom_adapter->subsystem_id;
|
u32 subsystem_id = icom_adapter->subsystem_id;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1381,7 +1381,7 @@ static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *i
|
||||||
0x8024 + 2 - 2 * (icom_port->port - 2);
|
0x8024 + 2 - 2 * (icom_port->port - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
|
static int icom_load_ports(struct icom_adapter *icom_adapter)
|
||||||
{
|
{
|
||||||
struct icom_port *icom_port;
|
struct icom_port *icom_port;
|
||||||
int port_num;
|
int port_num;
|
||||||
|
@ -1407,7 +1407,7 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit icom_alloc_adapter(struct icom_adapter
|
static int icom_alloc_adapter(struct icom_adapter
|
||||||
**icom_adapter_ref)
|
**icom_adapter_ref)
|
||||||
{
|
{
|
||||||
int adapter_count = 0;
|
int adapter_count = 0;
|
||||||
|
@ -1487,7 +1487,7 @@ static void icom_kref_release(struct kref *kref)
|
||||||
icom_remove_adapter(icom_adapter);
|
icom_remove_adapter(icom_adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit icom_probe(struct pci_dev *dev,
|
static int icom_probe(struct pci_dev *dev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
@ -1596,7 +1596,7 @@ probe_exit0:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit icom_remove(struct pci_dev *dev)
|
static void icom_remove(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
struct icom_adapter *icom_adapter;
|
struct icom_adapter *icom_adapter;
|
||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
|
@ -1617,7 +1617,7 @@ static struct pci_driver icom_pci_driver = {
|
||||||
.name = ICOM_DRIVER_NAME,
|
.name = ICOM_DRIVER_NAME,
|
||||||
.id_table = icom_pci_table,
|
.id_table = icom_pci_table,
|
||||||
.probe = icom_probe,
|
.probe = icom_probe,
|
||||||
.remove = __devexit_p(icom_remove),
|
.remove = icom_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init icom_init(void)
|
static int __init icom_init(void)
|
||||||
|
|
|
@ -60,20 +60,27 @@
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/spi/ifx_modem.h>
|
#include <linux/spi/ifx_modem.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
#include "ifx6x60.h"
|
#include "ifx6x60.h"
|
||||||
|
|
||||||
#define IFX_SPI_MORE_MASK 0x10
|
#define IFX_SPI_MORE_MASK 0x10
|
||||||
#define IFX_SPI_MORE_BIT 12 /* bit position in u16 */
|
#define IFX_SPI_MORE_BIT 4 /* bit position in u8 */
|
||||||
#define IFX_SPI_CTS_BIT 13 /* bit position in u16 */
|
#define IFX_SPI_CTS_BIT 6 /* bit position in u8 */
|
||||||
#define IFX_SPI_MODE SPI_MODE_1
|
#define IFX_SPI_MODE SPI_MODE_1
|
||||||
#define IFX_SPI_TTY_ID 0
|
#define IFX_SPI_TTY_ID 0
|
||||||
#define IFX_SPI_TIMEOUT_SEC 2
|
#define IFX_SPI_TIMEOUT_SEC 2
|
||||||
#define IFX_SPI_HEADER_0 (-1)
|
#define IFX_SPI_HEADER_0 (-1)
|
||||||
#define IFX_SPI_HEADER_F (-2)
|
#define IFX_SPI_HEADER_F (-2)
|
||||||
|
|
||||||
|
#define PO_POST_DELAY 200
|
||||||
|
#define IFX_MDM_RST_PMU 4
|
||||||
|
|
||||||
/* forward reference */
|
/* forward reference */
|
||||||
static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev);
|
static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev);
|
||||||
|
static int ifx_modem_reboot_callback(struct notifier_block *nfb,
|
||||||
|
unsigned long event, void *data);
|
||||||
|
static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev);
|
||||||
|
|
||||||
/* local variables */
|
/* local variables */
|
||||||
static int spi_bpw = 16; /* 8, 16 or 32 bit word length */
|
static int spi_bpw = 16; /* 8, 16 or 32 bit word length */
|
||||||
|
@ -81,6 +88,29 @@ static struct tty_driver *tty_drv;
|
||||||
static struct ifx_spi_device *saved_ifx_dev;
|
static struct ifx_spi_device *saved_ifx_dev;
|
||||||
static struct lock_class_key ifx_spi_key;
|
static struct lock_class_key ifx_spi_key;
|
||||||
|
|
||||||
|
static struct notifier_block ifx_modem_reboot_notifier_block = {
|
||||||
|
.notifier_call = ifx_modem_reboot_callback,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev)
|
||||||
|
{
|
||||||
|
gpio_set_value(IFX_MDM_RST_PMU, 1);
|
||||||
|
msleep(PO_POST_DELAY);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ifx_modem_reboot_callback(struct notifier_block *nfb,
|
||||||
|
unsigned long event, void *data)
|
||||||
|
{
|
||||||
|
if (saved_ifx_dev)
|
||||||
|
ifx_modem_power_off(saved_ifx_dev);
|
||||||
|
else
|
||||||
|
pr_warn("no ifx modem active;\n");
|
||||||
|
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* GPIO/GPE settings */
|
/* GPIO/GPE settings */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,26 +182,67 @@ ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* swap_buf
|
* swap_buf_8
|
||||||
* @buf: our buffer
|
* @buf: our buffer
|
||||||
* @len : number of bytes (not words) in the buffer
|
* @len : number of bytes (not words) in the buffer
|
||||||
* @end: end of buffer
|
* @end: end of buffer
|
||||||
*
|
*
|
||||||
* Swap the contents of a buffer into big endian format
|
* Swap the contents of a buffer into big endian format
|
||||||
*/
|
*/
|
||||||
static inline void swap_buf(u16 *buf, int len, void *end)
|
static inline void swap_buf_8(unsigned char *buf, int len, void *end)
|
||||||
|
{
|
||||||
|
/* don't swap buffer if SPI word width is 8 bits */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swap_buf_16
|
||||||
|
* @buf: our buffer
|
||||||
|
* @len : number of bytes (not words) in the buffer
|
||||||
|
* @end: end of buffer
|
||||||
|
*
|
||||||
|
* Swap the contents of a buffer into big endian format
|
||||||
|
*/
|
||||||
|
static inline void swap_buf_16(unsigned char *buf, int len, void *end)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
u16 *buf_16 = (u16 *)buf;
|
||||||
len = ((len + 1) >> 1);
|
len = ((len + 1) >> 1);
|
||||||
if ((void *)&buf[len] > end) {
|
if ((void *)&buf_16[len] > end) {
|
||||||
pr_err("swap_buf: swap exceeds boundary (%p > %p)!",
|
pr_err("swap_buf_16: swap exceeds boundary (%p > %p)!",
|
||||||
&buf[len], end);
|
&buf_16[len], end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (n = 0; n < len; n++) {
|
for (n = 0; n < len; n++) {
|
||||||
*buf = cpu_to_be16(*buf);
|
*buf_16 = cpu_to_be16(*buf_16);
|
||||||
buf++;
|
buf_16++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swap_buf_32
|
||||||
|
* @buf: our buffer
|
||||||
|
* @len : number of bytes (not words) in the buffer
|
||||||
|
* @end: end of buffer
|
||||||
|
*
|
||||||
|
* Swap the contents of a buffer into big endian format
|
||||||
|
*/
|
||||||
|
static inline void swap_buf_32(unsigned char *buf, int len, void *end)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
u32 *buf_32 = (u32 *)buf;
|
||||||
|
len = (len + 3) >> 2;
|
||||||
|
|
||||||
|
if ((void *)&buf_32[len] > end) {
|
||||||
|
pr_err("swap_buf_32: swap exceeds boundary (%p > %p)!\n",
|
||||||
|
&buf_32[len], end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (n = 0; n < len; n++) {
|
||||||
|
*buf_32 = cpu_to_be32(*buf_32);
|
||||||
|
buf_32++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,9 +261,7 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev)
|
||||||
if (!val) {
|
if (!val) {
|
||||||
if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING,
|
if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING,
|
||||||
&ifx_dev->flags)) {
|
&ifx_dev->flags)) {
|
||||||
ifx_dev->spi_timer.expires =
|
mod_timer(&ifx_dev->spi_timer,jiffies + IFX_SPI_TIMEOUT_SEC*HZ);
|
||||||
jiffies + IFX_SPI_TIMEOUT_SEC*HZ;
|
|
||||||
add_timer(&ifx_dev->spi_timer);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,7 +518,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
|
||||||
tx_count-IFX_SPI_HEADER_OVERHEAD,
|
tx_count-IFX_SPI_HEADER_OVERHEAD,
|
||||||
ifx_dev->spi_more);
|
ifx_dev->spi_more);
|
||||||
/* swap actual data in the buffer */
|
/* swap actual data in the buffer */
|
||||||
swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count,
|
ifx_dev->swap_buf((ifx_dev->tx_buffer), tx_count,
|
||||||
&ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
|
&ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
|
||||||
return tx_count;
|
return tx_count;
|
||||||
}
|
}
|
||||||
|
@ -469,9 +538,17 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
|
||||||
{
|
{
|
||||||
struct ifx_spi_device *ifx_dev = tty->driver_data;
|
struct ifx_spi_device *ifx_dev = tty->driver_data;
|
||||||
unsigned char *tmp_buf = (unsigned char *)buf;
|
unsigned char *tmp_buf = (unsigned char *)buf;
|
||||||
int tx_count = kfifo_in_locked(&ifx_dev->tx_fifo, tmp_buf, count,
|
unsigned long flags;
|
||||||
&ifx_dev->fifo_lock);
|
bool is_fifo_empty;
|
||||||
mrdy_assert(ifx_dev);
|
int tx_count;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ifx_dev->fifo_lock, flags);
|
||||||
|
is_fifo_empty = kfifo_is_empty(&ifx_dev->tx_fifo);
|
||||||
|
tx_count = kfifo_in(&ifx_dev->tx_fifo, tmp_buf, count);
|
||||||
|
spin_unlock_irqrestore(&ifx_dev->fifo_lock, flags);
|
||||||
|
if (is_fifo_empty)
|
||||||
|
mrdy_assert(ifx_dev);
|
||||||
|
|
||||||
return tx_count;
|
return tx_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,12 +607,19 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty)
|
||||||
/* clear any old data; can't do this in 'close' */
|
/* clear any old data; can't do this in 'close' */
|
||||||
kfifo_reset(&ifx_dev->tx_fifo);
|
kfifo_reset(&ifx_dev->tx_fifo);
|
||||||
|
|
||||||
|
/* clear any flag which may be set in port shutdown procedure */
|
||||||
|
clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags);
|
||||||
|
clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags);
|
||||||
|
|
||||||
/* put port data into this tty */
|
/* put port data into this tty */
|
||||||
tty->driver_data = ifx_dev;
|
tty->driver_data = ifx_dev;
|
||||||
|
|
||||||
/* allows flip string push from int context */
|
/* allows flip string push from int context */
|
||||||
tty->low_latency = 1;
|
tty->low_latency = 1;
|
||||||
|
|
||||||
|
/* set flag to allows data transfer */
|
||||||
|
set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +635,7 @@ static void ifx_port_shutdown(struct tty_port *port)
|
||||||
struct ifx_spi_device *ifx_dev =
|
struct ifx_spi_device *ifx_dev =
|
||||||
container_of(port, struct ifx_spi_device, tty_port);
|
container_of(port, struct ifx_spi_device, tty_port);
|
||||||
|
|
||||||
|
clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
|
||||||
mrdy_set_low(ifx_dev);
|
mrdy_set_low(ifx_dev);
|
||||||
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
|
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
|
||||||
tasklet_kill(&ifx_dev->io_work_tasklet);
|
tasklet_kill(&ifx_dev->io_work_tasklet);
|
||||||
|
@ -617,7 +702,7 @@ static void ifx_spi_complete(void *ctx)
|
||||||
|
|
||||||
if (!ifx_dev->spi_msg.status) {
|
if (!ifx_dev->spi_msg.status) {
|
||||||
/* check header validity, get comm flags */
|
/* check header validity, get comm flags */
|
||||||
swap_buf((u16 *)ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
|
ifx_dev->swap_buf(ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
|
||||||
&ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]);
|
&ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]);
|
||||||
decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer,
|
decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer,
|
||||||
&length, &more, &cts);
|
&length, &more, &cts);
|
||||||
|
@ -636,7 +721,8 @@ static void ifx_spi_complete(void *ctx)
|
||||||
|
|
||||||
actual_length = min((unsigned int)length,
|
actual_length = min((unsigned int)length,
|
||||||
ifx_dev->spi_msg.actual_length);
|
ifx_dev->spi_msg.actual_length);
|
||||||
swap_buf((u16 *)(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
|
ifx_dev->swap_buf(
|
||||||
|
(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
|
||||||
actual_length,
|
actual_length,
|
||||||
&ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
|
&ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
|
||||||
ifx_spi_insert_flip_string(
|
ifx_spi_insert_flip_string(
|
||||||
|
@ -705,7 +791,8 @@ static void ifx_spi_io(unsigned long data)
|
||||||
int retval;
|
int retval;
|
||||||
struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data;
|
struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data;
|
||||||
|
|
||||||
if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) {
|
if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) &&
|
||||||
|
test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) {
|
||||||
if (ifx_dev->gpio.unack_srdy_int_nb > 0)
|
if (ifx_dev->gpio.unack_srdy_int_nb > 0)
|
||||||
ifx_dev->gpio.unack_srdy_int_nb--;
|
ifx_dev->gpio.unack_srdy_int_nb--;
|
||||||
|
|
||||||
|
@ -773,6 +860,7 @@ static void ifx_spi_free_port(struct ifx_spi_device *ifx_dev)
|
||||||
{
|
{
|
||||||
if (ifx_dev->tty_dev)
|
if (ifx_dev->tty_dev)
|
||||||
tty_unregister_device(tty_drv, ifx_dev->minor);
|
tty_unregister_device(tty_drv, ifx_dev->minor);
|
||||||
|
tty_port_destroy(&ifx_dev->tty_port);
|
||||||
kfifo_free(&ifx_dev->tx_fifo);
|
kfifo_free(&ifx_dev->tx_fifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,10 +894,12 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev)
|
||||||
dev_dbg(&ifx_dev->spi_dev->dev,
|
dev_dbg(&ifx_dev->spi_dev->dev,
|
||||||
"%s: registering tty device failed", __func__);
|
"%s: registering tty device failed", __func__);
|
||||||
ret = PTR_ERR(ifx_dev->tty_dev);
|
ret = PTR_ERR(ifx_dev->tty_dev);
|
||||||
goto error_ret;
|
goto error_port;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_port:
|
||||||
|
tty_port_destroy(pport);
|
||||||
error_ret:
|
error_ret:
|
||||||
ifx_spi_free_port(ifx_dev);
|
ifx_spi_free_port(ifx_dev);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -826,7 +916,7 @@ error_ret:
|
||||||
static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev)
|
static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev)
|
||||||
{
|
{
|
||||||
if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) {
|
if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) {
|
||||||
del_timer_sync(&ifx_dev->spi_timer);
|
del_timer(&ifx_dev->spi_timer);
|
||||||
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
|
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,6 +1091,14 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* init swap_buf function according to word width configuration */
|
||||||
|
if (spi->bits_per_word == 32)
|
||||||
|
ifx_dev->swap_buf = swap_buf_32;
|
||||||
|
else if (spi->bits_per_word == 16)
|
||||||
|
ifx_dev->swap_buf = swap_buf_16;
|
||||||
|
else
|
||||||
|
ifx_dev->swap_buf = swap_buf_8;
|
||||||
|
|
||||||
/* ensure SPI protocol flags are initialized to enable transfer */
|
/* ensure SPI protocol flags are initialized to enable transfer */
|
||||||
ifx_dev->spi_more = 0;
|
ifx_dev->spi_more = 0;
|
||||||
ifx_dev->spi_slave_cts = 0;
|
ifx_dev->spi_slave_cts = 0;
|
||||||
|
@ -1219,6 +1317,9 @@ static int ifx_spi_spi_remove(struct spi_device *spi)
|
||||||
|
|
||||||
static void ifx_spi_spi_shutdown(struct spi_device *spi)
|
static void ifx_spi_spi_shutdown(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
|
struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
|
||||||
|
|
||||||
|
ifx_modem_power_off(ifx_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1338,7 +1439,7 @@ static struct spi_driver ifx_spi_driver = {
|
||||||
.owner = THIS_MODULE},
|
.owner = THIS_MODULE},
|
||||||
.probe = ifx_spi_spi_probe,
|
.probe = ifx_spi_spi_probe,
|
||||||
.shutdown = ifx_spi_spi_shutdown,
|
.shutdown = ifx_spi_spi_shutdown,
|
||||||
.remove = __devexit_p(ifx_spi_spi_remove),
|
.remove = ifx_spi_spi_remove,
|
||||||
.suspend = ifx_spi_spi_suspend,
|
.suspend = ifx_spi_spi_suspend,
|
||||||
.resume = ifx_spi_spi_resume,
|
.resume = ifx_spi_spi_resume,
|
||||||
.id_table = ifx_id_table
|
.id_table = ifx_id_table
|
||||||
|
@ -1354,7 +1455,9 @@ static void __exit ifx_spi_exit(void)
|
||||||
{
|
{
|
||||||
/* unregister */
|
/* unregister */
|
||||||
tty_unregister_driver(tty_drv);
|
tty_unregister_driver(tty_drv);
|
||||||
|
put_tty_driver(tty_drv);
|
||||||
spi_unregister_driver((void *)&ifx_spi_driver);
|
spi_unregister_driver((void *)&ifx_spi_driver);
|
||||||
|
unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1389,16 +1492,31 @@ static int __init ifx_spi_init(void)
|
||||||
if (result) {
|
if (result) {
|
||||||
pr_err("%s: tty_register_driver failed(%d)",
|
pr_err("%s: tty_register_driver failed(%d)",
|
||||||
DRVNAME, result);
|
DRVNAME, result);
|
||||||
put_tty_driver(tty_drv);
|
goto err_free_tty;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = spi_register_driver((void *)&ifx_spi_driver);
|
result = spi_register_driver((void *)&ifx_spi_driver);
|
||||||
if (result) {
|
if (result) {
|
||||||
pr_err("%s: spi_register_driver failed(%d)",
|
pr_err("%s: spi_register_driver failed(%d)",
|
||||||
DRVNAME, result);
|
DRVNAME, result);
|
||||||
tty_unregister_driver(tty_drv);
|
goto err_unreg_tty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = register_reboot_notifier(&ifx_modem_reboot_notifier_block);
|
||||||
|
if (result) {
|
||||||
|
pr_err("%s: register ifx modem reboot notifier failed(%d)",
|
||||||
|
DRVNAME, result);
|
||||||
|
goto err_unreg_spi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err_unreg_spi:
|
||||||
|
spi_unregister_driver((void *)&ifx_spi_driver);
|
||||||
|
err_unreg_tty:
|
||||||
|
tty_unregister_driver(tty_drv);
|
||||||
|
err_free_tty:
|
||||||
|
put_tty_driver(tty_drv);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#define IFX_SPI_STATE_IO_IN_PROGRESS 1
|
#define IFX_SPI_STATE_IO_IN_PROGRESS 1
|
||||||
#define IFX_SPI_STATE_IO_READY 2
|
#define IFX_SPI_STATE_IO_READY 2
|
||||||
#define IFX_SPI_STATE_TIMER_PENDING 3
|
#define IFX_SPI_STATE_TIMER_PENDING 3
|
||||||
|
#define IFX_SPI_STATE_IO_AVAILABLE 4
|
||||||
|
|
||||||
/* flow control bitfields */
|
/* flow control bitfields */
|
||||||
#define IFX_SPI_DCD 0
|
#define IFX_SPI_DCD 0
|
||||||
|
@ -124,6 +125,7 @@ struct ifx_spi_device {
|
||||||
#define MR_INPROGRESS 1
|
#define MR_INPROGRESS 1
|
||||||
#define MR_COMPLETE 2
|
#define MR_COMPLETE 2
|
||||||
wait_queue_head_t mdm_reset_wait;
|
wait_queue_head_t mdm_reset_wait;
|
||||||
|
void (*swap_buf)(unsigned char *buf, int len, void *end);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _IFX6X60_H */
|
#endif /* _IFX6X60_H */
|
||||||
|
|
|
@ -2010,7 +2010,7 @@ static int ioc3uart_remove(struct ioc3_submodule *is,
|
||||||
* @idd: ioc3 driver data for this card
|
* @idd: ioc3 driver data for this card
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int __devinit
|
static int
|
||||||
ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
|
ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
|
||||||
{
|
{
|
||||||
struct pci_dev *pdev = idd->pdev;
|
struct pci_dev *pdev = idd->pdev;
|
||||||
|
|
|
@ -57,9 +57,11 @@ enum {
|
||||||
DBG_CARR = 0x10000,
|
DBG_CARR = 0x10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define jsm_printk(nlevel, klevel, pdev, fmt, args...) \
|
#define jsm_dbg(nlevel, pdev, fmt, ...) \
|
||||||
if ((DBG_##nlevel & jsm_debug)) \
|
do { \
|
||||||
dev_printk(KERN_##klevel, pdev->dev, fmt, ## args)
|
if (DBG_##nlevel & jsm_debug) \
|
||||||
|
dev_dbg(pdev->dev, fmt, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define MAXLINES 256
|
#define MAXLINES 256
|
||||||
#define MAXPORTS 8
|
#define MAXPORTS 8
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue