linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs.
@ 2012-09-12 12:55 Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 02/24] Staging: ipack/bridges/tpci200: Remove side effects of tpci200_{request,free}_irq Samuel Iglesias Gonsalvez
                   ` (22 more replies)
  0 siblings, 23 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Convert tpci200_set_clockrate and tpci200_interrupt.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   49 ++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 9d886b7..2560519 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -53,6 +53,32 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
 	return tpci200;
 }
 
+static void __tpci200_clear_mask(__le16 __iomem *addr, u16 mask)
+{
+	iowrite16(ioread16(addr) & (~mask), addr);
+}
+
+static void tpci200_clear_mask(struct tpci200_board *tpci200,
+			       __le16 __iomem *addr, u16 mask)
+{
+	mutex_lock(&tpci200->mutex);
+	__tpci200_clear_mask(addr, mask);
+	mutex_unlock(&tpci200->mutex);
+}
+
+static void __tpci200_set_mask(__le16 __iomem *addr, u16 mask)
+{
+	iowrite16(ioread16(addr) | mask, addr);
+}
+
+static void tpci200_set_mask(struct tpci200_board *tpci200,
+			     __le16 __iomem *addr, u16 mask)
+{
+	mutex_lock(&tpci200->mutex);
+	__tpci200_set_mask(addr, mask);
+	mutex_unlock(&tpci200->mutex);
+}
+
 static void tpci200_unregister(struct tpci200_board *tpci200)
 {
 	int i;
@@ -86,7 +112,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 {
 	struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
 	int i;
-	unsigned short status_reg, reg_value;
+	unsigned short status_reg;
 	unsigned short unhandled_ints = 0;
 	irqreturn_t ret = IRQ_NONE;
 	struct slot_irq *slot_irq;
@@ -124,12 +150,9 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 				dev_info(&slot_irq->holder->dev,
 					 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
 					 tpci200->number, i);
-				reg_value = readw(
-					&tpci200->info->interface_regs->control[i]);
-				reg_value &=
-					~(TPCI200_INT0_EN | TPCI200_INT1_EN);
-				writew(reg_value,
-				       &tpci200->info->interface_regs->control[i]);
+				__tpci200_clear_mask(
+					&tpci200->info->interface_regs->control[i],
+					TPCI200_INT0_EN | TPCI200_INT1_EN);
 			}
 		}
 	}
@@ -518,30 +541,22 @@ static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
 	u16 __iomem *addr;
-	u16 reg;
 
 	if (!tpci200)
 		return -ENODEV;
 
 	addr = &tpci200->info->interface_regs->control[dev->slot];
 
-	/* Ensure the control register is not changed by another task after we
-	 * have read it. */
-	mutex_lock(&tpci200->mutex);
-	reg = ioread16(addr);
 	switch (mherz) {
 	case 8:
-		reg &= ~(TPCI200_CLK32);
+		tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
 		break;
 	case 32:
-		reg |= TPCI200_CLK32;
+		tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
 		break;
 	default:
-		mutex_unlock(&tpci200->mutex);
 		return -EINVAL;
 	}
-	iowrite16(reg, addr);
-	mutex_unlock(&tpci200->mutex);
 	return 0;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 02/24] Staging: ipack/bridges/tpci200: Remove side effects of tpci200_{request,free}_irq.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 03/24] Staging: ipack/bridges/tpci200: Clean up interrupt handler Samuel Iglesias Gonsalvez
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Use the __tpci200_{set,clear}_mask routines to access control
register.  Do not overwrite flags unrelated to interrupt handling.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   31 ++++++-------------------------
 1 file changed, 6 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 2560519..3285dad 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -278,37 +278,18 @@ out_disable_pci:
 static int __tpci200_request_irq(struct tpci200_board *tpci200,
 				 struct ipack_device *dev)
 {
-	unsigned short slot_ctrl;
-
-	/* Set the default parameters of the slot
-	 * INT0 enabled, level sensitive
-	 * INT1 enabled, level sensitive
-	 * error interrupt disabled
-	 * timeout interrupt disabled
-	 * recover time disabled
-	 * clock rate 8 MHz
-	 */
-	slot_ctrl = TPCI200_INT0_EN | TPCI200_INT1_EN;
-	writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]);
-
+	__tpci200_set_mask(
+			&tpci200->info->interface_regs->control[dev->slot],
+			TPCI200_INT0_EN | TPCI200_INT1_EN);
 	return 0;
 }
 
 static void __tpci200_free_irq(struct tpci200_board *tpci200,
 			       struct ipack_device *dev)
 {
-	unsigned short slot_ctrl;
-
-	/* Set the default parameters of the slot
-	 * INT0 disabled, level sensitive
-	 * INT1 disabled, level sensitive
-	 * error interrupt disabled
-	 * timeout interrupt disabled
-	 * recover time disabled
-	 * clock rate 8 MHz
-	 */
-	slot_ctrl = 0;
-	writew(slot_ctrl, &tpci200->info->interface_regs->control[dev->slot]);
+	__tpci200_clear_mask(
+			&tpci200->info->interface_regs->control[dev->slot],
+			TPCI200_INT0_EN | TPCI200_INT1_EN);
 }
 
 static int tpci200_free_irq(struct ipack_device *dev)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 03/24] Staging: ipack/bridges/tpci200: Clean up interrupt handler.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 02/24] Staging: ipack/bridges/tpci200: Remove side effects of tpci200_{request,free}_irq Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 04/24] Staging: ipack/devices/ipoctal: split ipoctal_channel from ipoctal Samuel Iglesias Gonsalvez
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

This also removes a possible bug in the unhandles_ints part when
slots[i] is not set.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   42 +++++++++++++------------------
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 3285dad..24e2a11 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -108,12 +108,22 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
 	}
 }
 
+static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
+{
+	irqreturn_t ret = slot_irq->handler(slot_irq->arg);
+
+	/* Dummy reads */
+	readw(slot_irq->holder->io_space.address + 0xC0);
+	readw(slot_irq->holder->io_space.address + 0xC2);
+
+	return ret;
+}
+
 static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 {
 	struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
 	int i;
 	unsigned short status_reg;
-	unsigned short unhandled_ints = 0;
 	irqreturn_t ret = IRQ_NONE;
 	struct slot_irq *slot_irq;
 
@@ -121,33 +131,15 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 	status_reg = readw(&tpci200->info->interface_regs->status);
 
 	if (status_reg & TPCI200_SLOT_INT_MASK) {
-		unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK;
 		/* callback to the IRQ handler for the corresponding slot */
 		for (i = 0; i < TPCI200_NB_SLOT; i++) {
+			if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))))
+				continue;
 			slot_irq = tpci200->slots[i].irq;
-
-			if ((slot_irq != NULL) &&
-			    (status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) {
-
-				ret = slot_irq->handler(slot_irq->arg);
-
-				/* Dummy reads */
-				readw(slot_irq->holder->io_space.address +
-				      0xC0);
-				readw(slot_irq->holder->io_space.address +
-				      0xC2);
-
-				unhandled_ints &= ~(((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)));
-			}
-		}
-	}
-	/* Interrupts not handled are disabled */
-	if (unhandled_ints) {
-		for (i = 0; i < TPCI200_NB_SLOT; i++) {
-			slot_irq = tpci200->slots[i].irq;
-
-			if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) {
-				dev_info(&slot_irq->holder->dev,
+			if (slot_irq) {
+				ret = tpci200_slot_irq(slot_irq);
+			} else {
+				dev_info(&tpci200->info->pdev->dev,
 					 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
 					 tpci200->number, i);
 				__tpci200_clear_mask(
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 04/24] Staging: ipack/devices/ipoctal: split ipoctal_channel from ipoctal.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 02/24] Staging: ipack/bridges/tpci200: Remove side effects of tpci200_{request,free}_irq Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 03/24] Staging: ipack/bridges/tpci200: Clean up interrupt handler Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 05/24] Staging: ipack/devices/ipoctal: Directly use ioread/iowrite function Samuel Iglesias Gonsalvez
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

By moving everything channel related into a separate struct we will be
able to clean up a lot of code.  In the end tty->driver_data will no
longer need to point to ipoctal but instead can point to the respective
channel.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |  286 ++++++++++++++++---------------
 1 file changed, 150 insertions(+), 136 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 35513d9..9ab0e80 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -30,22 +30,26 @@
 
 static const struct tty_operations ipoctal_fops;
 
+struct ipoctal_channel {
+	struct ipoctal_stats		stats;
+	unsigned int			nb_bytes;
+	unsigned int			count_wr;
+	wait_queue_head_t		queue;
+	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;
+};
+
 struct ipoctal {
 	struct list_head		list;
 	struct ipack_device		*dev;
 	unsigned int			board_id;
-	union scc2698_channel __iomem	*chan_regs;
-	union scc2698_block __iomem	*block_regs;
-	struct ipoctal_stats		chan_stats[NR_CHANNELS];
-	unsigned int			nb_bytes[NR_CHANNELS];
-	unsigned int			count_wr[NR_CHANNELS];
-	wait_queue_head_t		queue[NR_CHANNELS];
-	spinlock_t			lock[NR_CHANNELS];
-	unsigned int			pointer_read[NR_CHANNELS];
-	unsigned int			pointer_write[NR_CHANNELS];
-	atomic_t			open[NR_CHANNELS];
+	struct ipoctal_channel		channel[NR_CHANNELS];
 	unsigned char			write;
-	struct tty_port			tty_port[NR_CHANNELS];
 	struct tty_driver		*tty_drv;
 };
 
@@ -87,7 +91,7 @@ static struct ipoctal *ipoctal_find_board(struct tty_struct *tty)
 static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
 {
 	struct ipoctal *ipoctal;
-	int channel = tty->index;
+	struct ipoctal_channel *channel;
 
 	ipoctal = ipoctal_find_board(tty);
 
@@ -96,17 +100,18 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
 			tty->driver->major);
 		return -ENODEV;
 	}
+	channel = &ipoctal->channel[tty->index];
 
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
 			     CR_ENABLE_RX);
 	return 0;
 }
 
 static int ipoctal_open(struct tty_struct *tty, struct file *file)
 {
-	int channel = tty->index;
 	int res;
 	struct ipoctal *ipoctal;
+	struct ipoctal_channel *channel;
 
 	ipoctal = ipoctal_find_board(tty);
 
@@ -115,17 +120,18 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file)
 			tty->driver->major);
 		return -ENODEV;
 	}
+	channel = &ipoctal->channel[tty->index];
 
-	if (atomic_read(&ipoctal->open[channel]))
+	if (atomic_read(&channel->open))
 		return -EBUSY;
 
 	tty->driver_data = ipoctal;
 
-	res = tty_port_open(&ipoctal->tty_port[channel], tty, file);
+	res = tty_port_open(&channel->tty_port, tty, file);
 	if (res)
 		return res;
 
-	atomic_inc(&ipoctal->open[channel]);
+	atomic_inc(&channel->open);
 	return 0;
 }
 
@@ -141,26 +147,27 @@ static void ipoctal_reset_stats(struct ipoctal_stats *stats)
 
 static void ipoctal_free_channel(struct tty_struct *tty)
 {
-	int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel;
 
 	if (ipoctal == NULL)
 		return;
+	channel = &ipoctal->channel[tty->index];
 
-	ipoctal_reset_stats(&ipoctal->chan_stats[channel]);
-	ipoctal->pointer_read[channel] = 0;
-	ipoctal->pointer_write[channel] = 0;
-	ipoctal->nb_bytes[channel] = 0;
+	ipoctal_reset_stats(&channel->stats);
+	channel->pointer_read = 0;
+	channel->pointer_write = 0;
+	channel->nb_bytes = 0;
 }
 
 static void ipoctal_close(struct tty_struct *tty, struct file *filp)
 {
-	int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
 
-	tty_port_close(&ipoctal->tty_port[channel], tty, filp);
+	tty_port_close(&channel->tty_port, tty, filp);
 
-	if (atomic_dec_and_test(&ipoctal->open[channel]))
+	if (atomic_dec_and_test(&channel->open))
 		ipoctal_free_channel(tty);
 }
 
@@ -168,24 +175,23 @@ static int ipoctal_get_icount(struct tty_struct *tty,
 			      struct serial_icounter_struct *icount)
 {
 	struct ipoctal *ipoctal = tty->driver_data;
-	int channel = tty->index;
+	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
 
 	icount->cts = 0;
 	icount->dsr = 0;
 	icount->rng = 0;
 	icount->dcd = 0;
-	icount->rx = ipoctal->chan_stats[channel].rx;
-	icount->tx = ipoctal->chan_stats[channel].tx;
-	icount->frame = ipoctal->chan_stats[channel].framing_err;
-	icount->parity = ipoctal->chan_stats[channel].parity_err;
-	icount->brk = ipoctal->chan_stats[channel].rcv_break;
+	icount->rx = channel->stats.rx;
+	icount->tx = channel->stats.tx;
+	icount->frame = channel->stats.framing_err;
+	icount->parity = channel->stats.parity_err;
+	icount->brk = channel->stats.rcv_break;
 	return 0;
 }
 
 static int ipoctal_irq_handler(void *arg)
 {
-	unsigned int channel;
-	unsigned int block;
+	unsigned int ichannel;
 	unsigned char isr;
 	unsigned char sr;
 	unsigned char isr_tx_rdy, isr_rx_rdy;
@@ -193,14 +199,16 @@ static int ipoctal_irq_handler(void *arg)
 	unsigned char flag;
 	struct tty_struct *tty;
 	struct ipoctal *ipoctal = (struct ipoctal *) arg;
+	struct ipoctal_channel *channel;
 
 	/* Check all channels */
-	for (channel = 0; channel < NR_CHANNELS; channel++) {
+	for (ichannel = 0; ichannel < NR_CHANNELS; ichannel++) {
+		channel = &ipoctal->channel[ichannel];
 		/* If there is no client, skip the check */
-		if (!atomic_read(&ipoctal->open[channel]))
+		if (!atomic_read(&channel->open))
 			continue;
 
-		tty = tty_port_tty_get(&ipoctal->tty_port[channel]);
+		tty = tty_port_tty_get(&channel->tty_port);
 		if (!tty)
 			continue;
 
@@ -208,13 +216,12 @@ static int ipoctal_irq_handler(void *arg)
 		 * The HW is organized in pair of channels.
 		 * See which register we need to read from
 		 */
-		block = channel / 2;
 		isr = ipoctal_read_io_reg(ipoctal,
-					  &ipoctal->block_regs[block].r.isr);
+					  &channel->block_regs->r.isr);
 		sr = ipoctal_read_io_reg(ipoctal,
-					 &ipoctal->chan_regs[channel].r.sr);
+					 &channel->regs->r.sr);
 
-		if ((channel % 2) == 1) {
+		if ((ichannel % 2) == 1) {
 			isr_tx_rdy = isr & ISR_TxRDY_B;
 			isr_rx_rdy = isr & ISR_RxRDY_FFULL_B;
 		} else {
@@ -227,47 +234,47 @@ static int ipoctal_irq_handler(void *arg)
 		 */
 		if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
 		    (sr & SR_TX_EMPTY) &&
-		    (ipoctal->nb_bytes[channel] == 0)) {
+		    (channel->nb_bytes == 0)) {
 			ipoctal_write_io_reg(ipoctal,
-					     &ipoctal->chan_regs[channel].w.cr,
+					     &channel->regs->w.cr,
 					     CR_DISABLE_TX);
 			ipoctal_write_cr_cmd(ipoctal,
-					     &ipoctal->chan_regs[channel].w.cr,
+					     &channel->regs->w.cr,
 					     CR_CMD_NEGATE_RTSN);
 			ipoctal_write_io_reg(ipoctal,
-					     &ipoctal->chan_regs[channel].w.cr,
+					     &channel->regs->w.cr,
 					     CR_ENABLE_RX);
 			ipoctal->write = 1;
-			wake_up_interruptible(&ipoctal->queue[channel]);
+			wake_up_interruptible(&channel->queue);
 		}
 
 		/* RX data */
 		if (isr_rx_rdy && (sr & SR_RX_READY)) {
 			value = ipoctal_read_io_reg(ipoctal,
-						    &ipoctal->chan_regs[channel].r.rhr);
+						    &channel->regs->r.rhr);
 			flag = TTY_NORMAL;
 
 			/* Error: count statistics */
 			if (sr & SR_ERROR) {
 				ipoctal_write_cr_cmd(ipoctal,
-						     &ipoctal->chan_regs[channel].w.cr,
+						     &channel->regs->w.cr,
 						     CR_CMD_RESET_ERR_STATUS);
 
 				if (sr & SR_OVERRUN_ERROR) {
-					ipoctal->chan_stats[channel].overrun_err++;
+					channel->stats.overrun_err++;
 					/* Overrun doesn't affect the current character*/
 					tty_insert_flip_char(tty, 0, TTY_OVERRUN);
 				}
 				if (sr & SR_PARITY_ERROR) {
-					ipoctal->chan_stats[channel].parity_err++;
+					channel->stats.parity_err++;
 					flag = TTY_PARITY;
 				}
 				if (sr & SR_FRAMING_ERROR) {
-					ipoctal->chan_stats[channel].framing_err++;
+					channel->stats.framing_err++;
 					flag = TTY_FRAME;
 				}
 				if (sr & SR_RECEIVED_BREAK) {
-					ipoctal->chan_stats[channel].rcv_break++;
+					channel->stats.rcv_break++;
 					flag = TTY_BREAK;
 				}
 			}
@@ -277,30 +284,29 @@ static int ipoctal_irq_handler(void *arg)
 
 		/* TX of each character */
 		if (isr_tx_rdy && (sr & SR_TX_READY)) {
-			unsigned int *pointer_write =
-				&ipoctal->pointer_write[channel];
+			unsigned int *pointer_write = &channel->pointer_write;
 
-			if (ipoctal->nb_bytes[channel] <= 0) {
-				ipoctal->nb_bytes[channel] = 0;
+			if (channel->nb_bytes <= 0) {
+				channel->nb_bytes = 0;
 				continue;
 			}
 
-			value = ipoctal->tty_port[channel].xmit_buf[*pointer_write];
+			value = channel->tty_port.xmit_buf[*pointer_write];
 			ipoctal_write_io_reg(ipoctal,
-					     &ipoctal->chan_regs[channel].w.thr,
+					     &channel->regs->w.thr,
 					     value);
-			ipoctal->chan_stats[channel].tx++;
-			ipoctal->count_wr[channel]++;
+			channel->stats.tx++;
+			channel->count_wr++;
 			(*pointer_write)++;
 			*pointer_write = *pointer_write % PAGE_SIZE;
-			ipoctal->nb_bytes[channel]--;
+			channel->nb_bytes--;
 
-			if ((ipoctal->nb_bytes[channel] == 0) &&
-			    (waitqueue_active(&ipoctal->queue[channel]))) {
+			if ((channel->nb_bytes == 0) &&
+			    (waitqueue_active(&channel->queue))) {
 
 				if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 					ipoctal->write = 1;
-					wake_up_interruptible(&ipoctal->queue[channel]);
+					wake_up_interruptible(&channel->queue);
 				}
 			}
 		}
@@ -348,6 +354,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 	struct tty_driver *tty;
 	char name[20];
 	unsigned char board_id;
+	struct ipoctal_channel *channel;
+	union scc2698_channel __iomem *chan_regs;
+	union scc2698_block __iomem *block_regs;
 
 	res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
 						IPACK_ID_SPACE);
@@ -385,41 +394,45 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 	}
 
 	/* Save the virtual address to access the registers easily */
-	ipoctal->chan_regs =
+	chan_regs =
 		(union scc2698_channel __iomem *) ipoctal->dev->io_space.address;
-	ipoctal->block_regs =
+	block_regs =
 		(union scc2698_block __iomem *) ipoctal->dev->io_space.address;
 
 	/* Disable RX and TX before touching anything */
 	for (i = 0; i < NR_CHANNELS ; i++) {
-		ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr,
+		struct ipoctal_channel *channel = &ipoctal->channel[i];
+		channel->regs = chan_regs + i;
+		channel->block_regs = block_regs + (i >> 1);
+
+		ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
 				     CR_DISABLE_RX | CR_DISABLE_TX);
-		ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr,
+		ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 				     CR_CMD_RESET_RX);
-		ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr,
+		ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 				     CR_CMD_RESET_TX);
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[i].w.mr,
+				     &channel->regs->w.mr,
 				     MR1_CHRL_8_BITS | MR1_ERROR_CHAR |
 				     MR1_RxINT_RxRDY); /* mr1 */
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[i].w.mr,
+				     &channel->regs->w.mr,
 				     0); /* mr2 */
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[i].w.csr,
+				     &channel->regs->w.csr,
 				     TX_CLK_9600  | RX_CLK_9600);
 	}
 
 	for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->block_regs[i].w.acr,
+				     &block_regs[i].w.acr,
 				     ACR_BRG_SET2);
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->block_regs[i].w.opcr,
+				     &block_regs[i].w.opcr,
 				     OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN |
 				     OPCR_MPOb_RTSN);
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->block_regs[i].w.imr,
+				     &block_regs[i].w.imr,
 				     IMR_TxRDY_A | IMR_RxRDY_FFULL_A |
 				     IMR_DELTA_BREAK_A | IMR_TxRDY_B |
 				     IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B);
@@ -472,25 +485,26 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 	ipoctal->tty_drv = tty;
 
 	for (i = 0; i < NR_CHANNELS; i++) {
-		tty_port_init(&ipoctal->tty_port[i]);
-		tty_port_alloc_xmit_buf(&ipoctal->tty_port[i]);
-		ipoctal->tty_port[i].ops = &ipoctal_tty_port_ops;
-
-		ipoctal_reset_stats(&ipoctal->chan_stats[i]);
-		ipoctal->nb_bytes[i] = 0;
-		init_waitqueue_head(&ipoctal->queue[i]);
-
-		spin_lock_init(&ipoctal->lock[i]);
-		ipoctal->pointer_read[i] = 0;
-		ipoctal->pointer_write[i] = 0;
-		ipoctal->nb_bytes[i] = 0;
+		channel = &ipoctal->channel[i];
+		tty_port_init(&channel->tty_port);
+		tty_port_alloc_xmit_buf(&channel->tty_port);
+		channel->tty_port.ops = &ipoctal_tty_port_ops;
+
+		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;
+		channel->nb_bytes = 0;
 		tty_register_device(tty, i, NULL);
 
 		/*
 		 * Enable again the RX. TX will be enabled when
 		 * there is something to send
 		 */
-		ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr,
+		ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
 				     CR_ENABLE_RX);
 	}
 
@@ -505,23 +519,22 @@ out_unregister_id_space:
 	return res;
 }
 
-static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal,
-					    unsigned int channel,
+static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
 					    const unsigned char *buf,
 					    int count)
 {
 	unsigned long flags;
 	int i;
-	unsigned int *pointer_read = &ipoctal->pointer_read[channel];
+	unsigned int *pointer_read = &channel->pointer_read;
 
 	/* Copy the bytes from the user buffer to the internal one */
 	for (i = 0; i < count; i++) {
-		if (i <= (PAGE_SIZE - ipoctal->nb_bytes[channel])) {
-			spin_lock_irqsave(&ipoctal->lock[channel], flags);
-			ipoctal->tty_port[channel].xmit_buf[*pointer_read] = buf[i];
+		if (i <= (PAGE_SIZE - channel->nb_bytes)) {
+			spin_lock_irqsave(&channel->lock, flags);
+			channel->tty_port.xmit_buf[*pointer_read] = buf[i];
 			*pointer_read = (*pointer_read + 1) % PAGE_SIZE;
-			ipoctal->nb_bytes[channel]++;
-			spin_unlock_irqrestore(&ipoctal->lock[channel], flags);
+			channel->nb_bytes++;
+			spin_unlock_irqrestore(&channel->lock, flags);
 		} else {
 			break;
 		}
@@ -529,21 +542,22 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal,
 	return i;
 }
 
-static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
+static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel,
 			 const unsigned char *buf, int count)
 {
-	ipoctal->nb_bytes[channel] = 0;
-	ipoctal->count_wr[channel] = 0;
+	struct ipoctal_channel *channel = &ipoctal->channel[ichannel];
+	channel->nb_bytes = 0;
+	channel->count_wr = 0;
 
-	ipoctal_copy_write_buffer(ipoctal, channel, buf, count);
+	ipoctal_copy_write_buffer(channel, buf, count);
 
 	/* As the IP-OCTAL 485 only supports half duplex, do it manually */
 	if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 		ipoctal_write_io_reg(ipoctal,
-				     &ipoctal->chan_regs[channel].w.cr,
+				     &channel->regs->w.cr,
 				     CR_DISABLE_RX);
 		ipoctal_write_cr_cmd(ipoctal,
-				     &ipoctal->chan_regs[channel].w.cr,
+				     &channel->regs->w.cr,
 				     CR_CMD_ASSERT_RTSN);
 	}
 
@@ -552,40 +566,39 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
 	 * operations
 	 */
 	ipoctal_write_io_reg(ipoctal,
-			     &ipoctal->chan_regs[channel].w.cr,
+			     &channel->regs->w.cr,
 			     CR_ENABLE_TX);
-	wait_event_interruptible(ipoctal->queue[channel], ipoctal->write);
+	wait_event_interruptible(channel->queue, ipoctal->write);
 	ipoctal_write_io_reg(ipoctal,
-			     &ipoctal->chan_regs[channel].w.cr,
+			     &channel->regs->w.cr,
 			     CR_DISABLE_TX);
 
 	ipoctal->write = 0;
-	return ipoctal->count_wr[channel];
+	return channel->count_wr;
 }
 
 static int ipoctal_write_tty(struct tty_struct *tty,
 			     const unsigned char *buf, int count)
 {
-	unsigned int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
 
-	return ipoctal_write(ipoctal, channel, buf, count);
+	return ipoctal_write(ipoctal, tty->index, buf, count);
 }
 
 static int ipoctal_write_room(struct tty_struct *tty)
 {
-	int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
 
-	return PAGE_SIZE - ipoctal->nb_bytes[channel];
+	return PAGE_SIZE - channel->nb_bytes;
 }
 
 static int ipoctal_chars_in_buffer(struct tty_struct *tty)
 {
-	int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
 
-	return ipoctal->nb_bytes[channel];
+	return channel->nb_bytes;
 }
 
 static void ipoctal_set_termios(struct tty_struct *tty,
@@ -595,22 +608,22 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	unsigned char mr1 = 0;
 	unsigned char mr2 = 0;
 	unsigned char csr = 0;
-	unsigned int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
 	speed_t baud;
 
 	cflag = tty->termios->c_cflag;
 
 	/* Disable and reset everything before change the setup */
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
 			     CR_DISABLE_RX | CR_DISABLE_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_RX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_ERR_STATUS);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_MR);
 
 	/* Set Bits per chars */
@@ -724,45 +737,45 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	mr1 |= MR1_RxINT_RxRDY;
 
 	/* Write the control registers */
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr1);
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr2);
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.csr, csr);
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr1);
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr2);
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.csr, csr);
 
 	/* Enable again the RX */
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
 			     CR_ENABLE_RX);
 }
 
 static void ipoctal_hangup(struct tty_struct *tty)
 {
 	unsigned long flags;
-	int channel = tty->index;
 	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
 
 	if (ipoctal == NULL)
 		return;
 
-	spin_lock_irqsave(&ipoctal->lock[channel], flags);
-	ipoctal->nb_bytes[channel] = 0;
-	ipoctal->pointer_read[channel] = 0;
-	ipoctal->pointer_write[channel] = 0;
-	spin_unlock_irqrestore(&ipoctal->lock[channel], flags);
+	spin_lock_irqsave(&channel->lock, flags);
+	channel->nb_bytes = 0;
+	channel->pointer_read = 0;
+	channel->pointer_write = 0;
+	spin_unlock_irqrestore(&channel->lock, flags);
 
-	tty_port_hangup(&ipoctal->tty_port[channel]);
+	tty_port_hangup(&channel->tty_port);
 
-	ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
 			     CR_DISABLE_RX | CR_DISABLE_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_RX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_TX);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_ERR_STATUS);
-	ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr,
+	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
 			     CR_CMD_RESET_MR);
 
-	clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags);
-	wake_up_interruptible(&ipoctal->tty_port[channel].open_wait);
+	clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
+	wake_up_interruptible(&channel->tty_port.open_wait);
 }
 
 static const struct tty_operations ipoctal_fops = {
@@ -806,8 +819,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
 	ipoctal->dev->bus->ops->free_irq(ipoctal->dev);
 
 	for (i = 0; i < NR_CHANNELS; i++) {
+		struct ipoctal_channel *channel = &ipoctal->channel[i];
 		tty_unregister_device(ipoctal->tty_drv, i);
-		tty_port_free_xmit_buf(&ipoctal->tty_port[i]);
+		tty_port_free_xmit_buf(&channel->tty_port);
 	}
 
 	tty_unregister_driver(ipoctal->tty_drv);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 05/24] Staging: ipack/devices/ipoctal: Directly use ioread/iowrite function.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (2 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 04/24] Staging: ipack/devices/ipoctal: split ipoctal_channel from ipoctal Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 06/24] Staging: ipack/devices/ipoctal: put ipoctal_channel into tty->driver_data Samuel Iglesias Gonsalvez
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |  151 +++++++++----------------------
 1 file changed, 41 insertions(+), 110 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 9ab0e80..c963456 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -56,26 +56,6 @@ struct ipoctal {
 /* Linked list to save the registered devices */
 static LIST_HEAD(ipoctal_list);
 
-static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal,
-					u8 __iomem *dest,
-					u8 value)
-{
-	iowrite8(value, dest);
-}
-
-static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal,
-					u8 __iomem *dest,
-					u8 value)
-{
-	ipoctal_write_io_reg(ipoctal, dest, value);
-}
-
-static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal,
-						u8 __iomem *src)
-{
-	return ioread8(src);
-}
-
 static struct ipoctal *ipoctal_find_board(struct tty_struct *tty)
 {
 	struct ipoctal *p;
@@ -102,8 +82,7 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
 	}
 	channel = &ipoctal->channel[tty->index];
 
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
-			     CR_ENABLE_RX);
+	iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
 	return 0;
 }
 
@@ -216,10 +195,8 @@ static int ipoctal_irq_handler(void *arg)
 		 * The HW is organized in pair of channels.
 		 * See which register we need to read from
 		 */
-		isr = ipoctal_read_io_reg(ipoctal,
-					  &channel->block_regs->r.isr);
-		sr = ipoctal_read_io_reg(ipoctal,
-					 &channel->regs->r.sr);
+		isr = ioread8(&channel->block_regs->r.isr);
+		sr = ioread8(&channel->regs->r.sr);
 
 		if ((ichannel % 2) == 1) {
 			isr_tx_rdy = isr & ISR_TxRDY_B;
@@ -235,30 +212,21 @@ static int ipoctal_irq_handler(void *arg)
 		if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
 		    (sr & SR_TX_EMPTY) &&
 		    (channel->nb_bytes == 0)) {
-			ipoctal_write_io_reg(ipoctal,
-					     &channel->regs->w.cr,
-					     CR_DISABLE_TX);
-			ipoctal_write_cr_cmd(ipoctal,
-					     &channel->regs->w.cr,
-					     CR_CMD_NEGATE_RTSN);
-			ipoctal_write_io_reg(ipoctal,
-					     &channel->regs->w.cr,
-					     CR_ENABLE_RX);
+			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);
 			ipoctal->write = 1;
 			wake_up_interruptible(&channel->queue);
 		}
 
 		/* RX data */
 		if (isr_rx_rdy && (sr & SR_RX_READY)) {
-			value = ipoctal_read_io_reg(ipoctal,
-						    &channel->regs->r.rhr);
+			value = ioread8(&channel->regs->r.rhr);
 			flag = TTY_NORMAL;
 
 			/* Error: count statistics */
 			if (sr & SR_ERROR) {
-				ipoctal_write_cr_cmd(ipoctal,
-						     &channel->regs->w.cr,
-						     CR_CMD_RESET_ERR_STATUS);
+				iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
 
 				if (sr & SR_OVERRUN_ERROR) {
 					channel->stats.overrun_err++;
@@ -292,9 +260,7 @@ static int ipoctal_irq_handler(void *arg)
 			}
 
 			value = channel->tty_port.xmit_buf[*pointer_write];
-			ipoctal_write_io_reg(ipoctal,
-					     &channel->regs->w.thr,
-					     value);
+			iowrite8(value, &channel->regs->w.thr);
 			channel->stats.tx++;
 			channel->count_wr++;
 			(*pointer_write)++;
@@ -405,37 +371,22 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 		channel->regs = chan_regs + i;
 		channel->block_regs = block_regs + (i >> 1);
 
-		ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
-				     CR_DISABLE_RX | CR_DISABLE_TX);
-		ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-				     CR_CMD_RESET_RX);
-		ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-				     CR_CMD_RESET_TX);
-		ipoctal_write_io_reg(ipoctal,
-				     &channel->regs->w.mr,
-				     MR1_CHRL_8_BITS | MR1_ERROR_CHAR |
-				     MR1_RxINT_RxRDY); /* mr1 */
-		ipoctal_write_io_reg(ipoctal,
-				     &channel->regs->w.mr,
-				     0); /* mr2 */
-		ipoctal_write_io_reg(ipoctal,
-				     &channel->regs->w.csr,
-				     TX_CLK_9600  | RX_CLK_9600);
+		iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
+		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,
+			 &channel->regs->w.mr); /* mr1 */
+		iowrite8(0, &channel->regs->w.mr); /* mr2 */
+		iowrite8(TX_CLK_9600  | RX_CLK_9600, &channel->regs->w.csr);
 	}
 
 	for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
-		ipoctal_write_io_reg(ipoctal,
-				     &block_regs[i].w.acr,
-				     ACR_BRG_SET2);
-		ipoctal_write_io_reg(ipoctal,
-				     &block_regs[i].w.opcr,
-				     OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN |
-				     OPCR_MPOb_RTSN);
-		ipoctal_write_io_reg(ipoctal,
-				     &block_regs[i].w.imr,
-				     IMR_TxRDY_A | IMR_RxRDY_FFULL_A |
-				     IMR_DELTA_BREAK_A | IMR_TxRDY_B |
-				     IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B);
+		iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr);
+		iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN,
+			 &block_regs[i].w.opcr);
+		iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A |
+			 IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B,
+			 &block_regs[i].w.imr);
 	}
 
 	/*
@@ -504,8 +455,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 		 * Enable again the RX. TX will be enabled when
 		 * there is something to send
 		 */
-		ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
-				     CR_ENABLE_RX);
+		iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
 	}
 
 	return 0;
@@ -553,25 +503,17 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel,
 
 	/* As the IP-OCTAL 485 only supports half duplex, do it manually */
 	if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
-		ipoctal_write_io_reg(ipoctal,
-				     &channel->regs->w.cr,
-				     CR_DISABLE_RX);
-		ipoctal_write_cr_cmd(ipoctal,
-				     &channel->regs->w.cr,
-				     CR_CMD_ASSERT_RTSN);
+		iowrite8(CR_DISABLE_RX, &channel->regs->w.cr);
+		iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr);
 	}
 
 	/*
 	 * Send a packet and then disable TX to avoid failure after several send
 	 * operations
 	 */
-	ipoctal_write_io_reg(ipoctal,
-			     &channel->regs->w.cr,
-			     CR_ENABLE_TX);
+	iowrite8(CR_ENABLE_TX, &channel->regs->w.cr);
 	wait_event_interruptible(channel->queue, ipoctal->write);
-	ipoctal_write_io_reg(ipoctal,
-			     &channel->regs->w.cr,
-			     CR_DISABLE_TX);
+	iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
 
 	ipoctal->write = 0;
 	return channel->count_wr;
@@ -615,16 +557,11 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	cflag = tty->termios->c_cflag;
 
 	/* Disable and reset everything before change the setup */
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
-			     CR_DISABLE_RX | CR_DISABLE_TX);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_RX);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_TX);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_ERR_STATUS);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_MR);
+	iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
+	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);
 
 	/* Set Bits per chars */
 	switch (cflag & CSIZE) {
@@ -737,13 +674,12 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	mr1 |= MR1_RxINT_RxRDY;
 
 	/* Write the control registers */
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr1);
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr2);
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.csr, csr);
+	iowrite8(mr1, &channel->regs->w.mr);
+	iowrite8(mr2, &channel->regs->w.mr);
+	iowrite8(csr, &channel->regs->w.csr);
 
 	/* Enable again the RX */
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
-			     CR_ENABLE_RX);
+	iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
 }
 
 static void ipoctal_hangup(struct tty_struct *tty)
@@ -763,16 +699,11 @@ static void ipoctal_hangup(struct tty_struct *tty)
 
 	tty_port_hangup(&channel->tty_port);
 
-	ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
-			     CR_DISABLE_RX | CR_DISABLE_TX);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_RX);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_TX);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_ERR_STATUS);
-	ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
-			     CR_CMD_RESET_MR);
+	iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
+	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);
 	wake_up_interruptible(&channel->tty_port.open_wait);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 06/24] Staging: ipack/devices/ipoctal: put ipoctal_channel into tty->driver_data.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (3 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 05/24] Staging: ipack/devices/ipoctal: Directly use ioread/iowrite function Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel Samuel Iglesias Gonsalvez
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Each tty's driver_data is now pointing to the channel it is talking to.  struct
ipoctal_channel contains all the information the callbacks require to do their
work.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   52 +++++++++++++------------------
 1 file changed, 21 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index c963456..70dc7a2 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -42,6 +42,8 @@ struct ipoctal_channel {
 	struct tty_port			tty_port;
 	union scc2698_channel __iomem	*regs;
 	union scc2698_block __iomem	*block_regs;
+	unsigned int			board_id;
+	unsigned char			*board_write;
 };
 
 struct ipoctal {
@@ -104,7 +106,7 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file)
 	if (atomic_read(&channel->open))
 		return -EBUSY;
 
-	tty->driver_data = ipoctal;
+	tty->driver_data = channel;
 
 	res = tty_port_open(&channel->tty_port, tty, file);
 	if (res)
@@ -124,15 +126,8 @@ static void ipoctal_reset_stats(struct ipoctal_stats *stats)
 	stats->parity_err = 0;
 }
 
-static void ipoctal_free_channel(struct tty_struct *tty)
+static void ipoctal_free_channel(struct ipoctal_channel *channel)
 {
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel;
-
-	if (ipoctal == NULL)
-		return;
-	channel = &ipoctal->channel[tty->index];
-
 	ipoctal_reset_stats(&channel->stats);
 	channel->pointer_read = 0;
 	channel->pointer_write = 0;
@@ -141,20 +136,18 @@ static void ipoctal_free_channel(struct tty_struct *tty)
 
 static void ipoctal_close(struct tty_struct *tty, struct file *filp)
 {
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
+	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(tty);
+		ipoctal_free_channel(channel);
 }
 
 static int ipoctal_get_icount(struct tty_struct *tty,
 			      struct serial_icounter_struct *icount)
 {
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
+	struct ipoctal_channel *channel = tty->driver_data;
 
 	icount->cts = 0;
 	icount->dsr = 0;
@@ -370,6 +363,8 @@ 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;
 
 		iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
 		iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
@@ -492,17 +487,16 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
 	return i;
 }
 
-static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel,
+static int ipoctal_write(struct ipoctal_channel *channel,
 			 const unsigned char *buf, int count)
 {
-	struct ipoctal_channel *channel = &ipoctal->channel[ichannel];
 	channel->nb_bytes = 0;
 	channel->count_wr = 0;
 
 	ipoctal_copy_write_buffer(channel, buf, count);
 
 	/* As the IP-OCTAL 485 only supports half duplex, do it manually */
-	if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
+	if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 		iowrite8(CR_DISABLE_RX, &channel->regs->w.cr);
 		iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr);
 	}
@@ -512,33 +506,31 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel,
 	 * operations
 	 */
 	iowrite8(CR_ENABLE_TX, &channel->regs->w.cr);
-	wait_event_interruptible(channel->queue, ipoctal->write);
+	wait_event_interruptible(channel->queue, *channel->board_write);
 	iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
 
-	ipoctal->write = 0;
+	*channel->board_write = 0;
 	return channel->count_wr;
 }
 
 static int ipoctal_write_tty(struct tty_struct *tty,
 			     const unsigned char *buf, int count)
 {
-	struct ipoctal *ipoctal = tty->driver_data;
+	struct ipoctal_channel *channel = tty->driver_data;
 
-	return ipoctal_write(ipoctal, tty->index, buf, count);
+	return ipoctal_write(channel, buf, count);
 }
 
 static int ipoctal_write_room(struct tty_struct *tty)
 {
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
+	struct ipoctal_channel *channel = tty->driver_data;
 
 	return PAGE_SIZE - channel->nb_bytes;
 }
 
 static int ipoctal_chars_in_buffer(struct tty_struct *tty)
 {
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
+	struct ipoctal_channel *channel = tty->driver_data;
 
 	return channel->nb_bytes;
 }
@@ -550,8 +542,7 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	unsigned char mr1 = 0;
 	unsigned char mr2 = 0;
 	unsigned char csr = 0;
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
+	struct ipoctal_channel *channel = tty->driver_data;
 	speed_t baud;
 
 	cflag = tty->termios->c_cflag;
@@ -598,7 +589,7 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 		mr2 |= MR2_STOP_BITS_LENGTH_1;
 
 	/* Set the flow control */
-	switch (ipoctal->board_id) {
+	switch (channel->board_id) {
 	case IPACK1_DEVICE_ID_SBS_OCTAL_232:
 		if (cflag & CRTSCTS) {
 			mr1 |= MR1_RxRTS_CONTROL_ON;
@@ -685,10 +676,9 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 static void ipoctal_hangup(struct tty_struct *tty)
 {
 	unsigned long flags;
-	struct ipoctal *ipoctal = tty->driver_data;
-	struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
+	struct ipoctal_channel *channel = tty->driver_data;
 
-	if (ipoctal == NULL)
+	if (channel == NULL)
 		return;
 
 	spin_lock_irqsave(&channel->lock, flags);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (4 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 06/24] Staging: ipack/devices/ipoctal: put ipoctal_channel into tty->driver_data Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-13 17:43   ` Dan Carpenter
  2012-09-12 12:55 ` [PATCH 08/24] Staging: ipack/devices/ipoctal: Split interrupt service routine Samuel Iglesias Gonsalvez
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

This way interrupt handling becomes independent of the channel number.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 70dc7a2..56e810b 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -44,6 +44,8 @@ struct ipoctal_channel {
 	union scc2698_block __iomem	*block_regs;
 	unsigned int			board_id;
 	unsigned char			*board_write;
+	u8				isr_rx_rdy_mask;
+	u8				isr_tx_rdy_mask;
 };
 
 struct ipoctal {
@@ -166,7 +168,6 @@ static int ipoctal_irq_handler(void *arg)
 	unsigned int ichannel;
 	unsigned char isr;
 	unsigned char sr;
-	unsigned char isr_tx_rdy, isr_rx_rdy;
 	unsigned char value;
 	unsigned char flag;
 	struct tty_struct *tty;
@@ -191,14 +192,6 @@ static int ipoctal_irq_handler(void *arg)
 		isr = ioread8(&channel->block_regs->r.isr);
 		sr = ioread8(&channel->regs->r.sr);
 
-		if ((ichannel % 2) == 1) {
-			isr_tx_rdy = isr & ISR_TxRDY_B;
-			isr_rx_rdy = isr & ISR_RxRDY_FFULL_B;
-		} else {
-			isr_tx_rdy = isr & ISR_TxRDY_A;
-			isr_rx_rdy = isr & ISR_RxRDY_FFULL_A;
-		}
-
 		/* In case of RS-485, change from TX to RX when finishing TX.
 		 * Half-duplex.
 		 */
@@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg)
 		}
 
 		/* RX data */
-		if (isr_rx_rdy && (sr & SR_RX_READY)) {
+		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
 			value = ioread8(&channel->regs->r.rhr);
 			flag = TTY_NORMAL;
 
@@ -244,7 +237,7 @@ static int ipoctal_irq_handler(void *arg)
 		}
 
 		/* TX of each character */
-		if (isr_tx_rdy && (sr & SR_TX_READY)) {
+		if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) {
 			unsigned int *pointer_write = &channel->pointer_write;
 
 			if (channel->nb_bytes <= 0) {
@@ -365,6 +358,13 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 		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;
+			channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B;
+		} else {
+			channel->isr_tx_rdy_mask = ISR_TxRDY_A;
+			channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A;
+		}
 
 		iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
 		iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 08/24] Staging: ipack/devices/ipoctal: Split interrupt service routine.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (5 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 09/24] Staging: ipack/devices/ipoctal: remove superfluous function Samuel Iglesias Gonsalvez
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Split the IRQ service routing in TX part and RX part.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |  188 ++++++++++++++++---------------
 1 file changed, 97 insertions(+), 91 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 56e810b..e0be660 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -163,109 +163,115 @@ static int ipoctal_get_icount(struct tty_struct *tty,
 	return 0;
 }
 
-static int ipoctal_irq_handler(void *arg)
+static void ipoctal_irq_rx(struct ipoctal_channel *channel,
+			   struct tty_struct *tty, u8 sr)
+{
+	unsigned char value = ioread8(&channel->regs->r.rhr);
+	unsigned char flag = TTY_NORMAL;
+
+	/* Error: count statistics */
+	if (sr & SR_ERROR) {
+		iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
+
+		if (sr & SR_OVERRUN_ERROR) {
+			channel->stats.overrun_err++;
+			/* Overrun doesn't affect the current character*/
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+		}
+		if (sr & SR_PARITY_ERROR) {
+			channel->stats.parity_err++;
+			flag = TTY_PARITY;
+		}
+		if (sr & SR_FRAMING_ERROR) {
+			channel->stats.framing_err++;
+			flag = TTY_FRAME;
+		}
+		if (sr & SR_RECEIVED_BREAK) {
+			channel->stats.rcv_break++;
+			flag = TTY_BREAK;
+		}
+	}
+
+	tty_insert_flip_char(tty, value, flag);
+}
+
+static void ipoctal_irq_tx(struct ipoctal_channel *channel)
 {
-	unsigned int ichannel;
-	unsigned char isr;
-	unsigned char sr;
 	unsigned char value;
-	unsigned char flag;
-	struct tty_struct *tty;
-	struct ipoctal *ipoctal = (struct ipoctal *) arg;
-	struct ipoctal_channel *channel;
+	unsigned int *pointer_write = &channel->pointer_write;
 
-	/* Check all channels */
-	for (ichannel = 0; ichannel < NR_CHANNELS; ichannel++) {
-		channel = &ipoctal->channel[ichannel];
-		/* If there is no client, skip the check */
-		if (!atomic_read(&channel->open))
-			continue;
+	if (channel->nb_bytes <= 0) {
+		channel->nb_bytes = 0;
+		return;
+	}
 
-		tty = tty_port_tty_get(&channel->tty_port);
-		if (!tty)
-			continue;
+	value = channel->tty_port.xmit_buf[*pointer_write];
+	iowrite8(value, &channel->regs->w.thr);
+	channel->stats.tx++;
+	channel->count_wr++;
+	(*pointer_write)++;
+	*pointer_write = *pointer_write % PAGE_SIZE;
+	channel->nb_bytes--;
 
-		/*
-		 * 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);
+	if ((channel->nb_bytes == 0) &&
+	    (waitqueue_active(&channel->queue))) {
 
-		/* In case of RS-485, change from TX to RX when finishing TX.
-		 * Half-duplex.
-		 */
-		if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
-		    (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);
-			ipoctal->write = 1;
+		if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
+			*channel->board_write = 1;
 			wake_up_interruptible(&channel->queue);
 		}
+	}
+}
 
-		/* RX data */
-		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
-			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);
-
-				if (sr & SR_OVERRUN_ERROR) {
-					channel->stats.overrun_err++;
-					/* Overrun doesn't affect the current character*/
-					tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-				}
-				if (sr & SR_PARITY_ERROR) {
-					channel->stats.parity_err++;
-					flag = TTY_PARITY;
-				}
-				if (sr & SR_FRAMING_ERROR) {
-					channel->stats.framing_err++;
-					flag = TTY_FRAME;
-				}
-				if (sr & SR_RECEIVED_BREAK) {
-					channel->stats.rcv_break++;
-					flag = TTY_BREAK;
-				}
-			}
-
-			tty_insert_flip_char(tty, value, flag);
-		}
+static void ipoctal_irq_channel(struct ipoctal_channel *channel)
+{
+	u8 isr, sr;
+	struct tty_struct *tty;
 
-		/* TX of each character */
-		if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) {
-			unsigned int *pointer_write = &channel->pointer_write;
-
-			if (channel->nb_bytes <= 0) {
-				channel->nb_bytes = 0;
-				continue;
-			}
-
-			value = channel->tty_port.xmit_buf[*pointer_write];
-			iowrite8(value, &channel->regs->w.thr);
-			channel->stats.tx++;
-			channel->count_wr++;
-			(*pointer_write)++;
-			*pointer_write = *pointer_write % PAGE_SIZE;
-			channel->nb_bytes--;
-
-			if ((channel->nb_bytes == 0) &&
-			    (waitqueue_active(&channel->queue))) {
-
-				if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
-					ipoctal->write = 1;
-					wake_up_interruptible(&channel->queue);
-				}
-			}
-		}
+	/* If there is no client, skip the check */
+	if (!atomic_read(&channel->open))
+		return;
 
-		tty_flip_buffer_push(tty);
-		tty_kref_put(tty);
+	tty = tty_port_tty_get(&channel->tty_port);
+	if (!tty)
+		return;
+	/* 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)) {
+		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);
 	}
+
+	/* RX data */
+	if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY))
+		ipoctal_irq_rx(channel, tty, sr);
+
+	/* TX of each character */
+	if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
+		ipoctal_irq_tx(channel);
+
+	tty_flip_buffer_push(tty);
+	tty_kref_put(tty);
+}
+
+static int 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]);
+
 	return IRQ_HANDLED;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 09/24] Staging: ipack/devices/ipoctal: remove superfluous function.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (6 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 08/24] Staging: ipack/devices/ipoctal: Split interrupt service routine Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 10/24] Staging: ipack/bridges/tpci200: RCU protect slot_irq pointers Samuel Iglesias Gonsalvez
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

ipoctal_write_tty and ipoctal_write are merged.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index e0be660..4cc9173 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -493,9 +493,11 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
 	return i;
 }
 
-static int ipoctal_write(struct ipoctal_channel *channel,
-			 const unsigned char *buf, int count)
+static int ipoctal_write_tty(struct tty_struct *tty,
+			     const unsigned char *buf, int count)
 {
+	struct ipoctal_channel *channel = tty->driver_data;
+
 	channel->nb_bytes = 0;
 	channel->count_wr = 0;
 
@@ -519,14 +521,6 @@ static int ipoctal_write(struct ipoctal_channel *channel,
 	return channel->count_wr;
 }
 
-static int ipoctal_write_tty(struct tty_struct *tty,
-			     const unsigned char *buf, int count)
-{
-	struct ipoctal_channel *channel = tty->driver_data;
-
-	return ipoctal_write(channel, buf, count);
-}
-
 static int ipoctal_write_room(struct tty_struct *tty)
 {
 	struct ipoctal_channel *channel = tty->driver_data;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 10/24] Staging: ipack/bridges/tpci200: RCU protect slot_irq pointers.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (7 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 09/24] Staging: ipack/devices/ipoctal: remove superfluous function Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 11/24] Staging: ipack/bridges/tpci200: Protect device registers with spinlock Samuel Iglesias Gonsalvez
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

In tpci200_request_irq as well as tpci200_free_irq we set and unset the
pointer to struct slot_irq.  This pointer is accessed in
tpci200_interrupt.  To ensure that the pointer is not freed after it has
been fetched in tpci200_interrupt() it is now protected through RCU.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 24e2a11..9ce577a 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -132,10 +132,11 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 
 	if (status_reg & TPCI200_SLOT_INT_MASK) {
 		/* callback to the IRQ handler for the corresponding slot */
+		rcu_read_lock();
 		for (i = 0; i < TPCI200_NB_SLOT; i++) {
 			if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))))
 				continue;
-			slot_irq = tpci200->slots[i].irq;
+			slot_irq = rcu_dereference(tpci200->slots[i].irq);
 			if (slot_irq) {
 				ret = tpci200_slot_irq(slot_irq);
 			} else {
@@ -147,6 +148,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 					TPCI200_INT0_EN | TPCI200_INT1_EN);
 			}
 		}
+		rcu_read_unlock();
 	}
 
 	return ret;
@@ -303,9 +305,9 @@ static int tpci200_free_irq(struct ipack_device *dev)
 
 	__tpci200_free_irq(tpci200, dev);
 	slot_irq = tpci200->slots[dev->slot].irq;
-	tpci200->slots[dev->slot].irq = NULL;
+	RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
+	synchronize_rcu();
 	kfree(slot_irq);
-
 	mutex_unlock(&tpci200->mutex);
 	return 0;
 }
@@ -490,7 +492,7 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector,
 	slot_irq->arg = arg;
 	slot_irq->holder = dev;
 
-	tpci200->slots[dev->slot].irq = slot_irq;
+	rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
 	res = __tpci200_request_irq(tpci200, dev);
 
 out_unlock:
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 11/24] Staging: ipack/bridges/tpci200: Protect device registers with spinlock.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (8 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 10/24] Staging: ipack/bridges/tpci200: RCU protect slot_irq pointers Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 12/24] Staging: ipack/bridges/tpci200: Clean up interrupt handling Samuel Iglesias Gonsalvez
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Some of the device registers are accessed from both interrupt and
non-interrupt context.  To ensure proper read-modify-write modification
of these registers we can not use the  "global" tpci200 mutex.  Instead
a spin-lock is used.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   33 +++++++++++++------------------
 drivers/staging/ipack/bridges/tpci200.h |    1 +
 2 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 9ce577a..b1ddbe3 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -53,30 +53,22 @@ static struct tpci200_board *check_slot(struct ipack_device *dev)
 	return tpci200;
 }
 
-static void __tpci200_clear_mask(__le16 __iomem *addr, u16 mask)
-{
-	iowrite16(ioread16(addr) & (~mask), addr);
-}
-
 static void tpci200_clear_mask(struct tpci200_board *tpci200,
 			       __le16 __iomem *addr, u16 mask)
 {
-	mutex_lock(&tpci200->mutex);
-	__tpci200_clear_mask(addr, mask);
-	mutex_unlock(&tpci200->mutex);
-}
-
-static void __tpci200_set_mask(__le16 __iomem *addr, u16 mask)
-{
-	iowrite16(ioread16(addr) | mask, addr);
+	unsigned long flags;
+	spin_lock_irqsave(&tpci200->regs_lock, flags);
+	iowrite16(ioread16(addr) & (~mask), addr);
+	spin_unlock_irqrestore(&tpci200->regs_lock, flags);
 }
 
 static void tpci200_set_mask(struct tpci200_board *tpci200,
 			     __le16 __iomem *addr, u16 mask)
 {
-	mutex_lock(&tpci200->mutex);
-	__tpci200_set_mask(addr, mask);
-	mutex_unlock(&tpci200->mutex);
+	unsigned long flags;
+	spin_lock_irqsave(&tpci200->regs_lock, flags);
+	iowrite16(ioread16(addr) | mask, addr);
+	spin_unlock_irqrestore(&tpci200->regs_lock, flags);
 }
 
 static void tpci200_unregister(struct tpci200_board *tpci200)
@@ -143,7 +135,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 				dev_info(&tpci200->info->pdev->dev,
 					 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
 					 tpci200->number, i);
-				__tpci200_clear_mask(
+				tpci200_clear_mask(tpci200,
 					&tpci200->info->interface_regs->control[i],
 					TPCI200_INT0_EN | TPCI200_INT1_EN);
 			}
@@ -213,6 +205,9 @@ static int tpci200_register(struct tpci200_board *tpci200)
 					   TPCI200_MEM8_SPACE_BAR),
 			TPCI200_MEM8_SIZE);
 
+	/* Initialize lock that protects interface_regs */
+	spin_lock_init(&tpci200->regs_lock);
+
 	ioidint_base = pci_resource_start(tpci200->info->pdev,
 					  TPCI200_IO_ID_INT_SPACES_BAR);
 	mem_base = pci_resource_start(tpci200->info->pdev,
@@ -272,7 +267,7 @@ out_disable_pci:
 static int __tpci200_request_irq(struct tpci200_board *tpci200,
 				 struct ipack_device *dev)
 {
-	__tpci200_set_mask(
+	tpci200_set_mask(tpci200,
 			&tpci200->info->interface_regs->control[dev->slot],
 			TPCI200_INT0_EN | TPCI200_INT1_EN);
 	return 0;
@@ -281,7 +276,7 @@ static int __tpci200_request_irq(struct tpci200_board *tpci200,
 static void __tpci200_free_irq(struct tpci200_board *tpci200,
 			       struct ipack_device *dev)
 {
-	__tpci200_clear_mask(
+	tpci200_clear_mask(tpci200,
 			&tpci200->info->interface_regs->control[dev->slot],
 			TPCI200_INT0_EN | TPCI200_INT1_EN);
 }
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 75a5dcc..b8e9826 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -163,6 +163,7 @@ struct tpci200_infos {
 struct tpci200_board {
 	unsigned int		number;
 	struct mutex		mutex;
+	spinlock_t		regs_lock;
 	struct tpci200_slot	*slots;
 	struct tpci200_infos	*info;
 };
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 12/24] Staging: ipack/bridges/tpci200: Clean up interrupt handling.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (9 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 11/24] Staging: ipack/bridges/tpci200: Protect device registers with spinlock Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 13/24] Staging: ipack/bridges/tpci200: Cleanup in tpci200_slot_irq() and tpci200_interrupt() Samuel Iglesias Gonsalvez
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Previously the return value from tpci200_interrupt was not quite correct
if a slot had caused an interrupt but no handler was instellalled:
IRQ_NONE was returned.  However in this case we react to the interrupt
by disabling the IPack device interrupt.

Basically there are two cases the code now distinguishes:
 - The tpci200 has raised an interrupt.  We handle it and return
   IRQ_HANDLED.
 - Our device did not raise an interrupt. We return IRQ_NONE.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index b1ddbe3..0cbaf3a 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -116,7 +116,6 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 	struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
 	int i;
 	unsigned short status_reg;
-	irqreturn_t ret = IRQ_NONE;
 	struct slot_irq *slot_irq;
 
 	/* Read status register */
@@ -130,7 +129,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 				continue;
 			slot_irq = rcu_dereference(tpci200->slots[i].irq);
 			if (slot_irq) {
-				ret = tpci200_slot_irq(slot_irq);
+				tpci200_slot_irq(slot_irq);
 			} else {
 				dev_info(&tpci200->info->pdev->dev,
 					 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
@@ -141,9 +140,11 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 			}
 		}
 		rcu_read_unlock();
-	}
 
-	return ret;
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
 }
 
 static int tpci200_register(struct tpci200_board *tpci200)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 13/24] Staging: ipack/bridges/tpci200: Cleanup in tpci200_slot_irq() and tpci200_interrupt()
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (10 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 12/24] Staging: ipack/bridges/tpci200: Clean up interrupt handling Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 14/24] Staging: ipack/bridges/tpci200: More cleanups Samuel Iglesias Gonsalvez
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Minor cleanup.  No functional changes.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   58 +++++++++++++++++--------------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 0cbaf3a..4eaa2aa 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -102,9 +102,13 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
 
 static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
 {
-	irqreturn_t ret = slot_irq->handler(slot_irq->arg);
+	irqreturn_t ret;
 
-	/* Dummy reads */
+	if (!slot_irq)
+		return -ENODEV;
+	ret = slot_irq->handler(slot_irq->arg);
+
+	/* Clear the IPack device interrupt */
 	readw(slot_irq->holder->io_space.address + 0xC0);
 	readw(slot_irq->holder->io_space.address + 0xC2);
 
@@ -114,37 +118,37 @@ static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
 static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 {
 	struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
-	int i;
-	unsigned short status_reg;
 	struct slot_irq *slot_irq;
+	irqreturn_t ret;
+	u16 status_reg;
+	int i;
 
 	/* Read status register */
-	status_reg = readw(&tpci200->info->interface_regs->status);
-
-	if (status_reg & TPCI200_SLOT_INT_MASK) {
-		/* callback to the IRQ handler for the corresponding slot */
-		rcu_read_lock();
-		for (i = 0; i < TPCI200_NB_SLOT; i++) {
-			if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))))
-				continue;
-			slot_irq = rcu_dereference(tpci200->slots[i].irq);
-			if (slot_irq) {
-				tpci200_slot_irq(slot_irq);
-			} else {
-				dev_info(&tpci200->info->pdev->dev,
-					 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
-					 tpci200->number, i);
-				tpci200_clear_mask(tpci200,
-					&tpci200->info->interface_regs->control[i],
-					TPCI200_INT0_EN | TPCI200_INT1_EN);
-			}
-		}
-		rcu_read_unlock();
+	status_reg = ioread16(&tpci200->info->interface_regs->status);
 
-		return IRQ_HANDLED;
-	} else {
+	/* Did we cause the interrupt? */
+	if (!(status_reg & TPCI200_SLOT_INT_MASK))
 		return IRQ_NONE;
+
+	/* callback to the IRQ handler for the corresponding slot */
+	rcu_read_lock();
+	for (i = 0; i < TPCI200_NB_SLOT; i++) {
+		if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
+			continue;
+		slot_irq = rcu_dereference(tpci200->slots[i].irq);
+		ret = tpci200_slot_irq(slot_irq);
+		if (ret == -ENODEV) {
+			dev_info(&tpci200->info->pdev->dev,
+				 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
+				 tpci200->number, i);
+			tpci200_clear_mask(tpci200,
+				&tpci200->info->interface_regs->control[i],
+				TPCI200_INT0_EN | TPCI200_INT1_EN);
+		}
 	}
+	rcu_read_unlock();
+
+	return IRQ_HANDLED;
 }
 
 static int tpci200_register(struct tpci200_board *tpci200)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 14/24] Staging: ipack/bridges/tpci200: More cleanups.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (11 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 13/24] Staging: ipack/bridges/tpci200: Cleanup in tpci200_slot_irq() and tpci200_interrupt() Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 15/24] Staging: ipack/bridges/tpci200: move tpci200_free_irq() and tpci200_request_irq() Samuel Iglesias Gonsalvez
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Rename __tpci_request_irq() to tpci_enable_irq() and __tpci_free_irq()
to tpci_disable_irq().  Change their second argument, move them above
tpci200_interrupt(), and use tpci_disable_irq() in the latter

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   44 +++++++++++++++----------------
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 4eaa2aa..c7ec342 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -100,6 +100,22 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
 	}
 }
 
+static void tpci200_enable_irq(struct tpci200_board *tpci200,
+			       int islot)
+{
+	tpci200_set_mask(tpci200,
+			&tpci200->info->interface_regs->control[islot],
+			TPCI200_INT0_EN | TPCI200_INT1_EN);
+}
+
+static void tpci200_disable_irq(struct tpci200_board *tpci200,
+				int islot)
+{
+	tpci200_clear_mask(tpci200,
+			&tpci200->info->interface_regs->control[islot],
+			TPCI200_INT0_EN | TPCI200_INT1_EN);
+}
+
 static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
 {
 	irqreturn_t ret;
@@ -141,9 +157,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 			dev_info(&tpci200->info->pdev->dev,
 				 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
 				 tpci200->number, i);
-			tpci200_clear_mask(tpci200,
-				&tpci200->info->interface_regs->control[i],
-				TPCI200_INT0_EN | TPCI200_INT1_EN);
+			tpci200_disable_irq(tpci200, i);
 		}
 	}
 	rcu_read_unlock();
@@ -269,23 +283,6 @@ out_disable_pci:
 	return res;
 }
 
-static int __tpci200_request_irq(struct tpci200_board *tpci200,
-				 struct ipack_device *dev)
-{
-	tpci200_set_mask(tpci200,
-			&tpci200->info->interface_regs->control[dev->slot],
-			TPCI200_INT0_EN | TPCI200_INT1_EN);
-	return 0;
-}
-
-static void __tpci200_free_irq(struct tpci200_board *tpci200,
-			       struct ipack_device *dev)
-{
-	tpci200_clear_mask(tpci200,
-			&tpci200->info->interface_regs->control[dev->slot],
-			TPCI200_INT0_EN | TPCI200_INT1_EN);
-}
-
 static int tpci200_free_irq(struct ipack_device *dev)
 {
 	struct slot_irq *slot_irq;
@@ -303,8 +300,9 @@ static int tpci200_free_irq(struct ipack_device *dev)
 		return -EINVAL;
 	}
 
-	__tpci200_free_irq(tpci200, dev);
+	tpci200_disable_irq(tpci200, dev->slot);
 	slot_irq = tpci200->slots[dev->slot].irq;
+	/* uninstall handler */
 	RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
 	synchronize_rcu();
 	kfree(slot_irq);
@@ -453,7 +451,7 @@ out_unlock:
 static int tpci200_request_irq(struct ipack_device *dev, int vector,
 			       int (*handler)(void *), void *arg)
 {
-	int res;
+	int res = 0;
 	struct slot_irq *slot_irq;
 	struct tpci200_board *tpci200;
 
@@ -493,7 +491,7 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector,
 	slot_irq->holder = dev;
 
 	rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
-	res = __tpci200_request_irq(tpci200, dev);
+	tpci200_enable_irq(tpci200, dev->slot);
 
 out_unlock:
 	mutex_unlock(&tpci200->mutex);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 15/24] Staging: ipack/bridges/tpci200: move tpci200_free_irq() and tpci200_request_irq()
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (12 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 14/24] Staging: ipack/bridges/tpci200: More cleanups Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 16/24] Staging: ipack: Let interrupts return irqreturn_t Samuel Iglesias Gonsalvez
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Now, all the interrupt related functions are next to each other.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |  154 +++++++++++++++----------------
 1 file changed, 77 insertions(+), 77 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index c7ec342..b0d2205 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -165,6 +165,83 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int tpci200_free_irq(struct ipack_device *dev)
+{
+	struct slot_irq *slot_irq;
+	struct tpci200_board *tpci200;
+
+	tpci200 = check_slot(dev);
+	if (tpci200 == NULL)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&tpci200->mutex))
+		return -ERESTARTSYS;
+
+	if (tpci200->slots[dev->slot].irq == NULL) {
+		mutex_unlock(&tpci200->mutex);
+		return -EINVAL;
+	}
+
+	tpci200_disable_irq(tpci200, dev->slot);
+	slot_irq = tpci200->slots[dev->slot].irq;
+	/* uninstall handler */
+	RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
+	synchronize_rcu();
+	kfree(slot_irq);
+	mutex_unlock(&tpci200->mutex);
+	return 0;
+}
+
+static int tpci200_request_irq(struct ipack_device *dev, int vector,
+			       int (*handler)(void *), void *arg)
+{
+	int res = 0;
+	struct slot_irq *slot_irq;
+	struct tpci200_board *tpci200;
+
+	tpci200 = check_slot(dev);
+	if (tpci200 == NULL)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&tpci200->mutex))
+		return -ERESTARTSYS;
+
+	if (tpci200->slots[dev->slot].irq != NULL) {
+		dev_err(&dev->dev,
+			"Slot [%d:%d] IRQ already registered !\n", dev->bus_nr,
+			dev->slot);
+		res = -EINVAL;
+		goto out_unlock;
+	}
+
+	slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
+	if (slot_irq == NULL) {
+		dev_err(&dev->dev,
+			"Slot [%d:%d] unable to allocate memory for IRQ !\n",
+			dev->bus_nr, dev->slot);
+		res = -ENOMEM;
+		goto out_unlock;
+	}
+
+	/*
+	 * WARNING: Setup Interrupt Vector in the IndustryPack device
+	 * before an IRQ request.
+	 * Read the User Manual of your IndustryPack device to know
+	 * where to write the vector in memory.
+	 */
+	slot_irq->vector = vector;
+	slot_irq->handler = handler;
+	slot_irq->arg = arg;
+	slot_irq->holder = dev;
+
+	rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
+	tpci200_enable_irq(tpci200, dev->slot);
+
+out_unlock:
+	mutex_unlock(&tpci200->mutex);
+	return res;
+}
+
 static int tpci200_register(struct tpci200_board *tpci200)
 {
 	int i;
@@ -283,33 +360,6 @@ out_disable_pci:
 	return res;
 }
 
-static int tpci200_free_irq(struct ipack_device *dev)
-{
-	struct slot_irq *slot_irq;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&tpci200->mutex))
-		return -ERESTARTSYS;
-
-	if (tpci200->slots[dev->slot].irq == NULL) {
-		mutex_unlock(&tpci200->mutex);
-		return -EINVAL;
-	}
-
-	tpci200_disable_irq(tpci200, dev->slot);
-	slot_irq = tpci200->slots[dev->slot].irq;
-	/* uninstall handler */
-	RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
-	synchronize_rcu();
-	kfree(slot_irq);
-	mutex_unlock(&tpci200->mutex);
-	return 0;
-}
-
 static int tpci200_slot_unmap_space(struct ipack_device *dev, int space)
 {
 	struct ipack_addr_space *virt_addr_space;
@@ -448,56 +498,6 @@ out_unlock:
 	return res;
 }
 
-static int tpci200_request_irq(struct ipack_device *dev, int vector,
-			       int (*handler)(void *), void *arg)
-{
-	int res = 0;
-	struct slot_irq *slot_irq;
-	struct tpci200_board *tpci200;
-
-	tpci200 = check_slot(dev);
-	if (tpci200 == NULL)
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&tpci200->mutex))
-		return -ERESTARTSYS;
-
-	if (tpci200->slots[dev->slot].irq != NULL) {
-		dev_err(&dev->dev,
-			"Slot [%d:%d] IRQ already registered !\n", dev->bus_nr,
-			dev->slot);
-		res = -EINVAL;
-		goto out_unlock;
-	}
-
-	slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
-	if (slot_irq == NULL) {
-		dev_err(&dev->dev,
-			"Slot [%d:%d] unable to allocate memory for IRQ !\n",
-			dev->bus_nr, dev->slot);
-		res = -ENOMEM;
-		goto out_unlock;
-	}
-
-	/*
-	 * WARNING: Setup Interrupt Vector in the IndustryPack device
-	 * before an IRQ request.
-	 * Read the User Manual of your IndustryPack device to know
-	 * where to write the vector in memory.
-	 */
-	slot_irq->vector = vector;
-	slot_irq->handler = handler;
-	slot_irq->arg = arg;
-	slot_irq->holder = dev;
-
-	rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
-	tpci200_enable_irq(tpci200, dev->slot);
-
-out_unlock:
-	mutex_unlock(&tpci200->mutex);
-	return res;
-}
-
 static int tpci200_get_clockrate(struct ipack_device *dev)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 16/24] Staging: ipack: Let interrupts return irqreturn_t.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (13 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 15/24] Staging: ipack/bridges/tpci200: move tpci200_free_irq() and tpci200_request_irq() Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 17/24] Staging: ipack/devices/ipoctal: Clean up device removal Samuel Iglesias Gonsalvez
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |    2 +-
 drivers/staging/ipack/bridges/tpci200.h |    3 +--
 drivers/staging/ipack/devices/ipoctal.c |    2 +-
 drivers/staging/ipack/ipack.h           |    4 +++-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index b0d2205..1a149d8 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -193,7 +193,7 @@ static int tpci200_free_irq(struct ipack_device *dev)
 }
 
 static int tpci200_request_irq(struct ipack_device *dev, int vector,
-			       int (*handler)(void *), void *arg)
+			       irqreturn_t (*handler)(void *), void *arg)
 {
 	int res = 0;
 	struct slot_irq *slot_irq;
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index b8e9826..2718d22 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -17,7 +17,6 @@
 #include <linux/limits.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
-#include <linux/interrupt.h>
 #include <linux/swab.h>
 #include <linux/io.h>
 
@@ -123,7 +122,7 @@ struct tpci200_regs {
 struct slot_irq {
 	struct ipack_device *holder;
 	int		vector;
-	int		(*handler)(void *);
+	irqreturn_t	(*handler)(void *);
 	void		*arg;
 };
 
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 4cc9173..8e61ebd 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -263,7 +263,7 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel)
 	tty_kref_put(tty);
 }
 
-static int ipoctal_irq_handler(void *arg)
+static irqreturn_t ipoctal_irq_handler(void *arg)
 {
 	unsigned int i;
 	struct ipoctal *ipoctal = (struct ipoctal *) arg;
diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h
index 0ea9d84..9c3079d 100644
--- a/drivers/staging/ipack/ipack.h
+++ b/drivers/staging/ipack/ipack.h
@@ -11,6 +11,7 @@
 
 #include <linux/mod_devicetable.h>
 #include <linux/device.h>
+#include <linux/interrupt.h>
 
 #include "ipack_ids.h"
 
@@ -126,7 +127,8 @@ struct ipack_driver {
 struct ipack_bus_ops {
 	int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space);
 	int (*unmap_space) (struct ipack_device *dev, int space);
-	int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg);
+	int (*request_irq) (struct ipack_device *dev, int vector,
+			    irqreturn_t (*handler)(void *), void *arg);
 	int (*free_irq) (struct ipack_device *dev);
 	int (*get_clockrate) (struct ipack_device *dev);
 	int (*set_clockrate) (struct ipack_device *dev, int mherz);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 17/24] Staging: ipack/devices/ipoctal: Clean up device removal.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (14 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 16/24] Staging: ipack: Let interrupts return irqreturn_t Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 18/24] Staging: ipack/devices/ipoctal: Check tty_register_device return value Samuel Iglesias Gonsalvez
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Make use of dev_set_drvdata() and dev_get_drvdata() to store and obtain
a pointer to the ipoctal struct corresponding to a struct dev.
Previously we relied on a private list of devices.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 8e61ebd..b84ab5e 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -725,6 +725,7 @@ static int ipoctal_probe(struct ipack_device *dev)
 	if (res)
 		goto out_uninst;
 
+	dev_set_drvdata(&dev->dev, ipoctal);
 	list_add_tail(&ipoctal->list, &ipoctal_list);
 	return 0;
 
@@ -751,14 +752,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
 	kfree(ipoctal);
 }
 
-static void ipoctal_remove(struct ipack_device *device)
+static void ipoctal_remove(struct ipack_device *idev)
 {
-	struct ipoctal *ipoctal, *next;
-
-	list_for_each_entry_safe(ipoctal, next, &ipoctal_list, list) {
-		if (ipoctal->dev == device)
-			__ipoctal_remove(ipoctal);
-	}
+	__ipoctal_remove(dev_get_drvdata(&idev->dev));
 }
 
 static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 18/24] Staging: ipack/devices/ipoctal: Check tty_register_device return value.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (15 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 17/24] Staging: ipack/devices/ipoctal: Clean up device removal Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 19/24] Staging: ipack/devices/ipoctal: Use KBUILD_MODNAME instead of hardcoded string Samuel Iglesias Gonsalvez
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index b84ab5e..7371270 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -437,6 +437,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 	ipoctal->tty_drv = tty;
 
 	for (i = 0; i < NR_CHANNELS; i++) {
+		struct device *tty_dev;
+
 		channel = &ipoctal->channel[i];
 		tty_port_init(&channel->tty_port);
 		tty_port_alloc_xmit_buf(&channel->tty_port);
@@ -450,7 +452,11 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 		channel->pointer_read = 0;
 		channel->pointer_write = 0;
 		channel->nb_bytes = 0;
-		tty_register_device(tty, i, NULL);
+		tty_dev = tty_register_device(tty, i, NULL);
+		if (IS_ERR(tty_dev)) {
+			dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
+			continue;
+		}
 
 		/*
 		 * Enable again the RX. TX will be enabled when
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 19/24] Staging: ipack/devices/ipoctal: Use KBUILD_MODNAME instead of hardcoded string.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (16 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 18/24] Staging: ipack/devices/ipoctal: Check tty_register_device return value Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 20/24] Staging: ipack/devices/ipoctal: Get rid of ipoctal_list Samuel Iglesias Gonsalvez
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 7371270..a0c1e76 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -411,8 +411,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 
 	/* Fill struct tty_driver with ipoctal data */
 	tty->owner = THIS_MODULE;
-	tty->driver_name = "ipoctal";
-	sprintf(name, "ipoctal.%d.%d.", bus_nr, slot);
+	tty->driver_name = KBUILD_MODNAME;
+	sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot);
 	tty->name = name;
 	tty->major = 0;
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 20/24] Staging: ipack/devices/ipoctal: Get rid of ipoctal_list.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (17 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 19/24] Staging: ipack/devices/ipoctal: Use KBUILD_MODNAME instead of hardcoded string Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 21/24] Staging: ipack/devices/ipoctal: read more than one character from RX FIFO Samuel Iglesias Gonsalvez
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Use tty_dev->dev's drdata to associate struct ipocal_channel to the
respective tty_struct.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   39 +++----------------------------
 1 file changed, 3 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index a0c1e76..8b2be61 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -49,7 +49,6 @@ struct ipoctal_channel {
 };
 
 struct ipoctal {
-	struct list_head		list;
 	struct ipack_device		*dev;
 	unsigned int			board_id;
 	struct ipoctal_channel		channel[NR_CHANNELS];
@@ -57,34 +56,11 @@ struct ipoctal {
 	struct tty_driver		*tty_drv;
 };
 
-/* Linked list to save the registered devices */
-static LIST_HEAD(ipoctal_list);
-
-static struct ipoctal *ipoctal_find_board(struct tty_struct *tty)
-{
-	struct ipoctal *p;
-
-	list_for_each_entry(p, &ipoctal_list, list) {
-		if (tty->driver->major == p->tty_drv->major)
-			return p;
-	}
-
-	return NULL;
-}
-
 static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
 {
-	struct ipoctal *ipoctal;
 	struct ipoctal_channel *channel;
 
-	ipoctal = ipoctal_find_board(tty);
-
-	if (ipoctal == NULL) {
-		dev_err(tty->dev, "Device not found. Major %d\n",
-			tty->driver->major);
-		return -ENODEV;
-	}
-	channel = &ipoctal->channel[tty->index];
+	channel = dev_get_drvdata(tty->dev);
 
 	iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
 	return 0;
@@ -93,17 +69,9 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
 static int ipoctal_open(struct tty_struct *tty, struct file *file)
 {
 	int res;
-	struct ipoctal *ipoctal;
 	struct ipoctal_channel *channel;
 
-	ipoctal = ipoctal_find_board(tty);
-
-	if (ipoctal == NULL) {
-		dev_err(tty->dev, "Device not found. Major %d\n",
-			tty->driver->major);
-		return -ENODEV;
-	}
-	channel = &ipoctal->channel[tty->index];
+	channel = dev_get_drvdata(tty->dev);
 
 	if (atomic_read(&channel->open))
 		return -EBUSY;
@@ -457,6 +425,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 			dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
 			continue;
 		}
+		dev_set_drvdata(tty_dev, channel);
 
 		/*
 		 * Enable again the RX. TX will be enabled when
@@ -732,7 +701,6 @@ static int ipoctal_probe(struct ipack_device *dev)
 		goto out_uninst;
 
 	dev_set_drvdata(&dev->dev, ipoctal);
-	list_add_tail(&ipoctal->list, &ipoctal_list);
 	return 0;
 
 out_uninst:
@@ -754,7 +722,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
 
 	tty_unregister_driver(ipoctal->tty_drv);
 	put_tty_driver(ipoctal->tty_drv);
-	list_del(&ipoctal->list);
 	kfree(ipoctal);
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 21/24] Staging: ipack/devices/ipoctal: read more than one character from RX FIFO.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (18 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 20/24] Staging: ipack/devices/ipoctal: Get rid of ipoctal_list Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 22/24] Staging: ipack: update TODO file Samuel Iglesias Gonsalvez
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsalvez

The RX FIFO has a size of 3 characters. Check if when we are picking the
oldest one, we have more to read.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |   60 ++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 24 deletions(-)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 8b2be61..4f79fad 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -134,33 +134,45 @@ static int ipoctal_get_icount(struct tty_struct *tty,
 static void ipoctal_irq_rx(struct ipoctal_channel *channel,
 			   struct tty_struct *tty, u8 sr)
 {
-	unsigned char value = ioread8(&channel->regs->r.rhr);
+	unsigned char value;
 	unsigned char flag = TTY_NORMAL;
-
-	/* Error: count statistics */
-	if (sr & SR_ERROR) {
-		iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
-
-		if (sr & SR_OVERRUN_ERROR) {
-			channel->stats.overrun_err++;
-			/* Overrun doesn't affect the current character*/
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
-		if (sr & SR_PARITY_ERROR) {
-			channel->stats.parity_err++;
-			flag = TTY_PARITY;
-		}
-		if (sr & SR_FRAMING_ERROR) {
-			channel->stats.framing_err++;
-			flag = TTY_FRAME;
+	u8 isr;
+
+	do {
+		value = ioread8(&channel->regs->r.rhr);
+		/* Error: count statistics */
+		if (sr & SR_ERROR) {
+			iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
+
+			if (sr & SR_OVERRUN_ERROR) {
+				channel->stats.overrun_err++;
+				/* Overrun doesn't affect the current character*/
+				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+			}
+			if (sr & SR_PARITY_ERROR) {
+				channel->stats.parity_err++;
+				flag = TTY_PARITY;
+			}
+			if (sr & SR_FRAMING_ERROR) {
+				channel->stats.framing_err++;
+				flag = TTY_FRAME;
+			}
+			if (sr & SR_RECEIVED_BREAK) {
+				channel->stats.rcv_break++;
+				flag = TTY_BREAK;
+			}
 		}
-		if (sr & SR_RECEIVED_BREAK) {
-			channel->stats.rcv_break++;
-			flag = TTY_BREAK;
-		}
-	}
+		tty_insert_flip_char(tty, value, flag);
 
-	tty_insert_flip_char(tty, value, flag);
+		/* Check if there are more characters in RX FIFO
+		 * If there are more, the isr register for this channel
+		 * has enabled the RxRDY|FFULL bit.
+		 */
+		isr = ioread8(&channel->block_regs->r.isr);
+		sr = ioread8(&channel->regs->r.sr);
+	} while (isr & channel->isr_rx_rdy_mask);
+
+	tty_flip_buffer_push(tty);
 }
 
 static void ipoctal_irq_tx(struct ipoctal_channel *channel)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 22/24] Staging: ipack: update TODO file
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (19 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 21/24] Staging: ipack/devices/ipoctal: read more than one character from RX FIFO Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 23/24] Staging: ipack/devices/ipoctal: Unmap memory on device removal Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 24/24] staging: ipack/bridges/tpci200: Use endianess-aware types where applicable Samuel Iglesias Gonsalvez
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Samuel Iglesias Gonsalvez

With the latest patches, the TODO file was outdated.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/TODO |   25 ++-----------------------
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO
index b21d33a..ffafe69 100644
--- a/drivers/staging/ipack/TODO
+++ b/drivers/staging/ipack/TODO
@@ -12,29 +12,8 @@ operations between the two kind of boards.
 TODO
 ====
 
-TPCI-200
---------
-
-* It has a linked list with the tpci200 devices it is managing. Get rid of it
-  and use driver_for_each_device() instead.
-
-IP-OCTAL
---------
-
-* It has a linked list which saves the devices it is currently
-  managing. It should use the driver_for_each_device() function. It is not there
-  due to the impossibility of using container_of macro to recover the
-  corresponding "struct ipoctal" because the attribute "struct ipack_device" is
-  a pointer. This code should be refactored.
-
-Ipack
------
-
-* The structures and API exported can be improved a lot. For example, the
-  way to unregistering IP module devices, doing the IP module driver a call to
-  remove_device() to notify the carrier driver, or the opposite with the call to
-  the ipack_driver_ops' remove() function could be improved.
-
+checkpatch.pl warnings
+cleanup
 
 Contact
 =======
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 23/24] Staging: ipack/devices/ipoctal: Unmap memory on device removal.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (20 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 22/24] Staging: ipack: update TODO file Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  2012-09-12 12:55 ` [PATCH 24/24] staging: ipack/bridges/tpci200: Use endianess-aware types where applicable Samuel Iglesias Gonsalvez
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/devices/ipoctal.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 4f79fad..0292364 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -734,6 +734,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
 
 	tty_unregister_driver(ipoctal->tty_drv);
 	put_tty_driver(ipoctal->tty_drv);
