aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/pti.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/pti.c')
-rw-r--r--drivers/misc/pti.c111
1 files changed, 71 insertions, 40 deletions
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index 71aa7835e86..8f4d9abf425 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -40,18 +40,22 @@
#include <linux/miscdevice.h>
#include <linux/pti.h>
-#define DRIVERNAME "pti"
-#define PCINAME "pciPTI"
-#define TTYNAME "ttyPTI"
-#define CHARNAME "pti"
-#define MAX_APP_IDS 128
-#define MAX_OS_IDS 128
-#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 to copy data from user space */
+#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 128
+#define MAX_OS_IDS 128
+#define MAX_MODEM_IDS 128
+#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 */
struct pti_tty {
struct masterchannel *mc;
@@ -65,6 +69,7 @@ struct pti_dev {
unsigned long pti_iolen;
u8 IA_App[MAX_APP_IDS];
u8 IA_OS[MAX_OS_IDS];
+ u8 IA_Modem[MAX_MODEM_IDS];
};
@@ -268,6 +273,8 @@ static struct masterchannel *getID(u8 *IDarray, int max_IDS, int baseID)
* 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.
* @return: masterchannel struct or 0 for error.
*
@@ -288,6 +295,8 @@ struct masterchannel *mipi_request_masterchannel(u8 type)
mc = getID(drv_data->IA_OS, MAX_OS_IDS, OS_BASE_ID);
break;
+ case 2:
+ mc = getID(drv_data->IA_Modem, MAX_MODEM_IDS, MODEM_BASE_ID);
default:
mutex_unlock(&alloclock);
return 0;
@@ -296,7 +305,7 @@ struct masterchannel *mipi_request_masterchannel(u8 type)
mutex_unlock(&alloclock);
return mc;
}
-EXPORT_SYMBOL(mipi_request_masterchannel);
+EXPORT_SYMBOL_GPL(mipi_request_masterchannel);
/**
* mipi_release_masterchannel() - Kernel API function used to release
@@ -315,21 +324,25 @@ void mipi_release_masterchannel(struct masterchannel *mc)
master = mc->master;
channel = mc->channel;
- if (master >= 80) {
- i = ((master-80) << 4) + (channel>>3);
+ if (master == APP_BASE_ID) {
+ i = channel >> 3;
drv_data->IA_App[i] &= ~(0x80>>(channel & 0x7));
}
- if (master >= 72) {
- i = ((master-72) << 4) + (channel>>3);
+ 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(mipi_release_masterchannel);
+EXPORT_SYMBOL_GPL(mipi_release_masterchannel);
/**
* mipi_pti_writedata() - Kernel API function used to write trace
@@ -356,7 +369,7 @@ void mipi_pti_writedata(struct masterchannel *mc, u8 *buf, int count)
}
return;
}
-EXPORT_SYMBOL(mipi_pti_writedata);
+EXPORT_SYMBOL_GPL(mipi_pti_writedata);
static void __devexit pti_pci_remove(struct pci_dev *pdev)
{
@@ -386,9 +399,14 @@ static void __devexit pti_pci_remove(struct pci_dev *pdev)
*
* @return int : Success = 0, otherwise fail.
*
- * 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.
+ * 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)
{
@@ -396,6 +414,9 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
struct masterchannel *mc;
int ret = 0;
+ pr_debug("%s: tty->name is: %s\n", __func__, tty->name);
+ pr_debug("%s: tty->index is: %d\n", __func__, tty->index);
+
/*
we actually want to allocate a new channel per open, per
system arch. HW gives more than plenty channels for a single
@@ -405,7 +426,11 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
*/
ret = tty_port_open(&drv_data->port, tty, filp);
pti_tty_data = tty->driver_data;
- mc = mipi_request_masterchannel(0);
+
+ if (tty->index == PTITTY_MINOR_START)
+ mc = mipi_request_masterchannel(0);
+ else
+ mc = mipi_request_masterchannel(2);
if (mc == 0)
return -EBUSY;
pti_tty_data->mc = mc;
@@ -435,8 +460,8 @@ static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
if (pti_tty_data != NULL) {
mc = pti_tty_data->mc;
mipi_release_masterchannel(mc);
+ pti_tty_data->mc = NULL;
}
-
tty_port_close(&drv_data->port, tty, filp);
return;
@@ -558,7 +583,7 @@ int pti_char_release(struct inode *inode, struct file *filp)
* @return int : # of bytes written, or error.
*/
ssize_t pti_char_write(struct file *filp, const char *data, size_t len,
- loff_t *ppose)
+ loff_t *ppose)
{
struct masterchannel *mc;
void *kbuf;
@@ -667,19 +692,21 @@ static struct console pti_console = {
* pti_port_activate(): Used to start/initialize any items upon
* first opening of tty_port().
*
- * @param port
- * @param tty
+ * @param port- The tty port number of the PTI device.
+ * @param tty- The tty struct associated with this device.
*
* @return int - Always returns 0.
*
- * Notes: The primary purpose of the PTI tty port is to hook the
- * syslog daemon to it; thus this port will be open for a very
- * long time.
+ * 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.
*/
int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
{
pr_debug("%s(%d): Called.\n", __func__, __LINE__);
- console_start(&pti_console);
+ pr_debug("%s(%d): index is: %d\n", __func__, __LINE__, port->tty->index);
+ if (port->tty->index == PTITTY_MINOR_START)
+ console_start(&pti_console);
return 0;
}
@@ -687,16 +714,18 @@ int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
* pti_port_shutdown(): Used to stop/shutdown any items upon the
* last tty port close.
*
- * @param port
+ * @param port- The tty port number of the PTI device.
*
- * Notes: The primary purpose of the PTI tty port is to hook the
- * syslog daemon to it; thus this port will be open for a very
- * long time.
+ * 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.
*/
void pti_port_shutdown(struct tty_port *port)
{
pr_debug("%s(%d): Called.\n", __func__, __LINE__);
- console_stop(&pti_console);
+ pr_debug("%s(%d): index is: %d\n", __func__, __LINE__, port->tty->index);
+ if (port->tty->index == PTITTY_MINOR_START)
+ console_stop(&pti_console);
}
static const struct tty_port_operations tty_port_ops = {
@@ -762,7 +791,8 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev,
tty_port_init(&drv_data->port);
drv_data->port.ops = &tty_port_ops;
- tty_register_device(pti_tty_driver, 0, NULL);
+ tty_register_device(pti_tty_driver, 0, &pdev->dev);
+ tty_register_device(pti_tty_driver, 1, &pdev->dev);
register_console(&pti_console);
@@ -810,9 +840,9 @@ static int __init pti_init(void)
pti_tty_driver->driver_name = DRIVERNAME;
pti_tty_driver->name = TTYNAME;
pti_tty_driver->major = 0;
- pti_tty_driver->minor_start = 0;
- pti_tty_driver->minor_num = 1;
- pti_tty_driver->num = 1;
+ 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 |
@@ -866,6 +896,7 @@ static void __exit pti_exit(void)
}
tty_unregister_device(pti_tty_driver, 0);
+ tty_unregister_device(pti_tty_driver, 1);
retval = tty_unregister_driver(pti_tty_driver);
if (retval) {