Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [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

* [PATCH] ARM: pxa: PalmZ72: Add OV9640 camera support
From: Eric Miao @ 2011-01-13 20:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294928050-15872-1-git-send-email-marek.vasut@gmail.com>

On Thu, Jan 13, 2011 at 8:14 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
> Rework of patch from 2009:
> PalmZ72: Add support for OV9640 camera sensor
>
> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> ---
> ?arch/arm/mach-pxa/include/mach/palmz72.h | ? ?5 +
> ?arch/arm/mach-pxa/palmz72.c ? ? ? ? ? ? ?| ?135 ++++++++++++++++++++++++++++++
> ?2 files changed, 140 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
> index 2bbcf70..0d4700a 100644
> --- a/arch/arm/mach-pxa/include/mach/palmz72.h
> +++ b/arch/arm/mach-pxa/include/mach/palmz72.h
> @@ -44,6 +44,11 @@
> ?#define GPIO_NR_PALMZ72_BT_POWER ? ? ? ? ? ? ? 17
> ?#define GPIO_NR_PALMZ72_BT_RESET ? ? ? ? ? ? ? 83
>
> +/* Camera */
> +#define GPIO_NR_PALMZ72_CAM_PWDN ? ? ? ? ? ? ? 56
> +#define GPIO_NR_PALMZ72_CAM_RESET ? ? ? ? ? ? ?57
> +#define GPIO_NR_PALMZ72_CAM_POWER ? ? ? ? ? ? ?91
> +
> ?/** Initial values **/
>
> ?/* Battery */
> diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
> index 7bf4017..12d58d2 100644
> --- a/arch/arm/mach-pxa/palmz72.c
> +++ b/arch/arm/mach-pxa/palmz72.c
> @@ -30,6 +30,7 @@
> ?#include <linux/wm97xx.h>
> ?#include <linux/power_supply.h>
> ?#include <linux/usb/gpio_vbus.h>
> +#include <linux/i2c-gpio.h>
>
> ?#include <asm/mach-types.h>
> ?#include <asm/mach/arch.h>
> @@ -47,6 +48,9 @@
> ?#include <mach/palm27x.h>
>
> ?#include <mach/pm.h>
> +#include <mach/camera.h>
> +
> +#include <media/soc_camera.h>
>
> ?#include "generic.h"
> ?#include "devices.h"
> @@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = {
> ? ? ? ?GPIO22_GPIO, ? ?/* LCD border color */
> ? ? ? ?GPIO96_GPIO, ? ?/* lcd power */
>
> + ? ? ? /* PXA Camera */
> + ? ? ? GPIO81_CIF_DD_0,
> + ? ? ? GPIO48_CIF_DD_5,
> + ? ? ? GPIO50_CIF_DD_3,
> + ? ? ? GPIO51_CIF_DD_2,
> + ? ? ? GPIO52_CIF_DD_4,
> + ? ? ? GPIO53_CIF_MCLK,
> + ? ? ? GPIO54_CIF_PCLK,
> + ? ? ? GPIO55_CIF_DD_1,
> + ? ? ? GPIO84_CIF_FV,
> + ? ? ? GPIO85_CIF_LV,
> + ? ? ? GPIO93_CIF_DD_6,
> + ? ? ? GPIO108_CIF_DD_7,
> +
> + ? ? ? GPIO56_GPIO, ? ?/* OV9640 Powerdown */
> + ? ? ? GPIO57_GPIO, ? ?/* OV9640 Reset */
> + ? ? ? GPIO91_GPIO, ? ?/* OV9640 Power */
> +
> + ? ? ? /* I2C */
> + ? ? ? GPIO117_GPIO, ? /* I2C_SCL */
> + ? ? ? GPIO118_GPIO, ? /* I2C_SDA */
> +
> ? ? ? ?/* Misc. */
> ? ? ? ?GPIO0_GPIO ? ? ?| WAKEUP_ON_LEVEL_HIGH, /* power detect */
> ? ? ? ?GPIO88_GPIO, ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* green led */
> @@ -254,6 +280,114 @@ device_initcall(palmz72_pm_init);
> ?#endif
>
> ?/******************************************************************************
> + * SoC Camera
> + ******************************************************************************/
> +#if defined(CONFIG_SOC_CAMERA_OV9640) || \
> + ? ? ? defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
> +static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
> + ? ? ? .flags ? ? ? ? ?= PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
> + ? ? ? ? ? ? ? ? ? ? ? PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
> + ? ? ? .mclk_10khz ? ? = 2600,
> +};
> +
> +/* Board I2C devices. */
> +static struct i2c_board_info palmz72_i2c_device[] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? I2C_BOARD_INFO("ov9640", 0x30),
> + ? ? ? }
> +};
> +
> +static int palmz72_camera_power(struct device *dev, int power)
> +{
> + ? ? ? gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
> + ? ? ? mdelay(50);
> + ? ? ? return 0;
> +}
> +
> +static int palmz72_camera_reset(struct device *dev)
> +{
> + ? ? ? gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
> + ? ? ? mdelay(50);
> + ? ? ? gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
> + ? ? ? mdelay(50);
> + ? ? ? return 0;
> +}
> +
> +static struct soc_camera_link palmz72_iclink = {
> + ? ? ? .bus_id ? ? ? ? = 0, /* Match id in pxa27x_device_camera in device.c */
> + ? ? ? .board_info ? ? = &palmz72_i2c_device[0],
> + ? ? ? .i2c_adapter_id = 0,
> + ? ? ? .module_name ? ?= "ov96xx",
> + ? ? ? .power ? ? ? ? ?= &palmz72_camera_power,
> + ? ? ? .reset ? ? ? ? ?= &palmz72_camera_reset,
> + ? ? ? .flags ? ? ? ? ?= SOCAM_DATAWIDTH_8,
> +};
> +
> +static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
> + ? ? ? .sda_pin ? ? ? ?= 118,
> + ? ? ? .scl_pin ? ? ? ?= 117,
> + ? ? ? .udelay ? ? ? ? = 10,
> + ? ? ? .timeout ? ? ? ?= 100,
> +};
> +
> +static struct platform_device palmz72_i2c_bus_device = {
> + ? ? ? .name ? ? ? ? ? = "i2c-gpio",
> + ? ? ? .id ? ? ? ? ? ? = 0, /* we use this as a replacement for i2c-pxa */
> + ? ? ? .dev ? ? ? ? ? ?= {
> + ? ? ? ? ? ? ? .platform_data ?= &palmz72_i2c_bus_data,
> + ? ? ? }
> +};
> +
> +static struct platform_device palmz72_camera = {
> + ? ? ? .name ? = "soc-camera-pdrv",
> + ? ? ? .id ? ? = -1,
> + ? ? ? .dev ? ?= {
> + ? ? ? ? ? ? ? .platform_data ?= &palmz72_iclink,
> + ? ? ? },
> +};
> +
> +/* Here we request the camera GPIOs and configure them. We power up the camera
> + * module, deassert the reset pin, but put it into powerdown (low to no power
> + * consumption) mode. This allows us to later bring the module up fast. */
> +static inline void __init palmz72_cam_gpio_init(void)
> +{
> + ? ? ? if (gpio_request(GPIO_NR_PALMZ72_CAM_PWDN, "Camera PWDN"))
> + ? ? ? ? ? ? ? goto err1;
> + ? ? ? if (gpio_request(GPIO_NR_PALMZ72_CAM_RESET, "Camera RESET"))
> + ? ? ? ? ? ? ? goto err2;
> + ? ? ? if (gpio_request(GPIO_NR_PALMZ72_CAM_POWER, "Camera DVDD"))
> + ? ? ? ? ? ? ? goto err3;
> + ? ? ? if (gpio_direction_output(GPIO_NR_PALMZ72_CAM_POWER, 1))
> + ? ? ? ? ? ? ? goto err4;
> + ? ? ? if (gpio_direction_output(GPIO_NR_PALMZ72_CAM_RESET, 0))
> + ? ? ? ? ? ? ? goto err4;
> + ? ? ? if (gpio_direction_output(GPIO_NR_PALMZ72_CAM_PWDN, 0))
> + ? ? ? ? ? ? ? goto err4;

You can use gpio_request_array() and gpio_free_array() to avoid all the
above lengthy redundant and error prone code.

> + ? ? ? return;
> +
> +err4:
> + ? ? ? gpio_free(GPIO_NR_PALMZ72_CAM_POWER);
> +err3:
> + ? ? ? gpio_free(GPIO_NR_PALMZ72_CAM_RESET);
> +err2:
> + ? ? ? gpio_free(GPIO_NR_PALMZ72_CAM_PWDN);
> +err1:
> + ? ? ? printk(KERN_ERR "Camera GPIO init failed!\n");
> + ? ? ? return;
> +}
> +
> +static void __init palmz72_camera_init(void)
> +{
> + ? ? ? palmz72_cam_gpio_init();
> + ? ? ? pxa_set_camera_info(&palmz72_pxacamera_platform_data);
> + ? ? ? platform_device_register(&palmz72_i2c_bus_device);
> + ? ? ? platform_device_register(&palmz72_camera);
> +}
> +#else
> +static inline void palmz72_camera_init(void) {}
> +#endif
> +
> +/******************************************************************************
> ?* Machine init
> ?******************************************************************************/
> ?static void __init palmz72_init(void)
> @@ -276,6 +410,7 @@ static void __init palmz72_init(void)
> ? ? ? ?palm27x_pmic_init();
> ? ? ? ?palmz72_kpc_init();
> ? ? ? ?palmz72_leds_init();
> + ? ? ? palmz72_camera_init();
> ?}
>
> ?MACHINE_START(PALMZ72, "Palm Zire72")
> --
> 1.7.2.3
>
>

