1
0
Fork 0

Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6

* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (48 commits)
  serial: 8250_pci: add support for Cronyx Omega PCI multiserial board.
  tty/serial: Fix break handling for PORT_TEGRA
  tty/serial: Add explicit PORT_TEGRA type
  n_tracerouter and n_tracesink ldisc additions.
  Intel PTI implementaiton of MIPI 1149.7.
  Kernel documentation for the PTI feature.
  export kernel call get_task_comm().
  tty: Remove to support serial for S5P6442
  pch_phub: Support new device ML7223
  8250_pci: Add support for the Digi/IBM PCIe 2-port Adapter
  ASoC: Update cx20442 for TTY API change
  pch_uart: Support new device ML7223 IOH
  parport: Use request_muxed_region for IT87 probe and lock
  tty/serial: add support for Xilinx PS UART
  n_gsm: Use print_hex_dump_bytes
  drivers/tty/moxa.c: Put correct tty value
  TTY: tty_io, annotate locking functions
  TTY: serial_core, remove superfluous set_task_state
  TTY: serial_core, remove invalid test
  Char: moxa, fix locking in moxa_write
  ...

Fix up trivial conflicts in drivers/bluetooth/hci_ldisc.c and
drivers/tty/serial/Makefile.

I did the hci_ldisc thing as an evil merge, cleaning things up.
hifive-unleashed-5.1
Linus Torvalds 2011-05-23 12:23:20 -07:00
commit 99dff58562
103 changed files with 3349 additions and 518 deletions

View File

@ -0,0 +1,99 @@
The Intel MID PTI project is HW implemented in Intel Atom
system-on-a-chip designs based on the Parallel Trace
Interface for MIPI P1149.7 cJTAG standard. The kernel solution
for this platform involves the following files:
./include/linux/pti.h
./drivers/.../n_tracesink.h
./drivers/.../n_tracerouter.c
./drivers/.../n_tracesink.c
./drivers/.../pti.c
pti.c is the driver that enables various debugging features
popular on platforms from certain mobile manufacturers.
n_tracerouter.c and n_tracesink.c allow extra system information to
be collected and routed to the pti driver, such as trace
debugging data from a modem. Although n_tracerouter
and n_tracesink are a part of the complete PTI solution,
these two line disciplines can work separately from
pti.c and route any data stream from one /dev/tty node
to another /dev/tty node via kernel-space. This provides
a stable, reliable connection that will not break unless
the user-space application shuts down (plus avoids
kernel->user->kernel context switch overheads of routing
data).
An example debugging usage for this driver system:
*Hook /dev/ttyPTI0 to syslogd. Opening this port will also start
a console device to further capture debugging messages to PTI.
*Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW.
This is where n_tracerouter and n_tracesink are used.
*Hook /dev/pti to a user-level debugging application for writing
to PTI HW.
*Use mipi_* Kernel Driver API in other device drivers for
debugging to PTI by first requesting a PTI write address via
mipi_request_masterchannel(1).
Below is example pseudo-code on how a 'privileged' application
can hook up n_tracerouter and n_tracesink to any tty on
a system. 'Privileged' means the application has enough
privileges to successfully manipulate the ldisc drivers
but is not just blindly executing as 'root'. Keep in mind
the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter
and n_tracesink line discpline drivers but is a generic
operation for a program to use a line discpline driver
on a tty port other than the default n_tty.
/////////// To hook up n_tracerouter and n_tracesink /////////
// Note that n_tracerouter depends on n_tracesink.
#include <errno.h>
#define ONE_TTY "/dev/ttyOne"
#define TWO_TTY "/dev/ttyTwo"
// needed global to hand onto ldisc connection
static int g_fd_source = -1;
static int g_fd_sink = -1;
// these two vars used to grab LDISC values from loaded ldisc drivers
// in OS. Look at /proc/tty/ldiscs to get the right numbers from
// the ldiscs loaded in the system.
int source_ldisc_num, sink_ldisc_num = -1;
int retval;
g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W
g_fd_sink = open(TWO_TTY, O_RDWR); // must be R/W
if (g_fd_source <= 0) || (g_fd_sink <= 0) {
// doubt you'll want to use these exact error lines of code
printf("Error on open(). errno: %d\n",errno);
return errno;
}
retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num);
if (retval < 0) {
printf("Error on ioctl(). errno: %d\n", errno);
return errno;
}
retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num);
if (retval < 0) {
printf("Error on ioctl(). errno: %d\n", errno);
return errno;
}
/////////// To disconnect n_tracerouter and n_tracesink ////////
// First make sure data through the ldiscs has stopped.
// Second, disconnect ldiscs. This provides a
// little cleaner shutdown on tty stack.
sink_ldisc_num = 0;
source_ldisc_num = 0;
ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num);
ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num);
// Three, program closes connection, and cleanup:
close(g_fd_uart);
close(g_fd_gadget);
g_fd_uart = g_fd_gadget = NULL;

View File

@ -355,26 +355,29 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
* flags pointer to flags for data
* count count of received data in bytes
*
* Return Value: None
* Return Value: Number of bytes received
*/
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
static unsigned int hci_uart_tty_receive(struct tty_struct *tty,
const u8 *data, char *flags, int count)
{
int ret;
struct hci_uart *hu = (void *)tty->disc_data;
int received;
if (!hu || tty != hu->tty)
return;
return -ENODEV;
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
return;
return -EINVAL;
spin_lock(&hu->rx_lock);
ret = hu->proto->recv(hu, (void *) data, count);
if (ret > 0)
hu->hdev->stat.byte_rx += count;
received = hu->proto->recv(hu, (void *) data, count);
if (received > 0)
hu->hdev->stat.byte_rx += received;
spin_unlock(&hu->rx_lock);
tty_unthrottle(tty);
return received;
}
static int hci_uart_register_dev(struct hci_uart *hu)

View File

@ -120,17 +120,21 @@ static void serport_ldisc_close(struct tty_struct *tty)
* 'interrupt' routine.
*/
static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
static unsigned int serport_ldisc_receive(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct serport *serport = (struct serport*) tty->disc_data;
unsigned long flags;
unsigned int ch_flags;
int ret = 0;
int i;
spin_lock_irqsave(&serport->lock, flags);
if (!test_bit(SERPORT_ACTIVE, &serport->flags))
if (!test_bit(SERPORT_ACTIVE, &serport->flags)) {
ret = -EINVAL;
goto out;
}
for (i = 0; i < count; i++) {
switch (fp[i]) {
@ -152,6 +156,8 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c
out:
spin_unlock_irqrestore(&serport->lock, flags);
return ret == 0 ? count : ret;
}
/*

View File

@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
* cflags buffer containing error flags for received characters (ignored)
* count number of received characters
*/
static void
static unsigned int
gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
char *cflags, int count)
{
@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
struct inbuf_t *inbuf;
if (!cs)
return;
return -ENODEV;
inbuf = cs->inbuf;
if (!inbuf) {
dev_err(cs->dev, "%s: no inbuf\n", __func__);
cs_put(cs);
return;
return -EINVAL;
}
tail = inbuf->tail;
@ -725,6 +725,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
gigaset_schedule_event(cs);
cs_put(cs);
return count;
}
/*

View File

@ -144,6 +144,19 @@ config PHANTOM
If you choose to build module, its name will be phantom. If unsure,
say N here.
config INTEL_MID_PTI
tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
default n
help
The PTI (Parallel Trace Interface) driver directs
trace data routed from various parts in the system out
through an Intel Penwell PTI port and out of the mobile
device for analysis with a debugging tool (Lauterbach or Fido).
You should select this driver if the target kernel is meant for
an Intel Atom (non-netbook) mobile device containing a MIPI
P1149.7 standard implementation.
config SGI_IOC4
tristate "SGI IOC4 Base IO support"
depends on PCI
@ -459,7 +472,7 @@ config BMP085
module will be called bmp085.
config PCH_PHUB
tristate "PCH Packet Hub of Intel Topcliff / OKI SEMICONDUCTOR ML7213"
tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"
depends on PCI
help
This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
@ -467,10 +480,12 @@ config PCH_PHUB
processor. The Topcliff has MAC address and Option ROM data in SROM.
This driver can access MAC address and Option ROM data in SROM.
This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
for IVI(In-Vehicle Infotainment) use.
ML7213 is companion chip for Intel Atom E6xx series.
ML7213 is completely compatible for Intel EG20T PCH.
This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
Output Hub), ML7213 and ML7223.
ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
for MP(Media Phone) use.
ML7213/ML7223 is companion chip for Intel Atom E6xx series.
ML7213/ML7223 is completely compatible for Intel EG20T PCH.
To compile this driver as a module, choose M here: the module will
be called pch_phub.

View File

@ -6,6 +6,7 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
0bj-$(CONFIG_INTEL_MID_PTI) += pti.o
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o

View File

@ -34,12 +34,18 @@
#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
#define PCH_PHUB_MAC_START_ADDR 0x20C /* MAC data area start address offset */
#define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset
#define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address
offset */
#define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address
offset */
#define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
(Intel EG20T PCH)*/
#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
offset(OKI SEMICONDUCTOR ML7213)
*/
#define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
offset(OKI SEMICONDUCTOR ML7223)
*/
/* MAX number of INT_REDUCE_CONTROL registers */
#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
@ -63,6 +69,10 @@
#define PCI_VENDOR_ID_ROHM 0x10db
#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
/* Macros for ML7223 */
#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
/* SROM ACCESS Macro */
#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
@ -100,6 +110,9 @@
* @clkcfg_reg: CLK CFG register val
* @pch_phub_base_address: Register base address
* @pch_phub_extrom_base_address: external rom base address
* @pch_mac_start_address: MAC address area start address
* @pch_opt_rom_start_address: Option ROM start address
* @ioh_type: Save IOH type
*/
struct pch_phub_reg {
u32 phub_id_reg;
@ -117,6 +130,9 @@ struct pch_phub_reg {
u32 clkcfg_reg;
void __iomem *pch_phub_base_address;
void __iomem *pch_phub_extrom_base_address;
u32 pch_mac_start_address;
u32 pch_opt_rom_start_address;
int ioh_type;
};
/* SROM SPEC for MAC address assignment offset */
@ -319,7 +335,7 @@ static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
{
unsigned int mem_addr;
mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T +
mem_addr = chip->pch_mac_start_address +
pch_phub_mac_offset[offset_address];
pch_phub_read_serial_rom(chip, mem_addr, data);
@ -336,7 +352,7 @@ static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
int retval;
unsigned int mem_addr;
mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T +
mem_addr = chip->pch_mac_start_address +
pch_phub_mac_offset[offset_address];
retval = pch_phub_write_serial_rom(chip, mem_addr, data);
@ -384,6 +400,48 @@ static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
return retval;
}
/* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
* for Gigabit Ethernet MAC address
*/
static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
{
int retval;
u32 offset_addr;
offset_addr = 0x200;
retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
return retval;
}
/**
* pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
* @offset_address: Gigabit Ethernet MAC address offset value.
@ -406,7 +464,10 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
int retval;
int i;
retval = pch_phub_gbe_serial_rom_conf(chip);
if (chip->ioh_type == 1) /* EG20T */
retval = pch_phub_gbe_serial_rom_conf(chip);
else /* ML7223 */
retval = pch_phub_gbe_serial_rom_conf_mp(chip);
if (retval)
return retval;
@ -441,12 +502,16 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
}
/* Get Rom signature */
pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature);
pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
(unsigned char *)&rom_signature);
rom_signature &= 0xff;
pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp);
pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
(unsigned char *)&tmp);
rom_signature |= (tmp & 0xff) << 8;
if (rom_signature == 0xAA55) {
pch_phub_read_serial_rom(chip, 0x82, &rom_length);
pch_phub_read_serial_rom(chip,
chip->pch_opt_rom_start_address + 2,
&rom_length);
orom_size = rom_length * 512;
if (orom_size < off) {
addr_offset = 0;
@ -458,8 +523,9 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
}
for (addr_offset = 0; addr_offset < count; addr_offset++) {
pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off,
&buf[addr_offset]);
pch_phub_read_serial_rom(chip,
chip->pch_opt_rom_start_address + addr_offset + off,
&buf[addr_offset]);
}
} else {
err = -ENODATA;
@ -502,8 +568,9 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
if (PCH_PHUB_OROM_SIZE < off + addr_offset)
goto return_ok;
ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off,
buf[addr_offset]);
ret = pch_phub_write_serial_rom(chip,
chip->pch_opt_rom_start_address + addr_offset + off,
buf[addr_offset]);
if (ret) {
err = ret;
goto return_err;
@ -603,19 +670,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
"in pch_phub_base_address variable is %p\n", __func__,
chip->pch_phub_base_address);
chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
if (chip->pch_phub_extrom_base_address == 0) {
dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__);
ret = -ENOMEM;
goto err_pci_map;
if (id->driver_data != 3) {
chip->pch_phub_extrom_base_address =\
pci_map_rom(pdev, &rom_size);
if (chip->pch_phub_extrom_base_address == 0) {
dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
ret = -ENOMEM;
goto err_pci_map;
}
dev_dbg(&pdev->dev, "%s : "
"pci_map_rom SUCCESS and value in "
"pch_phub_extrom_base_address variable is %p\n",
__func__, chip->pch_phub_extrom_base_address);
}
dev_dbg(&pdev->dev, "%s : "
"pci_map_rom SUCCESS and value in "
"pch_phub_extrom_base_address variable is %p\n", __func__,
chip->pch_phub_extrom_base_address);
if (id->driver_data == 1) {
if (id->driver_data == 1) { /* EG20T PCH */
retval = sysfs_create_file(&pdev->dev.kobj,
&dev_attr_pch_mac.attr);
if (retval)
@ -642,7 +712,9 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
/* set the interrupt delay value */
iowrite32(0x25, chip->pch_phub_base_address + 0x44);
} else if (id->driver_data == 2) {
chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
} else if (id->driver_data == 2) { /* ML7213 IOH */
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
if (retval)
goto err_sysfs_create;
@ -653,7 +725,38 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
* Device8(USB OHCI #0/ USB EHCI #0):a
*/
iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
chip->pch_opt_rom_start_address =\
PCH_PHUB_ROM_START_ADDR_ML7213;
} else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
/* set the prefech value
* Device8(GbE)
*/
iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
chip->pch_opt_rom_start_address =\
PCH_PHUB_ROM_START_ADDR_ML7223;
chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
} else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
retval = sysfs_create_file(&pdev->dev.kobj,
&dev_attr_pch_mac.attr);
if (retval)
goto err_sysfs_create;
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
if (retval)
goto exit_bin_attr;
/* set the prefech value
* Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
* Device4(SDIO #0,1):f
* Device6(SATA 2):f
*/
iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
/* set the interrupt delay value */
iowrite32(0x25, chip->pch_phub_base_address + 0x140);
chip->pch_opt_rom_start_address =\
PCH_PHUB_ROM_START_ADDR_ML7223;
chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
}
chip->ioh_type = id->driver_data;
pci_set_drvdata(pdev, chip);
return 0;
@ -733,6 +836,8 @@ static int pch_phub_resume(struct pci_dev *pdev)
static struct pci_device_id pch_phub_pcidev_id[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, },
{ }
};
MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
@ -759,5 +864,5 @@ static void __exit pch_phub_pci_exit(void)
module_init(pch_phub_pci_init);
module_exit(pch_phub_pci_exit);
MODULE_DESCRIPTION("PCH Packet Hub PCI Driver");
MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB");
MODULE_LICENSE("GPL");

