Linux Serial subsystem development
 help / color / mirror / Atom feed
* Need to remove ch35x wch driver which already running
From: Lokesh @ 2012-11-16  7:59 UTC (permalink / raw)
  To: linux-serial

HI

I have a pci base serial card i.e wch35x card. for 3.0.5, the driver does not
exisits. Iam redeveloping for the same from scratch. But due mis detection, the
pci card claims a driver named "serial".

The lspci -k dispaly driver in use as serial. but in lsmod it does not lists.

I want to remove the serial module which is claiming this device. so that is i
can re write the driver just for learning purpose.

02:00.0 Serial controller: Device 4348:5046 (rev 10) (prog-if 02 [16550])
	Subsystem: Device 4348:5046
	Flags: medium devsel, IRQ 21
	I/O ports at d030 [size=8]
	I/O ports at d020 [size=8]
	I/O ports at d010 [size=8]
	I/O ports at d000 [size=16]
	Kernel driver in use: serial
00: 48 43 46 50 01 00 00 02 10 02 00 07 00 00 00 00
10: 31 d0 00 00 21 d0 00 00 11 d0 00 00 01 d0 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 48 43 46 50
30: 00 00 00 00 00 00 00 00 00 00 00 00 0b 01 00 00




^ permalink raw reply

* [PATCH v3 1/3] serial: mxs-auart: distinguish the different SOCs
From: Huang Shijie @ 2012-11-16  8:03 UTC (permalink / raw)
  To: gregkh
  Cc: linux-serial, linux-arm-kernel, linux, vinod.koul, lauri.hintsala,
	Huang Shijie
In-Reply-To: <1353053034-10944-1-git-send-email-b32955@freescale.com>

The current mxs-auart driver is used for both mx23 and mx28.

But in mx23, the DMA has a bug(see errata:2836). We can not add the
DMA support in mx23, but we can add DMA support to auart in mx28.

So in order to add the DMA support for the auart in mx28, we should
distinguish the distinguish SOCs.

This patch adds a new platform_device_id table and a inline function
is_imx28_auart() to distinguish the mx23 and mx28.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/tty/serial/mxs-auart.c |   42 ++++++++++++++++++++++++++++++++++-----
 1 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 6db3baa..06d7271 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -114,11 +114,17 @@
 
 static struct uart_driver auart_driver;
 
+enum mxs_auart_type {
+	IMX23_AUART,
+	IMX28_AUART,
+};
+
 struct mxs_auart_port {
 	struct uart_port port;
 
 	unsigned int flags;
 	unsigned int ctrl;
+	enum mxs_auart_type devtype;
 
 	unsigned int irq;
 
@@ -126,6 +132,29 @@ struct mxs_auart_port {
 	struct device *dev;
 };
 
+static struct platform_device_id mxs_auart_devtype[] = {
+	{ .name = "mxs-auart-imx23", .driver_data = IMX23_AUART },
+	{ .name = "mxs-auart-imx28", .driver_data = IMX28_AUART },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, mxs_auart_devtype);
+
+static struct of_device_id mxs_auart_dt_ids[] = {
+	{
+		.compatible = "fsl,imx28-auart",
+		.data = &mxs_auart_devtype[IMX28_AUART]
+	}, {
+		.compatible = "fsl,imx23-auart",
+		.data = &mxs_auart_devtype[IMX23_AUART]
+	}, { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
+
+static inline int is_imx28_auart(struct mxs_auart_port *s)
+{
+	return s->devtype == IMX28_AUART;
+}
+
 static void mxs_auart_stop_tx(struct uart_port *u);
 
 #define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
@@ -706,6 +735,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
 
 static int __devinit mxs_auart_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id =
+			of_match_device(mxs_auart_dt_ids, &pdev->dev);
 	struct mxs_auart_port *s;
 	u32 version;
 	int ret = 0;
@@ -730,6 +761,11 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
 		goto out_free;
 	}
 
+	if (of_id) {
+		pdev->id_entry = of_id->data;
+		s->devtype = pdev->id_entry->driver_data;
+	}
+
 	s->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(s->clk)) {
 		ret = PTR_ERR(s->clk);
@@ -805,12 +841,6 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct of_device_id mxs_auart_dt_ids[] = {
-	{ .compatible = "fsl,imx23-auart", },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
-
 static struct platform_driver mxs_auart_driver = {
 	.probe = mxs_auart_probe,
 	.remove = __devexit_p(mxs_auart_remove),
-- 
1.7.0.4



^ permalink raw reply related

* [PATCH v3 3/3] ARM: dts: enable dma support for auart0 in mx28
From: Huang Shijie @ 2012-11-16  8:03 UTC (permalink / raw)
  To: gregkh
  Cc: linux-serial, linux-arm-kernel, linux, vinod.koul, lauri.hintsala,
	Huang Shijie
In-Reply-To: <1353053034-10944-1-git-send-email-b32955@freescale.com>

enable the dma support for auart0 in mx28.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 arch/arm/boot/dts/imx28.dtsi |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 55c57ea..b4587b2 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -799,6 +799,7 @@
 				compatible = "fsl,imx28-auart", "fsl,imx23-auart";
 				reg = <0x8006a000 0x2000>;
 				interrupts = <112 70 71>;
+				fsl,auart-dma-channel = <8 9>;
 				clocks = <&clks 45>;
 				status = "disabled";
 			};
-- 
1.7.0.4



^ permalink raw reply related

* [PATCH v3 2/3] serial: mxs-auart: add the DMA support for mx28
From: Huang Shijie @ 2012-11-16  8:03 UTC (permalink / raw)
  To: gregkh
  Cc: linux-serial, linux-arm-kernel, linux, vinod.koul, lauri.hintsala,
	Huang Shijie
In-Reply-To: <1353053034-10944-1-git-send-email-b32955@freescale.com>

Only we meet the following conditions, we can enable the DMA support for
auart:

  (1) We enable the DMA support in the dts file, such as
      arch/arm/boot/dts/imx28.dtsi.

  (2) We enable the hardware flow control.

  (3) We use the mx28, not the mx23. Due to hardware bug(see errata: 2836),
      we can not add the DMA support to mx23.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 .../bindings/tty/serial/fsl-mxs-auart.txt          |    8 +
 drivers/tty/serial/mxs-auart.c                     |  322 +++++++++++++++++++-
 2 files changed, 325 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
index 2ee903f..273a8d5 100644
--- a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
+++ b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
@@ -6,11 +6,19 @@ Required properties:
 - reg : Address and length of the register set for the device
 - interrupts : Should contain the auart interrupt numbers
 
+Optional properties:
+- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other
+		is for TX. If you add this property, it also means that you
+		will enable the DMA support for the auart.
+		Note: due to the hardware bug in imx23(see errata : 2836),
+		only the imx28 can enable the DMA support for the auart.
+
 Example:
 auart0: serial@8006a000 {
 	compatible = "fsl,imx28-auart", "fsl,imx23-auart";
 	reg = <0x8006a000 0x2000>;
 	interrupts = <112 70 71>;
+	fsl,auart-dma-channel = <8 9>;
 };
 
 Note: Each auart port should have an alias correctly numbered in "aliases"
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 06d7271..d5b9e30 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -34,6 +34,8 @@
 #include <linux/io.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/of_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl/mxs-dma.h>
 
 #include <asm/cacheflush.h>
 
@@ -71,6 +73,15 @@
 
 #define AUART_CTRL0_SFTRST			(1 << 31)
 #define AUART_CTRL0_CLKGATE			(1 << 30)
+#define AUART_CTRL0_RXTO_ENABLE			(1 << 27)
+#define AUART_CTRL0_RXTIMEOUT(v)		(((v) & 0x7ff) << 16)
+#define AUART_CTRL0_XFER_COUNT(v)		((v) & 0xffff)
+
+#define AUART_CTRL1_XFER_COUNT(v)		((v) & 0xffff)
+
+#define AUART_CTRL2_DMAONERR			(1 << 26)
+#define AUART_CTRL2_TXDMAE			(1 << 25)
+#define AUART_CTRL2_RXDMAE			(1 << 24)
 
 #define AUART_CTRL2_CTSEN			(1 << 15)
 #define AUART_CTRL2_RTSEN			(1 << 14)
@@ -111,6 +122,7 @@
 #define AUART_STAT_BERR				(1 << 18)
 #define AUART_STAT_PERR				(1 << 17)
 #define AUART_STAT_FERR				(1 << 16)
+#define AUART_STAT_RXCOUNT_MASK			0xffff
 
 static struct uart_driver auart_driver;
 
@@ -122,7 +134,11 @@ enum mxs_auart_type {
 struct mxs_auart_port {
 	struct uart_port port;
 
-	unsigned int flags;
+#define MXS_AUART_DMA_CONFIG	0x1
+#define MXS_AUART_DMA_ENABLED	0x2
+#define MXS_AUART_DMA_TX_SYNC	2  /* bit 2 */
+#define MXS_AUART_DMA_RX_READY	3  /* bit 3 */
+	unsigned long flags;
 	unsigned int ctrl;
 	enum mxs_auart_type devtype;
 
@@ -130,6 +146,20 @@ struct mxs_auart_port {
 
 	struct clk *clk;
 	struct device *dev;
+
+	/* for DMA */
+	struct mxs_dma_data dma_data;
+	int dma_channel_rx, dma_channel_tx;
+	int dma_irq_rx, dma_irq_tx;
+	int dma_channel;
+
+	struct scatterlist tx_sgl;
+	struct dma_chan	*tx_dma_chan;
+	void *tx_dma_buf;
+
+	struct scatterlist rx_sgl;
+	struct dma_chan	*rx_dma_chan;
+	void *rx_dma_buf;
 };
 
 static struct platform_device_id mxs_auart_devtype[] = {
@@ -155,14 +185,107 @@ static inline int is_imx28_auart(struct mxs_auart_port *s)
 	return s->devtype == IMX28_AUART;
 }
 
+static inline bool auart_dma_enabled(struct mxs_auart_port *s)
+{
+	return s->flags & MXS_AUART_DMA_ENABLED;
+}
+
 static void mxs_auart_stop_tx(struct uart_port *u);
 
 #define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
 
-static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
+static void mxs_auart_tx_chars(struct mxs_auart_port *s);
+
+static void dma_tx_callback(void *param)
 {
+	struct mxs_auart_port *s = param;
 	struct circ_buf *xmit = &s->port.state->xmit;
 
+	dma_unmap_sg(s->dev, &s->tx_sgl, 1, DMA_TO_DEVICE);
+
+	/* clear the bit used to serialize the DMA tx. */
+	clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+	smp_mb__after_clear_bit();
+
+	/* wake up the possible processes. */
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(&s->port);
+
+	mxs_auart_tx_chars(s);
+}
+
+static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct scatterlist *sgl = &s->tx_sgl;
+	struct dma_chan *channel = s->tx_dma_chan;
+	u32 pio;
+
+	/* [1] : send PIO. Note, the first pio word is CTRL1. */
+	pio = AUART_CTRL1_XFER_COUNT(size);
+	desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio,
+					1, DMA_TRANS_NONE, 0);
+	if (!desc) {
+		dev_err(s->dev, "step 1 error\n");
+		return -EINVAL;
+	}
+
+	/* [2] : set DMA buffer. */
+	sg_init_one(sgl, s->tx_dma_buf, size);
+	dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE);
+	desc = dmaengine_prep_slave_sg(channel, sgl,
+			1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(s->dev, "step 2 error\n");
+		return -EINVAL;
+	}
+
+	/* [3] : submit the DMA */
+	desc->callback = dma_tx_callback;
+	desc->callback_param = s;
+	dmaengine_submit(desc);
+	dma_async_issue_pending(channel);
+	return 0;
+}
+
+static void mxs_auart_tx_chars(struct mxs_auart_port *s)
+{
+	struct circ_buf *xmit = &s->port.state->xmit;
+
+	if (auart_dma_enabled(s)) {
+		int i = 0;
+		int size;
+		void *buffer = s->tx_dma_buf;
+
+		if (test_and_set_bit(MXS_AUART_DMA_TX_SYNC, &s->flags))
+			return;
+
+		while (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
+			size = min_t(u32, UART_XMIT_SIZE - i,
+				     CIRC_CNT_TO_END(xmit->head,
+						     xmit->tail,
+						     UART_XMIT_SIZE));
+			memcpy(buffer + i, xmit->buf + xmit->tail, size);
+			xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1);
+
+			i += size;
+			if (i >= UART_XMIT_SIZE)
+				break;
+		}
+
+		if (uart_tx_stopped(&s->port))
+			mxs_auart_stop_tx(&s->port);
+
+		if (i) {
+			mxs_auart_dma_tx(s, i);
+		} else {
+			clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+			smp_mb__after_clear_bit();
+		}
+		return;
+	}
+
+
 	while (!(readl(s->port.membase + AUART_STAT) &
 		 AUART_STAT_TXFF)) {
 		if (s->port.x_char) {
@@ -316,10 +439,157 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u)
 	return mctrl;
 }
 
+static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
+{
+	struct mxs_auart_port *s = param;
+
+	if (!mxs_dma_is_apbx(chan))
+		return false;
+
+	if (s->dma_channel == chan->chan_id) {
+		chan->private = &s->dma_data;
+		return true;
+	}
+	return false;
+}
+
+static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s);
+static void dma_rx_callback(void *arg)
+{
+	struct mxs_auart_port *s = (struct mxs_auart_port *) arg;
+	struct tty_struct *tty = s->port.state->port.tty;
+	int count;
+	u32 stat;
+
+	stat = readl(s->port.membase + AUART_STAT);
+	stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR |
+			AUART_STAT_PERR | AUART_STAT_FERR);
+
+	count = stat & AUART_STAT_RXCOUNT_MASK;
+	tty_insert_flip_string(tty, s->rx_dma_buf, count);
+
+	writel(stat, s->port.membase + AUART_STAT);
+	tty_flip_buffer_push(tty);
+
+	/* start the next DMA for RX. */
+	mxs_auart_dma_prep_rx(s);
+}
+
+static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct scatterlist *sgl = &s->rx_sgl;
+	struct dma_chan *channel = s->rx_dma_chan;
+	u32 pio[1];
+
+	/* [1] : send PIO */
+	pio[0] = AUART_CTRL0_RXTO_ENABLE
+		| AUART_CTRL0_RXTIMEOUT(0x80)
+		| AUART_CTRL0_XFER_COUNT(UART_XMIT_SIZE);
+	desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
+					1, DMA_TRANS_NONE, 0);
+	if (!desc) {
+		dev_err(s->dev, "step 1 error\n");
+		return -EINVAL;
+	}
+
+	/* [2] : send DMA request */
+	sg_init_one(sgl, s->rx_dma_buf, UART_XMIT_SIZE);
+	dma_map_sg(s->dev, sgl, 1, DMA_FROM_DEVICE);
+	desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_DEV_TO_MEM,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(s->dev, "step 2 error\n");
+		return -1;
+	}
+
+	/* [3] : submit the DMA, but do not issue it. */
+	desc->callback = dma_rx_callback;
+	desc->callback_param = s;
+	dmaengine_submit(desc);
+	dma_async_issue_pending(channel);
+	return 0;
+}
+
+static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s)
+{
+	if (s->tx_dma_chan) {
+		dma_release_channel(s->tx_dma_chan);
+		s->tx_dma_chan = NULL;
+	}
+	if (s->rx_dma_chan) {
+		dma_release_channel(s->rx_dma_chan);
+		s->rx_dma_chan = NULL;
+	}
+
+	kfree(s->tx_dma_buf);
+	kfree(s->rx_dma_buf);
+	s->tx_dma_buf = NULL;
+	s->rx_dma_buf = NULL;
+}
+
+static void mxs_auart_dma_exit(struct mxs_auart_port *s)
+{
+
+	writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR,
+		s->port.membase + AUART_CTRL2_CLR);
+
+	mxs_auart_dma_exit_channel(s);
+	s->flags &= ~MXS_AUART_DMA_ENABLED;
+	clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+	clear_bit(MXS_AUART_DMA_RX_READY, &s->flags);
+}
+
+static int mxs_auart_dma_init(struct mxs_auart_port *s)
+{
+	dma_cap_mask_t mask;
+
+	if (auart_dma_enabled(s))
+		return 0;
+
+	/* We do not get the right DMA channels. */
+	if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1)
+		return -EINVAL;
+
+	/* init for RX */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	s->dma_channel = s->dma_channel_rx;
+	s->dma_data.chan_irq = s->dma_irq_rx;
+	s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+	if (!s->rx_dma_chan)
+		goto err_out;
+	s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+	if (!s->rx_dma_buf)
+		goto err_out;
+
+	/* init for TX */
+	s->dma_channel = s->dma_channel_tx;
+	s->dma_data.chan_irq = s->dma_irq_tx;
+	s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+	if (!s->tx_dma_chan)
+		goto err_out;
+	s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+	if (!s->tx_dma_buf)
+		goto err_out;
+
+	/* set the flags */
+	s->flags |= MXS_AUART_DMA_ENABLED;
+	dev_dbg(s->dev, "enabled the DMA support.");
+
+	return 0;
+
+err_out:
+	mxs_auart_dma_exit_channel(s);
+	return -EINVAL;
+
+}
+
 static void mxs_auart_settermios(struct uart_port *u,
 				 struct ktermios *termios,
 				 struct ktermios *old)
 {
+	struct mxs_auart_port *s = to_auart_port(u);
 	u32 bm, ctrl, ctrl2, div;
 	unsigned int cflag, baud;
 
@@ -391,10 +661,23 @@ static void mxs_auart_settermios(struct uart_port *u,
 		ctrl |= AUART_LINECTRL_STP2;
 
 	/* figure out the hardware flow control settings */
-	if (cflag & CRTSCTS)
+	if (cflag & CRTSCTS) {
+		/*
+		 * The DMA has a bug(see errata:2836) in mx23.
+		 * So we can not implement the DMA for auart in mx23,
+		 * we can only implement the DMA support for auart
+		 * in mx28.
+		 */
+		if (is_imx28_auart(s) && (s->flags & MXS_AUART_DMA_CONFIG)) {
+			if (!mxs_auart_dma_init(s))
+				/* enable DMA tranfer */
+				ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE
+				       | AUART_CTRL2_DMAONERR;
+		}
 		ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN;
-	else
+	} else {
 		ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN);
+	}
 
 	/* set baud rate */
 	baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
@@ -406,6 +689,18 @@ static void mxs_auart_settermios(struct uart_port *u,
 	writel(ctrl2, u->membase + AUART_CTRL2);
 
 	uart_update_timeout(u, termios->c_cflag, baud);
+
+	/* prepare for the DMA RX. */
+	if (auart_dma_enabled(s) &&
+		!test_and_set_bit(MXS_AUART_DMA_RX_READY, &s->flags)) {
+		if (!mxs_auart_dma_prep_rx(s)) {
+			/* Disable the normal RX interrupt. */
+			writel(AUART_INTR_RXIEN, u->membase + AUART_INTR_CLR);
+		} else {
+			mxs_auart_dma_exit(s);
+			dev_err(s->dev, "We can not start up the DMA.\n");
+		}
+	}
 }
 
 static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
@@ -484,6 +779,9 @@ static void mxs_auart_shutdown(struct uart_port *u)
 {
 	struct mxs_auart_port *s = to_auart_port(u);
 
+	if (auart_dma_enabled(s))
+		mxs_auart_dma_exit(s);
+
 	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
 
 	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
@@ -717,6 +1015,7 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
 		struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
+	u32 dma_channel[2];
 	int ret;
 
 	if (!np)
@@ -730,6 +1029,20 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
 	}
 	s->port.line = ret;
 
+	s->dma_irq_rx = platform_get_irq(pdev, 1);
+	s->dma_irq_tx = platform_get_irq(pdev, 2);
+
+	ret = of_property_read_u32_array(np, "fsl,auart-dma-channel",
+					dma_channel, 2);
+	if (ret == 0) {
+		s->dma_channel_rx = dma_channel[0];
+		s->dma_channel_tx = dma_channel[1];
+
+		s->flags |= MXS_AUART_DMA_CONFIG;
+	} else {
+		s->dma_channel_rx = -1;
+		s->dma_channel_tx = -1;
+	}
 	return 0;
 }
 
@@ -787,7 +1100,6 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
 	s->port.type = PORT_IMX;
 	s->port.dev = s->dev = get_device(&pdev->dev);
 
-	s->flags = 0;
 	s->ctrl = 0;
 
 	s->irq = platform_get_irq(pdev, 0);
-- 
1.7.0.4



^ permalink raw reply related

* [PATCH v3 0/3] serial: mxs-auart: add DMA support for auart in mx28
From: Huang Shijie @ 2012-11-16  8:03 UTC (permalink / raw)
  To: gregkh
  Cc: linux-serial, linux-arm-kernel, linux, vinod.koul, lauri.hintsala,
	Huang Shijie

This patch set adds the DMA support for auart in mx28.
patch 1:
	In mx23, the DMA has a bug(see errata:2836). We can not add the
	DMA support in mx23, but we can add DMA support to auart in mx28.
	So in order to add the DMA support for the auart in mx28, we should add
	the platform_device_id to distinguish the distinguish SOCs.

patch 2: add the DMA support for mx28
	Only we meet the following conditions, we can enable the DMA support
	for auart:
        (1) We enable the DMA support in the dts file, such as
            arch/arm/boot/dts/imx28.dtsi.
        (2) We enable the hardware flow control.
        (3) We use the mx28, not the mx23. Due to hardware bug(see errata: 2836),
            we can not add the DMA support to mx23.

patch 3: enable the DMA support in dts for mx28 
	You can use the /ttyAPP0 to test this patch set. 
	I tested this patch in mx28-evk board.


To Lauri: Please try this patch set. thanks.


v2 --> v3:
	[1] fix a multi-open issue found by Lauri.

v1 --> v2:
	[1] use the inline function, not a macro, to distinguish the SOCs.
	[2] remove the "inline" for mxs_auart_tx_chars().
	[3] use the `pio`, not the `pio[1]` to fill the DMA descriptor.
	[4] use bit operation to serialize the DMA TX.
	[5] use the RX/TX DMA channel to enable the DMA support, remove the
	    "fsl,auart-enable-dma".

Huang Shijie (3):
  serial: mxs-auart: distinguish the different SOCs
  serial: mxs-auart: add the DMA support for mx28
  ARM: dts: enable dma support for auart0 in mx28

 .../bindings/tty/serial/fsl-mxs-auart.txt          |    8 +
 arch/arm/boot/dts/imx28.dtsi                       |    1 +
 drivers/tty/serial/mxs-auart.c                     |  364 +++++++++++++++++++-
 3 files changed, 362 insertions(+), 11 deletions(-)



^ permalink raw reply

* RE: [PATCH] tty/8250_early: Turn serial_in/serial_out into weak symbols.
From: Noam Camus @ 2012-11-16  5:03 UTC (permalink / raw)
  To: Greg KH
  Cc: Alan Cox, linux-serial@vger.kernel.org, Vineet Gupta,
	Gilad Ben Yossef
In-Reply-To: <20121116011124.GA12506@kroah.com>


>From: Greg KH [gregkh@linuxfoundation.org]
>Sent: Friday, November 16, 2012 3:11 AM

>This patch no longer applies to my tree.  Can you please refresh it
>against the tty-next tree and resend it, with Alan's ack kept on it, so
>I remember it is there?

Hello Greg,
Here is my refreshed patch:

>From b1f527ea26ce6ef2bbe3efcb7872aa4a4e6b77d5 Mon Sep 17 00:00:00 2001
From: Noam Camus <noamc@ezchip.com>
Date: Fri, 16 Nov 2012 06:42:53 +0200
Subject: [PATCH] tty/8250_early: Turn serial_in/serial_out into weak symbols.

Allows overriding default methods serial_in/serial_out.

In such platform specific replacement it is possible to use
other regshift, biased register offset, any other manipulation
that is not covered with common default methods.

Overriding default methods may be useful for platforms which got
serial peripheral with registers represented in big endian.
In this situation and assuming that 32 bit operations / alignment
is required then it may be useful to swab words before/after
accessing the serial registers.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Alan Cox <alan@linux.intel.com>
---
 drivers/tty/serial/8250/8250_early.c |   42 +++++++++++++++++-----------------
 include/linux/serial_8250.h          |    2 +
 2 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index 843a150..f53a7db 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -48,7 +48,7 @@ struct early_serial8250_device {
 
 static struct early_serial8250_device early_device;
 
-static unsigned int __init serial_in(struct uart_port *port, int offset)
+unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset)
 {
 	switch (port->iotype) {
 	case UPIO_MEM:
@@ -62,7 +62,7 @@ static unsigned int __init serial_in(struct uart_port *port, int offset)
 	}
 }
 
