Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: msm: 7x30: don't force a gpiomux table for the whole arch
From: Rohit Vaswani @ 2011-01-14  3:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294686030-9817-1-git-send-email-dima@android.com>

On 1/10/2011 11:00 AM, Dima Zavin wrote:
> This is completely board specific and therefore must be provided
> on a per-board basis.
>
> Change-Id: I96f922ad9bb9cbce7874c5ae6ac0d7479b7a2124
> Signed-off-by: Dima Zavin<dima@android.com>
>
Tested-by: Rohit Vaswani <rvaswani@codeaurora.org>

Thanks,
Rohit Vaswani

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* still nfs problems [Was: Linux 2.6.37-rc8]
From: Trond Myklebust @ 2011-01-14  2:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110114022554.GA17397@hexapodia.org>

On Thu, 2011-01-13 at 18:25 -0800, Andy Isaacson wrote: 
> On Wed, Jan 05, 2011 at 09:53:13AM -0500, Trond Myklebust wrote:
> > > There was a bug in at least -rc5[1] that was considered already fixed in
> > > -rc4[2]. The later announcements didn't mention it anymore. 
> > > 
> > > > I don't know why it's stopped producing the errors, although once it
> > > > went I never investigated it any further (was far too busy trying to
> > > > get AMBA DMA support working.)
> > > It seems it was fixed for most users though. Trond?
> > 
> > As I said, I can't reproduce it.
> > 
> > I'm seeing a lot of mention of ARM above. Is anyone seeing this bug on
> > x86, or does it appear to be architecture-specific?
> 
> I'm seeing processes stuck in D with "fileid changed" in dmesg, on
> x86_64 (both server and client).  The repro testcase is to run an
> executable off of NFS, recompile it on the server, and then try to tab
> complete the executable name.  The client prints
> 
>     NFS: server <hostname> error: fileid changed
>     fsid 0:18: expected fileid 0x107aa4a, got 0x107ad3e
> 
> and /bin/zsh hangs in D.
> 
> My server is running 2.6.36.1, filesystem is ext3 on sda3 on AHCI,
> client is currently running 2.6.37-rc1.  I'm assuming that 37a09f will
> fix it.

Why are you sticking to 2.6.37-rc1 when the final 2.6.37 is out? There
have been several readdir bugfixes merged in the months since -rc1 came
out.

Trond
-- 
Trond Myklebust
Linux NFS client maintainer

NetApp
Trond.Myklebust at netapp.com
www.netapp.com

^ permalink raw reply

* still nfs problems [Was: Linux 2.6.37-rc8]
From: Andy Isaacson @ 2011-01-14  2:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294239193.3014.9.camel@heimdal.trondhjem.org>

On Wed, Jan 05, 2011 at 09:53:13AM -0500, Trond Myklebust wrote:
> > There was a bug in at least -rc5[1] that was considered already fixed in
> > -rc4[2]. The later announcements didn't mention it anymore. 
> > 
> > > I don't know why it's stopped producing the errors, although once it
> > > went I never investigated it any further (was far too busy trying to
> > > get AMBA DMA support working.)
> > It seems it was fixed for most users though. Trond?
> 
> As I said, I can't reproduce it.
> 
> I'm seeing a lot of mention of ARM above. Is anyone seeing this bug on
> x86, or does it appear to be architecture-specific?

I'm seeing processes stuck in D with "fileid changed" in dmesg, on
x86_64 (both server and client).  The repro testcase is to run an
executable off of NFS, recompile it on the server, and then try to tab
complete the executable name.  The client prints

    NFS: server <hostname> error: fileid changed
    fsid 0:18: expected fileid 0x107aa4a, got 0x107ad3e

and /bin/zsh hangs in D.

My server is running 2.6.36.1, filesystem is ext3 on sda3 on AHCI,
client is currently running 2.6.37-rc1.  I'm assuming that 37a09f will
fix it.

-andy

^ permalink raw reply

* [PATCH] Introduce VPR200 board.
From: Jamie Iles @ 2011-01-14  0:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294962532-15790-2-git-send-email-marc@cpdesign.com.au>

Hi Marc,

A couple of nitpicks inline, but otherwise looks good to me (I'm not 
familiar with mxc or most of the hardware though, so I'm not sure how 
useful my comments are!).

Jamie

On Fri, Jan 14, 2011 at 10:48:52AM +1100, Marc Reilly wrote:
> diff --git a/arch/arm/mach-mx3/mach-vpr200.c b/arch/arm/mach-mx3/mach-vpr200.c
> new file mode 100644
> index 0000000..a4f0514
> --- /dev/null
> +++ b/arch/arm/mach-mx3/mach-vpr200.c
> @@ -0,0 +1,404 @@
> +/*
> + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
> + * Copyright 2010 Creative Product Design
> + *
> + * Derived from mx35 3stack.
> + * Original author: Fabio Estevam <fabio.estevam@freescale.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 program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/types.h>
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/mtd/physmap.h>
> +#include <linux/memory.h>
> +#include <linux/gpio.h>
> +
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +#include <asm/mach/map.h>

I don't think you need asm/mach/map.h as you aren't setting up any IO 
mappings.

> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-mx35.h>
> +#include <mach/irqs.h>
> +#include <mach/ipu.h>
> +#include <mach/mx3fb.h>
> +
> +#include <linux/i2c.h>
> +#include <linux/i2c/at24.h>
> +#include <linux/regulator/machine.h>

I don't think you need linux/regulator/machine.h either.

> +#include <linux/mfd/mc13xxx.h>
> +#include <video/platform_lcd.h>
> +
> +#include "devices-imx35.h"
> +#include "devices.h"
> +
> +#define GPIO_LCDPWR	IMX_GPIO_NR(1, 2)
> +#define GPIO_PMIC_INT	IMX_GPIO_NR(2, 0)
> +
> +#define GPIO_BUTTON1	IMX_GPIO_NR(1, 4)
> +#define GPIO_BUTTON2	IMX_GPIO_NR(1, 5)
> +#define GPIO_BUTTON3	IMX_GPIO_NR(1, 7)
> +#define GPIO_BUTTON4	IMX_GPIO_NR(1, 8)
> +#define GPIO_BUTTON5	IMX_GPIO_NR(1, 9)
> +#define GPIO_BUTTON6	IMX_GPIO_NR(1, 10)
> +#define GPIO_BUTTON7	IMX_GPIO_NR(1, 11)
> +#define GPIO_BUTTON8	IMX_GPIO_NR(1, 12)
> +
> +static const struct fb_videomode fb_modedb[] = {
> +	{
> +	/* 800x480 @ 60 Hz */
> +	.name		= "PT0708048",
> +	.refresh	= 60,
> +	.xres		= 800,
> +	.yres		= 480,
> +	.pixclock	= KHZ2PICOS(33260),
> +	.left_margin	= 50,
> +	.right_margin	= 156,
> +	.upper_margin	= 10,
> +	.lower_margin	= 10,
> +	.hsync_len	= 1,	/* note: DE only display */
> +	.vsync_len	= 1,	/* note: DE only display */
> +	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
> +	.vmode		= FB_VMODE_NONINTERLACED,
> +	.flag		= 0,
> +	}, {
> +	/* 800x480 @ 60 Hz */
> +	.name		= "CTP-CLAA070LC0ACW",
> +	.refresh	= 60,
> +	.xres		= 800,
> +	.yres		= 480,
> +	.pixclock	= KHZ2PICOS(27000),
> +	.left_margin	= 50,
> +	.right_margin	= 50,	/* whole line should have 900 clocks */
> +	.upper_margin	= 10,
> +	.lower_margin	= 10,	/* whole frame should have 500 lines */
> +	.hsync_len	= 1,	/* note: DE only display */
> +	.vsync_len	= 1,	/* note: DE only display */
> +	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
> +	.vmode		= FB_VMODE_NONINTERLACED,
> +	.flag		= 0,
> +	}
> +};

I think the contents of each array entry would usually have an extra 
level of indendation here.

