Page MenuHomeFreeBSD

D47246.diff
No OneTemporary

D47246.diff

diff --git a/sys/dev/psci/psci.h b/sys/dev/psci/psci.h
--- a/sys/dev/psci/psci.h
+++ b/sys/dev/psci/psci.h
@@ -31,6 +31,12 @@
#include <dev/psci/smccc.h>
#ifdef _KERNEL
+typedef enum {
+ PSCI_METHOD_UNKNOWN,
+ PSCI_METHOD_HVC,
+ PSCI_METHOD_SMC,
+} psci_method_t;
+
typedef int (*psci_initfn_t)(device_t dev, int default_version);
typedef int (*psci_callfn_t)(register_t, register_t, register_t, register_t,
register_t, register_t, register_t, register_t,
@@ -42,6 +48,7 @@
void psci_reset(void);
int32_t psci_features(uint32_t);
int psci_get_version(void);
+psci_method_t psci_get_method(void);
/* Handler to let us call into the PSCI/SMCCC firmware */
extern psci_callfn_t psci_callfn;
diff --git a/sys/dev/psci/psci.c b/sys/dev/psci/psci.c
--- a/sys/dev/psci/psci.c
+++ b/sys/dev/psci/psci.c
@@ -126,24 +126,31 @@
static int psci_attach(device_t, psci_initfn_t, int);
-static int psci_find_callfn(psci_callfn_t *);
+static void psci_find_method(void);
static int psci_def_callfn(register_t, register_t, register_t, register_t,
register_t, register_t, register_t, register_t,
struct arm_smccc_res *res);
+static psci_method_t psci_method = PSCI_METHOD_UNKNOWN;
psci_callfn_t psci_callfn = psci_def_callfn;
static void
psci_init(void *dummy)
{
- psci_callfn_t new_callfn;
-
- if (psci_find_callfn(&new_callfn) != PSCI_RETVAL_SUCCESS) {
- printf("No PSCI/SMCCC call function found\n");
+ psci_find_method();
+ switch (psci_method) {
+ case PSCI_METHOD_UNKNOWN:
+ default:
+ printf("No PSCI/SMCCC call method found\n");
return;
+ case PSCI_METHOD_HVC:
+ psci_callfn = arm_smccc_hvc;
+ break;
+ case PSCI_METHOD_SMC:
+ psci_callfn = arm_smccc_smc;
+ break;
}
- psci_callfn = new_callfn;
psci_present = true;
}
/* This needs to be before cpu_mp at SI_SUB_CPU, SI_ORDER_THIRD */
@@ -182,24 +189,6 @@
EARLY_DRIVER_MODULE(psci, ofwbus, psci_fdt_driver, 0, 0,
BUS_PASS_CPU + BUS_PASS_ORDER_FIRST);
-static psci_callfn_t
-psci_fdt_get_callfn(phandle_t node)
-{
- char method[16];
-
- if ((OF_getprop(node, "method", method, sizeof(method))) > 0) {
- if (strcmp(method, "hvc") == 0)
- return (arm_smccc_hvc);
- else if (strcmp(method, "smc") == 0)
- return (arm_smccc_smc);
- else
- printf("psci: PSCI conduit \"%s\" invalid\n", method);
- } else
- printf("psci: PSCI conduit not supplied in the device tree\n");
-
- return (NULL);
-}
-
static int
psci_fdt_probe(device_t dev)
{
@@ -277,22 +266,6 @@
return (flags);
}
-static psci_callfn_t
-psci_acpi_get_callfn(int flags)
-{
-
- if ((flags & ACPI_FADT_PSCI_COMPLIANT) != 0) {
- if ((flags & ACPI_FADT_PSCI_USE_HVC) != 0)
- return (arm_smccc_hvc);
- else
- return (arm_smccc_smc);
- } else {
- printf("psci: PSCI conduit not supplied in the device tree\n");
- }
-
- return (NULL);
-}
-
static void
psci_acpi_identify(driver_t *driver, device_t parent)
{
@@ -379,9 +352,10 @@
}
#ifdef FDT
-static int
-psci_fdt_callfn(psci_callfn_t *callfn)
+static void
+psci_find_fdt_method(void)
{
+ char method[16];
phandle_t node;
/* XXX: This is suboptimal, we should walk the tree & check each
@@ -395,56 +369,61 @@
break;
}
if (node == 0)
- return (PSCI_MISSING);
+ return;
if (!ofw_bus_node_status_okay(node))
- return (PSCI_MISSING);
+ return;
- *callfn = psci_fdt_get_callfn(node);
- return (0);
+ if ((OF_getprop(node, "method", method, sizeof(method))) > 0) {
+ if (strcmp(method, "hvc") == 0)
+ psci_method = PSCI_METHOD_HVC;
+ else if (strcmp(method, "smc") == 0)
+ psci_method = PSCI_METHOD_SMC;
+ else
+ printf("psci: PSCI conduit \"%s\" invalid\n", method);
+ } else
+ printf("psci: PSCI conduit not supplied in the device tree\n");
}
#endif
#ifdef DEV_ACPI
-static int
-psci_acpi_callfn(psci_callfn_t *callfn)
+static void
+psci_find_acpi_method(void)
{
int flags;
flags = psci_acpi_bootflags();
if ((flags & ACPI_FADT_PSCI_COMPLIANT) == 0)
- return (PSCI_MISSING);
+ return;
- *callfn = psci_acpi_get_callfn(flags);
- return (0);
+ if ((flags & ACPI_FADT_PSCI_USE_HVC) != 0)
+ psci_method = PSCI_METHOD_HVC;
+ else
+ psci_method = PSCI_METHOD_SMC;
}
#endif
-static int
-psci_find_callfn(psci_callfn_t *callfn)
+static void
+psci_find_method(void)
{
- int error;
-
- *callfn = NULL;
#ifdef FDT
if (USE_FDT) {
- error = psci_fdt_callfn(callfn);
- if (error != 0)
- return (error);
+ psci_find_fdt_method();
+ return;
}
#endif
#ifdef DEV_ACPI
- if (*callfn == NULL && USE_ACPI) {
- error = psci_acpi_callfn(callfn);
- if (error != 0)
- return (error);
+ if (USE_ACPI) {
+ psci_find_acpi_method();
+ return;
}
#endif
+}
- if (*callfn == NULL)
- return (PSCI_MISSING);
-
- return (PSCI_RETVAL_SUCCESS);
+psci_method_t
+psci_get_method(void)
+{
+ return (psci_method);
}
int32_t

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 28, 1:47 AM (20 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14317470
Default Alt Text
D47246.diff (4 KB)

Event Timeline