980
drivers/misc/pti.c 100644
View File

@ -0,0 +1,980 @@
/*
* pti.c - PTI driver for cJTAG data extration
*
* Copyright (C) Intel 2010
*
* 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.
*
* 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.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The PTI (Parallel Trace Interface) driver directs trace data routed from
* various parts in the system out through the Intel Penwell PTI port and
* out of the mobile device for analysis with a debugging tool
* (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
* compact JTAG, standard.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/console.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/pci.h>
#include <linux/mutex.h>
#include <linux/miscdevice.h>
#include <linux/pti.h>
#define DRIVERNAME "pti"
#define PCINAME "pciPTI"
#define TTYNAME "ttyPTI"
#define CHARNAME "pti"
#define PTITTY_MINOR_START 0
#define PTITTY_MINOR_NUM 2
#define MAX_APP_IDS 16 /* 128 channel ids / u8 bit size */
#define MAX_OS_IDS 16 /* 128 channel ids / u8 bit size */
#define MAX_MODEM_IDS 16 /* 128 channel ids / u8 bit size */
#define MODEM_BASE_ID 71 /* modem master ID address */
#define CONTROL_ID 72 /* control master ID address */
#define CONSOLE_ID 73 /* console master ID address */
#define OS_BASE_ID 74 /* base OS master ID address */
#define APP_BASE_ID 80 /* base App master ID address */
#define CONTROL_FRAME_LEN 32 /* PTI control frame maximum size */
#define USER_COPY_SIZE 8192 /* 8Kb buffer for user space copy */
#define APERTURE_14 0x3800000 /* offset to first OS write addr */
#define APERTURE_LEN 0x400000 /* address length */
struct pti_tty {
struct pti_masterchannel *mc;
};
struct pti_dev {
struct tty_port port;
unsigned long pti_addr;
unsigned long aperture_base;
void __iomem *pti_ioaddr;
u8 ia_app[MAX_APP_IDS];
u8 ia_os[MAX_OS_IDS];
u8 ia_modem[MAX_MODEM_IDS];
};
/*
* This protects access to ia_app, ia_os, and ia_modem,
* which keeps track of channels allocated in
* an aperture write id.
*/
static DEFINE_MUTEX(alloclock);
static struct pci_device_id pci_ids[] __devinitconst = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)},
{0}
};
static struct tty_driver *pti_tty_driver;
static struct pti_dev *drv_data;
static unsigned int pti_console_channel;
static unsigned int pti_control_channel;
/**
* pti_write_to_aperture()- The private write function to PTI HW.
*
* @mc: The 'aperture'. It's part of a write address that holds
* a master and channel ID.
* @buf: Data being written to the HW that will ultimately be seen
* in a debugging tool (Fido, Lauterbach).
* @len: Size of buffer.
*
* Since each aperture is specified by a unique
* master/channel ID, no two processes will be writing
* to the same aperture at the same time so no lock is required. The
* PTI-Output agent will send these out in the order that they arrived, and
* thus, it will intermix these messages. The debug tool can then later
* regroup the appropriate message segments together reconstituting each
* message.
*/
static void pti_write_to_aperture(struct pti_masterchannel *mc,
u8 *buf,
int len)
{
int dwordcnt;
int final;
int i;
u32 ptiword;
u32 __iomem *aperture;
u8 *p = buf;
/*
* calculate the aperture offset from the base using the master and
* channel id's.
*/
aperture = drv_data->pti_ioaddr + (mc->master << 15)
+ (mc->channel << 8);
dwordcnt = len >> 2;
final = len - (dwordcnt << 2); /* final = trailing bytes */
if (final == 0 && dwordcnt != 0) { /* always need a final dword */
final += 4;
dwordcnt--;
}
for (i = 0; i < dwordcnt; i++) {
ptiword = be32_to_cpu(*(u32 *)p);
p += 4;
iowrite32(ptiword, aperture);
}
aperture += PTI_LASTDWORD_DTS; /* adding DTS signals that is EOM */
ptiword = 0;
for (i = 0; i < final; i++)
ptiword |= *p++ << (24-(8*i));
iowrite32(ptiword, aperture);
return;
}
/**
* pti_control_frame_built_and_sent()- control frame build and send function.
*
* @mc: The master / channel structure on which the function
* built a control frame.
*
* To be able to post process the PTI contents on host side, a control frame
* is added before sending any PTI content. So the host side knows on
* each PTI frame the name of the thread using a dedicated master / channel.
* The thread name is retrieved from the 'current' global variable.
* This function builds this frame and sends it to a master ID CONTROL_ID.
* The overhead is only 32 bytes since the driver only writes to HW
* in 32 byte chunks.
*/
static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc)
{
struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
.channel = 0};
const char *control_format = "%3d %3d %s";
u8 control_frame[CONTROL_FRAME_LEN];
/*
* Since we access the comm member in current's task_struct,
* we only need to be as large as what 'comm' in that
* structure is.
*/
char comm[TASK_COMM_LEN];
if (!in_interrupt())
get_task_comm(comm, current);
else
strncpy(comm, "Interrupt", TASK_COMM_LEN);
/* Absolutely ensure our buffer is zero terminated. */
comm[TASK_COMM_LEN-1] = 0;
mccontrol.channel = pti_control_channel;
pti_control_channel = (pti_control_channel + 1) & 0x7f;
snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
mc->channel, comm);
pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
}
/**
* pti_write_full_frame_to_aperture()- high level function to
* write to PTI.
*
* @mc: The 'aperture'. It's part of a write address that holds
* a master and channel ID.
* @buf: Data being written to the HW that will ultimately be seen
* in a debugging tool (Fido, Lauterbach).
* @len: Size of buffer.
*
* All threads sending data (either console, user space application, ...)
* are calling the high level function to write to PTI meaning that it is
* possible to add a control frame before sending the content.
*/
static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
const unsigned char *buf,
int len)
{
pti_control_frame_built_and_sent(mc);
pti_write_to_aperture(mc, (u8 *)buf, len);
}
/**
* get_id()- Allocate a master and channel ID.
*
* @id_array: an array of bits representing what channel
* id's are allocated for writing.
* @max_ids: The max amount of available write IDs to use.
* @base_id: The starting SW channel ID, based on the Intel
* PTI arch.
*
* Returns:
* pti_masterchannel struct with master, channel ID address
* 0 for error
*
* Each bit in the arrays ia_app and ia_os correspond to a master and
* channel id. The bit is one if the id is taken and 0 if free. For
* every master there are 128 channel id's.
*/
static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id)
{
struct pti_masterchannel *mc;
int i, j, mask;
mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL);
if (mc == NULL)
return NULL;
/* look for a byte with a free bit */
for (i = 0; i < max_ids; i++)
if (id_array[i] != 0xff)
break;
if (i == max_ids) {
kfree(mc);
return NULL;
}
/* find the bit in the 128 possible channel opportunities */
mask = 0x80;
for (j = 0; j < 8; j++) {
if ((id_array[i] & mask) == 0)
break;
mask >>= 1;
}
/* grab it */
id_array[i] |= mask;
mc->master = base_id;
mc->channel = ((i & 0xf)<<3) + j;
/* write new master Id / channel Id allocation to channel control */
pti_control_frame_built_and_sent(mc);
return mc;
}
/*
* The following three functions:
* pti_request_mastercahannel(), mipi_release_masterchannel()
* and pti_writedata() are an API for other kernel drivers to
* access PTI.
*/
/**
* pti_request_masterchannel()- Kernel API function used to allocate
* a master, channel ID address
* to write to PTI HW.
*
* @type: 0- request Application master, channel aperture ID write address.
* 1- request OS master, channel aperture ID write
* address.
* 2- request Modem master, channel aperture ID
* write address.
* Other values, error.
*
* Returns:
* pti_masterchannel struct
* 0 for error
*/
struct pti_masterchannel *pti_request_masterchannel(u8 type)
{
struct pti_masterchannel *mc;
mutex_lock(&alloclock);
switch (type) {
case 0:
mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID);
break;
case 1:
mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID);
break;
case 2:
mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID);
break;
default:
mc = NULL;
}
mutex_unlock(&alloclock);
return mc;
}
EXPORT_SYMBOL_GPL(pti_request_masterchannel);
/**
* pti_release_masterchannel()- Kernel API function used to release
* a master, channel ID address
* used to write to PTI HW.
*
* @mc: master, channel apeture ID address to be released.
*/
void pti_release_masterchannel(struct pti_masterchannel *mc)
{
u8 master, channel, i;
mutex_lock(&alloclock);
if (mc) {
master = mc->master;
channel = mc->channel;
if (master == APP_BASE_ID) {
i = channel >> 3;
drv_data->ia_app[i] &= ~(0x80>>(channel & 0x7));
} else if (master == OS_BASE_ID) {
i = channel >> 3;
drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7));
} else {
i = channel >> 3;
drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7));
}
kfree(mc);
}
mutex_unlock(&alloclock);
}
EXPORT_SYMBOL_GPL(pti_release_masterchannel);
/**
* pti_writedata()- Kernel API function used to write trace
* debugging data to PTI HW.
*
* @mc: Master, channel aperture ID address to write to.
* Null value will return with no write occurring.
* @buf: Trace debuging data to write to the PTI HW.
* Null value will return with no write occurring.
* @count: Size of buf. Value of 0 or a negative number will
* return with no write occuring.
*/
void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count)
{
/*
* since this function is exported, this is treated like an
* API function, thus, all parameters should
* be checked for validity.
*/
if ((mc != NULL) && (buf != NULL) && (count > 0))
pti_write_to_aperture(mc, buf, count);
return;
}
EXPORT_SYMBOL_GPL(pti_writedata);
/**
* pti_pci_remove()- Driver exit method to remove PTI from
* PCI bus.
* @pdev: variable containing pci info of PTI.
*/
static void __devexit pti_pci_remove(struct pci_dev *pdev)
{
struct pti_dev *drv_data;
drv_data = pci_get_drvdata(pdev);
if (drv_data != NULL) {
pci_iounmap(pdev, drv_data->pti_ioaddr);
pci_set_drvdata(pdev, NULL);
kfree(drv_data);
pci_release_region(pdev, 1);
pci_disable_device(pdev);
}
}
/*
* for the tty_driver_*() basic function descriptions, see tty_driver.h.
* Specific header comments made for PTI-related specifics.
*/
/**
* pti_tty_driver_open()- Open an Application master, channel aperture
* ID to the PTI device via tty device.
*
* @tty: tty interface.
* @filp: filp interface pased to tty_port_open() call.
*
* Returns:
* int, 0 for success
* otherwise, fail value
*
* The main purpose of using the tty device interface is for
* each tty port to have a unique PTI write aperture. In an
* example use case, ttyPTI0 gets syslogd and an APP aperture
* ID and ttyPTI1 is where the n_tracesink ldisc hooks to route
* modem messages into PTI. Modem trace data does not have to
* go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct
* master IDs. These messages go through the PTI HW and out of
* the handheld platform and to the Fido/Lauterbach device.
*/
static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
{
/*
* we actually want to allocate a new channel per open, per
* system arch. HW gives more than plenty channels for a single
* system task to have its own channel to write trace data. This
* also removes a locking requirement for the actual write
* procedure.
*/
return tty_port_open(&drv_data->port, tty, filp);
}
/**
* pti_tty_driver_close()- close tty device and release Application
* master, channel aperture ID to the PTI device via tty device.
*
* @tty: tty interface.
* @filp: filp interface pased to tty_port_close() call.
*
* The main purpose of using the tty device interface is to route
* syslog daemon messages to the PTI HW and out of the handheld platform
* and to the Fido/Lauterbach device.
*/
static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
{
tty_port_close(&drv_data->port, tty, filp);
}
/**
* pti_tty_intstall()- Used to set up specific master-channels
* to tty ports for organizational purposes when
* tracing viewed from debuging tools.
*
* @driver: tty driver information.
* @tty: tty struct containing pti information.
*
* Returns:
* 0 for success
* otherwise, error
*/
static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
{
int idx = tty->index;
struct pti_tty *pti_tty_data;
int ret = tty_init_termios(tty);
if (ret == 0) {
tty_driver_kref_get(driver);
tty->count++;
driver->ttys[idx] = tty;
pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL);
if (pti_tty_data == NULL)
return -ENOMEM;
if (idx == PTITTY_MINOR_START)
pti_tty_data->mc = pti_request_masterchannel(0);
else
pti_tty_data->mc = pti_request_masterchannel(2);
if (pti_tty_data->mc == NULL)
return -ENXIO;
tty->driver_data = pti_tty_data;
}
return ret;
}
/**
* pti_tty_cleanup()- Used to de-allocate master-channel resources
* tied to tty's of this driver.
*
* @tty: tty struct containing pti information.
*/
static void pti_tty_cleanup(struct tty_struct *tty)
{
struct pti_tty *pti_tty_data = tty->driver_data;
if (pti_tty_data == NULL)
return;
pti_release_masterchannel(pti_tty_data->mc);
kfree(tty->driver_data);
tty->driver_data = NULL;
}
/**
* pti_tty_driver_write()- Write trace debugging data through the char
* interface to the PTI HW. Part of the misc device implementation.
*
* @filp: Contains private data which is used to obtain
* master, channel write ID.
* @data: trace data to be written.
* @len: # of byte to write.
*
* Returns:
* int, # of bytes written
* otherwise, error
*/
static int pti_tty_driver_write(struct tty_struct *tty,
const unsigned char *buf, int len)
{
struct pti_tty *pti_tty_data = tty->driver_data;
if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) {
pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len);
return len;
}
/*
* we can't write to the pti hardware if the private driver_data
* and the mc address is not there.
*/
else
return -EFAULT;
}
/**
* pti_tty_write_room()- Always returns 2048.
*
* @tty: contains tty info of the pti driver.
*/
static int pti_tty_write_room(struct tty_struct *tty)
{
return 2048;
}
/**
* pti_char_open()- Open an Application master, channel aperture
* ID to the PTI device. Part of the misc device implementation.
*
* @inode: not used.
* @filp: Output- will have a masterchannel struct set containing
* the allocated application PTI aperture write address.
*
* Returns:
* int, 0 for success
* otherwise, a fail value
*/
static int pti_char_open(struct inode *inode, struct file *filp)
{
struct pti_masterchannel *mc;
/*
* We really do want to fail immediately if
* pti_request_masterchannel() fails,
* before assigning the value to filp->private_data.
* Slightly easier to debug if this driver needs debugging.
*/
mc = pti_request_masterchannel(0);
if (mc == NULL)
return -ENOMEM;
filp->private_data = mc;
return 0;
}
/**
* pti_char_release()- Close a char channel to the PTI device. Part
* of the misc device implementation.
*
* @inode: Not used in this implementaiton.
* @filp: Contains private_data that contains the master, channel
* ID to be released by the PTI device.
*
* Returns:
* always 0
*/
static int pti_char_release(struct inode *inode, struct file *filp)
{
pti_release_masterchannel(filp->private_data);
kfree(filp->private_data);
return 0;
}
/**
* pti_char_write()- Write trace debugging data through the char
* interface to the PTI HW. Part of the misc device implementation.
*
* @filp: Contains private data which is used to obtain
* master, channel write ID.
* @data: trace data to be written.
* @len: # of byte to write.
* @ppose: Not used in this function implementation.
*
* Returns:
* int, # of bytes written
* otherwise, error value
*
* Notes: From side discussions with Alan Cox and experimenting
* with PTI debug HW like Nokia's Fido box and Lauterbach
* devices, 8192 byte write buffer used by USER_COPY_SIZE was
* deemed an appropriate size for this type of usage with
* debugging HW.
*/
static ssize_t pti_char_write(struct file *filp, const char __user *data,
size_t len, loff_t *ppose)
{
struct pti_masterchannel *mc;
void *kbuf;
const char __user *tmp;
size_t size = USER_COPY_SIZE;
size_t n = 0;
tmp = data;
mc = filp->private_data;
kbuf = kmalloc(size, GFP_KERNEL);
if (kbuf == NULL) {
pr_err("%s(%d): buf allocation failed\n",
__func__, __LINE__);
return -ENOMEM;
}
do {
if (len - n > USER_COPY_SIZE)
size = USER_COPY_SIZE;
else
size = len - n;
if (copy_from_user(kbuf, tmp, size)) {
kfree(kbuf);
return n ? n : -EFAULT;
}
pti_write_to_aperture(mc, kbuf, size);
n += size;
tmp += size;
} while (len > n);
kfree(kbuf);
return len;
}
static const struct tty_operations pti_tty_driver_ops = {
.open = pti_tty_driver_open,
.close = pti_tty_driver_close,
.write = pti_tty_driver_write,
.write_room = pti_tty_write_room,
.install = pti_tty_install,
.cleanup = pti_tty_cleanup
};
static const struct file_operations pti_char_driver_ops = {
.owner = THIS_MODULE,
.write = pti_char_write,
.open = pti_char_open,
.release = pti_char_release,
};
static struct miscdevice pti_char_driver = {
.minor = MISC_DYNAMIC_MINOR,
.name = CHARNAME,
.fops = &pti_char_driver_ops
};
/**
* pti_console_write()- Write to the console that has been acquired.
*
* @c: Not used in this implementaiton.
* @buf: Data to be written.
* @len: Length of buf.
*/
static void pti_console_write(struct console *c, const char *buf, unsigned len)
{
static struct pti_masterchannel mc = {.master = CONSOLE_ID,
.channel = 0};
mc.channel = pti_console_channel;
pti_console_channel = (pti_console_channel + 1) & 0x7f;
pti_write_full_frame_to_aperture(&mc, buf, len);
}
/**
* pti_console_device()- Return the driver tty structure and set the
* associated index implementation.
*
* @c: Console device of the driver.
* @index: index associated with c.
*
* Returns:
* always value of pti_tty_driver structure when this function
* is called.
*/
static struct tty_driver *pti_console_device(struct console *c, int *index)
{
*index = c->index;
return pti_tty_driver;
}
/**
* pti_console_setup()- Initialize console variables used by the driver.
*
* @c: Not used.
* @opts: Not used.
*
* Returns:
* always 0.
*/
static int pti_console_setup(struct console *c, char *opts)
{
pti_console_channel = 0;
pti_control_channel = 0;
return 0;
}
/*
* pti_console struct, used to capture OS printk()'s and shift
* out to the PTI device for debugging. This cannot be
* enabled upon boot because of the possibility of eating
* any serial console printk's (race condition discovered).
* The console should be enabled upon when the tty port is
* used for the first time. Since the primary purpose for
* the tty port is to hook up syslog to it, the tty port
* will be open for a really long time.
*/
static struct console pti_console = {
.name = TTYNAME,
.write = pti_console_write,
.device = pti_console_device,
.setup = pti_console_setup,
.flags = CON_PRINTBUFFER,
.index = 0,
};
/**
* pti_port_activate()- Used to start/initialize any items upon
* first opening of tty_port().
*
* @port- The tty port number of the PTI device.
* @tty- The tty struct associated with this device.
*
* Returns:
* always returns 0
*
* Notes: The primary purpose of the PTI tty port 0 is to hook
* the syslog daemon to it; thus this port will be open for a
* very long time.
*/
static int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
{
if (port->tty->index == PTITTY_MINOR_START)
console_start(&pti_console);
return 0;
}
/**
* pti_port_shutdown()- Used to stop/shutdown any items upon the
* last tty port close.
*
* @port- The tty port number of the PTI device.
*
* Notes: The primary purpose of the PTI tty port 0 is to hook
* the syslog daemon to it; thus this port will be open for a
* very long time.
*/
static void pti_port_shutdown(struct tty_port *port)
{
if (port->tty->index == PTITTY_MINOR_START)
console_stop(&pti_console);
}
static const struct tty_port_operations tty_port_ops = {
.activate = pti_port_activate,
.shutdown = pti_port_shutdown,
};
/*
* Note the _probe() call sets everything up and ties the char and tty
* to successfully detecting the PTI device on the pci bus.
*/
/**
* pti_pci_probe()- Used to detect pti on the pci bus and set
* things up in the driver.
*
* @pdev- pci_dev struct values for pti.
* @ent- pci_device_id struct for pti driver.
*
* Returns:
* 0 for success
* otherwise, error
*/
static int __devinit pti_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int retval = -EINVAL;
int pci_bar = 1;
dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__,
__func__, __LINE__, pdev->vendor, pdev->device);
retval = misc_register(&pti_char_driver);
if (retval) {
pr_err("%s(%d): CHAR registration failed of pti driver\n",
__func__, __LINE__);
pr_err("%s(%d): Error value returned: %d\n",
__func__, __LINE__, retval);
return retval;
}
retval = pci_enable_device(pdev);
if (retval != 0) {
dev_err(&pdev->dev,
"%s: pci_enable_device() returned error %d\n",
__func__, retval);
return retval;
}
drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
if (drv_data == NULL) {
retval = -ENOMEM;
dev_err(&pdev->dev,
"%s(%d): kmalloc() returned NULL memory.\n",
__func__, __LINE__);
return retval;
}
drv_data->pti_addr = pci_resource_start(pdev, pci_bar);
retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
if (retval != 0) {
dev_err(&pdev->dev,
"%s(%d): pci_request_region() returned error %d\n",
__func__, __LINE__, retval);
kfree(drv_data);
return retval;
}
drv_data->aperture_base = drv_data->pti_addr+APERTURE_14;
drv_data->pti_ioaddr =
ioremap_nocache((u32)drv_data->aperture_base,
APERTURE_LEN);
if (!drv_data->pti_ioaddr) {
pci_release_region(pdev, pci_bar);
retval = -ENOMEM;
kfree(drv_data);
return retval;
}
pci_set_drvdata(pdev, drv_data);
tty_port_init(&drv_data->port);
drv_data->port.ops = &tty_port_ops;
tty_register_device(pti_tty_driver, 0, &pdev->dev);
tty_register_device(pti_tty_driver, 1, &pdev->dev);
register_console(&pti_console);
return retval;
}
static struct pci_driver pti_pci_driver = {
.name = PCINAME,
.id_table = pci_ids,
.probe = pti_pci_probe,
.remove = pti_pci_remove,
};
/**
*
* pti_init()- Overall entry/init call to the pti driver.
* It starts the registration process with the kernel.
*
* Returns:
* int __init, 0 for success
* otherwise value is an error
*
*/
static int __init pti_init(void)
{
int retval = -EINVAL;
/* First register module as tty device */
pti_tty_driver = alloc_tty_driver(1);
if (pti_tty_driver == NULL) {
pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n",
__func__, __LINE__);
return -ENOMEM;
}
pti_tty_driver->owner = THIS_MODULE;
pti_tty_driver->magic = TTY_DRIVER_MAGIC;
pti_tty_driver->driver_name = DRIVERNAME;
pti_tty_driver->name = TTYNAME;
pti_tty_driver->major = 0;
pti_tty_driver->minor_start = PTITTY_MINOR_START;
pti_tty_driver->minor_num = PTITTY_MINOR_NUM;
pti_tty_driver->num = PTITTY_MINOR_NUM;
pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS;
pti_tty_driver->flags = TTY_DRIVER_REAL_RAW |
TTY_DRIVER_DYNAMIC_DEV;
pti_tty_driver->init_termios = tty_std_termios;
tty_set_operations(pti_tty_driver, &pti_tty_driver_ops);
retval = tty_register_driver(pti_tty_driver);
if (retval) {
pr_err("%s(%d): TTY registration failed of pti driver\n",
__func__, __LINE__);
pr_err("%s(%d): Error value returned: %d\n",
__func__, __LINE__, retval);
pti_tty_driver = NULL;
return retval;
}
retval = pci_register_driver(&pti_pci_driver);
if (retval) {
pr_err("%s(%d): PCI registration failed of pti driver\n",
__func__, __LINE__);
pr_err("%s(%d): Error value returned: %d\n",
__func__, __LINE__, retval);
tty_unregister_driver(pti_tty_driver);
pr_err("%s(%d): Unregistering TTY part of pti driver\n",
__func__, __LINE__);
pti_tty_driver = NULL;
return retval;
}
return retval;
}
/**
* pti_exit()- Unregisters this module as a tty and pci driver.
*/
static void __exit pti_exit(void)
{
int retval;
tty_unregister_device(pti_tty_driver, 0);
tty_unregister_device(pti_tty_driver, 1);
retval = tty_unregister_driver(pti_tty_driver);
if (retval) {
pr_err("%s(%d): TTY unregistration failed of pti driver\n",
__func__, __LINE__);
pr_err("%s(%d): Error value returned: %d\n",
__func__, __LINE__, retval);
}
pci_unregister_driver(&pti_pci_driver);
retval = misc_deregister(&pti_char_driver);
if (retval) {
pr_err("%s(%d): CHAR unregistration failed of pti driver\n",
__func__, __LINE__);
pr_err("%s(%d): Error value returned: %d\n",
__func__, __LINE__, retval);
}
unregister_console(&pti_console);
return;
}
module_init(pti_init);
module_exit(pti_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ken Mills, Jay Freyensee");
MODULE_DESCRIPTION("PTI Driver");

View File

@ -747,8 +747,8 @@ static void st_tty_close(struct tty_struct *tty)
pr_debug("%s: done ", __func__);
}
static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
char *tty_flags, int count)
static unsigned int st_tty_receive(struct tty_struct *tty,
const unsigned char *data, char *tty_flags, int count)
{
#ifdef VERBOSE
print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
@ -761,6 +761,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
*/
st_recv(tty->disc_data, data, count);
pr_debug("done %s", __func__);
return count;
}
/* wake-up function called in from the TTY layer

View File

@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
#endif
static void ldisc_receive(struct tty_struct *tty, const u8 *data,
char *flags, int count)
static unsigned int ldisc_receive(struct tty_struct *tty,
const u8 *data, char *flags, int count)
{
struct sk_buff *skb = NULL;
struct ser_device *ser;
@ -215,6 +215,8 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data,
} else
++ser->dev->stats.rx_dropped;
update_tty_status(ser);
return count;
}
static int handle_tx(struct ser_device *ser)

View File

@ -425,16 +425,17 @@ static void slc_setup(struct net_device *dev)
* in parallel
*/
static void slcan_receive_buf(struct tty_struct *tty,
static unsigned int slcan_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct slcan *sl = (struct slcan *) tty->disc_data;
int bytes = count;
if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
return;
return -ENODEV;
/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->dev->stats.rx_errors++;
@ -443,6 +444,8 @@ static void slcan_receive_buf(struct tty_struct *tty,
}
slcan_unesc(sl, *cp++);
}
return count;
}
/************************************

View File

@ -456,7 +456,7 @@ out:
* a block of 6pack data has been received, which can now be decapsulated
* and sent on to some IP layer for further processing.
*/
static void sixpack_receive_buf(struct tty_struct *tty,
static unsigned int sixpack_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct sixpack *sp;
@ -464,11 +464,11 @@ static void sixpack_receive_buf(struct tty_struct *tty,
int count1;
if (!count)
return;
return 0;
sp = sp_get(tty);
if (!sp)
return;
return -ENODEV;
memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
@ -487,6 +487,8 @@ static void sixpack_receive_buf(struct tty_struct *tty,
sp_put(sp);
tty_unthrottle(tty);
return count1;
}
/*

View File

@ -923,13 +923,14 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
* a block of data has been received, which can now be decapsulated
* and sent on to the AX.25 layer for further processing.
*/
static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int mkiss_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct mkiss *ax = mkiss_get(tty);
int bytes = count;
if (!ax)
return;
return -ENODEV;
/*
* Argh! mtu change time! - costs us the packet part received
@ -939,7 +940,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
ax_changedmtu(ax);
/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp != NULL && *fp++) {
if (!test_and_set_bit(AXF_ERROR, &ax->flags))
ax->dev->stats.rx_errors++;
@ -952,6 +953,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
mkiss_put(ax);
tty_unthrottle(tty);
return count;
}
/*

View File

@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t
* usbserial: urb-complete-interrupt / softint
*/
static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int irtty_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct sir_dev *dev;
struct sirtty_cb *priv = tty->disc_data;
int i;
IRDA_ASSERT(priv != NULL, return;);
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
IRDA_ASSERT(priv != NULL, return -ENODEV;);
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;);
if (unlikely(count==0)) /* yes, this happens */
return;
return 0;
dev = priv->dev;
if (!dev) {
IRDA_WARNING("%s(), not ready yet!\n", __func__);
return;
return -ENODEV;
}
for (i = 0; i < count; i++) {
@ -242,11 +242,13 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
if (fp && *fp++) {
IRDA_DEBUG(0, "Framing or parity error!\n");
sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */
return;
return -EINVAL;
}
}
sirdev_receive(dev, cp, count);
return count;
}
/*

View File

@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
}
/* May sleep, don't call from interrupt level or with interrupts disabled */
static void
static unsigned int
ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
char *cflags, int count)
{
@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
unsigned long flags;
if (!ap)
return;
return -ENODEV;
spin_lock_irqsave(&ap->recv_lock, flags);
ppp_async_input(ap, buf, cflags, count);
spin_unlock_irqrestore(&ap->recv_lock, flags);
@ -356,6 +356,8 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
tasklet_schedule(&ap->tsk);
ap_put(ap);
tty_unthrottle(tty);
return count;
}
static void