[...]
> +static void vpr200_init_keys(void)
> +{
> +	gpio_request(GPIO_BUTTON1, "BUTTON1");
> +	gpio_direction_input(GPIO_BUTTON1);
> +	gpio_free(GPIO_BUTTON1);
> +
> +	gpio_request(GPIO_BUTTON2, "BUTTON2");
> +	gpio_direction_input(GPIO_BUTTON2);
> +	gpio_free(GPIO_BUTTON2);
> +
> +	gpio_request(GPIO_BUTTON3, "BUTTON3");
> +	gpio_direction_input(GPIO_BUTTON3);
> +	gpio_free(GPIO_BUTTON3);
> +
> +	gpio_request(GPIO_BUTTON4, "BUTTON4");
> +	gpio_direction_input(GPIO_BUTTON4);
> +	gpio_free(GPIO_BUTTON4);
> +
> +	gpio_request(GPIO_BUTTON5, "BUTTON5");
> +	gpio_direction_input(GPIO_BUTTON5);
> +	gpio_free(GPIO_BUTTON5);
> +
> +	gpio_request(GPIO_BUTTON6, "BUTTON6");
> +	gpio_direction_input(GPIO_BUTTON6);
> +	gpio_free(GPIO_BUTTON6);
> +
> +	gpio_request(GPIO_BUTTON7, "BUTTON7");
> +	gpio_direction_input(GPIO_BUTTON7);
> +	gpio_free(GPIO_BUTTON7);
> +
> +	gpio_request(GPIO_BUTTON8, "BUTTON8");
> +	gpio_direction_input(GPIO_BUTTON8);
> +	gpio_free(GPIO_BUTTON8);
> +
> +	platform_device_register(&vpr200_device_gpiokeys);
> +}

You can use gpio_request_array() and gpio_free_array() here to simplify 
any potential error handling.  Is this function just to turn the buttons 
into inputs for the gpio_keys driver?  AFAICT t looks to me that the 
gpio_keys driver does this for you in the probe method with 
gpio_keys_setup_key().  

> +static void vpr200_lcd_power_set(struct plat_lcd_data *pd,
> +				   unsigned int power)
> +{
> +	if (power)
> +		gpio_direction_output(GPIO_LCDPWR, 0);
> +	else
> +		gpio_direction_output(GPIO_LCDPWR, 1);

Does this GPIO ever change direction or could you use gpio_set_value() 
here?

[...]
> +static struct plat_lcd_data vpr200_lcd_power_data = {
> +	.set_power		= vpr200_lcd_power_set,
> +};
> +
> +static struct platform_device vpr200_lcd_powerdev = {
> +	.name			= "platform-lcd",
> +	.dev.platform_data	= &vpr200_lcd_power_data,
> +};

Should you have an explicit .id in this device?

[...]
> +/*
> + * Board specific initialization.
> + */
> +static void __init mxc_board_init(void)
> +{
> +	mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
> +
> +	imx35_add_fec(NULL);
> +	imx35_add_imx2_wdt(NULL);
> +
> +	platform_add_devices(devices, ARRAY_SIZE(devices));
> +
> +	gpio_request(GPIO_LCDPWR, "LCDPWR");
> +	gpio_direction_output(GPIO_LCDPWR, 0);
> +	gpio_free(GPIO_LCDPWR);
> +
> +	gpio_request(GPIO_PMIC_INT, "PMIC_INT");
> +	gpio_direction_input(GPIO_PMIC_INT);
> +	gpio_free(GPIO_PMIC_INT);

Why are these gpio's requested, configured, then freed?  They're
used in vpr200_lcd_power_set() so does something else request them again 
later?  It's probably worth checking the return value of gpio_request() 
too.

^ permalink raw reply

* [PATCH 1/1 v2] ARM: Thumb-2: Symbol manipulation macros for function body copying
From: Russell King - ARM Linux @ 2011-01-13 23:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294951905-23748-2-git-send-email-dave.martin@linaro.org>

On Thu, Jan 13, 2011 at 02:51:45PM -0600, Dave Martin wrote:
> +/* Cast function pointer to integer: */
> +#define __funcp_to_uint(funcp) ({				\

uint is confusing here - it suggests casting a pointer to an unsigned int,
rather than a uintptr_t.  Please use uintptr here.

> +/*
> + * FSYM_REBASE: Determine the correct function pointer for funcp,
> + * after the function has been copied to dest_buf:
> + */
> +#define FSYM_REBASE(funcp, dest_buf)					\
> +	__uint_to_funcp((uintptr_t)(dest_buf) | FSYM_TYPE(funcp), funcp)
> +
> +/*
> + * FSYM_BASE: Determine the base address in memory of the function funcp
> + * FSYM_TYPE: Determine the instruction set type (ARM/Thumb) of funcp
> + * (both defined below)
> + */
> +
> +#ifdef CONFIG_THUMB2_KERNEL
> +#define FSYM_BASE(funcp) ((void *)(__funcp_to_uint(funcp) & ~(uintptr_t)1))
> +#define FSYM_TYPE(funcp) (__funcp_to_uint(funcp) & 1)
> +#else /* !CONFIG_THUMB2_KERNEL */
> +#define FSYM_BASE(funcp) ((void *)__funcp_to_uint(funcp))
> +#define FSYM_TYPE(funcp) 0
> +#endif /* !CONFIG_THUMB2_KERNEL */

I'd really like to see these gone - otherwise they'll end up being used
in code inappropriately.  I like things to be kept as simple as possible
with as few opportunities for people to needlessly hook into internal
implementation details.

If you expose implementation details, people will use them, and then if
you need to change the implementation, you've got a lot of code to deal
with.

I don't think we need to make this conditional on THUMB2 either - we're
probably not wasting much by always clearing and copying the LSB.  And
this isn't particularly performance code.

^ permalink raw reply

* [PATCH] Introduce VPR200 board.
From: Marc Reilly @ 2011-01-13 23:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294962532-15790-1-git-send-email-marc@cpdesign.com.au>

Signed-off-by: Marc Reilly <marc@cpdesign.com.au>
---
 arch/arm/mach-mx3/Kconfig       |   15 ++
 arch/arm/mach-mx3/Makefile      |    1 +
 arch/arm/mach-mx3/mach-vpr200.c |  404 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 420 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mx3/mach-vpr200.c

diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 0717f88..ca63c35 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -229,4 +229,19 @@ config MACH_EUKREA_MBIMXSD35_BASEBOARD
 
 endchoice
 
+config MACH_VPR200
+	bool "Support VPR200 platform"
+	select SOC_IMX35
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	select IMX_HAVE_PLATFORM_MXC_PWM
+	help
+	  Include support for VPR200 platform. This includes specific
+	  configurations for the board and its peripherals.
+
 endif
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 8db1329..bc7294f 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_MACH_MX35_3DS)	+= mach-mx35_3ds.o
 obj-$(CONFIG_MACH_KZM_ARM11_01)	+= mach-kzm_arm11_01.o
 obj-$(CONFIG_MACH_EUKREA_CPUIMX35)	+= mach-cpuimx35.o
 obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD)	+= eukrea_mbimxsd-baseboard.o
