/*
 * 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(__pa_symbol(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);
	of_node_put(syscon_np);
	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 const struct smp_operations axxia_smp_ops __initconst = {
	.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);