^ permalink raw reply

* SMP: BUG() on cat /proc/$PID/stack
From: Rabin Vincent @ 2011-01-13 18:54 UTC (permalink / raw)
  To: linux-arm-kernel

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

Also, get_wchan() does similar stack walking but there it just checks
for task->state != TASK_RUNNING before.  Is that a sufficient check
there?

^ permalink raw reply

* i.MX & IRQF_ONESHOT
From: Thomas Gleixner @ 2011-01-13 18:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D2EDE10.3040809@atmel.com>

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:
> >> while testing 2.6.37 on our i.MX27 based board - code in
> >> arch/arm/mach-imx/eukrea_mbimx27-baseboard.c - I noticed the
> >> touchscreen controller (ADS7846) doesn't work anymore.
> >>
> >> A few IRQ are generated when probing for the chipset and starting
> >> calibration (usually first point works), then nothing more (even if
> >> the IRQ signals is generated as seen on the scope, the irq count
> >> doesn't increase anymore and stays <= 4 and no data is reported to
> >> the input layer).
> >>
> >> drivers/input/touchscreen/ads7846.c was switched to threaded IRQ in
> >> commit 2991a1ca6e9b13b639a82c0eec0cbc191bf1f42f where was added :
> >> irq_flags |= IRQF_ONESHOT;
> > AFAIK this is how threaded irq usually work.  The irq should get
> > reenabled by irq_thread -> irq_finalize_oneshot then.

Well, yes and no. That applies only when you have a level type
interrupt as you want to keep the irq line masked until the thread did
it's magic with the device. Keeping the line masked for edge type
interrupts would be fatal as you might loose interrupts. That's why we
have the different flow handlers and the ONESHOT check is only
implemented in handle_level_irq().

Though the driver sets the ONESHOT flag unconditionally, which should
be not a problem in theory as we don't handle oneshot stuff in other
flow handlers. The only problem could be irq_finalize_oneshot()
fiddling with the irq line, but that's guarded by a IRQ_DISABLED and
IRQ_MASKED check so this should not hurt.

Though it might hurt when the interrupt line has handle_level_irq()
and the interrupt pin is configured for edge. The driver uses
TRIGGER_RAISING/FALLING which is usually a sign of edge type. So I
assume that there is some wreckage lurking in there, which just got
covered up by the old code in some way.

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

Thanks,

	tglx

^ permalink raw reply

* [PATCH v2] unbreak ehci-mxc on otg port of i.MX27
From: Greg KH @ 2011-01-13 18:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D2F3AE1.6000505@ru.mvista.com>

On Thu, Jan 13, 2011 at 08:48:17PM +0300, Sergei Shtylyov wrote:
> Hello.
> 
> Eric B?nard wrote:
> 
> >commit 711669e5b80b6f2d88f61ed8a9681f83d8cbd201 fixed port 0 support
> 
>    Please also specify the commit summary in parens, as asked by
> Linus. I think I have already asked you to do so.

No need, I can handle it.

thanks,

greg k-h

^ permalink raw reply

* [PATCH v2] unbreak ehci-mxc on otg port of i.MX27
From: Sergei Shtylyov @ 2011-01-13 17:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294926797-19345-1-git-send-email-eric@eukrea.com>

Hello.

Eric B?nard wrote:

> commit 711669e5b80b6f2d88f61ed8a9681f83d8cbd201 fixed port 0 support

    Please also specify the commit summary in parens, as asked by Linus. I think 
I have already asked you to do so.

> for i.MX51 but broke it for (at least) i.MX27 which doesn't have
> a usb_phy1 clock but has a pdev->id 0.

> Signed-off-by: Eric B?nard <eric@eukrea.com>
> Cc: Arnaud Patard <arnaud.patard@rtp-net.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>

WBR, Sergei

^ permalink raw reply

* resume regression in 2.6.37
From: Thomas Gleixner @ 2011-01-13 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294938961.10740.24.camel@sven>

