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
x86
kernel
reboot_fixups_32.c
Go to the documentation of this file.
1
/*
2
* This is a good place to put board specific reboot fixups.
3
*
4
* List of supported fixups:
5
* geode-gx1/cs5530a - Jaya Kumar <
[email protected]
>
6
* geode-gx/lx/cs5536 - Andres Salomon <
[email protected]
>
7
*
8
*/
9
10
#include <asm/delay.h>
11
#include <linux/pci.h>
12
#include <
linux/interrupt.h
>
13
#include <
asm/reboot_fixups.h
>
14
#include <
asm/msr.h
>
15
#include <
linux/cs5535.h
>
16
17
static
void
cs5530a_warm_reset(
struct
pci_dev
*
dev
)
18
{
19
/* writing 1 to the reset control register, 0x44 causes the
20
cs5530a to perform a system warm reset */
21
pci_write_config_byte(dev, 0x44, 0x1);
22
udelay
(50);
/* shouldn't get here but be safe and spin-a-while */
23
return
;
24
}
25
26
static
void
cs5536_warm_reset(
struct
pci_dev
*
dev
)
27
{
28
/* writing 1 to the LSB of this MSR causes a hard reset */
29
wrmsrl(
MSR_DIVIL_SOFT_RESET
, 1ULL);
30
udelay
(50);
/* shouldn't get here but be safe and spin a while */
31
}
32
33
static
void
rdc321x_reset(
struct
pci_dev
*
dev
)
34
{
35
unsigned
i
;
36
/* Voluntary reset the watchdog timer */
37
outl
(0x80003840, 0xCF8);
38
/* Generate a CPU reset on next tick */
39
i =
inl
(0xCFC);
40
/* Use the minimum timer resolution */
41
i |= 0x1600;
42
outl
(i, 0xCFC);
43
outb
(1, 0x92);
44
}
45
46
static
void
ce4100_reset(
struct
pci_dev
*
dev
)
47
{
48
int
i
;
49
50
for
(i = 0; i < 10; i++) {
51
outb
(0x2, 0xcf9);
52
udelay
(50);
53
}
54
}
55
56
struct
device_fixup
{
57
unsigned
int
vendor
;
58
unsigned
int
device
;
59
void
(*
reboot_fixup
)(
struct
pci_dev
*);
60
};
61
62
/*
63
* PCI ids solely used for fixups_table go here
64
*/
65
#define PCI_DEVICE_ID_INTEL_CE4100 0x0708
66
67
static
const
struct
device_fixup
fixups_table[] = {
68
{
PCI_VENDOR_ID_CYRIX
,
PCI_DEVICE_ID_CYRIX_5530_LEGACY
, cs5530a_warm_reset },
69
{
PCI_VENDOR_ID_AMD
,
PCI_DEVICE_ID_AMD_CS5536_ISA
, cs5536_warm_reset },
70
{
PCI_VENDOR_ID_NS
,
PCI_DEVICE_ID_NS_SC1100_BRIDGE
, cs5530a_warm_reset },
71
{
PCI_VENDOR_ID_RDC
,
PCI_DEVICE_ID_RDC_R6030
, rdc321x_reset },
72
{
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_CE4100
, ce4100_reset },
73
};
74
75
/*
76
* we see if any fixup is available for our current hardware. if there
77
* is a fixup, we call it and we expect to never return from it. if we
78
* do return, we keep looking and then eventually fall back to the
79
* standard mach_reboot on return.
80
*/
81
void
mach_reboot_fixups
(
void
)
82
{
83
const
struct
device_fixup
*
cur
;
84
struct
pci_dev
*
dev
;
85
int
i
;
86
87
/* we can be called from sysrq-B code. In such a case it is
88
* prohibited to dig PCI */
89
if
(
in_interrupt
())
90
return
;
91
92
for
(i=0; i <
ARRAY_SIZE
(fixups_table); i++) {
93
cur = &(fixups_table[
i
]);
94
dev =
pci_get_device
(cur->
vendor
, cur->
device
,
NULL
);
95
if
(!dev)
96
continue
;
97
98
cur->
reboot_fixup
(dev);
99
pci_dev_put
(dev);
100
}
101
}
102
Generated on Thu Jan 10 2013 13:21:01 for Linux Kernel by
1.8.2