Linux Serial subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH 02/10] arm: at91: move platfarm_data to include/linux/platform_data/atmel.h
From: Marc Kleine-Budde @ 2012-11-07 12:20 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD
  Cc: linux-arm-kernel, Nicolas Ferre, linux-ide, linux-input,
	linux-mmc, linux-can, netdev, linux-pcmcia, rtc-linux,
	spi-devel-general, linux-serial, linux-usb, linux-fbdev
In-Reply-To: <1352287374-25176-2-git-send-email-plagnioj@jcrosoft.com>

[-- Attachment #1: Type: text/plain, Size: 1147 bytes --]

On 11/07/2012 12:22 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: linux-ide@vger.kernel.org
> Cc: linux-input@vger.kernel.org
> Cc: linux-mmc@vger.kernel.org
> Cc: linux-can@vger.kernel.org
> Cc: netdev@vger.kernel.org
> Cc: linux-pcmcia@lists.infradead.org
> Cc: rtc-linux@googlegroups.com
> Cc: spi-devel-general@lists.sourceforge.net
> Cc: linux-serial@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> Cc: linux-fbdev@vger.kernel.org
> ---
> HI all,
> 
> 	If it's ok with everyone this will go via at91
> 	with the patch serie than clean up the include/mach

Fine with me.

> 	For preparation to switch to arm multiarch kernel

Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> (for the CAN related changes)

Marc


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply

* [PATCH 02/10] arm: at91: move platfarm_data to include/linux/platform_data/atmel.h
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-07 11:22 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-fbdev, linux-usb, rtc-linux, linux-mmc, linux-pcmcia,
	Nicolas Ferre, linux-can, linux-ide, netdev, linux-serial,
	linux-input, spi-devel-general, Jean-Christophe PLAGNIOL-VILLARD
In-Reply-To: <1352287374-25176-1-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: linux-ide@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
Cc: linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-pcmcia@lists.infradead.org
Cc: rtc-linux@googlegroups.com
Cc: spi-devel-general@lists.sourceforge.net
Cc: linux-serial@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Cc: linux-fbdev@vger.kernel.org
---
HI all,

	If it's ok with everyone this will go via at91
	with the patch serie than clean up the include/mach

	For preparation to switch to arm multiarch kernel

Best Regards,
J.
 arch/arm/mach-at91/include/mach/board.h     |   55 ----------------------
 arch/avr32/mach-at32ap/include/mach/board.h |    7 ---
 drivers/ata/pata_at91.c                     |    2 +-
 drivers/input/touchscreen/atmel_tsadcc.c    |    2 +-
 drivers/mmc/host/atmel-mci.c                |    2 +-
 drivers/net/can/at91_can.c                  |    3 +-
 drivers/net/ethernet/cadence/at91_ether.c   |    2 +-
 drivers/pcmcia/at91_cf.c                    |    2 +-
 drivers/rtc/rtc-at91sam9.c                  |    2 +-
 drivers/spi/spi-atmel.c                     |    2 +-
 drivers/tty/serial/atmel_serial.c           |    2 +-
 drivers/usb/gadget/at91_udc.c               |    2 +-
 drivers/usb/gadget/atmel_usba_udc.c         |    2 +-
 drivers/usb/host/ohci-at91.c                |    2 +-
 drivers/video/atmel_lcdfb.c                 |    2 +-
 include/linux/platform_data/atmel.h         |   67 +++++++++++++++++++++++++++
 16 files changed, 80 insertions(+), 76 deletions(-)

diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index c55a436..662451d 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -31,42 +31,15 @@
 #ifndef __ASM_ARCH_BOARD_H
 #define __ASM_ARCH_BOARD_H
 
-#include <linux/mtd/partitions.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/atmel_usba_udc.h>
-#include <linux/atmel-mci.h>
-#include <sound/atmel-ac97c.h>
-#include <linux/serial.h>
-#include <linux/platform_data/macb.h>
 #include <linux/platform_data/atmel.h>
 
  /* USB Device */
-struct at91_udc_data {
-	int	vbus_pin;		/* high == host powering us */
-	u8	vbus_active_low;	/* vbus polarity */
-	u8	vbus_polled;		/* Use polling, not interrupt */
-	int	pullup_pin;		/* active == D+ pulled up */
-	u8	pullup_active_low;	/* true == pullup_pin is active low */
-};
 extern void __init at91_add_device_udc(struct at91_udc_data *data);
 
  /* USB High Speed Device */
 extern void __init at91_add_device_usba(struct usba_platform_data *data);
 
  /* Compact Flash */
-struct at91_cf_data {
-	int	irq_pin;		/* I/O IRQ */
-	int	det_pin;		/* Card detect */
-	int	vcc_pin;		/* power switching */
-	int	rst_pin;		/* card reset */
-	u8	chipselect;		/* EBI Chip Select number */
-	u8	flags;
-#define AT91_CF_TRUE_IDE	0x01
-#define AT91_IDE_SWAP_A0_A2	0x02
-};
 extern void __init at91_add_device_cf(struct at91_cf_data *data);
 
  /* MMC / SD */
@@ -86,16 +59,6 @@ extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *d
 extern void __init at91_add_device_eth(struct macb_platform_data *data);
 
  /* USB Host */
-#define AT91_MAX_USBH_PORTS	3
-struct at91_usbh_data {
-	int		vbus_pin[AT91_MAX_USBH_PORTS];	/* port power-control pin */
-	int             overcurrent_pin[AT91_MAX_USBH_PORTS];
-	u8		ports;				/* number of ports on root hub */
-	u8              overcurrent_supported;
-	u8              vbus_pin_active_low[AT91_MAX_USBH_PORTS];
-	u8              overcurrent_status[AT91_MAX_USBH_PORTS];
-	u8              overcurrent_changed[AT91_MAX_USBH_PORTS];
-};
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
@@ -124,13 +87,6 @@ extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pin
 
 extern struct platform_device *atmel_default_console_device;
 
-struct atmel_uart_data {
-	int			num;		/* port num */
-	short			use_dma_tx;	/* use transmit DMA? */
-	short			use_dma_rx;	/* use receive DMA? */
-	void __iomem		*regs;		/* virt. base address, if any */
-	struct serial_rs485	rs485;		/* rs485 settings */
-};
 extern void __init at91_add_device_serial(void);
 
 /*
@@ -173,24 +129,13 @@ extern void __init at91_add_device_isi(struct isi_platform_data *data,
 		bool use_pck_as_mck);
 
  /* Touchscreen Controller */
-struct at91_tsadcc_data {
-	unsigned int    adc_clock;
-	u8		pendet_debounce;
-	u8		ts_sample_hold_time;
-};
 extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data);
 
 /* CAN */
