1/*
2 * misc.c:  Miscellaneous prom functions that don't belong
3 *          anywhere else.
4 *
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 */
7
8#include <linux/types.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/module.h>
12
13#include <asm/openprom.h>
14#include <asm/oplib.h>
15#include <asm/auxio.h>
16#include <asm/system.h>
17
18extern void restore_current(void);
19
20DEFINE_SPINLOCK(prom_lock);
21
22/* Reset and reboot the machine with the command 'bcommand'. */
23void
24prom_reboot(char *bcommand)
25{
26	unsigned long flags;
27	spin_lock_irqsave(&prom_lock, flags);
28	(*(romvec->pv_reboot))(bcommand);
29	/* Never get here. */
30	restore_current();
31	spin_unlock_irqrestore(&prom_lock, flags);
32}
33
34/* Forth evaluate the expression contained in 'fstring'. */
35void
36prom_feval(char *fstring)
37{
38	unsigned long flags;
39	if(!fstring || fstring[0] == 0)
40		return;
41	spin_lock_irqsave(&prom_lock, flags);
42	if(prom_vers == PROM_V0)
43		(*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring);
44	else
45		(*(romvec->pv_fortheval.v2_eval))(fstring);
46	restore_current();
47	spin_unlock_irqrestore(&prom_lock, flags);
48}
49EXPORT_SYMBOL(prom_feval);
50
51/* Drop into the prom, with the chance to continue with the 'go'
52 * prom command.
53 */
54void
55prom_cmdline(void)
56{
57	extern void install_obp_ticker(void);
58	extern void install_linux_ticker(void);
59	unsigned long flags;
60
61	spin_lock_irqsave(&prom_lock, flags);
62	install_obp_ticker();
63	(*(romvec->pv_abort))();
64	restore_current();
65	install_linux_ticker();
66	spin_unlock_irqrestore(&prom_lock, flags);
67	set_auxio(AUXIO_LED, 0);
68}
69
70/* Drop into the prom, but completely terminate the program.
71 * No chance of continuing.
72 */
73void
74prom_halt(void)
75{
76	unsigned long flags;
77again:
78	spin_lock_irqsave(&prom_lock, flags);
79	(*(romvec->pv_halt))();
80	/* Never get here. */
81	restore_current();
82	spin_unlock_irqrestore(&prom_lock, flags);
83	goto again; /* PROM is out to get me -DaveM */
84}
85
86typedef void (*sfunc_t)(void);
87
88/* Set prom sync handler to call function 'funcp'. */
89void
90prom_setsync(sfunc_t funcp)
91{
92	if(!funcp) return;
93	*romvec->pv_synchook = funcp;
94}
95
96/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
97 * format type.  'num_bytes' is the number of bytes that your idbuf
98 * has space for.  Returns 0xff on error.
99 */
100unsigned char
101prom_get_idprom(char *idbuf, int num_bytes)
102{
103	int len;
104
105	len = prom_getproplen(prom_root_node, "idprom");
106	if((len>num_bytes) || (len==-1)) return 0xff;
107	if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
108		return idbuf[0];
109
110	return 0xff;
111}
112
113/* Get the major prom version number. */
114int
115prom_version(void)
116{
117	return romvec->pv_romvers;
118}
119
120/* Get the prom plugin-revision. */
121int
122prom_getrev(void)
123{
124	return prom_rev;
125}
126
127/* Get the prom firmware print revision. */
128int
129prom_getprev(void)
130{
131	return prom_prev;
132}
133