Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sparc
kernel
apc.c
Go to the documentation of this file.
1
/* apc - Driver implementation for power management functions
2
* of Aurora Personality Chip (APC) on SPARCstation-4/5 and
3
* derivatives.
4
*
5
* Copyright (c) 2002 Eric Brower (
[email protected]
)
6
*/
7
8
#include <linux/kernel.h>
9
#include <linux/fs.h>
10
#include <linux/errno.h>
11
#include <
linux/init.h
>
12
#include <
linux/miscdevice.h
>
13
#include <
linux/pm.h
>
14
#include <
linux/of.h
>
15
#include <
linux/of_device.h
>
16
#include <linux/module.h>
17
18
#include <asm/io.h>
19
#include <asm/oplib.h>
20
#include <asm/uaccess.h>
21
#include <
asm/auxio.h
>
22
#include <
asm/apc.h
>
23
24
/* Debugging
25
*
26
* #define APC_DEBUG_LED
27
*/
28
29
#define APC_MINOR MISC_DYNAMIC_MINOR
30
#define APC_OBPNAME "power-management"
31
#define APC_DEVNAME "apc"
32
33
static
u8
__iomem
*
regs
;
34
static
int
apc_no_idle
__devinitdata
= 0;
35
36
#define apc_readb(offs) (sbus_readb(regs+offs))
37
#define apc_writeb(val, offs) (sbus_writeb(val, regs+offs))
38
39
/* Specify "apc=noidle" on the kernel command line to
40
* disable APC CPU standby support. Certain prototype
41
* systems (SPARCstation-Fox) do not play well with APC
42
* CPU idle, so disable this if your system has APC and
43
* crashes randomly.
44
*/
45
static
int
__init
apc_setup(
char
*
str
)
46
{
47
if
(!
strncmp
(str,
"noidle"
,
strlen
(
"noidle"
))) {
48
apc_no_idle = 1;
49
return
1;
50
}
51
return
0;
52
}
53
__setup
(
"apc="
, apc_setup);
54
55
/*
56
* CPU idle callback function
57
* See .../arch/sparc/kernel/process.c
58
*/
59
static
void
apc_swift_idle(
void
)
60
{
61
#ifdef APC_DEBUG_LED
62
set_auxio
(0x00,
AUXIO_LED
);
63
#endif
64
65
apc_writeb
(
apc_readb
(
APC_IDLE_REG
) |
APC_IDLE_ON
,
APC_IDLE_REG
);
66
67
#ifdef APC_DEBUG_LED
68
set_auxio
(
AUXIO_LED
, 0x00);
69
#endif
70
}
71
72
static
inline
void
apc_free(
struct
platform_device
*
op
)
73
{
74
of_iounmap
(&op->
resource
[0],
regs
, resource_size(&op->
resource
[0]));
75
}
76
77
static
int
apc_open(
struct
inode
*
inode
,
struct
file
*
f
)
78
{
79
return
0;
80
}
81
82
static
int
apc_release(
struct
inode
*
inode
,
struct
file
*
f
)
83
{
84
return
0;
85
}
86
87
static
long
apc_ioctl(
struct
file
*
f
,
unsigned
int
cmd
,
unsigned
long
__arg)
88
{
89
__u8
inarg,
__user
*
arg
= (
__u8
__user
*) __arg;
90
91
switch
(cmd) {
92
case
APCIOCGFANCTL
:
93
if
(
put_user
(
apc_readb
(
APC_FANCTL_REG
) &
APC_REGMASK
, arg))
94
return
-
EFAULT
;
95
break
;
96
97
case
APCIOCGCPWR
:
98
if
(
put_user
(
apc_readb
(
APC_CPOWER_REG
) & APC_REGMASK, arg))
99
return
-
EFAULT
;
100
break
;
101
102
case
APCIOCGBPORT
:
103
if
(
put_user
(
apc_readb
(
APC_BPORT_REG
) &
APC_BPMASK
, arg))
104
return
-
EFAULT
;
105
break
;
106
107
case
APCIOCSFANCTL
:
108
if
(
get_user
(inarg, arg))
109
return
-
EFAULT
;
110
apc_writeb
(inarg & APC_REGMASK,
APC_FANCTL_REG
);
111
break
;
112
113
case
APCIOCSCPWR
:
114
if
(
get_user
(inarg, arg))
115
return
-
EFAULT
;
116
apc_writeb
(inarg & APC_REGMASK,
APC_CPOWER_REG
);
117
break
;
118
119
case
APCIOCSBPORT
:
120
if
(
get_user
(inarg, arg))
121
return
-
EFAULT
;
122
apc_writeb
(inarg & APC_BPMASK,
APC_BPORT_REG
);
123
break
;
124
125
default
:
126
return
-
EINVAL
;
127
}
128
129
return
0;
130
}
131
132
static
const
struct
file_operations
apc_fops = {
133
.unlocked_ioctl = apc_ioctl,
134
.open = apc_open,
135
.release = apc_release,
136
.llseek =
noop_llseek
,
137
};
138
139
static
struct
miscdevice
apc_miscdev = {
APC_MINOR
,
APC_DEVNAME
, &apc_fops };
140
141
static
int
__devinit
apc_probe(
struct
platform_device
*op)
142
{
143
int
err
;
144
145
regs
=
of_ioremap
(&op->
resource
[0], 0,
146
resource_size(&op->
resource
[0]),
APC_OBPNAME
);
147
if
(!
regs
) {
148
printk
(
KERN_ERR
"%s: unable to map registers\n"
,
APC_DEVNAME
);
149
return
-
ENODEV
;
150
}
151
152
err =
misc_register
(&apc_miscdev);
153
if
(err) {
154
printk
(
KERN_ERR
"%s: unable to register device\n"
,
APC_DEVNAME
);
155
apc_free(op);
156
return
-
ENODEV
;
157
}
158
159
/* Assign power management IDLE handler */
160
if
(!apc_no_idle)
161
pm_idle
= apc_swift_idle;
162
163
printk
(
KERN_INFO
"%s: power management initialized%s\n"
,
164
APC_DEVNAME
, apc_no_idle ?
" (CPU idle disabled)"
:
""
);
165
166
return
0;
167
}
168
169
static
struct
of_device_id
apc_match[] = {
170
{
171
.name =
APC_OBPNAME
,
172
},
173
{},
174
};
175
MODULE_DEVICE_TABLE
(of, apc_match);
176
177
static
struct
platform_driver
apc_driver = {
178
.driver = {
179
.name =
"apc"
,
180
.owner =
THIS_MODULE
,
181
.of_match_table = apc_match,
182
},
183
.probe = apc_probe,
184
};
185
186
static
int
__init
apc_init(
void
)
187
{
188
return
platform_driver_register
(&apc_driver);
189
}
190
191
/* This driver is not critical to the boot process
192
* and is easiest to ioremap when SBus is already
193
* initialized, so we install ourselves thusly:
194
*/
195
__initcall
(apc_init);
Generated on Thu Jan 10 2013 13:18:15 for Linux Kernel by
1.8.2