-struct at91_can_data {
-	void (*transceiver_switch)(int on);
-};
 extern void __init at91_add_device_can(struct at91_can_data *data);
 
  /* LEDs */
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
 extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
 
-/* FIXME: this needs a better location, but gets stuff building again */
-extern int at91_suspend_entering_slow_clock(void);
-
 #endif
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h
index 70742ec..dca9345 100644
--- a/arch/avr32/mach-at32ap/include/mach/board.h
+++ b/arch/avr32/mach-at32ap/include/mach/board.h
@@ -34,13 +34,6 @@ extern struct platform_device *atmel_default_console_device;
 #define	ATMEL_USART_CTS		0x02
 #define	ATMEL_USART_CLK		0x04
 
-struct atmel_uart_data {
-	int		num;		/* port num */
-	short		use_dma_tx;	/* use transmit DMA? */
-	short		use_dma_rx;	/* use receive DMA? */
-	void __iomem	*regs;		/* virtual base address, if any */
-	struct serial_rs485	rs485;		/* rs485 settings */
-};
 void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
 struct platform_device *at32_add_device_usart(unsigned int id);
 
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c
index 53d3770..2a96bb2 100644
--- a/drivers/ata/pata_at91.c
+++ b/drivers/ata/pata_at91.c
@@ -27,9 +27,9 @@
 #include <linux/libata.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
+#include <linux/platform_data/atmel.h>
 
 #include <mach/at91sam9_smc.h>
-#include <mach/board.h>
 #include <asm/gpio.h>
 
 #define DRV_NAME		"pata_at91"
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index 201b2d2..ea392ee 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -22,7 +22,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <mach/board.h>
+#include <linux/platform_data/atmel.h>
 #include <mach/cpu.h>
 
 /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index ddf096e..8689989 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/types.h>