-static void __init serial_out(struct uart_port *port, int offset, int value)
+void __weak __init serial8250_early_out(struct uart_port *port, int offset, int value)
 {
 	switch (port->iotype) {
 	case UPIO_MEM:
@@ -84,7 +84,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
 	unsigned int status;
 
 	for (;;) {
-		status = serial_in(port, UART_LSR);
+		status = serial8250_early_in(port, UART_LSR);
 		if ((status & BOTH_EMPTY) == BOTH_EMPTY)
 			return;
 		cpu_relax();
@@ -94,7 +94,7 @@ static void __init wait_for_xmitr(struct uart_port *port)
 static void __init serial_putc(struct uart_port *port, int c)
 {
 	wait_for_xmitr(port);
-	serial_out(port, UART_TX, c);
+	serial8250_early_out(port, UART_TX, c);
 }
 
 static void __init early_serial8250_write(struct console *console,
@@ -104,14 +104,14 @@ static void __init early_serial8250_write(struct console *console,
 	unsigned int ier;
 
 	/* Save the IER and disable interrupts */
-	ier = serial_in(port, UART_IER);
-	serial_out(port, UART_IER, 0);
+	ier = serial8250_early_in(port, UART_IER);
+	serial8250_early_out(port, UART_IER, 0);
 
 	uart_console_write(port, s, count, serial_putc);
 
 	/* Wait for transmitter to become empty and restore the IER */
 	wait_for_xmitr(port);
-	serial_out(port, UART_IER, ier);
+	serial8250_early_out(port, UART_IER, ier);
 }
 
 static unsigned int __init probe_baud(struct uart_port *port)
@@ -119,11 +119,11 @@ static unsigned int __init probe_baud(struct uart_port *port)
 	unsigned char lcr, dll, dlm;
 	unsigned int quot;
 
-	lcr = serial_in(port, UART_LCR);
-	serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial_in(port, UART_DLL);
-	dlm = serial_in(port, UART_DLM);
-	serial_out(port, UART_LCR, lcr);
+	lcr = serial8250_early_in(port, UART_LCR);
+	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+	dll = serial8250_early_in(port, UART_DLL);
+	dlm = serial8250_early_in(port, UART_DLM);
+	serial8250_early_out(port, UART_LCR, lcr);
 
 	quot = (dlm << 8) | dll;
 	return (port->uartclk / 16) / quot;
@@ -135,17 +135,17 @@ static void __init init_port(struct early_serial8250_device *device)
 	unsigned int divisor;
 	unsigned char c;
 
-	serial_out(port, UART_LCR, 0x3);	/* 8n1 */
-	serial_out(port, UART_IER, 0);		/* no interrupt */
-	serial_out(port, UART_FCR, 0);		/* no fifo */
-	serial_out(port, UART_MCR, 0x3);	/* DTR + RTS */
+	serial8250_early_out(port, UART_LCR, 0x3);	/* 8n1 */
+	serial8250_early_out(port, UART_IER, 0);	/* no interrupt */
+	serial8250_early_out(port, UART_FCR, 0);	/* no fifo */
+	serial8250_early_out(port, UART_MCR, 0x3);	/* DTR + RTS */
 
 	divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud);
-	c = serial_in(port, UART_LCR);
-	serial_out(port, UART_LCR, c | UART_LCR_DLAB);
-	serial_out(port, UART_DLL, divisor & 0xff);
-	serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
-	serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
+	c = serial8250_early_in(port, UART_LCR);
+	serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB);
+	serial8250_early_out(port, UART_DLL, divisor & 0xff);
+	serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff);
+	serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB);
 }
 
 static int __init parse_options(struct early_serial8250_device *device,
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index c174c90..c490d20 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -105,6 +105,8 @@ extern int early_serial_setup(struct uart_port *port);
 
 extern int serial8250_find_port(struct uart_port *p);
 extern int serial8250_find_port_for_earlycon(void);
+extern unsigned int serial8250_early_in(struct uart_port *port, int offset);
+extern void serial8250_early_out(struct uart_port *port, int offset, int value);
 extern int setup_early_serial8250_console(char *cmdline);
 extern void serial8250_do_set_termios(struct uart_port *port,
 		struct ktermios *termios, struct ktermios *old);
-- 
1.7.1

Noam Camus

^ permalink raw reply related

* [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs
From: Jun Chen @ 2012-11-16 12:59 UTC (permalink / raw)
  To: Greg KH
  Cc: serial, russ.gorby, liu chuansheng, Linux Kernel, Jun Chen,
	Bi Chao, Alan Cox


The Medfield Platform implements a recovery procedure consisting in an escalation
from simple and light recovery procedures to stronger ones with increased visibility
and impact to end-user.After platform find some problem from Modem,such as no response,
platform will try do modem warm reset.If several tries failed, platform will try to
do modem cold boot procedure.For Modem Cold Boot, AP is responsible to generate
blob (binary object containing PIN code and other necessary information).
Blob is stored in AP volatile memory. AP decides to read PIN code from cache instead of
prompting end-user, and sends it to modem as if end-user had entered it.

This patch add module parameters to manage the modem status through sysfs.
Reset_modem can be read and write by user space.When read the reset_modem,user space will
get the mdm_reset_state which used to avoid to run twice at once.When set the reset_modem to
IFX_COLD_RESET_REQ,modem will do cold reset, other val value will trigger modem reset.

Hangup_reasons used to give one interface to user space to know and clear the modem reset reasons.
Now there are four reasons:SPI timeout, modem initiative reset,modem coredump,spi tranfer error.

Cc: Bi Chao <chao.bi@intel.com>
Cc: Liu chuansheng <chuansheng.liu@intel.com>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Chen Jun <jun.d.chen@intel.com>
---
 drivers/tty/serial/Kconfig   |    2 +-
 drivers/tty/serial/ifx6x60.c |  193 ++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/ifx6x60.h |    8 ++
 3 files changed, 202 insertions(+), 1 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2a53be5..640b36a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1323,7 +1323,7 @@ config SERIAL_ALTERA_UART_CONSOLE
 
 config SERIAL_IFX6X60
         tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)"
-	depends on GPIOLIB && SPI
+	depends on GPIOLIB && SPI && X86_INTEL_MID && INTEL_SCU_IPC
 	help
 	  Support for the IFX6x60 modem devices on Intel MID platforms.
 
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index 5b9bc19..c17efc6 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -60,6 +60,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/spi/ifx_modem.h>
 #include <linux/delay.h>
+#include <asm/intel_scu_ipc.h>
 
 #include "ifx6x60.h"
 
@@ -72,6 +73,27 @@
 #define IFX_SPI_HEADER_0		(-1)
 #define IFX_SPI_HEADER_F		(-2)
 
+
+/* Delays for powering up/resetting the modem, ms */
+#define PO_INTERLINE_DELAY	1
+#define PO_POST_DELAY		200
+
+#define IFX_COLD_RESET_REQ	1
+
+#define IFX_MDM_PWR_ON	3
+#define IFX_MDM_RST_PMU	4
+
+/* For modem cold boot */
+#define V1P35CNT_W		0x0E0	/* PMIC register used to power off */
+/* the modem */
+#define V1P35_OFF	4
+#define V1P35_ON		6
+#define COLD_BOOT_DELAY_OFF_MIN	20000	/* 20 ms (use of usleep_range) */
+#define COLD_BOOT_DELAY_OFF_MAX	25000	/* 25 ms (use of usleep_range) */
+#define COLD_BOOT_DELAY_ON_MIN	10000	/* 10 ms (use of usleep_range) */
+#define COLD_BOOT_DELAY_ON_MAX	15000	/* 15 ms (use of usleep_range) */
+
+
 /* forward reference */
 static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev);
 
@@ -81,6 +103,35 @@ static struct tty_driver *tty_drv;
 static struct ifx_spi_device *saved_ifx_dev;
 static struct lock_class_key ifx_spi_key;
 
+
+/**
+ * do_modem_power - activity required to bring up modem
+ *
+ * Toggle gpios required to bring up modem power and start modem.
+ */
+static void do_modem_power(void)
+{
+	gpio_set_value(IFX_MDM_PWR_ON, 1);
+	mdelay(PO_INTERLINE_DELAY);
+	gpio_set_value(IFX_MDM_PWR_ON, 0);
+	msleep(PO_POST_DELAY);
+}
+
+/**
+ * do_modem_reset - activity required to reset modem
+ *
+ * Toggle gpios required to reset modem.
+ */
+static void do_modem_reset(void)
+{
+	gpio_set_value(IFX_MDM_RST_PMU, 0);
+	mdelay(PO_INTERLINE_DELAY);
+	gpio_set_value(IFX_MDM_RST_PMU, 1);
+	msleep(PO_POST_DELAY);
+}
+
+
+
 /* GPIO/GPE settings */
 
 /**
@@ -229,6 +280,7 @@ static void ifx_spi_timeout(unsigned long arg)
 	struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg;
 
 	dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***");
+	ifx_dev->hangup_reasons |= HU_TIMEOUT;
 	ifx_spi_ttyhangup(ifx_dev);
 	mrdy_set_low(ifx_dev);
 	clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
@@ -881,6 +933,7 @@ static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev)
 		/* exited reset */
 		clear_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state);
 		if (solreset) {
+			clear_bit(MR_START, &ifx_dev->mdm_reset_state);
 			set_bit(MR_COMPLETE, &ifx_dev->mdm_reset_state);
 			wake_up(&ifx_dev->mdm_reset_wait);
 		}
@@ -1405,6 +1458,146 @@ static int __init ifx_spi_init(void)
 module_init(ifx_spi_init);
 module_exit(ifx_spi_exit);
 
+/*
+ * Module parameters to manage the modem status through sysfs
+ */
+
+/**
+ * reset_modem - modem reset command function
+ * @val: a reference to the string where the modem reset query is given
+ * @kp: an unused reference to the kernel parameter
+ */
+
+static int reset_modem(const char *val, const struct kernel_param *kp)
+{
+	unsigned long reset_request;
+	int err = 0;
+
+	u16 addr = V1P35CNT_W;
+	u8 data, def_value;
+
+	if (kstrtoul(val, 10, &reset_request) < 0)
+		return -EINVAL;
+
+	if (!saved_ifx_dev) {
+		dev_dbg(&saved_ifx_dev->spi_dev->dev,
+				"%s is called before probe\n", __func__);
+		return -ENODEV;
+	}
+
+	dev_dbg(&saved_ifx_dev->spi_dev->dev,
+					"%s requested !\n", __func__);
+
+	if (test_and_set_bit(MR_START, &saved_ifx_dev->mdm_reset_state))
+		return -EBUSY;
+
+	if (reset_request == IFX_COLD_RESET_REQ) {
+		gpio_set_value(IFX_MDM_RST_PMU, 0);
+
+		/* Save the current register value */
+		err = intel_scu_ipc_readv(&addr, &def_value, 1);
+		if (err) {
+			dev_err(&saved_ifx_dev->spi_dev->dev,
+				" - %s -  read error: %d", __func__, err);
+			goto out;
+		}
+
+		/* Write the new register value (V1P35_OFF) */
+		data = (def_value & 0xf8) | V1P35_OFF;
+		err =  intel_scu_ipc_writev(&addr, &data, 1);
+		if (err) {
+			dev_err(&saved_ifx_dev->spi_dev->dev,
+				" - %s -  write error: %d", __func__, err);
+			goto out;
+		}
+		usleep_range(COLD_BOOT_DELAY_OFF_MIN, COLD_BOOT_DELAY_OFF_MAX);
+
+		/* Write the new register value (V1P35_ON) */
+		data = (def_value & 0xf8) | V1P35_ON;
+		err =  intel_scu_ipc_writev(&addr, &data, 1);
+		if (err) {
+			dev_err(&saved_ifx_dev->spi_dev->dev,
+				" - %s -  write error: %d", __func__, err);
+			goto out;
+		}
+		usleep_range(COLD_BOOT_DELAY_ON_MIN, COLD_BOOT_DELAY_ON_MAX);
+
+		/* Write back the initial register value */
+		err =  intel_scu_ipc_writev(&addr, &def_value, 1);
+		if (err) {
+			dev_err(&saved_ifx_dev->spi_dev->dev,
+				" - %s -  write error: %d", __func__, err);
+			goto out;
+		}
+
+	}
+
+	/* Perform a complete modem reset */
+	do_modem_reset();
+	do_modem_power();
+
+out:
+
+	return err;
+}
+
+
+/**
+* is_modem_reset - modem reset status module parameter callback function
+ * @val: a reference to the string where the modem reset status is returned
+ * @kp: an unused reference to the kernel parameter
+ */
+static int is_modem_reset(char *val, const struct kernel_param *kp)
+{
+	if (saved_ifx_dev)
+		return sprintf(val, "%lu", saved_ifx_dev->mdm_reset_state);
+	else
+		return -ENOTTY;
+}
+
+
+/**
+ * clear_hangup_reasons - clearing all hangup reasons
+ * @val: a reference to the string where the hangup reasons clear query is given
+ * @kp: an unused reference to the kernel parameter
+ */
+static int clear_hangup_reasons(const char *val, const struct kernel_param *kp)
+{
+	if (saved_ifx_dev) {
+		saved_ifx_dev->hangup_reasons = 0;
+		return 0;
+	} else
+		return -ENOTTY;
+}
+
+/**
+ * hangup_reasons - modem hangup reasons module parameter callback function
+ * @val: a reference to the string where the hangup reasons are returned
+ * @kp: an unused reference to the kernel parameter
+ */
+
+static int hangup_reasons(char *val, const struct kernel_param *kp)
+{
+	if (saved_ifx_dev)
+		return sprintf(val, "%lu", saved_ifx_dev->hangup_reasons);
+	else
+		return -ENOTTY;
+}
+
+
+static struct kernel_param_ops reset_modem_ops = {
+	.set = reset_modem,
+	.get = is_modem_reset,
+};
+module_param_cb(reset_modem, &reset_modem_ops, NULL, 0644);
+
+static struct kernel_param_ops hangup_reasons_ops = {
+	.set = clear_hangup_reasons,
+	.get = hangup_reasons,
+};
+module_param_cb(hangup_reasons, &hangup_reasons_ops, NULL, 0644);
+
+
 MODULE_AUTHOR("Intel");
 MODULE_DESCRIPTION("IFX6x60 spi driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h
index e8464ba..274b468 100644
--- a/drivers/tty/serial/ifx6x60.h
+++ b/drivers/tty/serial/ifx6x60.h
@@ -66,6 +66,13 @@
 #define IFX_SPI_POWER_DATA_PENDING	1
 #define IFX_SPI_POWER_SRDY		2
 
+
+/* reasons for hanging up */
+#define	HU_TIMEOUT		1	/* spi timer out */
+#define	HU_RESET			2	/* modem initiative reset */
+#define	HU_COREDUMP		4	/* modem crash coredump */
+#define	HU_RORTUR			8	/* transfer error:ROR or TUR */
+
 struct ifx_spi_device {
 	/* Our SPI device */
 	struct spi_device *spi_dev;
@@ -120,6 +127,7 @@ struct ifx_spi_device {
 
 	/* modem reset */
 	unsigned long mdm_reset_state;
+	unsigned long hangup_reasons;
 #define MR_START	0
 #define MR_INPROGRESS	1
 #define MR_COMPLETE	2
-- 
1.7.4.1




^ permalink raw reply related

* RE: [tty:tty-next 76/76] drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code
From: Chen, Jun D @ 2012-11-16  3:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Wu, Fengguang; +Cc: linux-serial@vger.kernel.org
In-Reply-To: <20121116020605.GA30669@kroah.com>



-----Original Message-----
From: Greg Kroah-Hartman [mailto:gregkh@linuxfoundation.org] 
Sent: Friday, November 16, 2012 10:06 AM
To: Wu, Fengguang
Cc: Chen, Jun D; linux-serial@vger.kernel.org
Subject: Re: [tty:tty-next 76/76] drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code

On Fri, Nov 16, 2012 at 09:09:24AM +0800, kbuild test robot wrote:
> tree:   git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next
> head:   e8823f1ca8d5a0c5d69a8862682ee8bde26990ca
> commit: e8823f1ca8d5a0c5d69a8862682ee8bde26990ca [76/76] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty
> config: i386-randconfig-b691 (attached as .config)
> 
> All warnings:
> 
> drivers/tty/serial/ifx6x60.c: In function 'ifx_spi_write':
> drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]

Ah, missed that one.  Jun, care to send a fix for this?
[Jun] I have already sent the new patch to fix this warning.

> drivers/tty/serial/ifx6x60.c: In function 'ifx_spi_complete':
> drivers/tty/serial/ifx6x60.c:726:8: warning: 'more' may be used uninitialized in this function [-Wmaybe-uninitialized]

And verify that this isn't a real problem please.
[Jun] I didn't modify this line, but I also checked it and can't find warning for " more ". 
thanks,

greg k-h

^ permalink raw reply

* [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty.
From: Jun Chen @ 2012-11-16 11:08 UTC (permalink / raw)
  To: Alan Cox
  Cc: Jun Chen, Bi Chao, serial, russ.gorby, linux-kernel, fengguang.wu,
	gregkh


This patch check whether the fifo lenth is empty before writing new data to fifo.If condition
is true,ifx_spi_write need to trigger one mrdy_assert. If condition is false,the mrdy_assert
will be trigger by the next ifx_spi_io.
Cc: Bi Chao <chao.bi@intel.com>
Signed-off-by: Chen Jun <jun.d.chen@intel.com>
---
 drivers/tty/serial/ifx6x60.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index 5b9bc19..aa01989 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -469,9 +469,17 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
 {
 	struct ifx_spi_device *ifx_dev = tty->driver_data;
 	unsigned char *tmp_buf = (unsigned char *)buf;
-	int tx_count = kfifo_in_locked(&ifx_dev->tx_fifo, tmp_buf, count,
-				   &ifx_dev->fifo_lock);
-	mrdy_assert(ifx_dev);
+	int tx_count;
+	unsigned long flags;
+	bool is_fifo_empty;
+
+	spin_lock_irqsave(&ifx_dev->fifo_lock, flags);
+	is_fifo_empty = kfifo_is_empty(&ifx_dev->tx_fifo);
+	tx_count = kfifo_in(&ifx_dev->tx_fifo, tmp_buf, count);
+	spin_unlock_irqrestore(&ifx_dev->fifo_lock, flags);
+	if (is_fifo_empty)
+		mrdy_assert(ifx_dev);
+
 	return tx_count;
 }
 
-- 
1.7.4.1




^ permalink raw reply related

* [PATCHv3] tty: Added a CONFIG_TTY option to allow removal of TTY
From: Joe Millenbach @ 2012-11-16  2:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Alan Cox, Jiri Slaby, linux-serial,
	linux-kernel
  Cc: Josh Triplett, Joe Millenbach

The option allows you to remove TTY and compile without errors. This
saves space on systems that won't support TTY interfaces anyway.
bloat-o-meter output is below.

The bulk of this patch consists of Kconfig changes adding "depends on
TTY" to various serial devices and similar drivers that require the TTY
layer.  Ideally, these dependencies would occur on a common intermediate
symbol such as SERIO, but most drivers "select SERIO" rather than
"depends on SERIO", and "select" does not respect dependencies.

bloat-o-meter output filtered to not show removed entries with awk
'$3 != "-"' as the list was very long.

add/remove: 0/385 grow/shrink: 2/18 up/down: 14/-54016 (-54002)
function                                     old     new   delta
chr_dev_init                                 193     205     +12
selinux_setprocattr                         1167    1169      +2
static.__warned                              557     556      -1
start_kernel                                 840     835      -5
proc_root_init                               167     162      -5
unregister_console                           165     157      -8
sys_setsid                                   213     205      -8
sys_vhangup                                   37      21     -16
daemonize                                    689     673     -16
t_stop                                        72      54     -18
t_next                                       129     108     -21
static.do_acct_process                       838     806     -32
release_task                                1157    1125     -32
do_exit                                     2325    2288     -37
t_start                                      269     221     -48
static.__func__                            18289   18219     -70
do_task_stat                                2962    2892     -70
flush_unauthorized_files                     740     614    -126
static._rs                                  1440    1280    -160
static.__key                                8560    8384    -176

Signed-off-by: Joe Millenbach <jmillenbach@gmail.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
---
v3: Incorporated feedback from Jiri Slaby: fixed compilation issues on non
    x86/x64 platforms by finding all calls to alloc_tty_driver and
    tty_alloc_driver, then added "depends on" or "selects" TTY to config
    options that enabled compilation of those files.  Also rebased to newer
    kernel sources.
v2: Incorporated feedback from Alan Cox: used "if TTY ... endif" to wrap
    long runs of symbols that all need "depends on TTY"; grouped all the
    stubbed-out functions together in linux/tty.h.

 arch/alpha/Kconfig                    |    2 ++
 arch/ia64/hp/sim/Kconfig              |    1 +
 arch/m68k/Kconfig.devices             |    2 +-
 arch/parisc/Kconfig                   |    1 +
 arch/tile/Kconfig                     |    1 +
 arch/um/Kconfig.common                |    1 +
 arch/xtensa/Kconfig                   |    1 +
 drivers/bluetooth/Kconfig             |    1 +
 drivers/char/Kconfig                  |    7 +++---
 drivers/char/pcmcia/Kconfig           |    4 +--
 drivers/i2c/busses/Kconfig            |    2 +-
 drivers/input/joystick/Kconfig        |    4 +++
 drivers/input/keyboard/Kconfig        |   10 +++++++-
 drivers/input/mouse/Kconfig           |    3 +++
 drivers/input/serio/Kconfig           |    1 +
 drivers/input/touchscreen/Kconfig     |   24 +++++++++++++++++-
 drivers/isdn/Kconfig                  |    1 +
 drivers/isdn/capi/Kconfig             |    1 +
 drivers/isdn/gigaset/Kconfig          |    1 +
 drivers/isdn/hardware/mISDN/Kconfig   |    1 +
 drivers/lguest/Kconfig                |    2 +-
 drivers/media/radio/wl128x/Kconfig    |    2 +-
 drivers/misc/Kconfig                  |    2 +-
 drivers/misc/ti-st/Kconfig            |    2 +-
 drivers/mmc/card/Kconfig              |    1 +
 drivers/net/caif/Kconfig              |    2 +-
 drivers/net/can/Kconfig               |    2 +-
 drivers/net/hamradio/Kconfig          |    4 +--
 drivers/net/irda/Kconfig              |    2 +-
 drivers/net/ppp/Kconfig               |    3 +++
 drivers/net/slip/Kconfig              |    1 +
 drivers/net/usb/Kconfig               |    4 +--
 drivers/net/wan/Kconfig               |    2 +-
 drivers/pps/clients/Kconfig           |    2 +-
 drivers/s390/char/Kconfig             |    8 +++---
 drivers/staging/ccg/Kconfig           |    2 +-
 drivers/staging/dgrp/Kconfig          |    2 +-
 drivers/staging/ipack/devices/Kconfig |    2 +-
 drivers/tty/Kconfig                   |   13 ++++++++++
 drivers/tty/Makefile                  |    2 +-
 drivers/tty/hvc/Kconfig               |    3 +++
 drivers/tty/serial/Kconfig            |    4 +++
 drivers/usb/class/Kconfig             |    2 +-
 drivers/usb/gadget/Kconfig            |    6 +++++
 drivers/usb/serial/Kconfig            |    2 +-
 fs/proc/Makefile                      |    3 ++-
 include/linux/console.h               |    5 ++++
 include/linux/proc_fs.h               |    5 ++++
 include/linux/tty.h                   |   44 ++++++++++++++++++++++++---------
 lib/Kconfig.kgdb                      |    1 +
 net/bluetooth/rfcomm/Kconfig          |    1 +
 net/irda/ircomm/Kconfig               |    2 +-
 sound/soc/codecs/Kconfig              |    3 ++-
 53 files changed, 164 insertions(+), 46 deletions(-)

diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 5dd7f5d..202c95b 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -126,6 +126,7 @@ choice
 
 config ALPHA_GENERIC
 	bool "Generic"
+	depends on TTY
 	help
 	  A generic kernel will run on all supported Alpha hardware.
 
@@ -492,6 +493,7 @@ config VGA_HOSE
 
 config ALPHA_SRM
 	bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
+	depends on TTY
 	default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
 	---help---
 	  There are two different types of booting firmware on Alphas: SRM,
diff --git a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig
index 8d513a8..d84707d 100644
--- a/arch/ia64/hp/sim/Kconfig
+++ b/arch/ia64/hp/sim/Kconfig
@@ -8,6 +8,7 @@ config HP_SIMETH
 
 config HP_SIMSERIAL
 	bool "Simulated serial driver support"
+	depends on TTY
 
 config HP_SIMSERIAL_CONSOLE
 	bool "Console for HP simulator"
diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
index 04a3d9b..1ce1593 100644
--- a/arch/m68k/Kconfig.devices
+++ b/arch/m68k/Kconfig.devices
@@ -41,7 +41,7 @@ config NFBLOCK
 
 config NFCON
 	tristate "NatFeat console driver"
-	depends on NATFEAT
+	depends on TTY && NATFEAT
 	help
 	  Say Y to include support for the ARAnyM NatFeat console driver
 	  which allows the console output to be redirected to the stderr
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 11def45..21fd1a4 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -22,6 +22,7 @@ config PARISC
 	select GENERIC_STRNCPY_FROM_USER
 	select HAVE_MOD_ARCH_SPECIFIC
 	select MODULES_USE_ELF_RELA
+	select TTY # Needed for pdc_cons.c
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 875d008..ae8a7ca 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -121,6 +121,7 @@ config DEBUG_COPY_FROM_USER
 	def_bool n
 
 config HVC_TILE
+	depends on TTY
 	select HVC_DRIVER
 	def_bool y
 
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 648121b..bceee66 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -12,6 +12,7 @@ config UML
 	select GENERIC_CPU_DEVICES
 	select GENERIC_IO
 	select GENERIC_CLOCKEVENTS
+	select TTY # Needed for line.c
 
 config MMU
 	bool
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index cdcb48a..c392d84 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -130,6 +130,7 @@ choice
 
 config XTENSA_PLATFORM_ISS
 	bool "ISS"
+	depends on TTY
 	select XTENSA_CALIBRATE_CCOUNT
 	select SERIAL_CONSOLE
 	select XTENSA_ISS_NETWORK
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index e9f203e..fdfd61a 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -26,6 +26,7 @@ config BT_HCIBTSDIO
 
 config BT_HCIUART
 	tristate "HCI UART driver"
+	depends on TTY
 	help
 	  Bluetooth HCI UART driver.
 	  This driver is required if you want to use Bluetooth devices with
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 72bedad..3bb6fa3 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -53,7 +53,7 @@ source "drivers/tty/serial/Kconfig"
 
 config TTY_PRINTK
 	bool "TTY driver to output user messages via printk"
-	depends on EXPERT
+	depends on EXPERT && TTY
 	default n
 	---help---
 	  If you say Y here, the support for writing user messages (i.e.
@@ -159,7 +159,7 @@ source "drivers/tty/hvc/Kconfig"
 
 config VIRTIO_CONSOLE
 	tristate "Virtio console"
-	depends on VIRTIO
+	depends on VIRTIO && TTY
 	select HVC_DRIVER
 	help
 	  Virtio console for use with lguest and other hypervisors.
@@ -392,6 +392,7 @@ config XILINX_HWICAP
 
 config R3964
 	tristate "Siemens R3964 line discipline"
+	depends on TTY
 	---help---
 	  This driver allows synchronous communication with devices using the
 	  Siemens R3964 packet protocol. Unless you are dealing with special
@@ -439,7 +440,7 @@ source "drivers/char/pcmcia/Kconfig"
 
 config MWAVE
 	tristate "ACP Modem (Mwave) support"
-	depends on X86
+	depends on X86 && TTY
 	select SERIAL_8250
 	---help---
 	  The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
index 6614416..2a166d5 100644
--- a/drivers/char/pcmcia/Kconfig
+++ b/drivers/char/pcmcia/Kconfig
@@ -7,7 +7,7 @@ menu "PCMCIA character devices"
 
 config SYNCLINK_CS
 	tristate "SyncLink PC Card support"
-	depends on PCMCIA
+	depends on PCMCIA && TTY
 	help
 	  Enable support for the SyncLink PC Card serial adapter, running
 	  asynchronous and HDLC communications up to 512Kbps. The port is
@@ -45,7 +45,7 @@ config CARDMAN_4040
 
 config IPWIRELESS
 	tristate "IPWireless 3G UMTS PCMCIA card support"
-	depends on PCMCIA && NETDEVICES
+	depends on PCMCIA && NETDEVICES && TTY
 	select PPP
 	help
 	  This is a driver for 3G UMTS PCMCIA card from IPWireless company. In
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 65dd599..a2c0313 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -794,7 +794,7 @@ config I2C_PARPORT_LIGHT
 
 config I2C_TAOS_EVM
 	tristate "TAOS evaluation module"
-	depends on EXPERIMENTAL
+	depends on EXPERIMENTAL && TTY
 	select SERIO
 	select SERIO_SERPORT
 	default n
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 56eb471..055bcab 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -132,6 +132,8 @@ config JOYSTICK_TMDC
 
 source "drivers/input/joystick/iforce/Kconfig"
 
+if TTY
+
 config JOYSTICK_WARRIOR
 	tristate "Logitech WingMan Warrior joystick"
 	select SERIO
@@ -205,6 +207,8 @@ config JOYSTICK_ZHENHUA
 	  To compile this driver as a module, choose M here: the
 	  module will be called zhenhua.
 
+endif # TTY
+
 config JOYSTICK_DB9
 	tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads"
 	depends on PARPORT
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index b4b65af..028cbf9 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -69,6 +69,7 @@ config KEYBOARD_ATARI
 config KEYBOARD_ATKBD
 	tristate "AT keyboard" if EXPERT || !X86
 	default y
+	depends on TTY
 	select SERIO
 	select SERIO_LIBPS2
 	select SERIO_I8042 if X86
@@ -153,6 +154,7 @@ config KEYBOARD_BFIN
 
 config KEYBOARD_LKKBD
 	tristate "DECstation/VAXstation LK201/LK401 keyboard"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y here if you want to use a LK201 or LK401 style serial
@@ -268,7 +270,7 @@ config KEYBOARD_HIL_OLD
 
 config KEYBOARD_HIL
 	tristate "HP HIL keyboard/pointer support"
-	depends on GSC || HP300
+	depends on (GSC || HP300) && TTY
 	default y
 	select HP_SDC
 	select HIL_MLC
@@ -399,6 +401,7 @@ config KEYBOARD_IMX
 
 config KEYBOARD_NEWTON
 	tristate "Newton keyboard"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y here if you have a Newton keyboard on a serial port.
@@ -478,6 +481,8 @@ config KEYBOARD_SAMSUNG
 	  To compile this driver as a module, choose M here: the
 	  module will be called samsung-keypad.
 
+if TTY
+
 config KEYBOARD_STOWAWAY
 	tristate "Stowaway keyboard"
 	select SERIO
@@ -500,6 +505,8 @@ config KEYBOARD_SUNKBD
 	  To compile this driver as a module, choose M here: the
 	  module will be called sunkbd.
 
+endif # TTY
+
 config KEYBOARD_SH_KEYSC
 	tristate "SuperH KEYSC keypad support"
 	depends on SUPERH || ARCH_SHMOBILE
@@ -595,6 +602,7 @@ config KEYBOARD_TWL4030
 
 config KEYBOARD_XTKBD
 	tristate "XT keyboard"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y here if you want to use the old IBM PC/XT keyboard (or
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index cd6268c..fc160f7 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -14,6 +14,7 @@ if INPUT_MOUSE
 
 config MOUSE_PS2
 	tristate "PS/2 mouse"
+	depends on TTY
 	default y
 	select SERIO
 	select SERIO_LIBPS2
@@ -138,6 +139,7 @@ config MOUSE_PS2_OLPC
 
 config MOUSE_SERIAL
 	tristate "Serial mouse"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y here if you have a serial (RS-232, COM port) mouse connected
@@ -262,6 +264,7 @@ config MOUSE_RISCPC
 
 config MOUSE_VSXXXAA
 	tristate "DEC VSXXX-AA/GA mouse and VSXXX-AB tablet"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y (or M) if you want to use a DEC VSXXX-AA (hockey
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index 55f2c22..56a6163 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -4,6 +4,7 @@
 config SERIO
 	tristate "Serial I/O support" if EXPERT || !X86
 	default y
+	depends on TTY
 	help
 	  Say Yes here if you have any input device that uses serial I/O to
 	  communicate with the system. This includes the
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 1ba232c..7b8d9f6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -113,7 +113,7 @@ config TOUCHSCREEN_AUO_PIXCIR
 
 config TOUCHSCREEN_BITSY
 	tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
-	depends on SA1100_BITSY
+	depends on SA1100_BITSY && TTY
 	select SERIO
 	help
 	  Say Y here if you have the h3600 (Bitsy) touchscreen.
@@ -204,6 +204,8 @@ config TOUCHSCREEN_DA9052
 	  To compile this driver as a module, choose M here: the
 	  module will be called da9052_tsi.
 
+if TTY
+
 config TOUCHSCREEN_DYNAPRO
 	tristate "Dynapro serial touchscreen"
 	select SERIO
@@ -228,6 +230,8 @@ config TOUCHSCREEN_HAMPSHIRE
 	  To compile this driver as a module, choose M here: the
 	  module will be called hampshire.
 
+endif # TTY
+
 config TOUCHSCREEN_EETI
 	tristate "EETI touchscreen panel support"
 	depends on I2C
@@ -249,6 +253,7 @@ config TOUCHSCREEN_EGALAX
 
 config TOUCHSCREEN_FUJITSU
 	tristate "Fujitsu serial touchscreen"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y here if you have the Fujitsu touchscreen (such as one
@@ -287,6 +292,8 @@ config TOUCHSCREEN_S3C2410
 	  To compile this driver as a module, choose M here: the
 	  module will be called s3c2410_ts.
 
+if TTY
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	select SERIO
@@ -323,6 +330,8 @@ config TOUCHSCREEN_WACOM_W8001
 	  To compile this driver as a module, choose M here: the
 	  module will be called wacom_w8001.
 
+endif # TTY
+
 config TOUCHSCREEN_WACOM_I2C
 	tristate "Wacom Tablet support (I2C)"
 	depends on I2C
@@ -381,6 +390,8 @@ config TOUCHSCREEN_MMS114
 	  To compile this driver as a module, choose M here: the
 	  module will be called mms114.
 
+if TTY
+
 config TOUCHSCREEN_MTOUCH
 	tristate "MicroTouch serial touchscreens"
 	select SERIO
@@ -405,6 +416,8 @@ config TOUCHSCREEN_INEXIO
 	  To compile this driver as a module, choose M here: the
 	  module will be called inexio.
 
+endif # TTY
+
 config TOUCHSCREEN_INTEL_MID
 	tristate "Intel MID platform resistive touchscreen"
 	depends on INTEL_SCU_IPC
@@ -462,6 +475,7 @@ config TOUCHSCREEN_HTCPEN
 
 config TOUCHSCREEN_PENMOUNT
 	tristate "Penmount serial touchscreen"
+	depends on TTY
 	select SERIO
 	help
 	  Say Y here if you have a Penmount serial touchscreen connected to
@@ -505,6 +519,8 @@ config TOUCHSCREEN_TNETV107X
 	  To compile this driver as a module, choose M here: the
 	  module will be called tnetv107x-ts.
 
+if TTY
+
 config TOUCHSCREEN_TOUCHRIGHT
 	tristate "Touchright serial touchscreen"
 	select SERIO
@@ -529,6 +545,8 @@ config TOUCHSCREEN_TOUCHWIN
 	  To compile this driver as a module, choose M here: the
 	  module will be called touchwin.
 
+endif # TTY
+
 config TOUCHSCREEN_TI_TSCADC
 	tristate "TI Touchscreen Interface"
 	depends on ARCH_OMAP2PLUS
@@ -802,6 +820,8 @@ config TOUCHSCREEN_USB_EASYTOUCH
 	  Say Y here if you have an EasyTouch USB Touch controller.
 	  If unsure, say N.
 
+if TTY
+
 config TOUCHSCREEN_TOUCHIT213
 	tristate "Sahara TouchIT-213 touchscreen"
 	select SERIO
@@ -825,6 +845,8 @@ config TOUCHSCREEN_TSC_SERIO
 	  To compile this driver as a module, choose M here: the
 	  module will be called tsc40.
 
+endif # TTY
+
 config TOUCHSCREEN_TSC2005
         tristate "TSC2005 based touchscreens"
         depends on SPI_MASTER && GENERIC_HARDIRQS
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index a233ed5..37d50fc 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -22,6 +22,7 @@ if ISDN
 
 menuconfig ISDN_I4L
 	tristate "Old ISDN4Linux (deprecated)"
+	depends on TTY
 	---help---
 	  This driver allows you to use an ISDN adapter for networking
 	  connections and as dialin/out device.  The isdn-tty's have a built
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
index 15c3ffd..f046865 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -18,6 +18,7 @@ config CAPI_TRACE
 
 config ISDN_CAPI_MIDDLEWARE
 	bool "CAPI2.0 Middleware support"
+	depends on TTY
 	help
 	  This option will enhance the capabilities of the /dev/capi20
 	  interface.  It will provide a means of moving a data connection,
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index b18a92c..dde5e09 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -1,5 +1,6 @@
 menuconfig ISDN_DRV_GIGASET
 	tristate "Siemens Gigaset support"
+	depends on TTY
 	select CRC_CCITT
 	select BITREVERSE
 	help
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
index eadc1cd..b8611e3 100644
--- a/drivers/isdn/hardware/mISDN/Kconfig
+++ b/drivers/isdn/hardware/mISDN/Kconfig
@@ -76,6 +76,7 @@ config MISDN_NETJET
 	tristate "Support for NETJet cards"
 	depends on MISDN
 	depends on PCI
+	depends on TTY
 	select MISDN_IPAC
 	select ISDN_HDLC
 	select ISDN_I4L
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig
index 34ae49d..f9c4314 100644
--- a/drivers/lguest/Kconfig
+++ b/drivers/lguest/Kconfig
@@ -1,6 +1,6 @@
 config LGUEST
 	tristate "Linux hypervisor example code"
-	depends on X86_32 && EXPERIMENTAL && EVENTFD
+	depends on X86_32 && EXPERIMENTAL && EVENTFD && TTY
 	select HVC_DRIVER
 	---help---
 	  This is a very simple module which allows you to run
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
index ea1e654..f359be7 100644
--- a/drivers/media/radio/wl128x/Kconfig
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -4,7 +4,7 @@
 menu "Texas Instruments WL128x FM driver (ST based)"
 config RADIO_WL128X
 	tristate "Texas Instruments WL128x FM Radio"
-	depends on VIDEO_V4L2 && RFKILL && GPIOLIB
+	depends on VIDEO_V4L2 && RFKILL && GPIOLIB && TTY
 	select TI_ST if NET
 	help
 	Choose Y here if you have this FM radio chip.
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b151b7c..4b2bb93 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -127,7 +127,7 @@ config PHANTOM
 
 config INTEL_MID_PTI
 	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
-	depends on PCI
+	depends on PCI && TTY
 	default n
 	help
 	  The PTI (Parallel Trace Interface) driver directs
diff --git a/drivers/misc/ti-st/Kconfig b/drivers/misc/ti-st/Kconfig
index abb5de1..f34dcc5 100644
--- a/drivers/misc/ti-st/Kconfig
+++ b/drivers/misc/ti-st/Kconfig
@@ -5,7 +5,7 @@
 menu "Texas Instruments shared transport line discipline"
 config TI_ST
 	tristate "Shared transport core driver"
-	depends on NET && GPIOLIB
+	depends on NET && GPIOLIB && TTY
 	select FW_LOADER
 	help
 	  This enables the shared transport core driver for TI
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 3b1f783..5562308 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -52,6 +52,7 @@ config MMC_BLOCK_BOUNCE
 
 config SDIO_UART
 	tristate "SDIO UART/GPS class support"
+	depends on TTY
 	help
 	  SDIO function driver for SDIO cards that implements the UART
 	  class, as well as the GPS class which appears like a UART.
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index abf4d7a..60c2142 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -6,7 +6,7 @@ comment "CAIF transport drivers"
 
 config CAIF_TTY
 	tristate "CAIF TTY transport driver"
-	depends on CAIF
+	depends on CAIF && TTY
 	default n
 	---help---
 	The CAIF TTY transport driver is a Line Discipline (ldisc)
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..d5743ae 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -13,7 +13,7 @@ config CAN_VCAN
 
 config CAN_SLCAN
 	tristate "Serial / USB serial CAN Adaptors (slcan)"
-	depends on CAN
+	depends on CAN && TTY
 	---help---
 	  CAN driver for several 'low cost' CAN interfaces that are attached
 	  via serial lines or via USB-to-serial adapters using the LAWICEL
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 95dbcfd..bf5e596 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -1,6 +1,6 @@
 config MKISS
 	tristate "Serial port KISS driver"
-	depends on AX25
+	depends on AX25 && TTY
 	select CRC16
 	---help---
 	  KISS is a protocol used for the exchange of data between a computer
@@ -18,7 +18,7 @@ config MKISS
 
 config 6PACK
 	tristate "Serial port 6PACK driver"
-	depends on AX25
+	depends on AX25 && TTY
 	---help---
 	  6pack is a transmission protocol for the data exchange between your
 	  PC and your TNC (the Terminal Node Controller acts as a kind of
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 5952054..e1454cd 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -5,7 +5,7 @@ comment "SIR device drivers"
 
 config IRTTY_SIR
 	tristate "IrTTY (uses Linux serial driver)"
-	depends on IRDA
+	depends on IRDA && TTY
 	help
 	  Say Y here if you want to build support for the IrTTY line
 	  discipline.  To compile it as a module, choose M here: the module
diff --git a/drivers/net/ppp/Kconfig b/drivers/net/ppp/Kconfig
index 872df3e..3d9ef4f 100644
--- a/drivers/net/ppp/Kconfig
+++ b/drivers/net/ppp/Kconfig
@@ -147,6 +147,7 @@ config PPPOL2TP
 	  Support for PPP-over-L2TP socket family. L2TP is a protocol
 	  used by ISPs and enterprises to tunnel PPP traffic over UDP
 	  tunnels. L2TP is replacing PPTP for VPN uses.
+if TTY
 
 config PPP_ASYNC
 	tristate "PPP support for async serial ports"
@@ -172,4 +173,6 @@ config PPP_SYNC_TTY
 
 	  To compile this driver as a module, choose M here.
 
+endif # TTY
+
 endif # PPP
diff --git a/drivers/net/slip/Kconfig b/drivers/net/slip/Kconfig
index 211b160..48e6871 100644
--- a/drivers/net/slip/Kconfig
+++ b/drivers/net/slip/Kconfig
@@ -4,6 +4,7 @@
 
 config SLIP
 	tristate "SLIP (serial line) support"
+	depends on TTY
 	---help---
 	  Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
 	  connect to your Internet service provider or to connect to some
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index c1ae769..81ed3d3 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -423,7 +423,7 @@ config USB_NET_QMI_WWAN
 
 config USB_HSO
 	tristate "Option USB High Speed Mobile Devices"
-	depends on USB && RFKILL
+	depends on USB && RFKILL && TTY
 	default n
 	help
 	  Choose this option if you have an Option HSDPA/HSUPA card.
@@ -471,7 +471,7 @@ config USB_SIERRA_NET
 
 config USB_VL600
 	tristate "LG VL600 modem dongle"
-	depends on USB_NET_CDCETHER
+	depends on USB_NET_CDCETHER && TTY
 	select USB_ACM
 	help
 	  Select this if you want to use an LG Electronics 4G/LTE usb modem
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index d58431e..61eb899 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -429,7 +429,7 @@ config LAPBETHER
 
 config X25_ASY
 	tristate "X.25 async driver (EXPERIMENTAL)"
-	depends on LAPB && X25
+	depends on LAPB && X25 && TTY
 	---help---
 	  Send and receive X.25 frames over regular asynchronous serial
 	  lines such as telephone lines equipped with ordinary modems.
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig
index 445197d..6efd9b6 100644
--- a/drivers/pps/clients/Kconfig
+++ b/drivers/pps/clients/Kconfig
@@ -17,7 +17,7 @@ config PPS_CLIENT_KTIMER
 
 config PPS_CLIENT_LDISC
 	tristate "PPS line discipline"
-	depends on PPS
+	depends on PPS && TTY
 	help
 	  If you say yes here you get support for a PPS source connected
 	  with the CD (Carrier Detect) pin of your serial port.
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig
index 2c9a776..71bf959 100644
--- a/drivers/s390/char/Kconfig
+++ b/drivers/s390/char/Kconfig
@@ -11,7 +11,7 @@ config TN3270
 config TN3270_TTY
 	def_tristate y
 	prompt "Support for tty input/output on 3270 terminals"
-	depends on TN3270
+	depends on TN3270 && TTY
 	help
 	  Include support for using an IBM 3270 terminal as a Linux tty.
 
@@ -33,7 +33,7 @@ config TN3270_CONSOLE
 config TN3215
 	def_bool y
 	prompt "Support for 3215 line mode terminal"
-	depends on CCW
+	depends on CCW && TTY
 	help
 	  Include support for IBM 3215 line-mode terminals.
 
@@ -51,7 +51,7 @@ config CCW_CONSOLE
 config SCLP_TTY
 	def_bool y
 	prompt "Support for SCLP line mode terminal"
-	depends on S390
+	depends on S390 && TTY
 	help
 	  Include support for IBM SCLP line-mode terminals.
 
@@ -66,7 +66,7 @@ config SCLP_CONSOLE
 config SCLP_VT220_TTY
 	def_bool y
 	prompt "Support for SCLP VT220-compatible terminal"
-	depends on S390
+	depends on S390 && TTY
 	help
 	  Include support for an IBM SCLP VT220-compatible terminal.
 
diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig
index 8997a8c..7ed5bc6 100644
--- a/drivers/staging/ccg/Kconfig
+++ b/drivers/staging/ccg/Kconfig
@@ -2,7 +2,7 @@ if USB_GADGET
 
 config USB_G_CCG
 	tristate "Configurable Composite Gadget (STAGING)"
-	depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM
+	depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM && TTY
 	help
 	  The Configurable Composite Gadget supports multiple USB
 	  functions: acm, mass storage, rndis and FunctionFS.
diff --git a/drivers/staging/dgrp/Kconfig b/drivers/staging/dgrp/Kconfig
index 39f4bb6..e4c4155 100644
--- a/drivers/staging/dgrp/Kconfig
+++ b/drivers/staging/dgrp/Kconfig
@@ -1,7 +1,7 @@
 config DGRP
        tristate "Digi Realport driver"
        default n
-       depends on SYSFS
+       depends on SYSFS && TTY
        ---help---
        Support for Digi Realport devices.  These devices allow you to
        access remote serial ports as if they are local tty devices.  This
diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/staging/ipack/devices/Kconfig
index 39f7188..16edbe7 100644
--- a/drivers/staging/ipack/devices/Kconfig
+++ b/drivers/staging/ipack/devices/Kconfig
@@ -1,6 +1,6 @@
 config SERIAL_IPOCTAL
 	tristate "IndustryPack IP-OCTAL uart support"
-	depends on IPACK_BUS
+	depends on IPACK_BUS && TTY
 	help
 	  This driver supports the IPOCTAL serial port device for the IndustryPack bus.
 	default n
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index d8e05ee..f21b4b7 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -1,3 +1,14 @@
+config TTY
+	bool "Enable TTY" if EXPERT
+	default y
+	---help---
+	  Allows you to remove TTY support which can save space, and
+	  blocks features that require TTY from inclusion in the kernel.
+	  TTY is required for any text terminals or serial port
+	  communication. Most users should leave this enabled.
+
+if TTY
+
 config VT
 	bool "Virtual terminal" if EXPERT
 	depends on !S390 && !UML
@@ -387,3 +398,5 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE
 	  If the number you specify is not a valid byte channel handle, then
 	  there simply will be no early console output.  This is true also
 	  if you don't boot under a hypervisor at all.
+
+endif # TTY
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
index 2953059..df5663d 100644
--- a/drivers/tty/Makefile
+++ b/drivers/tty/Makefile
@@ -1,4 +1,4 @@
-obj-y				+= tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
+obj-$(CONFIG_TTY)		+= tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
 				   tty_buffer.o tty_port.o tty_mutex.o
 obj-$(CONFIG_LEGACY_PTYS)	+= pty.o
 obj-$(CONFIG_UNIX98_PTYS)	+= pty.o
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index f47b734..8902f9b 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -1,3 +1,5 @@
+if TTY
+
 config HVC_DRIVER
 	bool
 	help
@@ -119,3 +121,4 @@ config HVCS
 	  which will also be compiled when this driver is built as a
 	  module.
 
+endif # TTY
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2a53be5..76f736a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -2,6 +2,8 @@
 # Serial device configuration
 #
 
+if TTY
+
 menu "Serial drivers"
 	depends on HAS_IOMEM
 
@@ -1424,3 +1426,5 @@ config SERIAL_EFM32_UART_CONSOLE
 	select SERIAL_CORE_CONSOLE
 
 endmenu
+
+endif # TTY
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index 2519e32..316aac8 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -6,7 +6,7 @@ comment "USB Device Class drivers"
 
 config USB_ACM
 	tristate "USB Modem (CDC ACM) support"
-	depends on USB
+	depends on USB && TTY
 	---help---
 	  This driver supports USB modems and ISDN adapters which support the
 	  Communication Device Class Abstract Control Model interface.
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index e0ff51b..88c4835 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -775,6 +775,7 @@ config USB_GADGET_TARGET
 
 config USB_G_SERIAL
 	tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
+	depends on TTY
 	select USB_LIBCOMPOSITE
 	help
 	  The Serial Gadget talks to the Linux-USB generic serial driver.
@@ -824,6 +825,8 @@ config USB_G_PRINTER
 	  For more information, see Documentation/usb/gadget_printer.txt
 	  which includes sample code for accessing the device file.
 
+if TTY
+
 config USB_CDC_COMPOSITE
 	tristate "CDC Composite Device (Ethernet and ACM)"
 	depends on NET
@@ -904,6 +907,8 @@ config USB_G_MULTI_CDC
 
 	  If unsure, say "y".
 
+endif # TTY
+
 config USB_G_HID
 	tristate "HID Gadget"
 	select USB_LIBCOMPOSITE
@@ -920,6 +925,7 @@ config USB_G_HID
 # Standalone / single function gadgets
 config USB_G_DBGP
 	tristate "EHCI Debug Device Gadget"
+	depends on TTY
 	select USB_LIBCOMPOSITE
 	help
 	  This gadget emulates an EHCI Debug device. This is useful when you want
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 76f4622..d8e35fe 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -4,7 +4,7 @@
 
 menuconfig USB_SERIAL
 	tristate "USB Serial Converter support"
-	depends on USB
+	depends on USB && TTY
 	---help---
 	  Say Y here if you have a USB device that provides normal serial
 	  ports, or acts like a serial device, and you want to connect it to
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index 99349ef..209b601 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,7 +8,8 @@ proc-y			:= nommu.o task_nommu.o
 proc-$(CONFIG_MMU)	:= mmu.o task_mmu.o
 
 proc-y       += inode.o root.o base.o generic.o array.o \
-		proc_tty.o fd.o
+		fd.0
+proc-$(CONFIG_TTY)      += proc_tty.o
 proc-y	+= cmdline.o
 proc-y	+= consoles.o
 proc-y	+= cpuinfo.o
diff --git a/include/linux/console.h b/include/linux/console.h
index dedb082..3b709da 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -157,7 +157,12 @@ extern int is_console_locked(void);
 extern int braille_register_console(struct console *, int index,
 		char *console_options, char *braille_options);
 extern int braille_unregister_console(struct console *);
+#ifdef CONFIG_TTY
 extern void console_sysfs_notify(void);
+#else
+static inline void console_sysfs_notify(void)
+{ }
+#endif
 extern bool console_suspend_enabled;
 
 /* Suspend and resume console messages over PM events */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 3fd2e87..c700315 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -123,7 +123,12 @@ extern void pid_ns_release_proc(struct pid_namespace *ns);
  * proc_tty.c
  */
 struct tty_driver;
+#ifdef CONFIG_TTY
 extern void proc_tty_init(void);
+#else
+static inline void proc_tty_init(void)
+{ }
+#endif
 extern void proc_tty_register_driver(struct tty_driver *driver);
 extern void proc_tty_unregister_driver(struct tty_driver *driver);
 
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f0b4eb4..5a12c86 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -341,11 +341,43 @@ struct tty_file_private {
 
 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
 
+#ifdef CONFIG_TTY
+extern void console_init(void);
+extern void tty_kref_put(struct tty_struct *tty);
+extern struct pid *tty_get_pgrp(struct tty_struct *tty);
+extern void tty_vhangup_self(void);
+extern void disassociate_ctty(int priv);
+extern dev_t tty_devnum(struct tty_struct *tty);
+extern void proc_clear_tty(struct task_struct *p);
+extern struct tty_struct *get_current_tty(void);
+/* tty_io.c */
+extern int __init tty_init(void);
+#else
+static inline void console_init(void)
+{ }
+static inline void tty_kref_put(struct tty_struct *tty)
+{ }
+static inline struct pid *tty_get_pgrp(struct tty_struct *tty)
+{ return NULL; }
+static inline void tty_vhangup_self(void)
+{ }
+static inline void disassociate_ctty(int priv)
+{ }
+static inline dev_t tty_devnum(struct tty_struct *tty)
+{ return 0; }
+static inline void proc_clear_tty(struct task_struct *p)
+{ }
+static inline struct tty_struct *get_current_tty(void)
+{ return NULL; }
+/* tty_io.c */
+static inline int __init tty_init(void)
+{ return 0; }
+#endif
+
 extern void tty_write_flush(struct tty_struct *);
 
 extern struct ktermios tty_std_termios;
 
-extern void console_init(void);
 extern int vcs_init(void);
 
 extern struct class *tty_class;
@@ -365,7 +397,6 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty)
 		kref_get(&tty->kref);
 	return tty;
 }
-extern void tty_kref_put(struct tty_struct *tty);
 
 extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
 			      const char *routine);
@@ -397,18 +428,15 @@ extern void tty_driver_remove_tty(struct tty_driver *driver,
 				  struct tty_struct *tty);
 extern void tty_free_termios(struct tty_struct *tty);
 extern int is_current_pgrp_orphaned(void);
-extern struct pid *tty_get_pgrp(struct tty_struct *tty);
 extern int is_ignored(int sig);
 extern int tty_signal(int sig, struct tty_struct *tty);
 extern void tty_hangup(struct tty_struct *tty);
 extern void tty_vhangup(struct tty_struct *tty);
 extern void tty_vhangup_locked(struct tty_struct *tty);
-extern void tty_vhangup_self(void);
 extern void tty_unhangup(struct file *filp);
 extern int tty_hung_up_p(struct file *filp);
 extern void do_SAK(struct tty_struct *tty);
 extern void __do_SAK(struct tty_struct *tty);
-extern void disassociate_ctty(int priv);
 extern void no_tty(void);
 extern void tty_flip_buffer_push(struct tty_struct *tty);
 extern void tty_flush_to_ldisc(struct tty_struct *tty);
@@ -439,9 +467,6 @@ extern long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
 			unsigned int cmd, unsigned long arg);
 extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg);
-extern dev_t tty_devnum(struct tty_struct *tty);
-extern void proc_clear_tty(struct task_struct *p);
-extern struct tty_struct *get_current_tty(void);
 extern void tty_default_fops(struct file_operations *fops);
 extern struct tty_struct *alloc_tty_struct(void);
 extern int tty_alloc_file(struct file *file);
@@ -566,9 +591,6 @@ static inline int tty_audit_push_task(struct task_struct *tsk,
 }
 #endif
 
-/* tty_io.c */
-extern int __init tty_init(void);
-
 /* tty_ioctl.c */
 extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
 		       unsigned int cmd, unsigned long arg);
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb
index 43cb93f..30894fa 100644
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -22,6 +22,7 @@ config KGDB_SERIAL_CONSOLE
 	tristate "KGDB: use kgdb over the serial console"
 	select CONSOLE_POLL
 	select MAGIC_SYSRQ
+	depends on TTY
 	default y
 	help
 	  Share a serial console with kgdb. Sysrq-g must be used
diff --git a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig
index 22e718b..18d352e 100644
--- a/net/bluetooth/rfcomm/Kconfig
+++ b/net/bluetooth/rfcomm/Kconfig
@@ -12,6 +12,7 @@ config BT_RFCOMM
 config BT_RFCOMM_TTY
 	bool "RFCOMM TTY support"
 	depends on BT_RFCOMM
+	depends on TTY
 	help
 	  This option enables TTY emulation support for RFCOMM channels.
 
diff --git a/net/irda/ircomm/Kconfig b/net/irda/ircomm/Kconfig
index 2d4c6b4..19492c1 100644
--- a/net/irda/ircomm/Kconfig
+++ b/net/irda/ircomm/Kconfig
@@ -1,6 +1,6 @@
 config IRCOMM
 	tristate "IrCOMM protocol"
-	depends on IRDA
+	depends on IRDA && TTY
 	help
 	  Say Y here if you want to build support for the IrCOMM protocol.
 	  To compile it as modules, choose M here: the modules will be
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index b92759a..93303b1 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -34,7 +34,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_CS42L73 if I2C
 	select SND_SOC_CS4270 if I2C
 	select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
-	select SND_SOC_CX20442
+	select SND_SOC_CX20442 if TTY
 	select SND_SOC_DA7210 if I2C
 	select SND_SOC_DA732X if I2C
 	select SND_SOC_DA9055 if I2C
@@ -227,6 +227,7 @@ config SND_SOC_CS4271
 
 config SND_SOC_CX20442
 	tristate
+	depends on TTY
 
 config SND_SOC_JZ4740_CODEC
 	tristate
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH -next] tty: of_serial: fix return value check in of_platform_serial_setup()
From: Wei Yongjun @ 2012-11-16  2:21 UTC (permalink / raw)
  To: grant.likely
  Cc: alan, gregkh, rob.herring, seth.heasley, stable, yongjun_wei,
	linux-serial, devicetree-discuss
In-Reply-To: <20121115120811.B9EB63E0B12@localhost>

On 11/15/2012 08:08 PM, Grant Likely wrote:
> On Thu, 1 Nov 2012 13:27:34 +0800, Wei Yongjun <weiyj.lk@gmail.com> wrote:
>> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>>
>> In case of error, the function clk_get() returns ERR_PTR()
>> and never returns NULL. The NULL test in the return value
>> check should be replaced with IS_ERR().
>>
>> dpatch engine is used to auto generate this patch.
>> (https://github.com/weiyj/dpatch)
>>
>> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> Looks correct to me.
>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
>
> Alan, which tree should this go through?
>
> Wei, did you run into this causing a bug? Do you think it should go back
> into linux-stable? It looks like it should to me.

Hi,

this only happens in the -next tree, so I think no need for stable.
 


^ permalink raw reply

* RE: [tty:tty-next 76/76] drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code
From: Chen, Jun D @ 2012-11-16  2:16 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Wu, Fengguang; +Cc: linux-serial@vger.kernel.org
In-Reply-To: <20121116020605.GA30669@kroah.com>

Hi,Grek,
OK, I will fix this warning. Sorry for this mistake.

-----Original Message-----
From: Greg Kroah-Hartman [mailto:gregkh@linuxfoundation.org] 
Sent: Friday, November 16, 2012 10:06 AM
To: Wu, Fengguang
Cc: Chen, Jun D; linux-serial@vger.kernel.org
Subject: Re: [tty:tty-next 76/76] drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code

On Fri, Nov 16, 2012 at 09:09:24AM +0800, kbuild test robot wrote:
> tree:   git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next
> head:   e8823f1ca8d5a0c5d69a8862682ee8bde26990ca
> commit: e8823f1ca8d5a0c5d69a8862682ee8bde26990ca [76/76] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty
> config: i386-randconfig-b691 (attached as .config)
> 
> All warnings:
> 
> drivers/tty/serial/ifx6x60.c: In function 'ifx_spi_write':
> drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]

Ah, missed that one.  Jun, care to send a fix for this?

> drivers/tty/serial/ifx6x60.c: In function 'ifx_spi_complete':
> drivers/tty/serial/ifx6x60.c:726:8: warning: 'more' may be used uninitialized in this function [-Wmaybe-uninitialized]

And verify that this isn't a real problem please.

thanks,

greg k-h

^ permalink raw reply

* Re: [tty:tty-next 76/76] drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code
From: Greg Kroah-Hartman @ 2012-11-16  2:06 UTC (permalink / raw)
  To: kbuild test robot; +Cc: Jun Chen, linux-serial
In-Reply-To: <50a59244.WYf95+M2VB2UsDXN%fengguang.wu@intel.com>

On Fri, Nov 16, 2012 at 09:09:24AM +0800, kbuild test robot wrote:
> tree:   git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next
> head:   e8823f1ca8d5a0c5d69a8862682ee8bde26990ca
> commit: e8823f1ca8d5a0c5d69a8862682ee8bde26990ca [76/76] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty
> config: i386-randconfig-b691 (attached as .config)
> 
> All warnings:
> 
> drivers/tty/serial/ifx6x60.c: In function 'ifx_spi_write':
> drivers/tty/serial/ifx6x60.c:516:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]

Ah, missed that one.  Jun, care to send a fix for this?

> drivers/tty/serial/ifx6x60.c: In function 'ifx_spi_complete':
> drivers/tty/serial/ifx6x60.c:726:8: warning: 'more' may be used uninitialized in this function [-Wmaybe-uninitialized]

And verify that this isn't a real problem please.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH v2 00/10] serial: sh-sci fixes - console PM, SCIFB, SMP lockup, etc.
From: Greg KH @ 2012-11-16  2:04 UTC (permalink / raw)
  To: Shinya Kuribayashi
  Cc: lethal, magnus.damm, rjw, alan, takashi.yoshii.zj, linux-serial,
	linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

On Fri, Nov 16, 2012 at 10:49:15AM +0900, Shinya Kuribayashi wrote:
> Hi Greg,
> 
> On 11/16/2012 10:01 AM, Greg KH wrote:> On Wed, Nov 07, 2012 at 04:18:38PM +0900, Shinya Kuribayashi wrote:
> >> On 11/7/2012 3:57 PM, Shinya Kuribayashi wrote:
> >>> Hi Paul and serial forks,
> >> [...]
> >>> Takashi YOSHII (4):
> >>>       serial: sh-sci: fix condition test to set SCBRR
> >>>       serial: sh-sci: support lower baud rate
> >>>       serial: sh-sci: mask SCTFDR/RFDR according to fifosize
> >>>       serial: sh-sci: fix common SCIFB regmap definition
> >>>
> >>> Teppei Kamijou (1):
> >>>       serial: sh-sci: console runtime PM support (revisit)
> >>>
> >>>  drivers/tty/serial/sh-sci.c | 140 ++++++++++++++++++--------------------------
> >>>  1 file changed, 56 insertions(+), 84 deletions(-)
> >>
> >> Oops, I forgot to append proper From: author lines in five commits
> >> (patch 04/10 to 09/10).  Didn't mean to supersede your authoship.
> >>
> >> I'd respin the patchset later, waiting for some feedback.
> > 
> > Can you please resend this with this fixed up if you want to get this
> > into 3.8?
> 
> Thanks for your kind reminder.  Here's v2, providing From: authorship
> lines in five patches (04 to 08).  No logical change in the patches.

All now applied, thanks.

greg k-h

^ permalink raw reply

* RE: [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.
From: Chen, Jun D @ 2012-11-16  1:55 UTC (permalink / raw)
  To: Greg KH; +Cc: Alan Cox, serial, Gorby, Russ, Liu, Chuansheng, Bi, Chao
In-Reply-To: <20121116005215.GA12849@kroah.com>

Hi,Greg,
Got it, I will resend the new patch based on the tty-next branch to Alan again.  
Thanks!


-----Original Message-----
From: Greg KH [mailto:gregkh@linuxfoundation.org] 
Sent: Friday, November 16, 2012 8:52 AM
To: Chen, Jun D
Cc: Alan Cox; serial; Gorby, Russ; Liu, Chuansheng; Bi, Chao
Subject: Re: [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.

On Wed, Nov 07, 2012 at 06:06:14AM -0500, Jun Chen wrote:
> 
> The Medfield Platform implements a recovery procedure consisting in an 
> escalation from simple and light recovery procedures to stronger ones 
> with increased visibility and impact to end-user.After platform find 
> some problem from Modem,such as no response, platform will try do 
> modem warm reset.If several tries failed, platform will try to do 
> modem cold boot procedure.For Modem Cold Boot, AP is responsible to generate blob (binary object containing PIN code and other necessary information).
> Blob is stored in AP volatile memory. AP decides to read PIN code from 
> cache instead of prompting end-user, and sends it to modem as if end-user had entered it.
> 
> This patch add module parameters to manage the modem status through sysfs.
> Reset_modem can be read and write by user space.When read the 
> reset_modem,user space will get the mdm_reset_state which used to 
> avoid to run twice at once.When set the reset_modem to IFX_COLD_RESET_REQ,modem will do cold reset, other val value will trigger modem reset.
> 
> Hangup_reasons used to give one interface to user space to know and clear the modem reset reasons.
> Now there are four reasons:SPI timeout, modem initiative reset,modem coredump,spi tranfer error.
> 
> Cc: Bi Chao <chao.bi@intel.com>
> Cc: Liu chuansheng <chuansheng.liu@intel.com>
> Signed-off-by: Chen Jun <jun.d.chen@intel.com>
> Acked-by: Alan Cox <alan@linux.intel.com>
> ---
>  drivers/tty/serial/Kconfig   |    2 +-
>  drivers/tty/serial/ifx6x60.c |  194 +++++++++++++++++++++++++++++++++++++++++-
>  drivers/tty/serial/ifx6x60.h |    8 ++
>  3 files changed, 202 insertions(+), 2 deletions(-)

This patch fails to apply, can you please refresh it against my tty-next branch and resend it, keeping Alan's ack on it, so I remember it's there?

thanks,

greg k-h

^ permalink raw reply

* [PATCH v2 10/10] serial: sh-sci: fix possible race cases on SCSCR register accesses
From: Shinya Kuribayashi @ 2012-11-16  1:54 UTC (permalink / raw)
  To: lethal, magnus.damm, alan, gregkh
  Cc: rjw, takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

In the previous commit, console write function (serial_console_write)
is changed to disable SCI interrupts while printing console strings.
This introduces possible race cases in the serial startup / shutdown
functions on SMP systems.

This patch fixes the sh-sci in the same way as commit 9ec1882df2
(tty: serial: imx: console write routing is unsafe on SMP, from
Xinyu Chen <xinyu.chen@freescale.com>, 2012-08-27) did.

There could be several consumers of the console,
* the kernel printk
* the init process using /dev/kmsg to call printk to show log
* shell, which opens /dev/console and writes with sys_write()

The shell goes into the normal UART open() and write() system calls,
while the other two go into the console operations.  The open() call
invokes serial startup function (sci_startup), which will write to
the SCSCR register (to enable or disable SCI interrupts) without any
locking.  This will conflict with the console serial function.

Add spinlock protections in sci_startup() and sci_shutdown() properly.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 0b8d029..8e3c7f7 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1742,6 +1742,7 @@ static inline void sci_free_dma(struct uart_port *port)
 static int sci_startup(struct uart_port *port)
 {
 	struct sci_port *s = to_sci_port(port);
+	unsigned long flags;
 	int ret;
 
 	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
@@ -1752,8 +1753,10 @@ static int sci_startup(struct uart_port *port)
 
 	sci_request_dma(port);
 
+	spin_lock_irqsave(&port->lock, flags);
 	sci_start_tx(port);
 	sci_start_rx(port);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	return 0;
 }
@@ -1761,11 +1764,14 @@ static int sci_startup(struct uart_port *port)
 static void sci_shutdown(struct uart_port *port)
 {
 	struct sci_port *s = to_sci_port(port);
+	unsigned long flags;
 
 	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
 
+	spin_lock_irqsave(&port->lock, flags);
 	sci_stop_rx(port);
 	sci_stop_tx(port);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	sci_free_dma(port);
 	sci_free_irq(s);
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 09/10] serial: sh-sci: add locking to console write function to avoid SMP lockup
From: Shinya Kuribayashi @ 2012-11-16  1:54 UTC (permalink / raw)
  To: lethal, magnus.damm, alan, gregkh
  Cc: rjw, takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

Symptom:

When entering the suspend with Android logcat running, printk() call
gets stuck and never returns.  The issue can be observed at printk()s
on nonboot CPUs when going to offline with their interrupts disabled,
and never seen at boot CPU (core0 in our case).

Details:

serial_console_write() lacks of appropriate spinlock handling.

In SMP systems, as long as sci_transmit_chars() is being processed
at one CPU core, serial_console_write() can stuck at the other CPU
core(s), when it tries to access to the same serial port _without_
a proper locking.  serial_console_write() waits for the transmit FIFO
getting empty, while sci_transmit_chars() writes data to the FIFO.

In general, peripheral interrupts are routed to boot CPU (core0) by
Linux ARM standard affinity settings.  SCI(F) interrupts are handled
by core0, so sci_transmit_chars() is processed on core0 as well.

When logcat is running, it writes enormous log data to the kernel at
every moment, forever.  So core0 can repeatedly continue to process
sci_transmit_chars() in its interrupt handler, which eventually makes
the other CPU core(s) stuck at serial_console_write().

Looking at serial/8250.c, this is a known console write lockup issue
with SMP kernels.  Fix the sh-sci driver in the same way 8250.c does.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---

Similar fixes can be found at:

|commit ef605fdb33883d687cff5ba75095a91b313b4966
|Author: Rabin Vincent <rabin.vincent@stericsson.com>
|Date:   Tue Jan 17 11:52:28 2012 +0100
|
|    serial: amba-pl011: lock console writes against interrupts

|commit 9ec1882df244c4ee1baa692676fef5e8b0f5487d
|Author: Xinyu Chen <xinyu.chen@freescale.com>
|Date:   Mon Aug 27 09:36:51 2012 +0200
|
|    tty: serial: imx: console write routing is unsafe on SMP

 drivers/tty/serial/sh-sci.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 502fa47..0b8d029 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2202,7 +2202,21 @@ static void serial_console_write(struct console *co, const char *s,
 {
 	struct sci_port *sci_port = &sci_ports[co->index];
 	struct uart_port *port = &sci_port->port;
-	unsigned short bits;
+	unsigned short bits, ctrl;
+	unsigned long flags;
+	int locked = 1;
+
+	local_irq_save(flags);
+	if (port->sysrq)
+		locked = 0;
+	else if (oops_in_progress)
+		locked = spin_trylock(&port->lock);
+	else
+		spin_lock(&port->lock);
+
+	/* first save the SCSCR then disable the interrupts */
+	ctrl = serial_port_in(port, SCSCR);
+	serial_port_out(port, SCSCR, sci_port->cfg->scscr);
 
 	uart_console_write(port, s, count, serial_console_putchar);
 
@@ -2210,6 +2224,13 @@ static void serial_console_write(struct console *co, const char *s,
 	bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
 	while ((serial_port_in(port, SCxSR) & bits) != bits)
 		cpu_relax();
+
+	/* restore the SCSCR */
+	serial_port_out(port, SCSCR, ctrl);
+
+	if (locked)
+		spin_unlock(&port->lock);
+	local_irq_restore(flags);
 }
 
 static int __devinit serial_console_setup(struct console *co, char *options)
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 08/10] serial: sh-sci: fix common SCIFB regmap definition
From: Shinya Kuribayashi @ 2012-11-16  1:53 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

From: Takashi Yoshii <takashi.yoshii.zj@renesas.com>

About FIFO count, there are two variants of SCIFs which show
a) TX count in upper, RX count in lower byte of FDR register
b) TX count in TFDR register, RX count in RFDR register

Common SCIFB regmap in current source code is defined as "a".
At least 7372 and 73a0 HW manual say their SICFB are "b".

This patch alters the definition to "b", considering the current
one has come from a mistake. The reason is as follows.

The flag SCIFB sh-sci driver means it has 256 byte FIFO.
The count is from 0(empty) to 256(full), that makes 9-bit.
Because FDR is 16-bit register, it can not hold two 9-bits.
That's why, SCIFB can not be "a".

Signed-off-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com>
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 63a3bd0..502fa47 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -196,9 +196,9 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
 		[SCxSR]		= { 0x14, 16 },
 		[SCxRDR]	= { 0x60,  8 },
 		[SCFCR]		= { 0x18, 16 },
-		[SCFDR]		= { 0x1c, 16 },
-		[SCTFDR]	= sci_reg_invalid,
-		[SCRFDR]	= sci_reg_invalid,
+		[SCFDR]		= sci_reg_invalid,
+		[SCTFDR]	= { 0x38, 16 },
+		[SCRFDR]	= { 0x3c, 16 },
 		[SCSPTR]	= sci_reg_invalid,
 		[SCLSR]		= sci_reg_invalid,
 	},
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 07/10] serial: sh-sci: mask SCTFDR/RFDR according to fifosize
From: Shinya Kuribayashi @ 2012-11-16  1:53 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