View File

@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
}
/* May sleep, don't call from interrupt level or with interrupts disabled */
static void
static unsigned int
ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
char *cflags, int count)
{
@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
unsigned long flags;
if (!ap)
return;
return -ENODEV;
spin_lock_irqsave(&ap->recv_lock, flags);
ppp_sync_input(ap, buf, cflags, count);
spin_unlock_irqrestore(&ap->recv_lock, flags);
@ -397,6 +397,8 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
tasklet_schedule(&ap->tsk);
sp_put(ap);
tty_unthrottle(tty);
return count;
}
static void

View File

@ -670,16 +670,17 @@ static void sl_setup(struct net_device *dev)
* in parallel
*/
static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int slip_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct slip *sl = tty->disc_data;
int bytes = count;
if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
return;
return -ENODEV;
/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->dev->stats.rx_errors++;
@ -693,6 +694,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
#endif
slip_unesc(sl, *cp++);
}
return count;
}
/************************************

View File

@ -517,17 +517,18 @@ static int x25_asy_close(struct net_device *dev)
* and sent on to some IP layer for further processing.
*/
static void x25_asy_receive_buf(struct tty_struct *tty,
static unsigned int x25_asy_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct x25_asy *sl = tty->disc_data;
int bytes = count;
if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
return;
/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->dev->stats.rx_errors++;
@ -536,6 +537,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
}
x25_asy_unesc(sl, *cp++);
}
return count;
}
/*

View File

@ -1621,7 +1621,7 @@ static void __devinit detect_and_report_it87(void)
u8 origval, r;
if (verbose_probing)
printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
if (!request_region(0x2e, 2, __func__))
if (!request_muxed_region(0x2e, 2, __func__))
return;
origval = inb(0x2e); /* Save original value */
outb(0x87, 0x2e);