+obj-$(CONFIG_MACH_VPR200)	+= mach-vpr200.o
diff --git a/arch/arm/mach-mx3/mach-vpr200.c b/arch/arm/mach-mx3/mach-vpr200.c
new file mode 100644
index 0000000..a4f0514
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-vpr200.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
+ * Copyright 2010 Creative Product Design
+ *
+ * Derived from mx35 3stack.
+ * Original author: Fabio Estevam <fabio.estevam@freescale.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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/irqs.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13xxx.h>
+#include <video/platform_lcd.h>
+
+#include "devices-imx35.h"
+#include "devices.h"
+
+#define GPIO_LCDPWR	IMX_GPIO_NR(1, 2)
+#define GPIO_PMIC_INT	IMX_GPIO_NR(2, 0)
+
+#define GPIO_BUTTON1	IMX_GPIO_NR(1, 4)
+#define GPIO_BUTTON2	IMX_GPIO_NR(1, 5)
+#define GPIO_BUTTON3	IMX_GPIO_NR(1, 7)
+#define GPIO_BUTTON4	IMX_GPIO_NR(1, 8)
+#define GPIO_BUTTON5	IMX_GPIO_NR(1, 9)
+#define GPIO_BUTTON6	IMX_GPIO_NR(1, 10)
+#define GPIO_BUTTON7	IMX_GPIO_NR(1, 11)
+#define GPIO_BUTTON8	IMX_GPIO_NR(1, 12)
+
+static const struct fb_videomode fb_modedb[] = {
+	{
+	/* 800x480 @ 60 Hz */
+	.name		= "PT0708048",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(33260),
+	.left_margin	= 50,
+	.right_margin	= 156,
+	.upper_margin	= 10,
+	.lower_margin	= 10,
+	.hsync_len	= 1,	/* note: DE only display */
+	.vsync_len	= 1,	/* note: DE only display */
+	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+	.vmode		= FB_VMODE_NONINTERLACED,
+	.flag		= 0,
+	}, {
+	/* 800x480 @ 60 Hz */
+	.name		= "CTP-CLAA070LC0ACW",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(27000),
+	.left_margin	= 50,
+	.right_margin	= 50,	/* whole line should have 900 clocks */
+	.upper_margin	= 10,
+	.lower_margin	= 10,	/* whole frame should have 500 lines */
+	.hsync_len	= 1,	/* note: DE only display */
+	.vsync_len	= 1,	/* note: DE only display */
+	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+	.vmode		= FB_VMODE_NONINTERLACED,
+	.flag		= 0,
+	}
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.name		= "PT0708048",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+static struct physmap_flash_data vpr200_flash_data = {
+	.width  = 2,
+};
+
+static struct resource vpr200_flash_resource = {
+	.start	= MX35_CS0_BASE_ADDR,
+	.end	= MX35_CS0_BASE_ADDR + SZ_64M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device vpr200_flash = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &vpr200_flash_data,
+	},
+	.resource = &vpr200_flash_resource,
+	.num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data
+		vpr200_nand_board_info __initconst = {
+	.width = 1,
+	.hw_ecc = 1,
+	.flash_bbt = 1,
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#include <linux/gpio_keys.h>
+#define VPR_KEY_DEBOUNCE	500
+
+static struct gpio_keys_button vpr200_gpio_keys_table[] = {
+	{KEY_F2, GPIO_BUTTON1, 1, "vpr-keys: F2", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F3, GPIO_BUTTON2, 1, "vpr-keys: F3", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F4, GPIO_BUTTON3, 1, "vpr-keys: F4", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F5, GPIO_BUTTON4, 1, "vpr-keys: F5", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F6, GPIO_BUTTON5, 1, "vpr-keys: F6", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F7, GPIO_BUTTON6, 1, "vpr-keys: F7", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F8, GPIO_BUTTON7, 1, "vpr-keys: F8", 1, VPR_KEY_DEBOUNCE},
+	{KEY_F9, GPIO_BUTTON8, 1, "vpr-keys: F9", 1, VPR_KEY_DEBOUNCE},
+};
+
+static struct gpio_keys_platform_data vpr200_gpio_keys_data = {
+	.buttons = vpr200_gpio_keys_table,
+	.nbuttons = ARRAY_SIZE(vpr200_gpio_keys_table),
+};
+
+static struct platform_device vpr200_device_gpiokeys = {
+	.name = "gpio-keys",
+	.dev = {
+		.platform_data = &vpr200_gpio_keys_data,
+	}
+};
+
+static void vpr200_init_keys(void)
+{
+	gpio_request(GPIO_BUTTON1, "BUTTON1");
+	gpio_direction_input(GPIO_BUTTON1);
+	gpio_free(GPIO_BUTTON1);
+
+	gpio_request(GPIO_BUTTON2, "BUTTON2");
+	gpio_direction_input(GPIO_BUTTON2);
+	gpio_free(GPIO_BUTTON2);
+
+	gpio_request(GPIO_BUTTON3, "BUTTON3");
+	gpio_direction_input(GPIO_BUTTON3);
+	gpio_free(GPIO_BUTTON3);
+
+	gpio_request(GPIO_BUTTON4, "BUTTON4");
+	gpio_direction_input(GPIO_BUTTON4);
+	gpio_free(GPIO_BUTTON4);
+
+	gpio_request(GPIO_BUTTON5, "BUTTON5");
+	gpio_direction_input(GPIO_BUTTON5);
+	gpio_free(GPIO_BUTTON5);
+
+	gpio_request(GPIO_BUTTON6, "BUTTON6");
+	gpio_direction_input(GPIO_BUTTON6);
+	gpio_free(GPIO_BUTTON6);
+
+	gpio_request(GPIO_BUTTON7, "BUTTON7");
+	gpio_direction_input(GPIO_BUTTON7);
+	gpio_free(GPIO_BUTTON7);
+
+	gpio_request(GPIO_BUTTON8, "BUTTON8");
+	gpio_direction_input(GPIO_BUTTON8);
+	gpio_free(GPIO_BUTTON8);
+
+	platform_device_register(&vpr200_device_gpiokeys);
+}
+#else
+
+static void vpr200_init_keys(void)
+{
+}
+#endif
+
+static struct mc13xxx_platform_data board_pmic = {
+	.flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN,
+};
+
+#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
+static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = {
+	.bitrate = 50000,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 2048 / 8,
+	.page_size = 1,
+};
+
+static struct i2c_board_info vpr200_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */
+		.platform_data = &board_eeprom,
+	}, {
+		I2C_BOARD_INFO("mc13892", 0x08),
+		.platform_data = &board_pmic,
+		.irq = gpio_to_irq(GPIO_PMIC_INT),
+	}
+};
+#endif
+
+static iomux_v3_cfg_t vpr200_pads[] = {
+	/* UART1 */
+	MX35_PAD_CTS1__UART1_CTS,
+	MX35_PAD_RTS1__UART1_RTS,
+	MX35_PAD_TXD1__UART1_TXD_MUX,
+	MX35_PAD_RXD1__UART1_RXD_MUX,
+	/* UART3 */
+	MX35_PAD_ATA_DATA10__UART3_RXD_MUX,
+	MX35_PAD_ATA_DATA11__UART3_TXD_MUX,
+	/* FEC */
+	MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+	MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX35_PAD_FEC_COL__FEC_COL,
+	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX35_PAD_FEC_MDC__FEC_MDC,
+	MX35_PAD_FEC_MDIO__FEC_MDIO,
+	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+	MX35_PAD_FEC_CRS__FEC_CRS,
+	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+	/* Display */
+	MX35_PAD_LD0__IPU_DISPB_DAT_0,
+	MX35_PAD_LD1__IPU_DISPB_DAT_1,
+	MX35_PAD_LD2__IPU_DISPB_DAT_2,
+	MX35_PAD_LD3__IPU_DISPB_DAT_3,
+	MX35_PAD_LD4__IPU_DISPB_DAT_4,
+	MX35_PAD_LD5__IPU_DISPB_DAT_5,
+	MX35_PAD_LD6__IPU_DISPB_DAT_6,
+	MX35_PAD_LD7__IPU_DISPB_DAT_7,
+	MX35_PAD_LD8__IPU_DISPB_DAT_8,
+	MX35_PAD_LD9__IPU_DISPB_DAT_9,
+	MX35_PAD_LD10__IPU_DISPB_DAT_10,
+	MX35_PAD_LD11__IPU_DISPB_DAT_11,
+	MX35_PAD_LD12__IPU_DISPB_DAT_12,
+	MX35_PAD_LD13__IPU_DISPB_DAT_13,
+	MX35_PAD_LD14__IPU_DISPB_DAT_14,
+	MX35_PAD_LD15__IPU_DISPB_DAT_15,
+	MX35_PAD_LD16__IPU_DISPB_DAT_16,
+	MX35_PAD_LD17__IPU_DISPB_DAT_17,
+	MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+	/* LCD Enable */
+	MX35_PAD_D3_VSYNC__GPIO1_2,
+	/* USBOTG */
+	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+	/* SDCARD */
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* PMIC */
+	MX35_PAD_GPIO2_0__GPIO2_0,
+	/* GPIO keys */
+	MX35_PAD_SCKR__GPIO1_4,
+	MX35_PAD_COMPARE__GPIO1_5,
+	MX35_PAD_SCKT__GPIO1_7,
+	MX35_PAD_FST__GPIO1_8,
+	MX35_PAD_HCKT__GPIO1_9,
+	MX35_PAD_TX5_RX0__GPIO1_10,
+	MX35_PAD_TX4_RX1__GPIO1_11,
+	MX35_PAD_TX3_RX2__GPIO1_12,
+};
+static void vpr200_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power)
+		gpio_direction_output(GPIO_LCDPWR, 0);
+	else
+		gpio_direction_output(GPIO_LCDPWR, 1);
+}
+
+static struct plat_lcd_data vpr200_lcd_power_data = {
+	.set_power		= vpr200_lcd_power_set,
+};
+
+static struct platform_device vpr200_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.platform_data	= &vpr200_lcd_power_data,
+};
+
+/* USB Device config */
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI,
+	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
+};
+
+#if defined(CONFIG_USB_ULPI)
+/* USB HOST config */
+static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
+	.portsc		= MXC_EHCI_MODE_SERIAL,
+	.flags		= MXC_EHCI_INTERFACE_SINGLE_UNI |
+			  MXC_EHCI_INTERNAL_PHY,
+};
+#endif
+
+static struct platform_device *devices[] __initdata = {
+	&vpr200_flash,
+	&vpr200_lcd_powerdev,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
+
+	imx35_add_fec(NULL);
+	imx35_add_imx2_wdt(NULL);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	gpio_request(GPIO_LCDPWR, "LCDPWR");
+	gpio_direction_output(GPIO_LCDPWR, 0);
+	gpio_free(GPIO_LCDPWR);
+
+	gpio_request(GPIO_PMIC_INT, "PMIC_INT");
+	gpio_direction_input(GPIO_PMIC_INT);
+	gpio_free(GPIO_PMIC_INT);
+
+	imx35_add_imx_uart0(NULL);
+	imx35_add_imx_uart2(NULL);
+
+	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+	mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+	imx35_add_fsl_usb2_udc(&otg_device_pdata);
+
+#if defined(CONFIG_USB_ULPI)
+	imx35_add_mxc_ehci_hs(&usb_host_pdata);
+#endif
+
+	imx35_add_mxc_nand(&vpr200_nand_board_info);
+	imx35_add_sdhci_esdhc_imx(0, NULL);
+
+#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
+	i2c_register_board_info(0, vpr200_i2c_devices,
+			ARRAY_SIZE(vpr200_i2c_devices));
+
+	imx35_add_imx_i2c0(&vpr200_i2c0_data);
+#endif
+
+	vpr200_init_keys();
+}
+
+static void __init vpr200_timer_init(void)
+{
+	mx35_clocks_init();
+}
+
+struct sys_timer vpr200_timer = {
+	.init	= vpr200_timer_init,
+};
+
+MACHINE_START(VPR200, "VPR200")
+	/* Maintainer: Creative Product Design */
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx35_map_io,
+	.init_irq       = mx35_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &vpr200_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related

