xref: /kernel/linux/linux-6.6/arch/sparc/prom/misc_32.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * misc.c:  Miscellaneous prom functions that don't belong
462306a36Sopenharmony_ci *          anywhere else.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <linux/kernel.h>
1162306a36Sopenharmony_ci#include <linux/sched.h>
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <asm/openprom.h>
1562306a36Sopenharmony_ci#include <asm/oplib.h>
1662306a36Sopenharmony_ci#include <asm/auxio.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciextern void restore_current(void);
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciDEFINE_SPINLOCK(prom_lock);
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Reset and reboot the machine with the command 'bcommand'. */
2362306a36Sopenharmony_civoid
2462306a36Sopenharmony_ciprom_reboot(char *bcommand)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	unsigned long flags;
2762306a36Sopenharmony_ci	spin_lock_irqsave(&prom_lock, flags);
2862306a36Sopenharmony_ci	(*(romvec->pv_reboot))(bcommand);
2962306a36Sopenharmony_ci	/* Never get here. */
3062306a36Sopenharmony_ci	restore_current();
3162306a36Sopenharmony_ci	spin_unlock_irqrestore(&prom_lock, flags);
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/* Forth evaluate the expression contained in 'fstring'. */
3562306a36Sopenharmony_civoid
3662306a36Sopenharmony_ciprom_feval(char *fstring)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	unsigned long flags;
3962306a36Sopenharmony_ci	if(!fstring || fstring[0] == 0)
4062306a36Sopenharmony_ci		return;
4162306a36Sopenharmony_ci	spin_lock_irqsave(&prom_lock, flags);
4262306a36Sopenharmony_ci	if(prom_vers == PROM_V0)
4362306a36Sopenharmony_ci		(*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring);
4462306a36Sopenharmony_ci	else
4562306a36Sopenharmony_ci		(*(romvec->pv_fortheval.v2_eval))(fstring);
4662306a36Sopenharmony_ci	restore_current();
4762306a36Sopenharmony_ci	spin_unlock_irqrestore(&prom_lock, flags);
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ciEXPORT_SYMBOL(prom_feval);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* Drop into the prom, with the chance to continue with the 'go'
5262306a36Sopenharmony_ci * prom command.
5362306a36Sopenharmony_ci */
5462306a36Sopenharmony_civoid
5562306a36Sopenharmony_ciprom_cmdline(void)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	unsigned long flags;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	spin_lock_irqsave(&prom_lock, flags);
6062306a36Sopenharmony_ci	(*(romvec->pv_abort))();
6162306a36Sopenharmony_ci	restore_current();
6262306a36Sopenharmony_ci	spin_unlock_irqrestore(&prom_lock, flags);
6362306a36Sopenharmony_ci	set_auxio(AUXIO_LED, 0);
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* Drop into the prom, but completely terminate the program.
6762306a36Sopenharmony_ci * No chance of continuing.
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_civoid __noreturn
7062306a36Sopenharmony_ciprom_halt(void)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	unsigned long flags;
7362306a36Sopenharmony_ciagain:
7462306a36Sopenharmony_ci	spin_lock_irqsave(&prom_lock, flags);
7562306a36Sopenharmony_ci	(*(romvec->pv_halt))();
7662306a36Sopenharmony_ci	/* Never get here. */
7762306a36Sopenharmony_ci	restore_current();
7862306a36Sopenharmony_ci	spin_unlock_irqrestore(&prom_lock, flags);
7962306a36Sopenharmony_ci	goto again; /* PROM is out to get me -DaveM */
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_citypedef void (*sfunc_t)(void);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/* Set prom sync handler to call function 'funcp'. */
8562306a36Sopenharmony_civoid
8662306a36Sopenharmony_ciprom_setsync(sfunc_t funcp)
8762306a36Sopenharmony_ci{
8862306a36Sopenharmony_ci	if(!funcp) return;
8962306a36Sopenharmony_ci	*romvec->pv_synchook = funcp;
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
9362306a36Sopenharmony_ci * format type.  'num_bytes' is the number of bytes that your idbuf
9462306a36Sopenharmony_ci * has space for.  Returns 0xff on error.
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_ciunsigned char
9762306a36Sopenharmony_ciprom_get_idprom(char *idbuf, int num_bytes)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	int len;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	len = prom_getproplen(prom_root_node, "idprom");
10262306a36Sopenharmony_ci	if((len>num_bytes) || (len==-1)) return 0xff;
10362306a36Sopenharmony_ci	if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
10462306a36Sopenharmony_ci		return idbuf[0];
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	return 0xff;
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/* Get the major prom version number. */
11062306a36Sopenharmony_ciint
11162306a36Sopenharmony_ciprom_version(void)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	return romvec->pv_romvers;
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/* Get the prom plugin-revision. */
11762306a36Sopenharmony_ciint
11862306a36Sopenharmony_ciprom_getrev(void)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci	return prom_rev;
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/* Get the prom firmware print revision. */
12462306a36Sopenharmony_ciint
12562306a36Sopenharmony_ciprom_getprev(void)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	return prom_prev;
12862306a36Sopenharmony_ci}
129