View File

@ -319,3 +319,34 @@ config N_GSM
This line discipline provides support for the GSM MUX protocol and
presents the mux as a set of 61 individual tty devices.
config TRACE_ROUTER
tristate "Trace data router for MIPI P1149.7 cJTAG standard"
depends on TRACE_SINK
default n
help
The trace router uses the Linux tty line discipline framework to
route trace data coming from a tty port (say UART for example) to
the trace sink line discipline driver and to another tty port (say
USB). This is part of a solution for the MIPI P1149.7, compact JTAG,
standard, which is for debugging mobile devices. The PTI driver in
drivers/misc/pti.c defines the majority of this MIPI solution.
You should select this driver if the target kernel is meant for
a mobile device containing a modem. Then you will need to select
"Trace data sink for MIPI P1149.7 cJTAG standard" line discipline
driver.
config TRACE_SINK
tristate "Trace data sink for MIPI P1149.7 cJTAG standard"
default n
help
The trace sink uses the Linux line discipline framework to receive
trace data coming from the trace router line discipline driver
to a user-defined tty port target, like USB.
This is to provide a way to extract modem trace data on
devices that do not have a PTI HW module, or just need modem
trace data to come out of a different HW output port.
This is part of a solution for the P1149.7, compact JTAG, standard.
If you select this option, you need to select
"Trace data router for MIPI P1149.7 cJTAG standard".

View File

@ -6,6 +6,8 @@ obj-$(CONFIG_AUDIT) += tty_audit.o
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
obj-$(CONFIG_N_HDLC) += n_hdlc.o
obj-$(CONFIG_N_GSM) += n_gsm.o
obj-$(CONFIG_TRACE_ROUTER) += n_tracerouter.o
obj-$(CONFIG_TRACE_SINK) += n_tracesink.o
obj-$(CONFIG_R3964) += n_r3964.o
obj-y += vt/

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/amiserial.c
*
* Serial driver for the amiga builtin port.
*
* This code was created by taking serial.c version 4.30 from kernel

View File

@ -3,8 +3,6 @@
#undef Z_EXT_CHARS_IN_BUFFER
/*
* linux/drivers/char/cyclades.c
*
* This file contains the driver for the Cyclades async multiport
* serial boards.
*
@ -1445,13 +1443,11 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
{
struct cyclades_card *card;
unsigned long flags;
int channel;
if (!(info->port.flags & ASYNC_INITIALIZED))
return;
card = info->card;
channel = info->line - card->first_line;
if (!cy_is_Z(card)) {
spin_lock_irqsave(&card->card_lock, flags);
@ -1476,6 +1472,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
spin_unlock_irqrestore(&card->card_lock, flags);
} else {
#ifdef CY_DEBUG_OPEN
int channel = info->line - card->first_line;
printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
"base_addr %p\n", card, channel, card->base_addr);
#endif

View File

@ -1,6 +1,4 @@
#
# drivers/char/pcmcia/ipwireless/Makefile
#
# Makefile for the IPWireless driver
#

View File

@ -371,7 +371,7 @@ static int moxa_ioctl(struct tty_struct *tty,
tmp.cflag = p->cflag;
else
tmp.cflag = ttyp->termios->c_cflag;
tty_kref_put(tty);
tty_kref_put(ttyp);
copy:
if (copy_to_user(argm, &tmp, sizeof(tmp)))
return -EFAULT;
@ -1129,7 +1129,6 @@ static void moxa_shutdown(struct tty_port *port)
struct moxa_port *ch = container_of(port, struct moxa_port, port);
MoxaPortDisable(ch);
MoxaPortFlushData(ch, 2);
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
}
static int moxa_carrier_raised(struct tty_port *port)
@ -1155,7 +1154,6 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
struct moxa_board_conf *brd;
struct moxa_port *ch;
int port;
int retval;
port = tty->index;
if (port == MAX_PORTS) {
@ -1190,10 +1188,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
mutex_unlock(&ch->port.mutex);
mutex_unlock(&moxa_openlock);
retval = tty_port_block_til_ready(&ch->port, tty, filp);
if (retval == 0)
set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
return retval;
return tty_port_block_til_ready(&ch->port, tty, filp);
}
static void moxa_close(struct tty_struct *tty, struct file *filp)
@ -1207,14 +1202,15 @@ static int moxa_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
struct moxa_port *ch = tty->driver_data;
unsigned long flags;
int len;
if (ch == NULL)
return 0;
spin_lock_bh(&moxa_lock);
spin_lock_irqsave(&moxa_lock, flags);
len = MoxaPortWriteData(tty, buf, count);
spin_unlock_bh(&moxa_lock);
spin_unlock_irqrestore(&moxa_lock, flags);
set_bit(LOWWAIT, &ch->statusflags);
return len;
@ -1281,10 +1277,8 @@ static int moxa_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{
struct moxa_port *ch;
int port;
int dtr, rts;
port = tty->index;
mutex_lock(&moxa_openlock);
ch = tty->driver_data;
if (!ch) {
@ -1756,11 +1750,9 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
speed_t baud)
{
void __iomem *ofsAddr;
tcflag_t cflag;
tcflag_t mode = 0;
ofsAddr = port->tableAddr;
cflag = termio->c_cflag; /* termio->c_cflag */
mode = termio->c_cflag & CSIZE;
if (mode == CS5)

View File

