All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Slaby <jirislaby@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: <linux-kernel@vger.kernel.org>
Subject: [PATCH 1/4] Char: cyclades, remove bottom half processing
Date: Sun, 29 Jul 2007 22:01:15 +0200 (CEST)	[thread overview]
Message-ID: <2460336901848917845@wsc.cz> (raw)

cyclades, remove bottom half processing

The work done in bottom half doesn't cost much cpu time (e.g. tty_hangup
itself schedules its own bottom half), it's possible to do the work in isr
directly and save hence some .text.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>

---
commit 3fc1c2f3f8414d72e12e8d6aed1c36ddb1f19567
tree 071c1c5998332b01ac34ad262b55c2334d6e2392
parent f0d76dfb19957f269687e89a62ba75ecd7339e03
author Jiri Slaby <jirislaby@gmail.com> Sat, 28 Jul 2007 10:32:14 +0200
committer Jiri Slaby <jirislaby@gmail.com> Sat, 28 Jul 2007 10:32:14 +0200

 drivers/char/cyclades.c  |  111 ++++++++--------------------------------------
 include/linux/cyclades.h |   15 ------
 2 files changed, 20 insertions(+), 106 deletions(-)

diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index d6d37c3..6aa91f2 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -897,71 +897,6 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
 	return 0;
 }				/* serial_paranoia_check */
 
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver
- * (also known as the "bottom half").  This can be called any
- * number of times for any channel without harm.
- */
-static inline void cy_sched_event(struct cyclades_port *info, int event)
-{
-	info->event |= 1 << event; /* remember what kind of event and who */
-	schedule_work(&info->tqueue);
-}				/* cy_sched_event */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using cy_sched_event(), and they get done here.
- *
- * This is done through one level of indirection--the task queue.
- * When a hardware interrupt service routine wants service by the
- * driver's bottom half, it enqueues the appropriate tq_struct (one
- * per port) to the keventd work queue and sets a request flag
- * that the work queue be processed.
- *
- * Although this may seem unwieldy, it gives the system a way to
- * pass an argument (in this case the pointer to the cyclades_port
- * structure) to the bottom half of the driver.  Previous kernels
- * had to poll every port to see if that port needed servicing.
- */
-static void
-do_softint(struct work_struct *work)
-{
-	struct cyclades_port *info =
-		container_of(work, struct cyclades_port, tqueue);
-	struct tty_struct    *tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
-		tty_hangup(info->tty);
-		wake_up_interruptible(&info->open_wait);
-		        info->flags &= ~ASYNC_NORMAL_ACTIVE;
-	}
-	if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
-		wake_up_interruptible(&info->open_wait);
-#ifdef CONFIG_CYZ_INTR
-	if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
-			!timer_pending(&cyz_rx_full_timer[info->line]))
-		mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
-#endif
-	if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
-		wake_up_interruptible(&info->delta_msr_wait);
-	tty_wakeup(tty);
-#ifdef Z_WAKE
-	if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
-		complete(&info->shutdown_wait);
-#endif
-} /* do_softint */
-
-
 /***********************************************************/
 /********* Start of block of Cyclom-Y specific code ********/
 
@@ -1243,7 +1178,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
 			cy_writeb(base_addr + (CySRER << index),
 				  readb(base_addr + (CySRER << index)) &
 				  ~CyTxRdy);
-			goto txdone;
+			goto txend;
 		}
 
 		/* load the on-chip space for outbound data */
@@ -1334,9 +1269,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
 		}
 
 txdone:
-		if (info->xmit_cnt < WAKEUP_CHARS) {
-			cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-		}
+		tty_wakeup(info->tty);
 txend:
 		/* end of service */
 		cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f));
@@ -1369,17 +1302,16 @@ txend:
 				if (mdm_change & CyRI)
 					info->icount.rng++;
 
-				cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+				wake_up_interruptible(&info->delta_msr_wait);
 			}
 
 			if ((mdm_change & CyDCD) &&
 					(info->flags & ASYNC_CHECK_CD)) {
-				if (mdm_status & CyDCD) {
-					cy_sched_event(info,
-							Cy_EVENT_OPEN_WAKEUP);
-				} else {
-					cy_sched_event(info, Cy_EVENT_HANGUP);
+				if (!(mdm_status & CyDCD)) {
+					tty_hangup(info->tty);
+					info->flags &= ~ASYNC_NORMAL_ACTIVE;
 				}
+				wake_up_interruptible(&info->open_wait);
 			}
 			if ((mdm_change & CyCTS) &&
 					(info->flags & ASYNC_CTS_FLOW)) {
@@ -1394,8 +1326,7 @@ txend:
 								(CySRER <<
 									index))|
 							CyTxRdy);