+	ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
+	ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
+	ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
 	kfree(ipoctal);
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 24/24] staging: ipack/bridges/tpci200: Use endianess-aware types where applicable.
  2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
                   ` (21 preceding siblings ...)
  2012-09-12 12:55 ` [PATCH 23/24] Staging: ipack/devices/ipoctal: Unmap memory on device removal Samuel Iglesias Gonsalvez
@ 2012-09-12 12:55 ` Samuel Iglesias Gonsalvez
  22 siblings, 0 replies; 30+ messages in thread
From: Samuel Iglesias Gonsalvez @ 2012-09-12 12:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-kernel, industrypack-devel, Jens Taprogge,
	Samuel Iglesias Gonsalvez

From: Jens Taprogge <jens.taprogge@taprogge.org>

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
---
 drivers/staging/ipack/bridges/tpci200.c |   10 +++++-----
 drivers/staging/ipack/bridges/tpci200.h |    8 ++++----
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index 1a149d8..21b2b75 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -501,7 +501,7 @@ out_unlock:
 static int tpci200_get_clockrate(struct ipack_device *dev)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
-	u16 __iomem *addr;
+	__le16 __iomem *addr;
 
 	if (!tpci200)
 		return -ENODEV;
@@ -513,7 +513,7 @@ static int tpci200_get_clockrate(struct ipack_device *dev)
 static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
-	u16 __iomem *addr;
+	__le16 __iomem *addr;
 
 	if (!tpci200)
 		return -ENODEV;
@@ -536,7 +536,7 @@ static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
 static int tpci200_get_error(struct ipack_device *dev)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
-	u16 __iomem *addr;
+	__le16 __iomem *addr;
 	u16 mask;
 
 	if (!tpci200)
@@ -550,7 +550,7 @@ static int tpci200_get_error(struct ipack_device *dev)
 static int tpci200_get_timeout(struct ipack_device *dev)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
-	u16 __iomem *addr;
+	__le16 __iomem *addr;
 	u16 mask;
 
 	if (!tpci200)
@@ -565,7 +565,7 @@ static int tpci200_get_timeout(struct ipack_device *dev)
 static int tpci200_reset_timeout(struct ipack_device *dev)
 {
 	struct tpci200_board *tpci200 = check_slot(dev);
-	u16 __iomem *addr;
+	__le16 __iomem *addr;
 	u16 mask;
 
 	if (!tpci200)
diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h
index 2718d22..e1f60f3 100644
--- a/drivers/staging/ipack/bridges/tpci200.h
+++ b/drivers/staging/ipack/bridges/tpci200.h
@@ -37,12 +37,12 @@
 #define TPCI200_MEM8_SPACE_BAR        5
 
 struct tpci200_regs {
-	u16	revision;
+	__le16	revision;
 	/* writes to control should occur with the mutex held to protect
 	 * read-modify-write operations */
-	u16  control[4];
-	u16	reset;
-	u16	status;
+	__le16  control[4];
+	__le16	reset;
+	__le16	status;
 	u8	reserved[242];
 } __packed;
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-12 12:55 ` [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel Samuel Iglesias Gonsalvez
@ 2012-09-13 17:43   ` Dan Carpenter
  2012-09-13 17:49     ` Dan Carpenter
  0 siblings, 1 reply; 30+ messages in thread
From: Dan Carpenter @ 2012-09-13 17:43 UTC (permalink / raw)
  To: Samuel Iglesias Gonsalvez
  Cc: Greg Kroah-Hartman, devel, Jens Taprogge, linux-kernel,
	industrypack-devel

On Wed, Sep 12, 2012 at 02:55:29PM +0200, Samuel Iglesias Gonsalvez wrote:
> From: Jens Taprogge <jens.taprogge@taprogge.org>
> 
> This way interrupt handling becomes independent of the channel number.
> 
> Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
> ---
> @@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg)
>  		}
>  
>  		/* RX data */
> -		if (isr_rx_rdy && (sr & SR_RX_READY)) {
> +		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
                         ^^
Bitwise AND intended here I think.

>  			value = ioread8(&channel->regs->r.rhr);
>  			flag = TTY_NORMAL;
>  
> @@ -244,7 +237,7 @@ static int ipoctal_irq_handler(void *arg)
>  		}
>  
>  		/* TX of each character */
> -		if (isr_tx_rdy && (sr & SR_TX_READY)) {
> +		if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) {


regards,
dan carpenter


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-13 17:43   ` Dan Carpenter
@ 2012-09-13 17:49     ` Dan Carpenter
  2012-09-13 18:19       ` Joe Perches
  0 siblings, 1 reply; 30+ messages in thread
From: Dan Carpenter @ 2012-09-13 17:49 UTC (permalink / raw)
  To: Samuel Iglesias Gonsalvez
  Cc: devel, Greg Kroah-Hartman, Jens Taprogge, linux-kernel,
	industrypack-devel

On Thu, Sep 13, 2012 at 08:43:12PM +0300, Dan Carpenter wrote:
> On Wed, Sep 12, 2012 at 02:55:29PM +0200, Samuel Iglesias Gonsalvez wrote:
> > From: Jens Taprogge <jens.taprogge@taprogge.org>
> > 
> > This way interrupt handling becomes independent of the channel number.
> > 
> > Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
> > Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
> > ---
> > @@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg)
> >  		}
> >  
> >  		/* RX data */
> > -		if (isr_rx_rdy && (sr & SR_RX_READY)) {
> > +		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
>                          ^^
> Bitwise AND intended here I think.
> 

Never mind.  It gets silently fixed in the next patch.

Regards,
dan carpenter


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-13 17:49     ` Dan Carpenter
@ 2012-09-13 18:19       ` Joe Perches
  2012-09-13 18:43         ` Jens Taprogge
  0 siblings, 1 reply; 30+ messages in thread
From: Joe Perches @ 2012-09-13 18:19 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Samuel Iglesias Gonsalvez, devel, Greg Kroah-Hartman,
	Jens Taprogge, linux-kernel, industrypack-devel

On Thu, 2012-09-13 at 20:49 +0300, Dan Carpenter wrote:
> On Thu, Sep 13, 2012 at 08:43:12PM +0300, Dan Carpenter wrote:
> > On Wed, Sep 12, 2012 at 02:55:29PM +0200, Samuel Iglesias Gonsalvez wrote:
> > > From: Jens Taprogge <jens.taprogge@taprogge.org>
> > > 
> > > This way interrupt handling becomes independent of the channel number.
> > > 
> > > Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
> > > Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
> > > ---
> > > @@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg)
> > >  		}
> > >  
> > >  		/* RX data */
> > > -		if (isr_rx_rdy && (sr & SR_RX_READY)) {
> > > +		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
> >                          ^^
> > Bitwise AND intended here I think.
> > 
> 
> Never mind.  It gets silently fixed in the next patch.

Nope, you were right the first time.

It shouldn't be silently fixed,

The best path is to rework the original patch
to fix the misuse or the worse path is that the
subsequent patch log should mention the fix.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-13 18:19       ` Joe Perches
@ 2012-09-13 18:43         ` Jens Taprogge
  2012-09-13 19:17           ` Dan Carpenter
  0 siblings, 1 reply; 30+ messages in thread
From: Jens Taprogge @ 2012-09-13 18:43 UTC (permalink / raw)
  To: Joe Perches, Greg Kroah-Hartman
  Cc: Dan Carpenter, Samuel Iglesias Gonsalvez, devel, linux-kernel,
	industrypack-devel

On Thu, Sep 13, 2012 at 11:19:17AM -0700, Joe Perches wrote:
> On Thu, 2012-09-13 at 20:49 +0300, Dan Carpenter wrote:
> > On Thu, Sep 13, 2012 at 08:43:12PM +0300, Dan Carpenter wrote:
> > > On Wed, Sep 12, 2012 at 02:55:29PM +0200, Samuel Iglesias Gonsalvez wrote:
> > > > From: Jens Taprogge <jens.taprogge@taprogge.org>
> > > > 
> > > > This way interrupt handling becomes independent of the channel number.
> > > > 
> > > > Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
> > > > Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
> > > > ---
> > > > @@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg)
> > > >  		}
> > > >  
> > > >  		/* RX data */
> > > > -		if (isr_rx_rdy && (sr & SR_RX_READY)) {
> > > > +		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
> > >                          ^^
> > > Bitwise AND intended here I think.
> > > 
> > 
> > Never mind.  It gets silently fixed in the next patch.
> 
> Nope, you were right the first time.
> 
> It shouldn't be silently fixed,
> 
> The best path is to rework the original patch
> to fix the misuse or the worse path is that the
> subsequent patch log should mention the fix.

I am sorry this slipped through.  The patches are already in
staging-next.  What is the best action to take now?  Should I prepare
the two patches with the issue fixed?

Best Regards,
Jens

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-13 18:43         ` Jens Taprogge
@ 2012-09-13 19:17           ` Dan Carpenter
  2012-09-14  0:25             ` Joe Perches
  0 siblings, 1 reply; 30+ messages in thread
From: Dan Carpenter @ 2012-09-13 19:17 UTC (permalink / raw)
  To: Jens Taprogge
  Cc: Joe Perches, Greg Kroah-Hartman, Samuel Iglesias Gonsalvez,
	devel, linux-kernel, industrypack-devel

On Thu, Sep 13, 2012 at 08:43:46PM +0200, Jens Taprogge wrote:
> On Thu, Sep 13, 2012 at 11:19:17AM -0700, Joe Perches wrote:
> > On Thu, 2012-09-13 at 20:49 +0300, Dan Carpenter wrote:
> > > On Thu, Sep 13, 2012 at 08:43:12PM +0300, Dan Carpenter wrote:
> > > > On Wed, Sep 12, 2012 at 02:55:29PM +0200, Samuel Iglesias Gonsalvez wrote:
> > > > > From: Jens Taprogge <jens.taprogge@taprogge.org>
> > > > > 
> > > > > This way interrupt handling becomes independent of the channel number.
> > > > > 
> > > > > Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
> > > > > Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
> > > > > ---
> > > > > @@ -213,7 +206,7 @@ static int ipoctal_irq_handler(void *arg)
> > > > >  		}
> > > > >  
> > > > >  		/* RX data */
> > > > > -		if (isr_rx_rdy && (sr & SR_RX_READY)) {
> > > > > +		if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
> > > >                          ^^
> > > > Bitwise AND intended here I think.
> > > > 
> > > 
> > > Never mind.  It gets silently fixed in the next patch.
> > 
> > Nope, you were right the first time.
> > 
> > It shouldn't be silently fixed,
> > 
> > The best path is to rework the original patch
> > to fix the misuse or the worse path is that the
> > subsequent patch log should mention the fix.
> 
> I am sorry this slipped through.  The patches are already in
> staging-next.  What is the best action to take now?  Should I prepare
> the two patches with the issue fixed?

If it weren't in staging-next then, yeah, it probably would have
been better to resend those two patches.  You could send them by
themselves without resending any of the others.  But once they hit
staging-next, it's too late.

No stress.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel
  2012-09-13 19:17           ` Dan Carpenter
@ 2012-09-14  0:25             ` Joe Perches
  0 siblings, 0 replies; 30+ messages in thread
From: Joe Perches @ 2012-09-14  0:25 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Jens Taprogge, Greg Kroah-Hartman, Samuel Iglesias Gonsalvez,
	devel, linux-kernel, industrypack-devel

On Thu, 2012-09-13 at 22:17 +0300, Dan Carpenter wrote:

> If it weren't in staging-next then, yeah, it probably would have
> been better to resend those two patches.  You could send them by
> themselves without resending any of the others.  But once they hit
> staging-next, it's too late.
> 
> No stress.

What Dan said.  I didn't know it was already picked up.

cheers, Joe


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2012-09-14  0:26 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-12 12:55 [PATCH 01/24] Staging: ipack/bridges/tpci200: add helpers for writing control regs Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 02/24] Staging: ipack/bridges/tpci200: Remove side effects of tpci200_{request,free}_irq Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 03/24] Staging: ipack/bridges/tpci200: Clean up interrupt handler Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 04/24] Staging: ipack/devices/ipoctal: split ipoctal_channel from ipoctal Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 05/24] Staging: ipack/devices/ipoctal: Directly use ioread/iowrite function Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 06/24] Staging: ipack/devices/ipoctal: put ipoctal_channel into tty->driver_data Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 07/24] Staging: ipack/devices/ipoctal: Store isr masks in ipoctal_channel Samuel Iglesias Gonsalvez
2012-09-13 17:43   ` Dan Carpenter
2012-09-13 17:49     ` Dan Carpenter
2012-09-13 18:19       ` Joe Perches
2012-09-13 18:43         ` Jens Taprogge
2012-09-13 19:17           ` Dan Carpenter
2012-09-14  0:25             ` Joe Perches
2012-09-12 12:55 ` [PATCH 08/24] Staging: ipack/devices/ipoctal: Split interrupt service routine Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 09/24] Staging: ipack/devices/ipoctal: remove superfluous function Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 10/24] Staging: ipack/bridges/tpci200: RCU protect slot_irq pointers Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 11/24] Staging: ipack/bridges/tpci200: Protect device registers with spinlock Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 12/24] Staging: ipack/bridges/tpci200: Clean up interrupt handling Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 13/24] Staging: ipack/bridges/tpci200: Cleanup in tpci200_slot_irq() and tpci200_interrupt() Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 14/24] Staging: ipack/bridges/tpci200: More cleanups Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 15/24] Staging: ipack/bridges/tpci200: move tpci200_free_irq() and tpci200_request_irq() Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 16/24] Staging: ipack: Let interrupts return irqreturn_t Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 17/24] Staging: ipack/devices/ipoctal: Clean up device removal Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 18/24] Staging: ipack/devices/ipoctal: Check tty_register_device return value Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 19/24] Staging: ipack/devices/ipoctal: Use KBUILD_MODNAME instead of hardcoded string Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 20/24] Staging: ipack/devices/ipoctal: Get rid of ipoctal_list Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 21/24] Staging: ipack/devices/ipoctal: read more than one character from RX FIFO Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 22/24] Staging: ipack: update TODO file Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 23/24] Staging: ipack/devices/ipoctal: Unmap memory on device removal Samuel Iglesias Gonsalvez
2012-09-12 12:55 ` [PATCH 24/24] staging: ipack/bridges/tpci200: Use endianess-aware types where applicable Samuel Iglesias Gonsalvez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).