* [PATCH v5 04/10] ARM: SoC: convert OMAP4 to SoC descriptor
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Convert OMAP4 to use the SoC descriptor to provide its SMP
and CPU hotplug operations.
Tested on both Panda and IGEPv2 (MULTI_OMAP kernel)
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-omap2/board-4430sdp.c | 1 +
arch/arm/mach-omap2/board-omap4panda.c | 1 +
arch/arm/mach-omap2/include/mach/omap4-common.h | 14 +++++++++++++
arch/arm/mach-omap2/omap-hotplug.c | 6 ++--
arch/arm/mach-omap2/omap-smp.c | 24 +++++++++++++++++++---
arch/arm/mach-omap2/omap4-common.c | 7 ++++++
6 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4d0c8b9..c404c5b 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -986,6 +986,7 @@ static void __init omap_4430sdp_map_io(void)
MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
.atag_offset = 0x100,
+ .soc = &omap4_soc_desc,
.reserve = omap_reserve,
.map_io = omap_4430sdp_map_io,
.init_early = omap4430_init_early,
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 201c0c2..42d6168 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -579,6 +579,7 @@ static void __init omap4_panda_map_io(void)
MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
/* Maintainer: David Anders - Texas Instruments Inc */
.atag_offset = 0x100,
+ .soc = &omap4_soc_desc,
.reserve = omap_reserve,
.map_io = omap4_panda_map_io,
.init_early = omap4430_init_early,
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index e4bd876..1db7941 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -39,5 +39,19 @@ extern void omap_secondary_startup(void);
extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
extern void omap_auxcoreboot_addr(u32 cpu_addr);
extern u32 omap_read_auxcoreboot0(void);
+
+extern int omap4_cpu_kill(unsigned int cpu);
+extern void omap4_cpu_die(unsigned int cpu);
+extern int omap4_cpu_disable(unsigned int cpu);
+
+struct arm_soc_smp_init_ops;
+struct arm_soc_smp_ops;
+
+extern struct arm_soc_smp_init_ops omap4_soc_smp_init_ops;
+extern struct arm_soc_smp_ops omap4_soc_smp_ops;
#endif
+
+struct arm_soc_desc;
+extern struct arm_soc_desc omap4_soc_desc;
+
#endif
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 4976b93..40982c6 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -21,7 +21,7 @@
#include <asm/cacheflush.h>
#include <mach/omap4-common.h>
-int platform_cpu_kill(unsigned int cpu)
+int omap4_cpu_kill(unsigned int cpu)
{
return 1;
}
@@ -30,7 +30,7 @@ int platform_cpu_kill(unsigned int cpu)
* platform-specific code to shutdown a CPU
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void omap4_cpu_die(unsigned int cpu)
{
flush_cache_all();
dsb();
@@ -57,7 +57,7 @@ void platform_cpu_die(unsigned int cpu)
}
}
-int platform_cpu_disable(unsigned int cpu)
+int omap4_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ce65e93..061ed7f 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -23,6 +23,7 @@
#include <asm/cacheflush.h>
#include <asm/hardware/gic.h>
#include <asm/smp_scu.h>
+#include <asm/soc.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
@@ -31,7 +32,7 @@ static void __iomem *scu_base;
static DEFINE_SPINLOCK(boot_lock);
-void __cpuinit platform_secondary_init(unsigned int cpu)
+static void __cpuinit omap4_secondary_init(unsigned int cpu)
{
/*
* If any interrupts are already enabled for the primary
@@ -47,7 +48,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
/*
* Set synchronisation state between this boot processor
@@ -98,7 +99,7 @@ static void __init wakeup_secondary(void)
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
-void __init smp_init_cpus(void)
+static void __init omap4_smp_init_cpus(void)
{
unsigned int i, ncores;
@@ -123,7 +124,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq);
}
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
{
/*
@@ -133,3 +134,18 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
scu_enable(scu_base);
wakeup_secondary();
}
+
+struct arm_soc_smp_init_ops omap4_soc_smp_init_ops __initdata = {
+ .smp_init_cpus = omap4_smp_init_cpus,
+ .smp_prepare_cpus = omap4_smp_prepare_cpus,
+};
+
+struct arm_soc_smp_ops omap4_soc_smp_ops __initdata = {
+ .smp_secondary_init = omap4_secondary_init,
+ .smp_boot_secondary = omap4_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = omap4_cpu_kill,
+ .cpu_die = omap4_cpu_die,
+ .cpu_disable = omap4_cpu_disable,
+#endif
+};
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 35ac3e5..de39fd4 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -16,6 +16,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <asm/soc.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
@@ -111,3 +112,9 @@ static int __init omap_l2_cache_init(void)
}
early_initcall(omap_l2_cache_init);
#endif
+
+struct arm_soc_desc omap4_soc_desc __initdata = {
+ .name = "TI OMAP4",
+ soc_smp_init_ops(omap4_soc_smp_init_ops)
+ soc_smp_ops(omap4_soc_smp_ops)
+};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 05/10] ARM: SoC: convert Tegra to SoC descriptor
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Convert Tegra to use the SoC descriptor to provide its SMP
and CPU hotplug operations.
Tested on Harmony.
Cc: Colin Cross <ccross@android.com>
Acked-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-tegra/board-dt.c | 2 ++
arch/arm/mach-tegra/board-harmony.c | 2 ++
arch/arm/mach-tegra/board-paz00.c | 2 ++
arch/arm/mach-tegra/board-seaboard.c | 4 ++++
arch/arm/mach-tegra/board-trimslice.c | 2 ++
arch/arm/mach-tegra/common.c | 8 ++++++++
arch/arm/mach-tegra/common.h | 11 +++++++++++
arch/arm/mach-tegra/hotplug.c | 6 +++---
arch/arm/mach-tegra/platsmp.c | 26 ++++++++++++++++++++++----
9 files changed, 56 insertions(+), 7 deletions(-)
create mode 100644 arch/arm/mach-tegra/common.h
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
index 9f47e04..0b3f937 100644
--- a/arch/arm/mach-tegra/board-dt.c
+++ b/arch/arm/mach-tegra/board-dt.c
@@ -44,6 +44,7 @@
#include "board-harmony.h"
#include "clock.h"
#include "devices.h"
+#include "common.h"
void harmony_pinmux_init(void);
void seaboard_pinmux_init(void);
@@ -111,6 +112,7 @@ static const char * tegra_dt_board_compat[] = {
DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)")
.map_io = tegra_map_common_io,
+ .soc = &tegra_soc_desc,
.init_early = tegra_init_early,
.init_irq = tegra_init_irq,
.timer = &tegra_timer,
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index f0bdc5e..f2ef94f 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -43,6 +43,7 @@
#include "clock.h"
#include "devices.h"
#include "gpio-names.h"
+#include "common.h"
static struct plat_serial8250_port debug_uart_platform_data[] = {
{
@@ -183,6 +184,7 @@ static void __init tegra_harmony_init(void)
MACHINE_START(HARMONY, "harmony")
.atag_offset = 0x100,
+ .soc = &tegra_soc_desc,
.fixup = tegra_harmony_fixup,
.map_io = tegra_map_common_io,
.init_early = tegra_init_early,
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index 602f8dd..63595f0 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -43,6 +43,7 @@
#include "clock.h"
#include "devices.h"
#include "gpio-names.h"
+#include "common.h"
static struct plat_serial8250_port debug_uart_platform_data[] = {
{
@@ -186,6 +187,7 @@ static void __init tegra_paz00_init(void)
MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ")
.atag_offset = 0x100,
+ .soc = &tegra_soc_desc,
.fixup = tegra_paz00_fixup,
.map_io = tegra_map_common_io,
.init_early = tegra_init_early,
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index bf13ea3..dfd9c95 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -40,6 +40,7 @@
#include "clock.h"
#include "devices.h"
#include "gpio-names.h"
+#include "common.h"
static struct plat_serial8250_port debug_uart_platform_data[] = {
{
@@ -281,6 +282,7 @@ static void __init tegra_wario_init(void)
MACHINE_START(SEABOARD, "seaboard")
.atag_offset = 0x100,
+ .soc = &tegra_soc_desc,
.map_io = tegra_map_common_io,
.init_early = tegra_init_early,
.init_irq = tegra_init_irq,
@@ -290,6 +292,7 @@ MACHINE_END
MACHINE_START(KAEN, "kaen")
.atag_offset = 0x100,
+ .soc = &tegra_soc_desc,
.map_io = tegra_map_common_io,
.init_early = tegra_init_early,
.init_irq = tegra_init_irq,
@@ -299,6 +302,7 @@ MACHINE_END
MACHINE_START(WARIO, "wario")
.atag_offset = 0x100,
+ .soc = &tegra_soc_desc,
.map_io = tegra_map_common_io,
.init_early = tegra_init_early,
.init_irq = tegra_init_irq,
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index e008c0e..16cfc39 100644
--- a/arch/arm/mach-tegra/board-trimslice.c
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -38,6 +38,7 @@
#include "clock.h"
#include "devices.h"
#include "gpio-names.h"
+#include "common.h"
#include "board-trimslice.h"
@@ -173,6 +174,7 @@ static void __init tegra_trimslice_init(void)
MACHINE_START(TRIMSLICE, "trimslice")
.atag_offset = 0x100,
+ .soc = &tegra_soc_desc,
.fixup = tegra_trimslice_fixup,
.map_io = tegra_map_common_io,
.init_early = tegra_init_early,
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index d5e3f89..9f796bf 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <asm/soc.h>
#include <asm/hardware/cache-l2x0.h>
#include <mach/iomap.h>
@@ -30,6 +31,7 @@
#include "board.h"
#include "clock.h"
#include "fuse.h"
+#include "common.h"
void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
@@ -81,3 +83,9 @@ void __init tegra_init_early(void)
tegra_clk_init_from_table(common_clk_init_table);
tegra_init_cache();
}
+
+struct arm_soc_desc tegra_soc_desc __initdata = {
+ .name = "NVIDIA Tegra",
+ soc_smp_init_ops(tegra_soc_smp_init_ops)
+ soc_smp_ops(tegra_soc_smp_ops)
+};
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
new file mode 100644
index 0000000..e4c214d
--- /dev/null
+++ b/arch/arm/mach-tegra/common.h
@@ -0,0 +1,11 @@
+struct arm_soc_desc;
+extern struct arm_soc_desc tegra_soc_desc;
+
+struct arm_soc_smp_init_ops;
+struct arm_soc_smp_ops;
+extern struct arm_soc_smp_init_ops tegra_soc_smp_init_ops;
+extern struct arm_soc_smp_ops tegra_soc_smp_ops;
+
+extern int tegra_cpu_kill(unsigned int cpu);
+extern void tegra_cpu_die(unsigned int cpu);
+extern int tegra_cpu_disable(unsigned int cpu);
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index f329404..7319f5f 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -86,7 +86,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
}
}
-int platform_cpu_kill(unsigned int cpu)
+int tegra_cpu_kill(unsigned int cpu)
{
return 1;
}
@@ -96,7 +96,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void tegra_cpu_die(unsigned int cpu)
{
int spurious = 0;
@@ -116,7 +116,7 @@ void platform_cpu_die(unsigned int cpu)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}
-int platform_cpu_disable(unsigned int cpu)
+int tegra_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 0886cbc..f18b07d 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -23,9 +23,12 @@
#include <asm/hardware/gic.h>
#include <asm/mach-types.h>
#include <asm/smp_scu.h>
+#include <asm/soc.h>
#include <mach/iomap.h>
+#include "common.h"
+
extern void tegra_secondary_startup(void);
static DEFINE_SPINLOCK(boot_lock);
@@ -38,7 +41,7 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
(IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
-void __cpuinit platform_secondary_init(unsigned int cpu)
+static void __cpuinit tegra_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
@@ -54,7 +57,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long old_boot_vector;
unsigned long boot_vector;
@@ -110,7 +113,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
-void __init smp_init_cpus(void)
+static void __init tegra_smp_init_cpus(void)
{
unsigned int i, ncores = scu_get_core_count(scu_base);
@@ -126,8 +129,23 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq);
}
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
{
scu_enable(scu_base);
}
+
+struct arm_soc_smp_init_ops tegra_soc_smp_init_ops __initdata = {
+ .smp_init_cpus = tegra_smp_init_cpus,
+ .smp_prepare_cpus = tegra_smp_prepare_cpus,
+};
+
+struct arm_soc_smp_ops tegra_soc_smp_ops __initdata = {
+ .smp_secondary_init = tegra_secondary_init,
+ .smp_boot_secondary = tegra_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = tegra_cpu_kill,
+ .cpu_die = tegra_cpu_die,
+ .cpu_disable = tegra_cpu_disable,
+#endif
+};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 06/10] ARM: SoC: convert Exynos4 to SoC descriptor
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Convert Exynos4 to use the SoC descriptor to provide its SMP
and CPU hotplug operations.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Tested-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-exynos4/core.h | 14 ++++++++++++++
arch/arm/mach-exynos4/cpu.c | 8 ++++++++
arch/arm/mach-exynos4/hotplug.c | 8 +++++---
arch/arm/mach-exynos4/mach-armlex4210.c | 3 +++
arch/arm/mach-exynos4/mach-nuri.c | 3 +++
arch/arm/mach-exynos4/mach-origen.c | 3 +++
arch/arm/mach-exynos4/mach-smdk4x12.c | 4 ++++
arch/arm/mach-exynos4/mach-smdkv310.c | 4 ++++
arch/arm/mach-exynos4/mach-universal_c210.c | 3 +++
arch/arm/mach-exynos4/platsmp.c | 25 +++++++++++++++++++++----
10 files changed, 68 insertions(+), 7 deletions(-)
create mode 100644 arch/arm/mach-exynos4/core.h
diff --git a/arch/arm/mach-exynos4/core.h b/arch/arm/mach-exynos4/core.h
new file mode 100644
index 0000000..e20c239
--- /dev/null
+++ b/arch/arm/mach-exynos4/core.h
@@ -0,0 +1,14 @@
+#ifndef __EXYNOS4_CORE_H
+#define __EXYNOS4_CORE_H
+
+#include <asm/soc.h>
+
+extern struct arm_soc_smp_init_ops exynos4_soc_smp_init_ops;
+extern struct arm_soc_smp_ops exynos4_soc_smp_ops;
+extern struct arm_soc_desc exynos4_soc_desc;
+
+extern int exynos4_cpu_kill(unsigned int cpu);
+extern void exynos4_cpu_die(unsigned int cpu);
+extern int exynos4_cpu_disable(unsigned int cpu);
+
+#endif /* __EXYNOS4_CORE_H */
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 5b1765b..6662a66 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -33,6 +33,8 @@
#include <mach/regs-irq.h>
#include <mach/regs-pmu.h>
+#include "core.h"
+
unsigned int gic_bank_offset __read_mostly;
extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
@@ -291,3 +293,9 @@ int __init exynos4_init(void)
return sysdev_register(&exynos4_sysdev);
}
+
+struct arm_soc_desc exynos4_soc_desc __initdata = {
+ .name = "Samsung EXYNOS4",
+ soc_smp_init_ops(exynos4_soc_smp_init_ops)
+ soc_smp_ops(exynos4_soc_smp_ops)
+};
diff --git a/arch/arm/mach-exynos4/hotplug.c b/arch/arm/mach-exynos4/hotplug.c
index da70e7e..15fe884 100644
--- a/arch/arm/mach-exynos4/hotplug.c
+++ b/arch/arm/mach-exynos4/hotplug.c
@@ -19,6 +19,8 @@
#include <mach/regs-pmu.h>
+#include "core.h"
+
extern volatile int pen_release;
static inline void cpu_enter_lowpower(void)
@@ -93,7 +95,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
}
}
-int platform_cpu_kill(unsigned int cpu)
+int exynos4_cpu_kill(unsigned int cpu)
{
return 1;
}
@@ -103,7 +105,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void exynos4_cpu_die(unsigned int cpu)
{
int spurious = 0;
@@ -123,7 +125,7 @@ void platform_cpu_die(unsigned int cpu)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}
-int platform_cpu_disable(unsigned int cpu)
+int exynos4_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos4/mach-armlex4210.c
index f0ca6c1..8c82c6b 100644
--- a/arch/arm/mach-exynos4/mach-armlex4210.c
+++ b/arch/arm/mach-exynos4/mach-armlex4210.c
@@ -28,6 +28,8 @@
#include <mach/map.h>
+#include "core.h"
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define ARMLEX4210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -208,6 +210,7 @@ static void __init armlex4210_machine_init(void)
MACHINE_START(ARMLEX4210, "ARMLEX4210")
/* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = armlex4210_map_io,
.init_machine = armlex4210_machine_init,
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
index 2204911..923edc2 100644
--- a/arch/arm/mach-exynos4/mach-nuri.c
+++ b/arch/arm/mach-exynos4/mach-nuri.c
@@ -48,6 +48,8 @@
#include <mach/map.h>
+#include "core.h"
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define NURI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -1187,6 +1189,7 @@ static void __init nuri_machine_init(void)
MACHINE_START(NURI, "NURI")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = nuri_map_io,
.init_machine = nuri_machine_init,
diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c
index 71db848..818258e 100644
--- a/arch/arm/mach-exynos4/mach-origen.c
+++ b/arch/arm/mach-exynos4/mach-origen.c
@@ -42,6 +42,8 @@
#include <mach/map.h>
+#include "core.h"
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define ORIGEN_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -672,6 +674,7 @@ static void __init origen_machine_init(void)
MACHINE_START(ORIGEN, "ORIGEN")
/* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = origen_map_io,
.init_machine = origen_machine_init,
diff --git a/arch/arm/mach-exynos4/mach-smdk4x12.c b/arch/arm/mach-exynos4/mach-smdk4x12.c
index fcf2e0e..052b2cb 100644
--- a/arch/arm/mach-exynos4/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos4/mach-smdk4x12.c
@@ -36,6 +36,8 @@
#include <mach/map.h>
+#include "core.h"
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDK4X12_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -285,6 +287,7 @@ static void __init smdk4x12_machine_init(void)
MACHINE_START(SMDK4212, "SMDK4212")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = smdk4x12_map_io,
.init_machine = smdk4x12_machine_init,
@@ -295,6 +298,7 @@ MACHINE_START(SMDK4412, "SMDK4412")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = smdk4x12_map_io,
.init_machine = smdk4x12_machine_init,
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index cec2afa..525b042 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -43,6 +43,8 @@
#include <mach/map.h>
+#include "core.h"
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -373,6 +375,7 @@ MACHINE_START(SMDKV310, "SMDKV310")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = smdkv310_map_io,
.init_machine = smdkv310_machine_init,
@@ -383,6 +386,7 @@ MACHINE_END
MACHINE_START(SMDKC210, "SMDKC210")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = smdkv310_map_io,
.init_machine = smdkv310_machine_init,
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c
index a023faa..0c94673 100644
--- a/arch/arm/mach-exynos4/mach-universal_c210.c
+++ b/arch/arm/mach-exynos4/mach-universal_c210.c
@@ -47,6 +47,8 @@
#include <media/s5p_fimc.h>
#include <media/m5mols.h>
+#include "core.h"
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -1061,6 +1063,7 @@ static void __init universal_machine_init(void)
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100,
+ .soc = &exynos4_soc_desc,
.init_irq = exynos4_init_irq,
.map_io = universal_map_io,
.init_machine = universal_machine_init,
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index e698604..56377d2 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -32,6 +32,8 @@
#include <plat/cpu.h>
+#include "core.h"
+
extern unsigned int gic_bank_offset;
extern void exynos4_secondary_startup(void);
@@ -90,7 +92,7 @@ static void __cpuinit exynos4_gic_secondary_init(void)
__raw_writel(1, cpu_base + GIC_CPU_CTRL);
}
-void __cpuinit platform_secondary_init(unsigned int cpu)
+static void __cpuinit exynos4_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
@@ -114,7 +116,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
set_cpu_online(cpu, true);
}
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit exynos4_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
@@ -189,7 +191,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* which may be present or become present in the system.
*/
-void __init smp_init_cpus(void)
+static void __init exynos4_smp_init_cpus(void)
{
void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores;
@@ -211,7 +213,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq);
}
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+static void __init exynos4_smp_prepare_cpus(unsigned int max_cpus)
{
scu_enable(scu_base_addr());
@@ -225,3 +227,18 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
__raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
CPU1_BOOT_REG);
}
+
+struct arm_soc_smp_init_ops exynos4_soc_smp_init_ops __initdata = {
+ .smp_init_cpus = exynos4_smp_init_cpus,
+ .smp_prepare_cpus = exynos4_smp_prepare_cpus,
+};
+
+struct arm_soc_smp_ops exynos4_soc_smp_ops __initdata = {
+ .smp_secondary_init = exynos4_secondary_init,
+ .smp_boot_secondary = exynos4_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = exynos4_cpu_kill,
+ .cpu_die = exynos4_cpu_die,
+ .cpu_disable = exynos4_cpu_disable,
+#endif
+};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 07/10] ARM: SoC: convert MSM SMP to SoC descriptor
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Convert MSM SMP platforms to use the SoC descriptor to provide
their SMP and CPU hotplug operations.
Cc: David Brown <davidb@codeaurora.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-msm/Makefile | 2 +-
arch/arm/mach-msm/board-msm8960.c | 3 +++
arch/arm/mach-msm/board-msm8x60.c | 7 +++++++
arch/arm/mach-msm/core.c | 17 +++++++++++++++++
arch/arm/mach-msm/core.h | 9 +++++++++
arch/arm/mach-msm/hotplug.c | 8 +++++---
arch/arm/mach-msm/platsmp.c | 24 ++++++++++++++++++++----
7 files changed, 62 insertions(+), 8 deletions(-)
create mode 100644 arch/arm/mach-msm/core.c
create mode 100644 arch/arm/mach-msm/core.h
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 4ad3969..cba9355 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,5 +1,5 @@
obj-y += io.o idle.o timer.o
-obj-y += clock.o
+obj-y += clock.o core.o
obj-$(CONFIG_DEBUG_FS) += clock-debug.o
obj-$(CONFIG_MSM_VIC) += irq-vic.o
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index b04468e..c811e29 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -30,6 +30,7 @@
#include <mach/board.h>
#include <mach/msm_iomap.h>
+#include "core.h"
#include "devices.h"
static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag,
@@ -94,6 +95,7 @@ static void __init msm8960_rumi3_init(void)
}
MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
+ .soc = &msm_soc_desc,
.fixup = msm8960_fixup,
.reserve = msm8960_reserve,
.map_io = msm8960_map_io,
@@ -103,6 +105,7 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
MACHINE_END
MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
+ .soc = &msm_soc_desc,
.fixup = msm8960_fixup,
.reserve = msm8960_reserve,
.map_io = msm8960_map_io,
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 4ad2afb..a4bd858 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -28,6 +28,8 @@
#include <mach/board.h>
#include <mach/msm_iomap.h>
+#include "core.h"
+
static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag,
char **cmdline, struct meminfo *mi)
{
@@ -115,6 +117,7 @@ static const char *msm8x60_fluid_match[] __initdata = {
#endif /* CONFIG_OF */
MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
+ .soc = &msm_soc_desc,
.fixup = msm8x60_fixup,
.reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
@@ -124,6 +127,7 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
MACHINE_END
MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
+ .soc = &msm_soc_desc,
.fixup = msm8x60_fixup,
.reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
@@ -133,6 +137,7 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
MACHINE_END
MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
+ .soc = &msm_soc_desc,
.fixup = msm8x60_fixup,
.reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
@@ -142,6 +147,7 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
MACHINE_END
MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
+ .soc = &msm_soc_desc,
.fixup = msm8x60_fixup,
.reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
@@ -153,6 +159,7 @@ MACHINE_END
#ifdef CONFIG_OF
/* TODO: General device tree support for all MSM. */
DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
+ .soc = &msm_soc_desc,
.fixup = msm8x60_fixup,
.reserve = msm8x60_reserve,
.map_io = msm8x60_map_io,
diff --git a/arch/arm/mach-msm/core.c b/arch/arm/mach-msm/core.c
new file mode 100644
index 0000000..390cde7
--- /dev/null
+++ b/arch/arm/mach-msm/core.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2011 ARM Ltd.
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include "core.h"
+
+struct arm_soc_desc msm_soc_desc __initdata = {
+ .name = "Qualcomm MSM",
+ soc_smp_init_ops(msm_soc_smp_init_ops)
+ soc_smp_ops(msm_soc_smp_ops)
+};
diff --git a/arch/arm/mach-msm/core.h b/arch/arm/mach-msm/core.h
new file mode 100644
index 0000000..e8394dd
--- /dev/null
+++ b/arch/arm/mach-msm/core.h
@@ -0,0 +1,9 @@
+#include <asm/soc.h>
+
+extern struct arm_soc_smp_init_ops msm_soc_smp_init_ops;
+extern struct arm_soc_smp_ops msm_soc_smp_ops;
+extern struct arm_soc_desc msm_soc_desc;
+
+extern int msm_cpu_kill(unsigned int cpu);
+extern void msm_cpu_die(unsigned int cpu);
+extern int msm_cpu_disable(unsigned int cpu);
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 41c252d..eef1b30 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -12,6 +12,8 @@
#include <asm/cacheflush.h>
+#include "core.h"
+
extern volatile int pen_release;
static inline void cpu_enter_lowpower(void)
@@ -56,7 +58,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
}
}
-int platform_cpu_kill(unsigned int cpu)
+int msm_cpu_kill(unsigned int cpu)
{
return 1;
}
@@ -66,7 +68,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void msm_cpu_die(unsigned int cpu)
{
/*
* we're ready for shutdown now, so do it
@@ -81,7 +83,7 @@ void platform_cpu_die(unsigned int cpu)
cpu_leave_lowpower();
}
-int platform_cpu_disable(unsigned int cpu)
+int msm_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index e3375ee..4902c16 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -24,6 +24,7 @@
#include <mach/msm_iomap.h>
#include "scm-boot.h"
+#include "core.h"
#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
#define SCSS_CPU1CORE_RESET 0xD80
@@ -47,7 +48,7 @@ static inline int get_core_count(void)
return ((read_cpuid_id() >> 4) & 3) + 1;
}
-void __cpuinit platform_secondary_init(unsigned int cpu)
+static void __cpuinit msm_secondary_init(unsigned int cpu)
{
/* Configure edge-triggered PPIs */
writel(GIC_PPI_EDGE_MASK, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
@@ -92,7 +93,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu)
"address\n");
}
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
static int cold_boot_done;
@@ -152,7 +153,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* does not support the ARM SCU, so just set the possible cpu mask to
* NR_CPUS.
*/
-void __init smp_init_cpus(void)
+static void __init msm_smp_init_cpus(void)
{
unsigned int i, ncores = get_core_count();
@@ -162,6 +163,21 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq);
}
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
{
}
+
+struct arm_soc_smp_init_ops msm_soc_smp_init_ops __initdata = {
+ .smp_init_cpus = msm_smp_init_cpus,
+ .smp_prepare_cpus = msm_smp_prepare_cpus,
+};
+
+struct arm_soc_smp_ops msm_soc_smp_ops __initdata = {
+ .smp_secondary_init = msm_secondary_init,
+ .smp_boot_secondary = msm_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = msm_cpu_kill,
+ .cpu_die = msm_cpu_die,
+ .cpu_disable = msm_cpu_disable,
+#endif
+};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 08/10] ARM: SoC: convert ux500 to SoC descriptor
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Convert ux500 platforms to use the SoC descriptor to provide
their SMP and CPU hotplug operations.
Cc: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-ux500/board-mop500.c | 3 +++
arch/arm/mach-ux500/board-u5500.c | 1 +
arch/arm/mach-ux500/hotplug.c | 8 +++++---
arch/arm/mach-ux500/include/mach/setup.h | 9 +++++++++
arch/arm/mach-ux500/platsmp.c | 23 +++++++++++++++++++----
5 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index bdd7b80..f0b1a00 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -691,6 +691,7 @@ static void __init hrefv60_init_machine(void)
MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
/* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
.atag_offset = 0x100,
+ .soc = &ux500_soc_desc,
.map_io = u8500_map_io,
.init_irq = ux500_init_irq,
/* we re-use nomadik timer here */
@@ -700,6 +701,7 @@ MACHINE_END
MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
.atag_offset = 0x100,
+ .soc = &ux500_soc_desc,
.map_io = u8500_map_io,
.init_irq = ux500_init_irq,
.timer = &ux500_timer,
@@ -708,6 +710,7 @@ MACHINE_END
MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
.atag_offset = 0x100,
+ .soc = &ux500_soc_desc,
.map_io = u8500_map_io,
.init_irq = ux500_init_irq,
/* we re-use nomadik timer here */
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
index 82025ba..aeb125a 100644
--- a/arch/arm/mach-ux500/board-u5500.c
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -146,6 +146,7 @@ static void __init u5500_init_machine(void)
MACHINE_START(U5500, "ST-Ericsson U5500 Platform")
.atag_offset = 0x100,
+ .soc = &ux500_soc_desc,
.map_io = u5500_map_io,
.init_irq = ux500_init_irq,
.timer = &ux500_timer,
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index 572015e..03424ab 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -14,6 +14,8 @@
#include <asm/cacheflush.h>
+#include <mach/setup.h>
+
extern volatile int pen_release;
static inline void platform_do_lowpower(unsigned int cpu)
@@ -33,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
}
}
-int platform_cpu_kill(unsigned int cpu)
+int ux500_cpu_kill(unsigned int cpu)
{
return 1;
}
@@ -43,13 +45,13 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void ux500_cpu_die(unsigned int cpu)
{
/* directly enter low power state, skipping secure registers */
platform_do_lowpower(cpu);
}
-int platform_cpu_disable(unsigned int cpu)
+int ux500_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index a7d363f..e764530 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -11,6 +11,7 @@
#ifndef __ASM_ARCH_SETUP_H
#define __ASM_ARCH_SETUP_H
+#include <asm/soc.h>
#include <asm/mach/time.h>
#include <linux/init.h>
@@ -50,4 +51,12 @@ extern struct sys_timer ux500_timer;
.type = MT_MEMORY, \
}
+extern struct arm_soc_smp_init_ops ux500_soc_smp_init_ops;
+extern struct arm_soc_smp_ops ux500_soc_smp_ops;
+extern struct arm_soc_desc ux500_soc_desc;
+
+extern int ux500_cpu_kill(unsigned int cpu);
+extern void ux500_cpu_die(unsigned int cpu);
+extern int ux500_cpu_disable(unsigned int cpu);
+
#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 27e5281..9e9254c 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -59,7 +59,7 @@ static void __iomem *scu_base_addr(void)
static DEFINE_SPINLOCK(boot_lock);
-void __cpuinit platform_secondary_init(unsigned int cpu)
+static void __cpuinit ux500_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
@@ -81,7 +81,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
@@ -148,7 +148,7 @@ static void __init wakeup_secondary(void)
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
-void __init smp_init_cpus(void)
+static void __init ux500_smp_init_cpus(void)
{
void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores;
@@ -170,9 +170,24 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq);
}
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
{
scu_enable(scu_base_addr());
wakeup_secondary();
}
+
+struct arm_soc_smp_init_ops ux500_soc_smp_init_ops __initdata = {
+ .smp_init_cpus = ux500_smp_init_cpus,
+ .smp_prepare_cpus = ux500_smp_prepare_cpus,
+};
+
+struct arm_soc_smp_ops ux500_soc_smp_ops __initdata = {
+ .smp_secondary_init = ux500_secondary_init,
+ .smp_boot_secondary = ux500_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = ux500_cpu_kill,
+ .cpu_die = ux500_cpu_die,
+ .cpu_disable = ux500_cpu_disable,
+#endif
+};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 09/10] ARM: SoC: convert shmobile sh73a0 to SoC descriptor
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Convert shmobile SMP platform to use the SoC descriptor to provide
its SMP and CPU hotplug operations.
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-shmobile/Makefile | 2 +-
arch/arm/mach-shmobile/board-ag5evm.c | 1 +
arch/arm/mach-shmobile/hotplug.c | 8 ++-
arch/arm/mach-shmobile/include/mach/common.h | 7 +--
arch/arm/mach-shmobile/include/mach/sh73a0.h | 6 ++
arch/arm/mach-shmobile/platsmp.c | 68 --------------------------
arch/arm/mach-shmobile/setup-sh73a0.c | 6 ++
arch/arm/mach-shmobile/smp-sh73a0.c | 35 ++++++++++++--
8 files changed, 53 insertions(+), 80 deletions(-)
delete mode 100644 arch/arm/mach-shmobile/platsmp.c
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 612b270..43754f3 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
# SMP objects
-smp-y := platsmp.o headsmp.o
+smp-y := headsmp.o
smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 475342b..448f51a 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -601,6 +601,7 @@ struct sys_timer ag5evm_timer = {
MACHINE_START(AG5EVM, "ag5evm")
.map_io = ag5evm_map_io,
+ .soc = &sh73a0_soc_desc,
.init_irq = ag5evm_init_irq,
.handle_irq = shmobile_handle_irq_gic,
.init_machine = ag5evm_init,
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
index 238a0d9..687c8c2 100644
--- a/arch/arm/mach-shmobile/hotplug.c
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -13,12 +13,14 @@
#include <linux/errno.h>
#include <linux/smp.h>
-int platform_cpu_kill(unsigned int cpu)
+#include <mach/common.h>
+
+int shmobile_cpu_kill(unsigned int cpu)
{
return 1;
}
-void platform_cpu_die(unsigned int cpu)
+void shmobile_cpu_die(unsigned int cpu)
{
while (1) {
/*
@@ -31,7 +33,7 @@ void platform_cpu_die(unsigned int cpu)
}
}
-int platform_cpu_disable(unsigned int cpu)
+int shmobile_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index c0cdbf9..2283521 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -48,9 +48,8 @@ extern void sh73a0_pinmux_init(void);
extern struct clk sh73a0_extal1_clk;
extern struct clk sh73a0_extal2_clk;
-extern unsigned int sh73a0_get_core_count(void);
-extern void sh73a0_secondary_init(unsigned int cpu);
-extern int sh73a0_boot_secondary(unsigned int cpu);
-extern void sh73a0_smp_prepare_cpus(void);
+extern int shmobile_cpu_kill(unsigned int cpu);
+extern void shmobile_cpu_die(unsigned int cpu);
+extern int shmobile_cpu_disable(unsigned int cpu);
#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index b385e97..d22a1a5 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -507,4 +507,10 @@ enum {
SHDMA_SLAVE_MMCIF_RX,
};
+#include <asm/soc.h>
+
+extern struct arm_soc_smp_init_ops sh73a0_soc_smp_init_ops;
+extern struct arm_soc_smp_ops sh73a0_soc_smp_ops;
+extern struct arm_soc_desc sh73a0_soc_desc;
+
#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
deleted file mode 100644
index 66f9806..0000000
--- a/arch/arm/mach-shmobile/platsmp.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SMP support for R-Mobile / SH-Mobile
- *
- * Copyright (C) 2010 Magnus Damm
- * Copyright (C) 2011 Paul Mundt
- *
- * Based on vexpress, Copyright (C) 2002 ARM Ltd, 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 version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-#include <asm/hardware/gic.h>
-#include <asm/localtimer.h>
-#include <asm/mach-types.h>
-#include <mach/common.h>
-
-static unsigned int __init shmobile_smp_get_core_count(void)
-{
- if (machine_is_ag5evm())
- return sh73a0_get_core_count();
-
- return 1;
-}
-
-static void __init shmobile_smp_prepare_cpus(void)
-{
- if (machine_is_ag5evm())
- sh73a0_smp_prepare_cpus();
-}
-
-void __cpuinit platform_secondary_init(unsigned int cpu)
-{
- trace_hardirqs_off();
-
- if (machine_is_ag5evm())
- sh73a0_secondary_init(cpu);
-}
-
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
- if (machine_is_ag5evm())
- return sh73a0_boot_secondary(cpu);
-
- return -ENOSYS;
-}
-
-void __init smp_init_cpus(void)
-{
- unsigned int ncores = shmobile_smp_get_core_count();
- unsigned int i;
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-
- set_smp_cross_call(gic_raise_softirq);
-}
-
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
-{
- shmobile_smp_prepare_cpus();
-}
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index e46821c..85ab3e1 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -672,3 +672,9 @@ void __init sh73a0_add_early_devices(void)
early_platform_add_devices(sh73a0_early_devices,
ARRAY_SIZE(sh73a0_early_devices));
}
+
+struct arm_soc_desc sh73a0_soc_desc __initdata = {
+ .name = "Renesas sh73a0",
+ soc_smp_init_ops(sh73a0_soc_smp_init_ops)
+ soc_smp_ops(sh73a0_soc_smp_ops)
+};
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index be1ade7..274b9c5 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <mach/common.h>
+#include <mach/sh73a0.h>
#include <asm/smp_scu.h>
#include <asm/smp_twd.h>
#include <asm/hardware/gic.h>
@@ -55,7 +56,7 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
__raw_writel(tmp, scu_base + 8);
}
-unsigned int __init sh73a0_get_core_count(void)
+static unsigned int __init sh73a0_get_core_count(void)
{
void __iomem *scu_base = scu_base_addr();
@@ -67,12 +68,12 @@ unsigned int __init sh73a0_get_core_count(void)
return scu_get_core_count(scu_base);
}
-void __cpuinit sh73a0_secondary_init(unsigned int cpu)
+static void __cpuinit sh73a0_secondary_init(unsigned int cpu)
{
gic_secondary_init(0);
}
-int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
+static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
cpu = cpu_logical_map(cpu);
@@ -87,7 +88,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
return 0;
}
-void __init sh73a0_smp_prepare_cpus(void)
+static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
{
int cpu = cpu_logical_map(0);
@@ -100,3 +101,29 @@ void __init sh73a0_smp_prepare_cpus(void)
/* enable cache coherency on CPU0 */
modify_scu_cpu_psr(0, 3 << (cpu * 8));
}
+
+static void __init sh73a0_smp_init_cpus(void)
+{
+ unsigned int ncores = sh73a0_get_core_count();
+ unsigned int i;
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+struct arm_soc_smp_init_ops sh73a0_soc_smp_init_ops __initdata = {
+ .smp_init_cpus = sh73a0_smp_init_cpus,
+ .smp_prepare_cpus = sh73a0_smp_prepare_cpus,
+};
+
+struct arm_soc_smp_ops sh73a0_soc_smp_ops __initdata = {
+ .smp_secondary_init = sh73a0_secondary_init,
+ .smp_boot_secondary = sh73a0_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = shmobile_cpu_kill,
+ .cpu_die = shmobile_cpu_die,
+ .cpu_disable = shmobile_cpu_disable,
+#endif
+};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 10/10] ARM: smp: Make SoC descriptor mandatory for SMP platforms
From: Marc Zyngier @ 2011-10-10 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318255342-17451-1-git-send-email-marc.zyngier@arm.com>
Now that all SMP platforms have been converted to the SOC descriptor
and its SMP operations, remove the "weak" attribute from the hooks
in smp.c, and make the functions static wherever possible.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/smp.h | 15 ---------------
arch/arm/kernel/smp.c | 18 +++++++++---------
2 files changed, 9 insertions(+), 24 deletions(-)
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 674ebcd..bf25484 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -56,16 +56,6 @@ extern int boot_secondary(unsigned int cpu, struct task_struct *);
asmlinkage void secondary_start_kernel(void);
/*
- * Perform platform specific initialisation of the specified CPU.
- */
-extern void platform_secondary_init(unsigned int cpu);
-
-/*
- * Initialize cpu_possible map, and enable coherency
- */
-extern void platform_smp_prepare_cpus(unsigned int);
-
-/*
* Logical CPU mapping.
*/
extern int __cpu_logical_map[NR_CPUS];
@@ -82,15 +72,10 @@ struct secondary_data {
extern struct secondary_data secondary_data;
extern int __cpu_disable(void);
-extern int platform_cpu_disable(unsigned int cpu);
extern void __cpu_die(unsigned int cpu);
extern void cpu_die(void);
-extern void platform_cpu_die(unsigned int cpu);
-extern int platform_cpu_kill(unsigned int cpu);
-extern void platform_cpu_enable(unsigned int cpu);
-
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index f7a9add..c256dd9 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -179,25 +179,25 @@ void __init soc_smp_ops_register(struct arm_soc_smp_init_ops *smp_init_ops,
}
}
-void __attribute__((weak)) __init smp_init_cpus(void)
+void __init smp_init_cpus(void)
{
if (soc_smp_init_ops && soc_smp_init_ops->smp_init_cpus)
soc_smp_init_ops->smp_init_cpus();
}
-void __attribute__((weak)) __init platform_smp_prepare_cpus(unsigned int max_cpus)
+static void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
if (soc_smp_ops && soc_smp_init_ops->smp_prepare_cpus)
soc_smp_init_ops->smp_prepare_cpus(max_cpus);
}
-void __attribute__((weak)) __cpuinit platform_secondary_init(unsigned int cpu)
+static void __cpuinit platform_secondary_init(unsigned int cpu)
{
if (soc_smp_ops && soc_smp_ops->smp_secondary_init)
soc_smp_ops->smp_secondary_init(cpu);
}
-int __attribute__((weak)) __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
if (soc_smp_ops && soc_smp_ops->smp_boot_secondary)
return soc_smp_ops->smp_boot_secondary(cpu, idle);
@@ -207,20 +207,20 @@ int __attribute__((weak)) __cpuinit boot_secondary(unsigned int cpu, struct task
#ifdef CONFIG_HOTPLUG_CPU
static void percpu_timer_stop(void);
-int __attribute__((weak)) __cpuinit platform_cpu_kill(unsigned int cpu)
+static int __cpuinit platform_cpu_kill(unsigned int cpu)
{
if (soc_smp_ops && soc_smp_ops->cpu_kill)
return soc_smp_ops->cpu_kill(cpu);
return 0;
}
-void __attribute__((weak)) __cpuinit platform_cpu_die(unsigned int cpu)
+static void __cpuinit platform_cpu_die(unsigned int cpu)
{
if (soc_smp_ops && soc_smp_ops->cpu_die)
soc_smp_ops->cpu_die(cpu);
}
-int __attribute__((weak)) __cpuinit platform_cpu_disable(unsigned int cpu)
+static int __cpuinit platform_cpu_disable(unsigned int cpu)
{
if (soc_smp_ops && soc_smp_ops->cpu_disable)
return soc_smp_ops->cpu_disable(cpu);
@@ -230,7 +230,7 @@ int __attribute__((weak)) __cpuinit platform_cpu_disable(unsigned int cpu)
/*
* __cpu_disable runs on the processor to be shutdown.
*/
-int __cpu_disable(void)
+int __cpuinit __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
struct task_struct *p;
@@ -279,7 +279,7 @@ static DECLARE_COMPLETION(cpu_died);
* called on the thread which is asking for a CPU to be shutdown -
* waits until shutdown has completed, or it is timed out.
*/
-void __cpu_die(unsigned int cpu)
+void __cpuinit __cpu_die(unsigned int cpu)
{
if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
pr_err("CPU%u: cpu didn't die\n", cpu);
--
1.7.0.4
^ permalink raw reply related
* [PATCH] arm: mx23: add machine_is_stmp_378x()
From: Wolfram Sang @ 2011-10-10 14:11 UTC (permalink / raw)
To: linux-arm-kernel
Adding this line was forgotten when converting mach-stmp378x to
mach-mxs.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/include/mach/mxs.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
index 35a89dd..1332f73 100644
--- a/arch/arm/mach-mxs/include/mach/mxs.h
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -30,6 +30,7 @@
*/
#define cpu_is_mx23() ( \
machine_is_mx23evk() || \
+ machine_is_stmp378x() || \
0)
#define cpu_is_mx28() ( \
machine_is_mx28evk() || \
--
1.7.6.3
^ permalink raw reply related
* [PATCH] fix ehci alignment error
From: Greg KH @ 2011-10-10 14:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010124154.464239811@gmail.com>
On Mon, Oct 10, 2011 at 02:38:27PM +0200, Harro Haan wrote:
> The Kirkwood gave an unaligned memory access error on
> line 742 of drivers/usb/host/echi-hcd.c:
> "ehci->last_periodic_enable = ktime_get_real();"
What is "The Kirkwood"? What size processor is this?
^ permalink raw reply
* [PATCH 1/1] ARM: Make debug UART optional for S3C devices
From: Thiago A. Corrêa @ 2011-10-10 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317601968-9194-1-git-send-email-thiago.correa@gmail.com>
Hi,
This was the first patch I have submited, would appreciate an Ack
or comments.
Kind Regards,
Thiago A. Correa
^ permalink raw reply
* [PATCH] fix ehci alignment error
From: Alan Stern @ 2011-10-10 15:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010124154.464239811@gmail.com>
On Mon, 10 Oct 2011, Harro Haan wrote:
> The Kirkwood gave an unaligned memory access error on
> line 742 of drivers/usb/host/echi-hcd.c:
> "ehci->last_periodic_enable = ktime_get_real();"
>
> Signed-off-by: Harro Haan <hrhaan@gmail.com>
> ---
> include/linux/usb/hcd.h | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
> index 0097136..c0ecc5a 100644
> --- a/include/linux/usb/hcd.h
> +++ b/include/linux/usb/hcd.h
> @@ -178,7 +178,7 @@ struct usb_hcd {
> * this structure.
> */
> unsigned long hcd_priv[0]
> - __attribute__ ((aligned(sizeof(unsigned long))));
> + __attribute__ ((aligned(sizeof(s64))));
> };
>
> /* 2.4 does this a bit differently ... */
Acked-by: Alan Stern <stern@rowland.harvard.edu>
^ permalink raw reply
* [PATCH v3 1/6] iommu/core: split mapping to page sizes as supported by the hardware
From: Roedel, Joerg @ 2011-10-10 15:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAK=WgbZ7Wyax1yfS1jSXw9OdwMtxxidwLO8PTsNUXX9CWzmVrw@mail.gmail.com>
Hi Ohad,
On Mon, Oct 10, 2011 at 09:59:22AM -0400, Ohad Ben-Cohen wrote:
> > Also, the bus_set_iommu interface is now in the -next branch. Would be
> > good if you rebase the patches to that interface.
>
> Sure. It's a little tricky though: which branch do I base this on ?
> Are you ok with me basing this on your 'next' branch ? My current
> stack depends at least on three branches of yours, so that would be
> helpful for me (and less merging conflicts for you I guess :).
The master branch is best to base your patches on for generic work. For
more specific things like omap-only changes you can use the topic
branches.
> > I think we need some care here and check pgsize for 0. A BUG_ON should
> > do.
>
> I can add it if you prefer, but I don't think it can really happen:
> basically, it means that we chose a too small and unsupported page
> bit, which can't happen as long as we check for IS_ALIGNED(iova |
> paddr | size, iommu_min_pagesz) in the beginning of iommu_map.
It can happen when there is a bug somewhere :) So a BUG_ON will yell
then and makes debugging easier. An alternative is to use a WARN_ON and
let the map-call fail in this case.
> Ok, let's discuss the semantics of ->unmap().
>
> There isn't a clear documentation of that API (we should probably add
> some kernel docs after we nail it down now), but judging from the
> existing users (mainly kvm) and drivers, it seems that iommu_map() and
> iommu_unmap() aren't symmetric: users rely on unmap() to return the
> actual size that was unmapped. IOMMU drivers, in turn, should check
> which page is mapped on 'iova', unmap it, and return its size.
Right, currently the map/unmap calls are not symetric. But I think they
should be to get a clean semantic. Without this requirement and multiple
page-sizes in use the iommu-code may has to unmap more address space then
requested. The user doesn't know what will be unmapped so it has to make
sure that no DMA is happening while unmap runs.
When we require the calls to be symetric we can give a guarantee that
only the requested region is unmapped and allow DMA to the untouched
part of the address-space while unmap() is running.
So when the call-places to not follow this restriction we should convert
them mid-term.
> This way iommu_unmap() becomes very simple: it just iterates through
> the region, relying on iommu_ops->unmap() to return the sizes that
> were actually unmapped (very similar to how amd's iommu_unmap_page
> works today). This also means that iommu_ops->unmap() doesn't really
> need a size/order argument and we can remove it (after all drivers
> fully migrate..).
Yes, somthing like that. Probably the iommu_ops->unmap function should
be turned into a unmap_page function call which only takes an iova and
no size parameter. The iommu-driver unmaps the page pointing to that
iova and returns the size of the page unmapped. This still allows the
simple implementation for the unmap-call.
This change is no requirement for this patch-set, but if we agree on it
this patch-set should keep that direction in mind.
> The other approach which you suggest means symmetric iommu_map() and
> iommu_unmap(). It means adding a 'paddr' parameter to iommu_unmap(),
> which is easy, but maybe more concerning is the limitation that it
> incurs: users will now have to call iommu_unmap() exactly as they
> called iommu_map() beforehand. Note sure how well this will fly with
> the existing users (kvm ?) and whether we really want to enforce this
> (it doesn't mean drivers need to deal with page-size complexity. they
> are required to unmap a single page at a time, and iommu_unmap() will
> do the work for them).
It will work with KVM, that is no problem. We don't need to really
enforce the calls to be symetric. But we can define that we only give
the guarantee about what will be unmapped when the calls are symetric.
For example:
iommu_map( 0, 0x100000);
iommu_unmap(0, 0x100000); /* Guarantee that it will only unmap
the range 0-0x100000 */
whereas:
iommu_map( 0, 0x100000);
iommu_unmap(0, 0x1000); /* Guarantees that 0-0x1000 is
unmapped, but other undefined parts
of the address space may be
unmapped too, up to the whole
address space */
The alternative is that we implement page-splitting in the iommu_unmap
function. But that introduces complexity I am not sure we really need.
KVM for example just unmaps the whole address-space on destruction. For
the generic dma_ops this is also not required because the dma_map*
functions already have the requirement to be symetric.
>
> Another discussion:
>
> I think we better change iommu_ops->map() to directly take a 'size'
> (in bytes) instead of an 'order' (of pages). Most (all?) drivers just
> immediately do 'size = 0x1000UL << gfp_order', so this whole size ->
> order -> size back and forth seems redundant.
Yes, this get_order thing should be changes to size long-term.
Regards,
Joerg
--
AMD Operating System Research Center
Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632
^ permalink raw reply
* [PATCH v2 0/5] Device tree support for regulators
From: Rajendra Nayak @ 2011-10-10 16:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi Mark, Grant,
I have reworked the regulator-dt-suppport series based
on your reviews and also split it so I remove any dependency
with the omap specific dt conversion for i2c/twl.
So this latest series is based on mainline 3.1-rc9.
I will post the twl-regulator driver adaptation to dt and
the omap-panda/omap-sdp board regulator data being
passed from dt as a seperate series.
changes in v2:
-1- removed the int to u32 convertions as -ve voltages do exist
-2- merged patches to support fixed voltage regulator dt adaptation
-3- added support for regulator_get() without a device associated (ex: cpufreq)
-4- used same binding for regulator<->consumer and regulator<->parent mapping
regards,
Rajendra
Rajendra Nayak (5):
regulator: twl: Remove hardcoded board constraints from driver
dt: add empty dt helpers for non-dt build
regulator: helper routine to extract regulator_init_data
regulator: adapt fixed regulator driver to dt
regulator: map consumer regulator based on device tree
.../bindings/regulator/fixed-regulator.txt | 24 +++++
.../devicetree/bindings/regulator/regulator.txt | 44 +++++++++
drivers/regulator/Kconfig | 8 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/core.c | 91 ++++++++++++++++---
drivers/regulator/fixed.c | 58 ++++++++++++
drivers/regulator/of_regulator.c | 93 ++++++++++++++++++++
drivers/regulator/twl-regulator.c | 8 --
include/linux/of.h | 19 ++++
include/linux/regulator/driver.h | 2 +
include/linux/regulator/of_regulator.h | 21 +++++
11 files changed, 346 insertions(+), 23 deletions(-)
create mode 100644 Documentation/devicetree/bindings/regulator/fixed-regulator.txt
create mode 100644 Documentation/devicetree/bindings/regulator/regulator.txt
create mode 100644 drivers/regulator/of_regulator.c
create mode 100644 include/linux/regulator/of_regulator.h
^ permalink raw reply
* [PATCH v2 1/5] regulator: twl: Remove hardcoded board constraints from driver
From: Rajendra Nayak @ 2011-10-10 16:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318263578-7407-1-git-send-email-rnayak@ti.com>
Remove the hardcoded .valid_modes_mask and .valid_ops_mask for
each regulator from the twl driver and let the boards pass it.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/regulator/twl-regulator.c | 8 --------
1 files changed, 0 insertions(+), 8 deletions(-)
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index ee8747f..f696287 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1027,14 +1027,6 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
/* copy the features into regulator data */
info->features = (unsigned long)initdata->driver_data;
- /* Constrain board-specific capabilities according to what
- * this driver and the chip itself can actually do.
- */
- c = &initdata->constraints;
- c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
- c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS;
switch (pdev->id) {
case TWL4030_REG_VIO:
case TWL4030_REG_VDD1:
--
1.7.1
^ permalink raw reply related
* [PATCH v2 2/5] dt: add empty dt helpers for non-dt build
From: Rajendra Nayak @ 2011-10-10 16:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318263578-7407-1-git-send-email-rnayak@ti.com>
Add empty of_device_is_compatible(), of_find_property()
and of_parse_phandle() for non-dt builds to work.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
include/linux/of.h | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/include/linux/of.h b/include/linux/of.h
index 9180dc5..47ce461 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -263,6 +263,25 @@ static inline const void *of_get_property(const struct device_node *node,
return NULL;
}
+static inline int of_device_is_compatible(const struct device_node *device,
+ const char *name)
+{
+ return 0;
+}
+
+static inline struct property *of_find_property(const struct device_node *np,
+ const char *name,
+ int *lenp)
+{
+ return NULL;
+}
+
+static inline struct device_node *of_parse_phandle(struct device_node *np,
+ const char *phandle_name,
+ int index)
+{
+ return NULL;
+}
#endif /* CONFIG_OF */
static inline int of_property_read_u32(const struct device_node *np,
--
1.7.1
^ permalink raw reply related
* [PATCH v2 3/5] regulator: helper routine to extract regulator_init_data
From: Rajendra Nayak @ 2011-10-10 16:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318263578-7407-1-git-send-email-rnayak@ti.com>
The helper routine is meant to be used by regulator drivers
to extract the regulator_init_data structure from the data
that is passed from device tree.
'consumer_supplies' which is part of regulator_init_data is not extracted
as the regulator consumer mappings are passed through DT differently,
implemented in subsequent patches.
Similarly the regulator<-->parent/supply mapping is handled in
subsequent patches.
Also add documentation for regulator bindings to be used to pass
regulator_init_data struct information from device tree.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
.../devicetree/bindings/regulator/regulator.txt | 44 +++++++++
drivers/regulator/Kconfig | 8 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/of_regulator.c | 93 ++++++++++++++++++++
include/linux/regulator/of_regulator.h | 21 +++++
5 files changed, 167 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/regulator/regulator.txt
create mode 100644 drivers/regulator/of_regulator.c
create mode 100644 include/linux/regulator/of_regulator.h
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
new file mode 100644
index 0000000..a623fdd
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -0,0 +1,44 @@
+Voltage/Current Regulators
+
+Optional properties:
+- regulator-min-uV: smallest voltage consumers may set
+- regulator-max-uV: largest voltage consumers may set
+- regulator-uV-offset: Offset applied to voltages to compensate for voltage drops
+- regulator-min-uA: smallest current consumers may set
+- regulator-max-uA: largest current consumers may set
+- regulator-change-voltage: boolean, Output voltage can be changed by software
+- regulator-change-current: boolean, Output current can be chnaged by software
+- regulator-change-mode: boolean, Operating mode can be changed by software
+- regulator-change-status: boolean, Enable/Disable control for regulator exists
+- regulator-change-drms: boolean, Dynamic regulator mode switching is enabled
+- regulator-mode-fast: boolean, allow/set fast mode for the regulator
+- regulator-mode-normal: boolean, allow/set normal mode for the regulator
+- regulator-mode-idle: boolean, allow/set idle mode for the regulator
+- regulator-mode-standby: boolean, allow/set standby mode for the regulator
+- regulator-input-uV: Input voltage for regulator when supplied by another regulator
+- regulator-always-on: boolean, regulator should never be disabled
+- regulator-boot-on: bootloader/firmware enabled regulator
+- <name>-supply: phandle to the parent supply/regulator node
+
+Example:
+
+ xyzreg: regulator at 0 {
+ regulator-min-uV = <1000000>;
+ regulator-max-uV = <2500000>;
+ regulator-mode-fast;
+ regulator-change-voltage;
+ regulator-always-on;
+ vin-supply = <&vin>;
+ };
+
+The same binding used by a regulator to reference its
+supply can be used by any consumer to reference its
+regulator/supply
+
+Example of a device node referencing a regulator node,
+
+ devicenode: node at 0x0 {
+ ...
+ ...
+ <name>-supply = <&xyzreg>;
+ };
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c7fd2c0..981c92e 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -64,6 +64,14 @@ config REGULATOR_USERSPACE_CONSUMER
If unsure, say no.
+config OF_REGULATOR
+ tristate "OF regulator helpers"
+ depends on OF
+ default y if OF
+ help
+ OpenFirmware regulator framework helper routines that can
+ used by regulator drivers to extract data from device tree.
+
config REGULATOR_BQ24022
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
help
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 040d5aa..e6bc009 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_REGULATOR) += core.o dummy.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
+obj-$(CONFIG_OF_REGULATOR) += of_regulator.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
new file mode 100644
index 0000000..9262d06
--- /dev/null
+++ b/drivers/regulator/of_regulator.c
@@ -0,0 +1,93 @@
+/*
+ * OF helpers for regulator framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/regulator/machine.h>
+
+static void of_get_regulation_constraints(struct device_node *np,
+ struct regulator_init_data **init_data)
+{
+ const __be32 *min_uV, *max_uV, *uV_offset;
+ const __be32 *min_uA, *max_uA, *input_uV;
+ unsigned int valid_modes_mask = 0, valid_ops_mask = 0;
+
+ min_uV = of_get_property(np, "regulator-min-uV", NULL);
+ if (min_uV)
+ (*init_data)->constraints.min_uV = be32_to_cpu(*min_uV);
+ max_uV = of_get_property(np, "regulator-max-uV", NULL);
+ if (max_uV)
+ (*init_data)->constraints.max_uV = be32_to_cpu(*max_uV);
+ uV_offset = of_get_property(np, "regulator-uV-offset", NULL);
+ if (uV_offset)
+ (*init_data)->constraints.uV_offset = be32_to_cpu(*uV_offset);
+ min_uA = of_get_property(np, "regulator-min-uA", NULL);
+ if (min_uA)
+ (*init_data)->constraints.min_uA = be32_to_cpu(*min_uA);
+ max_uA = of_get_property(np, "regulator-max-uA", NULL);
+ if (max_uA)
+ (*init_data)->constraints.max_uA = be32_to_cpu(*max_uA);
+ input_uV = of_get_property(np, "regulator-input-uV", NULL);
+ if (input_uV)
+ (*init_data)->constraints.input_uV = be32_to_cpu(*input_uV);
+
+ /* valid modes mask */
+ if (of_find_property(np, "regulator-mode-fast", NULL))
+ valid_modes_mask |= REGULATOR_MODE_FAST;
+ if (of_find_property(np, "regulator-mode-normal", NULL))
+ valid_modes_mask |= REGULATOR_MODE_NORMAL;
+ if (of_find_property(np, "regulator-mode-idle", NULL))
+ valid_modes_mask |= REGULATOR_MODE_IDLE;
+ if (of_find_property(np, "regulator-mode-standby", NULL))
+ valid_modes_mask |= REGULATOR_MODE_STANDBY;
+
+ /* valid ops mask */
+ if (of_find_property(np, "regulator-change-voltage", NULL))
+ valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
+ if (of_find_property(np, "regulator-change-current", NULL))
+ valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
+ if (of_find_property(np, "regulator-change-mode", NULL))
+ valid_ops_mask |= REGULATOR_CHANGE_MODE;
+ if (of_find_property(np, "regulator-change-status", NULL))
+ valid_ops_mask |= REGULATOR_CHANGE_STATUS;
+
+ (*init_data)->constraints.valid_modes_mask = valid_modes_mask;
+ (*init_data)->constraints.valid_ops_mask = valid_ops_mask;
+
+ if (of_find_property(np, "regulator-always-on", NULL))
+ (*init_data)->constraints.always_on = true;
+ if (of_find_property(np, "regulator-boot-on", NULL))
+ (*init_data)->constraints.boot_on = true;
+}
+
+/**
+ * of_get_regulator_init_data - extract regulator_init_data structure info
+ * @dev: device requesting for regulator_init_data
+ *
+ * Populates regulator_init_data structure by extracting data from device
+ * tree node, returns a pointer to the populated struture or NULL if memory
+ * alloc fails.
+ */
+struct regulator_init_data *of_get_regulator_init_data(struct device *dev)
+{
+ struct regulator_init_data *init_data;
+
+ if (!dev->of_node)
+ return NULL;
+
+ init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
+ if (!init_data)
+ return NULL; /* Out of memory? */
+
+ of_get_regulation_constraints(dev->of_node, &init_data);
+ return init_data;
+}
diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h
new file mode 100644
index 0000000..c5a1ad6
--- /dev/null
+++ b/include/linux/regulator/of_regulator.h
@@ -0,0 +1,21 @@
+/*
+ * OpenFirmware regulator support routines
+ *
+ */
+
+#ifndef __LINUX_OF_REG_H
+#define __LINUX_OF_REG_H
+
+#if defined(CONFIG_OF_REGULATOR)
+extern struct regulator_init_data
+ *of_get_regulator_init_data(struct device *dev);
+#else
+static inline struct regulator_init_data
+ *of_get_regulator_init_data(struct device *dev)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF_REGULATOR */
+
+#endif /* __LINUX_OF_REG_H */
+
--
1.7.1
^ permalink raw reply related
* [PATCH v2 4/5] regulator: adapt fixed regulator driver to dt
From: Rajendra Nayak @ 2011-10-10 16:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318263578-7407-1-git-send-email-rnayak@ti.com>
The fixed regulator driver uses of_get_fixed_voltage_config()
to extract fixed_voltage_config structure contents from device tree.
Also add documenation for additional bindings for fixed
regulators that can be passed through dt.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
.../bindings/regulator/fixed-regulator.txt | 25 +++++++++
drivers/regulator/fixed.c | 58 ++++++++++++++++++++
2 files changed, 83 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/regulator/fixed-regulator.txt
diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
new file mode 100644
index 0000000..049df3d
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
@@ -0,0 +1,25 @@
+Fixed Voltage regulators
+
+Required properties:
+- compatible: Must be "regulator-fixed";
+
+Optional properties:
+- regulator-fixed-supply: Name of the regulator supply
+- regulator-fixed-microvolts: Output voltage of regulator
+- regulator-fixed-gpio: gpio to use for enable control
+- regulator-fixed-startup-delay: startup time in microseconds
+- regulator-fixed-enable-high: Polarity of enable GPIO,
+ 1 = Active High, 0 = Active low
+- regulator-fixed-enabled-at-boot: 1 = yes, 0 = no
+
+Example:
+
+ abc: fixedregulator at 0 {
+ compatible = "regulator-fixed";
+ regulator-fixed-supply = "fixed-supply";
+ regulator-fixed-microvolts = <1800000>;
+ regulator-fixed-gpio = <43>;
+ regulator-fixed-startup-delay = <70000>;
+ regulator-fixed-enable-high;
+ regulator-fixed-enabled-at-boot;
+ };
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 2fe9d99..eb37eb6 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -23,9 +23,12 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
struct fixed_voltage_data {
struct regulator_desc desc;
@@ -37,6 +40,47 @@ struct fixed_voltage_data {
bool is_enabled;
};
+
+/**
+ * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
+ * @dev: device requesting for fixed_voltage_config
+ *
+ * Populates fixed_voltage_config structure by extracting data from device
+ * tree node, returns a pointer to the populated structure of NULL if memory
+ * alloc fails.
+ */
+struct fixed_voltage_config *of_get_fixed_voltage_config(struct device *dev)
+{
+ struct fixed_voltage_config *config;
+ struct device_node *np = dev->of_node;
+ const __be32 *microvolts, *gpio, *delay;
+
+ config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), GFP_KERNEL);
+ if (!config)
+ return NULL;
+
+ config->supply_name = (char *)of_get_property(np,
+ "regulator-fixed-supply", NULL);
+ microvolts = of_get_property(np, "regulator-fixed-microvolts", NULL);
+ if (microvolts)
+ config->microvolts = be32_to_cpu(*microvolts);
+ gpio = of_get_property(np, "regulator-fixed-gpio", NULL);
+ if (gpio)
+ config->gpio = be32_to_cpu(*gpio);
+ delay = of_get_property(np, "regulator-fixed-startup-delay", NULL);
+ if (delay)
+ config->startup_delay = be32_to_cpu(*delay);
+
+ if (of_find_property(np, "regulator-fixed-enable-high", NULL))
+ config->enable_high = true;
+ if (of_find_property(np, "regulator-fixed-enabled-at-boot", NULL))
+ config->enabled_at_boot = true;
+
+ config->init_data = of_get_regulator_init_data(dev);
+
+ return config;
+}
+
static int fixed_voltage_is_enabled(struct regulator_dev *dev)
{
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
@@ -108,6 +152,9 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
struct fixed_voltage_data *drvdata;
int ret;
+ if (pdev->dev.of_node)
+ config = of_get_fixed_voltage_config(&pdev->dev);
+
drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n");
@@ -216,12 +263,23 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
return 0;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id fixed_of_match[] __devinitconst = {
+ { .compatible = "regulator-fixed", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, fixed_of_match);
+#else
+#define fixed_of_match NULL
+#endif
+
static struct platform_driver regulator_fixed_voltage_driver = {
.probe = reg_fixed_voltage_probe,
.remove = __devexit_p(reg_fixed_voltage_remove),
.driver = {
.name = "reg-fixed-voltage",
.owner = THIS_MODULE,
+ .of_match_table = fixed_of_match,
},
};
--
1.7.1
^ permalink raw reply related
* [PATCH v2 5/5] regulator: map consumer regulator based on device tree
From: Rajendra Nayak @ 2011-10-10 16:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318263578-7407-1-git-send-email-rnayak@ti.com>
Device nodes in DT can associate themselves with one or more
regulators/supply by providing a list of phandles (to regulator nodes)
and corresponding supply names.
For Example:
devicenode: node at 0x0 {
...
...
vmmc-supply = <®ulator1>;
vpll-supply = <®ulator1>;
};
The driver would then do a regulator_get(dev, "vmmc"); to get
regulator1 and do a regulator_get(dev, "vpll"); to get
regulator2.
of_get_regulator() extracts the regulator node for a given
device, based on the supply name.
Use it to look up the regulator for a given consumer from device tree, during
a regulator_get(). If not found fallback and lookup through
the regulator_map_list instead.
Also, since the regulator dt nodes can use the same binding to
associate with a parent regulator/supply, allow the drivers to
specify a supply_name, which can then be used to lookup dt
to find the parent phandle.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
drivers/regulator/core.c | 91 +++++++++++++++++++++++++++++++------
include/linux/regulator/driver.h | 2 +
2 files changed, 78 insertions(+), 15 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index d8e6a42..9a5ebbe 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -25,9 +25,11 @@
#include <linux/mutex.h>
#include <linux/suspend.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
#define CREATE_TRACE_POINTS
#include <trace/events/regulator.h>
@@ -131,6 +133,33 @@ static struct regulator *get_device_regulator(struct device *dev)
return NULL;
}
+/**
+ * of_get_regulator - get a regulator device node based on supply name
+ * @dev: Device pointer for the consumer (of regulator) device
+ * @supply: regulator supply name
+ *
+ * Extract the regulator device node corresponding to the supply name.
+ * retruns the device node corresponding to the regulator if found, else
+ * returns NULL.
+ */
+struct device_node *of_get_regulator(struct device *dev, const char *supply)
+{
+ struct device_node *regnode = NULL;
+ char prop_name[32]; /* 32 is max size of property name */
+
+ dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
+
+ snprintf(prop_name, 32, "%s-supply", supply);
+ regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+
+ if (!regnode) {
+ pr_warn("%s: %s property in node %s references invalid phandle",
+ __func__, prop_name, dev->of_node->full_name);
+ return NULL;
+ }
+ return regnode;
+}
+
/* Platform voltage constraint check */
static int regulator_check_voltage(struct regulator_dev *rdev,
int *min_uV, int *max_uV)
@@ -1155,6 +1184,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
struct regulator_map *map;
struct regulator *regulator = ERR_PTR(-ENODEV);
const char *devname = NULL;
+ struct device_node *node;
int ret;
if (id == NULL) {
@@ -1167,6 +1197,23 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
mutex_lock(®ulator_list_mutex);
+ /*
+ * Lookup happens in 3 ways
+ * 1. If a dev and dev->of_node exist, look for a
+ * regulator mapping in dt node.
+ * 2. Check if a match can be found in regulator_map_list
+ * if regulator info is still passed in non-dt way
+ * 3. if !dev, then just look for a matching regulator name.
+ * Useful for dt builds using regulator_get() without specifying
+ * a device.
+ */
+ if (dev && dev->of_node) {
+ node = of_get_regulator(dev, id);
+ if (node)
+ list_for_each_entry(rdev, ®ulator_list, list)
+ if (node == rdev->dev.parent->of_node)
+ goto found;
+ }
list_for_each_entry(map, ®ulator_map_list, list) {
/* If the mapping has a device set up it must match */
if (map->dev_name &&
@@ -1178,6 +1225,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
goto found;
}
}
+ if (!dev)
+ list_for_each_entry(rdev, ®ulator_list, list)
+ if (strcmp(rdev_get_name(rdev), id))
+ goto found;
if (board_wants_dummy_regulator) {
rdev = dummy_regulator_rdev;
@@ -2579,6 +2630,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
static atomic_t regulator_no = ATOMIC_INIT(0);
struct regulator_dev *rdev;
int ret, i;
+ const char *supply;
if (regulator_desc == NULL)
return ERR_PTR(-EINVAL);
@@ -2653,25 +2705,34 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (ret < 0)
goto scrub;
- if (init_data->supply_regulator) {
- struct regulator_dev *r;
- int found = 0;
+ if (init_data->supply_regulator)
+ supply = init_data->supply_regulator;
+ else if (regulator_desc->supply_name);
+ supply = regulator_desc->supply_name;
- list_for_each_entry(r, ®ulator_list, list) {
- if (strcmp(rdev_get_name(r),
- init_data->supply_regulator) == 0) {
- found = 1;
- break;
- }
+ if (supply) {
+ struct regulator_dev *r;
+ struct device_node *node;
+
+ /* first do a dt based lookup */
+ if (dev) {
+ node = of_get_regulator(dev, supply);
+ if (node)
+ list_for_each_entry(r, ®ulator_list, list)
+ if (node == r->dev.parent->of_node)
+ goto found;
}
- if (!found) {
- dev_err(dev, "Failed to find supply %s\n",
- init_data->supply_regulator);
- ret = -ENODEV;
- goto scrub;
- }
+ /* next try doing it non-dt way */
+ list_for_each_entry(r, ®ulator_list, list)
+ if (strcmp(rdev_get_name(r), supply) == 0)
+ goto found;
+ dev_err(dev, "Failed to find supply %s\n", supply);
+ ret = -ENODEV;
+ goto scrub;
+
+found:
ret = set_supply(rdev, r);
if (ret < 0)
goto scrub;
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 1a80bc7..65ca5ff 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -153,6 +153,7 @@ enum regulator_type {
* this type.
*
* @name: Identifying name for the regulator.
+ * @supply_name: Identifying the regulator supply
* @id: Numerical identifier for the regulator.
* @n_voltages: Number of selectors available for ops.list_voltage().
* @ops: Regulator operations table.
@@ -162,6 +163,7 @@ enum regulator_type {
*/
struct regulator_desc {
const char *name;
+ const char *supply_name;
int id;
unsigned n_voltages;
struct regulator_ops *ops;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 1/5] regulator: twl: Remove hardcoded board constraints from driver
From: Mark Brown @ 2011-10-10 16:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318263578-7407-2-git-send-email-rnayak@ti.com>
On Mon, Oct 10, 2011 at 09:49:34PM +0530, Rajendra Nayak wrote:
> Remove the hardcoded .valid_modes_mask and .valid_ops_mask for
> each regulator from the twl driver and let the boards pass it.
>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Please update this changelog - as I said in reply to your previous
posting this isn't actually hardcoding anything, it's dropping things
from the constraints which the hardware doesn't support.
^ permalink raw reply
* [PATCH] fix ehci alignment error
From: Måns Rullgård @ 2011-10-10 16:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010141402.GA21856@suse.de>
Greg KH <gregkh@suse.de> writes:
> On Mon, Oct 10, 2011 at 02:38:27PM +0200, Harro Haan wrote:
>> The Kirkwood gave an unaligned memory access error on
>> line 742 of drivers/usb/host/echi-hcd.c:
>> "ehci->last_periodic_enable = ktime_get_real();"
>
> What is "The Kirkwood"? What size processor is this?
It's an ARM926-like CPU from Marvell.
--
M?ns Rullg?rd
mans at mansr.com
^ permalink raw reply
* [PATCH v5 0/2] Add device tree support for Samsung's keypad controller driver
From: Thomas Abraham @ 2011-10-10 16:29 UTC (permalink / raw)
To: linux-arm-kernel
Changes since v4:
- Tested with linux 3.1-rc9. No changes in code.
Changes since v3:
- Addressed comments from Grant Likely.
- Set num_rows and num_cols to zero in samsung_keypad_parse_dt function.
- Fixed the wierd looking if-else block in samsung_keypad_probe function.
Changes since v2:
- Addressed comments from Grant Likely.
- Renamed 'keypad,key-code' property name to 'linux,code'.
- Fixed incorrect data types for all instances of of_property+read_u32.
- linux,input-type binding was not added as suggested since the driver
supports only EV_KEY event type.
Changes since v1:
- Addressed comments from Dmitry Torokhov.
- Type of controller is cached in driver's private data and the function
that determines the type of the controller for each keypad scan is
removed.
- pdata allocated during probe is explicitly freed after probe completes
without any error. In case of exit from probe due a error, no explicit
deallocation of pdata memory is performed and it is left to devres to
handle that.
- The generic code to translate KEY(x,y,code) is retained in the driver
itself. I am unsure of a right common place for it.
- Driver continues with the probe even if one or more gpio configuration
fails.
- Patch 1 that adds a new config option is still retained in this patchset.
This patchset adds device tree support for samsung's keypad controller driver.
First patch adds a new config option to be used by device tree enabled platforms
for selecting the samsung's keypad controller driver. The second patch adds device
tree support for the keypad driver.
Thomas Abraham (2):
input: samsung-keypad: Add HAVE_SAMSUNG_KEYPAD config option
input: samsung-keypad: Add device tree support
.../devicetree/bindings/input/samsung-keypad.txt | 88 ++++++++++
drivers/input/keyboard/Kconfig | 9 +-
drivers/input/keyboard/samsung-keypad.c | 174 ++++++++++++++++++--
3 files changed, 258 insertions(+), 13 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/samsung-keypad.txt
^ permalink raw reply
* [PATCH v5 1/2] input: samsung-keypad: Add HAVE_SAMSUNG_KEYPAD config option
From: Thomas Abraham @ 2011-10-10 16:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318264197-6698-1-git-send-email-thomas.abraham@linaro.org>
For platforms using device tree, the static keypad device instances
are not required and SAMSUNG_DEV_KEYPAD is not selected. Since,
samsung keypad driver has dependency on SAMSUNG_DEV_KEYPAD config
option, the driver is left out of the compilation for dt enabled
platforms.
An additional config option 'HAVE_SAMSUNG_KEYPAD' is added
which the device tree based platforms can select. This config
option is added as an alternative dependency for keypad driver.
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
drivers/input/keyboard/Kconfig | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index b4dee9d..7c322a3 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -423,9 +423,16 @@ config KEYBOARD_PMIC8XXX
To compile this driver as a module, choose M here: the module will
be called pmic8xxx-keypad.
+config HAVE_SAMSUNG_KEYPAD
+ bool
+ help
+ This will include Samsung Keypad controller driver support. If you
+ want to include Samsung Keypad support for any machine, kindly
+ select this in the respective mach-xxxx/Kconfig file.
+
config KEYBOARD_SAMSUNG
tristate "Samsung keypad support"
- depends on SAMSUNG_DEV_KEYPAD
+ depends on SAMSUNG_DEV_KEYPAD || HAVE_SAMSUNG_KEYPAD
help
Say Y here if you want to use the Samsung keypad.
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v5 2/2] input: samsung-keypad: Add device tree support
From: Thomas Abraham @ 2011-10-10 16:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318264197-6698-1-git-send-email-thomas.abraham@linaro.org>
Add device tree based discovery support for Samsung's keypad controller.
Cc: Joonyoung Shim <jy0922.shim@samsung.com>
Cc: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
.../devicetree/bindings/input/samsung-keypad.txt | 88 ++++++++++
drivers/input/keyboard/samsung-keypad.c | 174 ++++++++++++++++++--
2 files changed, 250 insertions(+), 12 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/samsung-keypad.txt
diff --git a/Documentation/devicetree/bindings/input/samsung-keypad.txt b/Documentation/devicetree/bindings/input/samsung-keypad.txt
new file mode 100644
index 0000000..ce3e394
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/samsung-keypad.txt
@@ -0,0 +1,88 @@
+* Samsung's Keypad Controller device tree bindings
+
+Samsung's Keypad controller is used to interface a SoC with a matrix-type
+keypad device. The keypad controller supports multiple row and column lines.
+A key can be placed at each intersection of a unique row and a unique column.
+The keypad controller can sense a key-press and key-release and report the
+event using a interrupt to the cpu.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+ - "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad
+ controller.
+ - "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad
+ controller.
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupts: The interrupt number to the cpu.
+
+Required Board Specific Properties:
+- samsung,keypad-num-rows: Number of row lines connected to the keypad
+ controller.
+
+- samsung,keypad-num-columns: Number of column lines connected to the
+ keypad controller.
+
+- row-gpios: List of gpios used as row lines. The gpio specifier for
+ this property depends on the gpio controller to which these row lines
+ are connected.
+
+- col-gpios: List of gpios used as column lines. The gpio specifier for
+ this property depends on the gpio controller to which these column
+ lines are connected.
+
+- Keys represented as child nodes: Each key connected to the keypad
+ controller is represented as a child node to the keypad controller
+ device node and should include the following properties.
+ - keypad,row: the row number to which the key is connected.
+ - keypad,column: the column number to which the key is connected.
+ - linux,code: the key-code to be reported when the key is pressed
+ and released.
+
+Optional Properties specific to linux:
+- linux,keypad-no-autorepeat: do no enable autorepeat feature.
+- linux,keypad-wakeup: use any event on keypad as wakeup event.
+
+
+Example:
+ keypad at 100A0000 {
+ compatible = "samsung,s5pv210-keypad";
+ reg = <0x100A0000 0x100>;
+ interrupts = <173>;
+ samsung,keypad-num-rows = <2>;
+ samsung,keypad-num-columns = <8>;
+ linux,input-no-autorepeat;
+ linux,input-wakeup;
+
+ row-gpios = <&gpx2 0 3 3 0
+ &gpx2 1 3 3 0>;
+
+ col-gpios = <&gpx1 0 3 0 0
+ &gpx1 1 3 0 0
+ &gpx1 2 3 0 0
+ &gpx1 3 3 0 0
+ &gpx1 4 3 0 0
+ &gpx1 5 3 0 0
+ &gpx1 6 3 0 0
+ &gpx1 7 3 0 0>;
+
+ key_1 {
+ keypad,row = <0>;
+ keypad,column = <3>;
+ linux,code = <2>;
+ };
+
+ key_2 {
+ keypad,row = <0>;
+ keypad,column = <4>;
+ linux,code = <3>;
+ };
+
+ key_3 {
+ keypad,row = <0>;
+ keypad,column = <5>;
+ linux,code = <4>;
+ };
+ };
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index f689f49..8a0060c 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -21,6 +21,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/sched.h>
#include <plat/keypad.h>
@@ -68,31 +70,26 @@ struct samsung_keypad {
wait_queue_head_t wait;
bool stopped;
int irq;
+ enum samsung_keypad_type type;
unsigned int row_shift;
unsigned int rows;
unsigned int cols;
unsigned int row_state[SAMSUNG_MAX_COLS];
+#ifdef CONFIG_OF
+ int row_gpios[SAMSUNG_MAX_ROWS];
+ int col_gpios[SAMSUNG_MAX_COLS];
+#endif
unsigned short keycodes[];
};
-static int samsung_keypad_is_s5pv210(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- enum samsung_keypad_type type =
- platform_get_device_id(pdev)->driver_data;
-
- return type == KEYPAD_TYPE_S5PV210;
-}
-
static void samsung_keypad_scan(struct samsung_keypad *keypad,
unsigned int *row_state)
{
- struct device *dev = keypad->input_dev->dev.parent;
unsigned int col;
unsigned int val;
for (col = 0; col < keypad->cols; col++) {
- if (samsung_keypad_is_s5pv210(dev)) {
+ if (keypad->type == KEYPAD_TYPE_S5PV210) {
val = S5PV210_KEYIFCOLEN_MASK;
val &= ~(1 << col) << 8;
} else {
@@ -235,6 +232,126 @@ static void samsung_keypad_close(struct input_dev *input_dev)
samsung_keypad_stop(keypad);
}
+#ifdef CONFIG_OF
+static struct samsung_keypad_platdata *samsung_keypad_parse_dt(
+ struct device *dev)
+{
+ struct samsung_keypad_platdata *pdata;
+ struct matrix_keymap_data *keymap_data;
+ uint32_t *keymap, num_rows = 0, num_cols = 0;
+ struct device_node *np = dev->of_node, *key_np;
+ unsigned int key_count = 0;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(dev, "could not allocate memory for platform data\n");
+ return NULL;
+ }
+
+ of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
+ of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
+ if (!num_rows || !num_cols) {
+ dev_err(dev, "number of keypad rows/columns not specified\n");
+ return NULL;
+ }
+ pdata->rows = num_rows;
+ pdata->cols = num_cols;
+
+ keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL);
+ if (!keymap_data) {
+ dev_err(dev, "could not allocate memory for keymap data\n");
+ return NULL;
+ }
+ pdata->keymap_data = keymap_data;
+
+ for_each_child_of_node(np, key_np)
+ key_count++;
+
+ keymap_data->keymap_size = key_count;
+ keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL);
+ if (!keymap) {
+ dev_err(dev, "could not allocate memory for keymap\n");
+ return NULL;
+ }
+ keymap_data->keymap = keymap;
+
+ for_each_child_of_node(np, key_np) {
+ u32 row, col, key_code;
+ of_property_read_u32(key_np, "keypad,row", &row);
+ of_property_read_u32(key_np, "keypad,column", &col);
+ of_property_read_u32(key_np, "linux,code", &key_code);
+ *keymap++ = KEY(row, col, key_code);
+ }
+
+ if (of_get_property(np, "linux,input-no-autorepeat", NULL))
+ pdata->no_autorepeat = true;
+ if (of_get_property(np, "linux,input-wakeup", NULL))
+ pdata->wakeup = true;
+
+ return pdata;
+}
+
+static void samsung_keypad_parse_dt_gpio(struct device *dev,
+ struct samsung_keypad *keypad)
+{
+ struct device_node *np = dev->of_node;
+ int gpio, ret, row, col;
+
+ for (row = 0; row < keypad->rows; row++) {
+ gpio = of_get_named_gpio(np, "row-gpios", row);
+ keypad->row_gpios[row] = gpio;
+ if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "keypad row[%d]: invalid gpio %d\n",
+ row, gpio);
+ continue;
+ }
+
+ ret = gpio_request(gpio, "keypad-row");
+ if (ret)
+ dev_err(dev, "keypad row[%d] gpio request failed\n",
+ row);
+ }
+
+ for (col = 0; col < keypad->cols; col++) {
+ gpio = of_get_named_gpio(np, "col-gpios", col);
+ keypad->col_gpios[col] = gpio;
+ if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "keypad column[%d]: invalid gpio %d\n",
+ col, gpio);
+ continue;
+ }
+
+ ret = gpio_request(gpio, "keypad-col");
+ if (ret)
+ dev_err(dev, "keypad column[%d] gpio request failed\n",
+ col);
+ }
+}
+
+static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < keypad->rows; cnt++)
+ if (gpio_is_valid(keypad->row_gpios[cnt]))
+ gpio_free(keypad->row_gpios[cnt]);
+
+ for (cnt = 0; cnt < keypad->cols; cnt++)
+ if (gpio_is_valid(keypad->col_gpios[cnt]))
+ gpio_free(keypad->col_gpios[cnt]);
+}
+#else
+static
+struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev)
+{
+ return NULL;
+}
+
+static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
+{
+}
+#endif
+
static int __devinit samsung_keypad_probe(struct platform_device *pdev)
{
const struct samsung_keypad_platdata *pdata;
@@ -246,7 +363,10 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
unsigned int keymap_size;
int error;
- pdata = pdev->dev.platform_data;
+ if (pdev->dev.of_node)
+ pdata = samsung_keypad_parse_dt(&pdev->dev);
+ else
+ pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL;
@@ -303,6 +423,16 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
keypad->cols = pdata->cols;
init_waitqueue_head(&keypad->wait);
+ if (pdev->dev.of_node) {
+#ifdef CONFIG_OF
+ samsung_keypad_parse_dt_gpio(&pdev->dev, keypad);
+ keypad->type = of_device_is_compatible(pdev->dev.of_node,
+ "samsung,s5pv210-keypad");
+#endif
+ } else {
+ keypad->type = platform_get_device_id(pdev)->driver_data;
+ }
+
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev;
@@ -343,12 +473,19 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, pdata->wakeup);
platform_set_drvdata(pdev, keypad);
+
+ if (pdev->dev.of_node) {
+ devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap);
+ devm_kfree(&pdev->dev, (void *)pdata->keymap_data);
+ devm_kfree(&pdev->dev, (void *)pdata);
+ }
return 0;
err_free_irq:
free_irq(keypad->irq, keypad);
err_put_clk:
clk_put(keypad->clk);
+ samsung_keypad_dt_gpio_free(keypad);
err_unmap_base:
iounmap(keypad->base);
err_free_mem:
@@ -374,6 +511,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
free_irq(keypad->irq, keypad);
clk_put(keypad->clk);
+ samsung_keypad_dt_gpio_free(keypad);
iounmap(keypad->base);
kfree(keypad);
@@ -447,6 +585,17 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = {
};
#endif
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_keypad_dt_match[] = {
+ { .compatible = "samsung,s3c6410-keypad" },
+ { .compatible = "samsung,s5pv210-keypad" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match);
+#else
+#define samsung_keypad_dt_match NULL
+#endif
+
static struct platform_device_id samsung_keypad_driver_ids[] = {
{
.name = "samsung-keypad",
@@ -465,6 +614,7 @@ static struct platform_driver samsung_keypad_driver = {
.driver = {
.name = "samsung-keypad",
.owner = THIS_MODULE,
+ .of_match_table = samsung_keypad_dt_match,
#ifdef CONFIG_PM
.pm = &samsung_keypad_pm_ops,
#endif
--
1.6.6.rc2
^ permalink raw reply related
* [PATCH v2 1/5] regulator: twl: Remove hardcoded board constraints from driver
From: Rajendra Nayak @ 2011-10-10 16:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20111010162507.GF3607@opensource.wolfsonmicro.com>
On Monday 10 October 2011 09:55 PM, Mark Brown wrote:
> On Mon, Oct 10, 2011 at 09:49:34PM +0530, Rajendra Nayak wrote:
>> Remove the hardcoded .valid_modes_mask and .valid_ops_mask for
>> each regulator from the twl driver and let the boards pass it.
>>
>> Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> Acked-by: Mark Brown<broonie@opensource.wolfsonmicro.com>
>
> Please update this changelog - as I said in reply to your previous
> posting this isn't actually hardcoding anything, it's dropping things
> from the constraints which the hardware doesn't support.
Looks like I completely missed the "&=" and your comment
on the previous posting. Looking at it now, seems to me
this patch is just un-necessary and what the driver seems
to be doing (preventing users from setting flags which the
hardware does not support) seems perfectly fine.
I will just go ahead and drop this patch.
^ permalink raw reply
* [PATCH 1/4] dmaengine: at_hdmac: platform data move to use .id_table
From: Nicolas Ferre @ 2011-10-10 16:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1314075338.22120.3.camel@vkoul-udesk3>
We remove platform data from DMA controller and move
to the use of .id_table to distinguish between compatible
types. The two implementations allow to determine the
number of channels and the capabilities of the controller.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
drivers/dma/at_hdmac.c | 48 ++++++++++++++++++++++++++++++++++---------
drivers/dma/at_hdmac_regs.h | 8 +++++++
2 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index fcfa0a8..fef57bc 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1175,6 +1175,18 @@ static void atc_free_chan_resources(struct dma_chan *chan)
/*-- Module Management -----------------------------------------------*/
+static struct platform_device_id atdma_devtypes[] = {
+ {
+ .name = "at91sam9rl_dma",
+ .driver_data = ATDMA_DEVTYPE_SAM9RL,
+ }, {
+ .name = "at91sam9g45_dma",
+ .driver_data = ATDMA_DEVTYPE_SAM9G45,
+ }, {
+ /* sentinel */
+ }
+};
+
/**
* at_dma_off - disable DMA controller
* @atdma: the Atmel HDAMC device
@@ -1193,18 +1205,32 @@ static void at_dma_off(struct at_dma *atdma)
static int __init at_dma_probe(struct platform_device *pdev)
{
- struct at_dma_platform_data *pdata;
struct resource *io;
struct at_dma *atdma;
size_t size;
int irq;
int err;
int i;
+ u32 nr_channels;
+ dma_cap_mask_t cap_mask = {};
+ enum atdma_devtype atdmatype;
+
+ dma_cap_set(DMA_MEMCPY, cap_mask);
+
+ /* get DMA parameters from controller type */
+ atdmatype = platform_get_device_id(pdev)->driver_data;
- /* get DMA Controller parameters from platform */
- pdata = pdev->dev.platform_data;
- if (!pdata || pdata->nr_channels > AT_DMA_MAX_NR_CHANNELS)
+ switch (atdmatype) {
+ case ATDMA_DEVTYPE_SAM9RL:
+ nr_channels = 2;
+ break;
+ case ATDMA_DEVTYPE_SAM9G45:
+ nr_channels = 8;
+ dma_cap_set(DMA_SLAVE, cap_mask);
+ break;
+ default:
return -EINVAL;
+ }
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!io)
@@ -1215,14 +1241,15 @@ static int __init at_dma_probe(struct platform_device *pdev)
return irq;
size = sizeof(struct at_dma);
- size += pdata->nr_channels * sizeof(struct at_dma_chan);
+ size += nr_channels * sizeof(struct at_dma_chan);
atdma = kzalloc(size, GFP_KERNEL);
if (!atdma)
return -ENOMEM;
- /* discover transaction capabilites from the platform data */
- atdma->dma_common.cap_mask = pdata->cap_mask;
- atdma->all_chan_mask = (1 << pdata->nr_channels) - 1;
+ /* discover transaction capabilites */
+ atdma->dma_common.cap_mask = cap_mask;
+ atdma->all_chan_mask = (1 << nr_channels) - 1;
+ atdma->devtype = atdmatype;
size = resource_size(io);
if (!request_mem_region(io->start, size, pdev->dev.driver->name)) {
@@ -1268,7 +1295,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
/* initialize channels related values */
INIT_LIST_HEAD(&atdma->dma_common.channels);
- for (i = 0; i < pdata->nr_channels; i++) {
+ for (i = 0; i < nr_channels; i++) {
struct at_dma_chan *atchan = &atdma->chan[i];
atchan->chan_common.device = &atdma->dma_common;
@@ -1313,7 +1340,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "",
- pdata->nr_channels);
+ nr_channels);
dma_async_device_register(&atdma->dma_common);
@@ -1495,6 +1522,7 @@ static const struct dev_pm_ops at_dma_dev_pm_ops = {
static struct platform_driver at_dma_driver = {
.remove = __exit_p(at_dma_remove),
.shutdown = at_dma_shutdown,
+ .id_table = atdma_devtypes,
.driver = {
.name = "at_hdmac",
.pm = &at_dma_dev_pm_ops,
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index aa4c9ae..d7d6737 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -248,9 +248,16 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
/*-- Controller ------------------------------------------------------*/
+enum atdma_devtype {
+ ATDMA_DEVTYPE_UNDEFINED = 0,
+ ATDMA_DEVTYPE_SAM9RL, /* compatible with SAM9RL DMA controller */
+ ATDMA_DEVTYPE_SAM9G45, /* compatible with SAM9G45 DMA controller */
+};
+
/**
* struct at_dma - internal representation of an Atmel HDMA Controller
* @chan_common: common dmaengine dma_device object members
+ * @atdma_devtype: identifier of DMA controller compatibility
* @ch_regs: memory mapped register base
* @clk: dma controller clock
* @save_imr: interrupt mask register that is saved on suspend/resume cycle
@@ -260,6 +267,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
*/
struct at_dma {
struct dma_device dma_common;
+ enum atdma_devtype devtype;
void __iomem *regs;
struct clk *clk;
u32 save_imr;
--
1.7.5.4
^ 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