-						cy_sched_event(info,
-							Cy_EVENT_WRITE_WAKEUP);
+						tty_wakeup(info->tty);
 					}
 				} else {
 					if (!(mdm_status & CyCTS)) {
@@ -1633,9 +1564,11 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
 				char_count = rx_put - rx_get;
 			else
 				char_count = rx_put - rx_get + rx_bufsize;
-			if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
-				cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
-			}
+			if (char_count >= (int)readl(&buf_ctrl->rx_threshold) &&
+					!timer_pending(&cyz_rx_full_timer[
+							info->line]))
+				mod_timer(&cyz_rx_full_timer[info->line],
+						jiffies + 1);
 #endif
 			info->idle_stats.recv_idle = jiffies;
 			tty_schedule_flip(tty);
@@ -1717,9 +1650,7 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
 		}
 #endif
 ztxdone:
-		if (info->xmit_cnt < WAKEUP_CHARS) {
-			cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-		}
+		tty_wakeup(tty);
 		/* Update tx_put */
 		cy_writel(&buf_ctrl->tx_put, tx_put);
 	}
@@ -1781,10 +1712,11 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 				if ((fw_ver > 241 ? ((u_long) param) :
 						readl(&ch_ctrl->rs_status)) &
 						C_RS_DCD) {
-					cy_sched_event(info,
-						 	Cy_EVENT_OPEN_WAKEUP);
+					wake_up_interruptible(&info->open_wait);
 				} else {
-					cy_sched_event(info, Cy_EVENT_HANGUP);
+					tty_hangup(info->tty);
+					wake_up_interruptible(&info->open_wait);
+					info->flags &= ~ASYNC_NORMAL_ACTIVE;
 				}
 			}
 			break;
@@ -1802,7 +1734,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 			break;
 #ifdef Z_WAKE
 		case C_CM_IOCTLW:
-			cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+			complete(&info->shutdown_wait);
 			break;
 #endif
 #ifdef CONFIG_CYZ_INTR
@@ -1834,7 +1766,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 			break;
 		}
 		if (delta_count)
-			cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+			wake_up_interruptible(&info->delta_msr_wait);
 		if (special_count)
 			tty_schedule_flip(tty);
 	}
@@ -2812,7 +2744,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
 	spin_lock_irqsave(&card->card_lock, flags);
 
 	tty->closing = 0;
-	info->event = 0;
 	info->tty = NULL;
 	if (info->blocked_open) {
 		spin_unlock_irqrestore(&card->card_lock, flags);
@@ -4444,7 +4375,6 @@ static void cy_hangup(struct tty_struct *tty)
 
 	cy_flush_buffer(tty);
 	shutdown(info);
-	info->event = 0;
 	info->count = 0;
 #ifdef CY_DEBUG_COUNT
 	printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
@@ -4502,7 +4432,6 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
 		info->closing_wait = CLOSING_WAIT_DELAY;
 		info->close_delay = 5 * HZ / 10;
 
-		INIT_WORK(&info->tqueue, do_softint);
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
 		init_completion(&info->shutdown_wait);
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 72aa00c..06b2725 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -569,7 +569,6 @@ struct cyclades_port {
 	int                     x_char; /* to be pushed out ASAP */
 	int			close_delay;
 	unsigned short		closing_wait;
-	unsigned long		event;
 	int			count;	/* # of fd on device */
 	int                     breakon;
 	int                     breakoff;
@@ -584,7 +583,6 @@ struct cyclades_port {
 	struct cyclades_monitor	mon;
 	struct cyclades_idle_stats	idle_stats;
 	struct cyclades_icount	icount;
-	struct work_struct	tqueue;
 	wait_queue_head_t       open_wait;
 	wait_queue_head_t       close_wait;
 	struct completion       shutdown_wait;
@@ -592,19 +590,6 @@ struct cyclades_port {
 	int throttle;
 };
 
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at cy interrupt time.
- */
-#define Cy_EVENT_READ_PROCESS		0
-#define Cy_EVENT_WRITE_WAKEUP		1
-#define Cy_EVENT_HANGUP			2
-#define Cy_EVENT_BREAK			3
-#define Cy_EVENT_OPEN_WAKEUP		4
-#define Cy_EVENT_SHUTDOWN_WAKEUP	5
-#define	Cy_EVENT_DELTA_WAKEUP		6
-#define	Cy_EVENT_Z_RX_FULL		7
-
 #define	CLOSING_WAIT_DELAY	30*HZ
 #define CY_CLOSING_WAIT_NONE	65535
 #define CY_CLOSING_WAIT_INF	0

             reply	other threads:[~2007-07-29 20:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-29 20:01 Jiri Slaby [this message]
2007-07-29 20:01 ` [PATCH 2/4] Char: cyclades, make the isr code readable Jiri Slaby
2007-07-29 20:01 ` [PATCH 3/4] Char: cyclades, move spin_lock to one place Jiri Slaby
2007-07-29 20:01 ` [PATCH 4/4] Char: cyclades, fix some -W warnings Jiri Slaby
     [not found]   ` <20070731013023.7769e5bc.akpm@linux-foundation.org>
2007-07-31 20:40     ` [PATCH 1/1 #2] " Jiri Slaby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2460336901848917845@wsc.cz \
    --to=jirislaby@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.