* [PATCH 11/16] spi: pl022: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/spi/spi-pl022.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index f103e470..43abaf2 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2424,6 +2424,8 @@ static struct amba_id pl022_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, pl022_ids);
+
static struct amba_driver pl022_driver = {
.drv = {
.name = "ssp-pl022",
--
1.7.4.1
^ permalink raw reply related
* [PATCH 10/16] rtc: pl031: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/rtc/rtc-pl031.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index ff1b84bd..a952c8d 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -420,6 +420,8 @@ static struct amba_id pl031_ids[] = {
{0, 0},
};
+MODULE_DEVICE_TABLE(amba, pl031_ids);
+
static struct amba_driver pl031_driver = {
.drv = {
.name = "rtc-pl031",
--
1.7.4.1
^ permalink raw reply related
* [PATCH 09/16] rtc: pl030: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/rtc/rtc-pl030.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index 1d28d44..02111fe 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -174,6 +174,8 @@ static struct amba_id pl030_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, pl030_ids);
+
static struct amba_driver pl030_driver = {
.drv = {
.name = "rtc-pl030",
--
1.7.4.1
^ permalink raw reply related
* [PATCH 08/16] mmc: mmci: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/mmc/host/mmci.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index b16ea4a..a7d398c 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1496,6 +1496,8 @@ static struct amba_id mmci_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, mmci_ids);
+
static struct amba_driver mmci_driver = {
.drv = {
.name = DRIVER_NAME,
--
1.7.4.1
^ permalink raw reply related
* [PATCH 07/16] input: ambakmi: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/input/serio/ambakmi.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 12abc50..8407d5b 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -195,6 +195,8 @@ static struct amba_id amba_kmi_idtable[] = {
{ 0, 0 }
};
+MODULE_DEVICE_TABLE(amba, amba_kmi_idtable);
+
static struct amba_driver ambakmi_driver = {
.drv = {
.name = "kmi-pl050",
--
1.7.4.1
^ permalink raw reply related
* [PATCH 06/16] gpio: pl061: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/gpio/gpio-pl061.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 2c5a18f..503e9d5 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -339,6 +339,8 @@ static struct amba_id pl061_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, pl061_ids);
+
static struct amba_driver pl061_gpio_driver = {
.drv = {
.name = "pl061_gpio",
--
1.7.4.1
^ permalink raw reply related
* [PATCH 05/16] dmaengine: pl330: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/dma/pl330.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 57104147..2d8d1b0 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -990,6 +990,8 @@ static struct amba_id pl330_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, pl330_ids);
+
#ifdef CONFIG_PM_RUNTIME
static int pl330_runtime_suspend(struct device *dev)
{
--
1.7.4.1
^ permalink raw reply related
* [PATCH 04/16] dmaengine: pl08x: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/dma/amba-pl08x.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index b7cbd1a..0698695 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -2054,6 +2054,8 @@ static struct amba_id pl08x_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, pl08x_ids);
+
static struct amba_driver pl08x_amba_driver = {
.drv.name = DRIVER_NAME,
.id_table = pl08x_ids,
--
1.7.4.1
^ permalink raw reply related
* [PATCH 03/16] hwrng: nomadik: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/char/hw_random/nomadik-rng.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c
index 52e08ca..3d3c1e6 100644
--- a/drivers/char/hw_random/nomadik-rng.c
+++ b/drivers/char/hw_random/nomadik-rng.c
@@ -95,6 +95,8 @@ static struct amba_id nmk_rng_ids[] = {
{0, 0},
};
+MODULE_DEVICE_TABLE(amba, nmk_rng_ids);
+
static struct amba_driver nmk_rng_driver = {
.drv = {
.owner = THIS_MODULE,
--
1.7.4.1
^ permalink raw reply related
* [PATCH 02/16] ARM: amba: Auto-generate AMBA driver module aliases during modpost
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
This patch adds the necessary support in file2alias.c to define
suitable aliases based on the amba_id table in AMBA driver modules.
This should be sufficient to allow such modules to be auto-loaded
via udev. The AMBA bus driver's uevent hotplug code is also
modified to pass an approriate MODALIAS string in the event.
For simplicity, the AMBA ID is treated an an opaque 32-bit numeber.
Module alises use patterns as appropriate to describe the value-
mask pairs described in the driver's amba_id list.
The proposed alias format is (extended regex):
^amba:d(HEX){8}$
Where HEX is a single upper-case HEX digit or a pattern (? or []
expression) matching a single upper-case HEX digit, as expected by
udev.
"d" is short for "device", following existing alias naming
conventions for other device types. This adds some flexibility for
unambiguously extending the alias format in the future by adding
additional leading and trailing fields, if this turns out to be
necessary.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
drivers/amba/bus.c | 9 +++++-
scripts/mod/file2alias.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index bd230e8..a8c598c 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -52,7 +52,14 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
int retval = 0;
retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid);
- return retval;
+ if (retval)
+ return retval;
+
+ retval = add_uevent_var(env, "MODALIAS=amba:d%08X", pcdev->periphid);
+ if (retval)
+ return retval;
+
+ return 0;
}
#else
#define amba_uevent NULL
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index f936d1f..363ab46 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -880,6 +880,74 @@ static int do_isapnp_entry(const char *filename,
return 1;
}
+/*
+ * Append a match expression for a single masked hex digit.
+ * outp points to a pointer to the character at which to append.
+ * *outp is updated on return to point just after the appended text,
+ * to facilitate further appending.
+ */
+static void append_nibble_mask(char **outp,
+ unsigned int nibble, unsigned int mask)
+{
+ char *p = *outp;
+ unsigned int i;
+
+ switch (mask) {
+ case 0:
+ *p++ = '?';
+ break;
+
+ case 0xf:
+ p += sprintf(p, "%X", nibble);
+ break;
+
+ default:
+ /*
+ * Dumbly emit a match pattern for all possible matching
+ * digits. This could be improved in some cases using ranges,
+ * but it has the advantage of being trivially correct, and is
+ * often optimal.
+ */
+ *p++ = '[';
+ for (i = 0; i < 0x10; i++)
+ if ((i & mask) == nibble)
+ p += sprintf(p, "%X", i);
+ *p++ = ']';
+ }
+
+ /* Ensure that the string remains NUL-terminated: */
+ *p = '\0';
+
+ /* Advance the caller's end-of-string pointer: */
+ *outp = p;
+}
+
+/*
+ * looks like: "amba:dN"
+ *
+ * N is exactly 8 digits, where each is an upper-case hex digit, or
+ * a ? or [] pattern matching exactly one digit.
+ */
+static int do_amba_entry(const char *filename,
+ struct amba_id *id, char *alias)
+{
+ unsigned int digit;
+ char *p = alias;
+
+ if ((id->id & id->mask) != id->id)
+ fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: "
+ "id=0x%08X, mask=0x%08X. Please fix this driver.\n",
+ filename, id->id, id->mask);
+
+ p += sprintf(alias, "amba:d");
+ for (digit = 0; digit < 8; digit++)
+ append_nibble_mask(&p,
+ (id->id >> (4 * (7 - digit))) & 0xf,
+ (id->mask >> (4 * (7 - digit))) & 0xf);
+
+ return 1;
+}
+
/* Ignore any prefix, eg. some architectures prepend _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -1047,6 +1115,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
do_table(symval, sym->st_size,
sizeof(struct isapnp_device_id), "isa",
do_isapnp_entry, mod);
+ else if (sym_is(symname, "__mod_amba_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct amba_id), "amba",
+ do_amba_entry, mod);
free(zeros);
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 01/16] ARM: amba: Move definition of struct amba_id to mod_devicetable.h
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317830707-17517-1-git-send-email-dave.martin@linaro.org>
The general kernel infrastructure for adding module alises during
module post processing expects the affected device type
identification structures in a common header
<linux/mod_devicetable.h>.
This patch simple moves struct amba_id to the common header, and
adds the appropriate include in <linux/amba/bus.h>.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
include/linux/amba/bus.h | 7 +------
include/linux/mod_devicetable.h | 18 ++++++++++++++++++
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index fcbbe71..724c69c 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/device.h>
+#include <linux/mod_devicetable.h>
#include <linux/err.h>
#include <linux/resource.h>
#include <linux/regulator/consumer.h>
@@ -35,12 +36,6 @@ struct amba_device {
unsigned int irq[AMBA_NR_IRQS];
};
-struct amba_id {
- unsigned int id;
- unsigned int mask;
- void *data;
-};
-
struct amba_driver {
struct device_driver drv;
int (*probe)(struct amba_device *, const struct amba_id *);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 468819c..83ac071 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -542,4 +542,22 @@ struct isapnp_device_id {
kernel_ulong_t driver_data; /* data private to the driver */
};
+/**
+ * struct amba_id - identifies a device on an AMBA bus
+ * @id: The significant bits if the hardware device ID
+ * @mask: Bitmask specifying which bits of the id field are significant when
+ * matching. A driver binds to a device when ((hardware device ID) & mask)
+ * == id.
+ * @data: Private data used by the driver.
+ */
+struct amba_id {
+ unsigned int id;
+ unsigned int mask;
+#ifndef __KERNEL__
+ kernel_ulong_t data;
+#else
+ void *data;
+#endif
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
--
1.7.4.1
^ permalink raw reply related
* [PATCH 00/16] ARM: amba: Enable module alias autogeneration for AMBA drivers
From: Dave Martin @ 2011-10-05 16:04 UTC (permalink / raw)
To: linux-arm-kernel
There's no special reason why AMBA device drivers should not be
auto-loadable via udev, but udev currently has no way to map AMBA
device IDs to drivers.
As part of the effort to help enable the building of multiple
ARM platforms into a single kernel image in the future, it's desirable
to be able to build any non-critical platform-specific drivers as
modules.
A straightforward solution is to use modaliases to allow udev to
identify the correct driver module to load.
This series enables the general infrastructure for modalias generation
to work for AMBA devices, and enables it in the affected drivers.
Briefly tested on Versatile Express, including aaci, mmci and amba-clcd
(which appears to have the most interesting modalias match pattern).
For me, the appropiate modules now get loaded at udev trigger time.
Any comments and feedback are welcome.
Dave Martin (16):
ARM: amba: Move definition of struct amba_id to mod_devicetable.h
ARM: amba: Auto-generate AMBA driver module aliases during modpost
hwrng: nomadik: Enable module alias autogeneration for AMBA drivers
dmaengine: pl08x: Enable module alias autogeneration for AMBA drivers
dmaengine: pl330: Enable module alias autogeneration for AMBA drivers
gpio: pl061: Enable module alias autogeneration for AMBA drivers
input: ambakmi: Enable module alias autogeneration for AMBA drivers
mmc: mmci: Enable module alias autogeneration for AMBA drivers
rtc: pl030: Enable module alias autogeneration for AMBA drivers
rtc: pl031: Enable module alias autogeneration for AMBA drivers
spi: pl022: Enable module alias autogeneration for AMBA drivers
serial: pl010: Enable module alias autogeneration for AMBA drivers
serial: pl011: Enable module alias autogeneration for AMBA drivers
fbdev: amba: Enable module alias autogeneration for AMBA drivers
watchdog: sp805: Enable module alias autogeneration for AMBA drivers
sound: aaci: Enable module alias autogeneration for AMBA drivers
drivers/amba/bus.c | 9 ++++-
drivers/char/hw_random/nomadik-rng.c | 2 +
drivers/dma/amba-pl08x.c | 2 +
drivers/dma/pl330.c | 2 +
drivers/gpio/gpio-pl061.c | 2 +
drivers/input/serio/ambakmi.c | 2 +
drivers/mmc/host/mmci.c | 2 +
drivers/rtc/rtc-pl030.c | 2 +
drivers/rtc/rtc-pl031.c | 2 +
drivers/spi/spi-pl022.c | 2 +
drivers/tty/serial/amba-pl010.c | 2 +
drivers/tty/serial/amba-pl011.c | 2 +
drivers/video/amba-clcd.c | 2 +
drivers/watchdog/sp805_wdt.c | 2 +
include/linux/amba/bus.h | 7 +---
include/linux/mod_devicetable.h | 18 ++++++++
scripts/mod/file2alias.c | 72 ++++++++++++++++++++++++++++++++++
sound/arm/aaci.c | 2 +
18 files changed, 127 insertions(+), 7 deletions(-)
--
1.7.4.1
^ permalink raw reply
* [PATCH v2 5/7] ARM: highbank: add SMP support
From: Rob Herring @ 2011-10-05 16:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110906010105.GA7623@S2100-06.ap.freescale.net>
Shawn,
On 09/05/2011 08:01 PM, Shawn Guo wrote:
> On Wed, Aug 31, 2011 at 08:44:04PM -0500, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> This enables SMP support on highbank processor.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> ---
>> Changes in v2:
>> - drop NULL check of scu_base
>> - use IPI #0 instead of #1 to boot secondary
>> - s/a9_base_addr/scu_base_addr/
>> - fix muliple mapping of twd registers
>>
>> arch/arm/Kconfig | 2 +-
>> arch/arm/mach-highbank/Makefile | 2 +
>> arch/arm/mach-highbank/localtimer.c | 38 +++++++++++++++++
>> arch/arm/mach-highbank/platsmp.c | 78 +++++++++++++++++++++++++++++++++++
>> 4 files changed, 119 insertions(+), 1 deletions(-)
>> create mode 100644 arch/arm/mach-highbank/localtimer.c
>> create mode 100644 arch/arm/mach-highbank/platsmp.c
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 9019a56..6d2add5 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1372,7 +1372,7 @@ config SMP
>> depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
>> MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
>> ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
>> - ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
>> + ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK
>> select USE_GENERIC_SMP_HELPERS
>> select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
>> help
>> diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
>> index 11d4010..311c0e8e 100644
>> --- a/arch/arm/mach-highbank/Makefile
>> +++ b/arch/arm/mach-highbank/Makefile
>> @@ -1,2 +1,4 @@
>> obj-y := clock.o highbank.o system.o
>> obj-$(CONFIG_DEBUG_LL) += lluart.o
>> +obj-$(CONFIG_SMP) += platsmp.o
>> +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
>> diff --git a/arch/arm/mach-highbank/localtimer.c b/arch/arm/mach-highbank/localtimer.c
>> new file mode 100644
>> index 0000000..344ea29
>> --- /dev/null
>> +++ b/arch/arm/mach-highbank/localtimer.c
>> @@ -0,0 +1,38 @@
>> +/*
>> + * Copyright 2010-2011 Calxeda, Inc.
>> + * Based on localtimer.c, Copyright (C) 2002 ARM Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
>> + */
>> +#include <linux/init.h>
>> +#include <linux/clockchips.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
>> +
>> +#include <asm/smp_twd.h>
>> +
>> +/*
>> + * Setup the local clock events for a CPU.
>> + */
>> +int __cpuinit local_timer_setup(struct clock_event_device *evt)
>> +{
>> + struct device_node *np;
>> +
>> + np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
>> + if (!twd_base)
>> + twd_base = of_iomap(np, 0);
>
> WARN_ON(!twd_base)?
>
Okay, will add it. Can I add your Reviewed-by for the series?
Rob
^ permalink raw reply
* [PATCH 2/3] mmc: Add OF bindings support for mmc host controller capabilities
From: Stephen Warren @ 2011-10-05 15:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJuYYwS_NeE6OG9X2p2rkjgo4OqO-ijeVwr1sLGkUuLJOxMw2g@mail.gmail.com>
Thomas Abraham wrote at Wednesday, October 05, 2011 8:28 AM:
> On 5 October 2011 18:59, Rob Herring <robherring2@gmail.com> wrote:
> > On 10/05/2011 05:13 AM, Thomas Abraham wrote:
> >> Device nodes representing sd/mmc controllers in a device tree would include
> >> mmc host controller capabilities. Add support for parsing of mmc host
> >> controller capabilities included in device nodes.
...
> >> +- linux,mmc_cap_4_bit_data - host can do 4 bit transfers
> >> +- linux,mmc_cap_mmc_highspeed - host can do MMC high-speed timing
> >> +- linux,mmc_cap_sd_highspeed - host can do SD high-speed timing
> >> +- linux,mmc_cap_needs_poll - host needs polling for card detection
> >> +- linux,mmc_cap_8_bit_data - host can do 8 bit transfer
> >
> > "sdhci,1-bit-only" already exists as a binding. Perhaps add
> > "sdhci,4-bit-only". No property then means can do 8-bit.
>
> Ok. But that would remain just as sdhci host controller capability and
> will not be applicable to other types of host controllers.
Just as an FYI, NVIDIA's SDHCI controller bindings use property
"support-8bit" to indicate 8-bit support. A similar property could be
used for 4-bit support too.
--
nvpublic
^ permalink raw reply
* [PATCH] ARM: hw_breakpoint: skip v7-specific reset on v6 cores
From: Will Deacon @ 2011-10-05 15:20 UTC (permalink / raw)
To: linux-arm-kernel
ARMv6 cores do not implement the DBGOSLAR register, so we don't need to
try and clear it on boot. Furthermore, the VCR is zeroed out of reset,
so we don't need to zero it explicitly when a CPU comes online.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
Taken against rmk/devel-stable.
arch/arm/kernel/hw_breakpoint.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 5a46225..814a52a9 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -892,6 +892,10 @@ static void reset_ctrl_regs(void *unused)
* later on.
*/
switch (debug_arch) {
+ case ARM_DEBUG_ARCH_V6:
+ case ARM_DEBUG_ARCH_V6_1:
+ /* ARMv6 cores just need to reset the registers. */
+ goto reset_regs;
case ARM_DEBUG_ARCH_V7_ECP14:
/*
* Ensure sticky power-down is clear (i.e. debug logic is
@@ -931,6 +935,7 @@ static void reset_ctrl_regs(void *unused)
asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
isb();
+reset_regs:
if (enable_monitor_mode())
return;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 2/3] mmc: Add OF bindings support for mmc host controller capabilities
From: Thomas Abraham @ 2011-10-05 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E8C5BD6.2070709@gmail.com>
Hi Rob,
On 5 October 2011 18:59, Rob Herring <robherring2@gmail.com> wrote:
> Thomas,
>
> On 10/05/2011 05:13 AM, Thomas Abraham wrote:
>> Device nodes representing sd/mmc controllers in a device tree would include
>> mmc host controller capabilities. Add support for parsing of mmc host
>> controller capabilities included in device nodes.
>>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> ---
>> ?.../devicetree/bindings/mmc/linux-mmc-host.txt ? ? | ? 11 +++++++
>> ?drivers/mmc/core/host.c ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 31 ++++++++++++++++++++
>> ?include/linux/mmc/host.h ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?3 ++
>> ?3 files changed, 45 insertions(+), 0 deletions(-)
>> ?create mode 100644 Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt b/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
>> new file mode 100644
>> index 0000000..cb43905
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
>> @@ -0,0 +1,11 @@
>> +* Linux mmc host capabilities
>> +
>> +MMC Host Controller capabilities used in linux:
>
> These aren't really linux properties... Is the capabilities register
> really this broken that all these are needed? If so, perhaps just a
> straight caps register value to override with would be better.
I was trying to provide bindings for the MMC_CAP_XXX defined in
include/linux/mmc/host.h file. I am no expert in mmc subsystem but I
believe that these capabilities are not directly mapped to any
capabilities register in the host controller hardware. All of the
MMC_CAP_XXX defines are flags used by the mmc core to make runtime
decisions. The host controller driver would read its capability
register and report its capabilities to the mmc core layer using these
MMC_CAP_XXX defines.
But not all of the MMC_CAP_XXX defines can be derived from a
capabilities register of a host controller. Some of the MMC_CAP_XXX
capabilities are used as defaults by the host controller driver while
some others which are board dependent are feed to the host controller
driver using the platform data.
While migrating a host controller driver to device tree, and not
relying on the aux data for platform data, there has to be mechanism
to specify the mmc core subsystem capabilities which are board
specific and I though bindings for MMC_CAP_XXX could be an option.
>
>> +- linux,mmc_cap_4_bit_data - host can do 4 bit transfers
>> +- linux,mmc_cap_mmc_highspeed - host can do MMC high-speed timing
>> +- linux,mmc_cap_sd_highspeed - host can do SD high-speed timing
>> +- linux,mmc_cap_needs_poll - host needs polling for card detection
>> +- linux,mmc_cap_8_bit_data - host can do 8 bit transfer
>
> "sdhci,1-bit-only" already exists as a binding. Perhaps add
> "sdhci,4-bit-only". No property then means can do 8-bit.
Ok. But that would remain just as sdhci host controller capability and
will not be applicable to other types of host controllers.
>
>> +- linux,mmc_cap_disable - host can be disabled
>
> What?
Apologies. I will be more verbose next time.
>
>> +- linux,mmc_cap_nonremovable - host is connected to nonremovable media
>> +- linux,mmc_cap_erase - host allows erase/trim commands
>
> Isn't TRIM a card property and transparent to the host controller?
I am not sure on this. Maybe it might have some dependency on the host
controller as well.
>
>> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
>> index 793d0a0..4ee2e43 100644
>> --- a/drivers/mmc/core/host.c
>> +++ b/drivers/mmc/core/host.c
>> @@ -19,6 +19,7 @@
>> ?#include <linux/leds.h>
>> ?#include <linux/slab.h>
>> ?#include <linux/suspend.h>
>> +#include <linux/of.h>
>>
>> ?#include <linux/mmc/host.h>
>> ?#include <linux/mmc/card.h>
>> @@ -385,3 +386,33 @@ void mmc_free_host(struct mmc_host *host)
>> ?}
>>
>> ?EXPORT_SYMBOL(mmc_free_host);
>> +
>> +#ifdef CONFIG_OF
>> +/**
>> + * ? mmc_of_parse_host_caps - parse mmc host capabilities from device node
>> + * ? @np: pointer to device node in device tree
>> + * ? @caps: pointer to host caps value to be returned
>> + *
>> + * ? Search the device node in device tree for mmc host capabilities.
>> + */
>> +void mmc_of_parse_host_caps(struct device_node *np, unsigned long *caps)
>> +{
>> + ? ? if (of_find_property(np, "linux,mmc_cap_4_bit_data", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_4_BIT_DATA;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_mmc_highspeed", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_MMC_HIGHSPEED;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_sd_highspeed", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_SD_HIGHSPEED;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_needs_poll", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_NEEDS_POLL;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_8_bit_data", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_8_BIT_DATA;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_disable", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_DISABLE;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_nonremovable", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_NONREMOVABLE;
>> + ? ? if (of_find_property(np, "linux,mmc_cap_erase", NULL))
>> + ? ? ? ? ? ? *caps |= MMC_CAP_ERASE;
>> +}
>> +EXPORT_SYMBOL(mmc_of_parse_host_caps);
>> +#endif /* CONFIG_OF */
>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>> index 1d09562..72b5df2 100644
>> --- a/include/linux/mmc/host.h
>> +++ b/include/linux/mmc/host.h
>> @@ -309,6 +309,9 @@ extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
>> ?extern int mmc_add_host(struct mmc_host *);
>> ?extern void mmc_remove_host(struct mmc_host *);
>> ?extern void mmc_free_host(struct mmc_host *);
>> +#ifdef CONFIG_OF
>> +extern void mmc_of_parse_host_caps(struct device_node *np, unsigned long *caps);
>> +#endif
>
> You don't need a ifdef around this.
Ok.
>
> Rob
>
Thanks for your review.
Regards,
Thomas.
^ permalink raw reply
* [PATCH 5/7] ARM: EXYNOS4: Add support external GIC
From: Marc Zyngier @ 2011-10-05 13:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1308555258-4322-6-git-send-email-chaos.youn@samsung.com>
Hi Changhwan,
On 20/06/11 08:34, Changhwan Youn wrote:
> For full support of power modes, this patch adds implementation
> external GIC on EXYNOS4.
>
> External GIC of Exynos4 cannot support register banking so
> several interrupt related code for CPU1 should be different
> from that of CPU0.
I just realized that patch has made it to mainline... Unfortunately, it
seems quite broken to me:
> Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
> ---
> arch/arm/mach-exynos4/cpu.c | 10 ++++++++
> arch/arm/mach-exynos4/include/mach/entry-macro.S | 5 ++++
> arch/arm/mach-exynos4/include/mach/map.h | 1 +
> arch/arm/mach-exynos4/platsmp.c | 27 +++++++++++++++++++++-
> 4 files changed, 42 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
> index fa33294..40a866c 100644
> --- a/arch/arm/mach-exynos4/cpu.c
> +++ b/arch/arm/mach-exynos4/cpu.c
> @@ -16,6 +16,7 @@
>
> #include <asm/proc-fns.h>
> #include <asm/hardware/cache-l2x0.h>
> +#include <asm/hardware/gic.h>
>
> #include <plat/cpu.h>
> #include <plat/clock.h>
> @@ -159,11 +160,20 @@ void __init exynos4_init_clocks(int xtal)
> exynos4_setup_clocks();
> }
>
> +static void exynos4_gic_irq_eoi(struct irq_data *d)
> +{
> + struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
> +
> + gic_data->cpu_base = S5P_VA_GIC_CPU +
> + (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id());
Here, you're overwriting a field that is shared among *all* the
interrupts in the system. What if an interrupt comes up on another CPU?
If you look at the implementation of gic_eoi_irq(), you'll definitely
see the race.
> +}
> +
> void __init exynos4_init_irq(void)
> {
> int irq;
>
> gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
> + gic_arch_extn.irq_eoi = exynos4_gic_irq_eoi;
And here you're abusing the GIC extension feature.
I've also had a look at -next, and this has been extended further to
support 4412. The problem with that is without banking, you're painfully
working around the GIC driver. At that stage, I wonder if you wouldn't
be better off with a separate driver instead of abusing the existing one...
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH 2/3] mmc: Add OF bindings support for mmc host controller capabilities
From: Rob Herring @ 2011-10-05 13:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317809581-28783-3-git-send-email-thomas.abraham@linaro.org>
Thomas,
On 10/05/2011 05:13 AM, Thomas Abraham wrote:
> Device nodes representing sd/mmc controllers in a device tree would include
> mmc host controller capabilities. Add support for parsing of mmc host
> controller capabilities included in device nodes.
>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> .../devicetree/bindings/mmc/linux-mmc-host.txt | 11 +++++++
> drivers/mmc/core/host.c | 31 ++++++++++++++++++++
> include/linux/mmc/host.h | 3 ++
> 3 files changed, 45 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt b/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
> new file mode 100644
> index 0000000..cb43905
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
> @@ -0,0 +1,11 @@
> +* Linux mmc host capabilities
> +
> +MMC Host Controller capabilities used in linux:
These aren't really linux properties... Is the capabilities register
really this broken that all these are needed? If so, perhaps just a
straight caps register value to override with would be better.
> +- linux,mmc_cap_4_bit_data - host can do 4 bit transfers
> +- linux,mmc_cap_mmc_highspeed - host can do MMC high-speed timing
> +- linux,mmc_cap_sd_highspeed - host can do SD high-speed timing
> +- linux,mmc_cap_needs_poll - host needs polling for card detection
> +- linux,mmc_cap_8_bit_data - host can do 8 bit transfer
"sdhci,1-bit-only" already exists as a binding. Perhaps add
"sdhci,4-bit-only". No property then means can do 8-bit.
> +- linux,mmc_cap_disable - host can be disabled
What?
> +- linux,mmc_cap_nonremovable - host is connected to nonremovable media
> +- linux,mmc_cap_erase - host allows erase/trim commands
Isn't TRIM a card property and transparent to the host controller?
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 793d0a0..4ee2e43 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -19,6 +19,7 @@
> #include <linux/leds.h>
> #include <linux/slab.h>
> #include <linux/suspend.h>
> +#include <linux/of.h>
>
> #include <linux/mmc/host.h>
> #include <linux/mmc/card.h>
> @@ -385,3 +386,33 @@ void mmc_free_host(struct mmc_host *host)
> }
>
> EXPORT_SYMBOL(mmc_free_host);
> +
> +#ifdef CONFIG_OF
> +/**
> + * mmc_of_parse_host_caps - parse mmc host capabilities from device node
> + * @np: pointer to device node in device tree
> + * @caps: pointer to host caps value to be returned
> + *
> + * Search the device node in device tree for mmc host capabilities.
> + */
> +void mmc_of_parse_host_caps(struct device_node *np, unsigned long *caps)
> +{
> + if (of_find_property(np, "linux,mmc_cap_4_bit_data", NULL))
> + *caps |= MMC_CAP_4_BIT_DATA;
> + if (of_find_property(np, "linux,mmc_cap_mmc_highspeed", NULL))
> + *caps |= MMC_CAP_MMC_HIGHSPEED;
> + if (of_find_property(np, "linux,mmc_cap_sd_highspeed", NULL))
> + *caps |= MMC_CAP_SD_HIGHSPEED;
> + if (of_find_property(np, "linux,mmc_cap_needs_poll", NULL))
> + *caps |= MMC_CAP_NEEDS_POLL;
> + if (of_find_property(np, "linux,mmc_cap_8_bit_data", NULL))
> + *caps |= MMC_CAP_8_BIT_DATA;
> + if (of_find_property(np, "linux,mmc_cap_disable", NULL))
> + *caps |= MMC_CAP_DISABLE;
> + if (of_find_property(np, "linux,mmc_cap_nonremovable", NULL))
> + *caps |= MMC_CAP_NONREMOVABLE;
> + if (of_find_property(np, "linux,mmc_cap_erase", NULL))
> + *caps |= MMC_CAP_ERASE;
> +}
> +EXPORT_SYMBOL(mmc_of_parse_host_caps);
> +#endif /* CONFIG_OF */
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 1d09562..72b5df2 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -309,6 +309,9 @@ extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
> extern int mmc_add_host(struct mmc_host *);
> extern void mmc_remove_host(struct mmc_host *);
> extern void mmc_free_host(struct mmc_host *);
> +#ifdef CONFIG_OF
> +extern void mmc_of_parse_host_caps(struct device_node *np, unsigned long *caps);
> +#endif
You don't need a ifdef around this.
Rob
^ permalink raw reply
* [PATCH V2] AT91: dt: at91sam9g45 family and board device tree files
From: Rob Herring @ 2011-10-05 13:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317636056-9537-1-git-send-email-nicolas.ferre@atmel.com>
Nicolas,
On 10/03/2011 05:00 AM, Nicolas Ferre wrote:
> Create a new device tree source file for Atmel at91sam9g45 SoC family.
> The Evaluation Kit at91sam9m10g45ek includes it.
> This first basic support will be populated as drivers and boards will be
> converted to device tree.
> Contains serial, dma and interrupt controllers.
>
> The generic board file still takes advantage of platform data for early serial
> init. As we need a storage media and the NAND flash driver is not converted to
> DT yet, we keep old initialization for it.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
> V2: foundation for AT91SAM generic support
> - device tree focused board file
> - inclusion of USART DT support
> - early USART and NAND still using platform data
>
> arch/arm/boot/dts/at91sam9g45.dtsi | 103 +++++++++++++++++++++++++
> arch/arm/boot/dts/at91sam9m10g45ek.dts | 37 +++++++++
> arch/arm/mach-at91/Kconfig | 11 +++
> arch/arm/mach-at91/Makefile | 3 +
> arch/arm/mach-at91/Makefile.boot | 2 +
> arch/arm/mach-at91/at91sam9g45_devices.c | 24 +++++--
> arch/arm/mach-at91/board-dt.c | 122 ++++++++++++++++++++++++++++++
> 7 files changed, 296 insertions(+), 6 deletions(-)
> create mode 100644 arch/arm/boot/dts/at91sam9g45.dtsi
> create mode 100644 arch/arm/boot/dts/at91sam9m10g45ek.dts
> create mode 100644 arch/arm/mach-at91/board-dt.c
>
> diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
> new file mode 100644
> index 0000000..7d3341f
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91sam9g45.dtsi
> @@ -0,0 +1,103 @@
> +/*
> + * at91sam9g45.dtsi - Device Tree Include file for AT91SAM9G45 family SoC
> + * applies to AT91SAM9G45, AT91SAM9M10,
> + * AT91SAM9G46, AT91SAM9M11 SoC
> + *
> + * Copyright (C) 2011 Atmel,
> + * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
> + *
> + * Licensed under GPLv2 or later.
> + */
> +
> +/include/ "skeleton.dtsi"
> +
> +/ {
> + model = "Atmel AT91SAM9G45 family SoC";
> + compatible = "atmel,at91sam9g45";
> + interrupt-parent = <&aic>;
> +
> + aliases {
> + serial0 = &dbgu;
> + serial1 = &usart0;
> + serial2 = &usart1;
> + serial3 = &usart2;
> + serial4 = &usart3;
> + };
> + cpus {
> + cpu at 0 {
> + compatible = "arm,arm926ejs";
> + };
> + };
> +
> + memory {
Should be memory at 0x70000000
> + reg = <0x70000000 0x10000000>;
> + };
> +
> + ahb {
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + apb {
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + aic: interrupt-controller at fffff000 {
> + #interrupt-cells = <1>;
> + compatible = "atmel,at91rm9200-aic";
> + interrupt-controller;
Add "interrupt-parent;" so that the aic is not the parent of itself.
> + reg = <0xfffff000 0x200>;
> + };
> +
> + dma: dma-controller at ffffec00 {
> + compatible = "atmel,at91sam9g45-hdmac";
> + reg = <0xffffec00 0x200>;
> + interrupts = <21>;
> + atmel,hdmac-nr-channels = <8>;
> + atmel,hdmac-cap-memcpy;
> + atmel,hdmac-cap-slave;
> + };
> +
> + dbgu: serial at ffffee00 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xffffee00 0x200>;
> + interrupts = <1>;
> + };
> +
> + usart0: serial at fff8c000 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfff8c000 0x4000>;
Is 16K really used? I would set to 4K so your not wasting virtual space
(probably not an issue yet on Atmel parts).
> + interrupts = <7>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + };
> +
> + usart1: serial at fff90000 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfff90000 0x4000>;
> + interrupts = <8>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + };
> +
> + usart2: serial at fff94000 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfff94000 0x4000>;
> + interrupts = <9>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + };
> +
> + usart3: serial at fff98000 {
> + compatible = "atmel,at91sam9260-usart";
> + reg = <0xfff98000 0x4000>;
> + interrupts = <10>;
> + atmel,use-dma-rx;
> + atmel,use-dma-tx;
> + };
> + };
> + };
> +};
> diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
> new file mode 100644
> index 0000000..cf743de
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
> @@ -0,0 +1,37 @@
> +/*
> + * at91sam9m10g45ek.dts - Device Tree file for AT91SAM9M10G45-EK board
> + *
> + * Copyright (C) 2011 Atmel,
> + * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
> + *
> + * Licensed under GPLv2 or later.
> + */
> +/dts-v1/;
> +/include/ "at91sam9g45.dtsi"
> +
> +/ {
> + model = "Atmel AT91SAM9M10G45-EK";
> + compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9";
> +
> + chosen {
> + bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:4M(bootstrap/uboot/kernel)ro,60M(rootfs),-(data) root=/dev/mtdblock1 rw rootfstype=jffs2";
> + };
> +
> + memory {
> + reg = <0x70000000 0x4000000>;
> + };
> +
> + ahb {
> + apb {
> + usart0: serial at fff8c000 {
> + status = "disabled";
> + };
> + usart2: serial at fff94000 {
> + status = "disabled";
> + };
> + usart3: serial at fff98000 {
> + status = "disabled";
> + };
> + };
> + };
> +};
> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
> index 2248467..4b59d96 100644
> --- a/arch/arm/mach-at91/Kconfig
> +++ b/arch/arm/mach-at91/Kconfig
> @@ -442,6 +442,17 @@ endif
>
> # ----------------------------------------------------------
>
> +comment "Generic Board Type"
> +
> +config MACH_AT91SAM_DT
> + bool "Atmel AT91SAM Evaluation Kits with device-tree support"
> + select USE_OF
> + help
> + Select this if you want to experiment device-tree with
> + an Atmel Evaluation Kit.
> +
> +# ----------------------------------------------------------
> +
> comment "AT91 Board Options"
>
> config MTD_AT91_DATAFLASH_CARD
> diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
> index bf57e8b..3ff245e 100644
> --- a/arch/arm/mach-at91/Makefile
> +++ b/arch/arm/mach-at91/Makefile
> @@ -74,6 +74,9 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
> # AT91SAM9G45 board-specific support
> obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
>
> +# AT91SAM board with device-tree
> +obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
> +
> # AT91CAP9 board-specific support
> obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
>
> diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
> index 3462b81..d278863 100644
> --- a/arch/arm/mach-at91/Makefile.boot
> +++ b/arch/arm/mach-at91/Makefile.boot
> @@ -16,3 +16,5 @@ else
> params_phys-y := 0x20000100
> initrd_phys-y := 0x20410000
> endif
> +
> +dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb
> diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
> index bb84040..27276b8 100644
> --- a/arch/arm/mach-at91/at91sam9g45_devices.c
> +++ b/arch/arm/mach-at91/at91sam9g45_devices.c
> @@ -69,9 +69,16 @@ static struct platform_device at_hdmac_device = {
>
> void __init at91_add_device_hdmac(void)
> {
> - dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
> - dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
> - platform_device_register(&at_hdmac_device);
> + struct device_node *of_node =
> + of_find_node_by_name(NULL, "dma-controller");
You should really search by the compatible string.
> +
> + if (of_node) {
> + of_node_put(of_node);
> + } else {
> + dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
> + dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
This really should be in the driver.
> + platform_device_register(&at_hdmac_device);
> + }
> }
> #else
> void __init at91_add_device_hdmac(void) {}
> @@ -1556,10 +1563,15 @@ void __init at91_set_serial_console(unsigned portnr)
> void __init at91_add_device_serial(void)
> {
> int i;
> + struct device_node *of_node = of_find_node_by_name(NULL, "serial");
>
> - for (i = 0; i < ATMEL_MAX_UART; i++) {
> - if (at91_uarts[i])
> - platform_device_register(at91_uarts[i]);
> + if (of_node) {
> + of_node_put(of_node);
> + } else {
> + for (i = 0; i < ATMEL_MAX_UART; i++) {
> + if (at91_uarts[i])
> + platform_device_register(at91_uarts[i]);
> + }
Why can't you only call these init functions when booting non-DT?
> }
>
> if (!atmel_default_console_device)
> diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
> new file mode 100644
> index 0000000..7bcb9a9
> --- /dev/null
> +++ b/arch/arm/mach-at91/board-dt.c
> @@ -0,0 +1,122 @@
> +/*
> + * Setup code for AT91SAM Evaluation Kits with Device Tree support
> + *
> + * Covers: * AT91SAM9G45-EKES board
> + * * AT91SAM9M10-EKES board
> + * * AT91SAM9M10G45-EK board
> + *
> + * Copyright (C) 2011 Atmel,
> + * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
> + *
> + * Licensed under GPLv2 or later.
> + */
> +
> +#include <linux/types.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/board.h>
> +#include <mach/gpio.h>
> +#include <mach/system_rev.h>
> +#include <mach/at91sam9_smc.h>
> +
> +#include <asm/setup.h>
> +#include <asm/irq.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <asm/mach/irq.h>
> +
> +#include "sam9_smc.h"
> +#include "generic.h"
> +
> +
> +static void __init ek_init_early(void)
> +{
> + /* Initialize processor: 12.000 MHz crystal */
> + at91_initialize(12000000);
> +
> + /* DGBU on ttyS0. (Rx & Tx only) */
> + at91_register_uart(0, 0, 0);
> +
> + /* USART0 not connected on the -EK board */
> + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
> + at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
> +
> + /* set serial console to ttyS0 (ie, DBGU) */
> + at91_set_serial_console(0);
> +}
> +
> +/* det_pin is not connected */
> +static struct atmel_nand_data __initdata ek_nand_data = {
> + .ale = 21,
> + .cle = 22,
> + .rdy_pin = AT91_PIN_PC8,
> + .enable_pin = AT91_PIN_PC14,
> +};
> +
> +static struct sam9_smc_config __initdata ek_nand_smc_config = {
> + .ncs_read_setup = 0,
> + .nrd_setup = 2,
> + .ncs_write_setup = 0,
> + .nwe_setup = 2,
> +
> + .ncs_read_pulse = 4,
> + .nrd_pulse = 4,
> + .ncs_write_pulse = 4,
> + .nwe_pulse = 4,
> +
> + .read_cycle = 7,
> + .write_cycle = 7,
> +
> + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
> + .tdf_cycles = 3,
> +};
> +
> +static void __init ek_add_device_nand(void)
> +{
> + ek_nand_data.bus_width_16 = board_have_nand_16bit();
> + /* setup bus-width (8 or 16) */
> + if (ek_nand_data.bus_width_16)
> + ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
> + else
> + ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
> +
> + /* configure chip-select 3 (NAND) */
> + sam9_smc_configure(3, &ek_nand_smc_config);
> +
> + at91_add_device_nand(&ek_nand_data);
> +}
> +
> +static const struct of_device_id aic_of_match[] __initconst = {
> + { .compatible = "atmel,at91rm9200-aic", },
> + {},
> +};
> +
> +static void __init at91_dt_device_init(void)
> +{
> + irq_domain_generate_simple(aic_of_match, 0xfffff000, 0);
Why is this not in the .init_irq function? I'm surprised your timer
interrupt even works.
Rob
^ permalink raw reply
* [PATCH 0/1] A trio of IXP425 boards
From: Krzysztof Halasa @ 2011-10-05 13:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1317215339.git.richard.cochran@omicron.at>
Richard Cochran <richardcochran@gmail.com> writes:
> This patch adds support for three boards using the ixp425. Since they
> are are almost identical to each other, they can share one setup file.
>
> The three machine types are slated for removal due to the fact that
> the board support has not been merged. My polite request is to merge
> this patch and restore the machine types.
This is a good idea, IMHO.
Acked-by: Krzysztof Ha?asa <khc@pm.waw.pl>
Unfortunately ATM I don't have access to kernel.org and being a bit
busy with unrelated things, I'd rather avoid "processing" this patch
personally if possible. Can you send it upstream yourself, please?
Let me know of any problem.
--
Krzysztof Halasa
^ permalink raw reply
* [PATCH] ARM: pl330: Fix a race condition
From: Javi Merino @ 2011-10-05 12:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E7896D8.5090606@arm.com>
On 20/09/11 14:36, Javi Merino wrote:
> On 19/09/11 19:07, Jassi Brar wrote:
>> IIUIC your race scenario should be taken care of simply by doing...
>>
>> diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
>> index 97912fa..7129cfb 100644
>> --- a/arch/arm/common/pl330.c
>> +++ b/arch/arm/common/pl330.c
>> @@ -1546,7 +1546,7 @@ int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
>>
>> /* Start the next */
>> case PL330_OP_START:
>> - if (!_start(thrd))
>> + if (!_thrd_active(thrd) && !_start(thrd))
>> ret = -EIO;
>> break;
>>
>
> My first reaction was this was just moving the race condition, but
> thinking about it carefully, it looks like a better (simpler) solution.
>
>> Could you please test if it fixes the issue?
>
> Yes, I'll kick off runs later today and see how it goes. I don't have a
> way to reproduce the bug consistently, I just do lots of DMA
> transactions and eventually, I end up hitting it. I'll run it overnight
> and see if it fixes it or not.
I have run a lot of tests using your patch and I haven't been able to
reproduce the bug so your proposed solution is probably a better
(simpler) fix than mine.
Cheers,
Javi
^ permalink raw reply
* [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup.
From: Rajendra Nayak @ 2011-10-05 11:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8762k48o66.fsf@ti.com>
Hi Kevin,
On Wednesday 05 October 2011 02:33 AM, Kevin Hilman wrote:
> Hi Rajendra,
>
> Rajendra Nayak<rnayak@ti.com> writes:
>
>> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>> Add API to enable IO pad wakeup capability based on mux dynamic pad and
>>> wake_up enable flag available from hwmod_mux initialization.
>>>
>>> Use the wakeup_enable flag and enable wakeup capability
>>> for the given pads. Wakeup capability will be enabled/disabled
>>> during hwmod idle transition based on whether wakeup_flag is
>>> set or cleared.
>>>
>>> Call the omap_hwmod_set_ioring_wakeup from hwmod_wakeup_enable/disable.
>>>
>>> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
>>> ---
>>> arch/arm/mach-omap2/omap_hwmod.c | 59 ++++++++++++++++++++++++++++++++++++++
>>> 1 files changed, 59 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
>>> index 84cc0bd..e751dd9 100644
>>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>>> @@ -2062,6 +2062,34 @@ static int __init omap_hwmod_setup_all(void)
>>> core_initcall(omap_hwmod_setup_all);
>>>
>>> /**
>>> + * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
>>> + * @oh: struct omap_hwmod *
>>> + * @set: bool value indicating to set or clear wakeup status.
>>> + *
>>> + * Set or Clear wakeup flag for the io_pad.
>>> + */
>>> +static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
>>> +{
>>> + struct omap_device_pad *pad;
>>> + int ret = -EINVAL, j;
>>> +
>>> + if (oh->mux&& oh->mux->enabled) {
>>> + for (j = 0; j< oh->mux->nr_pads_dynamic; j++) {
>>> + pad = oh->mux->pads_dynamic[j];
>>> + if (pad->flags& OMAP_DEVICE_PAD_WAKEUP) {
>>> + if (set_wake)
>>> + pad->idle |= OMAP_WAKEUP_EN;
>>> + else
>>> + pad->idle&= ~OMAP_WAKEUP_EN;
>>
>> I think apart from enabling/disabling the IO wakeup's at the pad
>> level, there is also a need to trigger the IO daisy chain control
>> (Wu clock) by programming the PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
>> bit and waiting on the PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN) bit,
>> which is done by the omap3_enable/disable_io_chain function.
>> This is still done in the cpuidle path, but it makes sense to
>> move that over here, since it should be done every time a pad
>> level wakeup is enabled or disabled.
>
> So should it be done just here or also in the idle path? In general,
> I'm certainly for moving things out of the idle path into the places
> where they belong.
>
> However, I don't get from the TRM description below that it should be
> done every time a pad-level wake is enabled or disabled. Can you
> clarify what part of the TRM description you mean?
+ Nilesh from the PRCM design team, I and Vishwa had a short meeting
with Nilesh just to double confirm our understanding on how IO daisy
should be implemented.
I agree the OMAP3 TRM isn't very clear in mentioning this and overall
there is very limited documentation on this.
The OMAP4 TRM however is a little better and there isn't any difference
in the way IO Daisy is implemented in OMAP3 and OMAP4.
So, I'll try and explain what I meant based on whats in the OMAP4 TRM :)
I am referring to OMAP4430_ES2.x Public TRM vO.
refer to Figure 3-74. I/O Pads Daisy-Chain Configuration,
The WUEN signal to each pad (which can be used to enable IO-daisy
for the given pad) is a AND of a signal from PRCM and
one from SCM.
The signal from PRCM can be enabled by writing into
PRM_IO_PMCTRL[16] GLOBAL_WUEN bit (which in our case we keep
enabled always, done early at boot).
The signal from SCM can be enabled by writing to the individual
pad registers in SCM
CONTROL.CONTROL_PADCONF_<IOpad>[14] WAKEUPENABLE0
CONTROL.CONTROL_PADCONF_<IOpad>[30] WAKEUPENABLE1.
This is done by hwmod every time the module is enabled/idled.
This is what is mentioned in the TRM here
"The I/O pad wake-up scheme must be enabled (WUEN signal) globally by
setting the
PRM_IO_PMCTRL[16] GLOBAL_WUEN bit and by also setting I/O pad wake-up
enabled/disabled
individually (WUEN signal) by writing to the following bit fields in the
control module:
? CONTROL.CONTROL_PADCONF_<IOpad>[14] WAKEUPENABLE0
? CONTROL.CONTROL_PADCONF_<IOpad>[30] WAKEUPENABLE1"
And then the TRM mentions this about the need to trigger WUCLKIN
for every pad enable/disable.
This is needed to reset any spurious wakeups events.
"Once configured, the wake-up scheme within each I/O pad is enabled and
disabled by triggering a control
(WUCLKIN signal) of the I/O daisy chain. This is done thanks to a
dedicated PRCM module register bit
PRM_IO_PMCTRL[8] WUCLK_CTRL. The software must enable the I/O wakeup
prior entering a
low-power mode and disable it following a wake-up event.
Writing the PRM_IO_PMCTRL[8] WUCLK_CTRL bit to 1 asserts signal WUCLKIN
high to reset spurious
wake-up event and to latch the current pad input value. PRCM module
register PRM_IO_PMCTRL[9]
WUCLK_STATUS logs the signal WUCLKOUT of the last pad of the I/O ring.
Once this status is set to 1,
the software may clear the PRM_IO_PMCTRL[8] WUCLK_CTRL bit to
effectively enable or disable the
wake-up feature within each pad."
The controls are exactly the same in case of OMAP3.
There is a global control at PRCM level (PRCM.PM_WKEN_WKUP[8] EN_IO)
and at pad level in SCM.
To assert the WUCLKIN, there is PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
and to log the signal WUCLKOUT of the last pad there is
PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN.
Its just that the registers in OMAP3 are named weirdly, the digram isn't
any clear and the explanation in the TRM does not help much,
causing confusion.
> All I understand is that it has to be done before PER domain
> transisions.
This is mostly coming from pre 3430 es3 days when there was no
control for a WUCLKIN trigger in software. The hardware did this
based on per/core entering sleep states.
With 3430es3.1 and the subsequent 3630/4430/4460 silicons, the software
can decide when to enable/trigger iodaisy and it should ideally be done
before the powerdomain corresponding to the given module transitions to
RET or OFF. Until then the modules async wakeup is expected to generate
a wakeup.
> Also, if this were to happen, are there side-effects of having the IO
> daisy chain armed outside the idle path?
IO daisy is actually designed so that it can be armed outside of idle,
by providing software control to generate the WUCLKIN pulse.
So as long as a module is clocked, it can generate interrupts, once
its clocks are cut, it can generate an async wakeup, and once the
powerdomain belonging to the module transitions to RET or OFF, it should
be programmed to generate IO wakeup, independent of system idle state.
regards,
Rajendra
>
>
>
> Kevin
>
>> See section 3.5.7.2.2 I/O Wake-Up Mechanism of 36xx TRM revA.
>>
>> "The I/O wake-up scheme is enabled by triggering the I/O daisy chain
>> control (Wu clock) by
>> programming a dedicated register (PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN)
>> in the PRCM module.Software must wait for the I/O daisy chain to
>> complete before it transitions the PER domain to a
>> nonfunctional state. This is done by polling a dedicated status bit in
>> the PRCM module
>> (PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN). This status bit must be cleared
>> by software when the bit is
>> read to 1."
^ permalink raw reply
* [PATCH] virtio: Add platform bus driver for memory mapped virtio device
From: Michael S. Tsirkin @ 2011-10-05 10:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87aa9ggs4k.fsf@rustcorp.com.au>
On Wed, Oct 05, 2011 at 11:40:51AM +1030, Rusty Russell wrote:
> The absolute maximum is a ring of 32k elements, which is about 850k.
> That seems a little excessive, though.
Given that it must be physically contigious and each descriptor
is 64 byte in size + space for used and avail rings, yes it does :)
^ permalink raw reply
* [PATCH 3/3] mmc: sdhci-s3c: Add device tree support
From: Thomas Abraham @ 2011-10-05 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317809581-28783-1-git-send-email-thomas.abraham@linaro.org>
Add device tree based discovery support for Samsung's sdhci controller
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
.../devicetree/bindings/mmc/samsung-sdhci.txt | 75 ++++++++++
drivers/mmc/host/sdhci-s3c.c | 150 +++++++++++++++++++-
2 files changed, 219 insertions(+), 6 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
new file mode 100644
index 0000000..dc94d24
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
@@ -0,0 +1,75 @@
+* Samsung's SDHCI Controller device tree bindings
+
+Samsung's SDHCI controller is used as a connectivity interface with external
+MMC, SD and eMMC storage mediums.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+ - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
+ controller.
+ - "samsung,exynos4-sdhci": For controller compatible with Exynos4 sdhci
+ controller.
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+ depends on the interrupt controller.
+
+
+Required Board Specific Properties:
+- gpios: Should specify the gpios used for clock, command and data lines. The
+ gpio specifier format depends on the gpio controller. Note: There is no
+ particular order in which the gpio's have to be listed.
+
+
+Optional Board Specific Properties:
+- samsung,sdhci-bus-width: Number of data lines connected to the controller.
+ Note: This excludes the clock,command and card detect lines. If this property
+ is not specified, default value is 1.
+
+- samsung,cd-gpio-invert: If 'samsung,sdhci-cd-gpio' card detect method is
+ selected, this property can be optionally specified to invert the value of
+ external card detect gpio line.
+
+- One of the following properties for card detect type.
+ - samsung,sdhci-cd-internal: Card detect line from the card slot is
+ connected to the card detect pad of the sdhci controller. A gpio is
+ used for this connection (with possible pin function settings).
+ - samsung,sdhci-cd-gpio: A gpio line (with possible pin function settings)
+ is used a card detect line. This gpio line is not connected to card detect
+ pad of the sdhci controller.
+ - samsung,sdhci-cd-none: There is no card detect line. Polling is used to
+ detect the presence of the card. (DEFAULT, if no card detect property
+ is specified).
+ - samsung,sdhci-cd-permanent: There is no card detect line. The card is
+ permanently connected to the sdhci controller.
+
+- gpio-cd: The gpio to be used as card detect line for
+ 'samsung,sdhci-cd-internal' or 'samsung,sdhci-cd-gpio' card detection method.
+ The gpio specifier format depends on the gpio controller.
+
+- One or more of the linux specific mmc host bindings.
+ See Documentation/devicetree/bindings/mmc/linux-mmc-host.txt for all the
+ linux mmc host controller specific bindings.
+
+Example:
+ sdhci at 12530000 {
+ compatible = "samsung,exynos4-sdhci";
+ reg = <0x12530000 0x100>;
+ interrupts = <139>;
+ samsung,sdhci-bus-width = <4>;
+ linux,mmc_cap_4_bit_data;
+ samsung,sdhci-cd-internal;
+ gpio-cd = <&gpk2 2 2 3 3>;
+ gpios = <&gpk2 0 2 0 3>, /* clock line */
+ <&gpk2 1 2 0 3>, /* command line */
+ <&gpk2 3 2 3 3>, /* data line 0 */
+ <&gpk2 4 2 3 3>, /* data line 1 */
+ <&gpk2 5 2 3 3>, /* data line 2 */
+ <&gpk2 6 2 3 3>; /* data line 3 */
+ };
+
+ Note: This example shows both SoC specific and board specific properties
+ in a single device node. The properties can be actually be seperated
+ into SoC specific node and board specific node.
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 8280af0..047c404 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -20,6 +20,8 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/mmc/host.h>
@@ -29,6 +31,8 @@
#include "sdhci.h"
#define MAX_BUS_CLK (4)
+/* Number of gpio's used is max data bus width + command and clock lines */
+#define NUM_GPIOS(x) (x + 2)
/**
* struct sdhci_s3c - S3C SDHCI instance
@@ -48,6 +52,7 @@ struct sdhci_s3c {
unsigned int cur_clk;
int ext_cd_irq;
int ext_cd_gpio;
+ int *gpios;
struct clk *clk_io;
struct clk *clk_bus[MAX_BUS_CLK];
@@ -415,9 +420,110 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
}
}
+#ifdef CONFIG_OF
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+ struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+ struct device_node *node = dev->of_node;
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ u32 max_width;
+ int gpio, cnt, ret;
+
+ /* if the bus-width property is not specified, assume width as 1 */
+ if (of_property_read_u32(node, "samsung,sdhci-bus-width",
+ &max_width))
+ max_width = 1;
+ pdata->max_width = max_width;
+
+ ourhost->gpios = devm_kzalloc(dev, NUM_GPIOS(pdata->max_width) *
+ sizeof(int), GFP_KERNEL);
+ if (!ourhost->gpios)
+ return -ENOMEM;
+
+ mmc_of_parse_host_caps(node, (unsigned long *)&pdata->host_caps);
+
+ /* get the card detection method */
+ if (of_get_property(node, "samsung,sdhci-cd-internal", NULL))
+ pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
+ else if (of_get_property(node, "samsung,sdhci-cd-gpio", NULL))
+ pdata->cd_type = S3C_SDHCI_CD_GPIO;
+ else if (of_get_property(node, "samsung,sdhci-cd-none", NULL))
+ pdata->cd_type = S3C_SDHCI_CD_NONE;
+ else if (of_get_property(node, "samsung,sdhci-cd-permanent", NULL))
+ pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
+ else
+ pdata->cd_type = S3C_SDHCI_CD_NONE;
+
+ /* get the gpio used for card detection */
+ if (pdata->cd_type == S3C_SDHCI_CD_GPIO || S3C_SDHCI_CD_INTERNAL) {
+ gpio = of_get_named_gpio(node, "gpio-cd", 0);
+ if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "invalid card detect gpio specified\n");
+ return -EINVAL;
+ }
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_GPIO) {
+ pdata->ext_cd_gpio = gpio;
+ ourhost->ext_cd_gpio = -1; /* invalid gpio number */
+ if (of_get_property(node, "samsung,cd-gpio-invert", NULL))
+ pdata->ext_cd_gpio_invert = 1;
+ } else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ ret = gpio_request(gpio, "sdhci-cd");
+ if (ret) {
+ dev_err(dev, "card detect gpio request failed\n");
+ return -EINVAL;
+ }
+ ourhost->ext_cd_gpio = gpio;
+ }
+
+ /* get the gpios for command, clock and data lines */
+ for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+ gpio = of_get_gpio(node, cnt);
+ if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "invalid gpio[%d]\n", cnt);
+ goto err_free_dt_cd_gpio;
+ }
+ ourhost->gpios[cnt] = gpio;
+ }
+
+ for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+ ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio");
+ if (ret) {
+ dev_err(dev, "gpio[%d] request failed\n", cnt);
+ goto err_free_dt_gpios;
+ }
+ }
+
+ return 0;
+
+ err_free_dt_gpios:
+ while (--cnt >= 0)
+ gpio_free(ourhost->gpios[cnt]);
+ err_free_dt_cd_gpio:
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+ gpio_free(ourhost->ext_cd_gpio);
+ return -EINVAL;
+}
+#else
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+ struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+}
+#endif
+
+static const struct of_device_id sdhci_s3c_dt_match[];
+
static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
struct platform_device *pdev)
{
+#if CONFIG_OF
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(sdhci_s3c_dt_match, pdev->dev.of_node);
+ return (struct sdhci_s3c_drv_data *)match->data;
+ }
+#endif
return (struct sdhci_s3c_drv_data *)
platform_get_device_id(pdev)->driver_data;
}
@@ -432,7 +538,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
struct resource *res;
int ret, irq, ptr, clks;
- if (!pdev->dev.platform_data) {
+ if (!pdev->dev.platform_data && !pdev->dev.of_node) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
@@ -454,21 +560,28 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
dev_err(dev, "sdhci_alloc_host() failed\n");
return PTR_ERR(host);
}
+ sc = sdhci_priv(host);
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
ret = -ENOMEM;
- goto err_io_clk;
+ goto err_pdata;
+ }
+
+ if (pdev->dev.of_node) {
+ ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
+ if (ret)
+ goto err_pdata;
+ } else {
+ memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+ sc->ext_cd_gpio = -1; /* invalid gpio number */
}
- memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
drv_data = sdhci_s3c_get_driver_data(pdev);
- sc = sdhci_priv(host);
sc->host = host;
sc->pdev = pdev;
sc->pdata = pdata;
- sc->ext_cd_gpio = -1; /* invalid gpio number */
platform_set_drvdata(pdev, host);
@@ -625,6 +738,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
clk_put(sc->clk_io);
err_io_clk:
+ for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+ gpio_free(sc->gpios[ptr]);
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+ gpio_free(sc->ext_cd_gpio);
+
+ err_pdata:
sdhci_free_host(host);
return ret;
@@ -632,9 +751,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
{
- struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_s3c *sc = sdhci_priv(host);
+ struct s3c_sdhci_platdata *pdata = sc->pdata;
int ptr;
if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
@@ -661,6 +780,11 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
release_resource(sc->ioarea);
kfree(sc->ioarea);
+ if (pdev->dev.of_node) {
+ for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+ gpio_free(sc->gpios[ptr]);
+ }
+
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
@@ -706,9 +830,22 @@ static struct platform_device_id sdhci_s3c_driver_ids[] = {
.name = "exynos4-sdhci",
.driver_data = EXYNOS4_SDHCI_DRV_DATA,
},
+ {},
};
MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_s3c_dt_match[] = {
+ { .compatible = "samsung,s3c6410-sdhci", },
+ { .compatible = "samsung,exynos4-sdhci",
+ .data = &exynos4_sdhci_drv_data },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+#else
+#define sdhci_s3c_dt_match NULL
+#endif
+
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
.remove = __devexit_p(sdhci_s3c_remove),
@@ -718,6 +855,7 @@ static struct platform_driver sdhci_s3c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "s3c-sdhci",
+ .of_match_table = sdhci_s3c_dt_match,
},
};
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH 2/3] mmc: Add OF bindings support for mmc host controller capabilities
From: Thomas Abraham @ 2011-10-05 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317809581-28783-1-git-send-email-thomas.abraham@linaro.org>
Device nodes representing sd/mmc controllers in a device tree would include
mmc host controller capabilities. Add support for parsing of mmc host
controller capabilities included in device nodes.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
.../devicetree/bindings/mmc/linux-mmc-host.txt | 11 +++++++
drivers/mmc/core/host.c | 31 ++++++++++++++++++++
include/linux/mmc/host.h | 3 ++
3 files changed, 45 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
diff --git a/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt b/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
new file mode 100644
index 0000000..cb43905
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/linux-mmc-host.txt
@@ -0,0 +1,11 @@
+* Linux mmc host capabilities
+
+MMC Host Controller capabilities used in linux:
+- linux,mmc_cap_4_bit_data - host can do 4 bit transfers
+- linux,mmc_cap_mmc_highspeed - host can do MMC high-speed timing
+- linux,mmc_cap_sd_highspeed - host can do SD high-speed timing
+- linux,mmc_cap_needs_poll - host needs polling for card detection
+- linux,mmc_cap_8_bit_data - host can do 8 bit transfer
+- linux,mmc_cap_disable - host can be disabled
+- linux,mmc_cap_nonremovable - host is connected to nonremovable media
+- linux,mmc_cap_erase - host allows erase/trim commands
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 793d0a0..4ee2e43 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -19,6 +19,7 @@
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/suspend.h>
+#include <linux/of.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
@@ -385,3 +386,33 @@ void mmc_free_host(struct mmc_host *host)
}
EXPORT_SYMBOL(mmc_free_host);
+
+#ifdef CONFIG_OF
+/**
+ * mmc_of_parse_host_caps - parse mmc host capabilities from device node
+ * @np: pointer to device node in device tree
+ * @caps: pointer to host caps value to be returned
+ *
+ * Search the device node in device tree for mmc host capabilities.
+ */
+void mmc_of_parse_host_caps(struct device_node *np, unsigned long *caps)
+{
+ if (of_find_property(np, "linux,mmc_cap_4_bit_data", NULL))
+ *caps |= MMC_CAP_4_BIT_DATA;
+ if (of_find_property(np, "linux,mmc_cap_mmc_highspeed", NULL))
+ *caps |= MMC_CAP_MMC_HIGHSPEED;
+ if (of_find_property(np, "linux,mmc_cap_sd_highspeed", NULL))
+ *caps |= MMC_CAP_SD_HIGHSPEED;
+ if (of_find_property(np, "linux,mmc_cap_needs_poll", NULL))
+ *caps |= MMC_CAP_NEEDS_POLL;
+ if (of_find_property(np, "linux,mmc_cap_8_bit_data", NULL))
+ *caps |= MMC_CAP_8_BIT_DATA;
+ if (of_find_property(np, "linux,mmc_cap_disable", NULL))
+ *caps |= MMC_CAP_DISABLE;
+ if (of_find_property(np, "linux,mmc_cap_nonremovable", NULL))
+ *caps |= MMC_CAP_NONREMOVABLE;
+ if (of_find_property(np, "linux,mmc_cap_erase", NULL))
+ *caps |= MMC_CAP_ERASE;
+}
+EXPORT_SYMBOL(mmc_of_parse_host_caps);
+#endif /* CONFIG_OF */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 1d09562..72b5df2 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -309,6 +309,9 @@ extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
extern int mmc_add_host(struct mmc_host *);
extern void mmc_remove_host(struct mmc_host *);
extern void mmc_free_host(struct mmc_host *);
+#ifdef CONFIG_OF
+extern void mmc_of_parse_host_caps(struct device_node *np, unsigned long *caps);
+#endif
static inline void *mmc_priv(struct mmc_host *host)
{
--
1.6.6.rc2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox