Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 354964
b: refs/heads/master
c: feee830
h: refs/heads/master
v: v3
  • Loading branch information
Greg Kroah-Hartman committed Jan 16, 2013
1 parent 066e9c0 commit 85280e3
Show file tree
Hide file tree
Showing 45 changed files with 12,655 additions and 2,285 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 689557d3c7045320958d5bc4141088f7b4dff7ba
refs/heads/master: feee830394cab4e697d2204da6d10a606619de3d
111 changes: 48 additions & 63 deletions trunk/drivers/ipack/devices/ipoctal.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <linux/serial.h>
#include <linux/tty_flip.h>
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/io.h>
#include <linux/ipack.h>
#include "ipoctal.h"
Expand All @@ -38,21 +37,19 @@ struct ipoctal_channel {
spinlock_t lock;
unsigned int pointer_read;
unsigned int pointer_write;
atomic_t open;
struct tty_port tty_port;
union scc2698_channel __iomem *regs;
union scc2698_block __iomem *block_regs;
unsigned int board_id;
unsigned char *board_write;
u8 isr_rx_rdy_mask;
u8 isr_tx_rdy_mask;
unsigned int rx_enable;
};

struct ipoctal {
struct ipack_device *dev;
unsigned int board_id;
struct ipoctal_channel channel[NR_CHANNELS];
unsigned char write;
struct tty_driver *tty_drv;
u8 __iomem *mem8_space;
u8 __iomem *int_space;
Expand All @@ -64,28 +61,23 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)

channel = dev_get_drvdata(tty->dev);

/*
* Enable RX. TX will be enabled when
* there is something to send
*/
iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
channel->rx_enable = 1;
return 0;
}

static int ipoctal_open(struct tty_struct *tty, struct file *file)
{
int res;
struct ipoctal_channel *channel;

channel = dev_get_drvdata(tty->dev);

if (atomic_read(&channel->open))
return -EBUSY;

tty->driver_data = channel;

res = tty_port_open(&channel->tty_port, tty, file);
if (res)
return res;

atomic_inc(&channel->open);
return 0;
return tty_port_open(&channel->tty_port, tty, file);
}

static void ipoctal_reset_stats(struct ipoctal_stats *stats)
Expand All @@ -111,9 +103,7 @@ static void ipoctal_close(struct tty_struct *tty, struct file *filp)
struct ipoctal_channel *channel = tty->driver_data;

tty_port_close(&channel->tty_port, tty, filp);

if (atomic_dec_and_test(&channel->open))
ipoctal_free_channel(channel);
ipoctal_free_channel(channel);
}

