Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.39 2/3] ARM: simpad: Cleanup CS3 accessors and add GPIO API
From: Jochen Friedrich @ 2011-02-11 12:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297427836-6341-1-git-send-email-jochen@scram.de>

- prepend CS3 accessors by simpad_ to indicate they
  are specific to simpad devices.
- use spinlock to protect shadow register.
- implement 8 read-only pins.
- use readl/writel macros so barriers are used where
  necessary.
- register CS3 as GPIO controller with 24 pins
  (16 output only and 8 input only).

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/arm/mach-sa1100/include/mach/simpad.h |   81 ++++++++++++++------
 arch/arm/mach-sa1100/leds-simpad.c         |    7 +-
 arch/arm/mach-sa1100/simpad.c              |  115 ++++++++++++++++++++++------
 drivers/pcmcia/sa1100_simpad.c             |   30 +++----
 4 files changed, 165 insertions(+), 68 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h
index 231550d..db28118 100644
--- a/arch/arm/mach-sa1100/include/mach/simpad.h
+++ b/arch/arm/mach-sa1100/include/mach/simpad.h
@@ -61,32 +61,67 @@
 #define SIMPAD_UCB1X00_GPIO_HEADSET	(SIMPAD_UCB1X00_GPIO_BASE + 8)
 #define SIMPAD_UCB1X00_GPIO_SPEAKER	(SIMPAD_UCB1X00_GPIO_BASE + 9)
 
-// CS3 Latch is write only, a shadow is necessary
+/*--- CS3 Latch ---*/
+#define SIMPAD_CS3_GPIO_BASE		(GPIO_MAX + 11)
+#define SIMPAD_CS3_VCC_5V_EN		(SIMPAD_CS3_GPIO_BASE)
+#define SIMPAD_CS3_VCC_3V_EN		(SIMPAD_CS3_GPIO_BASE + 1)
+#define SIMPAD_CS3_EN1			(SIMPAD_CS3_GPIO_BASE + 2)
+#define SIMPAD_CS3_EN0			(SIMPAD_CS3_GPIO_BASE + 3)
+#define SIMPAD_CS3_DISPLAY_ON		(SIMPAD_CS3_GPIO_BASE + 4)
+#define SIMPAD_CS3_PCMCIA_BUFF_DIS	(SIMPAD_CS3_GPIO_BASE + 5)
+#define SIMPAD_CS3_MQ_RESET		(SIMPAD_CS3_GPIO_BASE + 6)
+#define SIMPAD_CS3_PCMCIA_RESET		(SIMPAD_CS3_GPIO_BASE + 7)
+#define SIMPAD_CS3_DECT_POWER_ON	(SIMPAD_CS3_GPIO_BASE + 8)
+#define SIMPAD_CS3_IRDA_SD		(SIMPAD_CS3_GPIO_BASE + 9)
+#define SIMPAD_CS3_RS232_ON		(SIMPAD_CS3_GPIO_BASE + 10)
+#define SIMPAD_CS3_SD_MEDIAQ		(SIMPAD_CS3_GPIO_BASE + 11)
+#define SIMPAD_CS3_LED2_ON		(SIMPAD_CS3_GPIO_BASE + 12)
+#define SIMPAD_CS3_IRDA_MODE		(SIMPAD_CS3_GPIO_BASE + 13)
+#define SIMPAD_CS3_ENABLE_5V		(SIMPAD_CS3_GPIO_BASE + 14)
+#define SIMPAD_CS3_RESET_SIMCARD	(SIMPAD_CS3_GPIO_BASE + 15)
+
+#define SIMPAD_CS3_PCMCIA_BVD1		(SIMPAD_CS3_GPIO_BASE + 16)
+#define SIMPAD_CS3_PCMCIA_BVD2		(SIMPAD_CS3_GPIO_BASE + 17)
+#define SIMPAD_CS3_PCMCIA_VS1		(SIMPAD_CS3_GPIO_BASE + 18)
+#define SIMPAD_CS3_PCMCIA_VS2		(SIMPAD_CS3_GPIO_BASE + 19)
+#define SIMPAD_CS3_LOCK_IND		(SIMPAD_CS3_GPIO_BASE + 20)
+#define SIMPAD_CS3_CHARGING_STATE	(SIMPAD_CS3_GPIO_BASE + 21)
+#define SIMPAD_CS3_PCMCIA_SHORT		(SIMPAD_CS3_GPIO_BASE + 22)
+#define SIMPAD_CS3_GPIO_23		(SIMPAD_CS3_GPIO_BASE + 23)
 
-#define CS3BUSTYPE unsigned volatile long
 #define CS3_BASE        0xf1000000
 
-#define VCC_5V_EN       0x0001 // For 5V PCMCIA
-#define VCC_3V_EN       0x0002 // FOR 3.3V PCMCIA
-#define EN1             0x0004 // This is only for EPROM's
-#define EN0             0x0008 // Both should be enable for 3.3V or 5V
-#define DISPLAY_ON      0x0010
-#define PCMCIA_BUFF_DIS 0x0020
-#define MQ_RESET        0x0040
-#define PCMCIA_RESET    0x0080
-#define DECT_POWER_ON   0x0100
-#define IRDA_SD         0x0200 // Shutdown for powersave
-#define RS232_ON        0x0400
-#define SD_MEDIAQ       0x0800 // Shutdown for powersave
-#define LED2_ON         0x1000
-#define IRDA_MODE       0x2000 // Fast/Slow IrDA mode
-#define ENABLE_5V       0x4000 // Enable 5V circuit
-#define RESET_SIMCARD   0x8000
-
-#define RS232_ENABLE    0x0440
-#define PCMCIAMASK      0x402f
-
-
+long simpad_get_cs3_ro(void);
+long simpad_get_cs3_shadow(void);
+void simpad_set_cs3_bit(int value);
+void simpad_clear_cs3_bit(int value);
+
+#define VCC_5V_EN	0x0001 /* For 5V PCMCIA */
+#define VCC_3V_EN	0x0002 /* FOR 3.3V PCMCIA */
+#define EN1		0x0004 /* This is only for EPROM's */
+#define EN0		0x0008 /* Both should be enable for 3.3V or 5V */
+#define DISPLAY_ON	0x0010
+#define PCMCIA_BUFF_DIS	0x0020
+#define MQ_RESET	0x0040
+#define PCMCIA_RESET	0x0080
+#define DECT_POWER_ON	0x0100
+#define IRDA_SD		0x0200 /* Shutdown for powersave */
+#define RS232_ON	0x0400
+#define SD_MEDIAQ	0x0800 /* Shutdown for powersave */
+#define LED2_ON		0x1000
+#define IRDA_MODE	0x2000 /* Fast/Slow IrDA mode */
+#define ENABLE_5V	0x4000 /* Enable 5V circuit */
+#define RESET_SIMCARD	0x8000
+
+#define PCMCIA_BVD1	0x01
+#define PCMCIA_BVD2	0x02
+#define PCMCIA_VS1	0x04
+#define PCMCIA_VS2	0x08
+#define LOCK_IND	0x10
+#define CHARGING_STATE	0x20
+#define PCMCIA_SHORT	0x40
+
+/*--- Battery ---*/
 struct simpad_battery {
 	unsigned char ac_status;	/* line connected yes/no */
 	unsigned char status;		/* battery loading yes/no */
diff --git a/arch/arm/mach-sa1100/leds-simpad.c b/arch/arm/mach-sa1100/leds-simpad.c
index d50f4ee..d25784c 100644
--- a/arch/arm/mach-sa1100/leds-simpad.c
+++ b/arch/arm/mach-sa1100/leds-simpad.c
@@ -22,9 +22,6 @@ static unsigned int hw_led_state;
 #define	LED_GREEN	(1)
 #define	LED_MASK	(1)
 
-extern void set_cs3_bit(int value);
-extern void clear_cs3_bit(int value);     
-
 void simpad_leds_event(led_event_t evt)
 {
 	switch (evt)
@@ -93,8 +90,8 @@ void simpad_leds_event(led_event_t evt)
 	}
 
 	if  (led_state & LED_STATE_ENABLED)
-		set_cs3_bit(LED2_ON);
+		simpad_set_cs3_bit(LED2_ON);
 	else 
-	        clear_cs3_bit(LED2_ON);
+		simpad_clear_cs3_bit(LED2_ON);
 }
 
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 718b802..ec6e381 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -13,6 +13,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
@@ -31,32 +32,85 @@
 
 #include "generic.h"
 
-long cs3_shadow;
+/*
+ * CS3 support
+ */
+
+static long cs3_shadow;
+static spinlock_t cs3_lock;
+static struct gpio_chip cs3_gpio;
+
+long simpad_get_cs3_ro(void)
+{
+	return readl(CS3_BASE);
+}
+EXPORT_SYMBOL(simpad_get_cs3_ro);
 
-long get_cs3_shadow(void)
+long simpad_get_cs3_shadow(void)
 {
 	return cs3_shadow;
 }
+EXPORT_SYMBOL(simpad_get_cs3_shadow);
 
-void set_cs3(long value)
+static void __simpad_write_cs3(void)
 {
-	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
+	writel(cs3_shadow, CS3_BASE);
 }
 
-void set_cs3_bit(int value)
+void simpad_set_cs3_bit(int value)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&cs3_lock, flags);
 	cs3_shadow |= value;
-	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+	__simpad_write_cs3();
+	spin_unlock_irqrestore(&cs3_lock, flags);
 }
+EXPORT_SYMBOL(simpad_set_cs3_bit);
 
-void clear_cs3_bit(int value)
+void simpad_clear_cs3_bit(int value)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&cs3_lock, flags);
 	cs3_shadow &= ~value;
-	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+	__simpad_write_cs3();
+	spin_unlock_irqrestore(&cs3_lock, flags);
 }
+EXPORT_SYMBOL(simpad_clear_cs3_bit);
+
+static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	if (offset > 15)
+		return;
+	if (value)
+		simpad_set_cs3_bit(1 << offset);
+	else
+		simpad_clear_cs3_bit(1 << offset);
+};
 
-EXPORT_SYMBOL(set_cs3_bit);
-EXPORT_SYMBOL(clear_cs3_bit);
+static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	if (offset > 15)
+		return simpad_get_cs3_ro() & (1 << (offset - 16));
+	return simpad_get_cs3_shadow() & (1 << offset);
+};
+
+static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	if (offset > 15)
+		return 0;
+	return -EINVAL;
+};
+
+static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+	int value)
+{
+	if (offset > 15)
+		return -EINVAL;
+	cs3_gpio_set(chip, offset, value);
+	return 0;
+};
 
 static struct map_desc simpad_io_desc[] __initdata = {
 	{	/* MQ200 */
@@ -64,9 +118,9 @@ static struct map_desc simpad_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(0x4b800000),
 		.length		= 0x00800000,
 		.type		= MT_DEVICE
-	}, {	/* Paules CS3, write only */
-		.virtual	=  0xf1000000,
-		.pfn		= __phys_to_pfn(0x18000000),
+	}, {	/* Simpad CS3 */
+		.virtual	= CS3_BASE,
+		.pfn		= __phys_to_pfn(SA1100_CS3_PHYS),
 		.length		= 0x00100000,
 		.type		= MT_DEVICE
 	},
@@ -78,12 +132,12 @@ static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 	if (port->mapbase == (u_int)&Ser1UTCR0) {
 		if (state)
 		{
-			clear_cs3_bit(RS232_ON);
-			clear_cs3_bit(DECT_POWER_ON);
+			simpad_clear_cs3_bit(RS232_ON);
+			simpad_clear_cs3_bit(DECT_POWER_ON);
 		}else
 		{
-			set_cs3_bit(RS232_ON);
-			set_cs3_bit(DECT_POWER_ON);
+			simpad_set_cs3_bit(RS232_ON);
+			simpad_set_cs3_bit(DECT_POWER_ON);
 		}
 	}
 }
@@ -143,9 +197,10 @@ static void __init simpad_map_io(void)
 
 	iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
 
-	set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
-		      ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
-
+	/* Initialize CS3 */
+	cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON |
+		RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+	__simpad_write_cs3(); /* Spinlocks not yet initialized */
 
         sa1100_register_uart_fns(&simpad_port_fns);
 	sa1100_register_uart(0, 3);  /* serial interface */
@@ -171,12 +226,13 @@ static void __init simpad_map_io(void)
 
 static void simpad_power_off(void)
 {
-	local_irq_disable(); // was cli
-	set_cs3(0x800);        /* only SD_MEDIAQ */
+	local_irq_disable(); /* was cli */
+	cs3_shadow = SD_MEDIAQ;
+	__simpad_write_cs3(); /* Bypass spinlock here */
 
 	/* disable internal oscillator, float CS lines */
 	PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
-	/* enable wake-up on GPIO0 (Assabet...) */
+	/* enable wake-up on GPIO0 */
 	PWER = GFER = GRER = 1;
 	/*
 	 * set scratchpad to zero, just in case it is used as a
@@ -212,6 +268,19 @@ static int __init simpad_init(void)
 {
 	int ret;
 
+	spin_lock_init(&cs3_lock);
+
+	cs3_gpio.label = "simpad_cs3";
+	cs3_gpio.base = SIMPAD_CS3_GPIO_BASE;
+	cs3_gpio.ngpio = 24;
+	cs3_gpio.set = cs3_gpio_set;
+	cs3_gpio.get = cs3_gpio_get;
+	cs3_gpio.direction_input = cs3_gpio_direction_input;
+	cs3_gpio.direction_output = cs3_gpio_direction_output;
+	ret = gpiochip_add(&cs3_gpio);
+	if (ret)
+		printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
+
 	pm_power_off = simpad_power_off;
 
 	sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index c998f7a..540320d 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -15,10 +15,6 @@
 #include <mach/simpad.h>
 #include "sa1100_generic.h"
  
-extern long get_cs3_shadow(void);
-extern void set_cs3_bit(int value); 
-extern void clear_cs3_bit(int value);
-
 static struct pcmcia_irqs irqs[] = {
 	{ 1, IRQ_GPIO_CF_CD, "CF_CD" },
 };
@@ -26,7 +22,7 @@ static struct pcmcia_irqs irqs[] = {
 static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 
-	clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+	simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
 	skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
 
@@ -38,8 +34,8 @@ static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 
 	/* Disable CF bus: */
-	//set_cs3_bit(PCMCIA_BUFF_DIS);
-	clear_cs3_bit(PCMCIA_RESET);       
+	/*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
+	simpad_clear_cs3_bit(PCMCIA_RESET);
 }
 
 static void
@@ -47,15 +43,15 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 			   struct pcmcia_state *state)
 {
 	unsigned long levels = GPLR;
-	long cs3reg = get_cs3_shadow();
+	long cs3reg = simpad_get_cs3_shadow();
 
 	state->detect=((levels & GPIO_CF_CD)==0)?1:0;
 	state->ready=(levels & GPIO_CF_IRQ)?1:0;
 	state->bvd1=1; /* Not available on Simpad. */
 	state->bvd2=1; /* Not available on Simpad. */
 	state->wrprot=0; /* Not available on Simpad. */
-  
-	if((cs3reg & 0x0c) == 0x0c) {
+
+	if ((cs3reg & 0x0c) == 0x0c) {
 		state->vs_3v=0;
 		state->vs_Xv=0;
 	} else {
@@ -75,23 +71,23 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	/* Murphy: see table of MIC2562a-1 */
 	switch (state->Vcc) {
 	case 0:
-		clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+		simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 		break;
 
 	case 33:  
-		clear_cs3_bit(VCC_3V_EN|EN1);
-		set_cs3_bit(VCC_5V_EN|EN0);
+		simpad_clear_cs3_bit(VCC_3V_EN|EN1);
+		simpad_set_cs3_bit(VCC_5V_EN|EN0);
 		break;
 
 	case 50:
-		clear_cs3_bit(VCC_5V_EN|EN1);
-		set_cs3_bit(VCC_3V_EN|EN0);
+		simpad_clear_cs3_bit(VCC_5V_EN|EN1);
+		simpad_set_cs3_bit(VCC_3V_EN|EN0);
 		break;
 
 	default:
 		printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
 			__func__, state->Vcc);
-		clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+		simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 		local_irq_restore(flags);
 		return -1;
 	}
@@ -110,7 +106,7 @@ static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
 	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-	set_cs3_bit(PCMCIA_RESET);
+	simpad_set_cs3_bit(PCMCIA_RESET);
 }
 
 static struct pcmcia_low_level simpad_pcmcia_ops = { 
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 2.6.39 1/3] ARM: simpad: Add ucb1x00 GPIO definitions and register GPIO
From: Jochen Friedrich @ 2011-02-11 12:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297427836-6341-1-git-send-email-jochen@scram.de>

Add ucb1x00 GPIO definitions to simpad.h and add gpio_base
to ucb1x00 platform device so the pins are available using
the GPIO API.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/arm/mach-sa1100/include/mach/simpad.h |   13 +++++++++++++
 arch/arm/mach-sa1100/simpad.c              |    1 +
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h
index 9296c45..231550d 100644
--- a/arch/arm/mach-sa1100/include/mach/simpad.h
+++ b/arch/arm/mach-sa1100/include/mach/simpad.h
@@ -48,6 +48,19 @@
 #define GPIO_SMART_CARD		GPIO_GPIO10
 #define IRQ_GPIO_SMARD_CARD	IRQ_GPIO10
 
+/*--- ucb1x00 GPIO ---*/
+#define SIMPAD_UCB1X00_GPIO_BASE	(GPIO_MAX + 1)
+#define SIMPAD_UCB1X00_GPIO_PROG1	(SIMPAD_UCB1X00_GPIO_BASE)
+#define SIMPAD_UCB1X00_GPIO_PROG2	(SIMPAD_UCB1X00_GPIO_BASE + 1)
+#define SIMPAD_UCB1X00_GPIO_UP		(SIMPAD_UCB1X00_GPIO_BASE + 2)
+#define SIMPAD_UCB1X00_GPIO_DOWN	(SIMPAD_UCB1X00_GPIO_BASE + 3)
+#define SIMPAD_UCB1X00_GPIO_LEFT	(SIMPAD_UCB1X00_GPIO_BASE + 4)
+#define SIMPAD_UCB1X00_GPIO_RIGHT	(SIMPAD_UCB1X00_GPIO_BASE + 5)
+#define SIMPAD_UCB1X00_GPIO_6		(SIMPAD_UCB1X00_GPIO_BASE + 6)
+#define SIMPAD_UCB1X00_GPIO_7		(SIMPAD_UCB1X00_GPIO_BASE + 7)
+#define SIMPAD_UCB1X00_GPIO_HEADSET	(SIMPAD_UCB1X00_GPIO_BASE + 8)
+#define SIMPAD_UCB1X00_GPIO_SPEAKER	(SIMPAD_UCB1X00_GPIO_BASE + 9)
+
 // CS3 Latch is write only, a shadow is necessary
 
 #define CS3BUSTYPE unsigned volatile long
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index cfb7607..718b802 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -132,6 +132,7 @@ static struct resource simpad_flash_resources [] = {
 static struct mcp_plat_data simpad_mcp_data = {
 	.mccr0		= MCCR0_ADM,
 	.sclk_rate	= 11981000,
+	.gpio_base	= SIMPAD_UCB1X00_GPIO_BASE,
 };
 
 
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 2.6.39 0/3] ARM: simpad: Add support for GPIO attached hardware
From: Jochen Friedrich @ 2011-02-11 12:37 UTC (permalink / raw)
  To: linux-arm-kernel

This series enables GPIO API on UCB1x00 and implements the GPIO
API on the CS3 latch. The third patch finally registers platform
devices for the GPIO attached LED, buttons and I2C bus.

ARM: simpad: Add ucb1x00 GPIO definitions and register GPIO
ARM: simpad: Cleanup CS3 accessors and add GPIO API
ARM: simpad: add GPIO based device definitions

^ permalink raw reply

* [PATCH v2] i.MX51 iomux: Fixes MX51_PAD_UART2_TXD__UART2_TXD declaration
From: Richard Zhao @ 2011-02-11 12:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297420916-14505-1-git-send-email-julien.boibessot@free.fr>

Hi Julien,

#define _MX51_PAD_USBH1_DATA2__UART2_TXD	IOMUX_PAD(0x690, 0x290, 1, 0x09ec, 5, 0)

Will you change the above line too?

Thanks
Richard

On Fri, Feb 11, 2011 at 11:41:56AM +0100, julien.boibessot at free.fr wrote:
> From: Julien Boibessot <julien.boibessot@armadeus.com>
> 
> Fixes a regression of recent iomux changes: current MX51_PAD_UART2_TXD__UART2_TXD
> declaration overwrites IOMUXC_UART2_IPP_UART_RXD_MUX_SELECT_INPUT register
> (0x09ec) and prevent UART2 Rx from working properly.
> (Tested on my custom i.MX51 board where UART2 is used as console)
> 
> Signed-off-by: Julien Boibessot <julien.boibessot@armadeus.com>
> ---
> Changes since v1:
>     - Improve patch description as requested by Sascha Hauer
> 
>  arch/arm/plat-mxc/include/mach/iomux-mx51.h |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> index b6767f9..df531aa 100644
> --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> @@ -473,7 +473,7 @@
>  #define _MX51_PAD_UART2_RXD__UART2_RXD		IOMUX_PAD(0x628, 0x238, 0, 0x09ec, 2, 0)
>  #define _MX51_PAD_UART2_TXD__FIRI_RXD		IOMUX_PAD(0x62c, 0x23c, 1, 0x0000, 0, 0)
>  #define _MX51_PAD_UART2_TXD__GPIO1_21		IOMUX_PAD(0x62c, 0x23c, 3, 0x0000, 0, 0)
> -#define _MX51_PAD_UART2_TXD__UART2_TXD		IOMUX_PAD(0x62c, 0x23c, 0, 0x09ec, 3, 0)
> +#define _MX51_PAD_UART2_TXD__UART2_TXD		IOMUX_PAD(0x62c, 0x23c, 0, 0x0000, 0, 0)
>  #define _MX51_PAD_UART3_RXD__CSI1_D0		IOMUX_PAD(0x630, 0x240, 2, 0x0000, 0, 0)
>  #define _MX51_PAD_UART3_RXD__GPIO1_22		IOMUX_PAD(0x630, 0x240, 3, 0x0000, 0, 0)
>  #define _MX51_PAD_UART3_RXD__UART1_DTR		IOMUX_PAD(0x630, 0x240, 0, 0x0000, 0, 0)
> -- 
> 1.6.0.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [RFC PATCH 3/3] ARM: vfp: Use cpu pm notifiers to save vfp state
From: Russell King - ARM Linux @ 2011-02-11 12:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297426345.17584.99.camel@e102109-lin.cambridge.arm.com>

On Fri, Feb 11, 2011 at 12:12:25PM +0000, Catalin Marinas wrote:
> On SMP systems, we save the VFP at every context switch to deal with the
> thread migration (though I have a plan to make this lazily on SMP as
> well).

I'm not sure it's worth the complexity.  You'd have to do an IPI to the
old CPU to provoke it to save the context from its VFP unit.  You'd have
to do that in some kind of atomic way as the old CPU may be in the middle
of already saving it.  You're also going to have to add locking to the
last_VFP_context[] array as other CPUs will be accessing non-local
entries, and that means doing locking in assembly.  Yuck.

No, let's not go there.  Stick with what we currently have which works
well.

^ permalink raw reply

* reboot not working on linux-2.6.37 for ARMv7
From: Santosh Shilimkar @ 2011-02-11 12:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110211122007.GE23404@n2100.arm.linux.org.uk>

> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Sent: Friday, February 11, 2011 5:50 PM
> To: Santosh Shilimkar
> Cc: shiraz hashim; Armando VISCONTI; amit.goel at st.com;
> vipin.kumar at st.com; linux-arm-kernel at lists.infradead.org
> Subject: Re: reboot not working on linux-2.6.37 for ARMv7
>
> On Fri, Feb 11, 2011 at 05:40:46PM +0530, Santosh Shilimkar wrote:
> > > -----Original Message-----
> > > From: linux-arm-kernel-bounces at lists.infradead.org
> [mailto:linux-
> > > arm-kernel-bounces at lists.infradead.org] On Behalf Of Russell
> King -
> > > ARM Linux
> > > Sent: Friday, February 11, 2011 5:33 PM
> > > To: shiraz hashim
> > > Cc: Armando VISCONTI; amit.goel at st.com; vipin.kumar at st.com;
> linux-
> > > arm-kernel at lists.infradead.org
> > > Subject: Re: reboot not working on linux-2.6.37 for ARMv7
> > >
> > > On Fri, Feb 11, 2011 at 05:01:06PM +0530, shiraz hashim wrote:
> > > > Hi,
> > > >
> > > > I am using linux-2.6.37 on our ARM Cortex A9 (dual core) SMP
> > > platform
> > > > with PL310 as Level 2 cache. We observe that on reboot the
> control
> > > > is not able to reach to the arch_reset.
> > > >
> > > > The problem happens when L1 cache is disabled in
> > > > arm_machine_restart, through cpu_proc_fin() and L2 cache is
> > > flushed.
> > >
> > > Where's the L2 cache flush?  The sequence is:
> > >
> > >         /* Clean and invalidate caches */
> > >         flush_cache_all();
> > >         /* Turn off caching */
> > >         cpu_proc_fin();
> > >         /* Push out any further dirty data, and ensure cache is
> > > empty */
> > >         flush_cache_all();
> > >
> > > and flush_cache_all() calls v7_flush_kern_cache_all() in
> > > arch/arm/mm/cache-v7.S.
> > >
> > > I do hope you're not modifying flush_cache_all() to also call
> the L2
> > > cache functions because that's wrong.
> > >
> > I don't want to hijack this thread. But don't we need L2 flush too
> in
> > reboot path ? If the arch_reset function fails because of the data
> has
> > not made it main memory and stuck in L2 which is used as part of
> this
> > function. With C bit disabled, there won't be any look up done in
> L2.
>
> We only actually need the flushes if we're going to do a soft-
> reboot.
> Soft-reboot isn't supported on ARMv6 and ARMv7 (as the proc-*.S
> reset
> doesn't contain the necessary code).  ARMv5 and lower don't have L2
> caches, so its not a concern for them.
>
> Hard-reboot doesn't actually need the cache flushes.  Unfortunately,
> we've no way of knowing whether a platform implements soft-reboot or
> hard-reboot.

Thanks for clarification.

Regards,
Santosh

^ permalink raw reply

* reboot not working on linux-2.6.37 for ARMv7
From: Russell King - ARM Linux @ 2011-02-11 12:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b78da14247ac79e0f2c8ecae9bbf6745@mail.gmail.com>

On Fri, Feb 11, 2011 at 05:40:46PM +0530, Santosh Shilimkar wrote:
> > -----Original Message-----
> > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-
> > arm-kernel-bounces at lists.infradead.org] On Behalf Of Russell King -
> > ARM Linux
> > Sent: Friday, February 11, 2011 5:33 PM
> > To: shiraz hashim
> > Cc: Armando VISCONTI; amit.goel at st.com; vipin.kumar at st.com; linux-
> > arm-kernel at lists.infradead.org
> > Subject: Re: reboot not working on linux-2.6.37 for ARMv7
> >
> > On Fri, Feb 11, 2011 at 05:01:06PM +0530, shiraz hashim wrote:
> > > Hi,
> > >
> > > I am using linux-2.6.37 on our ARM Cortex A9 (dual core) SMP
> > platform
> > > with PL310 as Level 2 cache. We observe that on reboot the control
> > > is not able to reach to the arch_reset.
> > >
> > > The problem happens when L1 cache is disabled in
> > > arm_machine_restart, through cpu_proc_fin() and L2 cache is
> > flushed.
> >
> > Where's the L2 cache flush?  The sequence is:
> >
> >         /* Clean and invalidate caches */
> >         flush_cache_all();
> >         /* Turn off caching */
> >         cpu_proc_fin();
> >         /* Push out any further dirty data, and ensure cache is
> > empty */
> >         flush_cache_all();
> >
> > and flush_cache_all() calls v7_flush_kern_cache_all() in
> > arch/arm/mm/cache-v7.S.
> >
> > I do hope you're not modifying flush_cache_all() to also call the L2
> > cache functions because that's wrong.
> >
> I don't want to hijack this thread. But don't we need L2 flush too in
> reboot path ? If the arch_reset function fails because of the data has
> not made it main memory and stuck in L2 which is used as part of this
> function. With C bit disabled, there won't be any look up done in L2.

