[PATCH 07/14] ARM: LPC32XX: Misc support functions
Uwe Kleine-König
u.kleine-koenig at pengutronix.de
Fri Feb 12 15:06:09 EST 2010
Hi Kevin,
> +/*
> + * Detects and returns IRAM size for the device variation
> + */
> +#define LPC32XX_IRAM_BANK_SIZE (128 * SZ_1K)
SZ_128K ?
> +static u32 iram_size;
> +u32 lpc32xx_return_iram_size(void)
> +{
> + if (iram_size == 0) {
> + u32 savedval;
> + void __iomem *iramptr1, *iramptr2;
> +
> + iramptr1 = io_p2v(LPC32XX_IRAM_BASE);
> + iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE);
> + savedval = __raw_readl(iramptr2);
> +
> + __raw_writel(savedval + 1, iramptr2);
> +
> + /*
> + * If IRAM size is 128K, the value at iramptr2 will wrap back
> + * into iramptr1
> + */
> + if (__raw_readl(iramptr1) == __raw_readl(iramptr2))
> + iram_size = LPC32XX_IRAM_BANK_SIZE;
> + else
> + iram_size = LPC32XX_IRAM_BANK_SIZE * 2;
> +
> + __raw_writel(savedval, iramptr2);
> + }
> +
> + return iram_size;
> +}
I didn't understand this. The size of IRAM is either 128KiB or 256KiB,
right. And if it's 128KiB it's mirrored.
So if the content of a 256KiB IRAM happens to be
00000: 00000001 ....
...
20000: 00000000 ....
the above code does
savedval = 8
IRAM[20000] = 1
iram_size = LPC32XX_IRAM_BANK_SIZE;
IMHO you should do:
savedval1 = __raw_readl(iramptr1);
savedval2 = __raw_readl(iramptr2);
if (savedval1 == savedval2) {
__raw_writel(savedval2 + 1, iramptr2);
if (__raw_readl(iramptr1) == savedval2 + 1)
iram_size = LPC32XX_IRAM_BANK_SIZE;
else
iram_size = 2 * LPC32XX_IRAM_BANK_SIZE;
__raw_writel(savedval2, iramptr2);
} else
iram_size = 2 * LPC32XX_IRAM_BANK_SIZE;
> diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
> new file mode 100644
> index 0000000..8161efe
> --- /dev/null
> +++ b/arch/arm/mach-lpc32xx/common.h
> @@ -0,0 +1,75 @@
> +/*
> + * arch/arm/mach-lpc32xx/common.h
> + *
> + * Author: Kevin Wells <kevin.wells at nxp.com>
> + *
> + * Copyright (C) 2009-2010 NXP Semiconductors
> + *
> + * 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.
> + */
> +
> +#ifndef __LPC32XX_COMMON_H
> +#define __LPC32XX_COMMON_H
> +
> +#include <linux/platform_device.h>
> +
> +/*
> + * Arch specific platform device structures
> + */
> +extern struct platform_device watchdog_device;
lpc32xx_watchdoc_device?
> +extern struct platform_device i2c0_device;
> +extern struct platform_device i2c1_device;
> +extern struct platform_device i2c2_device;
I prefer using functions to add these devices because then it's easier
to add support for now SoCs that happen to have the watchdog at a
different address. Then you can just do:
static struct resource watchdog_resources[] __initdata = {
{
.flags = ...;
},
};
int __init lpc32xx_add_watchdog(void)
{
if (cpu_is_lpc3212()) {
watchdog_resources[0].start = LPC3212_WATCHDOG_BASE;
} else if (cpu_is_lpc3214()) {
watchdog_resources[0].start = LPC3214_WATCHDOG_BASE;
} else
return -ENODEV;
watchdog_resources[0].end = watchdog_resources[0].start + SZ_4K;
....
}
or something similar. Another variation is:
static struct resource watchdog_resources[] __initdata = {
...
}
int __init lpc32xx_add_watchdog(sometype baseaddr)
{
watchdog_resources[0].start = base;
...
}
and then in a header do:
#define lpc3212_add_watchdog() lpc32xx_add_watchdog(LPC3212_WATCHDOG_BASE)
#define lpc3214_add_watchdog() lpc32xx_add_watchdog(LPC3214_WATCHDOG_BASE)
or provide an inline function.
When providing platform_devices as in your patch you have to do:
extern struct platform_device lpc3212_watchdog_device;
extern struct platform_device lpc3214_watchdog_device;
and at least in a kernel that supports both SoCs one or the other only
sits in RAM doing nothing.
But YMMV.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
More information about the linux-arm-kernel
mailing list