* New i.MX35 based board - VPR200
From: Marc Reilly @ 2011-01-13 23:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

The following patch introduces a new i.MX35 based board which I'd like to get into mainline.
It should apply onto Sacha's imx-for-2.6.38.

Cheers,
Marc

^ permalink raw reply

* [PATCH v2] Add i.MX23/28 auart support
From: Russell King - ARM Linux @ 2011-01-13 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294924476-10653-1-git-send-email-s.hauer@pengutronix.de>

On Thu, Jan 13, 2011 at 02:14:34PM +0100, Sascha Hauer wrote:
> This is the second version of these patches. I have reworked the driver to
> support the NPCK, BRKINT, PARMRK, IGNPAR, IGNBRK and cflag CREAD flags. I have
> tested these flags to the best of my knowledge, but it's sometimes hard to
> judge if the behaviour is expected.

Well, it passes code inspection, so I'm now happy with it.

^ permalink raw reply

* [PATCH v2] ARM: Thumb-2: Fix out-of-range offset for Thumb-2 in proc-v7.S
From: Russell King - ARM Linux @ 2011-01-13 23:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294937485-7673-1-git-send-email-dave.martin@linaro.org>

On Thu, Jan 13, 2011 at 10:51:25AM -0600, Dave Martin wrote:
> Commit
> 
>        d30e45e (ARM: pgtable: switch order of Linux vs hardware page tables)
> 
> introduced a pre-increment addressing offset which is out of range for
> Thumb-2.  Thumb-2 only permits offsets <256.  So split the intruction in
> two for Thumb-2.

Ok, can you put it in the patch system please?  Thanks.

^ permalink raw reply

* [PATCH] ARM: make head.S less dependent on the compile time PHYS_OFFSET define
From: Russell King - ARM Linux @ 2011-01-13 23:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1101131659220.11803@xanadu.home>

On Thu, Jan 13, 2011 at 05:04:28PM -0500, Nicolas Pitre wrote:
> +	.macro phys_offset, rd
> +	mov	\rd, pc
> +	and	\rd, \rd, #0xf8000000
> +	.endm

We can do loads better than that, as the p2v fixup code has proven.
Now that r8 has been eliminated, I may rebase the p2v stuff ontop of
that commit, and move the computation of phys_offset out of the p2v
fixup code - and have it in r8 for __create_page_tables to use.

FYI, the real PHYS_OFFSET value can be found by (eg):

1:	.long	.
	.long	PAGE_OFFSET

	adr	r0, 1b
	ldmia	r0, {r1, r2}
	sub	r1, r0, r1
	add	r3, r2, r1

r1 now contains the offset between virtual and physical spaces, r2
contains the compile-time PAGE_OFFSET constant, and r3 the runtime
equivalent of PHYS_OFFSET.

None of this uses troublesome masking which will trip up on platforms
such as MSM - we really must stop writing code which assumes that
physical memory is aligned to >= 32MB.

^ permalink raw reply

* SMP: BUG() on cat /proc/$PID/stack
From: Russell King - ARM Linux @ 2011-01-13 23:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTinSNPC7+m1Uie5hbUW_hgPecAK=RRGKkMx2AqOm@mail.gmail.com>