On Thu, 13 Jan 2011, Sven Neumann wrote:
> On Thu, 2011-01-13 at 17:28 +0100, Thomas Gleixner wrote:
> > On Thu, 13 Jan 2011, Sven Neumann wrote:
> > > Any idea on how to proceed from here? I don't think I can just revert
> > > this commit and expect things to work, right?
> > 
> > Well, I somehow doubt, that this is the real culprit. The patch does
> > not change anything of the set_wake() functionality. It's a functional
> > equivivalent wrapper, nothing else.
> > 
> > Can you revert it on top of 2.6.37 and verify that it helps ?
> 
> I've done that now and while it doesn't solve the problem completely, I
> can definitely say that reverting the change does make a difference. 

Hmm. I have to admit that this confuses the hell out of me.

> Without the revert there is absolutely no sign of resume. With the
> change reverted I can see that the PXA powers up again, there's an LED
> showing that the USB controller has power again. Unfortunately there's
> seems to be another problem and the resume doesn't complete. I've tried
> to get console output by using no_console_suspend, but there's just
> gibberish on the console after resume :(
> 
> Any idea on how to proceed from here? I could perhaps ask our hardware
> engineer to try find out where exactly we are stuck in the resume. But
> I'd like to avoid that if possible.

Can you stick a printk into the set_wake() function of that irq chip
and print the irq and on arguments and the return value . Run that
with both stock 2.6.37 and the patch reverted.

Thanks,

	tglx

^ permalink raw reply

* resume regression in 2.6.37
From: Sven Neumann @ 2011-01-13 17:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1101131720350.2678@localhost6.localdomain6>

On Thu, 2011-01-13 at 17:28 +0100, Thomas Gleixner wrote:
> On Thu, 13 Jan 2011, Sven Neumann wrote:
> > Now I've tried to update the kernel to 2.6.37. After fixing the already
> > reported NULL pointer dereference on bootup in pxa3xx_nand_probe(), the
> > device seems to work fine until I suspend it and then try to wake it up
> > from suspend. Suspend seems to work fine, no warnings whatsoever.
> > However there is absolutely no sign of resume.
> > 
> > I've used git bisect to track this down to the following commit:
> > 
> > 
> > commit 2f7e99bb9be6a2d8d7b808dc86037710cc8b7bf1
> > Author: Thomas Gleixner <tglx@linutronix.de>
> > Date:   Mon Sep 27 12:45:50 2010 +0000
> > 
> >     genirq: Provide compat handling for chip->set_wake()
> >     
> >     Wrap the old chip function set_wake() until the migration is
> >     complete and the old chip functions are removed.
> >     
> >     Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> >     Cc: Peter Zijlstra <peterz@infradead.org>
> >     LKML-Reference: <20100927121842.927527393@linutronix.de>
> >     Reviewed-by: H. Peter Anvin <hpa@zytor.com>
> >     Reviewed-by: Ingo Molnar <mingo@elte.hu>
> > 
> > 
> > Any idea on how to proceed from here? I don't think I can just revert
> > this commit and expect things to work, right?
> 
> Well, I somehow doubt, that this is the real culprit. The patch does
> not change anything of the set_wake() functionality. It's a functional
> equivivalent wrapper, nothing else.
> 
> Can you revert it on top of 2.6.37 and verify that it helps ?

I've done that now and while it doesn't solve the problem completely, I
can definitely say that reverting the change does make a difference. 

Without the revert there is absolutely no sign of resume. With the
change reverted I can see that the PXA powers up again, there's an LED
showing that the USB controller has power again. Unfortunately there's
seems to be another problem and the resume doesn't complete. I've tried
to get console output by using no_console_suspend, but there's just
gibberish on the console after resume :(

Any idea on how to proceed from here? I could perhaps ask our hardware
engineer to try find out where exactly we are stuck in the resume. But
I'd like to avoid that if possible.


Thanks,
Sven

^ permalink raw reply

* [PATCH v2] ARM: Thumb-2: Fix out-of-range offset for Thumb-2 in proc-v7.S
From: Dave Martin @ 2011-01-13 16:51 UTC (permalink / raw)
  To: linux-arm-kernel

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

^ permalink raw reply related

* [PATCH] omap4: Fix ULPI PHY init for ES1.0 SDP (Re: 4430SDP boot failure)
From: Russell King - ARM Linux @ 2011-01-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113155152.GG4957@atomide.com>

On Thu, Jan 13, 2011 at 07:51:53AM -0800, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [110113 01:15]:
> > Given the very sorry state of OMAP in mainline at present, I'm surprised
> > that this kind of stuff is still going on...
> 
> At least I boot test the patches I send..

Which is why OMAP3 and OMAP4 can't be built in mainline because they
spit out lots of compile errors in the OMAP code...  As they won't
even compile they couldn't have been boot tested.

^ permalink raw reply

* resume regression in 2.6.37
From: Thomas Gleixner @ 2011-01-13 16:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294933492.2535.23.camel@sven>

On Thu, 13 Jan 2011, Sven Neumann wrote:
> Now I've tried to update the kernel to 2.6.37. After fixing the already
> reported NULL pointer dereference on bootup in pxa3xx_nand_probe(), the
> device seems to work fine until I suspend it and then try to wake it up
> from suspend. Suspend seems to work fine, no warnings whatsoever.
> However there is absolutely no sign of resume.
> 
> I've used git bisect to track this down to the following commit:
> 
> 
> commit 2f7e99bb9be6a2d8d7b808dc86037710cc8b7bf1
> Author: Thomas Gleixner <tglx@linutronix.de>
> Date:   Mon Sep 27 12:45:50 2010 +0000
> 
>     genirq: Provide compat handling for chip->set_wake()
>     
>     Wrap the old chip function set_wake() until the migration is
>     complete and the old chip functions are removed.
>     
>     Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>     Cc: Peter Zijlstra <peterz@infradead.org>
>     LKML-Reference: <20100927121842.927527393@linutronix.de>
>     Reviewed-by: H. Peter Anvin <hpa@zytor.com>
>     Reviewed-by: Ingo Molnar <mingo@elte.hu>
> 
> 
> Any idea on how to proceed from here? I don't think I can just revert
> this commit and expect things to work, right?

Well, I somehow doubt, that this is the real culprit. The patch does
not change anything of the set_wake() functionality. It's a functional
equivivalent wrapper, nothing else.

Can you revert it on top of 2.6.37 and verify that it helps ?

Thanks,

	tglx

^ permalink raw reply

* [PATCH 2/2] arm: omap3: cm-t3517: minor comment fix
From: Igor Grinberg @ 2011-01-13 16:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294935890-31160-1-git-send-email-grinberg@compulab.co.il>

offsets in the comment were wrong - fix this.

Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
---
 arch/arm/mach-omap2/board-cm-t3517.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 1706df0..8f9a64d 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -225,12 +225,12 @@ static struct mtd_partition cm_t3517_nand_partitions[] = {
 	},
 	{
 		.name           = "linux",
-		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x280000 */
+		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x2A0000 */
 		.size           = 32 * NAND_BLOCK_SIZE,
 	},
 	{
 		.name           = "rootfs",
-		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x680000 */
+		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x6A0000 */
 		.size           = MTDPART_SIZ_FULL,
 	},
 };
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 1/2] arm: omap3: cm-t3517: rtc fix
From: Igor Grinberg @ 2011-01-13 16:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294935890-31160-1-git-send-email-grinberg@compulab.co.il>

