Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  Copyright (C) 2002 ARM Ltd.
  4 *  All Rights Reserved
  5 *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  6 *  Copyright (c) 2014 The Linux Foundation. All rights reserved.
  7 */
  8
  9#include <linux/init.h>
 10#include <linux/errno.h>
 11#include <linux/delay.h>
 12#include <linux/device.h>
 13#include <linux/of.h>
 14#include <linux/of_address.h>
 15#include <linux/smp.h>
 16#include <linux/io.h>
 17#include <linux/qcom_scm.h>
 18
 19#include <asm/smp_plat.h>
 20
 21
 22#define VDD_SC1_ARRAY_CLAMP_GFS_CTL	0x35a0
 23#define SCSS_CPU1CORE_RESET		0x2d80
 24#define SCSS_DBG_STATUS_CORE_PWRDUP	0x2e64
 25
 26#define APCS_CPU_PWR_CTL	0x04
 27#define PLL_CLAMP		BIT(8)
 28#define CORE_PWRD_UP		BIT(7)
 29#define COREPOR_RST		BIT(5)
 30#define CORE_RST		BIT(4)
 31#define L2DT_SLP		BIT(3)
 
 32#define CLAMP			BIT(0)
 33
 34#define APC_PWR_GATE_CTL	0x14
 35#define BHS_CNT_SHIFT		24
 36#define LDO_PWR_DWN_SHIFT	16
 37#define LDO_BYP_SHIFT		8
 38#define BHS_SEG_SHIFT		1
 39#define BHS_EN			BIT(0)
 40
 41#define APCS_SAW2_VCTL		0x14
 42#define APCS_SAW2_2_VCTL	0x1c
 43
 44extern void secondary_startup_arm(void);
 45
 46#ifdef CONFIG_HOTPLUG_CPU
 47static void qcom_cpu_die(unsigned int cpu)
 48{
 49	wfi();
 50}
 51#endif
 52
 53static int scss_release_secondary(unsigned int cpu)
 54{
 55	struct device_node *node;
 56	void __iomem *base;
 57
 58	node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
 59	if (!node) {
 60		pr_err("%s: can't find node\n", __func__);
 61		return -ENXIO;
 62	}
 63
 64	base = of_iomap(node, 0);
 65	of_node_put(node);
 66	if (!base)
 67		return -ENOMEM;
 68
 69	writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
 70	writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
 71	writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
 72	mb();
 73	iounmap(base);
 74
 75	return 0;
 76}
 77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 78static int kpssv1_release_secondary(unsigned int cpu)
 79{
 80	int ret = 0;
 81	void __iomem *reg, *saw_reg;
 82	struct device_node *cpu_node, *acc_node, *saw_node;
 83	u32 val;
 84
 85	cpu_node = of_get_cpu_node(cpu, NULL);
 86	if (!cpu_node)
 87		return -ENODEV;
 88
 89	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
 90	if (!acc_node) {
 91		ret = -ENODEV;
 92		goto out_acc;
 93	}
 94
 95	saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
 96	if (!saw_node) {
 97		ret = -ENODEV;
 98		goto out_saw;
 99	}
100
101	reg = of_iomap(acc_node, 0);
102	if (!reg) {
103		ret = -ENOMEM;
104		goto out_acc_map;
105	}
106
107	saw_reg = of_iomap(saw_node, 0);
108	if (!saw_reg) {
109		ret = -ENOMEM;
110		goto out_saw_map;
111	}
112
113	/* Turn on CPU rail */
114	writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
115	mb();
116	udelay(512);
117
118	/* Krait bring-up sequence */
119	val = PLL_CLAMP | L2DT_SLP | CLAMP;
120	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
121	val &= ~L2DT_SLP;
122	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
123	mb();
124	ndelay(300);
125
126	val |= COREPOR_RST;
127	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
128	mb();
129	udelay(2);
130
131	val &= ~CLAMP;
132	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
133	mb();
134	udelay(2);
135
136	val &= ~COREPOR_RST;
137	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
138	mb();
139	udelay(100);
140
141	val |= CORE_PWRD_UP;
142	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
143	mb();
144
145	iounmap(saw_reg);
146out_saw_map:
147	iounmap(reg);
148out_acc_map:
149	of_node_put(saw_node);
150out_saw:
151	of_node_put(acc_node);
152out_acc:
153	of_node_put(cpu_node);
154	return ret;
155}
156
157static int kpssv2_release_secondary(unsigned int cpu)
158{
159	void __iomem *reg;
160	struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
161	void __iomem *l2_saw_base;
162	unsigned reg_val;
163	int ret;
164
165	cpu_node = of_get_cpu_node(cpu, NULL);
166	if (!cpu_node)
167		return -ENODEV;
168
169	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
170	if (!acc_node) {
171		ret = -ENODEV;
172		goto out_acc;
173	}
174
175	l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
176	if (!l2_node) {
177		ret = -ENODEV;
178		goto out_l2;
179	}
180
181	saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
182	if (!saw_node) {
183		ret = -ENODEV;
184		goto out_saw;
185	}
186
187	reg = of_iomap(acc_node, 0);
188	if (!reg) {
189		ret = -ENOMEM;
190		goto out_map;
191	}
192
193	l2_saw_base = of_iomap(saw_node, 0);
194	if (!l2_saw_base) {
195		ret = -ENOMEM;
196		goto out_saw_map;
197	}
198
199	/* Turn on the BHS, turn off LDO Bypass and power down LDO */
200	reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
201	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
202	mb();
203	/* wait for the BHS to settle */
204	udelay(1);
205
206	/* Turn on BHS segments */
207	reg_val |= 0x3f << BHS_SEG_SHIFT;
208	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
209	mb();
210	 /* wait for the BHS to settle */
211	udelay(1);
212
213	/* Finally turn on the bypass so that BHS supplies power */
214	reg_val |= 0x3f << LDO_BYP_SHIFT;
215	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
216
217	/* enable max phases */
218	writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
219	mb();
220	udelay(50);
221
222	reg_val = COREPOR_RST | CLAMP;
223	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
224	mb();
225	udelay(2);
226
227	reg_val &= ~CLAMP;
228	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
229	mb();
230	udelay(2);
231
232	reg_val &= ~COREPOR_RST;
233	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
234	mb();
235
236	reg_val |= CORE_PWRD_UP;
237	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
238	mb();
239
240	ret = 0;
241
242	iounmap(l2_saw_base);
243out_saw_map:
244	iounmap(reg);
245out_map:
246	of_node_put(saw_node);
247out_saw:
248	of_node_put(l2_node);
249out_l2:
250	of_node_put(acc_node);
251out_acc:
252	of_node_put(cpu_node);
253
254	return ret;
255}
256
257static DEFINE_PER_CPU(int, cold_boot_done);
258
259static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
260{
261	int ret = 0;
262
263	if (!per_cpu(cold_boot_done, cpu)) {
264		ret = func(cpu);
265		if (!ret)
266			per_cpu(cold_boot_done, cpu) = true;
267	}
268
269	/*
270	 * Send the secondary CPU a soft interrupt, thereby causing
271	 * the boot monitor to read the system wide flags register,
272	 * and branch to the address found there.
273	 */
274	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
275
276	return ret;
277}
278
279static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
280{
281	return qcom_boot_secondary(cpu, scss_release_secondary);
282}
283
 
 
 
 
 
