Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F101243849
D47246.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D47246.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 27, 2:50 PM (13 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14317470
Default Alt Text
D47246.diff (4 KB)
Attached To
Mode
D47246: dev/psci: Add a way to query the PSCI method
Attached
Detach File
Event Timeline
Log In to Comment