@ -526,19 +526,6 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
return olen;
}
static void hex_packet(const unsigned char *p, int len)
{
int i;
for (i = 0; i < len; i++) {
if (i && (i % 16) == 0) {
pr_cont("\n");
pr_debug("");
}
pr_cont("%02X ", *p++);
}
pr_cont("\n");
}
/**
* gsm_send - send a control frame
* @gsm: our GSM mux
@ -685,10 +672,10 @@ static void gsm_data_kick(struct gsm_mux *gsm)
len = msg->len + 2;
}
if (debug & 4) {
pr_debug("gsm_data_kick:\n");
hex_packet(gsm->txframe, len);
}
if (debug & 4)
print_hex_dump_bytes("gsm_data_kick: ",
DUMP_PREFIX_OFFSET,
gsm->txframe, len);
if (gsm->output(gsm, gsm->txframe + skip_sof,
len - skip_sof) < 0)
@ -2095,10 +2082,9 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
return -ENOSPC;
}
if (debug & 4) {
pr_debug("-->%d bytes out\n", len);
hex_packet(data, len);
}
if (debug & 4)
print_hex_dump_bytes("gsmld_output: ", DUMP_PREFIX_OFFSET,
data, len);
gsm->tty->ops->write(gsm->tty, data, len);
return len;
}
@ -2142,8 +2128,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
gsm->tty = NULL;
}
static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int gsmld_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct gsm_mux *gsm = tty->disc_data;
const unsigned char *dp;
@ -2152,10 +2138,9 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char buf[64];
char flags;
if (debug & 4) {
pr_debug("Inbytes %dd\n", count);
hex_packet(cp, count);
}
if (debug & 4)
print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET,
cp, count);
for (i = count, dp = cp, f = fp; i; i--, dp++) {
flags = *f++;
@ -2177,6 +2162,8 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
}
/* FASYNC if needed ? */
/* If clogged call tty_throttle(tty); */
return count;
}
/**

View File

@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
poll_table *wait);
static int n_hdlc_tty_open(struct tty_struct *tty);
static void n_hdlc_tty_close(struct tty_struct *tty);
static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
char *fp, int count);
static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
const __u8 *cp, char *fp, int count);
static void n_hdlc_tty_wakeup(struct tty_struct *tty);
#define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
* Called by tty low level driver when receive data is available. Data is
* interpreted as one HDLC frame.
*/
static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
char *flags, int count)
static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
const __u8 *data, char *flags, int count)
{
register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
register struct n_hdlc_buf *buf;
@ -521,20 +521,20 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
/* This can happen if stuff comes in on the backup tty */
if (!n_hdlc || tty != n_hdlc->tty)
return;
return -ENODEV;
/* verify line is using HDLC discipline */
if (n_hdlc->magic != HDLC_MAGIC) {
printk("%s(%d) line not using HDLC discipline\n",
__FILE__,__LINE__);
return;
return -EINVAL;
}
if ( count>maxframe ) {
if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d) rx count>maxframesize, data discarded\n",
__FILE__,__LINE__);
return;
return -EINVAL;
}
/* get a free HDLC buffer */
@ -550,7 +550,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d) no more rx buffers, data discarded\n",
__FILE__,__LINE__);
return;
return -EINVAL;
}
/* copy received data to HDLC buffer */
@ -565,6 +565,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
if (n_hdlc->tty->fasync != NULL)
kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
return count;
} /* end of n_hdlc_tty_receive() */
/**

View File

@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file,
static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
struct poll_table_struct *wait);
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count);
static unsigned int r3964_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count);
static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
.owner = THIS_MODULE,
@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
return result;
}
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int r3964_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct r3964_info *pInfo = tty->disc_data;
const unsigned char *p;
@ -1257,6 +1257,8 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
}
}
return count;
}
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,243 @@
/*
* n_tracerouter.c - Trace data router through tty space
*
* Copyright (C) Intel 2011
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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.
*
* 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.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This trace router uses the Linux line discipline framework to route
* trace data coming from a HW Modem to a PTI (Parallel Trace Module) port.
* The solution is not specific to a HW modem and this line disciple can
* be used to route any stream of data in kernel space.
* This is part of a solution for the P1149.7, compact JTAG, standard.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/tty.h>
#include <linux/tty_ldisc.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm-generic/bug.h>
#include "n_tracesink.h"
/*
* Other ldisc drivers use 65536 which basically means,
* 'I can always accept 64k' and flow control is off.
* This number is deemed appropriate for this driver.
*/
#define RECEIVE_ROOM 65536
#define DRIVERNAME "n_tracerouter"
/*
* struct to hold private configuration data for this ldisc.
* opencalled is used to hold if this ldisc has been opened.
* kref_tty holds the tty reference the ldisc sits on top of.
*/
struct tracerouter_data {
u8 opencalled;
struct tty_struct *kref_tty;
};
static struct tracerouter_data *tr_data;
/* lock for when tty reference is being used */
static DEFINE_MUTEX(routelock);
/**
* n_tracerouter_open() - Called when a tty is opened by a SW entity.
* @tty: terminal device to the ldisc.
*
* Return:
* 0 for success.
*
* Caveats: This should only be opened one time per SW entity.
*/
static int n_tracerouter_open(struct tty_struct *tty)
{
int retval = -EEXIST;
mutex_lock(&routelock);
if (tr_data->opencalled == 0) {
tr_data->kref_tty = tty_kref_get(tty);
if (tr_data->kref_tty == NULL) {
retval = -EFAULT;
} else {
tr_data->opencalled = 1;
tty->disc_data = tr_data;
tty->receive_room = RECEIVE_ROOM;
tty_driver_flush_buffer(tty);
retval = 0;
}
}
mutex_unlock(&routelock);
return retval;
}
/**
* n_tracerouter_close() - close connection
* @tty: terminal device to the ldisc.
*
* Called when a software entity wants to close a connection.
*/
static void n_tracerouter_close(struct tty_struct *tty)
{
struct tracerouter_data *tptr = tty->disc_data;
mutex_lock(&routelock);
WARN_ON(tptr->kref_tty != tr_data->kref_tty);
tty_driver_flush_buffer(tty);
tty_kref_put(tr_data->kref_tty);
tr_data->kref_tty = NULL;
tr_data->opencalled = 0;
tty->disc_data = NULL;
mutex_unlock(&routelock);
}
/**
* n_tracerouter_read() - read request from user space
* @tty: terminal device passed into the ldisc.
* @file: pointer to open file object.
* @buf: pointer to the data buffer that gets eventually returned.
* @nr: number of bytes of the data buffer that is returned.
*
* function that allows read() functionality in userspace. By default if this
* is not implemented it returns -EIO. This module is functioning like a
* router via n_tracerouter_receivebuf(), and there is no real requirement
* to implement this function. However, an error return value other than
* -EIO should be used just to show that there was an intent not to have
* this function implemented. Return value based on read() man pages.
*
* Return:
* -EINVAL
*/
static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file,
unsigned char __user *buf, size_t nr) {
return -EINVAL;
}
/**
* n_tracerouter_write() - Function that allows write() in userspace.
* @tty: terminal device passed into the ldisc.
* @file: pointer to open file object.
* @buf: pointer to the data buffer that gets eventually returned.
* @nr: number of bytes of the data buffer that is returned.
*
* By default if this is not implemented, it returns -EIO.
* This should not be implemented, ever, because
* 1. this driver is functioning like a router via
* n_tracerouter_receivebuf()
* 2. No writes to HW will ever go through this line discpline driver.
* However, an error return value other than -EIO should be used
* just to show that there was an intent not to have this function
* implemented. Return value based on write() man pages.
*
* Return:
* -EINVAL
*/
static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file,
const unsigned char *buf, size_t nr) {
return -EINVAL;
}
/**
* n_tracerouter_receivebuf() - Routing function for driver.
* @tty: terminal device passed into the ldisc. It's assumed
* tty will never be NULL.
* @cp: buffer, block of characters to be eventually read by
* someone, somewhere (user read() call or some kernel function).
* @fp: flag buffer.
* @count: number of characters (aka, bytes) in cp.
*
* This function takes the input buffer, cp, and passes it to
* an external API function for processing.
*/
static void n_tracerouter_receivebuf(struct tty_struct *tty,
const unsigned char *cp,
char *fp, int count)
{
mutex_lock(&routelock);
n_tracesink_datadrain((u8 *) cp, count);
mutex_unlock(&routelock);
}
/*
* Flush buffer is not impelemented as the ldisc has no internal buffering
* so the tty_driver_flush_buffer() is sufficient for this driver's needs.
*/
static struct tty_ldisc_ops tty_ptirouter_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = DRIVERNAME,
.open = n_tracerouter_open,
.close = n_tracerouter_close,
.read = n_tracerouter_read,
.write = n_tracerouter_write,
.receive_buf = n_tracerouter_receivebuf
};
/**
* n_tracerouter_init - module initialisation
*
* Registers this module as a line discipline driver.
*
* Return:
* 0 for success, any other value error.
*/
static int __init n_tracerouter_init(void)
{
int retval;
tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL);
if (tr_data == NULL)
return -ENOMEM;
/* Note N_TRACEROUTER is defined in linux/tty.h */
retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc);
if (retval < 0) {
pr_err("%s: Registration failed: %d\n", __func__, retval);
kfree(tr_data);
}
return retval;
}
/**
* n_tracerouter_exit - module unload
*
* Removes this module as a line discipline driver.
*/
static void __exit n_tracerouter_exit(void)
{
int retval = tty_unregister_ldisc(N_TRACEROUTER);
if (retval < 0)
pr_err("%s: Unregistration failed: %d\n", __func__, retval);
else
kfree(tr_data);
}
module_init(n_tracerouter_init);
module_exit(n_tracerouter_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jay Freyensee");
MODULE_ALIAS_LDISC(N_TRACEROUTER);
MODULE_DESCRIPTION("Trace router ldisc driver");

View File

@ -0,0 +1,238 @@
/*
* n_tracesink.c - Trace data router and sink path through tty space.
*
* Copyright (C) Intel 2011
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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.
*
* 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.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The trace sink uses the Linux line discipline framework to receive
* trace data coming from the PTI source line discipline driver
* to a user-desired tty port, like USB.
* This is to provide a way to extract modem trace data on
* devices that do not have a PTI HW module, or just need modem
* trace data to come out of a different HW output port.
* This is part of a solution for the P1149.7, compact JTAG, standard.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/tty.h>
#include <linux/tty_ldisc.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <asm-generic/bug.h>
#include "n_tracesink.h"
/*
* Other ldisc drivers use 65536 which basically means,
* 'I can always accept 64k' and flow control is off.
* This number is deemed appropriate for this driver.
*/
#define RECEIVE_ROOM 65536
#define DRIVERNAME "n_tracesink"
/*
* there is a quirk with this ldisc is he can write data
* to a tty from anyone calling his kernel API, which
* meets customer requirements in the drivers/misc/pti.c
* project. So he needs to know when he can and cannot write when
* the API is called. In theory, the API can be called
* after an init() but before a successful open() which
* would crash the system if tty is not checked.
*/
static struct tty_struct *this_tty;
static DEFINE_MUTEX(writelock);
/**
* n_tracesink_open() - Called when a tty is opened by a SW entity.
* @tty: terminal device to the ldisc.
*
* Return:
* 0 for success,
* -EFAULT = couldn't get a tty kref n_tracesink will sit
* on top of
* -EEXIST = open() called successfully once and it cannot
* be called again.
*
* Caveats: open() should only be successful the first time a
* SW entity calls it.
*/
static int n_tracesink_open(struct tty_struct *tty)
{
int retval = -EEXIST;
mutex_lock(&writelock);
if (this_tty == NULL) {
this_tty = tty_kref_get(tty);
if (this_tty == NULL) {
retval = -EFAULT;
} else {
tty->disc_data = this_tty;
tty_driver_flush_buffer(tty);
retval = 0;
}
}
mutex_unlock(&writelock);
return retval;
}
/**
* n_tracesink_close() - close connection
* @tty: terminal device to the ldisc.
*
* Called when a software entity wants to close a connection.
*/
static void n_tracesink_close(struct tty_struct *tty)
{
mutex_lock(&writelock);
tty_driver_flush_buffer(tty);
tty_kref_put(this_tty);
this_tty = NULL;
tty->disc_data = NULL;
mutex_unlock(&writelock);
}
/**
* n_tracesink_read() - read request from user space
* @tty: terminal device passed into the ldisc.
* @file: pointer to open file object.
* @buf: pointer to the data buffer that gets eventually returned.
* @nr: number of bytes of the data buffer that is returned.
*
* function that allows read() functionality in userspace. By default if this
* is not implemented it returns -EIO. This module is functioning like a
* router via n_tracesink_receivebuf(), and there is no real requirement
* to implement this function. However, an error return value other than
* -EIO should be used just to show that there was an intent not to have
* this function implemented. Return value based on read() man pages.
*
* Return:
* -EINVAL
*/
static ssize_t n_tracesink_read(struct tty_struct *tty, struct file *file,
unsigned char __user *buf, size_t nr) {
return -EINVAL;
}
/**
* n_tracesink_write() - Function that allows write() in userspace.
* @tty: terminal device passed into the ldisc.
* @file: pointer to open file object.
* @buf: pointer to the data buffer that gets eventually returned.
* @nr: number of bytes of the data buffer that is returned.
*
* By default if this is not implemented, it returns -EIO.
* This should not be implemented, ever, because
* 1. this driver is functioning like a router via
* n_tracesink_receivebuf()
* 2. No writes to HW will ever go through this line discpline driver.
* However, an error return value other than -EIO should be used
* just to show that there was an intent not to have this function
* implemented. Return value based on write() man pages.
*
* Return:
* -EINVAL
*/
static ssize_t n_tracesink_write(struct tty_struct *tty, struct file *file,
const unsigned char *buf, size_t nr) {
return -EINVAL;
}
/**
* n_tracesink_datadrain() - Kernel API function used to route
* trace debugging data to user-defined
* port like USB.
*
* @buf: Trace debuging data buffer to write to tty target
* port. Null value will return with no write occurring.
* @count: Size of buf. Value of 0 or a negative number will
* return with no write occuring.
*
* Caveat: If this line discipline does not set the tty it sits
* on top of via an open() call, this API function will not
* call the tty's write() call because it will have no pointer
* to call the write().
*/
void n_tracesink_datadrain(u8 *buf, int count)
{
mutex_lock(&writelock);
if ((buf != NULL) && (count > 0) && (this_tty != NULL))
this_tty->ops->write(this_tty, buf, count);
mutex_unlock(&writelock);
}
EXPORT_SYMBOL_GPL(n_tracesink_datadrain);
/*
* Flush buffer is not impelemented as the ldisc has no internal buffering
* so the tty_driver_flush_buffer() is sufficient for this driver's needs.
*/
/*
* tty_ldisc function operations for this driver.
*/
static struct tty_ldisc_ops tty_n_tracesink = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = DRIVERNAME,
.open = n_tracesink_open,
.close = n_tracesink_close,
.read = n_tracesink_read,
.write = n_tracesink_write
};
/**
* n_tracesink_init- module initialisation
*
* Registers this module as a line discipline driver.
*
* Return:
* 0 for success, any other value error.
*/
static int __init n_tracesink_init(void)
{
/* Note N_TRACESINK is defined in linux/tty.h */
int retval = tty_register_ldisc(N_TRACESINK, &tty_n_tracesink);
if (retval < 0)
pr_err("%s: Registration failed: %d\n", __func__, retval);
return retval;
}
/**
* n_tracesink_exit - module unload
*
* Removes this module as a line discipline driver.
*/
static void __exit n_tracesink_exit(void)
{
int retval = tty_unregister_ldisc(N_TRACESINK);
if (retval < 0)
pr_err("%s: Unregistration failed: %d\n", __func__, retval);
}
module_init(n_tracesink_init);
module_exit(n_tracesink_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jay Freyensee");
MODULE_ALIAS_LDISC(N_TRACESINK);
MODULE_DESCRIPTION("Trace sink ldisc driver");

View File

@ -0,0 +1,36 @@
/*
* n_tracesink.h - Kernel driver API to route trace data in kernel space.
*
* Copyright (C) Intel 2011
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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.
*
* 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.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The PTI (Parallel Trace Interface) driver directs trace data routed from
* various parts in the system out through the Intel Penwell PTI port and
* out of the mobile device for analysis with a debugging tool
* (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
* compact JTAG, standard.
*
* This header file is used by n_tracerouter to be able to send the
* data of it's tty port to the tty port this module sits. This
* mechanism can also be used independent of the PTI module.
*
*/
#ifndef N_TRACESINK_H_
#define N_TRACESINK_H_
void n_tracesink_datadrain(u8 *buf, int count);
#endif

View File

@ -81,38 +81,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
return put_user(x, ptr);
}
/**
* n_tty_set__room - receive space
* @tty: terminal
*
* Called by the driver to find out how much data it is
* permitted to feed to the line discipline without any being lost
* and thus to manage flow control. Not serialized. Answers for the
* "instant".
*/
static void n_tty_set_room(struct tty_struct *tty)
{
/* tty->read_cnt is not read locked ? */
int left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
int old_left;
/*
* If we are doing input canonicalization, and there are no
* pending newlines, let characters through without limit, so
* that erase characters will be handled. Other excess
* characters will be beeped.
*/
if (left <= 0)
left = tty->icanon && !tty->canon_data;
old_left = tty->receive_room;
tty->receive_room = left;
/* Did this open up the receive buffer? We may need to flip */
if (left && !old_left)
schedule_work(&tty->buf.work);
}
static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
{
if (tty->read_cnt < N_TTY_BUF_SIZE) {
@ -184,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty)
tty->canon_head = tty->canon_data = tty->erasing = 0;
memset(&tty->read_flags, 0, sizeof tty->read_flags);
n_tty_set_room(tty);
check_unthrottle(tty);
}
@ -1360,17 +1327,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
* calls one at a time and in order (or using flush_to_ldisc)
*/
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int n_tty_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
const unsigned char *p;
char *f, flags = TTY_NORMAL;
int i;
char buf[64];
unsigned long cpuflags;
int left;
int ret = 0;
if (!tty->read_buf)
return;
return 0;
if (tty->real_raw) {
spin_lock_irqsave(&tty->read_lock, cpuflags);
@ -1380,6 +1349,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
memcpy(tty->read_buf + tty->read_head, cp, i);
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
tty->read_cnt += i;
ret += i;
cp += i;
count -= i;
@ -1389,8 +1359,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
memcpy(tty->read_buf + tty->read_head, cp, i);
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
tty->read_cnt += i;
ret += i;
spin_unlock_irqrestore(&tty->read_lock, cpuflags);
} else {
ret = count;
for (i = count, p = cp, f = fp; i; i--, p++) {
if (f)
flags = *f++;
@ -1418,8 +1390,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
tty->ops->flush_chars(tty);
}
n_tty_set_room(tty);
if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
L_EXTPROC(tty)) {
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
@ -1432,8 +1402,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
* mode. We don't want to throttle the driver if we're in
* canonical mode and don't have a newline yet!
*/
if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
if (left < TTY_THRESHOLD_THROTTLE)
tty_throttle(tty);
return ret;
}
int is_ignored(int sig)
@ -1477,7 +1451,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
tty->raw = 1;
tty->real_raw = 1;
n_tty_set_room(tty);
return;
}
if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
@ -1530,7 +1503,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
else
tty->real_raw = 0;
}
n_tty_set_room(tty);
/* The termios change make the tty ready for I/O */
wake_up_interruptible(&tty->write_wait);
wake_up_interruptible(&tty->read_wait);
@ -1812,8 +1784,6 @@ do_it_again:
retval = -ERESTARTSYS;
break;
}
/* FIXME: does n_tty_set_room need locking ? */
n_tty_set_room(tty);
timeout = schedule_timeout(timeout);
continue;
}
@ -1885,10 +1855,8 @@ do_it_again:
* longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
* we won't get any more characters.
*/
if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
n_tty_set_room(tty);
if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
check_unthrottle(tty);
}
if (b - buf >= minimum)
break;
@ -1910,7 +1878,6 @@ do_it_again:
} else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
goto do_it_again;
n_tty_set_room(tty);
return retval;
}