static int ipoctal_get_icount(struct tty_struct *tty,
Expand All @@ -137,11 +127,12 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel,
struct tty_struct *tty, u8 sr)
{
unsigned char value;
unsigned char flag = TTY_NORMAL;
unsigned char flag;
u8 isr;

do {
value = ioread8(&channel->regs->r.rhr);
flag = TTY_NORMAL;
/* Error: count statistics */
if (sr & SR_ERROR) {
iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
Expand Down Expand Up @@ -183,54 +174,40 @@ static void ipoctal_irq_tx(struct ipoctal_channel *channel)
unsigned char value;
unsigned int *pointer_write = &channel->pointer_write;

if (channel->nb_bytes <= 0) {
channel->nb_bytes = 0;
if (channel->nb_bytes == 0)
return;
}

value = channel->tty_port.xmit_buf[*pointer_write];
iowrite8(value, &channel->regs->w.thr);
channel->stats.tx++;
(*pointer_write)++;
*pointer_write = *pointer_write % PAGE_SIZE;
channel->nb_bytes--;

if ((channel->nb_bytes == 0) &&
(waitqueue_active(&channel->queue))) {

if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
*channel->board_write = 1;
wake_up_interruptible(&channel->queue);
}
}
}

static void ipoctal_irq_channel(struct ipoctal_channel *channel)
{
u8 isr, sr;
struct tty_struct *tty;

/* If there is no client, skip the check */
if (!atomic_read(&channel->open))
return;

tty = tty_port_tty_get(&channel->tty_port);
if (!tty)
return;

spin_lock(&channel->lock);
/* The HW is organized in pair of channels. See which register we need
* to read from */
isr = ioread8(&channel->block_regs->r.isr);
sr = ioread8(&channel->regs->r.sr);

/* In case of RS-485, change from TX to RX when finishing TX.
* Half-duplex. */
if ((channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
(sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) {
if ((sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) {
iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
*channel->board_write = 1;
wake_up_interruptible(&channel->queue);
/* In case of RS-485, change from TX to RX when finishing TX.
* Half-duplex. */
if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
}
}

/* RX data */
Expand All @@ -241,23 +218,23 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel)
if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
ipoctal_irq_tx(channel);

tty_flip_buffer_push(tty);
tty_kref_put(tty);
spin_unlock(&channel->lock);
}

static irqreturn_t ipoctal_irq_handler(void *arg)
{
unsigned int i;
struct ipoctal *ipoctal = (struct ipoctal *) arg;

/* Check all channels */
for (i = 0; i < NR_CHANNELS; i++)
ipoctal_irq_channel(&ipoctal->channel[i]);

/* Clear the IPack device interrupt */
readw(ipoctal->int_space + ACK_INT_REQ0);
readw(ipoctal->int_space + ACK_INT_REQ1);

/* Check all channels */
for (i = 0; i < NR_CHANNELS; i++)
ipoctal_irq_channel(&ipoctal->channel[i]);

return IRQ_HANDLED;
}

Expand Down Expand Up @@ -324,7 +301,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
struct ipoctal_channel *channel = &ipoctal->channel[i];
channel->regs = chan_regs + i;
channel->block_regs = block_regs + (i >> 1);
channel->board_write = &ipoctal->write;
channel->board_id = ipoctal->board_id;
if (i & 1) {
channel->isr_tx_rdy_mask = ISR_TxRDY_B;
Expand All @@ -335,6 +311,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
}

iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
channel->rx_enable = 0;
iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY,
Expand Down Expand Up @@ -407,8 +384,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,

ipoctal_reset_stats(&channel->stats);
channel->nb_bytes = 0;
init_waitqueue_head(&channel->queue);

spin_lock_init(&channel->lock);
channel->pointer_read = 0;
channel->pointer_write = 0;
Expand All @@ -419,12 +394,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
continue;
}
dev_set_drvdata(tty_dev, channel);

/*
* Enable again the RX. TX will be enabled when
* there is something to send
*/
iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
}

return 0;
Expand Down Expand Up @@ -464,6 +433,7 @@ static int ipoctal_write_tty(struct tty_struct *tty,
/* As the IP-OCTAL 485 only supports half duplex, do it manually */
if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
iowrite8(CR_DISABLE_RX, &channel->regs->w.cr);
channel->rx_enable = 0;
iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr);
}

Expand All @@ -472,10 +442,6 @@ static int ipoctal_write_tty(struct tty_struct *tty,
* operations
*/
iowrite8(CR_ENABLE_TX, &channel->regs->w.cr);
wait_event_interruptible(channel->queue, *channel->board_write);
iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);

*channel->board_write = 0;
return char_copied;
}

Expand Down Expand Up @@ -627,8 +593,9 @@ static void ipoctal_set_termios(struct tty_struct *tty,
iowrite8(mr2, &channel->regs->w.mr);
iowrite8(csr, &channel->regs->w.csr);

/* Enable again the RX */
iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
/* Enable again the RX, if it was before */
if (channel->rx_enable)
iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
}

static void ipoctal_hangup(struct tty_struct *tty)
Expand All @@ -648,6 +615,7 @@ static void ipoctal_hangup(struct tty_struct *tty)
tty_port_hangup(&channel->tty_port);

iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
channel->rx_enable = 0;
iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
Expand All @@ -657,6 +625,22 @@ static void ipoctal_hangup(struct tty_struct *tty)
wake_up_interruptible(&channel->tty_port.open_wait);
}

static void ipoctal_shutdown(struct tty_struct *tty)
{
struct ipoctal_channel *channel = tty->driver_data;

if (channel == NULL)
return;

iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
channel->rx_enable = 0;
iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr);
clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
}

static const struct tty_operations ipoctal_fops = {
.ioctl = NULL,
.open = ipoctal_open,
Expand All @@ -667,6 +651,7 @@ static const struct tty_operations ipoctal_fops = {
.chars_in_buffer = ipoctal_chars_in_buffer,
.get_icount = ipoctal_get_icount,
.hangup = ipoctal_hangup,
.shutdown = ipoctal_shutdown,
};

static int ipoctal_probe(struct ipack_device *dev)
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,5 @@ source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig"
source "drivers/misc/mei/Kconfig"
source "drivers/misc/vmw_vmci/Kconfig"
endmenu
2 changes: 2 additions & 0 deletions trunk/drivers/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
5 changes: 3 additions & 2 deletions trunk/drivers/misc/mei/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
#
obj-$(CONFIG_INTEL_MEI) += mei.o
mei-objs := init.o
mei-objs += hbm.o
mei-objs += interrupt.o
mei-objs += interface.o
mei-objs += iorw.o
mei-objs += hw-me.o
mei-objs += main.o
mei-objs += amthif.o
mei-objs += wd.o
mei-objs += client.o
Loading

0 comments on commit 85280e3

Please sign in to comment.