We only actually need the flushes if we're going to do a soft-reboot.
Soft-reboot isn't supported on ARMv6 and ARMv7 (as the proc-*.S reset
doesn't contain the necessary code).  ARMv5 and lower don't have L2
caches, so its not a concern for them.

Hard-reboot doesn't actually need the cache flushes.  Unfortunately,
we've no way of knowing whether a platform implements soft-reboot or
hard-reboot.

^ permalink raw reply

* [RFC PATCH 3/3] ARM: vfp: Use cpu pm notifiers to save vfp state
From: Catalin Marinas @ 2011-02-11 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297373487-23902-4-git-send-email-ccross@android.com>

Colin,

On Thu, 2011-02-10 at 21:31 +0000, Colin Cross wrote:
> +static int vfp_idle_notifier(struct notifier_block *self, unsigned long cmd,
> +       void *v)
> +{
> +       u32 fpexc = fmrx(FPEXC);
> +       unsigned int cpu = smp_processor_id();
> +
> +       if (cmd != CPU_PM_ENTER)
> +               return NOTIFY_OK;
> +
> +       /* The VFP may be reset in idle, save the state */
> +       if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) {
> +               vfp_save_state(last_VFP_context[cpu], fpexc);
> +               last_VFP_context[cpu]->hard.cpu = cpu;
> +       }

Should we only handle the case where the VFP is enabled? At context
switch we disable the VFP and re-enable it when an application tries to
use it but it will remain disabled even the application hasn't used the
VFP. So switching to the idle thread would cause the VFP to be disabled
but the state not necessarily saved.

On SMP systems, we save the VFP at every context switch to deal with the
thread migration (though I have a plan to make this lazily on SMP as
well). On UP however, we don't save the VFP registers at context switch,
we just disable it and save it lazily if used later in a different task

Something like below (untested):

	if (last_VFP_context[cpu]) {
		vfp_save_state(last_VFP_context[cpu], fpexc);
		/* force a reload when coming back from idle */
		last_VFP_context[cpu] = NULL;
		fmxr(FPEXC, fpexc & ~FPEXC_EN);
	}

The last line (disabling) may not be necessary if we know that it comes
back from idle as disabled.

I wonder whether the current vfp_pm_suspend() function needs fixing for
UP systems as well. It is find if the hardware preserves the VFP
registers (which may not be the case).

-- 
Catalin

^ permalink raw reply

* [PATCH] OMAP4: PandaBoard: Adding DVI support
From: Bryan Wu @ 2011-02-11 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTimwCDYGfeXc=mW-1wyvSj+OGHd_fJMB7Grh60ih@mail.gmail.com>

On Wed, Feb 9, 2011 at 10:08 PM, Gadiyar, Anand <gadiyar@ti.com> wrote:
> On Wed, Feb 9, 2011 at 7:25 PM, Raghuveer Murthy
> <raghuveer.murthy@ti.com> wrote:
>> Adding DVI support to OMAP4 PandaBoard.
>>
>> PandaBoard uses TFP410 DVI Framer chip
>> http://focus.ti.com/lit/ds/symlink/tfp410.pdf
>>
>> The TFP410 gets its power enable and display data over GPIO lines muxed
>> in from OMAP4430. PandaBoard supports other LCD displays through expansion
>> connectors, following board rework. This will disable the DVI interface.
>> However, the existing mux settings remain the same
>>
>> PandaBoard additionally supports display over HDMI interface. It is
>> mutually exclusive to display over DVI. Hence the mux settings need to be
>> configured seperately, as and when HDMI is enabled
>>
>> Also, I2C3 bus used for reading EDID data from DVI Monitors is
>> registered here. Since the design is similar to BeagleBoard, the code
>> for the same is taken from the kernel.org commit e3333f48dd5cb21
>> (omap: Adding beagle i2c eeprom driver to read EDID)
>>
>> Reviewed-by: Manjunath G Kondaiah <manjugk@ti.com>
>> Reviewed-by: Anand Gadiyar <gadiyar@ti.com>
>
> I've also tested it on the Panda, and gone through this and most
> of the other patches in the series. So if you like, you could
> consider this an:
>
> Acked-by: Anand Gadiyar <gadiyar@ti.com>
>
>> Reviewed-by: Nishanth Menon <nm@ti.com>
>> Reviewed-by: Sumit Semwal <sumit.semwal@ti.com>
>> Signed-off-by: Raghuveer Murthy <raghuveer.murthy@ti.com>
>> ---
>>
>> Base
>> ====
>> url =
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
>> branch "master"
>> commit 100b33c8bd8a3235fd0b7948338d6cbb3db3c63d
>> tag 2.6.38-rc4
>>
>
> To make it easier for someone to test, I've extracted this
> and the 6 dependent series from patchwork, and hosted
> them in a branch on my devel tree. They are available
> against v2.6.38-rc4 here:
>
> git://dev.omapzoom.org/pub/scm/anand/linux-omap-usb.git
>
> in the display-patches-for-v2.6.38-rc4 branch if someone
> wants to take a look.

I fetched this branch which contains 35 patches on top of 2.6.38-rc4.
After fixing some conflict, I applied these 35 patches on our Ubuntu
ti-omap-dev kernel. With built-in the DSS2 driver and GENERIC_DPI
driver, kernel boots fine on my Panda with Ubuntu GUI. But I have to
set the kernel boot command args with omapfb.mode=dvi:1024x768MR-24 at 60
omapdss.def_disp=dvi, pointed out by Sebastien. Without this bootargs,
no graphic at all. so as Robert concerned, EDID detection doesn't
work. Does that related to I2C driver? I2C driver always tell me
timeout in dmesg.

Thanks a lot,
-- 
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer ? ?+86.138-1617-6545 Mobile
Ubuntu Kernel Team
Canonical Ltd. ? ? ?www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com

^ permalink raw reply

* reboot not working on linux-2.6.37 for ARMv7
From: Santosh Shilimkar @ 2011-02-11 12:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110211120305.GD23404@n2100.arm.linux.org.uk>

> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-
> arm-kernel-bounces at lists.infradead.org] On Behalf Of Russell King -
> ARM Linux
> Sent: Friday, February 11, 2011 5:33 PM
> To: shiraz hashim
> Cc: Armando VISCONTI; amit.goel at st.com; vipin.kumar at st.com; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: reboot not working on linux-2.6.37 for ARMv7
>
> On Fri, Feb 11, 2011 at 05:01:06PM +0530, shiraz hashim wrote:
> > Hi,
> >
> > I am using linux-2.6.37 on our ARM Cortex A9 (dual core) SMP
> platform
> > with PL310 as Level 2 cache. We observe that on reboot the control
> > is not able to reach to the arch_reset.
> >
> > The problem happens when L1 cache is disabled in
> > arm_machine_restart, through cpu_proc_fin() and L2 cache is
> flushed.
>
> Where's the L2 cache flush?  The sequence is:
>
>         /* Clean and invalidate caches */
>         flush_cache_all();
>         /* Turn off caching */
>         cpu_proc_fin();
>         /* Push out any further dirty data, and ensure cache is
> empty */
>         flush_cache_all();
>
> and flush_cache_all() calls v7_flush_kern_cache_all() in
> arch/arm/mm/cache-v7.S.
>
> I do hope you're not modifying flush_cache_all() to also call the L2
> cache functions because that's wrong.
>
I don't want to hijack this thread. But don't we need L2 flush too in
reboot path ? If the arch_reset function fails because of the data has
not made it main memory and stuck in L2 which is used as part of this
function. With C bit disabled, there won't be any look up done in L2.

May be I am missing something here.

Regards,
Santosh

^ permalink raw reply

* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
From: Santosh Shilimkar @ 2011-02-11 12:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110211115853.GC23404@n2100.arm.linux.org.uk>

> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-
> arm-kernel-bounces at lists.infradead.org] On Behalf Of Russell King -
> ARM Linux
> Sent: Friday, February 11, 2011 5:29 PM
> To: Colin Cross; Santosh Shilimkar; Kukjin Kim
> Cc: saeed bishara; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume
> support
>
> On Wed, Feb 09, 2011 at 07:15:25PM -0800, Colin Cross wrote:
> > The diagnostic register also needs to be saved to keep the errata
> bits
> > set in __v7_setup.
>
> Saving I've no problem with.  Restoring gets hairy with kernels
> running
> in non-secure mode, as we can't just write the register - we don't
> know
> whether we are running in secure or non-secure mode.  A write to the
> register in NS mode will crash.
>
> Santosh: is the diagnostic register on OMAP4 re-initialized by the
> secure code on OMAP?
>
There is a Monitor secure API, needs to be called from non-secure
software to set this diagnostic registers in resume path.

Regards,
Santosh

^ permalink raw reply

* reboot not working on linux-2.6.37 for ARMv7
From: Russell King - ARM Linux @ 2011-02-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTi=FCJr-0aF0LG92PC4Q7J4R5PDU7xobnvCgDHy8@mail.gmail.com>

On Fri, Feb 11, 2011 at 05:01:06PM +0530, shiraz hashim wrote:
> Hi,
> 
> I am using linux-2.6.37 on our ARM Cortex A9 (dual core) SMP platform
> with PL310 as Level 2 cache. We observe that on reboot the control
> is not able to reach to the arch_reset.
> 
> The problem happens when L1 cache is disabled in
> arm_machine_restart, through cpu_proc_fin() and L2 cache is flushed.

Where's the L2 cache flush?  The sequence is:

        /* Clean and invalidate caches */
        flush_cache_all();
        /* Turn off caching */
        cpu_proc_fin();
        /* Push out any further dirty data, and ensure cache is empty */
        flush_cache_all();

and flush_cache_all() calls v7_flush_kern_cache_all() in
arch/arm/mm/cache-v7.S.

I do hope you're not modifying flush_cache_all() to also call the L2
cache functions because that's wrong.

^ permalink raw reply

* [PATCH 1/2] arm: mx50_rdp: add fec support
From: Richard Zhao @ 2011-02-11 12:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110211102459.GG27982@pengutronix.de>

On Fri, Feb 11, 2011 at 11:24:59AM +0100, Uwe Kleine-K?nig wrote:
> On Fri, Feb 11, 2011 at 06:22:10PM +0800, Richard Zhao wrote:
> > Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
> > 
> > diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c
> > index dedf7f2..505513c 100644
> > --- a/arch/arm/mach-mx5/board-mx50_rdp.c
> > +++ b/arch/arm/mach-mx5/board-mx50_rdp.c
> > @@ -40,6 +40,9 @@
> >  #define FEC_EN		IMX_GPIO_NR(6, 23)
> >  #define FEC_RESET_B	IMX_GPIO_NR(4, 12)
> >  
> > +#define FEC_EN		IMX_GPIO_NR(6, 23)
> > +#define FEC_RESET_B	IMX_GPIO_NR(4, 12)
> > +
> I think this is a left-over of a rebase.  The #defines are already
> present and they alone don't justify saying "add fec support".
Yes, Sorry for that. Please review the second patch.

Thanks
Richard
> 
> Best regards
> Uwe
> 
> -- 
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
From: Russell King - ARM Linux @ 2011-02-11 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTimCtaSZ=CHT5snWZ496_bi4sH=0LU7vJ-Jfh=dP@mail.gmail.com>

On Wed, Feb 09, 2011 at 07:15:25PM -0800, Colin Cross wrote:
> The diagnostic register also needs to be saved to keep the errata bits
> set in __v7_setup.

Saving I've no problem with.  Restoring gets hairy with kernels running
in non-secure mode, as we can't just write the register - we don't know
whether we are running in secure or non-secure mode.  A write to the
register in NS mode will crash.

Santosh: is the diagnostic register on OMAP4 re-initialized by the secure
code on OMAP?

> > + ? ? ? stmia ? r0, {r4 - r11}
> > + ? ? ? ldmfd ? sp!, {r4 - r11, pc}
> > +ENDPROC(cpu_v7_do_suspend)
> > +
> > +ENTRY(cpu_v7_do_resume)
> > + ? ? ? mov ? ? ip, #0
> > + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate TLBs
> > + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 0 ? @ invalidate I cache
> 
> Does this need the same ALT_SMP/ALT_UP combo as v7_flush_icache_all?

That depends whether you the CPU which is resuming is part of a coherent
SMP system at that point.  This instruction will invalidate the I-cache
for the local CPU only, whereas the c7, c1 variant will invalidate the
instruction caches of all CPUs within the inner sharable domain.

Has anything changed in the other CPUs as a result of this CPU resuming
at this point?  I don't think so, so I think we just need to ensure that
the local CPU instruction cache is invalidated at this point.

> Tegra2 suspend and cpuidle works on top of this patch and the patch
> that adds SMP support to sleep_save_sp.  Tegra seems to need to
> invalidate the entire l1 data cache before enabling it,

As it's undefined what state the data cache is in on resume, I'm surprised
the s5pv210 code doesn't also need a D-cache invalidate too.  Maybe Samsung
folk can answer that.

> so I'm using a
> custom reset vector that branches to cpu_resume, and I'm handling the
> TLB invalidate in the function cpu_resume returns to.
> 
> Tested-by: Colin Cross <ccross@android.com>
> 
> Are you targeting 2.6.39 with these patches?  They replace a few
> hundred lines of code in the Tegra2 suspend, hotplug, and idle
> patches, so I'd like to wait until this is in before pushing mine.

Undecided at the moment.  It's great that you've tested it, and I've
also tested it on Assabet, but PXA and Samsung stuff hasn't been
tested yet.  I guess I could just push the generic and sa1100 bits for
2.6.39, unless the remainder gets tested.

Once the above issues have answers, I'll see about posting a new set of
patches.

^ permalink raw reply

* [PATCH] picoxcell_crypto: add support for the picoxcell crypto engines
From: Jamie Iles @ 2011-02-11 11:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110210220916.aac2b545.kim.phillips@freescale.com>

On Thu, Feb 10, 2011 at 10:09:16PM -0600, Kim Phillips wrote:
> On Tue, 8 Feb 2011 15:56:16 +0000
> Jamie Iles <jamie@jamieiles.com> wrote:
> 
> > Picochip picoXcell devices have two crypto engines, one targeted
> > at IPSEC offload and the other at WCDMA layer 2 ciphering.
> >
> > Cc: Herbert Xu <herbert@gondor.apana.org.au>
> > Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> > ---
> 
> nice driver ;).  Have a couple of comments though.

Hi Kim,

Thanks for the great review!

> 
> > +     help
> > +       This option enables support for the hardware offload engines in the
> > +       Picochip picoXcell SoC devices. Select this for IPSEC ESP offload
> > +       and for 3gpp Layer 2 ciphering support.
> 
> it'd be nice to mention what name the module will have.

Ok, will add.

> 
> > +#define SPACC_CRYPTO_AES_MAX_KEY_LEN 32
> > +#define SPACC_CRYPTO_AES_IV_LEN              16
> > +#define SPACC_CRYPTO_DES_IV_LEN              8
> 
> these are identical to algorithm-generic symbolic constants
> AES_MAX_KEY_SIZE, [AD]ES_BLOCK_SIZE - why not use them instead?

I wasn't aware of these constants but yes, that's much better.
> 
> > +struct spacc_generic_ctx;
> 
> this declaration isn't used prior to its definition, so it's not needed.

Ok, will remove.

> > +/* DDT format. This must match the hardware DDT format exactly. */
> > +struct spacc_ddt {
> > +     u32 p, len;
> 
> type-consistency: p should be a dma_addr_t

The reason I used a u32 was the the engine descriptor format is two 32 
bit words so I was trying to be explicit but I'll change this to 
dma_addr_t.

> 
> > +     /* AEAD specifc bits. */
> 
> specific

Good spot!

> > +static inline struct spacc_ablk_ctx *
> > +to_spacc_ablk_ctx(struct spacc_generic_ctx *ctx)
> > +{
> > +     return ctx ? container_of(ctx, struct spacc_ablk_ctx, generic) : NULL;
> > +}
> > +
> > +static inline struct spacc_aead_ctx *
> > +to_spacc_aead_ctx(struct spacc_generic_ctx *ctx)
> > +{
> > +     return ctx ? container_of(ctx, struct spacc_aead_ctx, generic) : NULL;
> > +}
> 
> these aren't being used anywhere.

Ok, will remove.

> 
> > +static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg);
> 
> define it here - forward declarations should only be necessary when
> dealing with circular dependencies.

Hmm, not sure why I didn't do that originally!  Will change.

> 
> > +/*
> > + * Take a crypto request and scatterlists for the data and turn them into DDTs
> > + * for passing to the crypto engines. This also DMA maps the data so that the
> > + * crypto engines can DMA to/from them.
> > + */
> > +static struct spacc_ddt *spacc_sg_to_ddt(struct spacc_engine *engine,
> > +                                      struct scatterlist *payload,
> > +                                      unsigned nbytes,
> > +                                      enum dma_data_direction dir,
> > +                                      dma_addr_t *ddt_phys)
> > +{
> > +     unsigned nents, mapped_ents;
> > +     struct scatterlist *cur;
> > +     struct spacc_ddt *ddt;
> > +     int i;
> > +
> > +     nents = sg_count(payload, nbytes);
> > +     mapped_ents = dma_map_sg(engine->dev, payload, nents, dir);
> > +
> > +     if (mapped_ents + 1 > MAX_DDT_LEN) {
> > +             dma_unmap_sg(engine->dev, payload, nents, dir);
> > +             return NULL;
> > +     }
> > +
> > +     ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, ddt_phys);
> > +     if (ddt) {
> > +             for_each_sg(payload, cur, mapped_ents, i) {
> > +                     ddt[i].p = sg_dma_address(cur);
> > +                     ddt[i].len = sg_dma_len(cur);
> > +             }
> > +
> > +             ddt[mapped_ents].p = 0;
> > +             ddt[mapped_ents].len = 0;
> > +     } else {
> > +             dma_unmap_sg(engine->dev, payload, nents, dir);
> > +             ddt = NULL;
> > +     }
> > +
> > +     return ddt;
> > +}
> 
> easier to read would be:
> 
>         if (mapped_ents + 1 > MAX_DDT_LEN)
>                 goto out;
> 
>         ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, ddt_phys);
>         if (!ddt)
>                 goto out;
> 
>         for_each_sg(payload, cur, mapped_ents, i) {
>                 ddt[i].p = sg_dma_address(cur);
>                 ddt[i].len = sg_dma_len(cur);
>         }
>         ddt[mapped_ents].p = 0;
>         ddt[mapped_ents].len = 0;
> 
>         return ddt;
> 
> out:
>         dma_unmap_sg(engine->dev, payload, nents, dir);
>         return NULL;
> }
> 
> even more so by moving ddt_set() above it, and then using ddt_set() to
> assign the p, len pairs.

Yes, that's much cleaner.

