aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2015-03-24 13:58:52 -0400
committerWill Deacon <will.deacon@arm.com>2015-03-26 11:13:10 -0400
commit48eb3c8a8b4fffb48f64019e1f68a7de4db4cc43 (patch)
treed8d4bd334a82bf649275c706167b5899392c749b /arch/arm64
parentd8f4f161e31f3ee9768467344e6cc31a0b9d9249 (diff)
ARM64: kernel: psci: factor out probe function
PSCI v0.2+ versions provide a specific PSCI call (PSCI_VERSION) to detect the PSCI version at run-time. Current PSCI v0.2 init code carries out the version probing in the PSCI 0.2 DT init function, but the version probing does not depend on DT so it can be factored out in order to make it available to other boot mechanisms (ie ACPI) to reuse. The psci_probe() probing function can be easily extended to add detection and initialization of PSCI functions defined in PSCI versions >0.2. Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/kernel/psci.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index d3c52ce5faf3..2caac4498154 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -303,25 +303,19 @@ static void __init psci_0_2_set_functions(void)
303} 303}
304 304
305/* 305/*
306 * PSCI Function IDs for v0.2+ are well defined so use 306 * Probe function for PSCI firmware versions >= 0.2
307 * standard values.
308 */ 307 */
309static int __init psci_0_2_init(struct device_node *np) 308static int __init psci_probe(void)
310{ 309{
311 int err, ver; 310 int ver = psci_get_version();
312
313 err = get_set_conduit_method(np);
314
315 if (err)
316 goto out_put_node;
317
318 ver = psci_get_version();
319 311
320 if (ver == PSCI_RET_NOT_SUPPORTED) { 312 if (ver == PSCI_RET_NOT_SUPPORTED) {
321 /* PSCI v0.2 mandates implementation of PSCI_ID_VERSION. */ 313 /*
314 * PSCI versions >=0.2 mandates implementation of
315 * PSCI_VERSION.
316 */
322 pr_err("PSCI firmware does not comply with the v0.2 spec.\n"); 317 pr_err("PSCI firmware does not comply with the v0.2 spec.\n");
323 err = -EOPNOTSUPP; 318 return -EOPNOTSUPP;
324 goto out_put_node;
325 } else { 319 } else {
326 pr_info("PSCIv%d.%d detected in firmware.\n", 320 pr_info("PSCIv%d.%d detected in firmware.\n",
327 PSCI_VERSION_MAJOR(ver), 321 PSCI_VERSION_MAJOR(ver),
@@ -329,14 +323,38 @@ static int __init psci_0_2_init(struct device_node *np)
329 323
330 if (PSCI_VERSION_MAJOR(ver) == 0 && 324 if (PSCI_VERSION_MAJOR(ver) == 0 &&
331 PSCI_VERSION_MINOR(ver) < 2) { 325 PSCI_VERSION_MINOR(ver) < 2) {
332 err = -EINVAL;
333 pr_err("Conflicting PSCI version detected.\n"); 326 pr_err("Conflicting PSCI version detected.\n");
334 goto out_put_node; 327 return -EINVAL;
335 } 328 }
336 } 329 }
337 330
338 psci_0_2_set_functions(); 331 psci_0_2_set_functions();
339 332
333 return 0;
334}
335
336/*
337 * PSCI init function for PSCI versions >=0.2
338 *
339 * Probe based on PSCI PSCI_VERSION function
340 */
341static int __init psci_0_2_init(struct device_node *np)
342{
343 int err;
344
345 err = get_set_conduit_method(np);
346
347 if (err)
348 goto out_put_node;
349 /*
350 * Starting with v0.2, the PSCI specification introduced a call
351 * (PSCI_VERSION) that allows probing the firmware version, so
352 * that PSCI function IDs and version specific initialization
353 * can be carried out according to the specific version reported
354 * by firmware
355 */
356 err = psci_probe();
357
340out_put_node: 358out_put_node:
341 of_node_put(np); 359 of_node_put(np);
342 return err; 360 return err;