From 3d53ceeca7bae807e5aba0935347f3757127a821 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 4 Mar 2013 17:15:19 -0800 Subject: ARM: smp: Remove duplicate dummy timer implementation Drop ARM's version of the dummy timer now that we have a generic implementation in drivers/clocksource. Acked-by: Marc Zyngier Cc: Russell King Signed-off-by: Stephen Boyd --- arch/arm/kernel/smp.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 47ab90563bf..4dc883a77ad 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -503,24 +503,6 @@ void tick_broadcast(const struct cpumask *mask) } #endif -static void broadcast_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ -} - -static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) -{ - evt->name = "dummy_timer"; - evt->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_DUMMY; - evt->rating = 100; - evt->mult = 1; - evt->set_mode = broadcast_timer_set_mode; - - clockevents_register_device(evt); -} - static struct local_timer_ops *lt_ops; #ifdef CONFIG_LOCAL_TIMERS @@ -544,8 +526,8 @@ static void __cpuinit percpu_timer_setup(void) evt->cpumask = cpumask_of(cpu); - if (!lt_ops || lt_ops->setup(evt)) - broadcast_timer_setup(evt); + if (lt_ops) + lt_ops->setup(evt); } #ifdef CONFIG_HOTPLUG_CPU -- cgit v1.2.3-70-g09d2 From a894fcc2d01a89e6fe3da0845a4d80a5312e1124 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 15 Feb 2013 16:02:20 -0800 Subject: ARM: smp_twd: Divorce smp_twd from local timer API Separate the smp_twd timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource. Tested-by: Mark Rutland Acked-by: Marc Zyngier Cc: Russell King Cc: Tony Lindgren Signed-off-by: Stephen Boyd --- arch/arm/Kconfig | 2 +- arch/arm/kernel/smp_twd.c | 64 ++++++++++++++++++++++++++++-------------- arch/arm/mach-highbank/Kconfig | 2 +- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-omap2/Kconfig | 2 +- arch/arm/mach-realview/Kconfig | 8 +++--- arch/arm/mach-spear/Kconfig | 2 +- arch/arm/mach-tegra/Kconfig | 2 +- arch/arm/mach-ux500/Kconfig | 2 +- arch/arm/mach-vexpress/Kconfig | 2 +- arch/arm/mach-zynq/Kconfig | 2 +- 11 files changed, 56 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 53d3a356f61..374a1d8900e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -638,7 +638,7 @@ config ARCH_SHMOBILE select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_CLK select HAVE_MACH_CLKDEV select HAVE_SMP diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 90525d9d290..aac1495b44d 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,6 @@ #include #include -#include /* set up by the platform code */ static void __iomem *twd_base; @@ -33,7 +33,7 @@ static struct clk *twd_clk; static unsigned long twd_timer_rate; static DEFINE_PER_CPU(bool, percpu_setup_called); -static struct clock_event_device __percpu **twd_evt; +static struct clock_event_device __percpu *twd_evt; static int twd_ppi; static void twd_set_mode(enum clock_event_mode mode, @@ -90,8 +90,10 @@ static int twd_timer_ack(void) return 0; } -static void twd_timer_stop(struct clock_event_device *clk) +static void twd_timer_stop(void) { + struct clock_event_device *clk = __this_cpu_ptr(twd_evt); + twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk); disable_percpu_irq(clk->irq); } @@ -106,7 +108,7 @@ static void twd_update_frequency(void *new_rate) { twd_timer_rate = *((unsigned long *) new_rate); - clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate); + clockevents_update_freq(__this_cpu_ptr(twd_evt), twd_timer_rate); } static int twd_rate_change(struct notifier_block *nb, @@ -132,7 +134,7 @@ static struct notifier_block twd_clk_nb = { static int twd_clk_init(void) { - if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk)) + if (twd_evt && __this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk)) return clk_notifier_register(twd_clk, &twd_clk_nb); return 0; @@ -151,7 +153,7 @@ static void twd_update_frequency(void *data) { twd_timer_rate = clk_get_rate(twd_clk); - clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate); + clockevents_update_freq(__this_cpu_ptr(twd_evt), twd_timer_rate); } static int twd_cpufreq_transition(struct notifier_block *nb, @@ -177,7 +179,7 @@ static struct notifier_block twd_cpufreq_nb = { static int twd_cpufreq_init(void) { - if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk)) + if (twd_evt && __this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk)) return cpufreq_register_notifier(&twd_cpufreq_nb, CPUFREQ_TRANSITION_NOTIFIER); @@ -228,7 +230,7 @@ static void __cpuinit twd_calibrate_rate(void) static irqreturn_t twd_handler(int irq, void *dev_id) { - struct clock_event_device *evt = *(struct clock_event_device **)dev_id; + struct clock_event_device *evt = dev_id; if (twd_timer_ack()) { evt->event_handler(evt); @@ -265,9 +267,9 @@ static void twd_get_clock(struct device_node *np) /* * Setup the local clock events for a CPU. */ -static int __cpuinit twd_timer_setup(struct clock_event_device *clk) +static void __cpuinit twd_timer_setup(void) { - struct clock_event_device **this_cpu_clk; + struct clock_event_device *clk = __this_cpu_ptr(twd_evt); int cpu = smp_processor_id(); /* @@ -276,9 +278,9 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk) */ if (per_cpu(percpu_setup_called, cpu)) { __raw_writel(0, twd_base + TWD_TIMER_CONTROL); - clockevents_register_device(*__this_cpu_ptr(twd_evt)); + clockevents_register_device(clk); enable_percpu_irq(clk->irq, 0); - return 0; + return; } per_cpu(percpu_setup_called, cpu) = true; @@ -297,27 +299,37 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->set_mode = twd_set_mode; clk->set_next_event = twd_set_next_event; clk->irq = twd_ppi; - - this_cpu_clk = __this_cpu_ptr(twd_evt); - *this_cpu_clk = clk; + clk->cpumask = cpumask_of(cpu); clockevents_config_and_register(clk, twd_timer_rate, 0xf, 0xffffffff); enable_percpu_irq(clk->irq, 0); +} - return 0; +static int __cpuinit twd_timer_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + twd_timer_setup(); + break; + case CPU_DYING: + twd_timer_stop(); + break; + } + + return NOTIFY_OK; } -static struct local_timer_ops twd_lt_ops __cpuinitdata = { - .setup = twd_timer_setup, - .stop = twd_timer_stop, +static struct notifier_block twd_timer_cpu_nb __cpuinitdata = { + .notifier_call = twd_timer_cpu_notify, }; static int __init twd_local_timer_common_register(struct device_node *np) { int err; - twd_evt = alloc_percpu(struct clock_event_device *); + twd_evt = alloc_percpu(struct clock_event_device); if (!twd_evt) { err = -ENOMEM; goto out_free; @@ -329,12 +341,22 @@ static int __init twd_local_timer_common_register(struct device_node *np) goto out_free; } - err = local_timer_register(&twd_lt_ops); + err = register_cpu_notifier(&twd_timer_cpu_nb); if (err) goto out_irq; twd_get_clock(np); + /* + * Immediately configure the timer on the boot CPU, unless we need + * jiffies to be incrementing to calibrate the rate in which case + * setup the timer in late_time_init. + */ + if (twd_timer_rate) + twd_timer_setup(); + else + late_time_init = twd_timer_setup; + return 0; out_irq: diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig index cd9fcb1cd7a..6acbdabf622 100644 --- a/arch/arm/mach-highbank/Kconfig +++ b/arch/arm/mach-highbank/Kconfig @@ -12,7 +12,7 @@ config ARCH_HIGHBANK select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select MAILBOX select PL320_MBOX diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index ba44328464f..c8adc79028b 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -798,7 +798,7 @@ config SOC_IMX6Q select COMMON_CLK select CPU_V7 select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_CAN_FLEXCAN if CAN select HAVE_IMX_ANATOP select HAVE_IMX_GPC diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index f49cd51e162..edb950a1af0 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -90,7 +90,7 @@ config ARCH_OMAP4 select CACHE_L2X0 select CPU_V7 select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select LOCAL_TIMERS if SMP select OMAP_INTERCONNECT diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index d210c0f9c2c..9db2029aa63 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -13,7 +13,7 @@ config REALVIEW_EB_A9MP depends on MACH_REALVIEW_EB select CPU_V7 select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help @@ -26,7 +26,7 @@ config REALVIEW_EB_ARM11MP select ARCH_HAS_BARRIERS if SMP select CPU_V6K select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help @@ -48,7 +48,7 @@ config MACH_REALVIEW_PB11MP select ARM_GIC select CPU_V6K select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_PATA_PLATFORM select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 @@ -92,7 +92,7 @@ config MACH_REALVIEW_PBX select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET select ARM_GIC select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_PATA_PLATFORM select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig index 442917eedff..df0d59afeb4 100644 --- a/arch/arm/mach-spear/Kconfig +++ b/arch/arm/mach-spear/Kconfig @@ -23,7 +23,7 @@ config ARCH_SPEAR13XX select CPU_V7 select GPIO_SPEAR_SPICS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select PINCTRL diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 84d72fc36df..1f3ea1f6ced 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -8,7 +8,7 @@ config ARCH_TEGRA select COMMON_CLK select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_CLK select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 6a4387e39df..0614ee2b052 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -8,7 +8,7 @@ config ARCH_U8500 select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 5907e10c37f..5bfdd73dea1 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -10,7 +10,7 @@ config ARCH_VEXPRESS select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_CLK select HAVE_PATA_PLATFORM select HAVE_SMP diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index c1d61f281e6..04f8a4a6e75 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -6,7 +6,7 @@ config ARCH_ZYNQ select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select ICST select MIGHT_HAVE_CACHE_L2X0 select USE_OF -- cgit v1.2.3-70-g09d2 From ef3160cd2f0a400751f2cf6fd2811225fee1d5a7 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 4 Mar 2013 19:24:35 -0800 Subject: ARM: OMAP2+: Divorce from local timer API Now that the TWD doesn't rely on the local timer API, OMAP can stop selecting it in Kconfig and relying on the config option to decide if it should call smp_twd functions. Acked-by: Santosh Shilimkar Acked-by: Tony Lindgren Acked-by: Marc Zyngier Signed-off-by: Stephen Boyd --- arch/arm/mach-omap2/Kconfig | 1 - arch/arm/mach-omap2/timer.c | 7 ------- 2 files changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index edb950a1af0..4e0049a6060 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -92,7 +92,6 @@ config ARCH_OMAP4 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP select HAVE_SMP - select LOCAL_TIMERS if SMP select OMAP_INTERCONNECT select PL310_ERRATA_588369 select PL310_ERRATA_727915 diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 4c069b0cab2..3b7cabacbcf 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -600,7 +600,6 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", #endif #ifdef CONFIG_ARCH_OMAP4 -#ifdef CONFIG_LOCAL_TIMERS static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); void __init omap4_local_timer_init(void) { @@ -619,12 +618,6 @@ void __init omap4_local_timer_init(void) pr_err("twd_local_timer_register failed %d\n", err); } } -#else /* CONFIG_LOCAL_TIMERS */ -void __init omap4_local_timer_init(void) -{ - omap4_sync32k_timer_init(); -} -#endif /* CONFIG_LOCAL_TIMERS */ #endif /* CONFIG_ARCH_OMAP4 */ #ifdef CONFIG_SOC_OMAP5 -- cgit v1.2.3-70-g09d2 From 4d70c59bb5be9e41a06b9f11ecfba75c14f9fea7 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 15 Feb 2013 17:31:31 -0800 Subject: ARM: msm: Divorce msm_timer from local timer API Separate the msm_timer from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource. Acked-by: David Brown Acked-by: Marc Zyngier Cc: Daniel Walker Cc: Bryan Huntsman Signed-off-by: Stephen Boyd --- arch/arm/mach-msm/timer.c | 126 +++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 56 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index b6418fd5fe0..dacdcfdbc34 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -26,7 +27,6 @@ #include #include -#include #include "common.h" @@ -49,7 +49,7 @@ static void __iomem *sts_base; static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = *(struct clock_event_device **)dev_id; + struct clock_event_device *evt = dev_id; /* Stop the timer tick */ if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); @@ -101,18 +101,7 @@ static void msm_timer_set_mode(enum clock_event_mode mode, writel_relaxed(ctrl, event_base + TIMER_ENABLE); } -static struct clock_event_device msm_clockevent = { - .name = "gp_timer", - .features = CLOCK_EVT_FEAT_ONESHOT, - .rating = 200, - .set_next_event = msm_timer_set_next_event, - .set_mode = msm_timer_set_mode, -}; - -static union { - struct clock_event_device *evt; - struct clock_event_device * __percpu *percpu_evt; -} msm_evt; +static struct clock_event_device __percpu *msm_evt; static void __iomem *source_base; @@ -138,37 +127,65 @@ static struct clocksource msm_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -#ifdef CONFIG_LOCAL_TIMERS +static int msm_timer_irq; +static int msm_timer_has_ppi; + static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt) { - /* Use existing clock_event for cpu 0 */ - if (!smp_processor_id()) - return 0; - - evt->irq = msm_clockevent.irq; - evt->name = "local_timer"; - evt->features = msm_clockevent.features; - evt->rating = msm_clockevent.rating; + int cpu = smp_processor_id(); + int err; + + evt->irq = msm_timer_irq; + evt->name = "msm_timer"; + evt->features = CLOCK_EVT_FEAT_ONESHOT; + evt->rating = 200; evt->set_mode = msm_timer_set_mode; evt->set_next_event = msm_timer_set_next_event; + evt->cpumask = cpumask_of(cpu); + + clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff); + + if (msm_timer_has_ppi) { + enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); + } else { + err = request_irq(evt->irq, msm_timer_interrupt, + IRQF_TIMER | IRQF_NOBALANCING | + IRQF_TRIGGER_RISING, "gp_timer", evt); + if (err) + pr_err("request_irq failed\n"); + } - *__this_cpu_ptr(msm_evt.percpu_evt) = evt; - clockevents_config_and_register(evt, GPT_HZ, 4, 0xf0000000); - enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); return 0; } -static void msm_local_timer_stop(struct clock_event_device *evt) +static void __cpuinit msm_local_timer_stop(struct clock_event_device *evt) { evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); disable_percpu_irq(evt->irq); } -static struct local_timer_ops msm_local_timer_ops __cpuinitdata = { - .setup = msm_local_timer_setup, - .stop = msm_local_timer_stop, +static int __cpuinit msm_timer_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + /* + * Grab cpu pointer in each case to avoid spurious + * preemptible warnings + */ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + msm_local_timer_setup(this_cpu_ptr(msm_evt)); + break; + case CPU_DYING: + msm_local_timer_stop(this_cpu_ptr(msm_evt)); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block msm_timer_cpu_nb __cpuinitdata = { + .notifier_call = msm_timer_cpu_notify, }; -#endif /* CONFIG_LOCAL_TIMERS */ static notrace u32 msm_sched_clock_read(void) { @@ -178,38 +195,35 @@ static notrace u32 msm_sched_clock_read(void) static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, bool percpu) { - struct clock_event_device *ce = &msm_clockevent; struct clocksource *cs = &msm_clocksource; - int res; + int res = 0; + + msm_timer_irq = irq; + msm_timer_has_ppi = percpu; + + msm_evt = alloc_percpu(struct clock_event_device); + if (!msm_evt) { + pr_err("memory allocation failed for clockevents\n"); + goto err; + } - ce->cpumask = cpumask_of(0); - ce->irq = irq; + if (percpu) + res = request_percpu_irq(irq, msm_timer_interrupt, + "gp_timer", msm_evt); - clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff); - if (percpu) { - msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); - if (!msm_evt.percpu_evt) { - pr_err("memory allocation failed for %s\n", ce->name); + if (res) { + pr_err("request_percpu_irq failed\n"); + } else { + res = register_cpu_notifier(&msm_timer_cpu_nb); + if (res) { + free_percpu_irq(irq, msm_evt); goto err; } - *__this_cpu_ptr(msm_evt.percpu_evt) = ce; - res = request_percpu_irq(ce->irq, msm_timer_interrupt, - ce->name, msm_evt.percpu_evt); - if (!res) { - enable_percpu_irq(ce->irq, IRQ_TYPE_EDGE_RISING); -#ifdef CONFIG_LOCAL_TIMERS - local_timer_register(&msm_local_timer_ops); -#endif - } - } else { - msm_evt.evt = ce; - res = request_irq(ce->irq, msm_timer_interrupt, - IRQF_TIMER | IRQF_NOBALANCING | - IRQF_TRIGGER_RISING, ce->name, &msm_evt.evt); + + /* Immediately configure the timer on the boot CPU */ + msm_local_timer_setup(__this_cpu_ptr(msm_evt)); } - if (res) - pr_err("request_irq failed for %s\n", ce->name); err: writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); res = clocksource_register_hz(cs, dgt_hz); -- cgit v1.2.3-70-g09d2 From 060fd3043e5e3488504b9e70182e188dd9113aea Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 15 Feb 2013 17:35:19 -0800 Subject: ARM: smp: Remove local timer API There are no more users of this API, remove it. Acked-by: Tony Lindgren Acked-by: Marc Zyngier Cc: Russell King Signed-off-by: Stephen Boyd --- arch/arm/Kconfig | 10 ------ arch/arm/include/asm/localtimer.h | 34 ------------------- arch/arm/kernel/smp.c | 69 --------------------------------------- 3 files changed, 113 deletions(-) delete mode 100644 arch/arm/include/asm/localtimer.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 374a1d8900e..46fa8809163 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1544,16 +1544,6 @@ config ARM_PSCI 0022A ("Power State Coordination Interface System Software on ARM processors"). -config LOCAL_TIMERS - bool "Use local timer interrupts" - depends on SMP - default y - help - Enable support for local timers on SMP platforms, rather then the - legacy IPI broadcast method. Local timers allows the system - accounting to be spread across the timer interval, preventing a - "thundering herd" at every timer tick. - # The GPIO number here must be sorted by descending number. In case of # a multiplatform kernel, we just want the highest value required by the # selected platforms. diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h deleted file mode 100644 index f77ffc1eb0c..00000000000 --- a/arch/arm/include/asm/localtimer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * arch/arm/include/asm/localtimer.h - * - * Copyright (C) 2004-2005 ARM Ltd. - * - * 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. - */ -#ifndef __ASM_ARM_LOCALTIMER_H -#define __ASM_ARM_LOCALTIMER_H - -#include - -struct clock_event_device; - -struct local_timer_ops { - int (*setup)(struct clock_event_device *); - void (*stop)(struct clock_event_device *); -}; - -#ifdef CONFIG_LOCAL_TIMERS -/* - * Register a local timer driver - */ -int local_timer_register(struct local_timer_ops *); -#else -static inline int local_timer_register(struct local_timer_ops *ops) -{ - return -ENXIO; -} -#endif - -#endif diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 4dc883a77ad..54aa994c4b2 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -133,8 +132,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) } #ifdef CONFIG_HOTPLUG_CPU -static void percpu_timer_stop(void); - static int platform_cpu_kill(unsigned int cpu) { if (smp_ops.cpu_kill) @@ -177,11 +174,6 @@ int __cpuinit __cpu_disable(void) */ migrate_irqs(); - /* - * Stop the local timer for this CPU. - */ - percpu_timer_stop(); - /* * Flush user cache and TLB mappings, and then remove this CPU * from the vm mask set of all processes. @@ -303,8 +295,6 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) store_cpu_topology(cpuid); } -static void percpu_timer_setup(void); - /* * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. @@ -359,11 +349,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) set_cpu_online(cpu, true); complete(&cpu_running); - /* - * Setup the percpu timer for this CPU. - */ - percpu_timer_setup(); - local_irq_enable(); local_fiq_enable(); @@ -409,12 +394,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (max_cpus > ncores) max_cpus = ncores; if (ncores > 1 && max_cpus) { - /* - * Enable the local timer or broadcast device for the - * boot CPU, but only if we have more than one CPU. - */ - percpu_timer_setup(); - /* * Initialise the present map, which describes the set of CPUs * actually populated at the present time. A platform should @@ -491,11 +470,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu) return sum; } -/* - * Timer (local or broadcast) support - */ -static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); - #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST void tick_broadcast(const struct cpumask *mask) { @@ -503,49 +477,6 @@ void tick_broadcast(const struct cpumask *mask) } #endif -static struct local_timer_ops *lt_ops; - -#ifdef CONFIG_LOCAL_TIMERS -int local_timer_register(struct local_timer_ops *ops) -{ - if (!is_smp() || !setup_max_cpus) - return -ENXIO; - - if (lt_ops) - return -EBUSY; - - lt_ops = ops; - return 0; -} -#endif - -static void __cpuinit percpu_timer_setup(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - - evt->cpumask = cpumask_of(cpu); - - if (lt_ops) - lt_ops->setup(evt); -} - -#ifdef CONFIG_HOTPLUG_CPU -/* - * The generic clock events code purposely does not stop the local timer - * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it - * manually here. - */ -static void percpu_timer_stop(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - - if (lt_ops) - lt_ops->stop(evt); -} -#endif - static DEFINE_RAW_SPINLOCK(stop_lock); /* -- cgit v1.2.3-70-g09d2 From f825c736e75b11adb59ec52a4a1096efddd2ec97 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 2 Jul 2013 11:15:15 +0530 Subject: mm/cma: Move dma contiguous changes into a seperate config We want to use CMA for allocating hash page table and real mode area for PPC64. Hence move DMA contiguous related changes into a seperate config so that ppc64 can enable CMA without requiring DMA contiguous. Acked-by: Michal Nazarewicz Acked-by: Paul Mackerras Signed-off-by: Aneesh Kumar K.V [removed defconfig changes] Signed-off-by: Marek Szyprowski --- arch/arm/include/asm/dma-contiguous.h | 2 +- arch/arm/mm/dma-mapping.c | 6 +++--- drivers/base/Kconfig | 20 ++++---------------- drivers/base/Makefile | 2 +- include/linux/dma-contiguous.h | 2 +- mm/Kconfig | 24 ++++++++++++++++++++++++ 6 files changed, 34 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h index 3ed37b4d93d..e072bb2ba1b 100644 --- a/arch/arm/include/asm/dma-contiguous.h +++ b/arch/arm/include/asm/dma-contiguous.h @@ -2,7 +2,7 @@ #define ASMARM_DMA_CONTIGUOUS_H #ifdef __KERNEL__ -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA #include #include diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index ef3e0f3aac9..1fb40dc37ec 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -358,7 +358,7 @@ static int __init atomic_pool_init(void) if (!pages) goto no_pages; - if (IS_ENABLED(CONFIG_CMA)) + if (IS_ENABLED(CONFIG_DMA_CMA)) ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, atomic_pool_init); else @@ -670,7 +670,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, addr = __alloc_simple_buffer(dev, size, gfp, &page); else if (!(gfp & __GFP_WAIT)) addr = __alloc_from_pool(size, &page); - else if (!IS_ENABLED(CONFIG_CMA)) + else if (!IS_ENABLED(CONFIG_DMA_CMA)) addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); else addr = __alloc_from_contiguous(dev, size, prot, &page, caller); @@ -759,7 +759,7 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr, __dma_free_buffer(page, size); } else if (__free_from_pool(cpu_addr, size)) { return; - } else if (!IS_ENABLED(CONFIG_CMA)) { + } else if (!IS_ENABLED(CONFIG_DMA_CMA)) { __dma_free_remap(cpu_addr, size); __dma_free_buffer(page, size); } else { diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 07abd9d76f7..10cd80af2ae 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -202,11 +202,9 @@ config DMA_SHARED_BUFFER APIs extension; the file's descriptor can then be passed on to other driver. -config CMA - bool "Contiguous Memory Allocator" - depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK - select MIGRATION - select MEMORY_ISOLATION +config DMA_CMA + bool "DMA Contiguous Memory Allocator" + depends on HAVE_DMA_CONTIGUOUS && CMA help This enables the Contiguous Memory Allocator which allows drivers to allocate big physically-contiguous blocks of memory for use with @@ -215,17 +213,7 @@ config CMA For more information see . If unsure, say "n". -if CMA - -config CMA_DEBUG - bool "CMA debug messages (DEVELOPMENT)" - depends on DEBUG_KERNEL - help - Turns on debug messages in CMA. This produces KERN_DEBUG - messages for every CMA call as well as various messages while - processing calls such as dma_alloc_from_contiguous(). - This option does not affect warning and error messages. - +if DMA_CMA comment "Default contiguous memory area size:" config CMA_SIZE_MBYTES diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 4e22ce3ed73..5d93bb51975 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -6,7 +6,7 @@ obj-y := core.o bus.o dd.o syscore.o \ attribute_container.o transport_class.o \ topology.o obj-$(CONFIG_DEVTMPFS) += devtmpfs.o -obj-$(CONFIG_CMA) += dma-contiguous.o +obj-$(CONFIG_DMA_CMA) += dma-contiguous.o obj-y += power/ obj-$(CONFIG_HAS_DMA) += dma-mapping.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h index 01b5c84be82..00141d3325f 100644 --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -57,7 +57,7 @@ struct cma; struct page; struct device; -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA /* * There is always at least global CMA area and a few optional device diff --git a/mm/Kconfig b/mm/Kconfig index e742d06285b..26a5f815cfc 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -477,3 +477,27 @@ config FRONTSWAP and swap data is stored as normal on the matching swap device. If unsure, say Y to enable frontswap. + +config CMA + bool "Contiguous Memory Allocator" + depends on HAVE_MEMBLOCK + select MIGRATION + select MEMORY_ISOLATION + help + This enables the Contiguous Memory Allocator which allows other + subsystems to allocate big physically-contiguous blocks of memory. + CMA reserves a region of memory and allows only movable pages to + be allocated from it. This way, the kernel can use the memory for + pagecache and when a subsystem requests for contiguous area, the + allocated pages are migrated away to serve the contiguous request. + + If unsure, say "n". + +config CMA_DEBUG + bool "CMA debug messages (DEVELOPMENT)" + depends on DEBUG_KERNEL && CMA + help + Turns on debug messages in CMA. This produces KERN_DEBUG + messages for every CMA call as well as various messages while + processing calls such as dma_alloc_from_contiguous(). + This option does not affect warning and error messages. -- cgit v1.2.3-70-g09d2 From f35320288c5306ddbcb5ecac046b73519837299c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 2 Jul 2013 16:15:10 +0200 Subject: KVM: PPC: Book3S: Ignore DABR register We don't emulate breakpoints yet, so just ignore reads and writes to / from DABR. This fixes booting of more recent Linux guest kernels for me. Reported-by: Nello Martuscielli Tested-by: Nello Martuscielli Signed-off-by: Alexander Graf --- arch/powerpc/kvm/book3s_emulate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 1f6344c4408..360ce68c980 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -458,6 +458,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: + case SPRN_DABR: break; unprivileged: default: @@ -555,6 +556,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: + case SPRN_DABR: *spr_val = 0; break; default: -- cgit v1.2.3-70-g09d2 From fa61a4e376d2129690c82dfb05b31705a67d6e0b Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 2 Jul 2013 11:15:16 +0530 Subject: powerpc/kvm: Contiguous memory allocator based hash page table allocation Powerpc architecture uses a hash based page table mechanism for mapping virtual addresses to physical address. The architecture require this hash page table to be physically contiguous. With KVM on Powerpc currently we use early reservation mechanism for allocating guest hash page table. This implies that we need to reserve a big memory region to ensure we can create large number of guest simultaneously with KVM on Power. Another disadvantage is that the reserved memory is not available to rest of the subsystems and and that implies we limit the total available memory in the host. This patch series switch the guest hash page table allocation to use contiguous memory allocator. Signed-off-by: Aneesh Kumar K.V Acked-by: Paul Mackerras Signed-off-by: Alexander Graf --- arch/powerpc/include/asm/kvm_book3s_64.h | 1 - arch/powerpc/include/asm/kvm_host.h | 2 +- arch/powerpc/include/asm/kvm_ppc.h | 8 +- arch/powerpc/kernel/setup_64.c | 2 + arch/powerpc/kvm/Kconfig | 1 + arch/powerpc/kvm/Makefile | 1 + arch/powerpc/kvm/book3s_64_mmu_hv.c | 37 +++-- arch/powerpc/kvm/book3s_hv_builtin.c | 91 +++++++++---- arch/powerpc/kvm/book3s_hv_cma.c | 227 +++++++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_hv_cma.h | 22 +++ 10 files changed, 341 insertions(+), 51 deletions(-) create mode 100644 arch/powerpc/kvm/book3s_hv_cma.c create mode 100644 arch/powerpc/kvm/book3s_hv_cma.h (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 9c1ff330c80..f8355a902ac 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -37,7 +37,6 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) #ifdef CONFIG_KVM_BOOK3S_64_HV #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ -extern int kvm_hpt_order; /* order of preallocated HPTs */ #endif #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index af326cde7cb..0097dab3d60 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -259,7 +259,7 @@ struct kvm_arch { spinlock_t slot_phys_lock; cpumask_t need_tlb_flush; struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; - struct kvmppc_linear_info *hpt_li; + int hpt_cma_alloc; #endif /* CONFIG_KVM_BOOK3S_64_HV */ #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a5287fe03d7..b5ef7a3c606 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -139,8 +139,8 @@ extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *rma); extern struct kvmppc_linear_info *kvm_alloc_rma(void); extern void kvm_release_rma(struct kvmppc_linear_info *ri); -extern struct kvmppc_linear_info *kvm_alloc_hpt(void); -extern void kvm_release_hpt(struct kvmppc_linear_info *li); +extern struct page *kvm_alloc_hpt(unsigned long nr_pages); +extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); extern int kvmppc_core_init_vm(struct kvm *kvm); extern void kvmppc_core_destroy_vm(struct kvm *kvm); extern void kvmppc_core_free_memslot(struct kvm_memory_slot *free, @@ -261,6 +261,7 @@ void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); struct openpic; #ifdef CONFIG_KVM_BOOK3S_64_HV +extern void kvm_cma_reserve(void) __init; static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) { paca[cpu].kvm_hstate.xics_phys = addr; @@ -284,6 +285,9 @@ extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu); extern void kvm_linear_init(void); #else +static inline void __init kvm_cma_reserve(void) +{} + static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) {} diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index e379d3fd169..ee28d1f4b85 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -229,6 +229,8 @@ void __init early_setup(unsigned long dt_ptr) /* Initialize the hash table or TLB handling */ early_init_mmu(); + kvm_cma_reserve(); + /* * Reserve any gigantic pages requested on the command line. * memblock needs to have been initialized by the time this is diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index eb643f86257..ffaef2cb101 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -72,6 +72,7 @@ config KVM_BOOK3S_64_HV bool "KVM support for POWER7 and PPC970 using hypervisor mode in host" depends on KVM_BOOK3S_64 select MMU_NOTIFIER + select CMA ---help--- Support running unmodified book3s_64 guest kernels in virtual machines on POWER7 and PPC970 processors that have diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 008cd856c5b..6646c952c5e 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -81,6 +81,7 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ book3s_64_vio_hv.o \ book3s_hv_ras.o \ book3s_hv_builtin.o \ + book3s_hv_cma.o \ $(kvm-book3s_64-builtin-xics-objs-y) kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 5880dfb3107..354f4bb21f5 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -52,8 +52,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) { unsigned long hpt; struct revmap_entry *rev; - struct kvmppc_linear_info *li; - long order = kvm_hpt_order; + struct page *page = NULL; + long order = KVM_DEFAULT_HPT_ORDER; if (htab_orderp) { order = *htab_orderp; @@ -61,26 +61,22 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) order = PPC_MIN_HPT_ORDER; } + kvm->arch.hpt_cma_alloc = 0; /* - * If the user wants a different size from default, * try first to allocate it from the kernel page allocator. + * We keep the CMA reserved for failed allocation. */ - hpt = 0; - if (order != kvm_hpt_order) { - hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| - __GFP_NOWARN, order - PAGE_SHIFT); - if (!hpt) - --order; - } + hpt = __get_free_pages(GFP_KERNEL | __GFP_ZERO | __GFP_REPEAT | + __GFP_NOWARN, order - PAGE_SHIFT); /* Next try to allocate from the preallocated pool */ if (!hpt) { - li = kvm_alloc_hpt(); - if (li) { - hpt = (ulong)li->base_virt; - kvm->arch.hpt_li = li; - order = kvm_hpt_order; - } + page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT)); + if (page) { + hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); + kvm->arch.hpt_cma_alloc = 1; + } else + --order; } /* Lastly try successively smaller sizes from the page allocator */ @@ -118,8 +114,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) return 0; out_freehpt: - if (kvm->arch.hpt_li) - kvm_release_hpt(kvm->arch.hpt_li); + if (kvm->arch.hpt_cma_alloc) + kvm_release_hpt(page, 1 << (order - PAGE_SHIFT)); else free_pages(hpt, order - PAGE_SHIFT); return -ENOMEM; @@ -165,8 +161,9 @@ void kvmppc_free_hpt(struct kvm *kvm) { kvmppc_free_lpid(kvm->arch.lpid); vfree(kvm->arch.revmap); - if (kvm->arch.hpt_li) - kvm_release_hpt(kvm->arch.hpt_li); + if (kvm->arch.hpt_cma_alloc) + kvm_release_hpt(virt_to_page(kvm->arch.hpt_virt), + 1 << (kvm->arch.hpt_order - PAGE_SHIFT)); else free_pages(kvm->arch.hpt_virt, kvm->arch.hpt_order - PAGE_SHIFT); diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index ec0a9e5de10..4b865c55333 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -13,20 +13,30 @@ #include #include #include +#include +#include #include #include #include +#include "book3s_hv_cma.h" + #define KVM_LINEAR_RMA 0 #define KVM_LINEAR_HPT 1 static void __init kvm_linear_init_one(ulong size, int count, int type); static struct kvmppc_linear_info *kvm_alloc_linear(int type); static void kvm_release_linear(struct kvmppc_linear_info *ri); - -int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; -EXPORT_SYMBOL_GPL(kvm_hpt_order); +/* + * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) + * should be power of 2. + */ +#define HPT_ALIGN_PAGES ((1 << 18) >> PAGE_SHIFT) /* 256k */ +/* + * By default we reserve 5% of memory for hash pagetable allocation. + */ +static unsigned long kvm_cma_resv_ratio = 5; /*************** RMA *************/ @@ -101,36 +111,29 @@ void kvm_release_rma(struct kvmppc_linear_info *ri) } EXPORT_SYMBOL_GPL(kvm_release_rma); -/*************** HPT *************/ - -/* - * This maintains a list of big linear HPT tables that contain the GVA->HPA - * memory mappings. If we don't reserve those early on, we might not be able - * to get a big (usually 16MB) linear memory region from the kernel anymore. - */ - -static unsigned long kvm_hpt_count; - -static int __init early_parse_hpt_count(char *p) +static int __init early_parse_kvm_cma_resv(char *p) { + pr_debug("%s(%s)\n", __func__, p); if (!p) - return 1; - - kvm_hpt_count = simple_strtoul(p, NULL, 0); - - return 0; + return -EINVAL; + return kstrtoul(p, 0, &kvm_cma_resv_ratio); } -early_param("kvm_hpt_count", early_parse_hpt_count); +early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv); -struct kvmppc_linear_info *kvm_alloc_hpt(void) +struct page *kvm_alloc_hpt(unsigned long nr_pages) { - return kvm_alloc_linear(KVM_LINEAR_HPT); + unsigned long align_pages = HPT_ALIGN_PAGES; + + /* Old CPUs require HPT aligned on a multiple of its size */ + if (!cpu_has_feature(CPU_FTR_ARCH_206)) + align_pages = nr_pages; + return kvm_alloc_cma(nr_pages, align_pages); } EXPORT_SYMBOL_GPL(kvm_alloc_hpt); -void kvm_release_hpt(struct kvmppc_linear_info *li) +void kvm_release_hpt(struct page *page, unsigned long nr_pages) { - kvm_release_linear(li); + kvm_release_cma(page, nr_pages); } EXPORT_SYMBOL_GPL(kvm_release_hpt); @@ -211,9 +214,6 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri) */ void __init kvm_linear_init(void) { - /* HPT */ - kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT); - /* RMA */ /* Only do this on PPC970 in HV mode */ if (!cpu_has_feature(CPU_FTR_HVMODE) || @@ -231,3 +231,40 @@ void __init kvm_linear_init(void) kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA); } + +/** + * kvm_cma_reserve() - reserve area for kvm hash pagetable + * + * This function reserves memory from early allocator. It should be + * called by arch specific code once the early allocator (memblock or bootmem) + * has been activated and all other subsystems have already allocated/reserved + * memory. + */ +void __init kvm_cma_reserve(void) +{ + unsigned long align_size; + struct memblock_region *reg; + phys_addr_t selected_size = 0; + /* + * We cannot use memblock_phys_mem_size() here, because + * memblock_analyze() has not been called yet. + */ + for_each_memblock(memory, reg) + selected_size += memblock_region_memory_end_pfn(reg) - + memblock_region_memory_base_pfn(reg); + + selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT; + if (selected_size) { + pr_debug("%s: reserving %ld MiB for global area\n", __func__, + (unsigned long)selected_size / SZ_1M); + /* + * Old CPUs require HPT aligned on a multiple of its size. So for them + * make the alignment as max size we could request. + */ + if (!cpu_has_feature(CPU_FTR_ARCH_206)) + align_size = __rounddown_pow_of_two(selected_size); + else + align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; + kvm_cma_declare_contiguous(selected_size, align_size); + } +} diff --git a/arch/powerpc/kvm/book3s_hv_cma.c b/arch/powerpc/kvm/book3s_hv_cma.c new file mode 100644 index 00000000000..e04b269b9c5 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_cma.c @@ -0,0 +1,227 @@ +/* + * Contiguous Memory Allocator for ppc KVM hash pagetable based on CMA + * for DMA mapping framework + * + * Copyright IBM Corporation, 2013 + * Author Aneesh Kumar K.V + * + * 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 optional) any later version of the license. + * + */ +#define pr_fmt(fmt) "kvm_cma: " fmt + +#ifdef CONFIG_CMA_DEBUG +#ifndef DEBUG +# define DEBUG +#endif +#endif + +#include +#include +#include +#include + +struct kvm_cma { + unsigned long base_pfn; + unsigned long count; + unsigned long *bitmap; +}; + +static DEFINE_MUTEX(kvm_cma_mutex); +static struct kvm_cma kvm_cma_area; + +/** + * kvm_cma_declare_contiguous() - reserve area for contiguous memory handling + * for kvm hash pagetable + * @size: Size of the reserved memory. + * @alignment: Alignment for the contiguous memory area + * + * This function reserves memory for kvm cma area. It should be + * called by arch code when early allocator (memblock or bootmem) + * is still activate. + */ +long __init kvm_cma_declare_contiguous(phys_addr_t size, phys_addr_t alignment) +{ + long base_pfn; + phys_addr_t addr; + struct kvm_cma *cma = &kvm_cma_area; + + pr_debug("%s(size %lx)\n", __func__, (unsigned long)size); + + if (!size) + return -EINVAL; + /* + * Sanitise input arguments. + * We should be pageblock aligned for CMA. + */ + alignment = max(alignment, (phys_addr_t)(PAGE_SIZE << pageblock_order)); + size = ALIGN(size, alignment); + /* + * Reserve memory + * Use __memblock_alloc_base() since + * memblock_alloc_base() panic()s. + */ + addr = __memblock_alloc_base(size, alignment, 0); + if (!addr) { + base_pfn = -ENOMEM; + goto err; + } else + base_pfn = PFN_DOWN(addr); + + /* + * Each reserved area must be initialised later, when more kernel + * subsystems (like slab allocator) are available. + */ + cma->base_pfn = base_pfn; + cma->count = size >> PAGE_SHIFT; + pr_info("CMA: reserved %ld MiB\n", (unsigned long)size / SZ_1M); + return 0; +err: + pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M); + return base_pfn; +} + +/** + * kvm_alloc_cma() - allocate pages from contiguous area + * @nr_pages: Requested number of pages. + * @align_pages: Requested alignment in number of pages + * + * This function allocates memory buffer for hash pagetable. + */ +struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages) +{ + int ret; + struct page *page = NULL; + struct kvm_cma *cma = &kvm_cma_area; + unsigned long mask, pfn, pageno, start = 0; + + + if (!cma || !cma->count) + return NULL; + + pr_debug("%s(cma %p, count %lu, align pages %lu)\n", __func__, + (void *)cma, nr_pages, align_pages); + + if (!nr_pages) + return NULL; + + VM_BUG_ON(!is_power_of_2(align_pages)); + mask = align_pages - 1; + + mutex_lock(&kvm_cma_mutex); + for (;;) { + pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count, + start, nr_pages, mask); + if (pageno >= cma->count) + break; + + pfn = cma->base_pfn + pageno; + ret = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_CMA); + if (ret == 0) { + bitmap_set(cma->bitmap, pageno, nr_pages); + page = pfn_to_page(pfn); + memset(pfn_to_kaddr(pfn), 0, nr_pages << PAGE_SHIFT); + break; + } else if (ret != -EBUSY) { + break; + } + pr_debug("%s(): memory range at %p is busy, retrying\n", + __func__, pfn_to_page(pfn)); + /* try again with a bit different memory target */ + start = pageno + mask + 1; + } + mutex_unlock(&kvm_cma_mutex); + pr_debug("%s(): returned %p\n", __func__, page); + return page; +} + +/** + * kvm_release_cma() - release allocated pages for hash pagetable + * @pages: Allocated pages. + * @nr_pages: Number of allocated pages. + * + * This function releases memory allocated by kvm_alloc_cma(). + * It returns false when provided pages do not belong to contiguous area and + * true otherwise. + */ +bool kvm_release_cma(struct page *pages, unsigned long nr_pages) +{ + unsigned long pfn; + struct kvm_cma *cma = &kvm_cma_area; + + + if (!cma || !pages) + return false; + + pr_debug("%s(page %p count %lu)\n", __func__, (void *)pages, nr_pages); + + pfn = page_to_pfn(pages); + + if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count) + return false; + + VM_BUG_ON(pfn + nr_pages > cma->base_pfn + cma->count); + + mutex_lock(&kvm_cma_mutex); + bitmap_clear(cma->bitmap, pfn - cma->base_pfn, nr_pages); + free_contig_range(pfn, nr_pages); + mutex_unlock(&kvm_cma_mutex); + + return true; +} + +static int __init kvm_cma_activate_area(unsigned long base_pfn, + unsigned long count) +{ + unsigned long pfn = base_pfn; + unsigned i = count >> pageblock_order; + struct zone *zone; + + WARN_ON_ONCE(!pfn_valid(pfn)); + zone = page_zone(pfn_to_page(pfn)); + do { + unsigned j; + base_pfn = pfn; + for (j = pageblock_nr_pages; j; --j, pfn++) { + WARN_ON_ONCE(!pfn_valid(pfn)); + /* + * alloc_contig_range requires the pfn range + * specified to be in the same zone. Make this + * simple by forcing the entire CMA resv range + * to be in the same zone. + */ + if (page_zone(pfn_to_page(pfn)) != zone) + return -EINVAL; + } + init_cma_reserved_pageblock(pfn_to_page(base_pfn)); + } while (--i); + return 0; +} + +static int __init kvm_cma_init_reserved_areas(void) +{ + int bitmap_size, ret; + struct kvm_cma *cma = &kvm_cma_area; + + pr_debug("%s()\n", __func__); + if (!cma->count) + return 0; + + bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); + cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + if (!cma->bitmap) + return -ENOMEM; + + ret = kvm_cma_activate_area(cma->base_pfn, cma->count); + if (ret) + goto error; + return 0; + +error: + kfree(cma->bitmap); + return ret; +} +core_initcall(kvm_cma_init_reserved_areas); diff --git a/arch/powerpc/kvm/book3s_hv_cma.h b/arch/powerpc/kvm/book3s_hv_cma.h new file mode 100644 index 00000000000..788bc3b7310 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_cma.h @@ -0,0 +1,22 @@ +/* + * Contiguous Memory Allocator for ppc KVM hash pagetable based on CMA + * for DMA mapping framework + * + * Copyright IBM Corporation, 2013 + * Author Aneesh Kumar K.V + * + * 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 optional) any later version of the license. + * + */ + +#ifndef __POWERPC_KVM_CMA_ALLOC_H__ +#define __POWERPC_KVM_CMA_ALLOC_H__ +extern struct page *kvm_alloc_cma(unsigned long nr_pages, + unsigned long align_pages); +extern bool kvm_release_cma(struct page *pages, unsigned long nr_pages); +extern long kvm_cma_declare_contiguous(phys_addr_t size, + phys_addr_t alignment) __init; +#endif -- cgit v1.2.3-70-g09d2 From 6c45b810989d1c04194499d666f695d3f811965f Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 2 Jul 2013 11:15:17 +0530 Subject: powerpc/kvm: Contiguous memory allocator based RMA allocation Older version of power architecture use Real Mode Offset register and Real Mode Limit Selector for mapping guest Real Mode Area. The guest RMA should be physically contigous since we use the range when address translation is not enabled. This patch switch RMA allocation code to use contigous memory allocator. The patch also remove the the linear allocator which not used any more Acked-by: Paul Mackerras Signed-off-by: Aneesh Kumar K.V Signed-off-by: Alexander Graf --- arch/powerpc/include/asm/kvm_book3s_64.h | 1 + arch/powerpc/include/asm/kvm_host.h | 12 +-- arch/powerpc/include/asm/kvm_ppc.h | 8 +- arch/powerpc/kernel/setup_64.c | 2 - arch/powerpc/kvm/book3s_hv.c | 27 +++-- arch/powerpc/kvm/book3s_hv_builtin.c | 167 ++++++++----------------------- 6 files changed, 65 insertions(+), 152 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index f8355a902ac..76ff0b5c999 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -37,6 +37,7 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) #ifdef CONFIG_KVM_BOOK3S_64_HV #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ +extern unsigned long kvm_rma_pages; #endif #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0097dab3d60..33283532e9d 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -183,13 +183,9 @@ struct kvmppc_spapr_tce_table { struct page *pages[0]; }; -struct kvmppc_linear_info { - void *base_virt; - unsigned long base_pfn; - unsigned long npages; - struct list_head list; - atomic_t use_count; - int type; +struct kvm_rma_info { + atomic_t use_count; + unsigned long base_pfn; }; /* XICS components, defined in book3s_xics.c */ @@ -246,7 +242,7 @@ struct kvm_arch { int tlbie_lock; unsigned long lpcr; unsigned long rmor; - struct kvmppc_linear_info *rma; + struct kvm_rma_info *rma; unsigned long vrma_slb_v; int rma_setup_done; int using_mmu_notifiers; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index b5ef7a3c606..5a26bfcd0bb 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -137,8 +137,8 @@ extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, unsigned long ioba, unsigned long tce); extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *rma); -extern struct kvmppc_linear_info *kvm_alloc_rma(void); -extern void kvm_release_rma(struct kvmppc_linear_info *ri); +extern struct kvm_rma_info *kvm_alloc_rma(void); +extern void kvm_release_rma(struct kvm_rma_info *ri); extern struct page *kvm_alloc_hpt(unsigned long nr_pages); extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); extern int kvmppc_core_init_vm(struct kvm *kvm); @@ -282,7 +282,6 @@ static inline void kvmppc_set_host_ipi(int cpu, u8 host_ipi) } extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu); -extern void kvm_linear_init(void); #else static inline void __init kvm_cma_reserve(void) @@ -291,9 +290,6 @@ static inline void __init kvm_cma_reserve(void) static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) {} -static inline void kvm_linear_init(void) -{} - static inline u32 kvmppc_get_xics_latch(void) { return 0; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index ee28d1f4b85..8a022f5de0e 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -611,8 +611,6 @@ void __init setup_arch(char **cmdline_p) /* Initialize the MMU context management stuff */ mmu_context_init(); - kvm_linear_init(); - /* Interrupt code needs to be 64K-aligned */ if ((unsigned long)_stext & 0xffff) panic("Kernelbase not 64K-aligned (0x%lx)!\n", diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 2efa9dde741..2b95c45e17d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1511,10 +1511,10 @@ static inline int lpcr_rmls(unsigned long rma_size) static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct kvmppc_linear_info *ri = vma->vm_file->private_data; struct page *page; + struct kvm_rma_info *ri = vma->vm_file->private_data; - if (vmf->pgoff >= ri->npages) + if (vmf->pgoff >= kvm_rma_pages) return VM_FAULT_SIGBUS; page = pfn_to_page(ri->base_pfn + vmf->pgoff); @@ -1536,7 +1536,7 @@ static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma) static int kvm_rma_release(struct inode *inode, struct file *filp) { - struct kvmppc_linear_info *ri = filp->private_data; + struct kvm_rma_info *ri = filp->private_data; kvm_release_rma(ri); return 0; @@ -1549,8 +1549,17 @@ static const struct file_operations kvm_rma_fops = { long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) { - struct kvmppc_linear_info *ri; long fd; + struct kvm_rma_info *ri; + /* + * Only do this on PPC970 in HV mode + */ + if (!cpu_has_feature(CPU_FTR_HVMODE) || + !cpu_has_feature(CPU_FTR_ARCH_201)) + return -EINVAL; + + if (!kvm_rma_pages) + return -EINVAL; ri = kvm_alloc_rma(); if (!ri) @@ -1560,7 +1569,7 @@ long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) if (fd < 0) kvm_release_rma(ri); - ret->rma_size = ri->npages << PAGE_SHIFT; + ret->rma_size = kvm_rma_pages << PAGE_SHIFT; return fd; } @@ -1725,7 +1734,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) { int err = 0; struct kvm *kvm = vcpu->kvm; - struct kvmppc_linear_info *ri = NULL; + struct kvm_rma_info *ri = NULL; unsigned long hva; struct kvm_memory_slot *memslot; struct vm_area_struct *vma; @@ -1803,7 +1812,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) } else { /* Set up to use an RMO region */ - rma_size = ri->npages; + rma_size = kvm_rma_pages; if (rma_size > memslot->npages) rma_size = memslot->npages; rma_size <<= PAGE_SHIFT; @@ -1831,14 +1840,14 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) /* POWER7 */ lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L); lpcr |= rmls << LPCR_RMLS_SH; - kvm->arch.rmor = kvm->arch.rma->base_pfn << PAGE_SHIFT; + kvm->arch.rmor = ri->base_pfn << PAGE_SHIFT; } kvm->arch.lpcr = lpcr; pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n", ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); /* Initialize phys addrs of pages in RMO */ - npages = ri->npages; + npages = kvm_rma_pages; porder = __ilog2(npages); physp = memslot->arch.slot_phys; if (physp) { diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 4b865c55333..8cd0daebb82 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -21,13 +21,6 @@ #include #include "book3s_hv_cma.h" - -#define KVM_LINEAR_RMA 0 -#define KVM_LINEAR_HPT 1 - -static void __init kvm_linear_init_one(ulong size, int count, int type); -static struct kvmppc_linear_info *kvm_alloc_linear(int type); -static void kvm_release_linear(struct kvmppc_linear_info *ri); /* * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) * should be power of 2. @@ -37,19 +30,17 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri); * By default we reserve 5% of memory for hash pagetable allocation. */ static unsigned long kvm_cma_resv_ratio = 5; - -/*************** RMA *************/ - /* - * This maintains a list of RMAs (real mode areas) for KVM guests to use. + * We allocate RMAs (real mode areas) for KVM guests from the KVM CMA area. * Each RMA has to be physically contiguous and of a size that the * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, * and other larger sizes. Since we are unlikely to be allocate that * much physically contiguous memory after the system is up and running, - * we preallocate a set of RMAs in early boot for KVM to use. + * we preallocate a set of RMAs in early boot using CMA. + * should be power of 2. */ -static unsigned long kvm_rma_size = 64 << 20; /* 64MB */ -static unsigned long kvm_rma_count; +unsigned long kvm_rma_pages = (1 << 27) >> PAGE_SHIFT; /* 128MB */ +EXPORT_SYMBOL_GPL(kvm_rma_pages); /* Work out RMLS (real mode limit selector) field value for a given RMA size. Assumes POWER7 or PPC970. */ @@ -79,35 +70,50 @@ static inline int lpcr_rmls(unsigned long rma_size) static int __init early_parse_rma_size(char *p) { - if (!p) - return 1; + unsigned long kvm_rma_size; + pr_debug("%s(%s)\n", __func__, p); + if (!p) + return -EINVAL; kvm_rma_size = memparse(p, &p); - + /* + * Check that the requested size is one supported in hardware + */ + if (lpcr_rmls(kvm_rma_size) < 0) { + pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); + return -EINVAL; + } + kvm_rma_pages = kvm_rma_size >> PAGE_SHIFT; return 0; } early_param("kvm_rma_size", early_parse_rma_size); -static int __init early_parse_rma_count(char *p) +struct kvm_rma_info *kvm_alloc_rma() { - if (!p) - return 1; - - kvm_rma_count = simple_strtoul(p, NULL, 0); - - return 0; -} -early_param("kvm_rma_count", early_parse_rma_count); - -struct kvmppc_linear_info *kvm_alloc_rma(void) -{ - return kvm_alloc_linear(KVM_LINEAR_RMA); + struct page *page; + struct kvm_rma_info *ri; + + ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); + if (!ri) + return NULL; + page = kvm_alloc_cma(kvm_rma_pages, kvm_rma_pages); + if (!page) + goto err_out; + atomic_set(&ri->use_count, 1); + ri->base_pfn = page_to_pfn(page); + return ri; +err_out: + kfree(ri); + return NULL; } EXPORT_SYMBOL_GPL(kvm_alloc_rma); -void kvm_release_rma(struct kvmppc_linear_info *ri) +void kvm_release_rma(struct kvm_rma_info *ri) { - kvm_release_linear(ri); + if (atomic_dec_and_test(&ri->use_count)) { + kvm_release_cma(pfn_to_page(ri->base_pfn), kvm_rma_pages); + kfree(ri); + } } EXPORT_SYMBOL_GPL(kvm_release_rma); @@ -137,101 +143,6 @@ void kvm_release_hpt(struct page *page, unsigned long nr_pages) } EXPORT_SYMBOL_GPL(kvm_release_hpt); -/*************** generic *************/ - -static LIST_HEAD(free_linears); -static DEFINE_SPINLOCK(linear_lock); - -static void __init kvm_linear_init_one(ulong size, int count, int type) -{ - unsigned long i; - unsigned long j, npages; - void *linear; - struct page *pg; - const char *typestr; - struct kvmppc_linear_info *linear_info; - - if (!count) - return; - - typestr = (type == KVM_LINEAR_RMA) ? "RMA" : "HPT"; - - npages = size >> PAGE_SHIFT; - linear_info = alloc_bootmem(count * sizeof(struct kvmppc_linear_info)); - for (i = 0; i < count; ++i) { - linear = alloc_bootmem_align(size, size); - pr_debug("Allocated KVM %s at %p (%ld MB)\n", typestr, linear, - size >> 20); - linear_info[i].base_virt = linear; - linear_info[i].base_pfn = __pa(linear) >> PAGE_SHIFT; - linear_info[i].npages = npages; - linear_info[i].type = type; - list_add_tail(&linear_info[i].list, &free_linears); - atomic_set(&linear_info[i].use_count, 0); - - pg = pfn_to_page(linear_info[i].base_pfn); - for (j = 0; j < npages; ++j) { - atomic_inc(&pg->_count); - ++pg; - } - } -} - -static struct kvmppc_linear_info *kvm_alloc_linear(int type) -{ - struct kvmppc_linear_info *ri, *ret; - - ret = NULL; - spin_lock(&linear_lock); - list_for_each_entry(ri, &free_linears, list) { - if (ri->type != type) - continue; - - list_del(&ri->list); - atomic_inc(&ri->use_count); - memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT); - ret = ri; - break; - } - spin_unlock(&linear_lock); - return ret; -} - -static void kvm_release_linear(struct kvmppc_linear_info *ri) -{ - if (atomic_dec_and_test(&ri->use_count)) { - spin_lock(&linear_lock); - list_add_tail(&ri->list, &free_linears); - spin_unlock(&linear_lock); - - } -} - -/* - * Called at boot time while the bootmem allocator is active, - * to allocate contiguous physical memory for the hash page - * tables for guests. - */ -void __init kvm_linear_init(void) -{ - /* RMA */ - /* Only do this on PPC970 in HV mode */ - if (!cpu_has_feature(CPU_FTR_HVMODE) || - !cpu_has_feature(CPU_FTR_ARCH_201)) - return; - - if (!kvm_rma_size || !kvm_rma_count) - return; - - /* Check that the requested size is one supported in hardware */ - if (lpcr_rmls(kvm_rma_size) < 0) { - pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); - return; - } - - kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA); -} - /** * kvm_cma_reserve() - reserve area for kvm hash pagetable * @@ -265,6 +176,8 @@ void __init kvm_cma_reserve(void) align_size = __rounddown_pow_of_two(selected_size); else align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; + + align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size); kvm_cma_declare_contiguous(selected_size, align_size); } } -- cgit v1.2.3-70-g09d2 From 990978e99359e1f3a843563b9f96f9dc7bb7c05a Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 2 Jul 2013 11:15:18 +0530 Subject: powerpc/kvm: Use 256K chunk to track both RMA and hash page table allocation. Both RMA and hash page table request will be a multiple of 256K. We can use a chunk size of 256K to track the free/used 256K chunk in the bitmap. This should help to reduce the bitmap size. Signed-off-by: Aneesh Kumar K.V Acked-by: Paul Mackerras Signed-off-by: Alexander Graf --- arch/powerpc/kvm/book3s_64_mmu_hv.c | 3 +++ arch/powerpc/kvm/book3s_hv_cma.c | 35 ++++++++++++++++++++++++----------- arch/powerpc/kvm/book3s_hv_cma.h | 5 +++++ 3 files changed, 32 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 354f4bb21f5..7eb5ddab120 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -37,6 +37,8 @@ #include #include +#include "book3s_hv_cma.h" + /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ #define MAX_LPID_970 63 @@ -71,6 +73,7 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) /* Next try to allocate from the preallocated pool */ if (!hpt) { + VM_BUG_ON(order < KVM_CMA_CHUNK_ORDER); page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT)); if (page) { hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); diff --git a/arch/powerpc/kvm/book3s_hv_cma.c b/arch/powerpc/kvm/book3s_hv_cma.c index e04b269b9c5..d9d3d8553d5 100644 --- a/arch/powerpc/kvm/book3s_hv_cma.c +++ b/arch/powerpc/kvm/book3s_hv_cma.c @@ -24,6 +24,8 @@ #include #include +#include "book3s_hv_cma.h" + struct kvm_cma { unsigned long base_pfn; unsigned long count; @@ -96,6 +98,7 @@ struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages) int ret; struct page *page = NULL; struct kvm_cma *cma = &kvm_cma_area; + unsigned long chunk_count, nr_chunk; unsigned long mask, pfn, pageno, start = 0; @@ -107,21 +110,27 @@ struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages) if (!nr_pages) return NULL; - + /* + * align mask with chunk size. The bit tracks pages in chunk size + */ VM_BUG_ON(!is_power_of_2(align_pages)); - mask = align_pages - 1; + mask = (align_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT)) - 1; + BUILD_BUG_ON(PAGE_SHIFT > KVM_CMA_CHUNK_ORDER); + + chunk_count = cma->count >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); + nr_chunk = nr_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); mutex_lock(&kvm_cma_mutex); for (;;) { - pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count, - start, nr_pages, mask); - if (pageno >= cma->count) + pageno = bitmap_find_next_zero_area(cma->bitmap, chunk_count, + start, nr_chunk, mask); + if (pageno >= chunk_count) break; - pfn = cma->base_pfn + pageno; + pfn = cma->base_pfn + (pageno << (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT)); ret = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_CMA); if (ret == 0) { - bitmap_set(cma->bitmap, pageno, nr_pages); + bitmap_set(cma->bitmap, pageno, nr_chunk); page = pfn_to_page(pfn); memset(pfn_to_kaddr(pfn), 0, nr_pages << PAGE_SHIFT); break; @@ -150,9 +159,9 @@ struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages) bool kvm_release_cma(struct page *pages, unsigned long nr_pages) { unsigned long pfn; + unsigned long nr_chunk; struct kvm_cma *cma = &kvm_cma_area; - if (!cma || !pages) return false; @@ -164,9 +173,12 @@ bool kvm_release_cma(struct page *pages, unsigned long nr_pages) return false; VM_BUG_ON(pfn + nr_pages > cma->base_pfn + cma->count); + nr_chunk = nr_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); mutex_lock(&kvm_cma_mutex); - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, nr_pages); + bitmap_clear(cma->bitmap, + (pfn - cma->base_pfn) >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT), + nr_chunk); free_contig_range(pfn, nr_pages); mutex_unlock(&kvm_cma_mutex); @@ -204,13 +216,14 @@ static int __init kvm_cma_activate_area(unsigned long base_pfn, static int __init kvm_cma_init_reserved_areas(void) { int bitmap_size, ret; + unsigned long chunk_count; struct kvm_cma *cma = &kvm_cma_area; pr_debug("%s()\n", __func__); if (!cma->count) return 0; - - bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); + chunk_count = cma->count >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); + bitmap_size = BITS_TO_LONGS(chunk_count) * sizeof(long); cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL); if (!cma->bitmap) return -ENOMEM; diff --git a/arch/powerpc/kvm/book3s_hv_cma.h b/arch/powerpc/kvm/book3s_hv_cma.h index 788bc3b7310..655144f75fa 100644 --- a/arch/powerpc/kvm/book3s_hv_cma.h +++ b/arch/powerpc/kvm/book3s_hv_cma.h @@ -14,6 +14,11 @@ #ifndef __POWERPC_KVM_CMA_ALLOC_H__ #define __POWERPC_KVM_CMA_ALLOC_H__ +/* + * Both RMA and Hash page allocation will be multiple of 256K. + */ +#define KVM_CMA_CHUNK_ORDER 18 + extern struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages); extern bool kvm_release_cma(struct page *pages, unsigned long nr_pages); -- cgit v1.2.3-70-g09d2 From 0773d73d818702191dd568e1e20bcafc5c64661a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 22 May 2013 10:38:53 +0200 Subject: ARM: move VFP init to an earlier boot stage In order to use the NEON unit in the kernel, we should initialize it a bit earlier in the boot process so NEON users that like to do a quick benchmark at load time (like the xor_blocks or RAID-6 code) find the NEON/VFP unit already enabled. Replaced late_initcall() with core_initcall(). Signed-off-by: Ard Biesheuvel Acked-by: Nicolas Pitre --- arch/arm/vfp/vfpmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 5dfbb0b8e7f..791993aed75 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -731,4 +731,4 @@ static int __init vfp_init(void) return 0; } -late_initcall(vfp_init); +core_initcall(vfp_init); -- cgit v1.2.3-70-g09d2 From ab3da15643469ab2d206dee3d9cfa4194ba77f25 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 24 May 2013 16:23:28 +0200 Subject: ARM: be strict about FP exceptions in kernel mode The support code in vfp_support_entry does not care whether the exception that caused it to be invoked occurred in kernel mode or in user mode. However, neither condition that could trigger this exception (lazy restore and VFP bounce to support code) is currently allowable in kernel mode. In either case, print a message describing the condition before letting the undefined instruction handler run its course and trigger an oops. Signed-off-by: Ard Biesheuvel Acked-by: Nicolas Pitre --- arch/arm/vfp/vfphw.S | 5 +++++ arch/arm/vfp/vfpmodule.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'arch') diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 8d10dc8a1e1..3e5d3115a2a 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -78,6 +78,11 @@ ENTRY(vfp_support_entry) DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 + ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions + and r3, r3, #MODE_MASK @ are supported in kernel mode + teq r3, #USR_MODE + bne vfp_kmode_exception @ Returns through lr + VFPFMRX r1, FPEXC @ Is the VFP enabled? DBGSTR1 "fpexc %08x", r1 tst r1, #FPEXC_EN diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 791993aed75..7620831a0c6 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -648,6 +648,26 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action, return NOTIFY_OK; } +void vfp_kmode_exception(void) +{ + /* + * If we reach this point, a floating point exception has been raised + * while running in kernel mode. If the NEON/VFP unit was enabled at the + * time, it means a VFP instruction has been issued that requires + * software assistance to complete, something which is not currently + * supported in kernel mode. + * If the NEON/VFP unit was disabled, and the location pointed to below + * is properly preceded by a call to kernel_neon_begin(), something has + * caused the task to be scheduled out and back in again. In this case, + * rebuilding and running with CONFIG_DEBUG_ATOMIC_SLEEP enabled should + * be helpful in localizing the problem. + */ + if (fmrx(FPEXC) & FPEXC_EN) + pr_crit("BUG: unsupported FP instruction in kernel mode\n"); + else + pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); +} + /* * VFP support code initialisation. */ -- cgit v1.2.3-70-g09d2 From 73c132c15da504789b924871e2491479a18e4f6a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 16 May 2013 11:41:48 +0200 Subject: ARM: add support for kernel mode NEON In order to safely support the use of NEON instructions in kernel mode, some precautions need to be taken: - the userland context that may be present in the registers (even if the NEON/VFP is currently disabled) must be stored under the correct task (which may not be 'current' in the UP case), - to avoid having to keep track of additional vfpstates for the kernel side, disallow the use of NEON in interrupt context and run with preemption disabled, - after use, re-enable preemption and re-enable the lazy restore machinery by disabling the NEON/VFP unit. This patch adds the functions kernel_neon_begin() and kernel_neon_end() which take care of the above. It also adds the Kconfig symbol KERNEL_MODE_NEON to enable it. Signed-off-by: Ard Biesheuvel Acked-by: Nicolas Pitre --- arch/arm/Kconfig | 7 +++++++ arch/arm/include/asm/neon.h | 36 ++++++++++++++++++++++++++++++++++ arch/arm/vfp/vfpmodule.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 arch/arm/include/asm/neon.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 136f263ed47..d6068b43515 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2197,6 +2197,13 @@ config NEON Say Y to include support code for NEON, the ARMv7 Advanced SIMD Extension. +config KERNEL_MODE_NEON + bool "Support for NEON in kernel mode" + default n + depends on NEON + help + Say Y to include support for NEON in kernel mode. + endmenu menu "Userspace binary formats" diff --git a/arch/arm/include/asm/neon.h b/arch/arm/include/asm/neon.h new file mode 100644 index 00000000000..8f730fe7009 --- /dev/null +++ b/arch/arm/include/asm/neon.h @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/include/asm/neon.h + * + * Copyright (C) 2013 Linaro Ltd + * + * 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 + +#define cpu_has_neon() (!!(elf_hwcap & HWCAP_NEON)) + +#ifdef __ARM_NEON__ + +/* + * If you are affected by the BUILD_BUG below, it probably means that you are + * using NEON code /and/ calling the kernel_neon_begin() function from the same + * compilation unit. To prevent issues that may arise from GCC reordering or + * generating(1) NEON instructions outside of these begin/end functions, the + * only supported way of using NEON code in the kernel is by isolating it in a + * separate compilation unit, and calling it from another unit from inside a + * kernel_neon_begin/kernel_neon_end pair. + * + * (1) Current GCC (4.7) might generate NEON instructions at O3 level if + * -mpfu=neon is set. + */ + +#define kernel_neon_begin() \ + BUILD_BUG_ON_MSG(1, "kernel_neon_begin() called from NEON code") + +#else +void kernel_neon_begin(void); +#endif +void kernel_neon_end(void); diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 7620831a0c6..52b8f40b1c7 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -668,6 +669,52 @@ void vfp_kmode_exception(void) pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); } +#ifdef CONFIG_KERNEL_MODE_NEON + +/* + * Kernel-side NEON support functions + */ +void kernel_neon_begin(void) +{ + struct thread_info *thread = current_thread_info(); + unsigned int cpu; + u32 fpexc; + + /* + * Kernel mode NEON is only allowed outside of interrupt context + * with preemption disabled. This will make sure that the kernel + * mode NEON register contents never need to be preserved. + */ + BUG_ON(in_interrupt()); + cpu = get_cpu(); + + fpexc = fmrx(FPEXC) | FPEXC_EN; + fmxr(FPEXC, fpexc); + + /* + * Save the userland NEON/VFP state. Under UP, + * the owner could be a task other than 'current' + */ + if (vfp_state_in_hw(cpu, thread)) + vfp_save_state(&thread->vfpstate, fpexc); +#ifndef CONFIG_SMP + else if (vfp_current_hw_state[cpu] != NULL) + vfp_save_state(vfp_current_hw_state[cpu], fpexc); +#endif + vfp_current_hw_state[cpu] = NULL; +} +EXPORT_SYMBOL(kernel_neon_begin); + +void kernel_neon_end(void) +{ + /* Disable the NEON/VFP unit. */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); + put_cpu(); +} +EXPORT_SYMBOL(kernel_neon_end); + +#endif /* CONFIG_KERNEL_MODE_NEON */ + /* * VFP support code initialisation. */ -- cgit v1.2.3-70-g09d2 From 01956597cbc46df072f20f90a40eebe356200c38 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 17 May 2013 18:51:23 +0200 Subject: ARM: crypto: add NEON accelerated XOR implementation Add a source file xor-neon.c (which is really just the reference C implementation passed through the GCC vectorizer) and hook it up to the XOR framework. Signed-off-by: Ard Biesheuvel Acked-by: Nicolas Pitre --- arch/arm/include/asm/xor.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++ arch/arm/lib/Makefile | 6 ++++ arch/arm/lib/xor-neon.c | 42 ++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 arch/arm/lib/xor-neon.c (limited to 'arch') diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h index 7604673dc42..4ffb26d4cad 100644 --- a/arch/arm/include/asm/xor.h +++ b/arch/arm/include/asm/xor.h @@ -7,7 +7,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include +#include +#include #define __XOR(a1, a2) a1 ^= a2 @@ -138,4 +141,74 @@ static struct xor_block_template xor_block_arm4regs = { xor_speed(&xor_block_arm4regs); \ xor_speed(&xor_block_8regs); \ xor_speed(&xor_block_32regs); \ + NEON_TEMPLATES; \ } while (0) + +#ifdef CONFIG_KERNEL_MODE_NEON + +extern struct xor_block_template const xor_block_neon_inner; + +static void +xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) +{ + if (in_interrupt()) { + xor_arm4regs_2(bytes, p1, p2); + } else { + kernel_neon_begin(); + xor_block_neon_inner.do_2(bytes, p1, p2); + kernel_neon_end(); + } +} + +static void +xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3) +{ + if (in_interrupt()) { + xor_arm4regs_3(bytes, p1, p2, p3); + } else { + kernel_neon_begin(); + xor_block_neon_inner.do_3(bytes, p1, p2, p3); + kernel_neon_end(); + } +} + +static void +xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4) +{ + if (in_interrupt()) { + xor_arm4regs_4(bytes, p1, p2, p3, p4); + } else { + kernel_neon_begin(); + xor_block_neon_inner.do_4(bytes, p1, p2, p3, p4); + kernel_neon_end(); + } +} + +static void +xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4, unsigned long *p5) +{ + if (in_interrupt()) { + xor_arm4regs_5(bytes, p1, p2, p3, p4, p5); + } else { + kernel_neon_begin(); + xor_block_neon_inner.do_5(bytes, p1, p2, p3, p4, p5); + kernel_neon_end(); + } +} + +static struct xor_block_template xor_block_neon = { + .name = "neon", + .do_2 = xor_neon_2, + .do_3 = xor_neon_3, + .do_4 = xor_neon_4, + .do_5 = xor_neon_5 +}; + +#define NEON_TEMPLATES \ + do { if (cpu_has_neon()) xor_speed(&xor_block_neon); } while (0) +#else +#define NEON_TEMPLATES +#endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index af72969820b..aaf3a873113 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -45,3 +45,9 @@ lib-$(CONFIG_ARCH_SHARK) += io-shark.o $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S + +ifeq ($(CONFIG_KERNEL_MODE_NEON),y) + NEON_FLAGS := -mfloat-abi=softfp -mfpu=neon + CFLAGS_xor-neon.o += $(NEON_FLAGS) + lib-$(CONFIG_XOR_BLOCKS) += xor-neon.o +endif diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c new file mode 100644 index 00000000000..f485e5a2af4 --- /dev/null +++ b/arch/arm/lib/xor-neon.c @@ -0,0 +1,42 @@ +/* + * linux/arch/arm/lib/xor-neon.c + * + * Copyright (C) 2013 Linaro Ltd + * + * 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 + +#ifndef __ARM_NEON__ +#error You should compile this file with '-mfloat-abi=softfp -mfpu=neon' +#endif + +/* + * Pull in the reference implementations while instructing GCC (through + * -ftree-vectorize) to attempt to exploit implicit parallelism and emit + * NEON instructions. + */ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#pragma GCC optimize "tree-vectorize" +#else +/* + * While older versions of GCC do not generate incorrect code, they fail to + * recognize the parallel nature of these functions, and emit plain ARM code, + * which is known to be slower than the optimized ARM code in asm-arm/xor.h. + */ +#warning This code requires at least version 4.6 of GCC +#endif + +#pragma GCC diagnostic ignored "-Wunused-variable" +#include + +struct xor_block_template const xor_block_neon_inner = { + .name = "__inner_neon__", + .do_2 = xor_8regs_2, + .do_3 = xor_8regs_3, + .do_4 = xor_8regs_4, + .do_5 = xor_8regs_5, +}; -- cgit v1.2.3-70-g09d2 From 5448050124d9d289bc2f5177318c68c0484ca413 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 8 Jul 2013 20:08:25 +1000 Subject: KVM: PPC: Book3S HV: Correct tlbie usage This corrects the usage of the tlbie (TLB invalidate entry) instruction in HV KVM. The tlbie instruction changed between PPC970 and POWER7. On the PPC970, the bit to select large vs. small page is in the instruction, not in the RB register value. This changes the code to use the correct form on PPC970. On POWER7 we were calculating the AVAL (Abbreviated Virtual Address, Lower) field of the RB value incorrectly for 64k pages. This fixes it. Since we now have several cases to handle for the tlbie instruction, this factors out the code to do a sequence of tlbies into a new function, do_tlbies(), and calls that from the various places where the code was doing tlbie instructions inline. It also makes kvmppc_h_bulk_remove() use the same global_invalidates() function for determining whether to do local or global TLB invalidations as is used in other places, for consistency, and also to make sure that kvm->arch.need_tlb_flush gets updated properly. Signed-off-by: Paul Mackerras Signed-off-by: Alexander Graf --- arch/powerpc/include/asm/kvm_book3s_64.h | 2 +- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 139 ++++++++++++++++++------------- 2 files changed, 82 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 76ff0b5c999..154ba3f6b7a 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -100,7 +100,7 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, /* (masks depend on page size) */ rb |= 0x1000; /* page encoding in LP field */ rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */ - rb |= (va_low & 0xfe); /* AVAL field (P7 doesn't seem to care) */ + rb |= ((va_low << 4) & 0xf0); /* AVAL field (P7 doesn't seem to care) */ } } else { /* 4kB page */ diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 6dcbb49105a..105b00f24f2 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -385,6 +385,80 @@ static inline int try_lock_tlbie(unsigned int *lock) return old == 0; } +/* + * tlbie/tlbiel is a bit different on the PPC970 compared to later + * processors such as POWER7; the large page bit is in the instruction + * not RB, and the top 16 bits and the bottom 12 bits of the VA + * in RB must be 0. + */ +static void do_tlbies_970(struct kvm *kvm, unsigned long *rbvalues, + long npages, int global, bool need_sync) +{ + long i; + + if (global) { + while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) + cpu_relax(); + if (need_sync) + asm volatile("ptesync" : : : "memory"); + for (i = 0; i < npages; ++i) { + unsigned long rb = rbvalues[i]; + + if (rb & 1) /* large page */ + asm volatile("tlbie %0,1" : : + "r" (rb & 0x0000fffffffff000ul)); + else + asm volatile("tlbie %0,0" : : + "r" (rb & 0x0000fffffffff000ul)); + } + asm volatile("eieio; tlbsync; ptesync" : : : "memory"); + kvm->arch.tlbie_lock = 0; + } else { + if (need_sync) + asm volatile("ptesync" : : : "memory"); + for (i = 0; i < npages; ++i) { + unsigned long rb = rbvalues[i]; + + if (rb & 1) /* large page */ + asm volatile("tlbiel %0,1" : : + "r" (rb & 0x0000fffffffff000ul)); + else + asm volatile("tlbiel %0,0" : : + "r" (rb & 0x0000fffffffff000ul)); + } + asm volatile("ptesync" : : : "memory"); + } +} + +static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues, + long npages, int global, bool need_sync) +{ + long i; + + if (cpu_has_feature(CPU_FTR_ARCH_201)) { + /* PPC970 tlbie instruction is a bit different */ + do_tlbies_970(kvm, rbvalues, npages, global, need_sync); + return; + } + if (global) { + while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) + cpu_relax(); + if (need_sync) + asm volatile("ptesync" : : : "memory"); + for (i = 0; i < npages; ++i) + asm volatile(PPC_TLBIE(%1,%0) : : + "r" (rbvalues[i]), "r" (kvm->arch.lpid)); + asm volatile("eieio; tlbsync; ptesync" : : : "memory"); + kvm->arch.tlbie_lock = 0; + } else { + if (need_sync) + asm volatile("ptesync" : : : "memory"); + for (i = 0; i < npages; ++i) + asm volatile("tlbiel %0" : : "r" (rbvalues[i])); + asm volatile("ptesync" : : : "memory"); + } +} + long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, unsigned long pte_index, unsigned long avpn, unsigned long *hpret) @@ -410,19 +484,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, if (v & HPTE_V_VALID) { hpte[0] &= ~HPTE_V_VALID; rb = compute_tlbie_rb(v, hpte[1], pte_index); - if (global_invalidates(kvm, flags)) { - while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) - cpu_relax(); - asm volatile("ptesync" : : : "memory"); - asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" - : : "r" (rb), "r" (kvm->arch.lpid)); - asm volatile("ptesync" : : : "memory"); - kvm->arch.tlbie_lock = 0; - } else { - asm volatile("ptesync" : : : "memory"); - asm volatile("tlbiel %0" : : "r" (rb)); - asm volatile("ptesync" : : : "memory"); - } + do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); /* Read PTE low word after tlbie to get final R/C values */ remove_revmap_chain(kvm, pte_index, rev, v, hpte[1]); } @@ -450,12 +512,11 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) unsigned long *hp, *hptes[4], tlbrb[4]; long int i, j, k, n, found, indexes[4]; unsigned long flags, req, pte_index, rcbits; - long int local = 0; + int global; long int ret = H_SUCCESS; struct revmap_entry *rev, *revs[4]; - if (atomic_read(&kvm->online_vcpus) == 1) - local = 1; + global = global_invalidates(kvm, 0); for (i = 0; i < 4 && ret == H_SUCCESS; ) { n = 0; for (; i < 4; ++i) { @@ -531,22 +592,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) break; /* Now that we've collected a batch, do the tlbies */ - if (!local) { - while(!try_lock_tlbie(&kvm->arch.tlbie_lock)) - cpu_relax(); - asm volatile("ptesync" : : : "memory"); - for (k = 0; k < n; ++k) - asm volatile(PPC_TLBIE(%1,%0) : : - "r" (tlbrb[k]), - "r" (kvm->arch.lpid)); - asm volatile("eieio; tlbsync; ptesync" : : : "memory"); - kvm->arch.tlbie_lock = 0; - } else { - asm volatile("ptesync" : : : "memory"); - for (k = 0; k < n; ++k) - asm volatile("tlbiel %0" : : "r" (tlbrb[k])); - asm volatile("ptesync" : : : "memory"); - } + do_tlbies(kvm, tlbrb, n, global, true); /* Read PTE low words after tlbie to get final R/C values */ for (k = 0; k < n; ++k) { @@ -605,19 +651,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, if (v & HPTE_V_VALID) { rb = compute_tlbie_rb(v, r, pte_index); hpte[0] = v & ~HPTE_V_VALID; - if (global_invalidates(kvm, flags)) { - while(!try_lock_tlbie(&kvm->arch.tlbie_lock)) - cpu_relax(); - asm volatile("ptesync" : : : "memory"); - asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" - : : "r" (rb), "r" (kvm->arch.lpid)); - asm volatile("ptesync" : : : "memory"); - kvm->arch.tlbie_lock = 0; - } else { - asm volatile("ptesync" : : : "memory"); - asm volatile("tlbiel %0" : : "r" (rb)); - asm volatile("ptesync" : : : "memory"); - } + do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); /* * If the host has this page as readonly but the guest * wants to make it read/write, reduce the permissions. @@ -688,13 +722,7 @@ void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, hptep[0] &= ~HPTE_V_VALID; rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); - while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) - cpu_relax(); - asm volatile("ptesync" : : : "memory"); - asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" - : : "r" (rb), "r" (kvm->arch.lpid)); - asm volatile("ptesync" : : : "memory"); - kvm->arch.tlbie_lock = 0; + do_tlbies(kvm, &rb, 1, 1, true); } EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); @@ -708,12 +736,7 @@ void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, rbyte = (hptep[1] & ~HPTE_R_R) >> 8; /* modify only the second-last byte, which contains the ref bit */ *((char *)hptep + 14) = rbyte; - while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) - cpu_relax(); - asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" - : : "r" (rb), "r" (kvm->arch.lpid)); - asm volatile("ptesync" : : : "memory"); - kvm->arch.tlbie_lock = 0; + do_tlbies(kvm, &rb, 1, 1, false); } EXPORT_SYMBOL_GPL(kvmppc_clear_ref_hpte); -- cgit v1.2.3-70-g09d2 From 4baa1d871c8c959084aa5367a9bf211f383941e5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 8 Jul 2013 20:09:53 +1000 Subject: KVM: PPC: Book3S HV: Allow negative offsets to real-mode hcall handlers The table of offsets to real-mode hcall handlers in book3s_hv_rmhandlers.S can contain negative values, if some of the handlers end up before the table in the vmlinux binary. Thus we need to use a sign-extending load to read the values in the table rather than a zero-extending load. Without this, the host crashes when the guest does one of the hcalls with negative offsets, due to jumping to a bogus address. Signed-off-by: Paul Mackerras Signed-off-by: Alexander Graf --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index b02f91e4c70..60dce5bfab3 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1381,7 +1381,7 @@ hcall_try_real_mode: cmpldi r3,hcall_real_table_end - hcall_real_table bge guest_exit_cont LOAD_REG_ADDR(r4, hcall_real_table) - lwzx r3,r3,r4 + lwax r3,r3,r4 cmpwi r3,0 beq guest_exit_cont add r3,r3,r4 -- cgit v1.2.3-70-g09d2 From 5f1c248f52c12e155e0fe6a614178181f7629901 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 10 Jul 2013 17:47:39 -0500 Subject: kvm/ppc: Call trace_hardirqs_on before entry Currently this is only being done on 64-bit. Rather than just move it out of the 64-bit ifdef, move it to kvm_lazy_ee_enable() so that it is consistent with lazy ee state, and so that we don't track more host code as interrupts-enabled than necessary. Rename kvm_lazy_ee_enable() to kvm_fix_ee_before_entry() to reflect that this function now has a role on 32-bit as well. Signed-off-by: Scott Wood Signed-off-by: Alexander Graf --- arch/powerpc/include/asm/kvm_ppc.h | 11 ++++++++--- arch/powerpc/kvm/book3s_pr.c | 4 ++-- arch/powerpc/kvm/booke.c | 4 ++-- arch/powerpc/kvm/powerpc.c | 2 -- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 5a26bfcd0bb..b15554a26c2 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -394,10 +394,15 @@ static inline void kvmppc_mmu_flush_icache(pfn_t pfn) } } -/* Please call after prepare_to_enter. This function puts the lazy ee state - back to normal mode, without actually enabling interrupts. */ -static inline void kvmppc_lazy_ee_enable(void) +/* + * Please call after prepare_to_enter. This function puts the lazy ee and irq + * disabled tracking state back to normal mode, without actually enabling + * interrupts. + */ +static inline void kvmppc_fix_ee_before_entry(void) { + trace_hardirqs_on(); + #ifdef CONFIG_PPC64 /* Only need to enable IRQs by hard enabling them after this */ local_paca->irq_happened = 0; diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 19498a567a8..ddfaf560e50 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -890,7 +890,7 @@ program_interrupt: local_irq_enable(); r = s; } else { - kvmppc_lazy_ee_enable(); + kvmppc_fix_ee_before_entry(); } } @@ -1161,7 +1161,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) if (vcpu->arch.shared->msr & MSR_FP) kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); - kvmppc_lazy_ee_enable(); + kvmppc_fix_ee_before_entry(); ret = __kvmppc_vcpu_run(kvm_run, vcpu); diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index dcc94f01600..6e353517c4a 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -698,7 +698,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_load_guest_fp(vcpu); #endif - kvmppc_lazy_ee_enable(); + kvmppc_fix_ee_before_entry(); ret = __kvmppc_vcpu_run(kvm_run, vcpu); @@ -1168,7 +1168,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, local_irq_enable(); r = (s << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); } else { - kvmppc_lazy_ee_enable(); + kvmppc_fix_ee_before_entry(); } } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 6316ee336e8..4e05f8c693b 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -117,8 +117,6 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) kvm_guest_exit(); continue; } - - trace_hardirqs_on(); #endif kvm_guest_enter(); -- cgit v1.2.3-70-g09d2 From c09ec198eb7d5d55fe2f23012a063b7ee107b34a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 10 Jul 2013 17:47:41 -0500 Subject: kvm/ppc/booke: Don't call kvm_guest_enter twice kvm_guest_enter() was already called by kvmppc_prepare_to_enter(). Don't call it again. Signed-off-by: Scott Wood Signed-off-by: Alexander Graf --- arch/powerpc/kvm/booke.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 6e353517c4a..17722d82f1d 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -674,8 +674,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) goto out; } - kvm_guest_enter(); - #ifdef CONFIG_PPC_FPU /* Save userspace FPU state in stack */ enable_kernel_fp(); -- cgit v1.2.3-70-g09d2 From b21e332d24f91b0a401a2871aadbfec00e8ed9bc Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 15 Jul 2013 09:26:07 +0930 Subject: lguest: Point to the right directory for the lguest launcher The code was moved in 07fe9977b6234ede1bd29e10e0323e478860c871 but the comment was not updated. The reference in drivers/vhost/vhost.c is left alone as it is historic. Signed-off-by: Holger Hans Peter Freyther Signed-off-by: Rusty Russell --- arch/x86/lguest/boot.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 6a22c19da66..7c1fde50ecb 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -7,8 +7,7 @@ * kernel and insert a module (lg.ko) which allows us to run other Linux * kernels the same way we'd run processes. We call the first kernel the Host, * and the others the Guests. The program which sets up and configures Guests - * (such as the example in Documentation/virtual/lguest/lguest.c) is called the - * Launcher. + * (such as the example in tools/lguest/lguest.c) is called the Launcher. * * Secondly, we only run specially modified Guests, not normal kernels: setting * CONFIG_LGUEST_GUEST to "y" compiles this file into the kernel so it knows -- cgit v1.2.3-70-g09d2 From 8c6ffba0eddc8c110dbf444f51354ce42069abfc Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 15 Jul 2013 11:20:32 +0930 Subject: PTR_RET is now PTR_ERR_OR_ZERO(): Replace most. Sweep of the simple cases. Cc: netdev@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Cc: Julia Lawall Signed-off-by: Rusty Russell Acked-by: David S. Miller Acked-by: Benjamin Herrenschmidt --- arch/arm/mach-omap2/i2c.c | 2 +- arch/m68k/amiga/platform.c | 2 +- arch/m68k/kernel/time.c | 2 +- arch/m68k/q40/config.c | 2 +- arch/powerpc/kernel/iommu.c | 2 +- arch/powerpc/kernel/time.c | 2 +- arch/powerpc/platforms/ps3/time.c | 2 +- arch/powerpc/sysdev/rtc_cmos_setup.c | 2 +- arch/s390/hypfs/hypfs_dbfs.c | 2 +- drivers/char/tile-srom.c | 2 +- drivers/infiniband/core/cma.c | 2 +- drivers/net/appletalk/cops.c | 2 +- drivers/net/appletalk/ltpc.c | 2 +- drivers/net/ethernet/amd/atarilance.c | 2 +- drivers/net/ethernet/amd/mvme147.c | 2 +- drivers/net/ethernet/amd/ni65.c | 2 +- drivers/net/ethernet/amd/sun3lance.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 2 +- drivers/net/wireless/brcm80211/brcmsmac/debug.c | 2 +- drivers/platform/x86/samsung-q10.c | 2 +- drivers/regulator/fan53555.c | 2 +- drivers/spi/spi-fsl-spi.c | 2 +- drivers/spi/spidev.c | 2 +- drivers/video/omap2/dss/core.c | 2 +- fs/btrfs/dev-replace.c | 2 +- fs/btrfs/inode.c | 2 +- net/bluetooth/hci_sysfs.c | 2 +- net/bridge/netfilter/ebtable_broute.c | 2 +- net/bridge/netfilter/ebtable_filter.c | 2 +- net/bridge/netfilter/ebtable_nat.c | 2 +- net/ipv4/netfilter/arptable_filter.c | 2 +- net/ipv4/netfilter/iptable_filter.c | 2 +- net/ipv4/netfilter/iptable_mangle.c | 2 +- net/ipv4/netfilter/iptable_nat.c | 2 +- net/ipv4/netfilter/iptable_raw.c | 2 +- net/ipv4/netfilter/iptable_security.c | 2 +- net/ipv6/netfilter/ip6table_filter.c | 2 +- net/ipv6/netfilter/ip6table_mangle.c | 2 +- net/ipv6/netfilter/ip6table_nat.c | 2 +- net/ipv6/netfilter/ip6table_raw.c | 2 +- net/ipv6/netfilter/ip6table_security.c | 2 +- scripts/coccinelle/api/ptr_ret.cocci | 10 +++++----- sound/soc/soc-io.c | 2 +- 43 files changed, 47 insertions(+), 47 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index d940e53dd9f..b456b4471f3 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c @@ -181,7 +181,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, sizeof(struct omap_i2c_bus_platform_data)); WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); - return PTR_RET(pdev); + return PTR_ERR_OR_ZERO(pdev); } static int __init omap_i2c_cmdline(void) diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 6083088c0cc..dacd9f911f7 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -56,7 +56,7 @@ static int __init amiga_init_bus(void) n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; pdev = platform_device_register_simple("amiga-zorro", -1, zorro_resources, n); - return PTR_RET(pdev); + return PTR_ERR_OR_ZERO(pdev); } subsys_initcall(amiga_init_bus); diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index bea6bcf8f9b..7eb9792009f 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c @@ -90,7 +90,7 @@ static int __init rtc_init(void) return -ENODEV; pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); - return PTR_RET(pdev); + return PTR_ERR_OR_ZERO(pdev); } module_init(rtc_init); diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 658542b914f..078bb744b5f 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -338,6 +338,6 @@ static __init int q40_add_kbd_device(void) return -ENODEV; pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); - return PTR_RET(pdev); + return PTR_ERR_OR_ZERO(pdev); } arch_initcall(q40_add_kbd_device); diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index b20ff173a67..0adab06ce5c 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -105,7 +105,7 @@ static int __init fail_iommu_debugfs(void) struct dentry *dir = fault_create_debugfs_attr("fail_iommu", NULL, &fail_iommu); - return PTR_RET(dir); + return PTR_ERR_OR_ZERO(dir); } late_initcall(fail_iommu_debugfs); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 65ab9e90937..cdcc156865e 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -1049,7 +1049,7 @@ static int __init rtc_init(void) pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); - return PTR_RET(pdev); + return PTR_ERR_OR_ZERO(pdev); } module_init(rtc_init); diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c index cba1e6be68e..ce73ce86561 100644 --- a/arch/powerpc/platforms/ps3/time.c +++ b/arch/powerpc/platforms/ps3/time.c @@ -90,7 +90,7 @@ static int __init ps3_rtc_init(void) pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); - return PTR_RET(pdev); + return PTR_ERR_OR_ZERO(pdev); } module_init(ps3_rtc_init); diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c index af79e1ea74b..af0f9beddca 100644 --- a/arch/powerpc/sysdev/rtc_cmos_setup.c +++ b/arch/powerpc/sysdev/rtc_cmos_setup.c @@ -62,7 +62,7 @@ static int __init add_rtc(void) pd = platform_device_register_simple("rtc_cmos", -1, &res[0], num_res); - return PTR_RET(pd); + return PTR_ERR_OR_ZERO(pd); } fs_initcall(add_rtc); diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index bb5dd496614..17ab8b7b53c 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -105,7 +105,7 @@ void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) int hypfs_dbfs_init(void) { dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); - return PTR_RET(dbfs_dir); + return PTR_ERR_OR_ZERO(dbfs_dir); } void hypfs_dbfs_exit(void) diff --git a/drivers/char/tile-srom.c b/drivers/char/tile-srom.c index 7faeb1cde97..ce04d6eb23d 100644 --- a/drivers/char/tile-srom.c +++ b/drivers/char/tile-srom.c @@ -349,7 +349,7 @@ static int srom_setup_minor(struct srom_dev *srom, int index) dev = device_create(srom_class, &platform_bus, MKDEV(srom_major, index), srom, "%d", index); - return PTR_RET(dev); + return PTR_ERR_OR_ZERO(dev); } /** srom_init() - Initialize the driver's module. */ diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index f1c279fabe6..4df360bede8 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -3205,7 +3205,7 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv, id_priv->id.port_num, &rec, comp_mask, GFP_KERNEL, cma_ib_mc_handler, mc); - return PTR_RET(mc->multicast.ib); + return PTR_ERR_OR_ZERO(mc->multicast.ib); } static void iboe_mcast_work_handler(struct work_struct *work) diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index cff6f023c03..7f2a032c354 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -996,7 +996,7 @@ static int __init cops_module_init(void) printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", cardname); cops_dev = cops_probe(-1); - return PTR_RET(cops_dev); + return PTR_ERR_OR_ZERO(cops_dev); } static void __exit cops_module_exit(void) diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index b5782cdf0bc..01e2ac55c13 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1243,7 +1243,7 @@ static int __init ltpc_module_init(void) "ltpc: Autoprobing is not recommended for modules\n"); dev_ltpc = ltpc_probe(); - return PTR_RET(dev_ltpc); + return PTR_ERR_OR_ZERO(dev_ltpc); } module_init(ltpc_module_init); #endif diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index e8d0ef508f4..10ceca523fc 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c @@ -1147,7 +1147,7 @@ static struct net_device *atarilance_dev; static int __init atarilance_module_init(void) { atarilance_dev = atarilance_probe(-1); - return PTR_RET(atarilance_dev); + return PTR_ERR_OR_ZERO(atarilance_dev); } static void __exit atarilance_module_exit(void) diff --git a/drivers/net/ethernet/amd/mvme147.c b/drivers/net/ethernet/amd/mvme147.c index a51497c9d2a..e108e911da0 100644 --- a/drivers/net/ethernet/amd/mvme147.c +++ b/drivers/net/ethernet/amd/mvme147.c @@ -188,7 +188,7 @@ static struct net_device *dev_mvme147_lance; int __init init_module(void) { dev_mvme147_lance = mvme147lance_probe(-1); - return PTR_RET(dev_mvme147_lance); + return PTR_ERR_OR_ZERO(dev_mvme147_lance); } void __exit cleanup_module(void) diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c index 26fc0ce0faa..1cf33addd15 100644 --- a/drivers/net/ethernet/amd/ni65.c +++ b/drivers/net/ethernet/amd/ni65.c @@ -1238,7 +1238,7 @@ MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)"); int __init init_module(void) { dev_ni65 = ni65_probe(-1); - return PTR_RET(dev_ni65); + return PTR_ERR_OR_ZERO(dev_ni65); } void __exit cleanup_module(void) diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c index 4375abe61da..d6b20296b8e 100644 --- a/drivers/net/ethernet/amd/sun3lance.c +++ b/drivers/net/ethernet/amd/sun3lance.c @@ -940,7 +940,7 @@ static struct net_device *sun3lance_dev; int __init init_module(void) { sun3lance_dev = sun3lance_probe(-1); - return PTR_RET(sun3lance_dev); + return PTR_ERR_OR_ZERO(sun3lance_dev); } void __exit cleanup_module(void) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index c37b9d68e45..0f9e9057e7d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -50,7 +50,7 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr) return -ENODEV; drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); - return PTR_RET(drvr->dbgfs_dir); + return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); } void brcmf_debugfs_detach(struct brcmf_pub *drvr) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c index 9761deb4620..a5d4add26f4 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/debug.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c @@ -56,7 +56,7 @@ int brcms_debugfs_attach(struct brcms_pub *drvr) drvr->dbgfs_dir = debugfs_create_dir( dev_name(&drvr->wlc->hw->d11core->dev), root_folder); - return PTR_RET(drvr->dbgfs_dir); + return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); } void brcms_debugfs_detach(struct brcms_pub *drvr) diff --git a/drivers/platform/x86/samsung-q10.c b/drivers/platform/x86/samsung-q10.c index 1a90b62a71c..4430b8c1369 100644 --- a/drivers/platform/x86/samsung-q10.c +++ b/drivers/platform/x86/samsung-q10.c @@ -176,7 +176,7 @@ static int __init samsungq10_init(void) samsungq10_probe, NULL, 0, NULL, 0); - return PTR_RET(samsungq10_device); + return PTR_ERR_OR_ZERO(samsungq10_device); } static void __exit samsungq10_exit(void) diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index f0e1ae52bb0..192444a8dab 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -219,7 +219,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, rdesc->owner = THIS_MODULE; di->rdev = regulator_register(&di->desc, config); - return PTR_RET(di->rdev); + return PTR_ERR_OR_ZERO(di->rdev); } diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 41e89c3e3ed..ca0ddb8cef5 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -901,7 +901,7 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev) return -EINVAL; master = fsl_spi_probe(&pdev->dev, mem, irq); - return PTR_RET(master); + return PTR_ERR_OR_ZERO(master); } static int plat_mpc8xxx_spi_remove(struct platform_device *pdev) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 911e9e0711d..ca5bcfe874d 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -603,7 +603,7 @@ static int spidev_probe(struct spi_device *spi) dev = device_create(spidev_class, &spi->dev, spidev->devt, spidev, "spidev%d.%d", spi->master->bus_num, spi->chip_select); - status = PTR_RET(dev); + status = PTR_ERR_OR_ZERO(dev); } else { dev_dbg(&spi->dev, "no minor number available!\n"); status = -ENODEV; diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 1aeb274e30f..a7ce26c090d 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -189,7 +189,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, write, &dss_debug_fops); - return PTR_RET(d); + return PTR_ERR_OR_ZERO(d); } #else /* CONFIG_OMAP2_DSS_DEBUGFS */ static inline int dss_initialize_debugfs(void) diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 4253ad580e3..5f8f3341c09 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -747,7 +747,7 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info) WARN_ON(atomic_xchg( &fs_info->mutually_exclusive_operation_running, 1)); task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl"); - return PTR_RET(task); + return PTR_ERR_OR_ZERO(task); } static int btrfs_dev_replace_kthread(void *data) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6d1b93c8aaf..2987e1755d6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3166,7 +3166,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) found_key.type = BTRFS_INODE_ITEM_KEY; found_key.offset = 0; inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); - ret = PTR_RET(inode); + ret = PTR_ERR_OR_ZERO(inode); if (ret && ret != -ESTALE) goto out; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 7ad6ecf36f2..edf623a2904 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -590,7 +590,7 @@ int __init bt_sysfs_init(void) bt_class = class_create(THIS_MODULE, "bluetooth"); - return PTR_RET(bt_class); + return PTR_ERR_OR_ZERO(bt_class); } void bt_sysfs_cleanup(void) diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 70f656ce0f4..dbd1c783431 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -64,7 +64,7 @@ static int ebt_broute(struct sk_buff *skb) static int __net_init broute_net_init(struct net *net) { net->xt.broute_table = ebt_register_table(net, &broute_table); - return PTR_RET(net->xt.broute_table); + return PTR_ERR_OR_ZERO(net->xt.broute_table); } static void __net_exit broute_net_exit(struct net *net) diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index 3c2e9dced9e..94b2b700cff 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -100,7 +100,7 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { static int __net_init frame_filter_net_init(struct net *net) { net->xt.frame_filter = ebt_register_table(net, &frame_filter); - return PTR_RET(net->xt.frame_filter); + return PTR_ERR_OR_ZERO(net->xt.frame_filter); } static void __net_exit frame_filter_net_exit(struct net *net) diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 10871bc7790..322555acdd4 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -100,7 +100,7 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { static int __net_init frame_nat_net_init(struct net *net) { net->xt.frame_nat = ebt_register_table(net, &frame_nat); - return PTR_RET(net->xt.frame_nat); + return PTR_ERR_OR_ZERO(net->xt.frame_nat); } static void __net_exit frame_nat_net_exit(struct net *net) diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index eadab1ed650..a865f6f9401 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c @@ -48,7 +48,7 @@ static int __net_init arptable_filter_net_init(struct net *net) net->ipv4.arptable_filter = arpt_register_table(net, &packet_filter, repl); kfree(repl); - return PTR_RET(net->ipv4.arptable_filter); + return PTR_ERR_OR_ZERO(net->ipv4.arptable_filter); } static void __net_exit arptable_filter_net_exit(struct net *net) diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 6b3da5cf54e..50af5b45c05 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c @@ -69,7 +69,7 @@ static int __net_init iptable_filter_net_init(struct net *net) net->ipv4.iptable_filter = ipt_register_table(net, &packet_filter, repl); kfree(repl); - return PTR_RET(net->ipv4.iptable_filter); + return PTR_ERR_OR_ZERO(net->ipv4.iptable_filter); } static void __net_exit iptable_filter_net_exit(struct net *net) diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index cba5658ec82..0d8cd82e0fa 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c @@ -107,7 +107,7 @@ static int __net_init iptable_mangle_net_init(struct net *net) net->ipv4.iptable_mangle = ipt_register_table(net, &packet_mangler, repl); kfree(repl); - return PTR_RET(net->ipv4.iptable_mangle); + return PTR_ERR_OR_ZERO(net->ipv4.iptable_mangle); } static void __net_exit iptable_mangle_net_exit(struct net *net) diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c index 6383273d54e..683bfaffed6 100644 --- a/net/ipv4/netfilter/iptable_nat.c +++ b/net/ipv4/netfilter/iptable_nat.c @@ -292,7 +292,7 @@ static int __net_init iptable_nat_net_init(struct net *net) return -ENOMEM; net->ipv4.nat_table = ipt_register_table(net, &nf_nat_ipv4_table, repl); kfree(repl); - return PTR_RET(net->ipv4.nat_table); + return PTR_ERR_OR_ZERO(net->ipv4.nat_table); } static void __net_exit iptable_nat_net_exit(struct net *net) diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 03d9696d3c6..1f82aea11df 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -48,7 +48,7 @@ static int __net_init iptable_raw_net_init(struct net *net) net->ipv4.iptable_raw = ipt_register_table(net, &packet_raw, repl); kfree(repl); - return PTR_RET(net->ipv4.iptable_raw); + return PTR_ERR_OR_ZERO(net->ipv4.iptable_raw); } static void __net_exit iptable_raw_net_exit(struct net *net) diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c index b283d8e2601..f867a8d38bf 100644 --- a/net/ipv4/netfilter/iptable_security.c +++ b/net/ipv4/netfilter/iptable_security.c @@ -66,7 +66,7 @@ static int __net_init iptable_security_net_init(struct net *net) net->ipv4.iptable_security = ipt_register_table(net, &security_table, repl); kfree(repl); - return PTR_RET(net->ipv4.iptable_security); + return PTR_ERR_OR_ZERO(net->ipv4.iptable_security); } static void __net_exit iptable_security_net_exit(struct net *net) diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index beb5777d204..29b44b14c5e 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c @@ -61,7 +61,7 @@ static int __net_init ip6table_filter_net_init(struct net *net) net->ipv6.ip6table_filter = ip6t_register_table(net, &packet_filter, repl); kfree(repl); - return PTR_RET(net->ipv6.ip6table_filter); + return PTR_ERR_OR_ZERO(net->ipv6.ip6table_filter); } static void __net_exit ip6table_filter_net_exit(struct net *net) diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index e075399d8b7..c705907ae6a 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c @@ -101,7 +101,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net) net->ipv6.ip6table_mangle = ip6t_register_table(net, &packet_mangler, repl); kfree(repl); - return PTR_RET(net->ipv6.ip6table_mangle); + return PTR_ERR_OR_ZERO(net->ipv6.ip6table_mangle); } static void __net_exit ip6table_mangle_net_exit(struct net *net) diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index 6383f90efda..9b076d2d3a7 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c @@ -293,7 +293,7 @@ static int __net_init ip6table_nat_net_init(struct net *net) return -ENOMEM; net->ipv6.ip6table_nat = ip6t_register_table(net, &nf_nat_ipv6_table, repl); kfree(repl); - return PTR_RET(net->ipv6.ip6table_nat); + return PTR_ERR_OR_ZERO(net->ipv6.ip6table_nat); } static void __net_exit ip6table_nat_net_exit(struct net *net) diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index 60d1bddff7a..9a626d86720 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c @@ -40,7 +40,7 @@ static int __net_init ip6table_raw_net_init(struct net *net) net->ipv6.ip6table_raw = ip6t_register_table(net, &packet_raw, repl); kfree(repl); - return PTR_RET(net->ipv6.ip6table_raw); + return PTR_ERR_OR_ZERO(net->ipv6.ip6table_raw); } static void __net_exit ip6table_raw_net_exit(struct net *net) diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c index db155351339..ce88d1d7e52 100644 --- a/net/ipv6/netfilter/ip6table_security.c +++ b/net/ipv6/netfilter/ip6table_security.c @@ -58,7 +58,7 @@ static int __net_init ip6table_security_net_init(struct net *net) net->ipv6.ip6table_security = ip6t_register_table(net, &security_table, repl); kfree(repl); - return PTR_RET(net->ipv6.ip6table_security); + return PTR_ERR_OR_ZERO(net->ipv6.ip6table_security); } static void __net_exit ip6table_security_net_exit(struct net *net) diff --git a/scripts/coccinelle/api/ptr_ret.cocci b/scripts/coccinelle/api/ptr_ret.cocci index 2274638d005..e18f8402e37 100644 --- a/scripts/coccinelle/api/ptr_ret.cocci +++ b/scripts/coccinelle/api/ptr_ret.cocci @@ -1,5 +1,5 @@ /// -/// Use PTR_RET rather than if(IS_ERR(...)) + PTR_ERR +/// Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR /// // Confidence: High // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. @@ -7,7 +7,7 @@ // URL: http://coccinelle.lip6.fr/ // Options: --no-includes --include-headers // -// Keywords: ERR_PTR, PTR_ERR, PTR_RET +// Keywords: ERR_PTR, PTR_ERR, PTR_RET, PTR_ERR_OR_ZERO // Version min: 2.6.39 // @@ -21,21 +21,21 @@ expression ptr; @@ - if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; -+ return PTR_RET(ptr); ++ return PTR_ERR_OR_ZERO(ptr); @depends on patch@ expression ptr; @@ - if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; -+ return PTR_RET(ptr); ++ return PTR_ERR_OR_ZERO(ptr); @depends on patch@ expression ptr; @@ - (IS_ERR(ptr) ? PTR_ERR(ptr) : 0) -+ PTR_RET(ptr) ++ PTR_ERR_OR_ZERO(ptr) @r1 depends on !patch@ expression ptr; diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 8ca9ecc5ac5..122c0c18b9d 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -158,7 +158,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, return -EINVAL; } - return PTR_RET(codec->control_data); + return PTR_ERR_OR_ZERO(codec->control_data); } EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); #else -- cgit v1.2.3-70-g09d2 From 228b82211b47b597fa75dff2ac146b40eaaddf18 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 15 Jul 2013 11:21:32 +0930 Subject: s390: Replace weird use of PTR_RET. Saves repeating "(void __force *)__uptr" but it's less clear. Using the output of PTR_RET() to determine the error rather than just testing IS_ERR() is odd. For example, I *assume* __gptr_to_uptr() never returns NULL? Because the __ret would be 0 for the old code. The new version is clearer, IMHO: it would try to get_user() on that address. If you hate this variant, I can just s/PTR_RET/PTR_ERR_OR_ZERO/ instead. Cc: Christian Borntraeger Cc: Martin Schwidefsky Signed-off-by: Rusty Russell Acked-by: Heiko Carstens --- arch/s390/kvm/gaccess.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index 302e0e52b00..99d789e8a01 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h @@ -42,9 +42,11 @@ static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu, ({ \ __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\ int __mask = sizeof(__typeof__(*(gptr))) - 1; \ - int __ret = PTR_RET((void __force *)__uptr); \ + int __ret; \ \ - if (!__ret) { \ + if (IS_ERR((void __force *)__uptr)) { \ + __ret = PTR_ERR((void __force *)__uptr); \ + } else { \ BUG_ON((unsigned long)__uptr & __mask); \ __ret = get_user(x, __uptr); \ } \ @@ -55,9 +57,11 @@ static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu, ({ \ __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\ int __mask = sizeof(__typeof__(*(gptr))) - 1; \ - int __ret = PTR_RET((void __force *)__uptr); \ + int __ret; \ \ - if (!__ret) { \ + if (IS_ERR((void __force *)__uptr)) { \ + __ret = PTR_ERR((void __force *)__uptr); \ + } else { \ BUG_ON((unsigned long)__uptr & __mask); \ __ret = put_user(x, __uptr); \ } \ -- cgit v1.2.3-70-g09d2 From 170ab436bff98f765ce365532d780d07aa1a576d Mon Sep 17 00:00:00 2001 From: Emilio López Date: Sun, 7 Jul 2013 18:31:56 -0300 Subject: ARM: sun5i: dt: Add I2C muxings for sun5i A10S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The information has been extracted from the A10S-OLinuXino-Micro schematics, as we do not have a user manual for A10S yet. Signed-off-by: Emilio López Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-a10s.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 2307ce827ae..7c9f88f701b 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -229,6 +229,27 @@ allwinner,drive = <0>; allwinner,pull = <0>; }; + + i2c0_pins_a: i2c0@0 { + allwinner,pins = "PB0", "PB1"; + allwinner,function = "i2c0"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + i2c1_pins_a: i2c1@0 { + allwinner,pins = "PB15", "PB16"; + allwinner,function = "i2c1"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + i2c2_pins_a: i2c2@0 { + allwinner,pins = "PB17", "PB18"; + allwinner,function = "i2c2"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; }; timer@01c20c00 { -- cgit v1.2.3-70-g09d2 From ca3d4ed5914b7e367a9079ce765bbe26332eb780 Mon Sep 17 00:00:00 2001 From: Emilio López Date: Sun, 7 Jul 2013 18:31:57 -0300 Subject: ARM: sun5i: dt: Add I2C controller nodes to the A10S dtsi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allwinner A10S has 3 I2C controllers embedded on it. Add them to the corresponding dtsi. Signed-off-by: Emilio López Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-a10s.dtsi | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 7c9f88f701b..0f0881a7ac8 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -303,5 +303,38 @@ clocks = <&apb1_gates 19>; status = "disabled"; }; + + i2c0: i2c@01c2ac00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2ac00 0x400>; + interrupts = <7>; + clocks = <&apb1_gates 0>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c1: i2c@01c2b000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = <8>; + clocks = <&apb1_gates 1>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c2: i2c@01c2b400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2b400 0x400>; + interrupts = <9>; + clocks = <&apb1_gates 2>; + clock-frequency = <100000>; + status = "disabled"; + }; }; }; -- cgit v1.2.3-70-g09d2 From d6c451dd2c388cb32d3a20e3c74c11cc84999ad0 Mon Sep 17 00:00:00 2001 From: Emilio López Date: Sun, 7 Jul 2013 18:31:58 -0300 Subject: ARM: sun5i: dt: Enable I2C controllers on A10S-OLinuXino-Micro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This board from OLIMEX is using the three I2C controllers present on A10S: * I2C-0 connects to the AXP152 PMU * I2C-1 holds an AT24C16BN-SH EEPROM with the MAC address for ethernet * I2C-2 is used for UEXT modules. Signed-off-by: Emilio López Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts index 64dc0c42c43..2a69ddffb65 100644 --- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts +++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts @@ -60,6 +60,24 @@ pinctrl-0 = <&uart3_pins_a>; status = "okay"; }; + + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; + + i2c2: i2c@01c2b400 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; + }; }; leds { -- cgit v1.2.3-70-g09d2 From bdbfd8e0bb86dcd59f6cfa3278e361c56933fec1 Mon Sep 17 00:00:00 2001 From: Emilio López Date: Sun, 7 Jul 2013 18:31:59 -0300 Subject: ARM: sun5i: dt: Add AT24 device on A10S-OLinuXino-Micro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This OLIMEX board has a AT24C16BN-SH EEPROM holding the MAC address. This patch adds the corresponding device tree node to reflect this. Signed-off-by: Emilio López Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts index 2a69ddffb65..24dd8bb7df8 100644 --- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts +++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts @@ -71,6 +71,13 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins_a>; status = "okay"; + + at24@50 { + compatible = "at,24c16"; + pagesize = <16>; + reg = <0x50>; + read-only; + }; }; i2c2: i2c@01c2b400 { -- cgit v1.2.3-70-g09d2 From 21b341cac2cdc52d59db5bd936a5c6b325286c2d Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 10 Jul 2013 12:30:43 +0530 Subject: ARM: tegra: enable gpio-keys on Dalmore Dalmore have the keys mounted on board which are connected to different pins of Tegra. Add the keys entry in DTS file to enable key functionality. This will enable KEY_POWER, KEY_HOME, KEY_VOLUMEUP and KEY_VOLUMEDOWN. Signed-off-by: Laxman Dewangan Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra114-dalmore.dts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index cb640eb6c93..a42bfa4211a 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts @@ -883,6 +883,35 @@ }; }; + gpio-keys { + compatible = "gpio-keys"; + + home { + label = "Home"; + gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + linux,code = <102>; /* KEY_HOME */ + }; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>; + linux,code = <116>; /* KEY_POWER */ + gpio-key,wakeup; + }; + + volume_down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW>; + linux,code = <114>; /* KEY_VOLUMEDOWN */ + }; + + volume_up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW>; + linux,code = <115>; /* KEY_VOLUMEUP */ + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; -- cgit v1.2.3-70-g09d2 From 74ecab275dfbd00bf3f1daa7f0be0c0288fbeac4 Mon Sep 17 00:00:00 2001 From: Wei Ni Date: Fri, 12 Jul 2013 15:49:23 +0800 Subject: ARM: tegra: add DT entry for nct1008 to Cardhu Enable thermal sensor nct1008 for Tegra30 Cardhu. Signed-off-by: Wei Ni Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra30-cardhu.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index f65b53d3241..e5759caae77 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -286,6 +286,13 @@ }; }; }; + + nct1008 { + compatible = "onnn,nct1008"; + reg = <0x4c>; + interrupt-parent = <&gpio>; + interrupts = ; + }; }; spi@7000da00 { -- cgit v1.2.3-70-g09d2 From 2b8584d5d2f4ba5b4eb49e500c1dd8f7a9784132 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 15 Jul 2013 10:33:53 -0600 Subject: ARM: tegra: fix DT node ordering in Tegra30 Cardhu Nodes should be sorted by reg. Fix location of the tps62361 node. Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra30-cardhu.dtsi | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index e5759caae77..c011b679764 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -173,19 +173,6 @@ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>; }; - tps62361 { - compatible = "ti,tps62361"; - reg = <0x60>; - - regulator-name = "tps62361-vout"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - ti,vsel0-state-high; - ti,vsel1-state-high; - }; - pmic: tps65911@2d { compatible = "ti,tps65911"; reg = <0x2d>; @@ -293,6 +280,19 @@ interrupt-parent = <&gpio>; interrupts = ; }; + + tps62361 { + compatible = "ti,tps62361"; + reg = <0x60>; + + regulator-name = "tps62361-vout"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + ti,vsel0-state-high; + ti,vsel1-state-high; + }; }; spi@7000da00 { -- cgit v1.2.3-70-g09d2 From f2bd77c8f3b8c108bc460e779585854fbd2d8c59 Mon Sep 17 00:00:00 2001 From: Joseph Lo Date: Wed, 3 Jul 2013 17:55:48 +0800 Subject: ARM: tegra: enable Cortex-A15 erratum 798181 The commit 93dc688 (ARM: 7684/1: errata: Workaround for Cortex-A15 erratum 798181 (TLBI/DSB operations)) introduced a workaround for Cortex-A15 erratum 798181. Enable it for Tegra114. Signed-off-by: Joseph Lo Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index ef3a8da49b2..add345e6a6b 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -59,6 +59,7 @@ config ARCH_TEGRA_3x_SOC config ARCH_TEGRA_114_SOC bool "Enable support for Tegra114 family" select HAVE_ARM_ARCH_TIMER + select ARM_ERRATA_798181 select ARM_GIC select ARM_L1_CACHE_SHIFT_6 select CPU_V7 -- cgit v1.2.3-70-g09d2 From bcfed2a8a61a0f6ee7769f5093a8279a9e50c526 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 6 Jun 2013 17:38:11 +0200 Subject: ARM: shmobile: armadillo800eva: remove left-overs A comment and a #define in board-armadillo800eva.c have been left over after recent changes and are no longer relevant or needed, remove them. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-armadillo800eva.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index e115f674210..66cfd568657 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -679,15 +679,6 @@ static struct platform_device vcc_sdhi1 = { }; /* SDHI0 */ -/* - * FIXME - * - * It use polling mode here, since - * CD (= Card Detect) pin is not connected to SDHI0_CD. - * We can use IRQ31 as card detect irq, - * but it needs chattering removal operation - */ -#define IRQ31 irq_pin(31) static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, -- cgit v1.2.3-70-g09d2 From eb2cabd7cfa25c0ec4a099bf632ad9bae3be79f1 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 15 Jul 2013 12:52:52 -0600 Subject: ARM: tegra: remove tegra114-pluto.dts Early upstream work on Tegra114 was performed on the Pluto board. However, it's not used any more, and the DT doesn't contain anything beyond a serial port, so the file isn't useful either. Remove it. Signed-off-by: Stephen Warren --- arch/arm/boot/dts/Makefile | 3 +-- arch/arm/boot/dts/tegra114-pluto.dts | 33 --------------------------------- 2 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 arch/arm/boot/dts/tegra114-pluto.dts (limited to 'arch') diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 641b3c9a702..de39162a7c0 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -224,8 +224,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra30-beaver.dtb \ tegra30-cardhu-a02.dtb \ tegra30-cardhu-a04.dtb \ - tegra114-dalmore.dtb \ - tegra114-pluto.dtb + tegra114-dalmore.dtb dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \ versatile-pb.dtb dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb diff --git a/arch/arm/boot/dts/tegra114-pluto.dts b/arch/arm/boot/dts/tegra114-pluto.dts deleted file mode 100644 index d5f8d3e0bde..00000000000 --- a/arch/arm/boot/dts/tegra114-pluto.dts +++ /dev/null @@ -1,33 +0,0 @@ -/dts-v1/; - -#include "tegra114.dtsi" - -/ { - model = "NVIDIA Tegra114 Pluto evaluation board"; - compatible = "nvidia,pluto", "nvidia,tegra114"; - - memory { - reg = <0x80000000 0x40000000>; - }; - - serial@70006300 { - status = "okay"; - }; - - pmc { - nvidia,invert-interrupt; - }; - - clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - clk32k_in: clock { - compatible = "fixed-clock"; - reg=<0>; - #clock-cells = <0>; - clock-frequency = <32768>; - }; - }; -}; -- cgit v1.2.3-70-g09d2 From c9031fbb35bd44d99c5cfe7d3c97ec238d63643a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 26 May 2013 17:53:37 -0700 Subject: ARM: shmobile: r8a7778: add __initdata on resource and device data These data will be kmemdup()'ed on platform_device_add_resources() and platform_device_add_data() Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7778.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 80c20392ad7..b70bfeef2f6 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -53,7 +53,7 @@ .irqs = SCIx_IRQ_MUXED(irq), \ } -static struct plat_sci_port scif_platform_data[] = { +static struct plat_sci_port scif_platform_data[] __initdata = { SCIF_INFO(0xffe40000, gic_iid(0x66)), SCIF_INFO(0xffe41000, gic_iid(0x67)), SCIF_INFO(0xffe42000, gic_iid(0x68)), @@ -63,24 +63,24 @@ static struct plat_sci_port scif_platform_data[] = { }; /* TMU */ -static struct resource sh_tmu0_resources[] = { +static struct resource sh_tmu0_resources[] __initdata = { DEFINE_RES_MEM(0xffd80008, 12), DEFINE_RES_IRQ(gic_iid(0x40)), }; -static struct sh_timer_config sh_tmu0_platform_data = { +static struct sh_timer_config sh_tmu0_platform_data __initdata = { .name = "TMU00", .channel_offset = 0x4, .timer_bit = 0, .clockevent_rating = 200, }; -static struct resource sh_tmu1_resources[] = { +static struct resource sh_tmu1_resources[] __initdata = { DEFINE_RES_MEM(0xffd80014, 12), DEFINE_RES_IRQ(gic_iid(0x41)), }; -static struct sh_timer_config sh_tmu1_platform_data = { +static struct sh_timer_config sh_tmu1_platform_data __initdata = { .name = "TMU01", .channel_offset = 0x10, .timer_bit = 1, @@ -189,7 +189,7 @@ USB_PLATFORM_INFO(ehci); USB_PLATFORM_INFO(ohci); /* Ether */ -static struct resource ether_resources[] = { +static struct resource ether_resources[] __initdata = { DEFINE_RES_MEM(0xfde00000, 0x400), DEFINE_RES_IRQ(gic_iid(0x89)), }; @@ -203,17 +203,17 @@ void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) } /* PFC/GPIO */ -static struct resource pfc_resources[] = { +static struct resource pfc_resources[] __initdata = { DEFINE_RES_MEM(0xfffc0000, 0x118), }; #define R8A7778_GPIO(idx) \ -static struct resource r8a7778_gpio##idx##_resources[] = { \ +static struct resource r8a7778_gpio##idx##_resources[] __initdata = { \ DEFINE_RES_MEM(0xffc40000 + 0x1000 * (idx), 0x30), \ DEFINE_RES_IRQ(gic_iid(0x87)), \ }; \ \ -static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data = { \ +static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data __initdata = { \ .gpio_base = 32 * (idx), \ .irq_base = GPIO_IRQ_BASE(idx), \ .number_of_pins = 32, \ @@ -249,7 +249,7 @@ void __init r8a7778_pinmux_init(void) }; /* SDHI */ -static struct resource sdhi_resources[] = { +static struct resource sdhi_resources[] __initdata = { /* SDHI0 */ DEFINE_RES_MEM(0xFFE4C000, 0x100), DEFINE_RES_IRQ(gic_iid(0x77)), @@ -365,12 +365,12 @@ void __init r8a7778_init_late(void) platform_device_register_full(&ohci_info); } -static struct renesas_intc_irqpin_config irqpin_platform_data = { +static struct renesas_intc_irqpin_config irqpin_platform_data __initdata = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ .sense_bitfield_width = 2, }; -static struct resource irqpin_resources[] = { +static struct resource irqpin_resources[] __initdata = { DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */ DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */ DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */ -- cgit v1.2.3-70-g09d2 From 474f67587345bf7b32bbd9d2b5621e85500103c5 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 27 Jun 2013 17:09:01 +0900 Subject: ARM: shmobile: sh73a0 pinmux platform device cleanup Use DEFINE_RES_MEM() and platform_device_register_simple() to save a couple of lines of code. Signed-off-by: Magnus Damm Acked-by: Laurent Pinchart [ remove const from resource pfc_resources to avoid section miss-match reported by 4.4.5 ] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 96e7ca1e4e1..79a6040774a 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -61,29 +61,16 @@ void __init sh73a0_map_io(void) iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); } -static struct resource sh73a0_pfc_resources[] = { - [0] = { - .start = 0xe6050000, - .end = 0xe6057fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0xe605801c, - .end = 0xe6058027, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device sh73a0_pfc_device = { - .name = "pfc-sh73a0", - .id = -1, - .resource = sh73a0_pfc_resources, - .num_resources = ARRAY_SIZE(sh73a0_pfc_resources), +/* PFC */ +static struct resource pfc_resources[] __initdata = { + DEFINE_RES_MEM(0xe6050000, 0x8000), + DEFINE_RES_MEM(0xe605801c, 0x000c), }; void __init sh73a0_pinmux_init(void) { - platform_device_register(&sh73a0_pfc_device); + platform_device_register_simple("pfc-sh73a0", -1, pfc_resources, + ARRAY_SIZE(pfc_resources)); } static struct plat_sci_port scif0_platform_data = { -- cgit v1.2.3-70-g09d2 From 34dd9fc04a028edad7658006764c4d18ac3dca73 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sun, 26 May 2013 22:05:23 +0900 Subject: ARM: shmobile: emev2: Remove init_irq declaration in machine description Commit ebafed7a ("ARM: irq: Call irqchip_init if no init_irq function is specified") removed the need to explictly setup the init_irq field in the machine description when using only irqchip_init. Remove that declaration for shmobile as well. Signed-off-by: Maxime Ripard Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-emev2.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 1ccddd22811..6e8b6ac3c6b 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -454,7 +453,6 @@ DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") .smp = smp_ops(emev2_smp_ops), .init_early = emev2_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_irq = irqchip_init, .init_machine = emev2_add_standard_devices_dt, .dt_compat = emev2_boards_compat_dt, MACHINE_END -- cgit v1.2.3-70-g09d2 From 0bdbe04db005e025d3522ad3ae9797a4954528e9 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sun, 26 May 2013 22:05:56 +0900 Subject: ARM: shmobile: r8a73a4: Remove init_irq declaration in machine description Commit ebafed7a ("ARM: irq: Call irqchip_init if no init_irq function is specified") removed the need to explictly setup the init_irq field in the machine description when using only irqchip_init. Remove that declaration for shmobile as well. Signed-off-by: Maxime Ripard Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a73a4.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 7f45c2edbca..a8c4e41bf27 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include -#include #include #include #include @@ -194,7 +193,6 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") - .init_irq = irqchip_init, .init_machine = r8a73a4_add_standard_devices_dt, .init_time = shmobile_timer_init, .dt_compat = r8a73a4_boards_compat_dt, -- cgit v1.2.3-70-g09d2 From c7f6085f6ea7b7cf155f470431cf1b12cd999450 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 15:01:21 +0900 Subject: ARM: shmobile: ape6evm: Remove init_irq declaration in machine description Remove redundant irqchip_init() callback. The default case of NULL will result in invoking irqchip_init() anyway. Signed-off-by: Magnus Damm [ horms+renesas@verge.net.au: Trimmed patch to remove portion that updates the r8a73a4 SoC and altered the subject to use the same format as the patch that updates the r8a73a4. ] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-ape6evm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index 5eb0caa6a7d..1fbc39a14e2 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -102,7 +101,6 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_irq = irqchip_init, .init_time = shmobile_timer_init, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, -- cgit v1.2.3-70-g09d2 From 125332daf2e4119614c561bc8cbf1f49cd243023 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2013 18:00:22 +0900 Subject: ARM: shmobile: r8a7790: Remove init_irq declaration in machine description Commit ebafed7a ("ARM: irq: Call irqchip_init if no init_irq function is specified") removed the need to explictly setup the init_irq field in the machine description when using only irqchip_init. Remove that declaration for shmobile as well. Signed-off-by: Maxime Ripard Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7790.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 28f94752b8f..d405dbd44b0 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -19,7 +19,6 @@ */ #include -#include #include #include #include @@ -188,7 +187,6 @@ static const char *r8a7790_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") - .init_irq = irqchip_init, .init_machine = r8a7790_add_standard_devices_dt, .init_time = r8a7790_timer_init, .dt_compat = r8a7790_boards_compat_dt, -- cgit v1.2.3-70-g09d2 From 5f85052c606e38c98de28170a2df72f78931aa30 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 15:01:31 +0900 Subject: ARM: shmobile: lager: Remove init_irq declaration in machine description Remove redundant irqchip_init() callback. The default case of NULL will result in invoking irqchip_init() anyway. Signed-off-by: Magnus Damm [ horms+renesas@verge.net.au: Trimmed patch to remove portion that updates the r8a7790 SoC and altered the subject to use the same format as the patch that updates the r8a7790. ] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-lager.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index d73e21d3ea8..1e99b17767b 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -103,7 +102,6 @@ static const char *lager_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(LAGER_DT, "lager") - .init_irq = irqchip_init, .init_time = r8a7790_timer_init, .init_machine = lager_add_standard_devices, .dt_compat = lager_boards_compat_dt, -- cgit v1.2.3-70-g09d2 From 7d6b8883547feacc705c476cdb7f272e309d9fb0 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2013 18:00:49 +0900 Subject: ARM: shmobile: sh73a0: Remove init_irq declaration in machine description Commit ebafed7a ("ARM: irq: Call irqchip_init if no init_irq function is specified") removed the need to explictly setup the init_irq field in the machine description when using only irqchip_init. Remove that declaration for shmobile as well. Signed-off-by: Maxime Ripard Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 79a6040774a..bd9370f2697 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -975,7 +974,6 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") .map_io = sh73a0_map_io, .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_irq = irqchip_init, .init_machine = sh73a0_add_standard_devices_dt, .dt_compat = sh73a0_boards_compat_dt, MACHINE_END -- cgit v1.2.3-70-g09d2 From fc492ba58aa6642f34eba716daf6ec4d2715e492 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 15:01:40 +0900 Subject: ARM: shmobile: kzm9g: Remove init_irq declaration in machine description Remove redundant irqchip_init() callback. The default case of NULL will result in invoking irqchip_init() anyway. Signed-off-by: Magnus Damm [ horms+renesas@verge.net.au: Trimmed patch to remove portion that updates the sh73a0 SoC and altered the subject to use the same format as the patch that updates the sh73a0. ] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9g-reference.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index 44055fe8a45..41092bb01ee 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -99,7 +98,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g-reference") .map_io = sh73a0_map_io, .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_irq = irqchip_init, .init_machine = kzm_init, .init_time = shmobile_timer_init, .dt_compat = kzm9g_boards_compat_dt, -- cgit v1.2.3-70-g09d2 From a597d8df88143f7a409b260b1e89735eb0bdca05 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:41:15 +0900 Subject: ARM: shmobile: Remove unused EMEV2 auxdata and callback Replace the SoC-specific callback init_machine() with a NULL to use the default code. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-emev2.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 6e8b6ac3c6b..b0564ce116e 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -434,15 +434,6 @@ void __init emev2_init_irq(void) } #ifdef CONFIG_USE_OF -static const struct of_dev_auxdata emev2_auxdata_lookup[] __initconst = { - { } -}; - -static void __init emev2_add_standard_devices_dt(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - emev2_auxdata_lookup, NULL); -} static const char *emev2_boards_compat_dt[] __initdata = { "renesas,emev2", @@ -453,7 +444,6 @@ DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") .smp = smp_ops(emev2_smp_ops), .init_early = emev2_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_machine = emev2_add_standard_devices_dt, .dt_compat = emev2_boards_compat_dt, MACHINE_END -- cgit v1.2.3-70-g09d2 From 88378837780166d67a11142cd6f76596c0a2d8c3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:41:24 +0900 Subject: ARM: shmobile: Remove unused r8a7740 auxdata table Pass NULL to of_platform_populate instead of passing an empty list. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7740.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 00c5a707238..ac29c2ee011 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -986,16 +986,22 @@ void __init r8a7740_add_early_devices(void) #ifdef CONFIG_USE_OF -static const struct of_dev_auxdata r8a7740_auxdata_lookup[] __initconst = { - { } -}; +void __init r8a7740_add_early_devices_dt(void) +{ + shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ + + early_platform_add_devices(r8a7740_early_devices, + ARRAY_SIZE(r8a7740_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); +} void __init r8a7740_add_standard_devices_dt(void) { platform_add_devices(r8a7740_devices_dt, ARRAY_SIZE(r8a7740_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, - r8a7740_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } void __init r8a7740_init_delay(void) -- cgit v1.2.3-70-g09d2 From 40216263d3d0b9b46688a28a96daf66fe75caa28 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:41:33 +0900 Subject: ARM: shmobile: Remove unused r8a7778 auxdata and callback Replace the SoC-specific callback init_machine() with a NULL to use the default code. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7778.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index b70bfeef2f6..2a101ebdedf 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -457,16 +457,6 @@ void __init r8a7778_init_irq_dt(void) r8a7778_init_irq_common(); } -static const struct of_dev_auxdata r8a7778_auxdata_lookup[] __initconst = { - {}, -}; - -void __init r8a7778_add_standard_devices_dt(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - r8a7778_auxdata_lookup, NULL); -} - static const char *r8a7778_compat_dt[] __initdata = { "renesas,r8a7778", NULL, @@ -475,7 +465,6 @@ static const char *r8a7778_compat_dt[] __initdata = { DT_MACHINE_START(R8A7778_DT, "Generic R8A7778 (Flattened Device Tree)") .init_early = r8a7778_init_delay, .init_irq = r8a7778_init_irq_dt, - .init_machine = r8a7778_add_standard_devices_dt, .init_time = shmobile_timer_init, .dt_compat = r8a7778_compat_dt, .init_late = r8a7778_init_late, -- cgit v1.2.3-70-g09d2 From 41b0156ca5a1460f8f6dde7e57baf1b80d6a7030 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:41:46 +0900 Subject: ARM: shmobile: Remove unused r8a7779 auxdata table Pass NULL to of_platform_populate instead of passing an empty list. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7779.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 398687761f5..66d38261eca 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -665,10 +665,6 @@ void __init r8a7779_init_delay(void) shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */ } -static const struct of_dev_auxdata r8a7779_auxdata_lookup[] __initconst = { - {}, -}; - void __init r8a7779_add_standard_devices_dt(void) { /* clocks are setup late during boot in the case of DT */ @@ -676,8 +672,7 @@ void __init r8a7779_add_standard_devices_dt(void) platform_add_devices(r8a7779_devices_dt, ARRAY_SIZE(r8a7779_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, - r8a7779_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char *r8a7779_compat_dt[] __initdata = { -- cgit v1.2.3-70-g09d2 From 975e5af958916f8b76a8926cd4d50c04936d7079 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:41:55 +0900 Subject: ARM: shmobile: Remove unused sh7372 auxdata table Pass NULL to of_platform_populate instead of passing an empty list. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh7372.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 5502d624aca..13e6fdbde0a 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1147,10 +1147,6 @@ void __init sh7372_add_early_devices_dt(void) shmobile_setup_console(); } -static const struct of_dev_auxdata sh7372_auxdata_lookup[] __initconst = { - { } -}; - void __init sh7372_add_standard_devices_dt(void) { /* clocks are setup late during boot in the case of DT */ @@ -1159,8 +1155,7 @@ void __init sh7372_add_standard_devices_dt(void) platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); - of_platform_populate(NULL, of_default_bus_match_table, - sh7372_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char *sh7372_boards_compat_dt[] __initdata = { -- cgit v1.2.3-70-g09d2 From ea31597fe72245985e9d2521ea7e87acf2f14252 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:42:04 +0900 Subject: ARM: shmobile: Remove unused sh73a0 auxdata table Pass NULL to of_platform_populate instead of passing an empty list. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index bd9370f2697..516c2391b47 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -944,10 +944,6 @@ void __init sh73a0_add_early_devices(void) #ifdef CONFIG_USE_OF -static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = { - {}, -}; - void __init sh73a0_add_standard_devices_dt(void) { struct platform_device_info devinfo = { .name = "cpufreq-cpu0", .id = -1, }; @@ -957,8 +953,7 @@ void __init sh73a0_add_standard_devices_dt(void) platform_add_devices(sh73a0_devices_dt, ARRAY_SIZE(sh73a0_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, - sh73a0_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); /* Instantiate cpufreq-cpu0 */ platform_device_register_full(&devinfo); -- cgit v1.2.3-70-g09d2 From fdbc45dbbe5a69a2c665630ab577726e01eadf23 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 1 Jul 2013 14:42:13 +0900 Subject: ARM: shmobile: Remove redundant r8a7790 callback Replace the SoC-specific callback init_machine() with a NULL to use the default code. This cleans up the code and reduces the number of lines. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7790.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index d405dbd44b0..b7e78b9a7fd 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -176,10 +176,6 @@ void __init r8a7790_timer_init(void) } #ifdef CONFIG_USE_OF -void __init r8a7790_add_standard_devices_dt(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -} static const char *r8a7790_boards_compat_dt[] __initdata = { "renesas,r8a7790", @@ -187,7 +183,6 @@ static const char *r8a7790_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") - .init_machine = r8a7790_add_standard_devices_dt, .init_time = r8a7790_timer_init, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END -- cgit v1.2.3-70-g09d2 From 4146fa8861419ac0d2c3607168339621586f6c03 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 2 Jul 2013 18:27:33 +0900 Subject: ARM: shmobile: Remove unused EMEV2/KZM9D early console Remove EMEV2 early console code from KZM9D and instead rely on console setup during regular platform device probe time. This makes the DT code and the KZM9D board support behave the same. Signed-off-by: Magnus Damm Acked-by: Arnd Bergmann Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9d.c | 2 +- arch/arm/mach-shmobile/include/mach/emev2.h | 2 +- arch/arm/mach-shmobile/setup-emev2.c | 24 +++--------------------- 3 files changed, 5 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c index 4368000e112..15900f1f8af 100644 --- a/arch/arm/mach-shmobile/board-kzm9d.c +++ b/arch/arm/mach-shmobile/board-kzm9d.c @@ -85,7 +85,7 @@ static const char *kzm9d_boards_compat_dt[] __initdata = { DT_MACHINE_START(KZM9D_DT, "kzm9d") .smp = smp_ops(emev2_smp_ops), .map_io = emev2_map_io, - .init_early = emev2_add_early_devices, + .init_early = emev2_init_delay, .nr_irqs = NR_IRQS_LEGACY, .init_irq = emev2_init_irq, .init_machine = kzm9d_add_standard_devices, diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h index ac3751705ca..3e0c0441c78 100644 --- a/arch/arm/mach-shmobile/include/mach/emev2.h +++ b/arch/arm/mach-shmobile/include/mach/emev2.h @@ -3,7 +3,7 @@ extern void emev2_map_io(void); extern void emev2_init_irq(void); -extern void emev2_add_early_devices(void); +extern void emev2_init_delay(void); extern void emev2_add_standard_devices(void); extern void emev2_clock_init(void); extern void emev2_set_boot_vector(unsigned long value); diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index b0564ce116e..f6edd190a6b 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -375,14 +375,11 @@ static struct platform_device pmu_device = { .resource = pmu_resources, }; -static struct platform_device *emev2_early_devices[] __initdata = { +static struct platform_device *emev2_devices[] __initdata = { &uart0_device, &uart1_device, &uart2_device, &uart3_device, -}; - -static struct platform_device *emev2_late_devices[] __initdata = { &sti_device, &gio0_device, &gio1_device, @@ -396,29 +393,14 @@ void __init emev2_add_standard_devices(void) { emev2_clock_init(); - platform_add_devices(emev2_early_devices, - ARRAY_SIZE(emev2_early_devices)); - - platform_add_devices(emev2_late_devices, - ARRAY_SIZE(emev2_late_devices)); + platform_add_devices(emev2_devices, ARRAY_SIZE(emev2_devices)); } -static void __init emev2_init_delay(void) +void __init emev2_init_delay(void) { shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */ } -void __init emev2_add_early_devices(void) -{ - emev2_init_delay(); - - early_platform_add_devices(emev2_early_devices, - ARRAY_SIZE(emev2_early_devices)); - - /* setup early console here as well */ - shmobile_setup_console(); -} - void __init emev2_init_irq(void) { void __iomem *gic_dist_base; -- cgit v1.2.3-70-g09d2 From 210e179da2e39c965872b941a36e55ab78328e49 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 2 Jul 2013 18:27:49 +0900 Subject: ARM: shmobile: Make EMEV2 platform devices more compact Convert the EMEV2 SoC device setup code from using very verbose resources and static platform devices to the same style as more recent boards. This reduces the size of the code. Signed-off-by: Magnus Damm Acked-by: Arnd Bergmann Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-emev2.c | 321 +++++++---------------------------- 1 file changed, 61 insertions(+), 260 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index f6edd190a6b..e4b46930db5 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -62,102 +62,40 @@ void __init emev2_map_io(void) /* UART */ static struct resource uart0_resources[] = { - [0] = { - .start = 0xe1020000, - .end = 0xe1020037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 40, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart0_device = { - .name = "serial8250-em", - .id = 0, - .num_resources = ARRAY_SIZE(uart0_resources), - .resource = uart0_resources, + DEFINE_RES_MEM(0xe1020000, 0x38), + DEFINE_RES_IRQ(40), }; static struct resource uart1_resources[] = { - [0] = { - .start = 0xe1030000, - .end = 0xe1030037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 41, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart1_device = { - .name = "serial8250-em", - .id = 1, - .num_resources = ARRAY_SIZE(uart1_resources), - .resource = uart1_resources, + DEFINE_RES_MEM(0xe1030000, 0x38), + DEFINE_RES_IRQ(41), }; static struct resource uart2_resources[] = { - [0] = { - .start = 0xe1040000, - .end = 0xe1040037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 42, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart2_device = { - .name = "serial8250-em", - .id = 2, - .num_resources = ARRAY_SIZE(uart2_resources), - .resource = uart2_resources, + DEFINE_RES_MEM(0xe1040000, 0x38), + DEFINE_RES_IRQ(42), }; static struct resource uart3_resources[] = { - [0] = { - .start = 0xe1050000, - .end = 0xe1050037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 43, - .flags = IORESOURCE_IRQ, - } + DEFINE_RES_MEM(0xe1050000, 0x38), + DEFINE_RES_IRQ(43), }; -static struct platform_device uart3_device = { - .name = "serial8250-em", - .id = 3, - .num_resources = ARRAY_SIZE(uart3_resources), - .resource = uart3_resources, -}; +#define emev2_register_uart(idx) \ + platform_device_register_simple("serial8250-em", idx, \ + uart##idx##_resources, \ + ARRAY_SIZE(uart##idx##_resources)) /* STI */ static struct resource sti_resources[] = { - [0] = { - .name = "STI", - .start = 0xe0180000, - .end = 0xe0180053, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 157, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sti_device = { - .name = "em_sti", - .id = 0, - .resource = sti_resources, - .num_resources = ARRAY_SIZE(sti_resources), + DEFINE_RES_MEM(0xe0180000, 0x54), + DEFINE_RES_IRQ(157), }; +#define emev2_register_sti() \ + platform_device_register_simple("em_sti", 0, \ + sti_resources, \ + ARRAY_SIZE(sti_resources)) /* GIO */ static struct gpio_em_config gio0_config = { @@ -167,36 +105,10 @@ static struct gpio_em_config gio0_config = { }; static struct resource gio0_resources[] = { - [0] = { - .name = "GIO_000", - .start = 0xe0050000, - .end = 0xe005002b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_000", - .start = 0xe0050040, - .end = 0xe005005f, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 99, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 100, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio0_device = { - .name = "em_gio", - .id = 0, - .resource = gio0_resources, - .num_resources = ARRAY_SIZE(gio0_resources), - .dev = { - .platform_data = &gio0_config, - }, + DEFINE_RES_MEM(0xe0050000, 0x2c), + DEFINE_RES_MEM(0xe0050040, 0x20), + DEFINE_RES_IRQ(99), + DEFINE_RES_IRQ(100), }; static struct gpio_em_config gio1_config = { @@ -206,36 +118,10 @@ static struct gpio_em_config gio1_config = { }; static struct resource gio1_resources[] = { - [0] = { - .name = "GIO_032", - .start = 0xe0050080, - .end = 0xe00500ab, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_032", - .start = 0xe00500c0, - .end = 0xe00500df, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 101, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 102, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio1_device = { - .name = "em_gio", - .id = 1, - .resource = gio1_resources, - .num_resources = ARRAY_SIZE(gio1_resources), - .dev = { - .platform_data = &gio1_config, - }, + DEFINE_RES_MEM(0xe0050080, 0x2c), + DEFINE_RES_MEM(0xe00500c0, 0x20), + DEFINE_RES_IRQ(101), + DEFINE_RES_IRQ(102), }; static struct gpio_em_config gio2_config = { @@ -245,36 +131,10 @@ static struct gpio_em_config gio2_config = { }; static struct resource gio2_resources[] = { - [0] = { - .name = "GIO_064", - .start = 0xe0050100, - .end = 0xe005012b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_064", - .start = 0xe0050140, - .end = 0xe005015f, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 103, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 104, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio2_device = { - .name = "em_gio", - .id = 2, - .resource = gio2_resources, - .num_resources = ARRAY_SIZE(gio2_resources), - .dev = { - .platform_data = &gio2_config, - }, + DEFINE_RES_MEM(0xe0050100, 0x2c), + DEFINE_RES_MEM(0xe0050140, 0x20), + DEFINE_RES_IRQ(103), + DEFINE_RES_IRQ(104), }; static struct gpio_em_config gio3_config = { @@ -284,36 +144,10 @@ static struct gpio_em_config gio3_config = { }; static struct resource gio3_resources[] = { - [0] = { - .name = "GIO_096", - .start = 0xe0050180, - .end = 0xe00501ab, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_096", - .start = 0xe00501c0, - .end = 0xe00501df, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 105, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 106, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio3_device = { - .name = "em_gio", - .id = 3, - .resource = gio3_resources, - .num_resources = ARRAY_SIZE(gio3_resources), - .dev = { - .platform_data = &gio3_config, - }, + DEFINE_RES_MEM(0xe0050180, 0x2c), + DEFINE_RES_MEM(0xe00501c0, 0x20), + DEFINE_RES_IRQ(105), + DEFINE_RES_IRQ(106), }; static struct gpio_em_config gio4_config = { @@ -323,77 +157,44 @@ static struct gpio_em_config gio4_config = { }; static struct resource gio4_resources[] = { - [0] = { - .name = "GIO_128", - .start = 0xe0050200, - .end = 0xe005022b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_128", - .start = 0xe0050240, - .end = 0xe005025f, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 107, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 108, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_MEM(0xe0050200, 0x2c), + DEFINE_RES_MEM(0xe0050240, 0x20), + DEFINE_RES_IRQ(107), + DEFINE_RES_IRQ(108), }; -static struct platform_device gio4_device = { - .name = "em_gio", - .id = 4, - .resource = gio4_resources, - .num_resources = ARRAY_SIZE(gio4_resources), - .dev = { - .platform_data = &gio4_config, - }, -}; +#define emev2_register_gio(idx) \ + platform_device_register_resndata(&platform_bus, "em_gio", \ + idx, gio##idx##_resources, \ + ARRAY_SIZE(gio##idx##_resources), \ + &gio##idx##_config, \ + sizeof(struct gpio_em_config)) static struct resource pmu_resources[] = { - [0] = { - .start = 152, - .end = 152, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = 153, - .end = 153, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(152), + DEFINE_RES_IRQ(153), }; -static struct platform_device pmu_device = { - .name = "arm-pmu", - .id = -1, - .num_resources = ARRAY_SIZE(pmu_resources), - .resource = pmu_resources, -}; - -static struct platform_device *emev2_devices[] __initdata = { - &uart0_device, - &uart1_device, - &uart2_device, - &uart3_device, - &sti_device, - &gio0_device, - &gio1_device, - &gio2_device, - &gio3_device, - &gio4_device, - &pmu_device, -}; +#define emev2_register_pmu() \ + platform_device_register_simple("arm-pmu", -1, \ + pmu_resources, \ + ARRAY_SIZE(pmu_resources)) void __init emev2_add_standard_devices(void) { emev2_clock_init(); - platform_add_devices(emev2_devices, ARRAY_SIZE(emev2_devices)); + emev2_register_uart(0); + emev2_register_uart(1); + emev2_register_uart(2); + emev2_register_uart(3); + emev2_register_sti(); + emev2_register_gio(0); + emev2_register_gio(1); + emev2_register_gio(2); + emev2_register_gio(3); + emev2_register_gio(4); + emev2_register_pmu(); } void __init emev2_init_delay(void) -- cgit v1.2.3-70-g09d2 From 09cb2e366737ac70f1d7c6c0a3747a75c8f90f1e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 8 Jul 2013 15:20:05 +0900 Subject: ARM: shmobile: Fix EMEV2 clock comment typo Update the STI timer frequency comment to 32.768 kHz to fix 37 kHz typo. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-emev2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c index 4710f1847bb..56dd0cfcddc 100644 --- a/arch/arm/mach-shmobile/clock-emev2.c +++ b/arch/arm/mach-shmobile/clock-emev2.c @@ -221,7 +221,7 @@ void __init emev2_clock_init(void) smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE); BUG_ON(!smu_base); - /* setup STI timer to run on 37.768 kHz and deassert reset */ + /* setup STI timer to run on 32.768 kHz and deassert reset */ emev2_smu_write(0, STI_CLKSEL); emev2_smu_write(1, STI_RSTCTRL); -- cgit v1.2.3-70-g09d2 From 54aa4c48bc0d364565e7d1c722b07314efdc2a10 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jul 2013 01:48:34 -0700 Subject: ARM: shmobile: r8a7778: remove r8a7778_init_irq() This patch removes r8a7778_init_irq(), since no-one is using it. And now, there is no reason to have r8a7778_init_irq_common(). r8a7778_init_irq_dt() includes it. Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7778.h | 1 - arch/arm/mach-shmobile/setup-r8a7778.c | 37 +++++++-------------------- 2 files changed, 9 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index 851d027a2f0..9b561bf4229 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -33,7 +33,6 @@ extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info); extern void r8a7778_init_late(void); extern void r8a7778_init_delay(void); -extern void r8a7778_init_irq(void); extern void r8a7778_init_irq_dt(void); extern void r8a7778_clock_init(void); extern void r8a7778_init_irq_extpin(int irlm); diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 2a101ebdedf..a3a2e37b03f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -408,17 +408,25 @@ void __init r8a7778_init_irq_extpin(int irlm) &irqpin_platform_data, sizeof(irqpin_platform_data)); } +void __init r8a7778_init_delay(void) +{ + shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ +} + +#ifdef CONFIG_USE_OF #define INT2SMSKCR0 0x82288 /* 0xfe782288 */ #define INT2SMSKCR1 0x8228c /* 0xfe78228c */ #define INT2NTSR0 0x00018 /* 0xfe700018 */ #define INT2NTSR1 0x0002c /* 0xfe70002c */ -static void __init r8a7778_init_irq_common(void) +void __init r8a7778_init_irq_dt(void) { void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000); BUG_ON(!base); + irqchip_init(); + /* route all interrupts to ARM */ __raw_writel(0x73ffffff, base + INT2NTSR0); __raw_writel(0xffffffff, base + INT2NTSR1); @@ -430,33 +438,6 @@ static void __init r8a7778_init_irq_common(void) iounmap(base); } -void __init r8a7778_init_irq(void) -{ - void __iomem *gic_dist_base; - void __iomem *gic_cpu_base; - - gic_dist_base = ioremap_nocache(0xfe438000, PAGE_SIZE); - gic_cpu_base = ioremap_nocache(0xfe430000, PAGE_SIZE); - BUG_ON(!gic_dist_base || !gic_cpu_base); - - /* use GIC to handle interrupts */ - gic_init(0, 29, gic_dist_base, gic_cpu_base); - - r8a7778_init_irq_common(); -} - -void __init r8a7778_init_delay(void) -{ - shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ -} - -#ifdef CONFIG_USE_OF -void __init r8a7778_init_irq_dt(void) -{ - irqchip_init(); - r8a7778_init_irq_common(); -} - static const char *r8a7778_compat_dt[] __initdata = { "renesas,r8a7778", NULL, -- cgit v1.2.3-70-g09d2 From ebd9616f439a8a46b9dca9a272b342f34c5f3614 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 9 Jul 2013 19:40:16 +0900 Subject: ARM: shmobile: Remove unused mach/dma.h Remove mach-shmobile mach/dma.h since it only seems to be used on non-mach-shmobile platforms. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/dma.h | 1 - 1 file changed, 1 deletion(-) delete mode 100644 arch/arm/mach-shmobile/include/mach/dma.h (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/dma.h b/arch/arm/mach-shmobile/include/mach/dma.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/arch/arm/mach-shmobile/include/mach/dma.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ -- cgit v1.2.3-70-g09d2 From 2c408d149299e99c89fc4be80fb4fe00a7016f02 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 27 Jun 2013 08:48:07 +0900 Subject: ARM: shmobile: Update romImage to relocate appended DTB Instead of relying of MACH_TYPE for board identification, update the romImage code to relocate an appended DTB to the beginning of RAM. This implementation is independent of ARM_APPENDED_DTB, this because it is necessary to copy the DTB to memory so the kernel can access it. Without this patch Mackerel does not boot via the Mask ROM over USB (r_usb_boot) - this since non-DT boot was broken ages ago in commit: 0ce53cd ARM: mach-shmobile: Use DT_MACHINE for mackerel Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/compressed/head-shmobile.S | 43 ++++++++++++++++++++++++++--- arch/arm/mach-shmobile/include/mach/zboot.h | 2 -- 2 files changed, 39 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S index e2d636336b7..e7f80928949 100644 --- a/arch/arm/boot/compressed/head-shmobile.S +++ b/arch/arm/boot/compressed/head-shmobile.S @@ -55,12 +55,47 @@ __tmp_stack: __continue: #endif /* CONFIG_ZBOOT_ROM_MMC || CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI */ - /* Set board ID necessary for boot */ - ldr r7, 1f @ Set machine type register - mov r8, #0 @ pass null pointer as atag + adr r0, dtb_info + ldmia r0, {r1, r3, r4, r5, r7} + + sub r0, r0, r1 @ calculate the delta offset + add r5, r5, r0 @ _edata + + ldr lr, [r5, #0] @ check if valid DTB is present + cmp lr, r3 + bne 0f + + add r9, r7, #31 @ rounded up to a multiple + bic r9, r9, #31 @ ... of 32 bytes + + add r6, r9, r5 @ copy from _edata + add r9, r9, r4 @ to MEMORY_START + +1: ldmdb r6!, {r0 - r3, r10 - r12, lr} + cmp r6, r5 + stmdb r9!, {r0 - r3, r10 - r12, lr} + bhi 1b + + /* Success: Zero board ID, pointer to start of memory for atag/dtb */ + mov r7, #0 + mov r8, r4 b 2f -1 : .long MACH_TYPE + .align 2 +dtb_info: + .word dtb_info +#ifndef __ARMEB__ + .word 0xedfe0dd0 @ sig is 0xd00dfeed big endian +#else + .word 0xd00dfeed +#endif + .word MEMORY_START + .word _edata + .word 0x4000 @ maximum DTB size +0: + /* Failure: Zero board ID, NULL atag/dtb */ + mov r7, #0 + mov r8, #0 @ pass null pointer as atag 2 : #endif /* CONFIG_ZBOOT_ROM */ diff --git a/arch/arm/mach-shmobile/include/mach/zboot.h b/arch/arm/mach-shmobile/include/mach/zboot.h index f2d8744c1f1..c3c4669a2d7 100644 --- a/arch/arm/mach-shmobile/include/mach/zboot.h +++ b/arch/arm/mach-shmobile/include/mach/zboot.h @@ -1,7 +1,6 @@ #ifndef ZBOOT_H #define ZBOOT_H -#include #include /************************************************** @@ -11,7 +10,6 @@ **************************************************/ #ifdef CONFIG_MACH_MACKEREL -#define MACH_TYPE MACH_TYPE_MACKEREL #define MEMORY_START 0x40000000 #include "mach/head-mackerel.txt" #else -- cgit v1.2.3-70-g09d2 From 14bd03e08831a52035e601ae85b05a4849214ec4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 4 Jul 2013 21:13:27 +0200 Subject: ARM: mach-shmobile: mackerel: Use gpio-backlight Replace the backlight callback with a gpio-backlight platform device. Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-mackerel.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 85f51a849a5..af06753eb80 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,6 @@ #include #include #include - #include