View File

@ -364,8 +364,6 @@ struct port {
u8 toggle_ul;
u16 token_dl;
/* mutex to ensure one access patch to this port */
struct mutex tty_sem;
wait_queue_head_t tty_wait;
struct async_icount tty_icount;
@ -1431,8 +1429,8 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
}
for (i = PORT_MDM; i < MAX_PORT; i++) {
if (kfifo_alloc(&dc->port[i].fifo_ul,
FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) {
if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_UL,
GFP_KERNEL)) {
dev_err(&pdev->dev,
"Could not allocate kfifo buffer\n");
ret = -ENOMEM;
@ -1474,7 +1472,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
struct device *tty_dev;
struct port *port = &dc->port[i];
port->dc = dc;
mutex_init(&port->tty_sem);
tty_port_init(&port->port);
port->port.ops = &noz_tty_port_ops;
tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
@ -1688,13 +1685,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
if (!dc || !port)
return -ENODEV;
mutex_lock(&port->tty_sem);
if (unlikely(!port->port.count)) {
DBG1(" ");
goto exit;
}
rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
/* notify card */
@ -1719,7 +1709,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
spin_unlock_irqrestore(&dc->spin_mutex, flags);
exit:
mutex_unlock(&port->tty_sem);
return rval;
}
@ -1738,12 +1727,9 @@ static int ntty_write_room(struct tty_struct *tty)
int room = 4096;
const struct nozomi *dc = get_dc_by_tty(tty);
if (dc) {
mutex_lock(&port->tty_sem);
if (port->port.count)
room = kfifo_avail(&port->fifo_ul);
mutex_unlock(&port->tty_sem);
}
if (dc)
room = kfifo_avail(&port->fifo_ul);
return room;
}
@ -1889,11 +1875,6 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
goto exit_in_buffer;
}
if (unlikely(!port->port.count)) {
dev_err(&dc->pdev->dev, "No tty open?\n");
goto exit_in_buffer;
}
rval = kfifo_len(&port->fifo_ul);
exit_in_buffer:

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/pty.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Added support for a Unix98-style ptmx device.
@ -295,8 +293,8 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENOMEM;
if (!try_module_get(driver->other->owner)) {
/* This cannot in fact currently happen */
free_tty_struct(o_tty);
return -ENOMEM;
retval = -ENOMEM;
goto err_free_tty;
}
initialize_tty_struct(o_tty, driver->other, idx);
@ -304,13 +302,11 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
the easy way .. */
retval = tty_init_termios(tty);
if (retval)
goto free_mem_out;
goto err_deinit_tty;
retval = tty_init_termios(o_tty);
if (retval) {
tty_free_termios(tty);
goto free_mem_out;
}
if (retval)
goto err_free_termios;
/*
* Everything allocated ... set up the o_tty structure.
@ -327,10 +323,14 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
tty->count++;
driver->ttys[idx] = tty;
return 0;
free_mem_out:
err_free_termios:
tty_free_termios(tty);
err_deinit_tty:
deinitialize_tty_struct(o_tty);
module_put(o_tty->driver->owner);
err_free_tty:
free_tty_struct(o_tty);
return -ENOMEM;
return retval;
}
static int pty_bsd_ioctl(struct tty_struct *tty,
@ -559,20 +559,19 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENOMEM;
if (!try_module_get(driver->other->owner)) {
/* This cannot in fact currently happen */
free_tty_struct(o_tty);
return -ENOMEM;
goto err_free_tty;
}
initialize_tty_struct(o_tty, driver->other, idx);
tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
if (tty->termios == NULL)
goto free_mem_out;
goto err_free_mem;
*tty->termios = driver->init_termios;
tty->termios_locked = tty->termios + 1;
o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
if (o_tty->termios == NULL)
goto free_mem_out;
goto err_free_mem;
*o_tty->termios = driver->other->init_termios;
o_tty->termios_locked = o_tty->termios + 1;
@ -591,11 +590,13 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
tty->count++;
pty_count++;
return 0;
free_mem_out:
err_free_mem:
deinitialize_tty_struct(o_tty);
kfree(o_tty->termios);
module_put(o_tty->driver->owner);
free_tty_struct(o_tty);
kfree(tty->termios);
module_put(o_tty->driver->owner);
err_free_tty:
free_tty_struct(o_tty);
return -ENOMEM;
}

View File

