Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3808a889 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Michael Ellerman
Browse files

powerpc: Move FW feature probing out of pseries probe()



We move the function itself to pseries/firmware.c and call it along
with almost all other flat device-tree parsers from early_init_devtree()

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
[mpe: Move #ifdefs into the header by providing pseries_probe_fw_features()]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent c40785ad
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -126,6 +126,12 @@ extern int fwnmi_active;

extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup;

#ifdef CONFIG_PPC_PSERIES
void pseries_probe_fw_features(void);
#else
static inline void pseries_probe_fw_features(void) { };
#endif

#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_FIRMWARE_H */
+4 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#include <asm/fadump.h>
#include <asm/debug.h>
#include <asm/epapr_hcalls.h>
#include <asm/firmware.h>

#include <mm/mmu_decl.h>

@@ -755,6 +756,9 @@ void __init early_init_devtree(void *params)
#endif
	epapr_paravirt_early_init();

	/* Now try to figure out if we are running on LPAR and so on */
	pseries_probe_fw_features();

	DBG(" <- early_init_devtree()\n");
}

+46 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
 */


#include <linux/of_fdt.h>
#include <asm/firmware.h>
#include <asm/prom.h>
#include <asm/udbg.h>
@@ -69,7 +70,8 @@ hypertas_fw_features_table[] = {
 * device-tree/ibm,hypertas-functions.  Ultimately this functionality may
 * be moved into prom.c prom_init().
 */
void __init fw_hypertas_feature_init(const char *hypertas, unsigned long len)
static void __init fw_hypertas_feature_init(const char *hypertas,
					    unsigned long len)
{
	const char *s;
	int i;
@@ -113,7 +115,7 @@ vec5_fw_features_table[] = {
	{FW_FEATURE_PRRN,		OV5_PRRN},
};

void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
static void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
{
	unsigned int index, feat;
	int i;
@@ -131,3 +133,45 @@ void __init fw_vec5_feature_init(const char *vec5, unsigned long len)

	pr_debug(" <- fw_vec5_feature_init()\n");
}

/*
 * Called very early, MMU is off, device-tree isn't unflattened
 */
static int __init probe_fw_features(unsigned long node, const char *uname, int
				    depth, void *data)
{
	const char *prop;
	int len;
	static int hypertas_found;
	static int vec5_found;

	if (depth != 1)
		return 0;

	if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) {
		prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions",
					   &len);
		if (prop) {
			powerpc_firmware_features |= FW_FEATURE_LPAR;
			fw_hypertas_feature_init(prop, len);
		}

		hypertas_found = 1;
	}

	if (!strcmp(uname, "chosen")) {
		prop = of_get_flat_dt_prop(node, "ibm,architecture-vec-5",
					   &len);
		if (prop)
			fw_vec5_feature_init(prop, len);

		vec5_found = 1;
	}

	return hypertas_found && vec5_found;
}

void __init pseries_probe_fw_features(void)
{
	of_scan_flat_dt(probe_fw_features, NULL);
}
+0 −5
Original line number Diff line number Diff line
@@ -20,11 +20,6 @@ extern void request_event_sources_irqs(struct device_node *np,

#include <linux/of.h>

extern void __init fw_hypertas_feature_init(const char *hypertas,
					    unsigned long len);
extern void __init fw_vec5_feature_init(const char *hypertas,
					unsigned long len);

struct pt_regs;

extern int pSeries_system_reset_exception(struct pt_regs *regs);
+0 −41
Original line number Diff line number Diff line
@@ -659,45 +659,6 @@ static void pseries_power_off(void)
	for (;;);
}

/*
 * Called very early, MMU is off, device-tree isn't unflattened
 */

static int __init pseries_probe_fw_features(unsigned long node,
					    const char *uname, int depth,
					    void *data)
{
	const char *prop;
	int len;
	static int hypertas_found;
	static int vec5_found;

	if (depth != 1)
		return 0;

	if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) {
		prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions",
					   &len);
		if (prop) {
			powerpc_firmware_features |= FW_FEATURE_LPAR;
			fw_hypertas_feature_init(prop, len);
		}

		hypertas_found = 1;
	}

	if (!strcmp(uname, "chosen")) {
		prop = of_get_flat_dt_prop(node, "ibm,architecture-vec-5",
					   &len);
		if (prop)
			fw_vec5_feature_init(prop, len);

		vec5_found = 1;
	}

	return hypertas_found && vec5_found;
}

static int __init pSeries_probe(void)
{
	unsigned long root = of_get_flat_dt_root();
@@ -717,8 +678,6 @@ static int __init pSeries_probe(void)

	pr_debug("pSeries detected, looking for LPAR capability...\n");

	/* Now try to figure out if we are running on LPAR */
	of_scan_flat_dt(pseries_probe_fw_features, NULL);

#ifdef __LITTLE_ENDIAN__
	if (firmware_has_feature(FW_FEATURE_SET_MODE)) {