From: Takashi Yoshii <takashi.yoshii.zj@renesas.com>

Current mask 0xff to SCTFDR/RFDR damages SCIFB, because the
registers on SCIFB have 9-bit data (0 to 256).

This patch changes the mask according to port->fifosize.
Though I'm not sure if the mask is really needed (I don't know if
there are variants which have non-zero upper bits), it is safer.

Signed-off-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com>
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 3021912..63a3bd0 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -485,7 +485,7 @@ static int sci_txfill(struct uart_port *port)
 
 	reg = sci_getreg(port, SCTFDR);
 	if (reg->size)
-		return serial_port_in(port, SCTFDR) & 0xff;
+		return serial_port_in(port, SCTFDR) & ((port->fifosize << 1) - 1);
 
 	reg = sci_getreg(port, SCFDR);
 	if (reg->size)
@@ -505,7 +505,7 @@ static int sci_rxfill(struct uart_port *port)
 
 	reg = sci_getreg(port, SCRFDR);
 	if (reg->size)
-		return serial_port_in(port, SCRFDR) & 0xff;
+		return serial_port_in(port, SCRFDR) & ((port->fifosize << 1) - 1);
 
 	reg = sci_getreg(port, SCFDR);
 	if (reg->size)
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 06/10] serial: sh-sci: support lower baud rate
From: Shinya Kuribayashi @ 2012-11-16  1:52 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