@ -1380,7 +1380,6 @@ static void rp_send_xchar(struct tty_struct *tty, char ch)
static void rp_throttle(struct tty_struct *tty)
{
struct r_port *info = tty->driver_data;
CHANNEL_t *cp;
#ifdef ROCKET_DEBUG_THROTTLE
printk(KERN_INFO "throttle %s: %d....\n", tty->name,
@ -1390,7 +1389,6 @@ static void rp_throttle(struct tty_struct *tty)
if (rocket_paranoia_check(info, "rp_throttle"))
return;
cp = &info->channel;
if (I_IXOFF(tty))
rp_send_xchar(tty, STOP_CHAR(tty));
@ -1400,7 +1398,6 @@ static void rp_throttle(struct tty_struct *tty)
static void rp_unthrottle(struct tty_struct *tty)
{
struct r_port *info = tty->driver_data;
CHANNEL_t *cp;
#ifdef ROCKET_DEBUG_THROTTLE
printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
tty->ldisc.chars_in_buffer(tty));
@ -1409,7 +1406,6 @@ static void rp_unthrottle(struct tty_struct *tty)
if (rocket_paranoia_check(info, "rp_throttle"))
return;
cp = &info->channel;
if (I_IXOFF(tty))
rp_send_xchar(tty, START_CHAR(tty));
@ -1722,13 +1718,10 @@ static int rp_write_room(struct tty_struct *tty)
static int rp_chars_in_buffer(struct tty_struct *tty)
{
struct r_port *info = tty->driver_data;
CHANNEL_t *cp;
if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
return 0;
cp = &info->channel;
#ifdef ROCKET_DEBUG_WRITE
printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
#endif
@ -1779,7 +1772,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
{
int num_aiops, aiop, max_num_aiops, num_chan, chan;
unsigned int aiopio[MAX_AIOPS_PER_BOARD];
char *str, *board_type;
CONTROLLER_t *ctlp;
int fast_clock = 0;
@ -1800,7 +1792,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
/* Depending on the model, set up some config variables */
switch (dev->device) {
case PCI_DEVICE_ID_RP4QUAD:
str = "Quadcable";
max_num_aiops = 1;
ports_per_aiop = 4;
rocketModel[i].model = MODEL_RP4QUAD;
@ -1808,42 +1799,36 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rocketModel[i].numPorts = 4;
break;
case PCI_DEVICE_ID_RP8OCTA:
str = "Octacable";
max_num_aiops = 1;
rocketModel[i].model = MODEL_RP8OCTA;
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_URP8OCTA:
str = "Octacable";
max_num_aiops = 1;
rocketModel[i].model = MODEL_UPCI_RP8OCTA;
strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_RP8INTF:
str = "8";
max_num_aiops = 1;
rocketModel[i].model = MODEL_RP8INTF;
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_URP8INTF:
str = "8";
max_num_aiops = 1;
rocketModel[i].model = MODEL_UPCI_RP8INTF;
strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_RP8J:
str = "8J";
max_num_aiops = 1;
rocketModel[i].model = MODEL_RP8J;
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_RP4J:
str = "4J";
max_num_aiops = 1;
ports_per_aiop = 4;
rocketModel[i].model = MODEL_RP4J;
@ -1851,56 +1836,48 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rocketModel[i].numPorts = 4;
break;
case PCI_DEVICE_ID_RP8SNI:
str = "8 (DB78 Custom)";
max_num_aiops = 1;
rocketModel[i].model = MODEL_RP8SNI;
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_RP16SNI:
str = "16 (DB78 Custom)";
max_num_aiops = 2;
rocketModel[i].model = MODEL_RP16SNI;
strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
rocketModel[i].numPorts = 16;
break;
case PCI_DEVICE_ID_RP16INTF:
str = "16";
max_num_aiops = 2;
rocketModel[i].model = MODEL_RP16INTF;
strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
rocketModel[i].numPorts = 16;
break;
case PCI_DEVICE_ID_URP16INTF:
str = "16";
max_num_aiops = 2;
rocketModel[i].model = MODEL_UPCI_RP16INTF;
strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
rocketModel[i].numPorts = 16;
break;
case PCI_DEVICE_ID_CRP16INTF:
str = "16";
max_num_aiops = 2;
rocketModel[i].model = MODEL_CPCI_RP16INTF;
strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
rocketModel[i].numPorts = 16;
break;
case PCI_DEVICE_ID_RP32INTF:
str = "32";
max_num_aiops = 4;
rocketModel[i].model = MODEL_RP32INTF;
strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
rocketModel[i].numPorts = 32;
break;
case PCI_DEVICE_ID_URP32INTF:
str = "32";
max_num_aiops = 4;
rocketModel[i].model = MODEL_UPCI_RP32INTF;
strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
rocketModel[i].numPorts = 32;
break;
case PCI_DEVICE_ID_RPP4:
str = "Plus Quadcable";
max_num_aiops = 1;
ports_per_aiop = 4;
altChanRingIndicator++;
@ -1910,7 +1887,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rocketModel[i].numPorts = 4;
break;
case PCI_DEVICE_ID_RPP8:
str = "Plus Octacable";
max_num_aiops = 2;
ports_per_aiop = 4;
altChanRingIndicator++;
@ -1920,7 +1896,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rocketModel[i].numPorts = 8;
break;
case PCI_DEVICE_ID_RP2_232:
str = "Plus 2 (RS-232)";
max_num_aiops = 1;
ports_per_aiop = 2;
altChanRingIndicator++;
@ -1930,7 +1905,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rocketModel[i].numPorts = 2;
break;
case PCI_DEVICE_ID_RP2_422:
str = "Plus 2 (RS-422)";
max_num_aiops = 1;
ports_per_aiop = 2;
altChanRingIndicator++;
@ -1943,7 +1917,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
max_num_aiops = 1;
ports_per_aiop = 6;
str = "6-port";
/* If revision is 1, the rocketmodem flash must be loaded.
* If it is 2 it is a "socketed" version. */
@ -1961,7 +1934,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
case PCI_DEVICE_ID_RP4M:
max_num_aiops = 1;
ports_per_aiop = 4;
str = "4-port";
if (dev->revision == 1) {
rcktpt_type[i] = ROCKET_TYPE_MODEMII;
rocketModel[i].loadrm2 = 1;
@ -1974,7 +1946,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rocketModel[i].numPorts = 4;
break;
default:
str = "(unknown/unsupported)";
max_num_aiops = 0;
break;
}
@ -2000,14 +1971,12 @@ static __init int register_PCI(int i, struct pci_dev *dev)
if (!
(sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
PCI_GPIO_CTRL_8PORT)) {
str = "Quadcable";
ports_per_aiop = 4;
rocketModel[i].numPorts = 4;
}
}
break;
case PCI_DEVICE_ID_UPCI_RM3_8PORT:
str = "8 ports";
max_num_aiops = 1;
rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
@ -2018,7 +1987,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
break;
case PCI_DEVICE_ID_UPCI_RM3_4PORT:
str = "4 ports";
max_num_aiops = 1;
rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
@ -2032,21 +2000,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
break;
}
switch (rcktpt_type[i]) {
case ROCKET_TYPE_MODEM:
board_type = "RocketModem";
break;
case ROCKET_TYPE_MODEMII:
board_type = "RocketModem II";
break;
case ROCKET_TYPE_MODEMIII:
board_type = "RocketModem III";
break;
default:
board_type = "RocketPort";
break;
}
if (fast_clock) {
sClockPrescale = 0x12; /* mod 2 (divide by 3) */
rp_baud_base[i] = 921600;

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/21285.c
*
* Driver for the serial port on the 21285 StrongArm-110 core logic chip.
*
* Based on drivers/char/serial.c

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/8250.c
*
* Driver for 8250/16550-type serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@ -273,7 +271,7 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 32,
.tx_loadsz = 32,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_UUE,
.flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
},
[PORT_RM9000] = {
.name = "RM9000",
@ -303,6 +301,14 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
[PORT_TEGRA] = {
.name = "Tegra",
.fifo_size = 32,
.tx_loadsz = 8,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
UART_FCR_T_TRIG_01,
.flags = UART_CAP_FIFO | UART_CAP_RTOIE,
},
};
#if defined(CONFIG_MIPS_ALCHEMY)
@ -1427,6 +1433,27 @@ static void serial8250_enable_ms(struct uart_port *port)
serial_out(up, UART_IER, up->ier);
}
/*
* Clear the Tegra rx fifo after a break
*
* FIXME: This needs to become a port specific callback once we have a
* framework for this
*/
static void clear_rx_fifo(struct uart_8250_port *up)
{
unsigned int status, tmout = 10000;
do {
status = serial_in(up, UART_LSR);
if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
status = serial_in(up, UART_RX);
else
break;
if (--tmout == 0)
break;
udelay(1);
} while (1);
}
static void
receive_chars(struct uart_8250_port *up, unsigned int *status)
{
@ -1461,6 +1488,13 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
if (lsr & UART_LSR_BI) {
lsr &= ~(UART_LSR_FE | UART_LSR_PE);
up->port.icount.brk++;
/*
* If tegra port then clear the rx fifo to
* accept another break/character.
*/
if (up->port.type == PORT_TEGRA)
clear_rx_fifo(up);
/*
* We do the SysRQ and SAK checking
* here because otherwise the break
@ -2405,7 +2439,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;
if (up->capabilities & UART_CAP_UUE)
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
up->ier |= UART_IER_UUE;
if (up->capabilities & UART_CAP_RTOIE)
up->ier |= UART_IER_RTOIE;
serial_out(up, UART_IER, up->ier);

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/8250.h
*
* Driver for 8250/16550-type serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@ -44,6 +42,7 @@ struct serial8250_config {
#define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
#define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/8250_accent.c
*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/8250_boca.c
*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/8250_exar.c
*
* Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
* Based on 8250_boca.
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/8250_fourport.c
*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/8250_hub6.c
*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/8250_mca.c
*
* Copyright (C) 2005 Russell King.
* Data taken from include/asm-i386/serial.h
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/8250_pci.c
*
* Probe module for 8250/16550-type PCI serial ports.
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@ -973,6 +971,14 @@ ce4100_serial_setup(struct serial_private *priv,
return ret;
}
static int
pci_omegapci_setup(struct serial_private *priv,
struct pciserial_board *board,
struct uart_port *port, int idx)
{
return setup_port(priv, port, 2, idx * 8, 0);
}
static int skip_tx_en_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_port *port, int idx)
@ -1012,6 +1018,8 @@ static int skip_tx_en_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_TITAN_200EI 0xA016
#define PCI_DEVICE_ID_TITAN_200EISI 0xA017
#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@ -1412,7 +1420,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.setup = pci_default_setup,
},
/*
* For Oxford Semiconductor and Mainpine
* For Oxford Semiconductor Tornado based devices
*/
{
.vendor = PCI_VENDOR_ID_OXSEMI,
@ -1430,6 +1438,24 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.init = pci_oxsemi_tornado_init,
.setup = pci_default_setup,
},
{
.vendor = PCI_VENDOR_ID_DIGI,
.device = PCIE_DEVICE_ID_NEO_2_OX_IBM,
.subvendor = PCI_SUBVENDOR_ID_IBM,
.subdevice = PCI_ANY_ID,
.init = pci_oxsemi_tornado_init,
.setup = pci_default_setup,
},
/*
* Cronyx Omega PCI (PLX-chip based)
*/
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_omegapci_setup,
},
/*
* Default "match everything" terminator entry
*/
@ -1617,6 +1643,7 @@ enum pci_board_num_t {
pbn_ADDIDATA_PCIe_4_3906250,
pbn_ADDIDATA_PCIe_8_3906250,
pbn_ce4100_1_115200,
pbn_omegapci,
};
/*
@ -2312,6 +2339,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 921600,
.reg_shift = 2,
},
[pbn_omegapci] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 115200,
.uart_offset = 0x200,
},
};
static const struct pci_device_id softmodem_blacklist[] = {
@ -3075,6 +3108,14 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */
PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
pbn_oxsemi_8_4000000 },
/*
* Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado
*/
{ PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM,
PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0,
pbn_oxsemi_2_4000000 },
/*
* SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
* from skokodyn@yahoo.com
@ -3801,6 +3842,12 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ce4100_1_115200 },
/*
* Cronyx Omega PCI
*/
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_omegapci },
/*
* These entries match devices with class COMMUNICATION_SERIAL,

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/8250_pnp.c
*
* Probe module for 8250/16550-type ISAPNP serial ports.
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.

View File

@ -537,7 +537,7 @@ config SERIAL_S3C6400
config SERIAL_S5PV210
tristate "Samsung S5PV210 Serial port support"
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_EXYNOS4210)
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210)
select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210)
default y
help
@ -1585,7 +1585,7 @@ config SERIAL_IFX6X60
Support for the IFX6x60 modem devices on Intel MID platforms.
config SERIAL_PCH_UART
tristate "Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH"
tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
depends on PCI
select SERIAL_CORE
help
@ -1593,10 +1593,12 @@ config SERIAL_PCH_UART
which is an IOH(Input/Output Hub) for x86 embedded processor.
Enabling PCH_DMA, this PCH UART works as DMA mode.
This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/
Output Hub) which is for IVI(In-Vehicle Infotainment) use.
ML7213 is companion chip for Intel Atom E6xx series.
ML7213 is completely compatible for Intel EG20T PCH.
This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
Output Hub), ML7213 and ML7223.
ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
for MP(Media Phone) use.
ML7213/ML7223 is companion chip for Intel Atom E6xx series.
ML7213/ML7223 is completely compatible for Intel EG20T PCH.
config SERIAL_MSM_SMD
bool "Enable tty device interface for some SMD ports"
@ -1620,4 +1622,17 @@ config SERIAL_MXS_AUART_CONSOLE
help
Enable a MXS AUART port to be the system console.
config SERIAL_XILINX_PS_UART
tristate "Xilinx PS UART support"
select SERIAL_CORE
help
This driver supports the Xilinx PS UART port.
config SERIAL_XILINX_PS_UART_CONSOLE
bool "Xilinx PS UART console support"
depends on SERIAL_XILINX_PS_UART=y
select SERIAL_CORE_CONSOLE
help
Enable a Xilinx PS UART port to be the system console.
endmenu

View File

@ -95,3 +95,4 @@ obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o
obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o
obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o

View File

@ -540,11 +540,14 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
int i = pdev->id;
int ret;
/* -1 emphasizes that the platform must have one port, no .N suffix */
if (i == -1)
i = 0;
/* if id is -1 scan for a free id and use that one */
if (i == -1) {
for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++)
if (altera_uart_ports[i].port.mapbase == 0)
break;
}
if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
return -EINVAL;
port = &altera_uart_ports[i].port;
@ -587,6 +590,8 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
port->ops = &altera_uart_ops;
port->flags = UPF_BOOT_AUTOCONF;
dev_set_drvdata(&pdev->dev, port);
uart_add_one_port(&altera_uart_driver, port);
return 0;
@ -594,14 +599,13 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
static int __devexit altera_uart_remove(struct platform_device *pdev)
{
struct uart_port *port;
int i = pdev->id;
struct uart_port *port = dev_get_drvdata(&pdev->dev);
if (i == -1)
i = 0;
port = &altera_uart_ports[i].port;
uart_remove_one_port(&altera_uart_driver, port);
if (port) {
uart_remove_one_port(&altera_uart_driver, port);
dev_set_drvdata(&pdev->dev, NULL);
port->mapbase = 0;
}
return 0;
}

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/amba.c
*
* Driver for AMBA serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/amba.c
*
* Driver for AMBA serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/atmel_serial.c
*
* Driver for Atmel AT91 / AT32 Serial ports
* Copyright (C) 2003 Rick Bronson
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/clps711x.c
*
* Driver for CLPS711x serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/cpm_uart.h
*
* Driver for CPM (SCC/SMC) serial ports
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/cpm_uart.c
*
* Driver for CPM (SCC/SMC) serial ports; core driver
*
* Based on arch/ppc/cpm2_io/uart.c by Dan Malek

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/cpm_uart.c
*
* Driver for CPM (SCC/SMC) serial ports; CPM1 definitions
*
* Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
*
* Driver for CPM (SCC/SMC) serial ports
*
* definitions for cpm1

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/cpm_uart_cpm2.c
*
* Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
*
* Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
*
* Driver for CPM (SCC/SMC) serial ports
*
* definitions for cpm2

View File

@ -41,7 +41,6 @@
#include <linux/tty.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/tty.h>
#include <linux/kfifo.h>
#include <linux/tty_flip.h>
#include <linux/timer.h>
@ -56,7 +55,6 @@
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/tty.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/spi/ifx_modem.h>

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/imx.c
*
* Driver for Motorola IMX serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.

View File