On Fri, Jan 14, 2011 at 12:24:19AM +0530, Rabin Vincent wrote:
> On SMP, this BUG() in save_stack_trace_tsk() can be easily triggered
> from user space by reading /proc/$PID/stack, where $PID is any pid but
> the current process:
> 
>         if (tsk != current) {
> #ifdef CONFIG_SMP
>                 /*
>                  * What guarantees do we have here that 'tsk'
>                  * is not running on another CPU?
>                  */
>                 BUG();
> #else
> 
> x86 appears to go ahead in this case, but has its stack walking code
> check at every step that the stack pointer it's reading from is valid --
> is this what is needed in the ARM unwind code to get rid of this BUG()?

x86 stack walking is very different from ARM unwinding.  I'd rather not
expose the unwinder to a volatile stack - that's probably a recipe for
it "sometimes" working and other times going oops because the stack
changed beneath it.

I suspect this may be one of the reasons x86 merged a dwarf unwinder
and then threw it out as it was too unreliable.

So, rather than going BUG(), lets instead return a terminated trace -
something like this.  Could you test and report back please?

Thanks.

diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index c2e112e..381d23a 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -94,10 +94,13 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	if (tsk != current) {
 #ifdef CONFIG_SMP
 		/*
-		 * What guarantees do we have here that 'tsk'
-		 * is not running on another CPU?
+		 * What guarantees do we have here that 'tsk' is not
+		 * running on another CPU?  For now, ignore it as we
+		 * can't guarantee we won't explode.
 		 */
-		BUG();
+		if (trace->nr_entries < trace->max_entries)
+			trace->entries[trace->nr_entries++] = ULONG_MAX;
+		return;
 #else
 		data.no_sched_functions = 1;
 		frame.fp = thread_saved_fp(tsk);

^ permalink raw reply related

* [GIT PULL] pxa: fixes for 2.6.38-rc
From: Russell King - ARM Linux @ 2011-01-13 23:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTim_zbLbN-WD9Fhg+Bgin2QR6ODuNw5ru2R+3hLJ@mail.gmail.com>

On Thu, Jan 13, 2011 at 03:15:21PM -0600, Eric Miao wrote:
> Hi Russell,
> 
> The following changes since commit aebf2fc9dc974270b4b25a83816c7051c73f07c8:
> 
>   it8152: add IT8152_LAST_IRQ definition to fix build error
> (2011-01-02 23:21:14 +0800)

Nope, not pulling.

I don't have this in my tree, and it doesn't appear to exist in Linus'
tree either.  There is this commit:

commit 823a2df258627b80df2e75056b850424a8eb5fed
Author: Mike Rapoport <mike@compulab.co.il>
Date:   Wed Dec 29 09:06:26 2010 +0200

    ARM: it8152: add IT8152_LAST_IRQ definition to fix build error

    The commit 6ac6b817f3f4c23c5febd960d8deb343e13af5f3 (ARM: pxa: encode
    IRQ number into .nr_irqs) removed definition of ITE_LAST_IRQ which
    caused the following build error:

    CC      arch/arm/common/it8152.o
    arch/arm/common/it8152.c: In function 'it8152_init_irq':
    arch/arm/common/it8152.c:86: error: 'IT8152_LAST_IRQ' undeclared (first use
    arch/arm/common/it8152.c:86: error: (Each undeclared identifier is reported
    arch/arm/common/it8152.c:86: error: for each function it appears in.)
    make[2]: *** [arch/arm/common/it8152.o] Error 1

    Defining the IT8152_LAST_IRQ in the arch/arm/include/hardware/it8152.c
    fixes the build.

    Signed-off-by: Mike Rapoport <mike@compulab.co.il>
    Signed-off-by: Eric Miao <eric.y.miao@gmail.com>

but although it matches the summary, it has a different commit ID.

I smell a rebase of code already merged into mainline, and it stinks.

^ permalink raw reply

* [PATCH v3 1/1] ARM: Thumb-2: Symbol manipulation macros for function body copying
From: Dave Martin @ 2011-01-13 22:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294958503-6537-1-git-send-email-dave.martin@linaro.org>

In low-level board support code, there is sometimes a need to
copy a function body to another location at run-time.

A straightforward call to memcpy doesn't work in Thumb-2,
because bit 0 of external Thumb function symbols is set to 1,
indicating that the function is Thumb.  Without corrective
measures, this will cause an off-by-one copy, and the copy
may be called using the wrong instruction set.

This patch adds macros to help with such cases.

Particular care is needed, because C doesn't guarantee any
defined behaviour when casting a function pointer to any other
type.  This has been observed to lead to strange optimisation
side-effects when doing the arithmetic which is required in
order to copy/move function bodies correctly in Thumb-2.

Thanks to Russell King and Nicolas Pitre for their input.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
KernelVersion: v2.6.37

 arch/arm/include/asm/fncpy.h |  110 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 110 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/fncpy.h

diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644
index 0000000..6399265
--- /dev/null
+++ b/arch/arm/include/asm/fncpy.h
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/include/asm/fncpy.h - helper macros for function body copying
+ *
+ * Copyright (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, &f, size_of_f);
+ *
+ * ... do any required D-side/I-side synchronisation ...
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
+
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/cacheflush.h>
+
+/* Function pointer casting macros */
+
+/* Cast function pointer to integer: */
+#define __funcp_to_uint(funcp) ({				\
+		uintptr_t __result;				\
+								\
+		asm("" : "=r" (__result) : "0" (funcp));	\
+		__result;					\
+	})
+
+/* Cast integer to function pointer with type matching funcp: */
+#define __uint_to_funcp(i, funcp) ({			\
+		typeof(funcp) __result;			\
+							\
+		asm("" : "=r" (__result) : "0" (i));	\
+		__result;				\
+	})
+
+
+/* Function symbol manipulation macros */
+
+/*
+ * FSYM_REBASE: Determine the correct function pointer for funcp,
+ * after the function has been copied to dest_buf:
+ */
+#define FSYM_REBASE(funcp, dest_buf)					\
+	__uint_to_funcp((uintptr_t)(dest_buf) | FSYM_TYPE(funcp), funcp)
+
+/*
+ * FSYM_BASE: Determine the base address in memory of the function funcp
+ * FSYM_TYPE: Determine the instruction set type (ARM/Thumb) of funcp
+ * (both defined below)
+ */
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define FSYM_BASE(funcp) ((void *)(__funcp_to_uint(funcp) & ~(uintptr_t)1))
+#define FSYM_TYPE(funcp) (__funcp_to_uint(funcp) & 1)
+#else /* !CONFIG_THUMB2_KERNEL */
+#define FSYM_BASE(funcp) ((void *)__funcp_to_uint(funcp))
+#define FSYM_TYPE(funcp) 0
+#endif /* !CONFIG_THUMB2_KERNEL */
+
+/* Function copy helper */
+#define fncpy(dest_buf, funcp, size) ({				\
+		memcpy(dest_buf, FSYM_BASE(funcp), size);	\
+		flush_icache_range((unsigned long)(dest_buf),	\
+			(unsigned long)(dest_buf) + (size));	\
+								\
+		FSYM_REBASE(funcp, dest_buf);			\
+	})
+
+#endif /* !__ASM_FNCPY_H */
-- 
1.7.1

^ permalink raw reply related

* [PATCH v3 0/1] ARM: Thumb-2: Symbol manipulation macros for function body copying
From: Dave Martin @ 2011-01-13 22:41 UTC (permalink / raw)
  To: linux-arm-kernel

For at least one board (omap3), some functions are copied from
their link-time location into other memory at run-time.

This is a plausible thing to do if, for example, the board
might need to do something like manipulating the SDRAM 
controller configuration during power management operations.
Such code may not be able to execute from the SDRAM itself.


In Thumb-2, copying function bodies is not straightforward:
for Thumb symbols, bit 0 is set by the toolchain, and so
a function symbol can't be used directly as a base address
for memcpy: this leads to an off-by-one error, resulting in
garbage instructions in the destination buffer.


The obvious solution is to mask off this bit when calling
memcpy() and then insert the bit into the address of the
target buffer, in order to derive a pointer which can be
used to call the copied function in the correct instruction
set.  However, in practice the compiler may optimise this
operation away.  This seems wrong, but having discussed this
with compiler folks I believe it's not a compiler bug: rather,
C doesn't specifiy what happens when casting function pointers
and attempting to do arithmetic on them.  So some surprising
optimisations can happen.


To make it easier to deal with cases like this, I've had a
go at writing some macros to make copying function bodies
easier, while being robust for ARM and Thumb-2.

In particular, the required type-casts are implemented as
empty asm() blocks, to ensure that the compiler makes no
assumptions about the result.

This patch provides a fncpy() macro which resembles memcpy().
It can be used as in this example:

    extern int scary_function(int a, char *b);
    extern const int size_of_scary_function;
    extern void *scary_memory_buf;

    int (*runtime_scary_function)(int a, char *b);

    runtime_scary_function = fncpy(scary_memory_buf,
            &scary_function, 
            size_of_scary_function);

This is quite a lot more readable than the explicit code,
and should give the correct result.

fncpy() calls flush_icache_range() as necessary.