From: Takashi Yoshii <takashi.yoshii.zj@renesas.com>

Support prescaler 1/16 and 1/64, in addition to current 1 and 1/4.

Supporting below 2400bps was dropped long time ago in mainline.
Since then, setting lower rate has been resulting in erroneous
register value, without indicating any errors through API.

This patch adds more prescaler to support lower rates again.
This still doesn't check range, but we won't hit the case because
even 50bps at 48MHz clock is now supported.

Signed-off-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com>
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ffeca65..3021912 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1814,7 +1814,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 {
 	struct sci_port *s = to_sci_port(port);
 	struct plat_sci_reg *reg;
-	unsigned int baud, smr_val, max_baud;
+	unsigned int baud, smr_val, max_baud, cks;
 	int t = -1;
 
 	/*
@@ -1848,21 +1848,18 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	uart_update_timeout(port, termios->c_cflag, baud);
 
-	serial_port_out(port, SCSMR, smr_val);
+	for (cks = 0; t >= 256 && cks <= 3; cks++)
+		t >>= 2;
 
-	dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
-		s->cfg->scscr);
+	dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n",
+		__func__, smr_val, cks, t, s->cfg->scscr);
 
 	if (t >= 0) {
-		if (t >= 256) {
-			serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1);
-			t >>= 2;
-		} else
-			serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3);
-
+		serial_port_out(port, SCSMR, (smr_val & ~3) | cks);
 		serial_port_out(port, SCBRR, t);
 		udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
-	}
+	} else
+		serial_port_out(port, SCSMR, smr_val);
 
 	sci_init_pins(port, termios->c_cflag);
 
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 05/10] serial: sh-sci: fix condition test to set SCBRR
From: Shinya Kuribayashi @ 2012-11-16  1:52 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

From: Takashi Yoshii <takashi.yoshii.zj@renesas.com>

SCBRR == 0 is valid value (divide by 1).

Signed-off-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com>
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index e65e546..ffeca65 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1853,7 +1853,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 	dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
 		s->cfg->scscr);
 
-	if (t > 0) {
+	if (t >= 0) {
 		if (t >= 256) {
 			serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1);
 			t >>= 2;
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 04/10] serial: sh-sci: console runtime PM support (revisit)
From: Shinya Kuribayashi @ 2012-11-16  1:51 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

From: Teppei Kamijou <teppei.kamijou.yb@renesas.com>

The commit 1ba7622094 (serial: sh-sci: console Runtime PM support,
from Magnus Damm <damm@opensource.se>, 2011-08-03), tried to support
console runtime PM, but unfortunately it didn't work for us for some
reason.  We did not investigated further at that time, instead would
like to propose a different approach.

In Linux tty/serial world, to get console PM work properly, a serial
client driver does not have to maintain .runtime_suspend()/..resume()
calls itself, but can leave console power power management handling to
the serial core driver.

This patch moves the sh-sci driver in that direction.

Notes:

* There is room to optimize console runtime PM more aggressively by
  maintaining additional local runtime PM calls, but as a first step
  having .pm() operation would suffice.

* We still have a couple of direct calls to sci_port_enable/..disable
  left in the driver.  We have to live with them, because they're out
  of serial core's help.

Signed-off-by: Teppei Kamijou <teppei.kamijou.yb@renesas.com>
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index e9e8883..e65e546 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1746,8 +1746,6 @@ static int sci_startup(struct uart_port *port)
 
 	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
 
-	sci_port_enable(s);
-
 	ret = sci_request_irq(s);
 	if (unlikely(ret < 0))
 		return ret;
@@ -1771,8 +1769,6 @@ static void sci_shutdown(struct uart_port *port)
 
 	sci_free_dma(port);
 	sci_free_irq(s);
-
-	sci_port_disable(s);
 }
 
 static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
@@ -1921,6 +1917,21 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 	sci_port_disable(s);
 }
 
+static void sci_pm(struct uart_port *port, unsigned int state,
+		   unsigned int oldstate)
+{
+	struct sci_port *sci_port = to_sci_port(port);
+
+	switch (state) {
+	case 3:
+		sci_port_disable(sci_port);
+		break;
+	default:
+		sci_port_enable(sci_port);
+		break;
+	}
+}
+
 static const char *sci_type(struct uart_port *port)
 {
 	switch (port->type) {
@@ -2042,6 +2053,7 @@ static struct uart_ops sci_uart_ops = {
 	.startup	= sci_startup,
 	.shutdown	= sci_shutdown,
 	.set_termios	= sci_set_termios,
+	.pm		= sci_pm,
 	.type		= sci_type,
 	.release_port	= sci_release_port,
 	.request_port	= sci_request_port,
@@ -2195,16 +2207,12 @@ static void serial_console_write(struct console *co, const char *s,
 	struct uart_port *port = &sci_port->port;
 	unsigned short bits;
 
-	sci_port_enable(sci_port);
-
 	uart_console_write(port, s, count, serial_console_putchar);
 
 	/* wait until fifo is empty and last bit has been transmitted */
 	bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
 	while ((serial_port_in(port, SCxSR) & bits) != bits)
 		cpu_relax();
-
-	sci_port_disable(sci_port);
 }
 
 static int __devinit serial_console_setup(struct console *co, char *options)