@ -1,5 +1,5 @@
/*
* drivers/serial/msm_serial.c - driver for msm7k serial device and console
* Driver for msm7k serial device and console
*
* Copyright (C) 2007 Google, Inc.
* Author: Robert Love <rlove@google.com>

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/msm_serial.h
*
* Copyright (C) 2007 Google, Inc.
* Author: Robert Love <rlove@google.com>
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.

View File

@ -1,5 +1,4 @@
/* drivers/tty/serial/msm_smd_tty.c
*
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/netx-serial.c
*
* Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify

View File

@ -253,6 +253,8 @@ enum pch_uart_num_t {
pch_ml7213_uart0,
pch_ml7213_uart1,
pch_ml7213_uart2,
pch_ml7223_uart0,
pch_ml7223_uart1,
};
static struct pch_uart_driver_data drv_dat[] = {
@ -263,6 +265,8 @@ static struct pch_uart_driver_data drv_dat[] = {
[pch_ml7213_uart0] = {PCH_UART_8LINE, 0},
[pch_ml7213_uart1] = {PCH_UART_2LINE, 1},
[pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
[pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
[pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
};
static unsigned int default_baud = 9600;
@ -1534,6 +1538,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {
.driver_data = pch_ml7213_uart1},
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029),
.driver_data = pch_ml7213_uart2},
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800C),
.driver_data = pch_ml7223_uart0},
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
.driver_data = pch_ml7223_uart1},
{0,},
};

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/pmac_zilog.c
*
* Driver for PowerMac Z85c30 based ESCC cell found in the
* "macio" ASICs of various PowerMac models
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/serial/pxa.c
*
* Based on drivers/serial/8250.c by Russell King.
*
* Author: Nicolas Pitre

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s3c240.c
*
/*
* Driver for Samsung SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s3c2410.c
*
/*
* Driver for Samsung S3C2410 SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s3c2412.c
*
/*
* Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s3c2440.c
*
/*
* Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s3c24a0.c
*
/*
* Driver for Samsung S3C24A0 SoC onboard UARTs.
*
* Based on drivers/serial/s3c2410.c

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s3c6400.c
*
/*
* Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
*
* Copyright 2008 Openmoko, Inc.

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/s5pv210.c
*
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/sa1100.c
*
* Driver for SA11x0 serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/samsuing.c
*
/*
* Driver core for Samsung SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics

View File

@ -1,5 +1,4 @@
/* linux/drivers/serial/samsung.h
*
/*
* Driver for Samsung SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/sb1250-duart.c
*
* Support for the asynchronous serial interface (DUART) included
* in the BCM1250 and derived System-On-a-Chip (SOC) devices.
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/core.c
*
* Driver core for serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@ -172,12 +170,16 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in
retval = uport->ops->startup(uport);
if (retval == 0) {
if (init_hw) {
/*
* Initialise the hardware port settings.
*/
uart_change_speed(tty, state, NULL);
if (uart_console(uport) && uport->cons->cflag) {
tty->termios->c_cflag = uport->cons->cflag;
uport->cons->cflag = 0;
}
/*
* Initialise the hardware port settings.
*/
uart_change_speed(tty, state, NULL);
if (init_hw) {
/*
* Setup the RTS and DTR signals once the
* port is open and ready to respond.
@ -1240,17 +1242,6 @@ static void uart_set_termios(struct tty_struct *tty,
}
spin_unlock_irqrestore(&state->uart_port->lock, flags);
}
#if 0
/*
* No need to wake up processes in open wait, since they
* sample the CLOCAL flag once, and don't recheck it.
* XXX It's not clear whether the current behavior is correct
* or not. Hence, this may change.....
*/
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
wake_up_interruptible(&state->uart_port.open_wait);
#endif
}
/*
@ -1423,7 +1414,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout)
if (time_after(jiffies, expire))
break;
}
set_current_state(TASK_RUNNING); /* might not be needed */
}
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
@ -1466,45 +1456,6 @@ static void uart_hangup(struct tty_struct *tty)
mutex_unlock(&port->mutex);
}
/**
* uart_update_termios - update the terminal hw settings
* @tty: tty associated with UART
* @state: UART to update
*
* Copy across the serial console cflag setting into the termios settings
* for the initial open of the port. This allows continuity between the
* kernel settings, and the settings init adopts when it opens the port
* for the first time.
*/
static void uart_update_termios(struct tty_struct *tty,
struct uart_state *state)
{
struct uart_port *port = state->uart_port;
if (uart_console(port) && port->cons->cflag) {
tty->termios->c_cflag = port->cons->cflag;
port->cons->cflag = 0;
}
/*
* If the device failed to grab its irq resources,
* or some other error occurred, don't try to talk
* to the port hardware.
*/
if (!(tty->flags & (1 << TTY_IO_ERROR))) {
/*
* Make termios settings take effect.
*/
uart_change_speed(tty, state, NULL);
/*
* And finally enable the RTS and DTR signals.
*/
if (tty->termios->c_cflag & CBAUD)
uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
}
}
static int uart_carrier_raised(struct tty_port *port)
{
struct uart_state *state = container_of(port, struct uart_state, port);
@ -1524,16 +1475,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff)
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport = state->uart_port;
if (onoff) {
if (onoff)
uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
/*
* If this is the first open to succeed,
* adjust things to suit.
*/
if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags))
uart_update_termios(port->tty, state);
}
else
uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
}
@ -1585,15 +1528,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
BUG_ON(!tty_locked());
pr_debug("uart_open(%d) called\n", line);
/*
* tty->driver->num won't change, so we won't fail here with
* tty->driver_data set to something non-NULL (and therefore
* we won't get caught by uart_close()).
*/
retval = -ENODEV;
if (line >= tty->driver->num)
goto fail;
/*
* We take the semaphore inside uart_get to guarantee that we won't
* be re-entered while allocating the state structure, or while we
@ -1972,13 +1906,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
struct tty_port *port = &state->port;
struct device *tty_dev;
struct uart_match match = {uport, drv};
struct tty_struct *tty;
mutex_lock(&port->mutex);
/* Must be inside the mutex lock until we convert to tty_port */
tty = port->tty;
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (device_may_wakeup(tty_dev)) {
if (!enable_irq_wake(uport->irq))

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/serial_ks8695.c
*
* Driver for KS8695 serial ports
*
* Based on drivers/serial/serial_amba.c, by Kam Lee.

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/serial_txx9.c
*
* Derived from many drivers using generic_serial interface,
* especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c
* (was in Linux/VR tree) by Jim Pick.

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/sh-sci.c
*
* SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
*
* Copyright (C) 2002 - 2011 Paul Mundt

View File

@ -1,6 +1,4 @@
/*
* drivers/serial/vt8500_serial.c
*
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
*
* Based on msm_serial.c, which is:

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/synclink.c
*
* $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI

View File

@ -416,6 +416,7 @@ static void flush_to_ldisc(struct work_struct *work)
struct tty_buffer *head, *tail = tty->buf.tail;
int seen_tail = 0;
while ((head = tty->buf.head) != NULL) {
int copied;
int count;
char *char_buf;
unsigned char *flag_buf;
@ -442,17 +443,19 @@ static void flush_to_ldisc(struct work_struct *work)
line discipline as we want to empty the queue */
if (test_bit(TTY_FLUSHPENDING, &tty->flags))
break;
if (!tty->receive_room || seen_tail)
break;
if (count > tty->receive_room)
count = tty->receive_room;
char_buf = head->char_buf_ptr + head->read;
flag_buf = head->flag_buf_ptr + head->read;
head->read += count;
spin_unlock_irqrestore(&tty->buf.lock, flags);
disc->ops->receive_buf(tty, char_buf,
copied = disc->ops->receive_buf(tty, char_buf,
flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
head->read += copied;
if (copied == 0 || seen_tail) {
schedule_work(&tty->buf.work);
break;
}
}
clear_bit(TTY_FLUSHING, &tty->flags);
}

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/tty_io.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
@ -964,12 +962,14 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
}
void tty_write_unlock(struct tty_struct *tty)
__releases(&tty->atomic_write_lock)
{
mutex_unlock(&tty->atomic_write_lock);
wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
int tty_write_lock(struct tty_struct *tty, int ndelay)
__acquires(&tty->atomic_write_lock)
{
if (!mutex_trylock(&tty->atomic_write_lock)) {
if (ndelay)
@ -1391,16 +1391,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
return ERR_PTR(-ENODEV);
tty = alloc_tty_struct();
if (!tty)
goto fail_no_mem;
if (!tty) {
retval = -ENOMEM;
goto err_module_put;
}
initialize_tty_struct(tty, driver, idx);
retval = tty_driver_install_tty(driver, tty);
if (retval < 0) {
free_tty_struct(tty);
module_put(driver->owner);
return ERR_PTR(retval);
}
if (retval < 0)
goto err_deinit_tty;
/*
* Structures all installed ... call the ldisc open routines.
@ -1409,15 +1408,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
*/
retval = tty_ldisc_setup(tty, tty->link);
if (retval)
goto release_mem_out;
goto err_release_tty;
return tty;
fail_no_mem:
err_deinit_tty:
deinitialize_tty_struct(tty);
free_tty_struct(tty);
err_module_put:
module_put(driver->owner);
return ERR_PTR(-ENOMEM);
return ERR_PTR(retval);
/* call the tty release_tty routine to clean out this slot */
release_mem_out:
err_release_tty:
if (printk_ratelimit())
printk(KERN_INFO "tty_init_dev: ldisc open failed, "
"clearing slot %d\n", idx);
@ -1892,6 +1894,7 @@ got_driver:
retval = tty_add_file(tty, filp);
if (retval) {
tty_unlock();
tty_release(inode, filp);
return retval;
}
@ -1902,12 +1905,10 @@ got_driver:
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "opening %s...", tty->name);
#endif
if (!retval) {
if (tty->ops->open)
retval = tty->ops->open(tty, filp);
else
retval = -ENODEV;
}
if (tty->ops->open)
retval = tty->ops->open(tty, filp);
else
retval = -ENODEV;
filp->f_flags = saved_flags;
if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
@ -2887,6 +2888,20 @@ void initialize_tty_struct(struct tty_struct *tty,
tty->dev = tty_get_device(tty);
}
/**
* deinitialize_tty_struct
* @tty: tty to deinitialize
*
* This subroutine deinitializes a tty structure that has been newly
* allocated but tty_release cannot be called on that yet.
*
* Locking: none - tty in question must not be exposed at this point
*/
void deinitialize_tty_struct(struct tty_struct *tty)
{
tty_ldisc_deinit(tty);
}
/**
* tty_put_char - write one character to a tty
* @tty: tty

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/tty_ioctl.c
*
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
*
* Modified by Fred N. van Kempen, 01/29/93, to add line disciplines

View File

@ -956,6 +956,19 @@ void tty_ldisc_init(struct tty_struct *tty)
tty_ldisc_assign(tty, ld);
}
/**
* tty_ldisc_init - ldisc cleanup for new tty
* @tty: tty that was allocated recently
*
* The tty structure must not becompletely set up (tty_ldisc_setup) when
* this call is made.
*/
void tty_ldisc_deinit(struct tty_struct *tty)
{
put_ldisc(tty->ldisc);
tty_ldisc_assign(tty, NULL);
}
void tty_ldisc_begin(void)
{
/* Setup the default TTY line discipline. */

View File

@ -1,6 +1,3 @@
/*
* drivers/char/tty_lock.c
*/
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/kallsyms.h>

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/keyboard.c
*
* Written for linux by Johan Myreen as a translation from
* the assembly version by Linus (with diacriticals added)
*

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/selection.c
*
* This module exports the functions:
*
* 'int set_selection(struct tiocl_selection __user *, struct tty_struct *)'
@ -334,8 +332,7 @@ int paste_selection(struct tty_struct *tty)
continue;
}
count = sel_buffer_lth - pasted;
count = min(count, tty->receive_room);
tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
NULL, count);
pasted += count;
}

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/vc_screen.c
*
* Provide access to virtual console memory.
* /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
* /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/vt.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
@ -858,7 +856,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
{
unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
unsigned long end;
unsigned int old_cols, old_rows, old_row_size, old_screen_size;
unsigned int old_rows, old_row_size;
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
unsigned int user;
unsigned short *newscreen;
@ -887,9 +885,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
return -ENOMEM;
old_rows = vc->vc_rows;
old_cols = vc->vc_cols;
old_row_size = vc->vc_size_row;
old_screen_size = vc->vc_screenbuf_size;
err = resize_screen(vc, new_cols, new_rows, user);
if (err) {
@ -1197,6 +1193,13 @@ static void csi_J(struct vc_data *vc, int vpar)
vc->vc_x + 1);
}
break;
case 3: /* erase scroll-back buffer (and whole display) */
scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
vc->vc_screenbuf_size >> 1);
set_origin(vc);
if (CON_IS_VISIBLE(vc))
update_screen(vc);
/* fall through */
case 2: /* erase whole display */
count = vc->vc_cols * vc->vc_rows;
start = (unsigned short *)vc->vc_origin;

View File

@ -1,6 +1,4 @@
/*
* linux/drivers/char/vt_ioctl.c
*
* Copyright (C) 1992 obz under the linux copyright
*
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
@ -698,10 +696,23 @@ int vt_ioctl(struct tty_struct *tty,
break;
case KDGKBMODE:
uival = ((kbd->kbdmode == VC_RAW) ? K_RAW :
(kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
(kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
K_XLATE);
switch (kbd->kbdmode) {
case VC_RAW:
uival = K_RAW;
break;
case VC_MEDIUMRAW:
uival = K_MEDIUMRAW;
break;
case VC_UNICODE:
uival = K_UNICODE;
break;
case VC_OFF:
uival = K_OFF;
break;
default:
uival = K_XLATE;
break;
}
goto setint;
/* this could be folded into KDSKBMODE, but for compatibility
@ -1499,7 +1510,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
{
struct vc_data *vc = tty->driver_data;
struct console_font_op op; /* used in multiple places here */
struct kbd_struct *kbd;
unsigned int console;
void __user *up = (void __user *)arg;
int perm;
@ -1522,7 +1532,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
perm = 1;
kbd = kbd_table + console;
switch (cmd) {
/*
* these need special handlers for incompatible data structures

View File

@ -1051,6 +1051,7 @@ char *get_task_comm(char *buf, struct task_struct *tsk)
task_unlock(tsk);
return buf;
}
EXPORT_SYMBOL_GPL(get_task_comm);
void set_task_comm(struct task_struct *tsk, char *buf)
{

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) Intel 2011
*
* 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.
*
* 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.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The PTI (Parallel Trace Interface) driver directs trace data routed from
* various parts in the system out through the Intel Penwell PTI port and
* out of the mobile device for analysis with a debugging tool
* (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
* compact JTAG, standard.
*
* This header file will allow other parts of the OS to use the
* interface to write out it's contents for debugging a mobile system.
*/
#ifndef PTI_H_
#define PTI_H_
/* offset for last dword of any PTI message. Part of MIPI P1149.7 */
#define PTI_LASTDWORD_DTS 0x30
/* basic structure used as a write address to the PTI HW */
struct pti_masterchannel {
u8 master;
u8 channel;
};
/* the following functions are defined in misc/pti.c */
void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count);
struct pti_masterchannel *pti_request_masterchannel(u8 type);
void pti_release_masterchannel(struct pti_masterchannel *mc);
#endif /*PTI_H_*/

View File

@ -45,7 +45,8 @@
#define PORT_OCTEON 17 /* Cavium OCTEON internal UART */
#define PORT_AR7 18 /* Texas Instruments AR7 internal UART */
#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */
#define PORT_MAX_8250 19 /* max port ID */
#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
#define PORT_MAX_8250 20 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
@ -202,6 +203,9 @@
/* VIA VT8500 SoC */
#define PORT_VT8500 97
/* Xilinx PSS UART */
#define PORT_XUARTPS 98
#ifdef __KERNEL__
#include <linux/compiler.h>

View File

@ -57,6 +57,7 @@
* ST16C654: 8 16 56 60 8 16 32 56 PORT_16654
* TI16C750: 1 16 32 56 xx xx xx xx PORT_16750
* TI16C752: 8 16 56 60 8 16 32 56
* Tegra: 1 4 8 14 16 8 4 1 PORT_TEGRA
*/
#define UART_FCR_R_TRIG_00 0x00
#define UART_FCR_R_TRIG_01 0x40
@ -118,6 +119,7 @@
#define UART_MCR_DTR 0x01 /* DTR complement */
#define UART_LSR 5 /* In: Line Status Register */
#define UART_LSR_FIFOE 0x80 /* Fifo error */
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */

Some files were not shown because too many files have changed in this diff Show More