> 
> > +static inline void ddt_set(struct spacc_ddt *ddt, unsigned long phys,
> 
> phys should be dma_addr_t

Ok.

> 
> > +static int spacc_aead_make_ddts(struct spacc_req *req, u8 *giv)
> > +{
> > +     struct aead_request *areq = container_of(req->req, struct aead_request,
> > +                                              base);
> > +     struct spacc_alg *alg = to_spacc_alg(req->req->tfm->__crt_alg);
> > +     struct spacc_engine *engine = req->engine;
> > +     struct spacc_ddt *src_ddt, *dst_ddt;
> > +     unsigned ivsize = alg->alg.cra_aead.ivsize;
> 
> no need to go through all those hoops to get to the ivsize - use helper
> fns crypto_aead_reqtfm() and crypto_aead_ivsize(), as is done at the
> callsite, or just pass it in from there.

Ok, will do.

> 
> > +static int spacc_aead_des_setkey(struct crypto_aead *aead, const u8 *key,
> > +                              unsigned int len)
> > +{
> > +     struct crypto_tfm *tfm = crypto_aead_tfm(aead);
> > +     struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
> > +     int err = 0;
> > +     u32 tmp[DES_EXPKEY_WORDS];
> > +
> > +     err = des_ekey(tmp, key);
> > +     if (unlikely(!err) &&
> 
> might want to change the name of the variable err here to something
> like ret or is_weak so as to not mislead the reader.
> 
> > +         (crypto_aead_get_flags(aead)) & CRYPTO_TFM_REQ_WEAK_KEY) {
> > +             tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
> > +             return -EINVAL;
> > +     }
> > +     err = 0;
> > +
> > +     memcpy(ctx->cipher_key, key, len);
> > +     ctx->cipher_key_len = len;
> > +
> > +     return err;
> 
> actually, it doesn't look like this fn needs a return variable
> at all.

Ok, I'll get rid of err and put the des_ekey() call into the 
conditional.

> > +/* Set the key for the AES block cipher component of the AEAD 
> > transform. */
> > +static int spacc_aead_aes_setkey(struct crypto_aead *aead, const u8 *key,
> > +                              unsigned int len)
> > +{
> > +     struct crypto_tfm *tfm = crypto_aead_tfm(aead);
> > +     struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
> > +     int err;
> > +
> > +     /*
> > +      * IPSec engine only supports 128 and 256 bit AES keys. If we get a
> > +      * request for any other size (192 bits) then we need to do a software
> > +      * fallback.
> > +      */
> > +     if (!(16 == len || 32 == len)) {
> 
> if (len != AES_KEYSIZE_128 && len != AES_KEYSIZE_256)

Ok, I'll clean up all of these uses.

> > +             /*
> > +              * Set the fallback transform to use the same request flags as
> > +              * the hardware transform.
> > +              */
> > +             ctx->sw_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
> > +             ctx->sw_cipher->base.crt_flags |=
> > +                     (tfm->crt_flags & CRYPTO_TFM_REQ_MASK);
> 
> parens not needed.

Ok.

> > +             err = crypto_aead_setkey(ctx->sw_cipher, key, len);
> > +     } else {
> > +             memcpy(ctx->cipher_key, key, len);
> > +             ctx->cipher_key_len = len;
> > +             err = 0;
> > +     }
> > +
> > +     return err;
> 
> 	return crypto_aead_setkey(ctx->sw_cipher, key, len);
> }
> memcpy(ctx->cipher_key, key, len);
> ctx->cipher_key_len = len;
> 
> return 0;

Ok.

> > +static int spacc_aead_setkey(struct crypto_aead *tfm, const u8 *key,
> > +                          unsigned int keylen)
> > +{
> > +     struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm);
> > +     struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg);
> > +     struct rtattr *rta = (void *)key;
> > +     struct crypto_authenc_key_param *param;
> > +     unsigned int authkeylen, enckeylen;
> > +     int err = -EINVAL;
> > +
> > +     if (!RTA_OK(rta, keylen))
> > +             goto badkey;
> > +
> > +     if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
> > +             goto badkey;
> > +
> > +     if (RTA_PAYLOAD(rta) < sizeof(*param))
> > +             goto badkey;
> 
> I'm not sure, but it should be safe to remove the above three checks -
> they cause a false badkey failure if the keys aren't within an rtattr
> struct, which, e.g., something like testmgr.c wouldn't do.
> 
> > +     param = RTA_DATA(rta);
> > +     enckeylen = be32_to_cpu(param->enckeylen);
> > +
> > +     key += RTA_ALIGN(rta->rta_len);
> > +     keylen -= RTA_ALIGN(rta->rta_len);
> 
> actually, I doubt crypto drivers should be including rtnetlink.h at
> all...but it's probably ok for now - talitos still does :)

Yes, it doesn't seem the nicest way to pass the keys.  ixp4xx and 
crypto/authenc.c do the same thing (including the first 3 checks).  
Perhaps this is worth refactoring into a generic 
crypto_authenc_get_keys() helper?

> > +     if ((spacc_alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
> > +         SPA_CTRL_CIPH_ALG_AES &&
> > +         !(16 == ctx->cipher_key_len || 32 == ctx->cipher_key_len))
> 
> as above, please use symbolic equivalents

Ok.

> > +static void spacc_aead_complete(struct spacc_req *req)
> > +{
> > +     spacc_aead_free_ddts(req);
> > +
> > +     if (req->req->complete)
> > +             req->req->complete(req->req, req->result);
> 
> when is there not a completion function?

Ok, I'll remove that check.

> > +     /* Set the source and destination DDT pointers. */
> > +     writel((u32)req->src_addr, engine->regs + SPA_SRC_PTR_REG_OFFSET);
> > +     writel((u32)req->dst_addr, engine->regs + SPA_DST_PTR_REG_OFFSET);
> 
> cast necessary?

No, probably not.  I'll double check and remove if ok.

> > +     ctrl = spacc_alg->ctrl_default;
> > +     ctrl |= ((req->ctx_id << SPA_CTRL_CTX_IDX) |
> > +              (1 << SPA_CTRL_ICV_APPEND) |
> > +              (req->is_encrypt ? (1 << SPA_CTRL_ENCRYPT_IDX) : 0) |
> > +              (req->is_encrypt ? (1 << SPA_CTRL_AAD_COPY) : 0));
> > +     if (!req->is_encrypt)
> > +             ctrl |= (1 << SPA_CTRL_KEY_EXP);
> 
> ctrl = spacc_alg->ctrl_default | (req->ctx_id << SPA_CTRL_CTX_IDX) |
>        (1 << SPA_CTRL_ICV_APPEND);
> 
> if (req->is_encrypt)
> 	ctrl |= (1 << SPA_CTRL_ENCRYPT_IDX) | (1 << SPA_CTRL_AAD_COPY);
> else
> 	ctrl |= (1 << SPA_CTRL_KEY_EXP);

Yes, that's nicer.

> > +static int spacc_des_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
> > +                         unsigned int len)
> > +{
> > +     struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
> > +     struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
> > +     int err;
> > +     u32 tmp[DES_EXPKEY_WORDS];
> > +
> > +     if (len > SPACC_CRYPTO_AES_MAX_KEY_LEN) {
> 
> AES left overs in a DES setkey

Good spot, will fix.

> > +static int spacc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
> > +                         unsigned int len)
> > +{
> > +     struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
> > +     struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
> > +     int err = 0;
> > +
> > +     if (len > SPACC_CRYPTO_AES_MAX_KEY_LEN) {
> > +             crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /*
> > +      * IPSec engine only supports 128 and 256 bit AES keys. If we get a
> > +      * request for any other size (192 bits) then we need to do a software
> > +      * fallback.
> > +      */
> > +     if (!(16 == len || 32 == len) && ctx->sw_cipher) {
> 
> symbolic constants

Ok.

> > +             /*
> > +              * Set the fallback transform to use the same request flags as
> > +              * the hardware transform.
> > +              */
> > +             ctx->sw_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
> > +             ctx->sw_cipher->base.crt_flags |=
> > +                 (cipher->base.crt_flags & CRYPTO_TFM_REQ_MASK);
> 
> parens not necessary

Ok.

> > +static int spacc_ablk_need_fallback(struct spacc_req *req)
> > +{
> > +     struct spacc_ablk_ctx *ctx;
> > +     struct crypto_tfm *tfm = req->req->tfm;
> > +     struct crypto_alg *alg = req->req->tfm->__crt_alg;
> > +     struct spacc_alg *spacc_alg = to_spacc_alg(alg);
> > +
> > +     ctx = crypto_tfm_ctx(tfm);
> > +
> > +     return (spacc_alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
> > +                     SPA_CTRL_CIPH_ALG_AES &&
> > +             !(16 == ctx->key_len || 32 == ctx->key_len);
> 
> symbolic constants

Ok.

> > +static ssize_t spacc_stat_irq_thresh_store(struct device *dev,
> > +                                        struct device_attribute *attr,
> > +                                        const char *buf, size_t len)
> > +{
> > +     struct spacc_engine *engine = spacc_dev_to_engine(dev);
> > +     unsigned thresh = simple_strtoul(buf, NULL, 0);
> 
> consider using strict_strtoul (checkpatch)

Ok, will change.

> > +static struct spacc_alg ipsec_engine_algs[] = {
> > +     {
> > +             .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC,
> > +             .key_offs = 0,
> > +             .iv_offs = SPACC_CRYPTO_AES_MAX_KEY_LEN,
> > +             .alg = {
> > +                     .cra_name = "cbc(aes)",
> > +                     .cra_driver_name = "cbc-aes-picoxcell",
> > +                     .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
> > +                     .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
> > +                                  CRYPTO_ALG_ASYNC |
> > +                                  CRYPTO_ALG_NEED_FALLBACK,
> > +                     .cra_blocksize = 16,
> 
> symbolic constant, here and throughout the rest of this section.

Ok.

Thanks again for taking the time to review Kim!

Jamie

^ permalink raw reply

* reboot not working on linux-2.6.37 for ARMv7
From: shiraz hashim @ 2011-02-11 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

I am using linux-2.6.37 on our ARM Cortex A9 (dual core) SMP platform
with PL310 as Level 2 cache. We observe that on reboot the control
is not able to reach to the arch_reset.

The problem happens when L1 cache is disabled in
arm_machine_restart, through cpu_proc_fin() and L2 cache is flushed.
L2 cache flushing takes a spinlock and our platform doesnot have monitor
support at L2 thus failing strex instruction. The strex (and hence spin locks)
behave sanely when L1 is enabled as monitor associated with SCU takes
care of it.

-- 
regards
Shiraz Hashim

^ permalink raw reply

* [PATCH] ARM: Avoid discarding sections that might have SMP_ON_UP fixups
From: Dave Martin @ 2011-02-11 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110211101345.GA23785@n2100.arm.linux.org.uk>

On Fri, Feb 11, 2011 at 10:13 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Feb 11, 2011 at 09:33:56AM +0000, Dave Martin wrote:
>> Agreed -- actually, I suspected we might need to support this. ?But I
>> don't think solving this problem (= keeping the fixup implementation
>> in memory and enhancing the module loader) solved the
>> fixups-referencing-sections-discarded-from-vmlinux problem. ?These
>> seem to be two separate issues. ?I am filing to understand something?
>
> They are separate, but related issues. ?They both ultimately have the
> same cause - the placement of the spinlock code inline rather than
> out of line, resulting in fixups appearing all over the place rather
> than just in kernel/spinlock.o.

I guess what I want to understand is whether I (or someone) still
need(s) to sort out the vmlinux.lds issue.

If we're keeping inline spinlocks (I currently assume "yes"), then the
vmlinux.lds issue still needs fixing.  Is that correct?  However, if
we get rid of inline spinlocks we won't have the problem, though there
may be some performance impact -- hard to judge how significant.

Apologies if I'm being dense here...

Cheers
---Dave

^ permalink raw reply

* [PATCHv6] watchdog: add support for the Synopsys DesignWare WDT
From: viresh kumar @ 2011-02-11 10:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1295871552-22254-1-git-send-email-jamie@jamieiles.com>

On Mon, Jan 24, 2011 at 5:49 PM, Jamie Iles <jamie@jamieiles.com> wrote:
> The Synopsys DesignWare watchdog is found in several ARM based systems
> and provides a choice of 16 timeout periods depending on the clock
> input. ?The watchdog cannot be disabled once started.
>
> Cc: Wim Van Sebroeck <wim@iguana.be>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
>
> v6:
> ? ? ? ?- add a Kconfig dependency on HAVE_CLK and don't allow rate to
> ? ? ? ? ?be set by platform data.
> v5:
> ? ? ? ?- don't select CONFIG_WATCHDOG_NOWAYOUT, use a software
> ? ? ? ? ?heartbeat to keep the wdt alive if we allow close.
> v4:
> ? ? ? ?- cleanups as suggested by Viresh Kumar and Wim
> ? ? ? ?- provide a mechanism to handle NULL clks and allow
> ? ? ? ? ?platform_data to specify the clk_rate
> ? ? ? ?- provide open-once protection
>
> v3:
> ? ? ? ?- convert pm to dev_pm_ops
> ? ? ? ?- use devres for resource allocation
>
> v2:
> ? ? ? ?- constify fops
> ? ? ? ?- request_mem_region() before ioremap()
> ? ? ? ?- disable clk if misc_register() fails
>
> ?drivers/watchdog/Kconfig ?| ? ?9 +
> ?drivers/watchdog/Makefile | ? ?1 +
> ?drivers/watchdog/dw_wdt.c | ?376 +++++++++++++++++++++++++++++++++++++++++++++
> ?3 files changed, 386 insertions(+), 0 deletions(-)
> ?create mode 100644 drivers/watchdog/dw_wdt.c
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index cbd37bb..f707536 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -331,6 +331,15 @@ config IMX2_WDT
> ? ? ? ? ?To compile this driver as a module, choose M here: the
> ? ? ? ? ?module will be called imx2_wdt.
>
> +config DW_WATCHDOG
> + ? ? ? tristate "Synopsys DesignWare watchdog"
> + ? ? ? depends on ARM && HAVE_CLK
> + ? ? ? help
> + ? ? ? ? Say Y here if to include support for the Synopsys DesignWare
> + ? ? ? ? watchdog timer found in many ARM chips.
> + ? ? ? ? To compile this driver as a module, choose M here: the
> + ? ? ? ? module will be called dw_wdt.
> +
> ?# AVR32 Architecture
>
> ?config AT32AP700X_WDT
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index cd1e7fe..e2b5b10 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
> ?obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
> ?obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
> ?obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
> +obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
>
> ?# AVR32 Architecture
> ?obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
> diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
> new file mode 100644
> index 0000000..f10f8c0
> --- /dev/null
> +++ b/drivers/watchdog/dw_wdt.c
> @@ -0,0 +1,376 @@
> +/*
> + * Copyright 2010-2011 Picochip Ltd., Jamie Iles
> + * http://www.picochip.com
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * This file implements a driver for the Synopsys DesignWare watchdog device
> + * in the many ARM subsystems. The watchdog has 16 different timeout periods
> + * and these are a function of the input clock frequency.
> + *
> + * The DesignWare watchdog cannot be stopped once it has been started so we
> + * use a software timer to implement a ping that will keep the watchdog alive.
> + * If we receive an expected close for the watchdog then we keep the timer
> + * running, otherwise the timer is stopped and the watchdog will expire.
> + */
> +#define pr_fmt(fmt) "dw_wdt: " fmt
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/fs.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/miscdevice.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/pm.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/timer.h>
> +#include <linux/uaccess.h>
> +#include <linux/watchdog.h>
> +
> +#define WDOG_CONTROL_REG_OFFSET ? ? ? ? ? ? ? ? ? ?0x00
> +#define WDOG_CONTROL_REG_WDT_EN_MASK ? ? ? 0x01
> +#define WDOG_TIMEOUT_RANGE_REG_OFFSET ? ? ?0x04
> +#define WDOG_CURRENT_COUNT_REG_OFFSET ? ? ?0x08
> +#define WDOG_COUNTER_RESTART_REG_OFFSET ? ? 0x0c
> +#define WDOG_COUNTER_RESTART_KICK_VALUE ? ? ? ? ? ?0x76
> +
> +/* The maximum TOP (timeout period) value that can be set in the watchdog. */
> +#define DW_WDT_MAX_TOP ? ? ? ? 15
> +
> +static int nowayout = WATCHDOG_NOWAYOUT;
> +module_param(nowayout, int, 0);
> +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
> + ? ? ? ? ? ? ? ?"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> +
> +#define WDT_TIMEOUT ? ? ? ? ? ?(HZ / 2)
> +
> +static struct {
> + ? ? ? spinlock_t ? ? ? ? ? ? ?lock;
> + ? ? ? void __iomem ? ? ? ? ? ?*regs;
> + ? ? ? struct clk ? ? ? ? ? ? ?*clk;
> + ? ? ? unsigned long ? ? ? ? ? in_use;
> + ? ? ? unsigned long ? ? ? ? ? next_heartbeat;
> + ? ? ? struct timer_list ? ? ? timer;
> + ? ? ? int ? ? ? ? ? ? ? ? ? ? expect_close;
> +} dw_wdt;
> +
> +static inline int dw_wdt_is_enabled(void)
> +{
> + ? ? ? return readl(dw_wdt.regs + WDOG_CONTROL_REG_OFFSET) &
> + ? ? ? ? ? ? ? WDOG_CONTROL_REG_WDT_EN_MASK;
> +}
> +
> +static inline int dw_wdt_top_in_seconds(unsigned top)
> +{
> + ? ? ? /*
> + ? ? ? ?* There are 16 possible timeout values in 0..15 where the number of
> + ? ? ? ?* cycles is 2 ^ (16 + i) and the watchdog counts down.
> + ? ? ? ?*/
> + ? ? ? return (1 << (16 + top)) / clk_get_rate(dw_wdt.clk);
> +}
> +
> +static int dw_wdt_get_top(void)
> +{
> + ? ? ? int top = readl(dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET) & 0xF;
> +
> + ? ? ? return dw_wdt_top_in_seconds(top);
> +}
> +
> +static inline void dw_wdt_set_next_heartbeat(void)
> +{
> + ? ? ? dw_wdt.next_heartbeat = jiffies + dw_wdt_get_top() * HZ;
> +}
> +
> +static int dw_wdt_set_top(unsigned top_s)
> +{
> + ? ? ? int i, top_val = DW_WDT_MAX_TOP;
> +
> + ? ? ? /*
> + ? ? ? ?* Iterate over the timeout values until we find the closest match. We
> + ? ? ? ?* always look for >=.
> + ? ? ? ?*/
> + ? ? ? for (i = 0; i <= DW_WDT_MAX_TOP; ++i)
> + ? ? ? ? ? ? ? if (dw_wdt_top_in_seconds(i) >= top_s) {
> + ? ? ? ? ? ? ? ? ? ? ? top_val = i;
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? /* Set the new value in the watchdog. */
> + ? ? ? writel(top_val, dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
> +
> + ? ? ? dw_wdt_set_next_heartbeat();
> +
> + ? ? ? return dw_wdt_top_in_seconds(top_val);
> +}
> +
> +static void dw_wdt_keepalive(void)
> +{
> + ? ? ? writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
> + ? ? ? ? ? ? ?WDOG_COUNTER_RESTART_REG_OFFSET);
> +}
> +
> +static void dw_wdt_ping(unsigned long data)
> +{
> + ? ? ? if (time_before(jiffies, dw_wdt.next_heartbeat) ||
> + ? ? ? ? ? (!nowayout && !dw_wdt.in_use)) {
> + ? ? ? ? ? ? ? dw_wdt_keepalive();
> + ? ? ? ? ? ? ? mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT);
> + ? ? ? } else
> + ? ? ? ? ? ? ? pr_crit("keepalive missed, machine will reset\n");
> +}
> +
> +static int dw_wdt_open(struct inode *inode, struct file *filp)
> +{
> + ? ? ? if (test_and_set_bit(0, &dw_wdt.in_use))
> + ? ? ? ? ? ? ? return -EBUSY;
> +
> + ? ? ? /* Make sure we don't get unloaded. */
> + ? ? ? __module_get(THIS_MODULE);
> +
> + ? ? ? spin_lock(&dw_wdt.lock);
> + ? ? ? if (!dw_wdt_is_enabled()) {
> + ? ? ? ? ? ? ? /*
> + ? ? ? ? ? ? ? ?* The watchdog is not currently enabled. Set the timeout to
> + ? ? ? ? ? ? ? ?* the maximum and then start it.
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? dw_wdt_set_top(DW_WDT_MAX_TOP);
> + ? ? ? ? ? ? ? writel(WDOG_CONTROL_REG_WDT_EN_MASK,
> + ? ? ? ? ? ? ? ? ? ? ?dw_wdt.regs + WDOG_CONTROL_REG_OFFSET);
> + ? ? ? }
> +
> + ? ? ? dw_wdt_set_next_heartbeat();
> +
> + ? ? ? spin_unlock(&dw_wdt.lock);
> +
> + ? ? ? return nonseekable_open(inode, filp);
> +}
> +
> +ssize_t dw_wdt_write(struct file *filp, const char __user *buf, size_t len,
> + ? ? ? ? ? ? ? ? ? ?loff_t *offset)
> +{
> + ? ? ? if (!len)
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? if (!nowayout) {
> + ? ? ? ? ? ? ? size_t i;
> +
> + ? ? ? ? ? ? ? dw_wdt.expect_close = 0;
> +
> + ? ? ? ? ? ? ? for (i = 0; i < len; ++i) {
> + ? ? ? ? ? ? ? ? ? ? ? char c;
> +
> + ? ? ? ? ? ? ? ? ? ? ? if (get_user(c, buf + i))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> +
> + ? ? ? ? ? ? ? ? ? ? ? if (c == 'V') {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dw_wdt.expect_close = 1;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? dw_wdt_set_next_heartbeat();
> + ? ? ? mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT);
> +
> + ? ? ? return len;
> +}
> +
> +static u32 dw_wdt_time_left(void)
> +{
> + ? ? ? return readl(dw_wdt.regs + WDOG_CURRENT_COUNT_REG_OFFSET) /
> + ? ? ? ? ? ? ? clk_get_rate(dw_wdt.clk);
> +}
> +
> +static const struct watchdog_info dw_wdt_ident = {
> + ? ? ? .options ? ? ? ?= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
> + ? ? ? ? ? ? ? ? ? ? ? ? WDIOF_MAGICCLOSE,
> + ? ? ? .identity ? ? ? = "Synopsys DesignWare Watchdog",
> +};
> +
> +static long dw_wdt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> +{
> + ? ? ? unsigned long val;
> + ? ? ? int timeout;
> +
> + ? ? ? switch (cmd) {
> + ? ? ? case WDIOC_GETSUPPORT:
> + ? ? ? ? ? ? ? return copy_to_user((struct watchdog_info *)arg, &dw_wdt_ident,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sizeof(dw_wdt_ident)) ? -EFAULT : 0;
> +
> + ? ? ? case WDIOC_GETSTATUS:
> + ? ? ? case WDIOC_GETBOOTSTATUS:
> + ? ? ? ? ? ? ? return put_user(0, (int *)arg);
> +
> + ? ? ? case WDIOC_KEEPALIVE:
> + ? ? ? ? ? ? ? dw_wdt_set_next_heartbeat();
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? case WDIOC_SETTIMEOUT:
> + ? ? ? ? ? ? ? if (get_user(val, (int __user *)arg))
> + ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> + ? ? ? ? ? ? ? timeout = dw_wdt_set_top(val);
> + ? ? ? ? ? ? ? return put_user(timeout , (int __user *)arg);
> +
> + ? ? ? case WDIOC_GETTIMEOUT:
> + ? ? ? ? ? ? ? return put_user(dw_wdt_get_top(), (int __user *)arg);
> +
> + ? ? ? case WDIOC_GETTIMELEFT:
> + ? ? ? ? ? ? ? /* Get the time left until expiry. */
> + ? ? ? ? ? ? ? if (get_user(val, (int __user *)arg))
> + ? ? ? ? ? ? ? ? ? ? ? return -EFAULT;
> + ? ? ? ? ? ? ? return put_user(dw_wdt_time_left(), (int __user *)arg);
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? return -ENOTTY;
> + ? ? ? }
> +}
> +
> +static int dw_wdt_release(struct inode *inode, struct file *filp)
> +{
> + ? ? ? clear_bit(0, &dw_wdt.in_use);
> +
> + ? ? ? if (!dw_wdt.expect_close) {
> + ? ? ? ? ? ? ? del_timer(&dw_wdt.timer);
> +
> + ? ? ? ? ? ? ? if (!nowayout)
> + ? ? ? ? ? ? ? ? ? ? ? pr_crit("unexpected close, system will reboot soon\n");
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? pr_crit("watchdog cannot be disabled, system will reboot soon\n");
> + ? ? ? }
> +
> + ? ? ? dw_wdt.expect_close = 0;
> +
> + ? ? ? return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int dw_wdt_suspend(struct device *dev)
> +{
> + ? ? ? clk_disable(dw_wdt.clk);
> +
> + ? ? ? return 0;
> +}
> +
> +static int dw_wdt_resume(struct device *dev)
> +{
> + ? ? ? int err = clk_enable(dw_wdt.clk);
> +
> + ? ? ? if (err)
> + ? ? ? ? ? ? ? return err;
> +
> + ? ? ? dw_wdt_keepalive();
> +
> + ? ? ? return 0;
> +}
> +
> +static const struct dev_pm_ops dw_wdt_pm_ops = {
> + ? ? ? .suspend ? ? ? ?= dw_wdt_suspend,
> + ? ? ? .resume ? ? ? ? = dw_wdt_resume,
> +};
> +#endif /* CONFIG_PM */
> +
> +static const struct file_operations wdt_fops = {
> + ? ? ? .owner ? ? ? ? ?= THIS_MODULE,
> + ? ? ? .llseek ? ? ? ? = no_llseek,
> + ? ? ? .open ? ? ? ? ? = dw_wdt_open,
> + ? ? ? .write ? ? ? ? ?= dw_wdt_write,
> + ? ? ? .unlocked_ioctl = dw_wdt_ioctl,
> + ? ? ? .release ? ? ? ?= dw_wdt_release
> +};
> +
> +static struct miscdevice dw_wdt_miscdev = {
> + ? ? ? .fops ? ? ? ? ? = &wdt_fops,
> + ? ? ? .name ? ? ? ? ? = "watchdog",
> + ? ? ? .minor ? ? ? ? ?= WATCHDOG_MINOR,
> +};
> +
> +static int __devinit dw_wdt_drv_probe(struct platform_device *pdev)
> +{
> + ? ? ? int ret;
> + ? ? ? struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + ? ? ? if (!mem)
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"dw_wdt"))
> + ? ? ? ? ? ? ? return -ENOMEM;
> +
> + ? ? ? dw_wdt.regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
> + ? ? ? if (!dw_wdt.regs)
> + ? ? ? ? ? ? ? return -ENOMEM;
> +
> + ? ? ? dw_wdt.clk = clk_get(&pdev->dev, NULL);
> + ? ? ? if (IS_ERR(dw_wdt.clk))
> + ? ? ? ? ? ? ? return PTR_ERR(dw_wdt.clk);
> +
> + ? ? ? ret = clk_enable(dw_wdt.clk);
> + ? ? ? if (ret)
> + ? ? ? ? ? ? ? goto out_put_clk;
> +
> + ? ? ? spin_lock_init(&dw_wdt.lock);
> +
> + ? ? ? ret = misc_register(&dw_wdt_miscdev);
> + ? ? ? if (ret)
> + ? ? ? ? ? ? ? goto out_disable_clk;
> +
> + ? ? ? dw_wdt_set_next_heartbeat();
> + ? ? ? setup_timer(&dw_wdt.timer, dw_wdt_ping, 0);
> + ? ? ? mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT);
> +
> + ? ? ? return 0;
> +
> +out_disable_clk:
> + ? ? ? clk_disable(dw_wdt.clk);
> +out_put_clk:
> + ? ? ? clk_put(dw_wdt.clk);
> +
> + ? ? ? return ret;
> +}
> +
> +static int __devexit dw_wdt_drv_remove(struct platform_device *pdev)
> +{
> + ? ? ? misc_deregister(&dw_wdt_miscdev);
> +
> + ? ? ? clk_disable(dw_wdt.clk);
> + ? ? ? clk_put(dw_wdt.clk);
> +
> + ? ? ? return 0;
> +}
> +
> +static struct platform_driver dw_wdt_driver = {
> + ? ? ? .probe ? ? ? ? ?= dw_wdt_drv_probe,
> + ? ? ? .remove ? ? ? ? = __devexit_p(dw_wdt_drv_remove),
> + ? ? ? .driver ? ? ? ? = {
> + ? ? ? ? ? ? ? .name ? = "dw_wdt",
> + ? ? ? ? ? ? ? .owner ?= THIS_MODULE,
> +#ifdef CONFIG_PM
> + ? ? ? ? ? ? ? .pm ? ? = &dw_wdt_pm_ops,
> +#endif /* CONFIG_PM */
> + ? ? ? },
> +};
> +
> +static int __init dw_wdt_watchdog_init(void)
> +{
> + ? ? ? return platform_driver_register(&dw_wdt_driver);
> +}
> +module_init(dw_wdt_watchdog_init);
> +
> +static void __exit dw_wdt_watchdog_exit(void)
> +{
> + ? ? ? platform_driver_unregister(&dw_wdt_driver);
> +}
> +module_exit(dw_wdt_watchdog_exit);
> +
> +MODULE_AUTHOR("Jamie Iles");
> +MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

Sorry for being late!!!

Acked-by: Viresh Kumar <viresh.kumar@st.com>

^ permalink raw reply

* [PATCH v2] i.MX51 iomux: Fixes MX51_PAD_UART2_TXD__UART2_TXD declaration
From: julien.boibessot at free.fr @ 2011-02-11 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: Julien Boibessot <julien.boibessot@armadeus.com>

Fixes a regression of recent iomux changes: current MX51_PAD_UART2_TXD__UART2_TXD
declaration overwrites IOMUXC_UART2_IPP_UART_RXD_MUX_SELECT_INPUT register
(0x09ec) and prevent UART2 Rx from working properly.
(Tested on my custom i.MX51 board where UART2 is used as console)

Signed-off-by: Julien Boibessot <julien.boibessot@armadeus.com>
---
Changes since v1:
    - Improve patch description as requested by Sascha Hauer

 arch/arm/plat-mxc/include/mach/iomux-mx51.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index b6767f9..df531aa 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -473,7 +473,7 @@
 #define _MX51_PAD_UART2_RXD__UART2_RXD		IOMUX_PAD(0x628, 0x238, 0, 0x09ec, 2, 0)
 #define _MX51_PAD_UART2_TXD__FIRI_RXD		IOMUX_PAD(0x62c, 0x23c, 1, 0x0000, 0, 0)
 #define _MX51_PAD_UART2_TXD__GPIO1_21		IOMUX_PAD(0x62c, 0x23c, 3, 0x0000, 0, 0)
-#define _MX51_PAD_UART2_TXD__UART2_TXD		IOMUX_PAD(0x62c, 0x23c, 0, 0x09ec, 3, 0)
+#define _MX51_PAD_UART2_TXD__UART2_TXD		IOMUX_PAD(0x62c, 0x23c, 0, 0x0000, 0, 0)
 #define _MX51_PAD_UART3_RXD__CSI1_D0		IOMUX_PAD(0x630, 0x240, 2, 0x0000, 0, 0)
 #define _MX51_PAD_UART3_RXD__GPIO1_22		IOMUX_PAD(0x630, 0x240, 3, 0x0000, 0, 0)
 #define _MX51_PAD_UART3_RXD__UART1_DTR		IOMUX_PAD(0x630, 0x240, 0, 0x0000, 0, 0)
-- 
1.6.0.4

^ permalink raw reply related

* [PATCH] mmci: make sure DMA transfers wait for FIFO drain
From: Linus Walleij @ 2011-02-11 10:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110211101056.GB23404@n2100.arm.linux.org.uk>

2011/2/11 Russell King - ARM Linux <linux@arm.linux.org.uk>:

> Maybe a solution to this is to use the DMA callback to signal that the
> data path has completed, but still have the data end interrupt in place
> so that it can trigger the stop command. ?That shouldn't result in
> additional delays or even the requirement for a timeout.

That should be possible, I'll try to fix up a patch like that.

Thanks,
Linus Walleij

^ permalink raw reply

* [PATCH 1/2] arm: mx50_rdp: add fec support
From: Uwe Kleine-König @ 2011-02-11 10:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297419731-16441-1-git-send-email-richard.zhao@freescale.com>

On Fri, Feb 11, 2011 at 06:22:10PM +0800, Richard Zhao wrote:
> Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
> 
> diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c
> index dedf7f2..505513c 100644
> --- a/arch/arm/mach-mx5/board-mx50_rdp.c
> +++ b/arch/arm/mach-mx5/board-mx50_rdp.c
> @@ -40,6 +40,9 @@
>  #define FEC_EN		IMX_GPIO_NR(6, 23)
>  #define FEC_RESET_B	IMX_GPIO_NR(4, 12)
>  
> +#define FEC_EN		IMX_GPIO_NR(6, 23)
> +#define FEC_RESET_B	IMX_GPIO_NR(4, 12)
> +
I think this is a left-over of a rebase.  The #defines are already
present and they alone don't justify saying "add fec support".

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [PATCH 2/2] ARM: imx50: correct iomux-mx50.h wrong daisy chain settings
From: Richard Zhao @ 2011-02-11 10:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297419731-16441-1-git-send-email-richard.zhao@freescale.com>

Most fix is for uart txd/cts. They don't need to select input.
And fix some other pads with wrong select input.

Signed-off-by: Richard Zhao <richard.zhao@freescale.com>

diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx50.h b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
index 058a922..98e7fd0 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx50.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
@@ -86,7 +86,7 @@
 #define MX50_PAD_I2C1_SCL__I2C1_SCL	IOMUX_PAD(0x2EC, 0x40, IOMUX_CONFIG_SION, 0x0, 0, \
 							MX50_I2C_PAD_CTRL)
 #define MX50_PAD_I2C1_SCL__GPIO_6_18	IOMUX_PAD(0x2EC, 0x40, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_I2C1_SCL__UART2_TXD	IOMUX_PAD(0x2EC, 0x40, 2, 0x7cc, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_I2C1_SCL__UART2_TXD	IOMUX_PAD(0x2EC, 0x40, 2, 0x0, 0, MX50_UART_PAD_CTRL)
 
 #define MX50_PAD_I2C1_SDA__I2C1_SDA	IOMUX_PAD(0x2F0, 0x44, IOMUX_CONFIG_SION, 0x0, 0, \
 							MX50_I2C_PAD_CTRL)
@@ -96,7 +96,7 @@
 #define MX50_PAD_I2C2_SCL__I2C2_SCL	IOMUX_PAD(0x2F4, 0x48, IOMUX_CONFIG_SION, 0x0, 0, \
 							MX50_I2C_PAD_CTRL)
 #define MX50_PAD_I2C2_SCL__GPIO_6_20	IOMUX_PAD(0x2F4, 0x48, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_I2C2_SCL__UART2_CTS	IOMUX_PAD(0x2F4, 0x48, 2, 0x7c8, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__UART2_CTS	IOMUX_PAD(0x2F4, 0x48, 2, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_I2C2_SCL__DCDC_OK	IOMUX_PAD(0x2F4, 0x48, 7, 0x0, 0, NO_PAD_CTRL)
 
 #define MX50_PAD_I2C2_SDA__I2C2_SDA	IOMUX_PAD(0x2F8, 0x4C, IOMUX_CONFIG_SION, 0x0, 0, \
@@ -172,7 +172,7 @@
 
 #define MX50_PAD_SSI_RXFS__AUD3_RXFS	IOMUX_PAD(0x328, 0x7C, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_SSI_RXFS__GPIO_6_4	IOMUX_PAD(0x328, 0x7C, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_SSI_RXFS__UART5_TXD	IOMUX_PAD(0x328, 0x7C, 2, 0x7e4, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__UART5_TXD	IOMUX_PAD(0x328, 0x7C, 2, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_SSI_RXFS__WEIM_D6	IOMUX_PAD(0x328, 0x7C, 3, 0x804, 0, NO_PAD_CTRL)
 #define MX50_PAD_SSI_RXFS__CSPI_SS2	IOMUX_PAD(0x328, 0x7C, 4, 0x6f0, 0, MX50_CSPI_SS_PAD)
 #define MX50_PAD_SSI_RXFS__FEC_COL	IOMUX_PAD(0x328, 0x7C, 5, 0x770, 0, PAD_CTL_DSE_HIGH)
@@ -186,25 +186,25 @@
 #define MX50_PAD_SSI_RXC__FEC_RX_CLK	IOMUX_PAD(0x32C, 0x80, 5, 0x780, 0, NO_PAD_CTRL)
 #define MX50_PAD_SSI_RXC__FEC_MDIO	IOMUX_PAD(0x32C, 0x80, 6, 0x774, 1, MX50_FEC_PAD_CTRL)
 
-#define MX50_PAD_UART1_TXD__UART1_TXD	IOMUX_PAD(0x330, 0x84, 0, 0x7c4, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_TXD__UART1_TXD	IOMUX_PAD(0x330, 0x84, 0, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART1_TXD__GPIO_6_6	IOMUX_PAD(0x330, 0x84, 1, 0x0, 0, NO_PAD_CTRL)
 
 #define MX50_PAD_UART1_RXD__UART1_RXD	IOMUX_PAD(0x334, 0x88, 0, 0x7c4, 1, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART1_RXD__GPIO_6_7	IOMUX_PAD(0x334, 0x88, 1, 0x0, 0, NO_PAD_CTRL)
 
-#define MX50_PAD_UART1_CTS__UART1_CTS	IOMUX_PAD(0x338, 0x8C, 0, 0x7c0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__UART1_CTS	IOMUX_PAD(0x338, 0x8C, 0, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART1_CTS__GPIO_6_8	IOMUX_PAD(0x338, 0x8C, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_UART1_CTS__UART5_TXD	IOMUX_PAD(0x338, 0x8C, 2, 0x7e4, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__UART5_TXD	IOMUX_PAD(0x338, 0x8C, 2, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART1_CTS__SD4_D4	IOMUX_PAD(0x338, 0x8C, 4, 0x760, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART1_CTS__SD4_CMD	IOMUX_PAD(0x338, 0x8C, 5, 0x74c, 0, MX50_SD_PAD_CTRL)
 
 #define MX50_PAD_UART1_RTS__UART1_RTS	IOMUX_PAD(0x33C, 0x90, 0, 0x7c0, 1, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART1_RTS__GPIO_6_9	IOMUX_PAD(0x33C, 0x90, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_UART1_RTS__UART5_RXD	IOMUX_PAD(0x33C, 0x90, 2, 0x7e4, 3, MX50_UART_PAD_CTRL)
-#define MX50_PAD_UART1_RTS__SD4_D5	IOMUX_PAD(0x33C, 0x90, 4, 0x0, 1, MX50_SD_PAD_CTRL)
-#define MX50_PAD_UART1_RTS__SD4_CLK	IOMUX_PAD(0x33C, 0x90, 5, 0x0, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__SD4_D5	IOMUX_PAD(0x33C, 0x90, 4, 0x764, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__SD4_CLK	IOMUX_PAD(0x33C, 0x90, 5, 0x748, 0, MX50_SD_PAD_CTRL)
 
-#define MX50_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x340, 0x94, 0, 0x7cc, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x340, 0x94, 0, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART2_TXD__GPIO_6_10	IOMUX_PAD(0x340, 0x94, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_UART2_TXD__SD4_D6	IOMUX_PAD(0x340, 0x94, 4, 0x768, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART2_TXD__SD4_D4	IOMUX_PAD(0x340, 0x94, 5, 0x760, 1, MX50_SD_PAD_CTRL)
@@ -214,7 +214,7 @@
 #define MX50_PAD_UART2_RXD__SD4_D7	IOMUX_PAD(0x344, 0x98, 4, 0x76c, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART2_RXD__SD4_D5	IOMUX_PAD(0x344, 0x98, 5, 0x764, 1, MX50_SD_PAD_CTRL)
 
-#define MX50_PAD_UART2_CTS__UART2_CTS	IOMUX_PAD(0x348, 0x9C, 0, 0x7c8, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__UART2_CTS	IOMUX_PAD(0x348, 0x9C, 0, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART2_CTS__GPIO_6_12	IOMUX_PAD(0x348, 0x9C, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_UART2_CTS__SD4_CMD	IOMUX_PAD(0x348, 0x9C, 4, 0x74c, 1, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART2_CTS__SD4_D6	IOMUX_PAD(0x348, 0x9C, 5, 0x768, 1, MX50_SD_PAD_CTRL)
@@ -224,7 +224,7 @@
 #define MX50_PAD_UART2_RTS__SD4_CLK	IOMUX_PAD(0x34C, 0xA0, 4, 0x748, 1, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART2_RTS__SD4_D7	IOMUX_PAD(0x34C, 0xA0, 5, 0x76c, 1, MX50_SD_PAD_CTRL)
 
-#define MX50_PAD_UART3_TXD__UART3_TXD	IOMUX_PAD(0x350, 0xA4, 0, 0x7d4, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__UART3_TXD	IOMUX_PAD(0x350, 0xA4, 0, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART3_TXD__GPIO_6_14	IOMUX_PAD(0x350, 0xA4, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_UART3_TXD__SD1_D4	IOMUX_PAD(0x350, 0xA4, 3, 0x0, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART3_TXD__SD4_D0	IOMUX_PAD(0x350, 0xA4, 4, 0x750, 0, MX50_SD_PAD_CTRL)
@@ -238,9 +238,9 @@
 #define MX50_PAD_UART3_RXD__SD2_CD	IOMUX_PAD(0x354, 0xA8, 5, 0x740, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART3_RXD__WEIM_D13	IOMUX_PAD(0x354, 0xA8, 6, 0x820, 0, NO_PAD_CTRL)
 
-#define MX50_PAD_UART4_TXD__UART4_TXD	IOMUX_PAD(0x358, 0xAC, 0, 0x7dc, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__UART4_TXD	IOMUX_PAD(0x358, 0xAC, 0, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART4_TXD__GPIO_6_16	IOMUX_PAD(0x358, 0xAC, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_UART4_TXD__UART3_CTS	IOMUX_PAD(0x358, 0xAC, 2, 0x7d0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__UART3_CTS	IOMUX_PAD(0x358, 0xAC, 2, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_UART4_TXD__SD1_D6	IOMUX_PAD(0x358, 0xAC, 3, 0x0, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART4_TXD__SD4_D2	IOMUX_PAD(0x358, 0xAC, 4, 0x758, 0, MX50_SD_PAD_CTRL)
 #define MX50_PAD_UART4_TXD__SD2_LCTL	IOMUX_PAD(0x358, 0xAC, 5, 0x0, 0, MX50_SD_PAD_CTRL)
@@ -278,7 +278,7 @@
 #define MX50_PAD_ECSPI1_MOSI__GPIO_4_13		IOMUX_PAD(0x374, 0xC8, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI1_MOSI__CSPI_SS1		IOMUX_PAD(0x374, 0xC8, 2, 0x6ec, 1, MX50_CSPI_SS_PAD)
 #define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1	IOMUX_PAD(0x374, 0xC8, 3, 0x0, 0, MX50_CSPI_SS_PAD)
-#define MX50_PAD_ECSPI1_MOSI__UART3_CTS		IOMUX_PAD(0x374, 0xC8, 4, 0x7d0, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__UART3_CTS		IOMUX_PAD(0x374, 0xC8, 4, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE7	IOMUX_PAD(0x374, 0xC8, 5, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI1_MOSI__WEIM_D9		IOMUX_PAD(0x374, 0xC8, 7, 0x810, 0, NO_PAD_CTRL)
 
@@ -294,7 +294,7 @@
 #define MX50_PAD_ECSPI1_SS0__GPIO_4_15		IOMUX_PAD(0x37C, 0xD0, 1, 0x0, 0, PAD_CTL_PUS_100K_UP)
 #define MX50_PAD_ECSPI1_SS0__CSPI_SS3		IOMUX_PAD(0x37C, 0xD0, 2, 0x6f4, 1, MX50_CSPI_SS_PAD)
 #define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3		IOMUX_PAD(0x37C, 0xD0, 3, 0x0, 0, MX50_CSPI_SS_PAD)
-#define MX50_PAD_ECSPI1_SS0__UART4_CTS		IOMUX_PAD(0x37C, 0xD0, 4, 0x7d8, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SS0__UART4_CTS		IOMUX_PAD(0x37C, 0xD0, 4, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_ECSPI1_SS0__EPDC_SDCE9		IOMUX_PAD(0x37C, 0xD0, 5, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI1_SS0__WEIM_D11		IOMUX_PAD(0x37C, 0xD0, 7, 0x818, 0, NO_PAD_CTRL)
 
@@ -311,17 +311,17 @@
 #define MX50_PAD_ECSPI2_MOSI__GPIO_4_17		IOMUX_PAD(0x384, 0xD8, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MOSI__ELCDIF_RD		IOMUX_PAD(0x384, 0xD8, 2, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1	IOMUX_PAD(0x384, 0xD8, 3, 0x0, 0, MX50_CSPI_SS_PAD)
-#define MX50_PAD_ECSPI2_MOSI__UART5_CTS		IOMUX_PAD(0x384, 0xD8, 4, 0x7e0, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__UART5_CTS		IOMUX_PAD(0x384, 0xD8, 4, 0x0, 0, MX50_UART_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MOSI__ELCDIF_EN		IOMUX_PAD(0x384, 0xD8, 5, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MOSI__NANDF_CEN5	IOMUX_PAD(0x384, 0xD8, 6, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MOSI__WEIM_D9		IOMUX_PAD(0x384, 0xD8, 7, 0x810, 1, NO_PAD_CTRL)
 
-#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO	IOMUX_PAD(0x388, 0xDC, 0, 0x73c, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO	IOMUX_PAD(0x388, 0xDC, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MISO__GPIO_4_18		IOMUX_PAD(0x388, 0xDC, 1, 0x0, 0, PAD_CTL_PUS_100K_UP)
 #define MX50_PAD_ECSPI2_MISO__ELCDIF_RS		IOMUX_PAD(0x388, 0xDC, 2, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2	IOMUX_PAD(0x388, 0xDC, 3, 0x0, 0, MX50_CSPI_SS_PAD)
-#define MX50_PAD_ECSPI2_MISO__UART5_TXD		IOMUX_PAD(0x388, 0xDC, 4, 0x7e4, 4, MX50_UART_PAD_CTRL)
-#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC	IOMUX_PAD(0x388, 0xDC, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__UART5_TXD		IOMUX_PAD(0x388, 0xDC, 4, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC	IOMUX_PAD(0x388, 0xDC, 5, 0x73c, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MISO__NANDF_CEN6	IOMUX_PAD(0x388, 0xDC, 6, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_ECSPI2_MISO__WEIM_D10		IOMUX_PAD(0x388, 0xDC, 7, 0x814, 1, NO_PAD_CTRL)
 
@@ -503,7 +503,7 @@
 #define MX50_PAD_DISP_RD__ELCDIF_EN	IOMUX_PAD(0x430, 0x150, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
 #define MX50_PAD_DISP_RD__WEIM_A25	IOMUX_PAD(0x430, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
 
-#define MX50_PAD_DISP_RS__ELCDIF_RS	IOMUX_PAD(0x434, 0x154, 0, 0x73c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RS__ELCDIF_RS	IOMUX_PAD(0x434, 0x154, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
 #define MX50_PAD_DISP_RS__GPIO_2_17	IOMUX_PAD(0x434, 0x154, 1, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_DISP_RS__ELCDIF_VSYNC	IOMUX_PAD(0x434, 0x154, 2, 0x73c, 1, MX50_ELCDIF_PAD_CTRL)
 #define MX50_PAD_DISP_RS__WEIM_A26	IOMUX_PAD(0x434, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
@@ -691,8 +691,8 @@
 
 #define MX50_PAD_EPDC_D9__EPDC_D9	IOMUX_PAD(0x570, 0x1D4, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_EPDC_D9__GPIO_3_9	IOMUX_PAD(0x570, 0x1D4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_EPDC_D9__WEIM_D9	IOMUX_PAD(0x570, 0x1D4, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX50_PAD_EPDC_D9__ELCDIF_D25	IOMUX_PAD(0x570, 0x1D4, 3, 0x810, 2, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__WEIM_D9	IOMUX_PAD(0x570, 0x1D4, 2, 0x810, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__ELCDIF_D25	IOMUX_PAD(0x570, 0x1D4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
 
 #define MX50_PAD_EPDC_D10__EPDC_D10	IOMUX_PAD(0x574, 0x1D8, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX50_PAD_EPDC_D10__GPIO_3_10	IOMUX_PAD(0x574, 0x1D8, 1, 0x0, 0, NO_PAD_CTRL)
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/2] arm: mx50_rdp: add fec support
From: Richard Zhao @ 2011-02-11 10:22 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Zhao <richard.zhao@freescale.com>

diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c
index dedf7f2..505513c 100644
--- a/arch/arm/mach-mx5/board-mx50_rdp.c
+++ b/arch/arm/mach-mx5/board-mx50_rdp.c
@@ -40,6 +40,9 @@
 #define FEC_EN		IMX_GPIO_NR(6, 23)
 #define FEC_RESET_B	IMX_GPIO_NR(4, 12)
 
+#define FEC_EN		IMX_GPIO_NR(6, 23)
+#define FEC_RESET_B	IMX_GPIO_NR(4, 12)
+
 static iomux_v3_cfg_t mx50_rdp_pads[] __initdata = {
 	/* SD1 */
 	MX50_PAD_ECSPI2_SS0__GPIO_4_19,
-- 
1.7.1

^ permalink raw reply related

* [PATCH] ARM: Avoid discarding sections that might have SMP_ON_UP fixups
From: Russell King - ARM Linux @ 2011-02-11 10:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTim0RRw-xHQYTdHLCXCS_GXkaCiW8y9Fz=jMmwPa@mail.gmail.com>

On Fri, Feb 11, 2011 at 09:33:56AM +0000, Dave Martin wrote:
> Agreed -- actually, I suspected we might need to support this.  But I
> don't think solving this problem (= keeping the fixup implementation
> in memory and enhancing the module loader) solved the
> fixups-referencing-sections-discarded-from-vmlinux problem.  These
> seem to be two separate issues.  I am filing to understand something?

They are separate, but related issues.  They both ultimately have the
same cause - the placement of the spinlock code inline rather than
out of line, resulting in fixups appearing all over the place rather
than just in kernel/spinlock.o.

^ permalink raw reply

* [PATCH] mmci: make sure DMA transfers wait for FIFO drain
From: Russell King - ARM Linux @ 2011-02-11 10:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTi=jP1G=foehWYNai5H=_F372FwpkLEO4wSkmqBc@mail.gmail.com>

On Fri, Feb 11, 2011 at 10:46:46AM +0100, Linus Walleij wrote:
> After discussing this with Ulf I think something like this is
> still needed...
> 
> 2011/2/1 Russell King - ARM Linux <linux@arm.linux.org.uk>:
> > With the code I have in place, you'll notice I have:
> >
> > ? ? ? ?/* Wait up to 1ms for the DMA to complete */
> > ? ? ? ?for (i = 0; ; i++) {
> > ? ? ? ? ? ? ? ?status = readl(host->base + MMCISTATUS);
> > ? ? ? ? ? ? ? ?if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100)
> > ? ? ? ? ? ? ? ? ? ? ? ?break;
> > ? ? ? ? ? ? ? ?udelay(10);
> > ? ? ? ?}
> >
> > This waits for the DMA controller to read the last data out of the FIFO
> > before allowing the request to complete. ?As it has a timeout, it is
> > able to detect ARMs broken DMA setup on their MMCI/DMAC, and disable DMA
> > support for this primecell rather than getting stuck.
> >
> > This may be sufficient without using the DMA callbacks.
> 
> According to our tests this does not really cut it on
> Ux500. Sometimes we get the DMA completion before the
> MCI_DATAEND IRQ, and sometimes after.
> 
> When  we get the callback *after* the MCI_DATAEND irq
> this does not work properly, since we still don't know if the DMA
> job is complete, so the DMA engine is not in sync and we mess up
> the channels by issuing a new job, hammering the DMA engine
> while it's still busy on the channel.

That may be a problem if the channel is still busy, but it in any case
it shouldn't result in the DMA engine being hammered.  The DMA
engine API is a queue based API - you submit requests to it and it
deals with them one after each other.  If you submit two requests in
succession, it should process the first request, complete that, before
it starts to process the second request.  I'd suggest fixing this in
any case.

Maybe a solution to this is to use the DMA callback to signal that the
data path has completed, but still have the data end interrupt in place
so that it can trigger the stop command.  That shouldn't result in
additional delays or even the requirement for a timeout.

^ 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