+#include <linux/platform_data/atmel.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/sdio.h>
@@ -40,7 +41,6 @@
 #include <asm/unaligned.h>
 
 #include <mach/cpu.h>
-#include <mach/board.h>
 
 #include "atmel-mci-regs.h"
 
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index fcff73a..994b6ac 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -33,12 +33,11 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/platform_data/atmel.h>
 
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 
-#include <mach/board.h>
-
 #define AT91_MB_MASK(i)		((1 << (i)) - 1)
 
 /* Common registers */
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c
index 4e980a7..35fc6edb 100644
--- a/drivers/net/ethernet/cadence/at91_ether.c
+++ b/drivers/net/ethernet/cadence/at91_ether.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/gfp.h>
 #include <linux/phy.h>
+#include <linux/platform_data/atmel.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -38,7 +39,6 @@
 
 #include <mach/at91rm9200_emac.h>
 #include <asm/gpio.h>
-#include <mach/board.h>
 
 #include "at91_ether.h"
 
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 9694c1e..01463c7 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/atmel.h>
 
 #include <pcmcia/ss.h>
 
@@ -24,7 +25,6 @@
 #include <asm/io.h>
 #include <asm/sizes.h>
 
-#include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
 #include <mach/at91_ramc.h>
 
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 2dfe7a2..e981798 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -19,8 +19,8 @@
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
 #include <linux/slab.h>
+#include <linux/platform_data/atmel.h>
 
-#include <mach/board.h>
 #include <mach/at91_rtt.h>
 #include <mach/cpu.h>
 
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 16d6a83..61fb0ec 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -19,9 +19,9 @@
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/platform_data/atmel.h>
 
 #include <asm/io.h>
-#include <mach/board.h>
 #include <asm/gpio.h>
 #include <mach/cpu.h>
 
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 3d7e1ee..5660ec2 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -39,12 +39,12 @@
 #include <linux/atmel_pdc.h>
 #include <linux/atmel_serial.h>
 #include <linux/uaccess.h>
+#include <linux/platform_data/atmel.h>
 
 #include <asm/io.h>
 #include <asm/ioctls.h>
 
 #include <asm/mach/serial_at91.h>
-#include <mach/board.h>
 
 #ifdef CONFIG_ARM
 #include <mach/cpu.h>
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 89d90b5..a7b042b 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -31,6 +31,7 @@
 #include <linux/usb/gadget.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_data/atmel.h>
 
 #include <asm/byteorder.h>
 #include <mach/hardware.h>
@@ -38,7 +39,6 @@
 #include <asm/irq.h>
 #include <asm/gpio.h>
 
-#include <mach/board.h>
 #include <mach/cpu.h>
 #include <mach/at91sam9261_matrix.h>
 #include <mach/at91_matrix.h>
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 9a9bced..a7aed84 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -21,9 +21,9 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb/atmel_usba_udc.h>
 #include <linux/delay.h>
+#include <linux/platform_data/atmel.h>
 
 #include <asm/gpio.h>
-#include <mach/board.h>
 
 #include "atmel_usba_udc.h"
 
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 0bf72f9..8e62f81 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -16,11 +16,11 @@
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_data/atmel.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
-#include <mach/board.h>
 #include <mach/cpu.h>
 
 #ifndef CONFIG_ARCH_AT91
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 94cac9f..12cf5f3 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -19,8 +19,8 @@
 #include <linux/backlight.h>
 #include <linux/gfp.h>
 #include <linux/module.h>
+#include <linux/platform_data/atmel.h>
 
-#include <mach/board.h>
 #include <mach/cpu.h>
 #include <asm/gpio.h>
 
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index b0f2c56..dbd6d53 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -8,6 +8,49 @@
 #define __ATMEL_H__
 
 #include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/atmel_usba_udc.h>
