/*
 *  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>
#include <linux/slab.h>
#include <linux/uaccess.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[PTITTY_MINOR_NUM];
	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 const struct pci_device_id pci_ids[] = {
		{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.
 *  @thread_name: The thread name associated with the master / channel or
 *                'NULL' if using the 'current' global variable.
 *
 *  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 'current' global variable if 'thread_name'
 *  is 'NULL', else it is retrieved from 'thread_name' parameter.
 *  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,
					     const char *thread_name)
{
	/*
	 * 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];
	struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
					      .channel = 0};
	const char *thread_name_p;
	const char *control_format = "%3d %3d %s";
	u8 control_frame[CONTROL_FRAME_LEN];

	if (!thread_name) {
		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;
		thread_name_p = comm;
	} else {
		thread_name_p = thread_name;
	}

	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, thread_name_p);
	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, NULL);
	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.
 * @thread_name: The thread name associated with the master / channel or
 *               'NULL' if using the 'current' global variable.
 *
 * 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,
					const char *thread_name)
{
	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, thread_name);
	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.
 * @thread_name: The thread name associated with the master / channel or
 *               'NULL' if using the 'current' global variable.
 *
 * Returns:
 *	pti_masterchannel struct
 *	0 for error
 */
struct pti_masterchannel *pti_request_masterchannel(u8 type,
						    const char *thread_name)
{
	struct pti_masterchannel *mc;

	mutex_lock(&alloclock);

	switch (type) {

	case 0:
		mc = get_id(drv_data->ia_app, MAX_APP_IDS,
			    APP_BASE_ID, thread_name);
		break;

	case 1:
		mc = get_id(drv_data->ia_os, MAX_OS_IDS,
			    OS_BASE_ID, thread_name);
		break;

	case 2:
		mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS,
			    MODEM_BASE_ID, thread_name);
		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.  This
 *      will de-allocate the structure via kfree().
 */
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);

/*
 * 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(tty->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(tty->port, tty, filp);
}

/**
 * pti_tty_install()- 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_standard_install(driver, tty);

	if (ret == 0) {
		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, NULL);
		else
			pti_tty_data->mc = pti_request_masterchannel(2, NULL);

		if (pti_tty_data->mc == NULL) {
			kfree(pti_tty_data);
			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(pti_tty_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, NULL);
	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);
	filp->private_data = NULL;
	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 pti_pci_probe(struct pci_dev *pdev,
		const struct pci_device_id *ent)
{
	unsigned int a;
	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);
		goto err;
	}

	retval = pci_enable_device(pdev);
	if (retval != 0) {
		dev_err(&pdev->dev,
			"%s: pci_enable_device() returned error %d\n",
			__func__, retval);
		goto err_unreg_misc;
	}

	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__);
		goto err_disable_pci;
	}
	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);
		goto err_free_dd;
	}
	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) {
		retval = -ENOMEM;
		goto err_rel_reg;
	}

	pci_set_drvdata(pdev, drv_data);

	for (a = 0; a < PTITTY_MINOR_NUM; a++) {
		struct tty_port *port = &drv_data->port[a];
		tty_port_init(port);
		port->ops = &tty_port_ops;

		tty_port_register_device(port, pti_tty_driver, a, &pdev->dev);
	}

	register_console(&pti_console);

	return 0;
err_rel_reg:
	pci_release_region(pdev, pci_bar);
err_free_dd:
	kfree(drv_data);
err_disable_pci:
	pci_disable_device(pdev);
err_unreg_misc:
	misc_deregister(&pti_char_driver);
err:
	return retval;
}

/**
 * pti_pci_remove()- Driver exit method to remove PTI from
 *		   PCI bus.
 * @pdev: variable containing pci info of PTI.
 */
static void pti_pci_remove(struct pci_dev *pdev)
{
	struct pti_dev *drv_data = pci_get_drvdata(pdev);

	unregister_console(&pti_console);

	tty_unregister_device(pti_tty_driver, 0);
	tty_unregister_device(pti_tty_driver, 1);

	iounmap(drv_data->pti_ioaddr);
	pci_set_drvdata(pdev, NULL);
	kfree(drv_data);
	pci_release_region(pdev, 1);
	pci_disable_device(pdev);

	misc_deregister(&pti_char_driver);
}

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(PTITTY_MINOR_NUM);
	if (pti_tty_driver == NULL) {
		pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n",
			__func__, __LINE__);
		return -ENOMEM;
	}

	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->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);

		goto put_tty;
	}

	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);
		goto unreg_tty;
	}

	return 0;
unreg_tty:
	tty_unregister_driver(pti_tty_driver);
put_tty:
	put_tty_driver(pti_tty_driver);
	pti_tty_driver = NULL;
	return retval;
}

/**
 * pti_exit()- Unregisters this module as a tty and pci driver.
 */
static void __exit pti_exit(void)
{
	tty_unregister_driver(pti_tty_driver);
	pci_unregister_driver(&pti_pci_driver);
	put_tty_driver(pti_tty_driver);
}

module_init(pti_init);
module_exit(pti_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ken Mills, Jay Freyensee");
MODULE_DESCRIPTION("PTI Driver");

