Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F176188470
D15745.id43565.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
D15745.id43565.diff
View Options
Index: sys/dev/psci/psci.h
===================================================================
--- sys/dev/psci/psci.h
+++ sys/dev/psci/psci.h
@@ -43,6 +43,9 @@
int psci_get_version(void);
+/* An internal function to find the PSCI/SMCCC call function */
+int psci_find_callfn(psci_callfn_t *);
+
/*
* PSCI return codes.
*/
Index: sys/dev/psci/psci.c
===================================================================
--- sys/dev/psci/psci.c
+++ sys/dev/psci/psci.c
@@ -74,7 +74,6 @@
struct psci_softc {
device_t dev;
- psci_callfn_t psci_call;
uint32_t psci_fnids[PSCI_FN_MAX];
};
@@ -107,6 +106,40 @@
static int psci_attach(device_t, psci_initfn_t);
static void psci_shutdown(void *, int);
+static int psci_def_callfn(register_t, register_t, register_t, register_t);
+
+static psci_callfn_t psci_callfn = psci_def_callfn;
+
+static inline int
+psci_call(register_t a, register_t b, register_t c, register_t d)
+{
+
+ return (psci_callfn(a, b, c, d));
+}
+
+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");
+ return;
+ }
+
+ psci_callfn = new_callfn;
+}
+/* This needs to be before cpu_mp at SI_SUB_CPU, SI_ORDER_THIRD */
+SYSINIT(psci_start, SI_SUB_CPU, SI_ORDER_FIRST, psci_init, NULL);
+
+static int
+psci_def_callfn(register_t a __unused, register_t b __unused,
+ register_t c __unused, register_t d __unused)
+{
+
+ panic("No PSCI/SMCCC call function set");
+}
+
#ifdef FDT
static int psci_fdt_probe(device_t dev);
static int psci_fdt_attach(device_t dev);
@@ -169,17 +202,12 @@
static int
psci_fdt_attach(device_t dev)
{
- struct psci_softc *sc = device_get_softc(dev);
const struct ofw_compat_data *ocd;
psci_initfn_t psci_init;
- phandle_t node;
ocd = ofw_bus_search_compatible(dev, compat_data);
psci_init = (psci_initfn_t)ocd->ocd_data;
- node = ofw_bus_get_node(dev);
- sc->psci_call = psci_fdt_get_callfn(node);
-
return (psci_attach(dev, psci_init));
}
#endif
@@ -283,12 +311,6 @@
struct psci_softc *sc = device_get_softc(dev);
uintptr_t flags;
- flags = (uintptr_t)acpi_get_private(dev);
- if ((flags & ACPI_FADT_PSCI_USE_HVC) != 0)
- sc->psci_call = psci_hvc_despatch;
- else
- sc->psci_call = psci_smc_despatch;
-
return (psci_attach(dev, psci_v0_2_init));
}
#endif
@@ -301,9 +323,6 @@
if (psci_softc != NULL)
return (ENXIO);
- if (sc->psci_call == NULL)
- return (ENXIO);
-
KASSERT(psci_init != NULL, ("PSCI init function cannot be NULL"));
if (psci_init(dev))
return (ENXIO);
@@ -321,7 +340,7 @@
/* PSCI version wasn't supported in v0.1. */
fnid = sc->psci_fnids[PSCI_FN_VERSION];
if (fnid)
- return (sc->psci_call(fnid, 0, 0, 0));
+ return (psci_call(fnid, 0, 0, 0));
return (PSCI_RETVAL_NOT_SUPPORTED);
}
@@ -369,39 +388,43 @@
#endif
int
-psci_cpu_on(unsigned long cpu, unsigned long entry, unsigned long context_id)
+psci_find_callfn(psci_callfn_t *callfn)
{
- psci_callfn_t callfn;
- uint32_t fnid;
int error;
- if (psci_softc == NULL) {
- fnid = PSCI_FNID_CPU_ON;
- callfn = NULL;
+ *callfn = NULL;
#ifdef FDT
- if (USE_FDT) {
- error = psci_fdt_callfn(&callfn);
- if (error != 0)
- return (error);
- }
+ if (USE_FDT) {
+ error = psci_fdt_callfn(callfn);
+ if (error != 0)
+ return (error);
+ }
#endif
#ifdef DEV_ACPI
- if (callfn == NULL && USE_ACPI) {
- error = psci_acpi_callfn(&callfn);
- if (error != 0)
- return (error);
- }
+ if (*callfn == NULL && USE_ACPI) {
+ error = psci_acpi_callfn(callfn);
+ if (error != 0)
+ return (error);
+ }
#endif
- if (callfn == NULL)
- return (PSCI_MISSING);
- } else {
- callfn = psci_softc->psci_call;
+ if (*callfn == NULL)
+ return (PSCI_MISSING);
+
+ return (PSCI_RETVAL_SUCCESS);
+}
+
+int
+psci_cpu_on(unsigned long cpu, unsigned long entry, unsigned long context_id)
+{
+ uint32_t fnid;
+
+ fnid = PSCI_FNID_CPU_ON;
+ if (psci_softc != NULL)
fnid = psci_softc->psci_fnids[PSCI_FN_CPU_ON];
- }
/* PSCI v0.1 and v0.2 both support cpu_on. */
- return (callfn(fnid, cpu, entry, context_id));
+ return (psci_call(fnid, cpu, entry, context_id));
}
static void
@@ -419,7 +442,7 @@
fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_RESET];
if (fn)
- psci_softc->psci_call(fn, 0, 0, 0);
+ psci_call(fn, 0, 0, 0);
/* System reset and off do not return. */
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 17, 7:44 PM (10 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40954836
Default Alt Text
D15745.id43565.diff (4 KB)
Attached To
Mode
D15745: Rework PSCI so it only searches for the call function once.
Attached
Detach File
Event Timeline
Log In to Comment