Fix rtc gpios and mux

Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
---
 arch/arm/mach-omap2/board-cm-t3517.c |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 5b0c777..1706df0 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -124,8 +124,9 @@ static inline void cm_t3517_init_hecc(void) {}
 #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
 #define RTC_IO_GPIO		(153)
 #define RTC_WR_GPIO		(154)
-#define RTC_RD_GPIO		(160)
+#define RTC_RD_GPIO		(53)
 #define RTC_CS_GPIO		(163)
+#define RTC_CS_EN_GPIO		(160)
 
 struct v3020_platform_data cm_t3517_v3020_pdata = {
 	.use_gpio	= 1,
@@ -145,6 +146,16 @@ static struct platform_device cm_t3517_rtc_device = {
 
 static void __init cm_t3517_init_rtc(void)
 {
+	int err;
+
+	err = gpio_request(RTC_CS_EN_GPIO, "rtc cs en");
+	if (err) {
+		pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
+		return;
+	}
+
+	gpio_direction_output(RTC_CS_EN_GPIO, 1);
+
 	platform_device_register(&cm_t3517_rtc_device);
 }
 #else
@@ -256,11 +267,19 @@ static void __init cm_t3517_init_irq(void)
 static struct omap_board_mux board_mux[] __initdata = {
 	/* GPIO186 - Green LED */
 	OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-	/* RTC GPIOs: IO, WR#, RD#, CS# */
+
+	/* RTC GPIOs: */
+	/* IO - GPIO153 */
 	OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+	/* WR# - GPIO154 */
 	OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-	OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+	/* RD# - GPIO53 */
+	OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+	/* CS# - GPIO163 */
 	OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+	/* CS EN - GPIO160 */
+	OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
 	/* HSUSB1 RESET */
 	OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
 	/* HSUSB2 RESET */
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 0/2] cm-t3517 fixes
From: Igor Grinberg @ 2011-01-13 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

This little patch serie is based on Tony's devel-board branch.
It fixes the rtc and some comments on cm-t3517.

Igor Grinberg (2):
  arm: omap3: cm-t3517: rtc fix
  arm: omap3: cm-t3517: minor comment fix

 arch/arm/mach-omap2/board-cm-t3517.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)

-- 
1.7.2.5

^ permalink raw reply

* Possible patch; fix perf Annotation of Thumb code
From: Dave Martin @ 2011-01-13 16:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113130037.GB5241@davesworkthinkpad>

On Thu, Jan 13, 2011 at 7:00 AM, Dr. David Alan Gilbert
<david.gilbert@linaro.org> wrote:
> Hi,
> ?I'm finding that if I annotate an ARM Thumb function with perf that it's
> mis-disassembling it; below is a patch that fixes it, but I'm not sure if
> it's the best place for the fix.
>
> ?The problem is that on Thumb, the bottom bit of the symbol address is
> set for thumb functions, and thus perf starts disassembling at address+1,
> and since all thumb instructions are 2 bytes aligned to 2 bytes you end
> up disassembling across the middle of pairs of instructions.
>
>
> ?The patch removes that bottom bit during symbol loading.
>
> ?Questions:
> ? ?1) Is this the right place to do it - does some other bit of Perf need the
> raw symbol value? ?My alternative is to mask it just before the objdump,
> but then my worry is if it also needs masking somewhere else.
>
> ? ?2) Should the check be more selective - i.e. only some symbol types?

We should definitely only do this if for function symbols, since data
symbols have no "thumb bit" and can be arbitrarily aligned.

I think this can be achieved by checking map->type :

