/*
 * linux/arch/arm/mach-axxia/platsmp.c
 *
 * Copyright (C) 2012 LSI Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/io.h>
#include <linux/smp.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/cacheflush.h>

/* Syscon register offsets for releasing cores from reset */
#define SC_CRIT_WRITE_KEY	0x1000
#define SC_RST_CPU_HOLD		0x1010

/*
 * Write the kernel entry point for secondary CPUs to the specified address
 */
static void write_release_addr(u32 release_phys)
{
	u32 *virt = (u32 *) phys_to_virt(release_phys);
	writel_relaxed(virt_to_phys(secondary_startup), virt);
	/* Make sure this store is visible to other CPUs */
	smp_wmb();
	__cpuc_flush_dcache_area(virt, sizeof(u32));
}

static int axxia_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	struct device_node *syscon_np;
	void __iomem *syscon;
	u32 tmp;

	syscon_np = of_find_compatible_node(NULL, NULL, "lsi,axxia-syscon");
	if (!syscon_np)
		return -ENOENT;

	syscon = of_iomap(syscon_np, 0);
	if (!syscon)
		return -ENOMEM;

	tmp = readl(syscon + SC_RST_CPU_HOLD);
	writel(0xab, syscon + SC_CRIT_WRITE_KEY);
	tmp &= ~(1 << cpu);
	writel(tmp, syscon + SC_RST_CPU_HOLD);

	return 0;
}

static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
{
	int cpu_count = 0;
	int cpu;

	/*
	 * Initialise the present map, which describes the set of CPUs actually
	 * populated at the present time.
	 */
	for_each_possible_cpu(cpu) {
		struct device_node *np;
		u32 release_phys;

		np = of_get_cpu_node(cpu, NULL);
		if (!np)
			continue;
		if (of_property_read_u32(np, "cpu-release-addr", &release_phys))
			continue;

		if (cpu_count < max_cpus) {
			set_cpu_present(cpu, true);
			cpu_count++;
		}

		if (release_phys != 0)
			write_release_addr(release_phys);
	}
}

static struct smp_operations axxia_smp_ops __initdata = {
	.smp_prepare_cpus	= axxia_smp_prepare_cpus,
	.smp_boot_secondary	= axxia_boot_secondary,
};
CPU_METHOD_OF_DECLARE(axxia_smp, "lsi,syscon-release", &axxia_smp_ops);