It's not possible to determine the size of a function from
C code.  This must be done by other means, such as adding
extra symbols in the assembler code where scary_function is
defined.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
KernelVersion: v2.6.37

Dave Martin (1):
  ARM: Thumb-2: Symbol manipulation macros for function body copying

 arch/arm/include/asm/fncpy.h |  110 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 110 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/fncpy.h

^ permalink raw reply

* mmaping a fixed address fails on ARM
From: Bryan Wu @ 2011-01-13 22:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113112552.GA26828@n2100.arm.linux.org.uk>

On Thu, Jan 13, 2011 at 7:25 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Thu, Jan 13, 2011 at 05:58:01AM +0800, Bryan Wu wrote:
>> The implementation of arch_get_unmapped_area() is different from ARM
>> and x86, that might makes mmap behavior different between ARM and x86.
>> Andre said 2.6.28-versatile. I'm not sure whether it is a regression.
>
> For the same conditions (iow, same mapping) on ARMv7 and ARMv5-only
> kernels vs x86 the results will be the same. ?On ARMv6-supporting kernels
> we have aliasing caches to deal with where we intentionally force the
> alignment of non-MAP_FIXED mappings.
>

Right, ARMv6 code is different in arch_get_unmapped_area() code from
others. The different results from x86 is because of some address was
mapped to libraries as Sebastien reported.

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

* mmaping a fixed address fails on ARM
From: Bryan Wu @ 2011-01-13 22:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <19758.51555.797311.465295@pilspetsen.it.uu.se>