+#include <linux/atmel-mci.h>
+#include <sound/atmel-ac97c.h>
+#include <linux/serial.h>
+#include <linux/platform_data/macb.h>
+
+ /* USB Device */
+struct at91_udc_data {
+	int	vbus_pin;		/* high == host powering us */
+	u8	vbus_active_low;	/* vbus polarity */
+	u8	vbus_polled;		/* Use polling, not interrupt */
+	int	pullup_pin;		/* active == D+ pulled up */
+	u8	pullup_active_low;	/* true == pullup_pin is active low */
+};
+
+ /* Compact Flash */
+struct at91_cf_data {
+	int	irq_pin;		/* I/O IRQ */
+	int	det_pin;		/* Card detect */
+	int	vcc_pin;		/* power switching */
+	int	rst_pin;		/* card reset */
+	u8	chipselect;		/* EBI Chip Select number */
+	u8	flags;
+#define AT91_CF_TRUE_IDE	0x01
+#define AT91_IDE_SWAP_A0_A2	0x02
+};
+
+ /* USB Host */
+#define AT91_MAX_USBH_PORTS	3
+struct at91_usbh_data {
+	int		vbus_pin[AT91_MAX_USBH_PORTS];	/* port power-control pin */
+	int             overcurrent_pin[AT91_MAX_USBH_PORTS];
+	u8		ports;				/* number of ports on root hub */
+	u8              overcurrent_supported;
+	u8              vbus_pin_active_low[AT91_MAX_USBH_PORTS];
+	u8              overcurrent_status[AT91_MAX_USBH_PORTS];
+	u8              overcurrent_changed[AT91_MAX_USBH_PORTS];
+};
 
  /* NAND / SmartMedia */
 struct atmel_nand_data {
@@ -24,4 +67,28 @@ struct atmel_nand_data {
 	unsigned int	num_parts;
 };
 
+ /* Serial */
+struct atmel_uart_data {
+	int			num;		/* port num */
+	short			use_dma_tx;	/* use transmit DMA? */
+	short			use_dma_rx;	/* use receive DMA? */
+	void __iomem		*regs;		/* virt. base address, if any */
+	struct serial_rs485	rs485;		/* rs485 settings */
+};
+
+ /* Touchscreen Controller */
+struct at91_tsadcc_data {
+	unsigned int    adc_clock;
+	u8		pendet_debounce;
+	u8		ts_sample_hold_time;
+};
+
+/* CAN */
+struct at91_can_data {
+	void (*transceiver_switch)(int on);
+};
+
+/* FIXME: this needs a better location, but gets stuff building again */
+extern int at91_suspend_entering_slow_clock(void);
+
 #endif /* __ATMEL_H__ */
-- 
1.7.10.4

^ permalink raw reply related

* RE: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty.
From: Chen, Jun D @ 2012-11-07  9:09 UTC (permalink / raw)
  To: Alan Cox; +Cc: Alan Cox, serial, Gorby, Russ, Bi, Chao
In-Reply-To: <20121106094728.7ed9d586@pyramind.ukuu.org.uk>

Hi,Alan
	Thank for your question, I will update this patch in other email. 
 
-----Original Message-----
From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk] 
Sent: Tuesday, November 06, 2012 5:47 PM
To: Chen, Jun D
Cc: Alan Cox; serial; Gorby, Russ; Bi, Chao
Subject: Re: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty.

On Tue, 06 Nov 2012 04:28:54 -0500
Jun Chen <jun.d.chen@intel.com> wrote:

> 
> This patch check whether the kfifo lenth equal to the count of write 
> data.If condition is true,ifx_spi_write need to trigger one 
> mrdy_assert. If condition is false,the mrdy_assert will be triggered 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 |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/tty/serial/ifx6x60.c 
> b/drivers/tty/serial/ifx6x60.c index ac718e1..b52ef8d 100644
> --- a/drivers/tty/serial/ifx6x60.c
> +++ b/drivers/tty/serial/ifx6x60.c
> @@ -522,7 +522,8 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
>  	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);
> +	if (kfifo_len(&ifx_dev->tx_fifo) == count)
> +		mrdy_assert(ifx_dev);
>  	return tx_count;

I'm not convinced this is safe. What stops the sending task from emptying data out of the fifo between the kfifo_in_locked and the kfifo_len check ?

Can't you just check tx_count ?

Alan

^ permalink raw reply

