[PATCH 05/74] ST SPEAr13XX: Adding machine specific src files

Russell King - ARM Linux linux at arm.linux.org.uk
Thu Sep 2 05:04:41 EDT 2010


On Mon, Aug 30, 2010 at 04:08:36PM +0530, Viresh KUMAR wrote:
> diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
> new file mode 100644
> index 0000000..8b75d1b
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/platsmp.c
> @@ -0,0 +1,203 @@
> +/*
> + * arch/arm/mach-spear13xx/platsmp.c
> + *
> + * based upon linux/arch/arm/mach-realview/platsmp.c
> + *
> + * Copyright (C) 2010 ST Microelectronics Ltd.
> + * Shiraz Hashim <shiraz.hashim at st.com>
> + *
> + * 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 <asm/cacheflush.h>
> +#include <asm/hardware/gic.h>
> +#include <asm/localtimer.h>
> +#include <asm/mach-types.h>
> +#include <asm/smp_scu.h>
> +#include <asm/unified.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/jiffies.h>
> +#include <linux/smp.h>
> +#include <mach/generic.h>
> +#include <mach/hardware.h>

linux/ before asm/ before mach/ please.

> +
> +/*
> + * control for which core is the next to come out of the secondary
> + * boot "holding pen"
> + */
> +volatile int __cpuinitdata pen_release = -1;
> +static DEFINE_SPINLOCK(boot_lock);
> +
> +static void __iomem *scu_base_addr(void)
> +{
> +	return __io_address(SPEAR13XX_SCU_BASE);
> +}
> +
> +static inline unsigned int get_core_count(void)
> +{
> +	void __iomem *scu_base = scu_base_addr();
> +
> +	if (scu_base)
> +		return scu_get_core_count(scu_base);
> +	return 1;
> +}
> +
> +void __cpuinit platform_secondary_init(unsigned int cpu)
> +{
> +	trace_hardirqs_off();
> +
> +	/*
> +	 * if any interrupts are already enabled for the primary
> +	 * core (e.g. timer irq), then they will not have been enabled
> +	 * for us: do so
> +	 */
> +	gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
> +
> +	/*
> +	 * let the primary processor know we're out of the
> +	 * pen, then head off into the C entry point
> +	 */
> +	pen_release = -1;
> +	smp_wmb();
> +
> +	/*
> +	 * Synchronise with the boot thread.
> +	 */
> +	spin_lock(&boot_lock);
> +	spin_unlock(&boot_lock);
> +}
> +
> +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
> +{
> +	unsigned long timeout;
> +
> +	/*
> +	 * set synchronisation state between this boot processor
> +	 * and the secondary one
> +	 */
> +	spin_lock(&boot_lock);
> +
> +	/*
> +	 * The secondary processor is waiting to be released from
> +	 * the holding pen - release it, then wait for it to flag
> +	 * that it has been released by resetting pen_release.
> +	 *
> +	 * Note that "pen_release" is the hardware CPU ID, whereas
> +	 * "cpu" is Linux's internal ID.
> +	 */
> +
> +	/*
> +	 * Note: Following is important otherwise cpu2 doesn't come up
> +	 * as secondary_data must be flushed before pen_release also
> +	 */
> +
> +	flush_cache_all();

You don't need this.  secondary_data is already taken care of as of a
few kernel releases ago.

> +	pen_release = cpu;
> +	flush_cache_all();
> +
> +	timeout = jiffies + (1 * HZ);
> +	while (time_before(jiffies, timeout)) {
> +		smp_rmb();
> +		if (pen_release == -1)
> +			break;
> +
> +		udelay(10);
> +	}
> +
> +	/*
> +	 * now the secondary core is starting up let it run its
> +	 * calibrations, then wait for it to finish
> +	 */
> +	spin_unlock(&boot_lock);
> +
> +	return pen_release != -1 ? -ENOSYS : 0;
> +}
> +
> +static void __init poke_milo(void)
> +{
> +	/* nobody is to be released from the pen yet */
> +	pen_release = -1;
> +
> +	/*
> +	 * Write the address of secondary startup into the system-wide
> +	 * location (presently it is in SRAM). The BootMonitor waits
> +	 * for this register to become non-zero.
> +	 */
> +	__raw_writel(BSYM(virt_to_phys(spear13xx_secondary_startup)),
> +			__io_address(SPEAR13XX_SYS_LOCATION));
> +
> +	mb();

Please get rid of this function.  You don't have milo, and milo is pretty
much dead anyway.  Please read the Versatile Express SMP code and base
your version off that (cleaned up) version instead.

> +}
> +
> +/*
> + * Initialise the CPU possible map early - this describes the CPUs
> + * which may be present or become present in the system.
> + */
> +void __init smp_init_cpus(void)
> +{
> +	unsigned int i, ncores = get_core_count();
> +
> +	for (i = 0; i < ncores; i++)
> +		set_cpu_possible(i, true);
> +}
> +
> +void __init smp_prepare_cpus(unsigned int max_cpus)
> +{
> +	unsigned int ncores = get_core_count();
> +	unsigned int cpu = smp_processor_id();
> +	int i;
> +
> +	/* sanity check */
> +	if (ncores == 0) {
> +		pr_err("Realview: strange CM count of 0? Default to 1\n");
> +
> +		ncores = 1;
> +	}
> +
> +	if (ncores > num_possible_cpus()) {
> +		ncores = num_possible_cpus();
> +		pr_err(
> +		       "spear13xx: no. of cores (%d) greater than configured "
> +		       "maximum of %d - clipping\n",
> +		       ncores, ncores);
> +	}
> +
> +	smp_store_cpu_info(cpu);
> +
> +	/*
> +	 * are we trying to boot more cores than exist?
> +	 */
> +	if (max_cpus > ncores)
> +		max_cpus = ncores;
> +
> +	/*
> +	 * Initialise the present map, which describes the set of CPUs
> +	 * actually populated at the present time.
> +	 */
> +	for (i = 0; i < max_cpus; i++)
> +		set_cpu_present(i, true);
> +
> +	/*
> +	 * Initialise the SCU if there are more than one CPU and let
> +	 * them know where to start. Note that, on modern versions of
> +	 * MILO, the "poke" doesn't actually do anything until each
> +	 * individual core is sent a soft interrupt to get it out of
> +	 * WFI
> +	 */
> +	if (max_cpus > 1) {
> +		/*
> +		 * Enable the local timer or broadcast device for the
> +		 * boot CPU, but only if we have more than one CPU.
> +		 */
> +		percpu_timer_setup();
> +
> +		scu_enable(scu_base_addr());
> +		poke_milo();
> +	}
> +}
> diff --git a/arch/arm/mach-spear13xx/spear1300.c b/arch/arm/mach-spear13xx/spear1300.c
> new file mode 100644
> index 0000000..c1b82f1
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/spear1300.c
> @@ -0,0 +1,23 @@
> +/*
> + * arch/arm/mach-spear13xx/spear1300.c
> + *
> + * SPEAr1300 machine source file
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim at st.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <mach/generic.h>
> +#include <mach/spear.h>
> +
> +/* Add spear1300 specific devices here */
> +
> +void __init spear1300_init(void)
> +{
> +	/* call spear13xx family common init function */
> +	spear13xx_init();
> +}
> diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c
> new file mode 100644
> index 0000000..d72c8a8
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/spear1300_evb.c
> @@ -0,0 +1,48 @@
> +/*
> + * arch/arm/mach-spear13xx/spear1300_evb.c
> + *
> + * SPEAr1300 evaluation board source file
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim at st.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach-types.h>
> +#include <mach/generic.h>
> +#include <mach/spear.h>
> +
> +static struct amba_device *amba_devs[] __initdata = {
> +	&uart_device,
> +};
> +
> +static struct platform_device *plat_devs[] __initdata = {
> +};
> +
> +static void __init spear1300_evb_init(void)
> +{
> +	unsigned int i;
> +
> +	/* call spear1300 machine init function */
> +	spear1300_init();
> +
> +	/* Add Platform Devices */
> +	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
> +
> +	/* Add Amba Devices */
> +	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
> +		amba_device_register(amba_devs[i], &iomem_resource);
> +}
> +
> +MACHINE_START(SPEAR1300, "ST-SPEAR1300-EVB")
> +	.boot_params	=	0x00000100,
> +	.map_io		=	spear13xx_map_io,
> +	.init_irq	=	spear13xx_init_irq,
> +	.timer		=	&spear13xx_timer,
> +	.init_machine	=	spear1300_evb_init,
> +MACHINE_END
> diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
> new file mode 100644
> index 0000000..d11e300
> --- /dev/null
> +++ b/arch/arm/mach-spear13xx/spear13xx.c
> @@ -0,0 +1,98 @@
> +/*
> + * arch/arm/mach-spear13xx/spear13xx.c
> + *
> + * SPEAr13XX machines common source file
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Shiraz Hashim <shiraz.hashim at st.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/types.h>
> +#include <linux/ptrace.h>
> +#include <linux/io.h>
> +#include <asm/hardware/gic.h>
> +#include <asm/irq.h>
> +#include <asm/localtimer.h>
> +#include <asm/mach/arch.h>
> +#include <asm/smp_twd.h>
> +#include <mach/irqs.h>
> +#include <mach/generic.h>
> +#include <mach/hardware.h>

So do you need all these includes?

> +
> +/* Add spear13xx machines common devices here */
> +/* uart device registeration */
> +struct amba_device uart_device = {
> +	.dev = {
> +		.init_name = "uart",
> +	},
> +	.res = {
> +		.start = SPEAR13XX_UART_BASE,
> +		.end = SPEAR13XX_UART_BASE + SZ_4K - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	.irq = {IRQ_UART, NO_IRQ},
> +};
> +
> +/* Do spear13xx familiy common initialization part here */
> +void __init spear13xx_init(void)
> +{
> +	/* nothing to do for now */
> +}
> +
> +/* This will initialize vic */
> +void __init spear13xx_init_irq(void)
> +{
> +	gic_dist_init(0, __io_address(SPEAR13XX_GIC_DIST_BASE), 29);
> +	gic_cpu_init(0, __io_address(SPEAR13XX_GIC_CPU_BASE));
> +}
> +
> +/* Following will create static virtual/physical mappings */
> +struct map_desc spear13xx_io_desc[] __initdata = {
> +	{
> +		.virtual	= IO_ADDRESS(SPEAR13XX_UART_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_UART_BASE),
> +		.length		= SZ_4K,
> +		.type		= MT_DEVICE
> +	}, {
> +		.virtual	= IO_ADDRESS(SPEAR13XX_A9SM_PERIP_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_A9SM_PERIP_BASE),
> +		.length		= SZ_8K,
> +		.type		= MT_DEVICE
> +	}, {
> +		.virtual	= IO_ADDRESS(SPEAR13XX_MISC_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_MISC_BASE),
> +		.length		= SZ_8K,
> +		.type		= MT_DEVICE
> +	}, {
> +		.virtual	= IO_ADDRESS(SPEAR13XX_SYSRAM0_BASE),
> +		.pfn		= __phys_to_pfn(SPEAR13XX_SYSRAM0_BASE),
> +		.length		= SZ_32K,
> +		.type		= MT_DEVICE
> +	},
> +};
> +
> +/* This will create static memory mapping for selected devices */
> +void __init spear13xx_map_io(void)
> +{
> +	iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
> +
> +	/* This will initialize clock framework */
> +	clk_init();
> +}
> +
> +static void __init spear13xx_timer_init(void)
> +{
> +#ifdef CONFIG_LOCAL_TIMERS
> +	/* Setup the local timer base */
> +	twd_base = __io_address(SPEAR13XX_LOCAL_TMR_BASE);
> +#endif
> +	spear_setup_timer();
> +}
> +
> +struct sys_timer spear13xx_timer = {
> +	.init = spear13xx_timer_init,
> +};
> -- 
> 1.7.2.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



More information about the linux-arm-kernel mailing list