On Thu, Jan 13, 2011 at 5:44 PM, Mikael Pettersson <mikpe@it.uu.se> wrote:
> Bryan Wu writes:
> ?> Let me add Andre here
> ?>
> ?> Thanks,
> ?> -Bryan
> ?>
> ?> On Thu, Jan 13, 2011 at 5:58 AM, Bryan Wu <bryan.wu@canonical.com> wrote:
> ?> > Hi Russell,
> ?> >
> ?> > Andre posted a mmap testcase [1] and a bug report [2] for Ubuntu
> ?> > kernel on OMAP4 system, since he is porting some applications from x86
> ?> > to ARM. He testcase works fine on x86, but always fail on ARM. I've
> ?> > tested it on OMAP3/OMAP4/i.MX51.
> ?> >
> ?> > Basically what he want to do is get a mapping on a specific virtual
> ?> > address. But AFAIK, mmap doesn't make sure we can get the mapping
> ?> > address as we want. On x86, it works fine. So if this fails, the
> ?> > application can't run on ARM.
> ?> >
> ?> > The implementation of arch_get_unmapped_area() is different from ARM
> ?> > and x86, that might makes mmap behavior different between ARM and x86.
> ?> > Andre said 2.6.28-versatile. I'm not sure whether it is a regression.
> ?> >
> ?> > [1]: http://launchpadlibrarian.net/61588086/main.c
> ?> > [2]: https://bugs.launchpad.net/ubuntu/+source/linux-ti-omap4/+bug/697004
>
> mmap() with a non-NULL hint referring to a currently unmapped area,
> but without MAP_FIXED, isn't even remotely portable or reliable
> (I've tried it myself in the context of JITs). ?It may work on
> Linux/x86, but that doesn't allow you to assume it should work
> on other OS/CPU combinations (and I know of several where it
> emphatically doesn't work).
>

Exactly. I also think the mmap() behavior is correct in this test
scenario. The address location was mapped by some LD libraries, so
mmaping those address won't get the address we expected.

> If you want a fixed address then use MAP_FIXED. ?If you don't want
> MAP_FIXED to clobber an existing mapping then you have to keep track
> of existing mappings yourself and avoid them.
>
> What is that "some application"?
>

I guess it is 'wine', don't be surprise. -:)

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

* [PATCH v2] ARM: Thumb-2: Fix out-of-range offset for Thumb-2 in proc-v7.S
From: Nicolas Pitre @ 2011-01-13 22:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294937485-7673-1-git-send-email-dave.martin@linaro.org>

On Thu, 13 Jan 2011, Dave Martin wrote:

> Commit
> 
>        d30e45e (ARM: pgtable: switch order of Linux vs hardware page tables)
> 
> introduced a pre-increment addressing offset which is out of range for
> Thumb-2.  Thumb-2 only permits offsets <256.  So split the intruction in
> two for Thumb-2.
> 
> Signed-off-by: Dave Martin <dave.martin@linaro.org>

Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>


> ---
> KernelVersion: next-20110112
> 
>  arch/arm/mm/proc-v7.S |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index b49fab2..0c1172b 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -159,7 +159,9 @@ ENTRY(cpu_v7_set_pte_ext)
>  	tstne	r1, #L_PTE_PRESENT
>  	moveq	r3, #0
>  
> -	str	r3, [r0, #2048]!
> + ARM(	str	r3, [r0, #2048]! )
> + THUMB(	add	r0, r0, #2048 )
> + THUMB(	str	r3, [r0] )
>  	mcr	p15, 0, r0, c7, c10, 1		@ flush_pte
>  #endif
>  	mov	pc, lr
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [PATCH] ARM: make head.S less dependent on the compile time PHYS_OFFSET define
From: Nicolas Pitre @ 2011-01-13 22:04 UTC (permalink / raw)
  To: linux-arm-kernel


In preparation to support a variable PHYS_OFFSET with the same kernel 
binary image, we need to get rid of the dependency on the compile time 
defined PHYS_OFFSET when establishing the initial page table.  The value 
of PHYS_OFFSET can be determined at run time by masking the pc value. A 
mask of 0xf8000000 is used to be consistent with the mask used by the 
CONFIG_AUTO_ZRELADDR feature.

If CONFIG_XIP_KERNEL is selected then the compile time PHYS_OFFSET is 
still used as before, as there is no point having a runtime determined 
PHYS_OFFSET in that case, and masking the pc value wouldn't be right 
anyway.

Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f17d9a0..be535b3 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -30,10 +30,6 @@
 #error "PHYS_OFFSET must be at an even 2MiB boundary!"
 #endif
 
-#define KERNEL_RAM_VADDR	(PAGE_OFFSET + TEXT_OFFSET)
-#define KERNEL_RAM_PADDR	(PHYS_OFFSET + TEXT_OFFSET)
-
-
 /*
  * swapper_pg_dir is the virtual address of the initial page table.
  * We place the page tables 16K below KERNEL_RAM_VADDR.  Therefore, we must
@@ -41,6 +37,7 @@
  * the least significant 16 bits to be 0x8000, but we could probably
  * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
  */
+#define KERNEL_RAM_VADDR	(PAGE_OFFSET + TEXT_OFFSET)
 #if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
 #error KERNEL_RAM_VADDR must start at 0xXXXX8000
 #endif
@@ -49,15 +46,29 @@
 	.equ	swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
 
 	.macro	pgtbl, rd
-	ldr	\rd, =(KERNEL_RAM_PADDR - 0x4000)
+	phys_offset \rd
+	add	\rd, \rd, #(TEXT_OFFSET - 0x4000)
 	.endm
 
 #ifdef CONFIG_XIP_KERNEL
+
 #define KERNEL_START	XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
 #define KERNEL_END	_edata_loc
+
+	.macro phys_offset, rd
+	ldr	\rd, =PHYS_OFFSET
+	.endm
+
 #else
+
 #define KERNEL_START	KERNEL_RAM_VADDR
 #define KERNEL_END	_end
+
+	.macro phys_offset, rd
+	mov	\rd, pc
+	and	\rd, \rd, #0xf8000000
+	.endm
+
 #endif
 
 /*
@@ -189,10 +200,9 @@ __create_page_tables:
 	/*
 	 * Map some ram to cover our .data and .bss areas.
 	 */
-	orr	r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
-	.if	(KERNEL_RAM_PADDR & 0x00f00000)
-	orr	r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
-	.endif
+	phys_offset r3
+	add	r3, r3, #TEXT_OFFSET 
+	orr	r3, r3, r7
 	add	r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> 18
 	str	r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
 	ldr	r6, =(_end - 1)

^ permalink raw reply related

* [RFC] Make SMP secondary CPU up more resilient to failure.
From: Andrei Warkentin @ 2011-01-13 22:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113111459.GC24149@n2100.arm.linux.org.uk>

On Thu, Jan 13, 2011 at 5:14 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>
> On Thu, Jan 13, 2011 at 04:19:40AM -0600, Andrei Warkentin wrote:
> > I fully agree. Would you be interested in me bringing back the actual
> > synchronization code from platform-dependent code into the preinit
> > function and posting that as a patch for review?
>
> I really don't like the idea of a preinit function - it's completely
> unnecessary as I've been trying to point out. ?It has been shown that
> it takes a hundred or so microseconds to get into the kernel, and
> then a couple of hundred milliseconds to run the delay loop.
>
> As platforms are expected to wait in their boot_secondary() for the
> first half - currently platforms wait one second - we're talking
> about around a hundred microseconds vs a timeout of one second.
> That's a factor of 10000 beyond what's required.
>
> It has also been shown that the problem you were seeing was down to
> synchronization/delayed write bugs which have since been solved - and
> adding yet more synchronization is not the answer to buggy
> synchronization.
>
> So, as the timeouts are already well in excess and the root cause of
> your problem has been resolved, I see no need to make this stuff more
> complex - the more complexity there is, the more chance there is of
> things going wrong.

Fair enough :).

^ permalink raw reply

* i.MX & IRQF_ONESHOT
From: Uwe Kleine-König @ 2011-01-13 21:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D2F6AB7.30800@eukrea.com>

On Thu, Jan 13, 2011 at 10:12:23PM +0100, Eric B?nard wrote:
> On 13/01/2011 19:15, Thomas Gleixner wrote:
> >On Thu, 13 Jan 2011, Nicolas Ferre wrote:
> >>Le 13/01/2011 10:13, Uwe Kleine-K?nig :
> >>>On Thu, Jan 13, 2011 at 09:25:19AM +0100, Eric B?nard wrote:
> >>>>Commenting out this line in the ads7846 driver makes it work again.
> >>>>Am I missing something obvious or is there a reason for IRQF_ONESHOT
> >>>>creating trouble with gpio irq or SPI on i.MX ?
> >>>I don't know.  Is the irq masked?  pending?
> >>
> >>Just to let you know that I have the same issue on my at91sam9g10ek:
> >>atmel_spi + ads7846 (using ADS7843e actually).
> >>... solved by same workaround.
> >
> >Eric, Nicolas: How are the interrupt handlers set for the relevant
> >interrupt lines and how are the interrupt pins configured?
> >
> on the i.MX27 :
> - gpio configured as a plain input (in function ads7846_dev_init()
> in arch/arm/mach-imx/eukrea_mbimx27-baseboard.c)
> - threaded interrupt handler registered with flags
> IRQF_TRIGGER_FALLING | IRQF_ONESHOT (in function ads7846_probe() in
> drivers/input/touchscreen/ads7846.c)
I didn't recheck the hw manual, but adding IRQF_TRIGGER_FALLING calls
gpio_set_irq_type (defined in arch/arm/plat-mxc/gpio.c) which results
into something called GPIO_INT_FALL_EDGE being written into a register.

So I'd say it's configured to be edge sensitive.

> - the gpio's irq is handled by a chained irq handled registered in
> arch/arm/plat-mxc/gpio.c (the CPU has only one real interrupt for
> all the GPIO banks so this real IRQ handles up to 5 x 32 gpio's
> IRQ).

Best reagrds
Uwe

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

^ permalink raw reply

* [GIT PULL] pxa: fixes for 2.6.38-rc
From: Eric Miao @ 2011-01-13 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

The following changes since commit aebf2fc9dc974270b4b25a83816c7051c73f07c8:

  it8152: add IT8152_LAST_IRQ definition to fix build error
(2011-01-02 23:21:14 +0800)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git devel

Eric Miao (1):
      ARM: pxa: fix recursive calls in pxa_low_gpio_chip

Marek Vasut (4):
      ARM: pxa: fix warning in zeus.c
      ARM: pxa: remove unused variable in clock-pxa3xx.c
      ARM: pxa: use cpu_has_ipr() consistently in irq.c
      ARM: pxa: fix suspend/resume array index miscalculation

Pavel Machek (1):
      ARM: sa1111: fix typo in sa1111_retrigger_lowirq()

Philip Rakity (2):
      ARM: mmp: MMP2 drive strength FAST using wrong value
      ARM: mmp: PXA910 drive strength FAST using wrong value

 arch/arm/common/sa1111.c                    |    2 +-
 arch/arm/mach-mmp/include/mach/mfp-mmp2.h   |    2 +-
 arch/arm/mach-mmp/include/mach/mfp-pxa910.h |    2 +-
 arch/arm/mach-pxa/clock-pxa3xx.c            |    1 -
 arch/arm/mach-pxa/irq.c                     |   49 ++++++++++-----------------
 arch/arm/mach-pxa/zeus.c                    |    4 +-
 6 files changed, 23 insertions(+), 37 deletions(-)

^ permalink raw reply

* i.MX & IRQF_ONESHOT
From: Eric Bénard @ 2011-01-13 21:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1101131839010.2678@localhost6.localdomain6>

On 13/01/2011 19:15, Thomas Gleixner wrote:
> On Thu, 13 Jan 2011, Nicolas Ferre wrote:
>> Le 13/01/2011 10:13, Uwe Kleine-K?nig :
>>> On Thu, Jan 13, 2011 at 09:25:19AM +0100, Eric B?nard wrote:
>>>> Commenting out this line in the ads7846 driver makes it work again.
>>>> Am I missing something obvious or is there a reason for IRQF_ONESHOT
>>>> creating trouble with gpio irq or SPI on i.MX ?
>>> I don't know.  Is the irq masked?  pending?
>>
>> Just to let you know that I have the same issue on my at91sam9g10ek:
>> atmel_spi + ads7846 (using ADS7843e actually).
>> ... solved by same workaround.
>
> Eric, Nicolas: How are the interrupt handlers set for the relevant
> interrupt lines and how are the interrupt pins configured?
>
on the i.MX27 :
- gpio configured as a plain input (in function ads7846_dev_init() in 
arch/arm/mach-imx/eukrea_mbimx27-baseboard.c)
- threaded interrupt handler registered with flags IRQF_TRIGGER_FALLING | 
IRQF_ONESHOT (in function ads7846_probe() in drivers/input/touchscreen/ads7846.c)
- the gpio's irq is handled by a chained irq handled registered in 
arch/arm/plat-mxc/gpio.c (the CPU has only one real interrupt for all the GPIO 
banks so this real IRQ handles up to 5 x 32 gpio's IRQ).

Eric

^ permalink raw reply

* [PATCH v4 05/10] net/fec: add dual fec support for mx28
From: Uwe Kleine-König @ 2011-01-13 21:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294297998-26930-6-git-send-email-shawn.guo@freescale.com>

Hello again,

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
>  static netdev_tx_t
>  fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	void *bufaddr;
>  	unsigned short	status;
> @@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  		bufaddr = fep->tx_bounce[index];
>  	}
>  
> +	/*
> +	 * Some design made an incorrect assumption on endian mode of
> +	 * the system that it's running on. As the result, driver has to
> +	 * swap every frame going to and coming from the controller.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +		swap_buffer(bufaddr, skb->len);
> +
Is that save here?  bufaddr either points to a bounce buffer (which
should be OK definitely) or skb->data.  Or asked differently:  Is the
skb here owned by the driver such that it is allowed to write to it?
Does the driver eventually need to restore the original data?

Just before this if, there is some bounce buffer handling.  If it is not
OK to modify skb->data, the call to swap_buffer can easily be moved in
there.

>  	/* Save skb pointer */
>  	fep->tx_skbuff[fep->skb_cur] = skb;
>  
> @@ -424,6 +464,8 @@ static void
>  fec_enet_rx(struct net_device *dev)
>  {
>  	struct	fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	struct bufdesc *bdp;
>  	unsigned short status;
>  	struct	sk_buff	*skb;
> @@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
>  	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
>          			DMA_FROM_DEVICE);
>  
> +		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
> +			swap_buffer(data, pkt_len);
> +
Here I guess it's OK, the hardware just wrote to the buffer, so the skb
cannot be shared to anything else and the write is all right.

Best regards
Uwe

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

^ permalink raw reply

* [PATCH 1/1 v2] ARM: Thumb-2: Symbol manipulation macros for function body copying
From: Dave Martin @ 2011-01-13 20:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294951905-23748-1-git-send-email-dave.martin@linaro.org>

In low-level board support code, there is sometimes a need to
copy a function body to another location at run-time.

A straightforward call to memcpy doesn't work in Thumb-2,
because bit 0 of external Thumb function symbols is set to 1,
indicating that the function is Thumb.  Without corrective
measures, this will cause an off-by-one copy, and the copy
may be called using the wrong instruction set.

This patch adds macros to help with such cases.

Particular care is needed, because C doesn't guarantee any
defined behaviour when casting a function pointer to any other
type.  This has been observed to lead to strange optimisation
side-effects when doing the arithmetic which is required in
order to copy/move function bodies correctly in Thumb-2.

Thanks to Russell King for his input on this patch.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
KernelVersion: v2.6.37

 arch/arm/include/asm/fncpy.h |  111 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/fncpy.h

diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644
index 0000000..a155fb7
--- /dev/null
+++ b/arch/arm/include/asm/fncpy.h
@@ -0,0 +1,111 @@
+/*
+ * arch/arm/include/asm/fncpy.h - helper macros for function body copying
+ *
+ * Copyright (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, &f, size_of_f);
+ *
+ * ... do any required D-side/I-side synchronisation ...
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
+
+ */
+
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/cacheflush.h>
+
+/* Function pointer casting macros */
+
+/* Cast function pointer to integer: */
+#define __funcp_to_uint(funcp) ({				\
+		uintptr_t __result;				\
+								\
+		asm("" : "=r" (__result) : "0" (funcp));	\
+		__result;					\
+	})
+
+/* Cast integer to function pointer with type matching funcp: */
+#define __uint_to_funcp(i, funcp) ({			\
+		typeof(funcp) __result;			\
+							\
+		asm("" : "=r" (__result) : "0" (i));	\
+		__result;				\
+	})
+
+
+/* Function symbol manipulation macros */
+
+/*
+ * FSYM_REBASE: Determine the correct function pointer for funcp,
+ * after the function has been copied to dest_buf:
+ */
+#define FSYM_REBASE(funcp, dest_buf)					\
+	__uint_to_funcp((uintptr_t)(dest_buf) | FSYM_TYPE(funcp), funcp)
+
+/*
+ * FSYM_BASE: Determine the base address in memory of the function funcp
+ * FSYM_TYPE: Determine the instruction set type (ARM/Thumb) of funcp
+ * (both defined below)
+ */
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define FSYM_BASE(funcp) ((void *)(__funcp_to_uint(funcp) & ~(uintptr_t)1))
+#define FSYM_TYPE(funcp) (__funcp_to_uint(funcp) & 1)
+#else /* !CONFIG_THUMB2_KERNEL */
+#define FSYM_BASE(funcp) ((void *)__funcp_to_uint(funcp))
+#define FSYM_TYPE(funcp) 0
+#endif /* !CONFIG_THUMB2_KERNEL */
+
+/* Function copy helper */
+#define fncpy(dest_buf, funcp, size) ({					\
+		memcpy(dest_buf, FSYM_BASE(funcp), size);		\
+		flush_icache_range(dest_buf, (char *)(dest_buf) + size); \
+									\
+		FSYM_REBASE(funcp, dest_buf);				\
+	})
+
+#endif /* !__ASM_FNCPY_H */
-- 
1.7.1

^ permalink raw reply related

* [PATCH v2 0/1] ARM: Thumb-2: Symbol manipulation macros for function body copying
From: Dave Martin @ 2011-01-13 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

For at least one board (omap3), some functions are copied from
their link-time location into other memory at run-time.

This is a plausible thing to do if, for example, the board
might need to do something like manipulating the SDRAM 
controller configuration during power management operations.
Such code may not be able to execute from the SDRAM itself.


In Thumb-2, copying function bodies is not straightforward:
for Thumb symbols, bit 0 is set by the toolchain, and so
a function symbol can't be used directly as a base address
for memcpy: this leads to an off-by-one error, resulting in
garbage instructions in the destination buffer.


The obvious solution is to mask off this bit when calling
memcpy() and then insert the bit into the address of the
target buffer, in order to derive a pointer which can be
used to call the copied function in the correct instruction
set.  However, in practice the compiler may optimise this
operation away.  This seems wrong, but having discussed this
with compiler folks I believe it's not a compiler bug: rather,
C doesn't specifiy what happens when casting function pointers
and attempting to do arithmetic on them.  So some surprising
optimisations can happen.


To make it easier to deal with cases like this, I've had a
go at writing some macros to make copying function bodies
easier, while being robust for ARM and Thumb-2.

In particular, the required type-casts are implemented as
empty asm() blocks, to ensure that the compiler makes no
assumptions about the result.

This patch provides a fncpy() macro which resembles memcpy().
It can be used as in this example:

    extern int scary_function(int a, char *b);
    extern const int size_of_scary_function;
    extern void *scary_memory_buf;

    int (*runtime_scary_function)(int a, char *b);

    runtime_scary_function = fncpy(scary_memory_buf,
            &scary_function, 
            size_of_scary_function);

This is quite a lot more readable than the explicit code,
and should give the correct result.

fncpy() calls flush_icache_range() as necessary.

It's not possible to determine the size of a function from
C code.  This must be done by other means, such as adding
extra symbols in the assembler code where scary_function is
defined.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
KernelVersion: v2.6.37

 arch/arm/include/asm/unified.h |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h
index bc63116..636a765 100644
--- a/arch/arm/include/asm/unified.h
+++ b/arch/arm/include/asm/unified.h
@@ -24,6 +24,32 @@
 	.syntax unified
 #endif
 
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#define __funcp_to_uint(funcp) ({				\
+		uintptr_t __result;				\
+								\
+		asm("" : "=r" (__result) : "0" (funcp));	\
+		__result;					\
+	})
+#define __uint_to_funcp(i, funcp) ({			\
+		typeof(funcp) __result;			\
+							\
+		asm("" : "=r" (__result) : "0" (i));	\
+		__result;				\
+	})
+#define FSYM_REBASE(funcp, dest_buf)					\
+	__uint_to_funcp((uintptr_t)(dest_buf) | FSYM_TYPE(funcp), funcp)
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define FSYM_BASE(funcp) ((void *)(__funcp_to_uint(funcp) & ~(uintptr_t)1))
+#define FSYM_TYPE(funcp) (__funcp_to_uint(funcp) & 1)
+#else /* !CONFIG_THUMB2_KERNEL */
+#define FSYM_BASE(funcp) ((void *)__funcp_to_uint(funcp))
+#define FSYM_TYPE(funcp) 0
+#endif /* !CONFIG_THUMB2_KERNEL */
+#endif /* !__ASSEMBLY__ */
+
 #ifdef CONFIG_THUMB2_KERNEL
 
 #if __GNUC__ < 4
-- 
1.7.1

*** BLURB HERE ***

Dave Martin (1):
  ARM: Thumb-2: Symbol manipulation macros for function body copying

 arch/arm/include/asm/unified.h |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

*** BLURB HERE ***

Dave Martin (1):
  ARM: Thumb-2: Symbol manipulation macros for function body copying

 arch/arm/include/asm/fncpy.h |  111 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/fncpy.h

^ permalink raw reply related


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