@@ -2236,12 +2244,9 @@ static int __devinit serial_console_setup(struct console *co, char *options)
 	if (unlikely(ret != 0))
 		return ret;
 
-	sci_port_enable(sci_port);
-
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 
-	/* TODO: disable clock */
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 03/10] Partially revert "serial: sh-sci: console Runtime PM support"
From: Shinya Kuribayashi @ 2012-11-16  1:51 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

This partially reverts commit 1ba7622094 (serial: sh-sci: console
Runtime PM support, from Magnus Damm <damm@opensource.se>, 2011-08-03).

The generic 'serial_core' can take care of console PM maintenance,
so all (or at least the first thing) we have to do to get console PM
work properly, is to implement uart_ops ->pm() operation in the sh-sci
serial client driver.

This patch partially reverts the commit above, but leaving sci_reset()
change in place, because sci_reset() is already part of another commit
(73c3d53f38 serial: sh-sci: Avoid FIFO clear for MCE toggle.).

A revised version of console PM support follows next.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 53 +--------------------------------------------
 1 file changed, 1 insertion(+), 52 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9abe977..e9e8883 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -99,12 +99,6 @@ struct sci_port {
 #endif
 
 	struct notifier_block		freq_transition;
-
-#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
-	unsigned short saved_smr;
-	unsigned short saved_fcr;
-	unsigned char saved_brr;
-#endif
 };
 
 /* Function prototypes */
@@ -2247,8 +2241,7 @@ static int __devinit serial_console_setup(struct console *co, char *options)
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 
-	sci_port_disable(sci_port);
-
+	/* TODO: disable clock */
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
@@ -2291,46 +2284,6 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
 	return 0;
 }
 
-#define uart_console(port)	((port)->cons->index == (port)->line)
-
-static int sci_runtime_suspend(struct device *dev)
-{
-	struct sci_port *sci_port = dev_get_drvdata(dev);
-	struct uart_port *port = &sci_port->port;
-
-	if (uart_console(port)) {
-		struct plat_sci_reg *reg;
-
-		sci_port->saved_smr = serial_port_in(port, SCSMR);
-		sci_port->saved_brr = serial_port_in(port, SCBRR);
-
-		reg = sci_getreg(port, SCFCR);
-		if (reg->size)
-			sci_port->saved_fcr = serial_port_in(port, SCFCR);
-		else
-			sci_port->saved_fcr = 0;
-	}
-	return 0;
-}
-
-static int sci_runtime_resume(struct device *dev)
-{
-	struct sci_port *sci_port = dev_get_drvdata(dev);
-	struct uart_port *port = &sci_port->port;
-
-	if (uart_console(port)) {
-		sci_reset(port);
-		serial_port_out(port, SCSMR, sci_port->saved_smr);
-		serial_port_out(port, SCBRR, sci_port->saved_brr);
-
-		if (sci_port->saved_fcr)
-			serial_port_out(port, SCFCR, sci_port->saved_fcr);
-
-		serial_port_out(port, SCSCR, sci_port->cfg->scscr);
-	}
-	return 0;
-}
-
 #define SCI_CONSOLE	(&serial_console)
 
 #else
@@ -2340,8 +2293,6 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
 }
 
 #define SCI_CONSOLE	NULL
-#define sci_runtime_suspend	NULL
-#define sci_runtime_resume	NULL
 
 #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
 
@@ -2459,8 +2410,6 @@ static int sci_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops sci_dev_pm_ops = {
-	.runtime_suspend = sci_runtime_suspend,
-	.runtime_resume = sci_runtime_resume,
 	.suspend	= sci_suspend,
 	.resume		= sci_resume,
 };
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 02/10] Revert "sh-sci / PM: Use power.irq_safe"
From: Shinya Kuribayashi @ 2012-11-16  1:51 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

This reverts commit 5a50a01bf0 (sh-sci / PM: Use power.irq_safe, from
Rafael J. Wysocki <rjw@sisk.pl>, 2011-08-24).

In order to get console PM work properly, we should implement uart_ops
->pm() operation, rather than sprinkle band-ading runtime PM calls in
the driver.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 526ad04..9abe977 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2116,7 +2116,6 @@ static int __devinit sci_init_single(struct platform_device *dev,
 
 		sci_init_gpios(sci_port);
 
-		pm_runtime_irq_safe(&dev->dev);
 		pm_runtime_enable(&dev->dev);
 	}
 
-- 
1.7.12.4


^ permalink raw reply related

* [PATCH v2 01/10] Revert "sh-sci / PM: Avoid deadlocking runtime PM"
From: Shinya Kuribayashi @ 2012-11-16  1:50 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <50A59B9B.2010501@renesas.com>

This reverts commit 048be431e4 (sh-sci / PM: Avoid deadlocking runtime
PM, from Rafael J. Wysocki <rjw@sisk.pl>, 2012-03-09).

In order to get console PM work properly, we should implement uart_ops
->pm() operation, rather than sprinkle band-ading runtime PM calls in
the driver.

Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
---
 drivers/tty/serial/sh-sci.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9be296c..526ad04 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1752,8 +1752,6 @@ static int sci_startup(struct uart_port *port)
 
 	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
 
-	pm_runtime_put_noidle(port->dev);
-
 	sci_port_enable(s);
 
 	ret = sci_request_irq(s);
@@ -1781,8 +1779,6 @@ static void sci_shutdown(struct uart_port *port)
 	sci_free_irq(s);
 
 	sci_port_disable(s);
-
-	pm_runtime_get_noresume(port->dev);
 }
 
 static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
@@ -2121,7 +2117,6 @@ static int __devinit sci_init_single(struct platform_device *dev,
 		sci_init_gpios(sci_port);
 
 		pm_runtime_irq_safe(&dev->dev);
-		pm_runtime_get_noresume(&dev->dev);
 		pm_runtime_enable(&dev->dev);
 	}
 
-- 
1.7.12.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox