162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * OMAP4 SMP cpu-hotplug support
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2010 Texas Instruments, Inc.
662306a36Sopenharmony_ci * Author:
762306a36Sopenharmony_ci *      Santosh Shilimkar <santosh.shilimkar@ti.com>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Platform file needed for the OMAP4 SMP. This file is based on arm
1062306a36Sopenharmony_ci * realview smp platform.
1162306a36Sopenharmony_ci * Copyright (c) 2002 ARM Limited.
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/kernel.h>
1562306a36Sopenharmony_ci#include <linux/errno.h>
1662306a36Sopenharmony_ci#include <linux/smp.h>
1762306a36Sopenharmony_ci#include <linux/io.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "omap-wakeupgen.h"
2062306a36Sopenharmony_ci#include "common.h"
2162306a36Sopenharmony_ci#include "powerdomain.h"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/*
2462306a36Sopenharmony_ci * platform-specific code to shutdown a CPU
2562306a36Sopenharmony_ci * Called with IRQs disabled
2662306a36Sopenharmony_ci */
2762306a36Sopenharmony_civoid omap4_cpu_die(unsigned int cpu)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	unsigned int boot_cpu = 0;
3062306a36Sopenharmony_ci	void __iomem *base = omap_get_wakeupgen_base();
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	/*
3362306a36Sopenharmony_ci	 * we're ready for shutdown now, so do it
3462306a36Sopenharmony_ci	 */
3562306a36Sopenharmony_ci	if (omap_secure_apis_support()) {
3662306a36Sopenharmony_ci		if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
3762306a36Sopenharmony_ci			pr_err("Secure clear status failed\n");
3862306a36Sopenharmony_ci	} else {
3962306a36Sopenharmony_ci		writel_relaxed(0, base + OMAP_AUX_CORE_BOOT_0);
4062306a36Sopenharmony_ci	}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	for (;;) {
4462306a36Sopenharmony_ci		/*
4562306a36Sopenharmony_ci		 * Enter into low power state
4662306a36Sopenharmony_ci		 */
4762306a36Sopenharmony_ci		omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci		if (omap_secure_apis_support())
5062306a36Sopenharmony_ci			boot_cpu = omap_read_auxcoreboot0() >> 9;
5162306a36Sopenharmony_ci		else
5262306a36Sopenharmony_ci			boot_cpu =
5362306a36Sopenharmony_ci				readl_relaxed(base + OMAP_AUX_CORE_BOOT_0) >> 5;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci		if (boot_cpu == smp_processor_id()) {
5662306a36Sopenharmony_ci			/*
5762306a36Sopenharmony_ci			 * OK, proper wakeup, we're done
5862306a36Sopenharmony_ci			 */
5962306a36Sopenharmony_ci			break;
6062306a36Sopenharmony_ci		}
6162306a36Sopenharmony_ci		pr_debug("CPU%u: spurious wakeup call\n", cpu);
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/* Needed by kexec and platform_can_cpu_hotplug() */
6662306a36Sopenharmony_ciint omap4_cpu_kill(unsigned int cpu)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	return 1;
6962306a36Sopenharmony_ci}
70