* Re: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty
From: Alan Cox @ 2012-11-07  9:11 UTC (permalink / raw)
  To: Jun Chen; +Cc: Alan Cox, Bi Chao, serial, russ.gorby
In-Reply-To: <1352307844.4332.63.camel@chenjun-workstation>

On Wed, 07 Nov 2012 12:04:04 -0500
Jun Chen <jun.d.chen@intel.com> wrote:

> 
> 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>

Acked-by: Alan Cox <alan@linux.intel.com>

^ 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-07 17:04 UTC (permalink / raw)
  To: Alan Cox; +Cc: Bi Chao, serial, russ.gorby, Jun Chen


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 |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index a688f8f..4a21f5e 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -520,9 +520,16 @@ 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);
+	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);
+	int 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

* Re: [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.
From: Alan Cox @ 2012-11-07  8:47 UTC (permalink / raw)
  To: Jun Chen; +Cc: Alan Cox, serial, russ.gorby, liu chuansheng, Bi Chao
In-Reply-To: <1352286374.4332.52.camel@chenjun-workstation>


> 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>

^ permalink raw reply

* Re: [PATCH 00/10] serial: sh-sci fixes - console PM, SCIFB, SMP lockup, etc.
From: Shinya Kuribayashi @ 2012-11-07  7:18 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh, takashi.yoshii.zj
  Cc: linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@renesas.com>

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.
--
Shinya Kuribayashi
Renesas Electronics

^ permalink raw reply

* [PATCH 10/10] serial: sh-sci: fix possible race cases on SCSCR register accesses
From: Shinya Kuribayashi @ 2012-11-07  7:01 UTC (permalink / raw)
  To: lethal, magnus.damm, alan, gregkh
  Cc: rjw, takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 09/10] serial: sh-sci: add locking to console write function to avoid SMP lockup
From: Shinya Kuribayashi @ 2012-11-07  7:00 UTC (permalink / raw)
  To: lethal, magnus.damm, alan, gregkh
  Cc: rjw, takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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>

|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 08/10] serial: sh-sci: fix common SCIFB regmap definition
From: Shinya Kuribayashi @ 2012-11-07  7:00 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 07/10] serial: sh-sci: mask SCTFDR/RFDR according to fifosize
From: Shinya Kuribayashi @ 2012-11-07  7:00 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 06/10] serial: sh-sci: support lower baud rate
From: Shinya Kuribayashi @ 2012-11-07  6:59 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 05/10] serial: sh-sci: fix condition test to set SCBRR
From: Shinya Kuribayashi @ 2012-11-07  6:59 UTC (permalink / raw)
  To: lethal, magnus.damm, takashi.yoshii.zj, alan, gregkh
  Cc: rjw, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 04/10] serial: sh-sci: console runtime PM support (revisit)
From: Shinya Kuribayashi @ 2012-11-07  6:59 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 03/10] Partially revert "serial: sh-sci: console Runtime PM support"
From: Shinya Kuribayashi @ 2012-11-07  6:58 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 02/10] Revert "sh-sci / PM: Use power.irq_safe"
From: Shinya Kuribayashi @ 2012-11-07  6:58 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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 01/10] Revert "sh-sci / PM: Avoid deadlocking runtime PM"
From: Shinya Kuribayashi @ 2012-11-07  6:58 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh
  Cc: takashi.yoshii.zj, linux-serial, linux-arm-kernel, linux-sh
In-Reply-To: <509A0658.1010503@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

* [PATCH 00/10] serial: sh-sci fixes - console PM, SCIFB, SMP lockup, etc.
From: Shinya Kuribayashi @ 2012-11-07  6:57 UTC (permalink / raw)
  To: lethal, magnus.damm, rjw, alan, gregkh, takashi.yoshii.zj
  Cc: linux-serial, linux-arm-kernel, linux-sh

Hi Paul and serial forks,

Here are sh-sci serial driver fixes that have been cooking for months
privately on my end:
* console PM rework with the help of serial-core's uart_change_pm()
* provide missing piece in SCIFB support (from Yoshii-san)
* address console write function vs. SMP lockup issue

and so on.  Comments and suggestions are welcome.

Build tested with vanilla v3.6, but not boot- nor PM-tested with
newer kernels after v3.4.  Anyone with can-sleep shmobile systems,
please give it try.