284static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
285{
286	return qcom_boot_secondary(cpu, kpssv1_release_secondary);
287}
288
289static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
290{
291	return qcom_boot_secondary(cpu, kpssv2_release_secondary);
292}
293
294static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
295{
296	int cpu;
297
298	if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,
299					cpu_present_mask)) {
300		for_each_present_cpu(cpu) {
301			if (cpu == smp_processor_id())
302				continue;
303			set_cpu_present(cpu, false);
304		}
305		pr_warn("Failed to set CPU boot address, disabling SMP\n");
306	}
307}
308
309static const struct smp_operations smp_msm8660_ops __initconst = {
310	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
311	.smp_boot_secondary	= msm8660_boot_secondary,
312#ifdef CONFIG_HOTPLUG_CPU
313	.cpu_die		= qcom_cpu_die,
314#endif
315};
316CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
 
 
 
 
 
 
 
 
 
 
 
317
318static const struct smp_operations qcom_smp_kpssv1_ops __initconst = {
319	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
320	.smp_boot_secondary	= kpssv1_boot_secondary,
321#ifdef CONFIG_HOTPLUG_CPU
322	.cpu_die		= qcom_cpu_die,
323#endif
324};
325CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
326
327static const struct smp_operations qcom_smp_kpssv2_ops __initconst = {
328	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
329	.smp_boot_secondary	= kpssv2_boot_secondary,
330#ifdef CONFIG_HOTPLUG_CPU
331	.cpu_die		= qcom_cpu_die,
332#endif
333};
334CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  Copyright (C) 2002 ARM Ltd.
  4 *  All Rights Reserved
  5 *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  6 *  Copyright (c) 2014 The Linux Foundation. All rights reserved.
  7 */
  8
  9#include <linux/init.h>
 10#include <linux/errno.h>
 11#include <linux/delay.h>
 12#include <linux/device.h>
 13#include <linux/of.h>
 14#include <linux/of_address.h>
 15#include <linux/smp.h>
 16#include <linux/io.h>
 17#include <linux/firmware/qcom/qcom_scm.h>
 18
 19#include <asm/smp_plat.h>
 20
 21
 22#define VDD_SC1_ARRAY_CLAMP_GFS_CTL	0x35a0
 23#define SCSS_CPU1CORE_RESET		0x2d80
 24#define SCSS_DBG_STATUS_CORE_PWRDUP	0x2e64
 25
 26#define APCS_CPU_PWR_CTL	0x04
 27#define PLL_CLAMP		BIT(8)
 28#define CORE_PWRD_UP		BIT(7)
 29#define COREPOR_RST		BIT(5)
 30#define CORE_RST		BIT(4)
 31#define L2DT_SLP		BIT(3)
 32#define CORE_MEM_CLAMP		BIT(1)
 33#define CLAMP			BIT(0)
 34
 35#define APC_PWR_GATE_CTL	0x14
 36#define BHS_CNT_SHIFT		24
 37#define LDO_PWR_DWN_SHIFT	16
 38#define LDO_BYP_SHIFT		8
 39#define BHS_SEG_SHIFT		1
 40#define BHS_EN			BIT(0)
 41
 42#define APCS_SAW2_VCTL		0x14
 43#define APCS_SAW2_2_VCTL	0x1c
 44
 45extern void secondary_startup_arm(void);
 46
 47#ifdef CONFIG_HOTPLUG_CPU
 48static void qcom_cpu_die(unsigned int cpu)
 49{
 50	wfi();
 51}
 52#endif
 53
 54static int scss_release_secondary(unsigned int cpu)
 55{
 56	struct device_node *node;
 57	void __iomem *base;
 58
 59	node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
 60	if (!node) {
 61		pr_err("%s: can't find node\n", __func__);
 62		return -ENXIO;
 63	}
 64
 65	base = of_iomap(node, 0);
 66	of_node_put(node);
 67	if (!base)
 68		return -ENOMEM;
 69
 70	writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
 71	writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
 72	writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
 73	mb();
 74	iounmap(base);
 75
 76	return 0;
 77}
 78
 79static int cortex_a7_release_secondary(unsigned int cpu)
 80{
 81	int ret = 0;
 82	void __iomem *reg;
 83	struct device_node *cpu_node, *acc_node;
 84	u32 reg_val;
 85
 86	cpu_node = of_get_cpu_node(cpu, NULL);
 87	if (!cpu_node)
 88		return -ENODEV;
 89
 90	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
 91	if (!acc_node) {
 92		ret = -ENODEV;
 93		goto out_acc;
 94	}
 95
 96	reg = of_iomap(acc_node, 0);
 97	if (!reg) {
 98		ret = -ENOMEM;
 99		goto out_acc_map;
100	}
101
102	/* Put the CPU into reset. */
103	reg_val = CORE_RST | COREPOR_RST | CLAMP | CORE_MEM_CLAMP;
104	writel(reg_val, reg + APCS_CPU_PWR_CTL);
105
106	/* Turn on the BHS and set the BHS_CNT to 16 XO clock cycles */
107	writel(BHS_EN | (0x10 << BHS_CNT_SHIFT), reg + APC_PWR_GATE_CTL);
108	/* Wait for the BHS to settle */
109	udelay(2);
110
111	reg_val &= ~CORE_MEM_CLAMP;
112	writel(reg_val, reg + APCS_CPU_PWR_CTL);
113	reg_val |= L2DT_SLP;
114	writel(reg_val, reg + APCS_CPU_PWR_CTL);
115	udelay(2);
116
117	reg_val = (reg_val | BIT(17)) & ~CLAMP;
118	writel(reg_val, reg + APCS_CPU_PWR_CTL);
119	udelay(2);
120
121	/* Release CPU out of reset and bring it to life. */
122	reg_val &= ~(CORE_RST | COREPOR_RST);
123	writel(reg_val, reg + APCS_CPU_PWR_CTL);
124	reg_val |= CORE_PWRD_UP;
125	writel(reg_val, reg + APCS_CPU_PWR_CTL);
126
127	iounmap(reg);
128out_acc_map:
129	of_node_put(acc_node);
130out_acc:
131	of_node_put(cpu_node);
132	return ret;
133}
134
135static int kpssv1_release_secondary(unsigned int cpu)
136{
137	int ret = 0;
138	void __iomem *reg, *saw_reg;
139	struct device_node *cpu_node, *acc_node, *saw_node;
140	u32 val;
141
142	cpu_node = of_get_cpu_node(cpu, NULL);
143	if (!cpu_node)
144		return -ENODEV;
145
146	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
147	if (!acc_node) {
148		ret = -ENODEV;
149		goto out_acc;
150	}
151
152	saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
153	if (!saw_node) {
154		ret = -ENODEV;
155		goto out_saw;
156	}
157
158	reg = of_iomap(acc_node, 0);
159	if (!reg) {
160		ret = -ENOMEM;
161		goto out_acc_map;
162	}
163
164	saw_reg = of_iomap(saw_node, 0);
165	if (!saw_reg) {
166		ret = -ENOMEM;
167		goto out_saw_map;
168	}
169
170	/* Turn on CPU rail */
171	writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
172	mb();
173	udelay(512);
174
175	/* Krait bring-up sequence */
176	val = PLL_CLAMP | L2DT_SLP | CLAMP;
177	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
178	val &= ~L2DT_SLP;
179	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
180	mb();
181	ndelay(300);
182
183	val |= COREPOR_RST;
184	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
185	mb();
186	udelay(2);
187
188	val &= ~CLAMP;
189	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
190	mb();
191	udelay(2);
192
193	val &= ~COREPOR_RST;
194	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
195	mb();
196	udelay(100);
197
198	val |= CORE_PWRD_UP;
199	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
200	mb();
201
202	iounmap(saw_reg);
203out_saw_map:
204	iounmap(reg);
205out_acc_map:
206	of_node_put(saw_node);
207out_saw:
208	of_node_put(acc_node);
209out_acc:
210	of_node_put(cpu_node);
211	return ret;
212}
213
214static int kpssv2_release_secondary(unsigned int cpu)
215{
216	void __iomem *reg;
217	struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
218	void __iomem *l2_saw_base;
219	unsigned reg_val;
220	int ret;
221
222	cpu_node = of_get_cpu_node(cpu, NULL);
223	if (!cpu_node)
224		return -ENODEV;
225
226	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
227	if (!acc_node) {
228		ret = -ENODEV;
229		goto out_acc;
230	}
231
232	l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
233	if (!l2_node) {
234		ret = -ENODEV;
235		goto out_l2;
236	}
237
238	saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
239	if (!saw_node) {
240		ret = -ENODEV;
241		goto out_saw;
242	}
243
244	reg = of_iomap(acc_node, 0);
245	if (!reg) {
246		ret = -ENOMEM;
247		goto out_map;
248	}
249
250	l2_saw_base = of_iomap(saw_node, 0);
251	if (!l2_saw_base) {
252		ret = -ENOMEM;
253		goto out_saw_map;
254	}
255
256	/* Turn on the BHS, turn off LDO Bypass and power down LDO */
257	reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
258	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
259	mb();
260	/* wait for the BHS to settle */
261	udelay(1);
262
263	/* Turn on BHS segments */
264	reg_val |= 0x3f << BHS_SEG_SHIFT;
265	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
266	mb();
267	 /* wait for the BHS to settle */
268	udelay(1);
269
270	/* Finally turn on the bypass so that BHS supplies power */
271	reg_val |= 0x3f << LDO_BYP_SHIFT;
272	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
273
274	/* enable max phases */
275	writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
276	mb();
277	udelay(50);
278
279	reg_val = COREPOR_RST | CLAMP;
280	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
281	mb();
282	udelay(2);
283
284	reg_val &= ~CLAMP;
285	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
286	mb();
287	udelay(2);
288
289	reg_val &= ~COREPOR_RST;
290	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
291	mb();
292
293	reg_val |= CORE_PWRD_UP;
294	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
295	mb();
296
297	ret = 0;
298
299	iounmap(l2_saw_base);
300out_saw_map:
301	iounmap(reg);
302out_map:
303	of_node_put(saw_node);
304out_saw:
305	of_node_put(l2_node);
306out_l2:
307	of_node_put(acc_node);
308out_acc:
309	of_node_put(cpu_node);
310
311	return ret;
312}
313
314static DEFINE_PER_CPU(int, cold_boot_done);
315
316static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
317{
318	int ret = 0;
319
320	if (!per_cpu(cold_boot_done, cpu)) {
321		ret = func(cpu);
322		if (!ret)
323			per_cpu(cold_boot_done, cpu) = true;
324	}
325
326	/*
327	 * Send the secondary CPU a soft interrupt, thereby causing
328	 * the boot monitor to read the system wide flags register,
329	 * and branch to the address found there.
330	 */
331	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
332
333	return ret;
334}
335
336static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
337{
338	return qcom_boot_secondary(cpu, scss_release_secondary);
339}
340
341static int cortex_a7_boot_secondary(unsigned int cpu, struct task_struct *idle)
342{
343	return qcom_boot_secondary(cpu, cortex_a7_release_secondary);
344}
345
346static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
347{
348	return qcom_boot_secondary(cpu, kpssv1_release_secondary);
349}
350
351static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
352{
353	return qcom_boot_secondary(cpu, kpssv2_release_secondary);
354}
355
356static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
357{
358	int cpu;
359
360	if (qcom_scm_set_cold_boot_addr(secondary_startup_arm)) {
 
361		for_each_present_cpu(cpu) {
362			if (cpu == smp_processor_id())
363				continue;
364			set_cpu_present(cpu, false);
365		}
366		pr_warn("Failed to set CPU boot address, disabling SMP\n");
367	}
368}
369
370static const struct smp_operations smp_msm8660_ops __initconst = {
371	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
372	.smp_boot_secondary	= msm8660_boot_secondary,
373#ifdef CONFIG_HOTPLUG_CPU
374	.cpu_die		= qcom_cpu_die,
375#endif
376};
377CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
378
379static const struct smp_operations qcom_smp_cortex_a7_ops __initconst = {
380	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
381	.smp_boot_secondary	= cortex_a7_boot_secondary,
382#ifdef CONFIG_HOTPLUG_CPU
383	.cpu_die		= qcom_cpu_die,
384#endif
385};
386CPU_METHOD_OF_DECLARE(qcom_smp_msm8226, "qcom,msm8226-smp", &qcom_smp_cortex_a7_ops);
387CPU_METHOD_OF_DECLARE(qcom_smp_msm8909, "qcom,msm8909-smp", &qcom_smp_cortex_a7_ops);
388CPU_METHOD_OF_DECLARE(qcom_smp_msm8916, "qcom,msm8916-smp", &qcom_smp_cortex_a7_ops);
389
390static const struct smp_operations qcom_smp_kpssv1_ops __initconst = {
391	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
392	.smp_boot_secondary	= kpssv1_boot_secondary,
393#ifdef CONFIG_HOTPLUG_CPU
394	.cpu_die		= qcom_cpu_die,
395#endif
396};
397CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
398
399static const struct smp_operations qcom_smp_kpssv2_ops __initconst = {
400	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
401	.smp_boot_secondary	= kpssv2_boot_secondary,
402#ifdef CONFIG_HOTPLUG_CPU
403	.cpu_die		= qcom_cpu_die,
404#endif
405};
406CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);