if ((ehdr.e_machine == EM_ARM) && map->type == MAP__FUNCTION &&
(sym.st_value & 1)) {
 ...

Cheers
---Dave

>
> This is against the Linaro 2.6.37 tree; I'm happy to rebase it against
> the clean 2.6.37 if people agree the patch is doing the right thing.
>
> Dave
> (For reference this corresponds to this bug
> https://bugs.launchpad.net/linux-linaro/+bug/677547 )
>
> ? ? ? ?Signed-off-by: Dr. David Alan Gilbert <david.gilbert@linaro.org>
> ---
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 439ab94..3d77b5e 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -1129,6 +1129,11 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
>
> ? ? ? ? ? ? ? ?section_name = elf_sec__name(&shdr, secstrs);
>
> + ? ? ? ? ? ? ? /* On ARM, symbols for thumb functions have 1 added to
> + ? ? ? ? ? ? ? the symbol address as a flag - remove it */
> + ? ? ? ? ? ? ? if ((ehdr.e_machine == EM_ARM) && (sym.st_value & 1))
> + ? ? ? ? ? ? ? ? ? ? ? sym.st_value-=1;
> +
> ? ? ? ? ? ? ? ?if (self->kernel != DSO_TYPE_USER || kmodule) {
> ? ? ? ? ? ? ? ? ? ? ? ?char dso_name[PATH_MAX];
>
>

^ permalink raw reply

* [PATCH] ARM mxs: clkdev related compile fixes
From: Uwe Kleine-König @ 2011-01-13 15:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20101117090635.GF12959@game.jcrosoft.org>

From: Sascha Hauer <s.hauer@pengutronix.de>

Since commit

	6d803ba (ARM: 6483/1: arm & sh: factorised duplicated clkdev.c)

platforms need to select CLKDEV_LOOKUP instead of COMMON_CLKDEV and need
to include <linux/clkdev.h>.

Cc: Shawn Guo <shawn.guo@freescale.com>
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
[ukl: make commit log more verbose; remove selection of COMMON_CLKDEV]
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 arch/arm/Kconfig               |    2 +-
 arch/arm/mach-mxs/clock-mx23.c |    1 +
 arch/arm/mach-mxs/clock-mx28.c |    1 +
 3 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e2f8011..041894e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -368,7 +368,7 @@ config ARCH_MXS
 	bool "Freescale MXS-based"
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
-	select COMMON_CLKDEV
+	select CLKDEV_LOOKUP
 	help
 	  Support for Freescale MXS-based family of processors
 
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index 8f5a19a..f94925b 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
+#include <linux/clkdev.h>
 
 #include <asm/clkdev.h>
 #include <asm/div64.h>
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 74e2103..56d7dc7 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
+#include <linux/clkdev.h>
 
 #include <asm/clkdev.h>
 #include <asm/div64.h>
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH] omap4: Fix ULPI PHY init for ES1.0 SDP (Re: 4430SDP boot failure)
From: Tony Lindgren @ 2011-01-13 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113091546.GA24429@n2100.arm.linux.org.uk>

* Russell King - ARM Linux <linux@arm.linux.org.uk> [110113 01:15]:
> On Thu, Jan 13, 2011 at 02:22:06PM +0530, Anand Gadiyar wrote:
> > Tony Lindgren wrote:
> > >  	/* Power on the ULPI PHY */
> > > -	if (gpio_is_valid(OMAP4SDP_MDM_PWR_EN_GPIO)) {
> > > -		/* FIXME: Assumes pad is already muxed for GPIO mode */
> > > -		gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY
> > VMDM_3V3");
> > > +	status = gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY
> > VMDM_3V3");
> > > +	if (status)
> > > +		pr_err("%s: Could not get USBB1 PHY GPIO\n");
> > 
> > Tony,
> > 
> > This throws up a build warning as there's no parameter corresponding to
> > the %s. Showed up in linux-next as of today.

Oops, sorry, will fix.
 
> It's pretty obvious that the above is wrong, and the compiler would
> have caught it with a warning when building it.  Was the above patch
> not build-tested before it was committed?

Sure, boot tested it but missed the warning though.
 
> Given the very sorry state of OMAP in mainline at present, I'm surprised
> that this kind of stuff is still going on...

At least I boot test the patches I send..

Regards,

Tony

^ permalink raw reply

* resume regression in 2.6.37
From: Sven Neumann @ 2011-01-13 15:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

we are using devices based on an PXA300 and are successfully using the
2.6.36.2 kernel (vanilla, basically unpatched). You can find the
platform-specific code that describes our devices
in /arch/arm/mach-pxa/raumfeld.c.

Now I've tried to update the kernel to 2.6.37. After fixing the already
reported NULL pointer dereference on bootup in pxa3xx_nand_probe(), the
device seems to work fine until I suspend it and then try to wake it up
from suspend. Suspend seems to work fine, no warnings whatsoever.
However there is absolutely no sign of resume.

I've used git bisect to track this down to the following commit:


commit 2f7e99bb9be6a2d8d7b808dc86037710cc8b7bf1
Author: Thomas Gleixner <tglx@linutronix.de>
Date:   Mon Sep 27 12:45:50 2010 +0000

    genirq: Provide compat handling for chip->set_wake()
    
    Wrap the old chip function set_wake() until the migration is
    complete and the old chip functions are removed.
    
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Cc: Peter Zijlstra <peterz@infradead.org>
    LKML-Reference: <20100927121842.927527393@linutronix.de>
    Reviewed-by: H. Peter Anvin <hpa@zytor.com>
    Reviewed-by: Ingo Molnar <mingo@elte.hu>


Any idea on how to proceed from here? I don't think I can just revert
this commit and expect things to work, right?


Regards,
Sven


-- 
Sven Neumann
Head of RAUMFELD Software Development

Lautsprecher Teufel GmbH | B?lowstr. 66 | 10783 Berlin | Germany
Tel: +49 (0)30-300 930 153 | s.neumann at raumfeld.com

^ permalink raw reply

* RFC i.MX ehci cleanup
From: Sascha Hauer @ 2011-01-13 15:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

As many of the i.MX users know the current ehci support in
arch/arm/plat-mxc/ehci.c is a mess. Basically we try to encode the
values for the USBCTRL register in pseudo generic flags, pass them via
platform data to the USB driver which again calls SoC code in ehci.c to
decode the flags again. On all i.MX SoCs (except i.MX51/53) We only need
to setup a single register which is completely static for a given
machine.  So I propose that we just provide a ehci_get function which
enables the USB clock to provide register access and let it up to the
board setting the register correctly. The following patch is an example
for the i.MX27 phycard module to describe what I'm talking about.  For
the i.MX51 we might want to provide some kind of helper function as the
USB phy setup is more complex on this SoC.

What do you think?

Sascha

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/mach-pca100.c      |   13 +++++++++++++
 arch/arm/plat-mxc/ehci.c             |   22 ++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/usb.h |   31 +++++++++++++++++++++++++++++++
 drivers/usb/host/ehci-mxc.c          |    2 +-
 4 files changed, 67 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index cccc0a0..1786e58 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -357,6 +357,7 @@ static const struct imx_fb_platform_data pca100_fb_data __initconst = {
 static void __init pca100_init(void)
 {
 	int ret;
+	void __iomem *usbbase;
 
 	/* SSI unit */
 	mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
@@ -402,6 +403,18 @@ static void __init pca100_init(void)
 	gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs");
 	gpio_direction_output(USBH2_PHY_CS_GPIO, 1);
 
+	usbbase = mx27_ehci_get();
+	if (usbbase) {
+		writel(IMX27_USBCTRL_H2DT |
+			IMX27_USBCTRL_H2PM |
+			IMX27_USBCTRL_H2WIE |
+			IMX27_USBCTRL_H2UIE |
+			IMX27_USBCTRL_OPM, usbbase + IMX27_USBCTRL);
+		mx27_ehci_put();
+	}
+
 #if defined(CONFIG_USB_ULPI)
 	if (otg_mode_host) {
 		otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 8772ce3..7941c20 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -15,6 +15,8 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
 
 #include <mach/hardware.h>
 #include <mach/mxc_ehci.h>
@@ -367,3 +369,23 @@ error:
 }
 EXPORT_SYMBOL(mxc_initialize_usb_hw);
 
+static struct clk *ehci_clk;
+
+void __iomem *mx27_ehci_get(void)
+{
+	if (!ehci_clk)
+		ehci_clk = clk_get_sys("mxc-ehci.0", "usb");
+	if (IS_ERR(ehci_clk)) {
+		WARN_ONCE("could not get USB clock\n");
+		return NULL;
+	}
+
+	clk_enable(ehci_clk);
+
+	return MX27_IO_ADDRESS(MX27_USB_BASE_ADDR);
+}
+
+void mx27_ehci_put(void)
+{
+	clk_disable(ehci_clk);
+}
diff --git a/arch/arm/plat-mxc/include/mach/usb.h b/arch/arm/plat-mxc/include/mach/usb.h
index be27337..3c042ce 100644
--- a/arch/arm/plat-mxc/include/mach/usb.h
+++ b/arch/arm/plat-mxc/include/mach/usb.h
@@ -20,4 +20,35 @@ struct imxusb_platform_data {
 	void (*exit)(struct device *);
 };
 
+#define IMX27_USBCTRL_H1DT		(1 << 4)
+#define IMX27_USBCTRL_H2DT		(1 << 5)
+#define IMX27_USBCTRL_H1PM		(1 << 8)
+#define IMX27_USBCTRL_H1WIE		(1 << 11)
+#define IMX27_USBCTRL_H1SIC_DIFF_UNI	(0 << 13)
+#define IMX27_USBCTRL_H1SIC_DIFF_BI	(1 << 13)
+#define IMX27_USBCTRL_H1SIC_SINGLE_UNI	(2 << 13)
+#define IMX27_USBCTRL_H1SIC_SINGLE_BI	(3 << 13)
+#define IMX27_USBCTRL_H1WIR		(1 << 15)
+#define IMX27_USBCTRL_H2PM		(1 << 16)
+#define IMX27_USBCTRL_H2WIE		(1 << 19)
+#define IMX27_USBCTRL_H2UIE		(1 << 20)
+#define IMX27_USBCTRL_H2SIC_DIFF_UNI	(0 << 21)
+#define IMX27_USBCTRL_H2SIC_DIFF_BI	(1 << 21)
+#define IMX27_USBCTRL_H2SIC_SINGLE_UNI	(2 << 21)
+#define IMX27_USBCTRL_H2SIC_SINGLE_BI	(3 << 21)
+#define IMX27_USBCTRL_H2WIR		(1 << 23)
+#define IMX27_USBCTRL_OPM		(1 << 24)
+#define IMX27_USBCTRL_OWIE		(1 << 27)
+#define IMX27_USBCTRL_OUIE		(1 << 28)
+#define IMX27_USBCTRL_OSIC_DIFF_UNI	(0 << 29)
+#define IMX27_USBCTRL_OSIC_DIFF_BI	(1 << 29)
+#define IMX27_USBCTRL_OSIC_SINGLE_UNI	(2 << 29)
+#define IMX27_USBCTRL_OSIC_SINGLE_BI	(3 << 29)
+#define IMX27_USBCTRL_OWIR		(1 << 31)
+
+#define IMX27_USBCTRL			0x600
+
+void __iomem *mx27_ehci_get(void);
+void mx27_ehci_put(void);
+
 #endif /* __ASM_ARCH_MXC_USB */
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index fa59b26..185f86f 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -178,7 +178,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
 	}
 
 	/* "dr" device has its own clock */
-	if (pdev->id == 0) {
+	if (cpu_is_mx51() && pdev->id == 0) {
 		priv->phy1clk = clk_get(dev, "usb_phy1");
 		if (IS_ERR(priv->phy1clk)) {
 			ret = PTR_ERR(priv->phy1clk);
-- 
1.7.2.3

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply related

* [PATCH v4 08/10] ARM: mxs: add ocotp read function
From: Uwe Kleine-König @ 2011-01-13 15:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294297998-26930-9-git-send-email-shawn.guo@freescale.com>

On Thu, Jan 06, 2011 at 03:13:16PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Call cpu_relax() during polling
> 
> Changes for v2:
>  - Add mutex locking for mxs_read_ocotp()
>  - Use type size_t for count and i
>  - Add comment for clk_enable/disable skipping
>  - Add ERROR bit clearing and polling step
> 
>  arch/arm/mach-mxs/Makefile              |    2 +-
>  arch/arm/mach-mxs/include/mach/common.h |    1 +
>  arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/ocotp.c
> 
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 39d3f9c..f23ebbd 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -1,5 +1,5 @@
>  # Common support
> -obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
is it worth to make ocotp optional?  (and let evk select
CONFIG_MXS_OCOTP)

Best regards
Uwe
>  
>  obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
>  obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
> index 59133eb..cf02552 100644
> --- a/arch/arm/mach-mxs/include/mach/common.h
> +++ b/arch/arm/mach-mxs/include/mach/common.h
> @@ -13,6 +13,7 @@
>  
>  struct clk;
>  
> +extern int mxs_read_ocotp(int offset, int count, u32 *values);
>  extern int mxs_reset_block(void __iomem *);
>  extern void mxs_timer_init(struct clk *, int);
>  
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..e2d39aa
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * 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/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define BM_OCOTP_CTRL_BUSY		(1 << 8)
> +#define BM_OCOTP_CTRL_ERROR		(1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +
> +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> +{
> +	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> +	int timeout = 0x400;
> +	size_t i;
> +
> +	mutex_lock(&ocotp_mutex);
> +
> +	/*
> +	 * clk_enable(hbus_clk) for ocotp can be skipped
> +	 * as it must be on when system is running.
> +	 */
> +
> +	/* try to clear ERROR bit */
> +	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> +	/* check both BUSY and ERROR cleared */
> +	while ((__raw_readl(ocotp_base) &
> +		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	/* open OCOTP banks for read */
> +	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	/* approximately wait 32 hclk cycles */
> +	udelay(1);
> +
> +	/* poll BUSY bit becoming cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
> +		cpu_relax();
> +
> +	if (unlikely(!timeout))
> +		goto error_unlock;
> +
> +	for (i = 0; i < count; i++, offset += 4)
> +		*values++ = __raw_readl(ocotp_base + offset);
> +
> +	/* close banks for power saving */
> +	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
> +
> +	mutex_unlock(&ocotp_mutex);
> +
> +	return 0;
> +
> +error_unlock:
> +	mutex_unlock(&ocotp_mutex);
> +	pr_err("%s: timeout in reading OCOTP\n", __func__);
> +	return -ETIMEDOUT;
> +}
> -- 
> 1.7.1
> 
> 
> 

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

^ permalink raw reply

* [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
From: Uwe Kleine-König @ 2011-01-13 15:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294297998-26930-7-git-send-email-shawn.guo@freescale.com>

Hi Shawn,

On Thu, Jan 06, 2011 at 03:13:14PM +0800, Shawn Guo wrote:
> Change device name from "fec" to "imx28-fec", so that fec driver
> can distinguish mx28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use "imx28-fec" as fec device name
> 
> Changes for v3:
>  - Change device name to "enet-mac"
> 
>  arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
>  arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
> index f20b254..e2a8b0f 100644
> --- a/arch/arm/mach-mxs/clock-mx28.c
> +++ b/arch/arm/mach-mxs/clock-mx28.c
> @@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
>  	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
>  	/* for amba-pl011 driver */
>  	_REGISTER_CLOCK("duart", NULL, uart_clk)
> -	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
>  	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
>  	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
>  	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> index c08168c..c42dff7 100644
> --- a/arch/arm/mach-mxs/devices/platform-fec.c
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
>  		},
>  	};
>  
> -	return mxs_add_platform_device("fec", data->id,
> +	return mxs_add_platform_device("imx28-fec", data->id,
IMHO "imx28-fec" shouldn't be hard coded here but come from data.  See
imx-spi device registration for an example.

Uwe
>  			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
>  }
> -- 
> 1.7.1
> 
> 
> 

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

^ permalink raw reply

* [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
From: Uwe Kleine-König @ 2011-01-13 14:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294297998-26930-10-git-send-email-shawn.guo@freescale.com>

Hello Shawn,

$SUBJECT ~= s,mx28,mxs/mx28evk, please

On Thu, Jan 06, 2011 at 03:13:17PM +0800, Shawn Guo wrote:
> Read fec mac address from ocotp and save it into fec_platform_data
> mac field for fec driver to use.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - It's not necessary to remove "const" for fec_platform_data from
>    platform-fec.c and devices-common.h, so add it back.
>  - Hard-coding Freescale OUI (00:04:9f) instead of just the first
>    two two octets.
>  - Correct the return of mx28evk_fec_get_mac() and check it
>    with caller
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> index def6519..54fa512 100644
> --- a/arch/arm/mach-mxs/mach-mx28evk.c
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
>  	},
>  };
>  
> +static int __init mx28evk_fec_get_mac(void)
> +{
> +	int i, ret;
> +	u32 val;
> +
> +	/*
> +	 * OCOTP only stores the last 4 octets for each mac address,
> +	 * so hard-code Freescale OUI (00:04:9f) here.
> +	 */
> +	for (i = 0; i < 2; i++) {
> +		ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
> +		if (ret)
> +			goto error;
> +
> +		mx28_fec_pdata[i].mac[0] = 0x00;
> +		mx28_fec_pdata[i].mac[1] = 0x04;
> +		mx28_fec_pdata[i].mac[2] = 0x9f;
> +		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
> +		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
> +		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
> +	}
> +
> +	return 0;
> +
> +error:
> +	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
> +	return ret;
> +}
> +
>  static void __init mx28evk_init(void)
>  {
>  	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
>  
>  	mx28_add_duart();
>  
> +	if (mx28evk_fec_get_mac())
> +		pr_warn("%s: failed on fec mac setup\n", __func__);
> +
>  	mx28evk_fec_reset();
>  	mx28_add_fec(0, &mx28_fec_pdata[0]);
>  #ifdef CONFIG_FEC2
> -- 
> 1.7.1
> 
> 
> 

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

^ permalink raw reply

* [PATCH v5] ARM: mx28: add the second fec device registration
From: Uwe Kleine-König @ 2011-01-13 14:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294747764-4499-1-git-send-email-shawn.guo@freescale.com>

On Tue, Jan 11, 2011 at 08:09:24PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v5:
>  - Do not use CONFIG_FEC2 which is a fec driver configration
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |   26 +++++++++++++++++++++++---
>  1 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> index d162e95..8e2c597 100644
> --- a/arch/arm/mach-mxs/mach-mx28evk.c
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
>  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
>  	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
>  		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	/* fec1 */
> +	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_COL__ENET1_TX_EN |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
> +	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
> +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
>  	/* phy power line */
>  	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
>  		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
> @@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
>  	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
>  }
>  
> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> -	.phy = PHY_INTERFACE_MODE_RMII,
> +static struct fec_platform_data mx28_fec_pdata[] = {
this can still be initdata, doesn't it?

> +	{
> +		/* fec0 */
> +		.phy = PHY_INTERFACE_MODE_RMII,
> +	}, {
> +		/* fec1 */
> +		.phy = PHY_INTERFACE_MODE_RMII,
> +	},
>  };
>  
>  static void __init mx28evk_init(void)
> @@ -117,7 +136,8 @@ static void __init mx28evk_init(void)
>  	mx28_add_duart();
>  
>  	mx28evk_fec_reset();
> -	mx28_add_fec(0, &mx28_fec_pdata);
> +	mx28_add_fec(0, &mx28_fec_pdata[0]);
> +	mx28_add_fec(1, &mx28_fec_pdata[1]);
>  }
>  
>  static void __init mx28evk_timer_init(void)
> -- 
> 1.7.1
> 
> 
> 

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

^ permalink raw reply

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

Hello,

hmm, this review comes to late, probably I will post a follow-up patch
for the low-hanging fruits at least.

On Thu, Jan 06, 2011 at 03:13:13PM +0800, Shawn Guo wrote:
> This patch is to add mx28 dual fec support. Here are some key notes
> for mx28 fec controller.
> 
>  - The mx28 fec controller naming ENET-MAC is a different IP from FEC
>    used on other i.mx variants.  But they are basically compatible
>    on software interface, so it's possible to share the same driver.
>  - ENET-MAC design on mx28 made an improper assumption that it runs
>    on a big-endian system. As the result, driver has to swap every
>    frame going to and coming from the controller.
>  - The external phys can only be configured by fec0, which means fec1
>    can not work independently and both phys need to be configured by
>    mii_bus attached on fec0.
>  - ENET-MAC reset will get mac address registers reset too.
>  - ENET-MAC MII/RMII mode and 10M/100M speed are configured
>    differently FEC.
>  - ETHER_EN bit must be set to get ENET-MAC interrupt work.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Use #ifndef CONFIG_ARM to include ColdFire header files
I intended you to not use CONFIG_ARCH_MXS at all, at least up to now
CONFIG_ARM works quite well.

>  - Define quirk bits in id_entry.driver_data to handle controller
>    difference, which is more scalable than using device name
>  - Define fec0_mii_bus as a static function in fec_enet_mii_init
>    to fold the mii_bus instance attached on fec0
IMHO not very good.  At least the current code doesn't allow to have two
dual-fecs, because the 2nd dual-fec's slave would be attached to the 1st
dual-fec's mii_bus.  Don't know a nice solution though.  Probably you
either need a slave pointer in platform_data or have to treat a dual-fec
as only a single device.

>  - Use cpu_to_be32 over __swab32 in function swap_buffer
> 
> Changes for v3:
>  - Move v2 changes into patch #3
>  - Use device name to check if it's running on ENET-MAC
> 
>  drivers/net/Kconfig |    7 ++-
>  drivers/net/fec.c   |  148 +++++++++++++++++++++++++++++++++++++++++++++------
>  drivers/net/fec.h   |    5 +-
>  3 files changed, 139 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4f1755b..f34629b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1944,18 +1944,19 @@ config 68360_ENET
>  config FEC
>  	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
>  	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> -		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> +		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC ?  Again this calls for a
more global approach for these registration facilities.

>  	select PHYLIB
>  	help
>  	  Say Y here if you want to use the built-in 10/100 Fast ethernet
>  	  controller on some Motorola ColdFire and Freescale i.MX processors.
>  
>  config FEC2
> -	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> +	bool "Second FEC ethernet controller"
>  	depends on FEC
>  	help
>  	  Say Y here if you want to use the second built-in 10/100 Fast
> -	  ethernet controller on some Motorola ColdFire processors.
> +	  ethernet controller on some Motorola ColdFire and Freescale
> +	  i.MX processors.
>  
>  config FEC_MPC52xx
>  	tristate "MPC52xx FEC driver"
> diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> index 8a1c51f..2a71373 100644
> --- a/drivers/net/fec.c
> +++ b/drivers/net/fec.c
> @@ -17,6 +17,8 @@
>   *
>   * Bug fixes and cleanup by Philippe De Muyter (phdm at macqel.be)
>   * Copyright (c) 2004-2006 Macq Electronique SA.
> + *
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
>   */
>  
>  #include <linux/module.h>
> @@ -45,20 +47,36 @@
>  
>  #include <asm/cacheflush.h>
>  
> -#ifndef CONFIG_ARCH_MXC
> +#ifndef CONFIG_ARM
>  #include <asm/coldfire.h>
>  #include <asm/mcfsim.h>
>  #endif
>  
>  #include "fec.h"
>  
> -#ifdef CONFIG_ARCH_MXC
> -#include <mach/hardware.h>
> +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
>  #define FEC_ALIGNMENT	0xf
>  #else
>  #define FEC_ALIGNMENT	0x3
>  #endif
>  
> +#define DRIVER_NAME	"fec"
> +
> +/* Controller is ENET-MAC */
> +#define FEC_QUIRK_ENET_MAC		(1 << 0)
does this really qualify to be a quirk?

> +/* Controller needs driver to swap frame */
> +#define FEC_QUIRK_SWAP_FRAME		(1 << 1)
IMHO this is a bit misnamed.  FEC_QUIRK_NEEDS_BE_DATA or similar would
be more accurate.

> +static struct platform_device_id fec_devtype[] = {
> +	{
> +		.name = DRIVER_NAME,
> +		.driver_data = 0,
> +	}, {
> +		.name = "imx28-fec",
> +		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
> +	}
> +};
> +
>  static unsigned char macaddr[ETH_ALEN];
>  module_param_array(macaddr, byte, NULL, 0);
>  MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
> @@ -129,7 +147,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
>   * account when setting it.
>   */
>  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> +    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> +    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
I wonder what is excluded here.  FEC depends on

	M523x || M527x || M5272 || M528x || M520x || M532x || \
	MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28

so the only difference is that the latter lists M5272 which seems a bit
redundant in the presence of M527x.

>  #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
>  #else
>  #define	OPT_FRAME_SIZE	0
> @@ -208,10 +227,23 @@ static void fec_stop(struct net_device *dev);
>  /* Transmitter timeout */
>  #define TX_TIMEOUT (2 * HZ)
>  
> +static void *swap_buffer(void *bufaddr, int len)
> +{
> +	int i;
> +	unsigned int *buf = bufaddr;
> +
> +	for (i = 0; i < (len + 3) / 4; i++, buf++)
> +		*buf = cpu_to_be32(*buf);
if len isn't a multiple of 4 this accesses bytes behind len.  Is this
generally OK here?  (E.g. because skbs always have a length that is a
multiple of 4?)
> +
> +	return bufaddr;
> +}
> +
>  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);
> +
>  	/* 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);
> +
>  		/* This does 16 byte alignment, exactly what we need.
>  		 * The packet length includes FCS, but we don't want to
>  		 * include that when passing upstream as it messes up
> @@ -689,6 +734,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  	char mdio_bus_id[MII_BUS_ID_SIZE];
>  	char phy_name[MII_BUS_ID_SIZE + 3];
>  	int phy_id;
> +	int dev_id = fep->pdev->id;
>  
>  	fep->phy_dev = NULL;
>  
> @@ -700,6 +746,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  			continue;
>  		if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
>  			continue;
> +		if (dev_id--)
> +			continue;
>  		strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
>  		break;
>  	}
> @@ -737,10 +785,35 @@ static int fec_enet_mii_probe(struct net_device *dev)
>  
>  static int fec_enet_mii_init(struct platform_device *pdev)
>  {
> +	static struct mii_bus *fec0_mii_bus;
>  	struct net_device *dev = platform_get_drvdata(pdev);
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	int err = -ENXIO, i;
>  
> +	/*
> +	 * The dual fec interfaces are not equivalent with enet-mac.
> +	 * Here are the differences:
> +	 *
> +	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII
> +	 *  - fec0 acts as the 1588 time master while fec1 is slave
> +	 *  - external phys can only be configured by fec0
> +	 *
> +	 * That is to say fec1 can not work independently. It only works
> +	 * when fec0 is working. The reason behind this design is that the
> +	 * second interface is added primarily for Switch mode.
> +	 *
> +	 * Because of the last point above, both phys are attached on fec0
> +	 * mdio interface in board design, and need to be configured by
> +	 * fec0 mii_bus.
> +	 */
> +	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
> +		/* fec1 uses fec0 mii_bus */
> +		fep->mii_bus = fec0_mii_bus;
> +		return 0;
What happens if imx28-fec.1 is probed before imx28-fec.0?
> +	}
> +
>  	fep->mii_timeout = 0;
>  
>  	/*
> @@ -777,6 +850,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
>  	if (mdiobus_register(fep->mii_bus))
>  		goto err_out_free_mdio_irq;
>  
> +	/* save fec0 mii_bus */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
> +		fec0_mii_bus = fep->mii_bus;
> +
>  	return 0;
>  
>  err_out_free_mdio_irq:
> @@ -1148,12 +1225,25 @@ static void
>  fec_restart(struct net_device *dev, int duplex)
>  {
>  	struct fec_enet_private *fep = netdev_priv(dev);
> +	const struct platform_device_id *id_entry =
> +				platform_get_device_id(fep->pdev);
>  	int i;
> +	u32 val, temp_mac[2];
>  
>  	/* Whack a reset.  We should wait for this. */
>  	writel(1, fep->hwp + FEC_ECNTRL);
>  	udelay(10);
>  
> +	/*
> +	 * enet-mac reset will reset mac address registers too,
> +	 * so need to reconfigure it.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> +		memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
> +		writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
> +		writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
> +	}
> +
>  	/* Clear any outstanding interrupt. */
>  	writel(0xffc00000, fep->hwp + FEC_IEVENT);
>  
> @@ -1200,20 +1290,45 @@ fec_restart(struct net_device *dev, int duplex)
>  	/* Set MII speed */
>  	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
>  
> -#ifdef FEC_MIIGSK_ENR
> -	if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
> -		/* disable the gasket and wait */
> -		writel(0, fep->hwp + FEC_MIIGSK_ENR);
> -		while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
> -			udelay(1);
> +	/*
> +	 * The phy interface and speed need to get configured
> +	 * differently on enet-mac.
> +	 */
> +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> +		val = readl(fep->hwp + FEC_R_CNTRL);
>  
> -		/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
> -		writel(1, fep->hwp + FEC_MIIGSK_CFGR);
> +		/* MII or RMII */
> +		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val |= (1 << 8);
Can we have a #define for 1 << 8 please?

> +		else
> +			val &= ~(1 << 8);

Best regards
Uwe

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

^ permalink raw reply

* ARM: relocation out of range (when loading a module)
From: Alexander Holler @ 2011-01-13 14:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113100407.GB24149@n2100.arm.linux.org.uk>

Am 13.01.2011 11:04, schrieb Russell King - ARM Linux:

>> At least I like that feature since it is available and won't miss it now. ;)
>
> The feature isn't available if it doesn't work.  It's not going to get
> fixed for 2.6.38 - it'll be 2.6.39 due to the timing and complexity of
> the problem.

I just wanted to express that I like that feature a lot and I didn't 
wanted to ask for a quick fix nor did I wanted to make pressure.

I've tried a the patch from Rabin Vincent (along with an alignment) and 
it works. It might not be the best solution and I certainly waste some 
memory (no free), but I don't care.

Regards,

Alexander

^ 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