Thanks in advance,

----------------------------------------------------------------
Shinya Kuribayashi (5):
      Revert "sh-sci / PM: Avoid deadlocking runtime PM"
      Revert "sh-sci / PM: Use power.irq_safe"
      Partially revert "serial: sh-sci: console Runtime PM support"
      serial: sh-sci: add locking to console write function to avoid SMP lockup
      serial: sh-sci: fix possible race cases on SCSCR register accesses

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(-)

-- 
Shinya Kuribayashi
Renesas Electronics

^ permalink raw reply

* [PATCH] serial: bfin-uart: avoid dead lock in rx irq handler in smp kernel
From: Sonic Zhang @ 2012-11-07  5:27 UTC (permalink / raw)
  To: linux-serial, Greg Kroah-Hartman
  Cc: uclinux-dist-devel, Steven Miao, Sonic Zhang

From: Steven Miao <realmz6@gmail.com>

Disabing dma irq and lock bottom half in smp kernel doesn't ensure exclusive
uart access. Call spin_lock_irqsave() instead.

Signed-off-by: Steven Miao <realmz6@gmail.com>
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
---
 drivers/tty/serial/bfin_uart.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 71c0c09..870a744 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
 void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
 {
 	int x_pos, pos;
+	unsigned long flags;
 
-	dma_disable_irq_nosync(uart->rx_dma_channel);
-	spin_lock_bh(&uart->rx_lock);
+	spin_lock_irqsave(&uart->rx_lock, flags);
 
 	/* 2D DMA RX buffer ring is used. Because curr_y_count and
 	 * curr_x_count can't be read as an atomic operation,
@@ -510,8 +510,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
 		uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
 	}
 
-	spin_unlock_bh(&uart->rx_lock);
-	dma_enable_irq(uart->rx_dma_channel);
+	spin_unlock_irqrestore(&uart->rx_lock, flags);
 
 	mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
 }
-- 
1.7.0.4



^ permalink raw reply related

* [PATCH] serial: bfin_uart: Don't switch baud rate untill the transfer buffer is empty.
From: Sonic Zhang @ 2012-11-07  4:55 UTC (permalink / raw)
  To: linux-serial, Greg Kroah-Hartman; +Cc: uclinux-dist-devel, Sonic Zhang

From: Sonic Zhang <sonic.zhang@analog.com>

set_termios may be invoked before the former data transfer is completed. Block until the
tranfer is done.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
---
 drivers/tty/serial/bfin_uart.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 9242d56..71c0c09 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -869,6 +869,10 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
 
+	/* Wait till the transfer buffer is empty */
+	while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT))
+		barrier();
+
 	/* Disable UART */
 	ier = UART_GET_IER(uart);
 	UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
-- 
1.7.0.4



^ permalink raw reply related

* RE: [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.
From: Chen, Jun D @ 2012-11-07  3:09 UTC (permalink / raw)
  To: Alan Cox; +Cc: Alan Cox, serial, Gorby, Russ, Bi, Chao, Liu, Chuansheng
In-Reply-To: <20121106094535.17daa290@pyramind.ukuu.org.uk>

Hi,Alan,
    Thank for your suggestion for two point, I have updated the patch in other email.

-----Original Message-----
From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk] 
Sent: Tuesday, November 06, 2012 5:46 PM
To: Chen, Jun D
Cc: Alan Cox; serial; Gorby, Russ; Bi, Chao; Liu, Chuansheng
Subject: Re: [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.

>  	dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***");
> +	saved_ifx_dev->hangup_reasons |= HU_TIMEOUT;
>  	ifx_spi_ttyhangup(ifx_dev);

This one should be using ifx_dev->hangup_reasons |=

this part of the code is clean for multiple devices so the ifx_dev pointer should be used (it will always be the same as saved_ifx_dev currently so it's just a tidy up)


> +/**
> + * 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))
> +		goto out;

This case returns 0 - rather than an error like -EBUSY - is that intentional ?

Otherwise

Acked-by: Alan Cox <alan@linux.intel.com>

and the two points noted can be fixed up with a later patch IMHO.

^ permalink raw reply

* [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.
From: Jun Chen @ 2012-11-07 11:06 UTC (permalink / raw)
  To: Alan Cox; +Cc: serial, russ.gorby, liu chuansheng, Bi Chao, jun.d.chen


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>
---
 drivers/tty/serial/Kconfig   |    2 +-
 drivers/tty/serial/ifx6x60.c |  194 +++++++++++++++++++++++++++++++++++++++++-
 drivers/tty/serial/ifx6x60.h |    8 ++
 3 files changed, 202 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 233fbaa..5ddff34 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 769396a..a688f8f 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 */
 
 /**
@@ -193,7 +244,6 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev)
 			ifx_dev->spi_timer.expires =
 				jiffies + IFX_SPI_TIMEOUT_SEC*HZ;
 			add_timer(&ifx_dev->spi_timer);
-
 		}
 	}
 	ifx_spi_power_state_set(ifx_dev, IFX_SPI_POWER_DATA_PENDING);
@@ -229,6 +279,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 +932,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 +1457,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..ae48d28 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	/* spi 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

* [PATCH] serial: cast before shifting on port io
From: Alan Cox @ 2012-11-06 14:30 UTC (permalink / raw)
  To: greg, linux-serial

From: Alan Cox <alan@linux.intel.com>

Without this we will shift data into oblivion and give wrong results on
some configurations

Signed-off-by: Alan Cox <alan@linux.intel.com>
---

 drivers/tty/serial/serial_core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 31af2a4..b2b77fd 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2409,7 +2409,7 @@ static ssize_t uart_get_attr_port(struct device *dev,
 	struct tty_port *port = dev_get_drvdata(dev);
 
 	uart_get_info(port, &tmp);
-	return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)(tmp.port | (tmp.port_high << HIGH_BITS_OFFSET)));
+	return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)(tmp.port | (((unsigned long)tmp.port_high) << HIGH_BITS_OFFSET)));
 }
 
 static ssize_t uart_get_attr_irq(struct device *dev,


^ permalink raw reply related

* Re: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty.
From: Alan Cox @ 2012-11-06  9:47 UTC (permalink / raw)
  To: Jun Chen; +Cc: Alan Cox, serial, russ.gorby, chao.bi
In-Reply-To: <1352194134.4332.47.camel@chenjun-workstation>

On Tue, 06 Nov 2012 04:28:54 -0500
Jun Chen <jun.d.chen@intel.com> wrote:

> 
> This patch check whether the kfifo lenth equal to the count of write data.If condition
> is true,ifx_spi_write need to trigger one mrdy_assert. If condition is false,the mrdy_assert
> will be triggered 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 |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
> index ac718e1..b52ef8d 100644
> --- a/drivers/tty/serial/ifx6x60.c
> +++ b/drivers/tty/serial/ifx6x60.c
> @@ -522,7 +522,8 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
>  	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);
> +	if (kfifo_len(&ifx_dev->tx_fifo) == count)
> +		mrdy_assert(ifx_dev);
>  	return tx_count;

I'm not convinced this is safe. What stops the sending task from emptying
data out of the fifo between the kfifo_in_locked and the kfifo_len check ?

Can't you just check tx_count ?

Alan

^ permalink raw reply

* Re: [PATCH] serial: ifx6x60: Add module parameters to manage the modem status through sysfs.
From: Alan Cox @ 2012-11-06  9:45 UTC (permalink / raw)
  To: Jun Chen; +Cc: Alan Cox, serial, russ.gorby, chao.bi, chuansheng.liu
In-Reply-To: <1352193872.4332.44.camel@chenjun-workstation>

>  	dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***");
> +	saved_ifx_dev->hangup_reasons |= HU_TIMEOUT;
>  	ifx_spi_ttyhangup(ifx_dev);

This one should be using ifx_dev->hangup_reasons |=

this part of the code is clean for multiple devices so the ifx_dev
pointer should be used (it will always be the same as saved_ifx_dev
currently so it's just a tidy up)


> +/**
> + * 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))
> +		goto out;

This case returns 0 - rather than an error like -EBUSY - is that
intentional ?

Otherwise

Acked-by: Alan Cox <alan@linux.intel.com>

and the two points noted can be fixed up with a later patch IMHO.

^ permalink raw reply


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