All of lore.kernel.org
 help / color / mirror / Atom feed
From: Songjun Wu <songjun.wu@linux.intel.com>
To: hua.ma@linux.intel.com, yixin.zhu@linux.intel.com,
	chuanhua.lei@intel.com
Cc: linux-mips@linux-mips.org, qi-ming.wu@intel.com,
	linux-clk@vger.kernel.org, linux-serial@vger.kernel.org,
	devicetree@vger.kernel.org,
	Songjun Wu <songjun.wu@linux.intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-kernel@vger.kernel.org, Jiri Slaby <jslaby@suse.com>
Subject: [PATCH 5/7] tty: serial: lantiq: Convert global lock to per device lock
Date: Tue, 12 Jun 2018 13:40:32 +0800	[thread overview]
Message-ID: <20180612054034.4969-6-songjun.wu@linux.intel.com> (raw)
In-Reply-To: <20180612054034.4969-1-songjun.wu@linux.intel.com>

Previous implementation uses one global lock to protect the resource.
If the serial driver have multiple entries, this kind of lock will
slow down the performance.
Add the lock at device level. This will lock only when the function
calling only to the same device.
So that it can avoid useless lock protection.

Signed-off-by: Songjun Wu <songjun.wu@linux.intel.com>
---

 drivers/tty/serial/lantiq.c | 51 ++++++++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c
index 1127586dbc94..72aab1b05265 100644
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -107,7 +107,6 @@
 static void lqasc_tx_chars(struct uart_port *port);
 static struct ltq_uart_port *lqasc_port[MAXPORTS];
 static struct uart_driver lqasc_reg;
-static DEFINE_SPINLOCK(ltq_asc_lock);
 
 struct ltq_uart_port {
 	struct uart_port	port;
@@ -118,6 +117,7 @@ struct ltq_uart_port {
 	unsigned int		tx_irq;
 	unsigned int		rx_irq;
 	unsigned int		err_irq;
+	spinlock_t		lock;  /* exclusive access for multi core */
 };
 
 static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port)
@@ -133,10 +133,11 @@ static void lqasc_stop_tx(struct uart_port *port)
 static void lqasc_start_tx(struct uart_port *port)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&ltq_asc_lock, flags);
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+
+	spin_lock_irqsave(&ltq_port->lock, flags);
 	lqasc_tx_chars(port);
-	spin_unlock_irqrestore(&ltq_asc_lock, flags);
-	return;
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
 }
 
 static void lqasc_stop_rx(struct uart_port *port)
@@ -238,10 +239,14 @@ static irqreturn_t lqasc_tx_int(int irq, void *_port)
 {
 	unsigned long flags;
 	struct uart_port *port = (struct uart_port *)_port;
-	spin_lock_irqsave(&ltq_asc_lock, flags);
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+
+	spin_lock_irqsave(&ltq_port->lock, flags);
 	writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
-	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
+
 	lqasc_start_tx(port);
+
 	return IRQ_HANDLED;
 }
 
@@ -250,8 +255,9 @@ static irqreturn_t lqasc_err_int(int irq, void *_port)
 	unsigned long flags;
 	u32 stat;
 	struct uart_port *port = (struct uart_port *)_port;
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
 
-	spin_lock_irqsave(&ltq_asc_lock, flags);
+	spin_lock_irqsave(&ltq_port->lock, flags);
 	/* clear any pending interrupts */
 	writel(ASC_IRNCR_EIR, port->membase + LTQ_ASC_IRNCR);
 	stat = readl(port->membase + LTQ_ASC_STATE);
@@ -266,7 +272,7 @@ static irqreturn_t lqasc_err_int(int irq, void *_port)
 		port->icount.overrun++;
 	}
 	asc_w32_mask(0, ASCWHBSTATE_CLRALL, port->membase + LTQ_ASC_WHBSTATE);
-	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
 
 	return IRQ_HANDLED;
 }
@@ -275,10 +281,13 @@ static irqreturn_t lqasc_rx_int(int irq, void *_port)
 {
 	unsigned long flags;
 	struct uart_port *port = (struct uart_port *)_port;
-	spin_lock_irqsave(&ltq_asc_lock, flags);
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+
+	spin_lock_irqsave(&ltq_port->lock, flags);
 	writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
 	lqasc_rx_chars(port);
-	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
+
 	return IRQ_HANDLED;
 }
 
@@ -309,11 +318,13 @@ lqasc_startup(struct uart_port *port)
 {
 	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
 	int retval;
+	unsigned long flags;
 
 	if (!IS_ERR(ltq_port->clk))
 		clk_enable(ltq_port->clk);
 	port->uartclk = clk_get_rate(ltq_port->fpiclk);
 
+	spin_lock_irqsave(&ltq_port->lock, flags);
 	asc_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
 		port->membase + LTQ_ASC_CLC);
 
@@ -330,6 +341,7 @@ lqasc_startup(struct uart_port *port)
 	wmb();
 	asc_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
 		     ASCCON_ROEN, port->membase + LTQ_ASC_CON);
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
 
 	retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
 			     0, "asc_tx", port);
@@ -410,6 +422,7 @@ static void lqasc_set_termios(struct uart_port *port,
 	unsigned long flags;
 	u32 fdv = 0;
 	u32 reload = 0;
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
 
 	cflag = new->c_cflag;
 	iflag = new->c_iflag;
@@ -463,7 +476,7 @@ static void lqasc_set_termios(struct uart_port *port,
 	/* set error signals  - framing, parity  and overrun, enable receiver */
 	con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN;
 
-	spin_lock_irqsave(&ltq_asc_lock, flags);
+	spin_lock_irqsave(&ltq_port->lock, flags);
 
 	/* set up CON */
 	asc_w32_mask(0, con, port->membase + LTQ_ASC_CON);
@@ -490,7 +503,7 @@ static void lqasc_set_termios(struct uart_port *port,
 	/* enable rx */
 	writel(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
 
-	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
 
 	/* Don't rewrite B0 */
 	if (tty_termios_baud_rate(new))
@@ -604,16 +617,14 @@ static void lqasc_console_putchar(struct uart_port *port, int ch)
 static void lqasc_serial_port_write(struct uart_port *port, const char *s,
 				    u_int count)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ltq_asc_lock, flags);
 	uart_console_write(port, s, count, lqasc_console_putchar);
-	spin_unlock_irqrestore(&ltq_asc_lock, flags);
 }
 
 static void lqasc_console_write(struct console *co, const char *s, u_int count)
 {
+	unsigned long flags;
 	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
 
 	if (co->index >= MAXPORTS)
 		return;
@@ -622,7 +633,11 @@ static void lqasc_console_write(struct console *co, const char *s, u_int count)
 	if (!ltq_port)
 		return;
 
-	lqasc_serial_port_write(&ltq_port->port, s, count);
+	port = &ltq_port->port;
+
+	spin_lock_irqsave(&ltq_port->lock, flags);
+	lqasc_serial_port_write(port, s, count);
+	spin_unlock_irqrestore(&ltq_port->lock, flags);
 }
 
 static int __init lqasc_console_setup(struct console *co, char *options)
@@ -760,6 +775,8 @@ static int __init lqasc_probe(struct platform_device *pdev)
 	ltq_port->rx_irq = irqres[1].start;
 	ltq_port->err_irq = irqres[2].start;
 
+	spin_lock_init(&ltq_port->lock);
+
 	lqasc_port[line] = ltq_port;
 	platform_set_drvdata(pdev, ltq_port);
 
-- 
2.11.0


  parent reply	other threads:[~2018-06-12  5:42 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-12  5:40 [PATCH 0/7] MIPS: intel: add initial support for Intel MIPS SoCs Songjun Wu
2018-06-12  5:40 ` [PATCH 1/7] MIPS: dts: Add aliases node for lantiq danube serial Songjun Wu
2018-06-12 22:24   ` Rob Herring
2018-06-14  6:19     ` Wu, Songjun
2018-06-14 10:03   ` Arnd Bergmann
2018-06-18  9:42     ` Wu, Songjun
2018-06-18 10:59       ` Arnd Bergmann
2018-06-19  6:46         ` Wu, Songjun
2018-06-12  5:40 ` [PATCH 2/7] clk: intel: Add clock driver for GRX500 SoC Songjun Wu
2018-06-12 22:37   ` Rob Herring
2018-06-14  8:40     ` yixin zhu
2018-06-14 14:09       ` Rob Herring
2018-06-18 10:05         ` yixin zhu
2018-06-12  5:40 ` [PATCH 3/7] MIPS: intel: Add initial support for Intel MIPS SoCs Songjun Wu
2018-06-12 11:23   ` James Hogan
2018-06-14  9:24     ` yixin zhu
2018-06-12 22:31   ` Rob Herring
2018-06-14  8:01     ` Hua Ma
2018-06-12  5:40 ` [PATCH 4/7] tty: serial: lantiq: Always use readl()/writel() Songjun Wu
2018-06-12  8:13   ` Andy Shevchenko
2018-06-14  7:05     ` Wu, Songjun
2018-06-14 10:07   ` Arnd Bergmann
2018-06-18  9:39     ` Wu, Songjun
2018-06-18 11:52       ` Arnd Bergmann
2018-06-12  5:40 ` Songjun Wu [this message]
2018-06-12  5:40 ` [PATCH 6/7] tty: serial: lantiq: Remove unneeded header includes and macros Songjun Wu
2018-06-12  5:40 ` [PATCH 7/7] tty: serial: lantiq: Add CCF support Songjun Wu
2018-06-12  8:07   ` kbuild test robot
2018-06-12  8:07     ` kbuild test robot
2018-06-12  8:07     ` kbuild test robot
2018-06-12 22:39   ` Rob Herring
2018-06-14  6:38     ` Wu, Songjun

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=20180612054034.4969-6-songjun.wu@linux.intel.com \
    --to=songjun.wu@linux.intel.com \
    --cc=chuanhua.lei@intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hua.ma@linux.intel.com \
    --cc=jslaby@suse.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=qi-ming.wu@intel.com \
    --cc=yixin.zhu@linux.intel.com \
    /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.