Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
be9e929d
Commit
be9e929d
authored
Jun 10, 2003
by
Patrick Mochel
Browse files
Options
Browse Files
Download
Plain Diff
Hand merge
parents
ae6a0c46
3d983e57
Changes
23
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
793 additions
and
394 deletions
+793
-394
arch/arm/kernel/pm.c
arch/arm/kernel/pm.c
+0
-8
arch/i386/kernel/apic.c
arch/i386/kernel/apic.c
+20
-25
arch/i386/kernel/cpu/mtrr/main.c
arch/i386/kernel/cpu/mtrr/main.c
+58
-2
arch/i386/kernel/i8259.c
arch/i386/kernel/i8259.c
+27
-35
arch/i386/kernel/nmi.c
arch/i386/kernel/nmi.c
+17
-21
arch/i386/kernel/time.c
arch/i386/kernel/time.c
+10
-6
arch/i386/oprofile/nmi_int.c
arch/i386/oprofile/nmi_int.c
+14
-19
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/i8259.c
+12
-16
drivers/base/cpu.c
drivers/base/cpu.c
+8
-40
drivers/base/memblk.c
drivers/base/memblk.c
+13
-18
drivers/base/node.c
drivers/base/node.c
+11
-30
drivers/base/power.c
drivers/base/power.c
+43
-0
drivers/base/sys.c
drivers/base/sys.c
+386
-81
drivers/s390/block/xpram.c
drivers/s390/block/xpram.c
+16
-7
fs/sysfs/file.c
fs/sysfs/file.c
+2
-2
include/linux/cpu.h
include/linux/cpu.h
+2
-3
include/linux/cpufreq.h
include/linux/cpufreq.h
+0
-4
include/linux/device.h
include/linux/device.h
+0
-24
include/linux/kobject.h
include/linux/kobject.h
+8
-0
include/linux/list.h
include/linux/list.h
+14
-0
include/linux/node.h
include/linux/node.h
+2
-2
include/linux/sysdev.h
include/linux/sysdev.h
+98
-0
kernel/cpufreq.c
kernel/cpufreq.c
+32
-51
No files found.
arch/arm/kernel/pm.c
View file @
be9e929d
...
...
@@ -11,7 +11,6 @@
#include <linux/config.h>
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <asm/leds.h>
#include <asm/system.h>
...
...
@@ -66,13 +65,6 @@ int suspend(void)
*/
device_resume
(
RESUME_POWER_ON
);
/*
* Restore the CPU frequency settings.
*/
#ifdef CONFIG_CPU_FREQ
cpufreq_restore
();
#endif
/*
* Resume LDM devices.
*/
...
...
arch/i386/kernel/apic.c
View file @
be9e929d
...
...
@@ -25,6 +25,9 @@
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
#include <linux/module.h>
#include <asm/atomic.h>
#include <asm/smp.h>
...
...
@@ -460,9 +463,6 @@ void __init setup_local_APIC (void)
#ifdef CONFIG_PM
#include <linux/device.h>
#include <linux/module.h>
static
struct
{
/* 'active' is true if the local APIC was enabled by us and
not the BIOS; this signifies that we are also responsible
...
...
@@ -484,13 +484,11 @@ static struct {
unsigned
int
apic_thmr
;
}
apic_pm_state
;
static
int
lapic_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
static
int
lapic_suspend
(
struct
sys_device
*
dev
,
u32
state
)
{
unsigned
int
l
,
h
;
unsigned
long
flags
;
if
(
level
!=
SUSPEND_POWER_DOWN
)
return
0
;
if
(
!
apic_pm_state
.
active
)
return
0
;
...
...
@@ -517,13 +515,11 @@ static int lapic_suspend(struct device *dev, u32 state, u32 level)
return
0
;
}
static
int
lapic_resume
(
struct
device
*
dev
,
u32
level
)
static
int
lapic_resume
(
struct
sys_device
*
dev
)
{
unsigned
int
l
,
h
;
unsigned
long
flags
;
if
(
level
!=
RESUME_POWER_ON
)
return
0
;
if
(
!
apic_pm_state
.
active
)
return
0
;
...
...
@@ -557,38 +553,37 @@ static int lapic_resume(struct device *dev, u32 level)
return
0
;
}
static
struct
device_driver
lapic_driver
=
{
.
name
=
"lapic"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
lapic_sysclass
=
{
set_kset_name
(
"lapic"
)
,
.
resume
=
lapic_resume
,
.
suspend
=
lapic_suspend
,
};
/* not static, needed by child devices */
struct
sys_device
device_lapic
=
{
.
name
=
"lapic"
,
static
struct
sys_device
device_lapic
=
{
.
id
=
0
,
.
dev
=
{
.
name
=
"lapic"
,
.
driver
=
&
lapic_driver
,
},
.
cls
=
&
lapic_sysclass
,
};
EXPORT_SYMBOL
(
device_lapic
);
static
void
__init
apic_pm_activate
(
void
)
{
apic_pm_state
.
active
=
1
;
}
static
int
__init
init_lapic_
device
fs
(
void
)
static
int
__init
init_lapic_
sys
fs
(
void
)
{
int
error
;
if
(
!
cpu_has_apic
)
return
0
;
/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
driver_register
(
&
lapic_driver
);
return
sys_device_register
(
&
device_lapic
);
error
=
sysdev_class_register
(
&
lapic_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_lapic
);
return
error
;
}
device_initcall
(
init_lapic_
device
fs
);
device_initcall
(
init_lapic_
sys
fs
);
#else
/* CONFIG_PM */
...
...
arch/i386/kernel/cpu/mtrr/main.c
View file @
be9e929d
...
...
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/cpu.h>
#include <asm/mtrr.h>
...
...
@@ -546,6 +547,58 @@ static void init_other_cpus(void)
}
}
struct
mtrr_value
{
mtrr_type
ltype
;
unsigned
long
lbase
;
unsigned
int
lsize
;
};
static
struct
mtrr_value
*
mtrr_state
;
static
int
mtrr_save
(
struct
sys_device
*
sysdev
,
u32
state
)
{
int
i
;
int
size
=
num_var_ranges
*
sizeof
(
struct
mtrr_value
);
mtrr_state
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
mtrr_state
)
memset
(
mtrr_state
,
0
,
size
);
else
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
num_var_ranges
;
i
++
)
{
mtrr_if
->
get
(
i
,
&
mtrr_state
[
i
].
lbase
,
&
mtrr_state
[
i
].
lsize
,
&
mtrr_state
[
i
].
ltype
);
}
return
0
;
}
static
int
mtrr_restore
(
struct
sys_device
*
sysdev
)
{
int
i
;
for
(
i
=
0
;
i
<
num_var_ranges
;
i
++
)
{
if
(
mtrr_state
[
i
].
lsize
)
set_mtrr
(
i
,
mtrr_state
[
i
].
lbase
,
mtrr_state
[
i
].
lsize
,
mtrr_state
[
i
].
ltype
);
}
kfree
(
mtrr_state
);
return
0
;
}
static
struct
sysdev_driver
mtrr_sysdev_driver
=
{
.
save
=
mtrr_save
,
.
restore
=
mtrr_restore
,
};
/**
* mtrr_init - initialie mtrrs on the boot CPU
*
...
...
@@ -630,8 +683,11 @@ static int __init mtrr_init(void)
set_num_var_ranges
();
init_table
();
init_other_cpus
();
return
sysdev_driver_register
(
&
cpu_sysdev_class
,
&
mtrr_sysdev_driver
);
}
return
mtrr_if
?
-
ENXIO
:
0
;
return
-
ENXIO
;
}
char
*
mtrr_strings
[
MTRR_NUM_TYPES
]
=
...
...
@@ -645,5 +701,5 @@ char *mtrr_strings[MTRR_NUM_TYPES] =
"write-back"
,
/* 6 */
};
core
_initcall
(
mtrr_init
);
subsys
_initcall
(
mtrr_init
);
arch/i386/kernel/i8259.c
View file @
be9e929d
...
...
@@ -10,7 +10,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <asm/atomic.h>
#include <asm/system.h>
...
...
@@ -238,35 +238,31 @@ void mask_and_ack_8259A(unsigned int irq)
}
}
static
int
i8259A_resume
(
struct
device
*
dev
,
u32
level
)
static
int
i8259A_resume
(
struct
sys_device
*
dev
)
{
if
(
level
==
RESUME_POWER_ON
)
init_8259A
(
0
);
return
0
;
}
static
struct
device_driver
i8259A_driver
=
{
.
name
=
"pic"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
i8259_sysdev_class
=
{
set_kset_name
(
"i8259"
),
.
resume
=
i8259A_resume
,
};
static
struct
sys_device
device_i8259A
=
{
.
name
=
"pic"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"i8259A PIC"
,
.
driver
=
&
i8259A_driver
,
},
.
cls
=
&
i8259_sysdev_class
,
};
static
int
__init
i
nit_8259A_device
fs
(
void
)
static
int
__init
i
8259A_init_sys
fs
(
void
)
{
driver_register
(
&
i8259A_driver
);
return
sys_device_register
(
&
device_i8259A
);
int
error
=
sysdev_class_register
(
&
i8259_sysdev_class
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_i8259A
);
return
error
;
}
device_initcall
(
i
nit_8259A_device
fs
);
device_initcall
(
i
8259A_init_sys
fs
);
void
init_8259A
(
int
auto_eoi
)
{
...
...
@@ -385,35 +381,31 @@ static void setup_timer(void)
spin_unlock_irqrestore
(
&
i8253_lock
,
flags
);
}
static
int
timer_resume
(
struct
device
*
dev
,
u32
level
)
static
int
timer_resume
(
struct
sys_device
*
dev
)
{
if
(
level
==
RESUME_POWER_ON
)
setup_timer
();
return
0
;
}
static
struct
device_driver
timer_driver
=
{
.
name
=
"timer"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
timer_sysclass
=
{
set_kset_name
(
"timer"
),
.
resume
=
timer_resume
,
};
static
struct
sys_device
device_timer
=
{
.
name
=
"timer"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"timer"
,
.
driver
=
&
timer_driver
,
},
.
cls
=
&
timer_sysclass
,
};
static
int
__init
init_timer_
device
fs
(
void
)
static
int
__init
init_timer_
sys
fs
(
void
)
{
driver_register
(
&
timer_driver
);
return
sys_device_register
(
&
device_timer
);
int
error
=
sysdev_class_register
(
&
timer_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_timer
);
return
error
;
}
device_initcall
(
init_timer_
device
fs
);
device_initcall
(
init_timer_
sys
fs
);
void
__init
init_IRQ
(
void
)
{
...
...
arch/i386/kernel/nmi.c
View file @
be9e929d
...
...
@@ -23,6 +23,7 @@
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <asm/smp.h>
#include <asm/mtrr.h>
...
...
@@ -180,53 +181,48 @@ void enable_lapic_nmi_watchdog(void)
#ifdef CONFIG_PM
#include <linux/device.h>
static
int
nmi_pm_active
;
/* nmi_active before suspend */
static
int
lapic_nmi_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
static
int
lapic_nmi_suspend
(
struct
sys_device
*
dev
,
u32
state
)
{
if
(
level
!=
SUSPEND_POWER_DOWN
)
return
0
;
nmi_pm_active
=
nmi_active
;
disable_lapic_nmi_watchdog
();
return
0
;
}
static
int
lapic_nmi_resume
(
struct
device
*
dev
,
u32
level
)
static
int
lapic_nmi_resume
(
struct
sys_device
*
dev
)
{
if
(
level
!=
RESUME_POWER_ON
)
return
0
;
if
(
nmi_pm_active
>
0
)
enable_lapic_nmi_watchdog
();
return
0
;
}
static
struct
device_driver
lapic_nmi_driver
=
{
.
name
=
"lapic_nmi"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
nmi_sysclass
=
{
set_kset_name
(
"lapic_nmi"
)
,
.
resume
=
lapic_nmi_resume
,
.
suspend
=
lapic_nmi_suspend
,
};
static
struct
sys_device
device_lapic_nmi
=
{
.
name
=
"lapic_nmi"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"lapic_nmi"
,
.
driver
=
&
lapic_nmi_driver
,
.
parent
=
&
device_lapic
.
dev
,
},
.
cls
=
&
nmi_sysclass
,
};
static
int
__init
init_lapic_nmi_
device
fs
(
void
)
static
int
__init
init_lapic_nmi_
sys
fs
(
void
)
{
int
error
;
if
(
nmi_active
==
0
)
return
0
;
driver_register
(
&
lapic_nmi_driver
);
return
sys_device_register
(
&
device_lapic_nmi
);
error
=
sysdev_class_register
(
&
nmi_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_lapic_nmi
);
return
error
;
}
/* must come after the local APIC's device_initcall() */
late_initcall
(
init_lapic_nmi_
device
fs
);
late_initcall
(
init_lapic_nmi_
sys
fs
);
#endif
/* CONFIG_PM */
...
...
arch/i386/kernel/time.c
View file @
be9e929d
...
...
@@ -42,7 +42,7 @@
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/module.h>
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <linux/bcd.h>
#include <asm/io.h>
...
...
@@ -278,18 +278,22 @@ unsigned long get_cmos_time(void)
return
retval
;
}
static
struct
sysdev_class
rtc_sysclass
=
{
set_kset_name
(
"rtc"
),
};
/* XXX this driverfs stuff should probably go elsewhere later -john */
static
struct
sys_device
device_i8253
=
{
.
name
=
"rtc"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"i8253 Real Time Clock"
,
},
.
cls
=
&
rtc_sysclass
,
};
static
int
time_init_device
(
void
)
{
return
sys_device_register
(
&
device_i8253
);
int
error
=
sysdev_class_register
(
&
rtc_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_i8253
);
return
error
;
}
device_initcall
(
time_init_device
);
...
...
arch/i386/oprofile/nmi_int.c
View file @
be9e929d
...
...
@@ -11,7 +11,7 @@
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/oprofile.h>
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
...
...
@@ -31,53 +31,48 @@ static int nmi_enabled = 0;
#ifdef CONFIG_PM
static
int
nmi_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
static
int
nmi_suspend
(
struct
sys_device
*
dev
,
u32
state
)
{
if
(
level
!=
SUSPEND_POWER_DOWN
)
return
0
;
if
(
nmi_enabled
==
1
)
nmi_stop
();
return
0
;
}
static
int
nmi_resume
(
struct
device
*
dev
,
u32
level
)
static
int
nmi_resume
(
struct
sys_device
*
dev
)
{
if
(
level
!=
RESUME_POWER_ON
)
return
0
;
if
(
nmi_enabled
==
1
)
nmi_start
();
return
0
;
}
static
struct
device_driver
nmi_driver
=
{
.
name
=
"oprofile"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
oprofile_sysclass
=
{
set_kset_name
(
"oprofile"
),
.
resume
=
nmi_resume
,
.
suspend
=
nmi_suspend
,
};
static
struct
device
device_nmi
=
{
.
name
=
"oprofile"
,
.
bus_id
=
"oprofile"
,
.
driver
=
&
nmi_driver
,
.
parent
=
&
device_lapic
.
dev
,
static
struct
sys_device
device_oprofile
=
{
.
id
=
0
,
.
cls
=
&
oprofile_sysclass
,
};
static
int
__init
init_driverfs
(
void
)
{
driver_register
(
&
nmi_driver
);
return
device_register
(
&
device_nmi
);
int
error
;
if
(
!
(
error
=
sysdev_class_register
(
&
oprofile_sysclass
)))
error
=
sys_device_register
(
&
device_oprofile
);
return
error
;
}
static
void
__exit
exit_driverfs
(
void
)
{
device_unregister
(
&
device_nmi
);
driver_unregister
(
&
nmi_driver
);
sys_device_unregister
(
&
device_oprofile
);
sysdev_class_unregister
(
&
oprofile_sysclass
);
}
#else
...
...
arch/x86_64/kernel/i8259.c
View file @
be9e929d
...
...
@@ -11,7 +11,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <asm/atomic.h>
#include <asm/system.h>
...
...
@@ -413,35 +413,31 @@ static void setup_timer(void)
outb
(
LATCH
>>
8
,
0x40
);
/* MSB */
}
static
int
timer_resume
(
struct
device
*
dev
,
u32
level
)
static
int
timer_resume
(
struct
sys_device
*
dev
)
{
if
(
level
==
RESUME_POWER_ON
)
setup_timer
();
return
0
;
}
static
struct
device_driver
timer_driver
=
{
.
name
=
"timer"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
timer_sysclass
=
{
set_kset_name
(
"timer"
),
.
resume
=
timer_resume
,
};
static
struct
sys_device
device_timer
=
{
.
name
=
"timer"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"timer"
,
.
driver
=
&
timer_driver
,
},
.
cls
&
timer_sysclass
,
};
static
int
__init
init_timer_
device
fs
(
void
)
static
int
__init
init_timer_
sys
fs
(
void
)
{
driver_register
(
&
timer_driver
);
return
sys_device_register
(
&
device_timer
);
int
error
=
sysdev_class_register
(
&
timer_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_timer
);
return
error
;
}
device_initcall
(
init_timer_
device
fs
);
device_initcall
(
init_timer_
sys
fs
);
void
__init
init_IRQ
(
void
)
{
...
...
drivers/base/cpu.c
View file @
be9e929d
...
...
@@ -2,23 +2,18 @@
* drivers/base/cpu.c - basic CPU class support
*/
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/topology.h>
#include <asm/topology.h>
struct
class
cpu
_class
=
{
.
name
=
"cpu"
,
struct
sysdev_class
cpu_sysdev
_class
=
{
set_kset_name
(
"cpu"
)
,
};
struct
device_driver
cpu_driver
=
{
.
name
=
"cpu"
,
.
bus
=
&
system_bus_type
,
};
/*
* register_cpu - Setup a driverfs device for a CPU.
* @num - CPU number to use when creating the device.
...
...
@@ -27,42 +22,15 @@ struct device_driver cpu_driver = {
*/
int
__init
register_cpu
(
struct
cpu
*
cpu
,
int
num
,
struct
node
*
root
)
{
int
retval
;
cpu
->
node_id
=
cpu_to_node
(
num
);
cpu
->
sysdev
.
name
=
"cpu"
;
cpu
->
sysdev
.
id
=
num
;
if
(
root
)
cpu
->
sysdev
.
root
=
&
root
->
sysroot
;
snprintf
(
cpu
->
sysdev
.
dev
.
name
,
DEVICE_NAME_SIZE
,
"CPU %u"
,
num
);
cpu
->
sysdev
.
dev
.
driver
=
&
cpu_driver
;
retval
=
sys_device_register
(
&
cpu
->
sysdev
);
if
(
retval
)
return
retval
;
memset
(
&
cpu
->
sysdev
.
class_dev
,
0x00
,
sizeof
(
struct
class_device
));
cpu
->
sysdev
.
class_dev
.
dev
=
&
cpu
->
sysdev
.
dev
;
cpu
->
sysdev
.
class_dev
.
class
=
&
cpu_class
;
snprintf
(
cpu
->
sysdev
.
class_dev
.
class_id
,
BUS_ID_SIZE
,
"cpu%d"
,
num
);
retval
=
class_device_register
(
&
cpu
->
sysdev
.
class_dev
);
if
(
retval
)
{
sys_device_unregister
(
&
cpu
->
sysdev
);
return
retval
;
}
return
0
;
cpu
->
sysdev
.
cls
=
&
cpu_sysdev_class
;
return
sys_device_register
(
&
cpu
->
sysdev
);
}
int
__init
cpu_dev_init
(
void
)
{
int
error
;
error
=
class_register
(
&
cpu_class
);
if
(
error
)
goto
out
;
error
=
driver_register
(
&
cpu_driver
);
if
(
error
)
class_unregister
(
&
cpu_class
);
out:
return
error
;
return
sysdev_class_register
(
&
cpu_sysdev_class
);
}
drivers/base/memblk.c
View file @
be9e929d
...
...
@@ -2,7 +2,6 @@
* drivers/base/memblk.c - basic Memory Block class support
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/memblk.h>
...
...
@@ -10,8 +9,8 @@
#include <linux/topology.h>
static
struct
class
memblk_class
=
{
.
name
=
"memblk"
,
static
struct
sysdev_
class
memblk_class
=
{
set_kset_name
(
"memblk"
)
,
};
...
...
@@ -29,27 +28,23 @@ static struct device_driver memblk_driver = {
*/
int
__init
register_memblk
(
struct
memblk
*
memblk
,
int
num
,
struct
node
*
root
)
{
int
error
;
memblk
->
node_id
=
memblk_to_node
(
num
);
memblk
->
sysdev
.
name
=
"memblk"
;
memblk
->
sysdev
.
cls
=
&
memblk_class
,
memblk
->
sysdev
.
id
=
num
;
if
(
root
)
memblk
->
sysdev
.
root
=
&
root
->
sysroot
;
snprintf
(
memblk
->
sysdev
.
dev
.
name
,
DEVICE_NAME_SIZE
,
"Memory Block %u"
,
num
);
memblk
->
sysdev
.
dev
.
driver
=
&
memblk_driver
;
return
sys_device_register
(
&
memblk
->
sysdev
);
error
=
sys_device_register
(
&
memblk
->
sysdev
);
if
(
!
error
)
error
=
sysfs_create_link
(
&
root
->
sysdev
.
kobj
,
&
memblk
->
sysdev
,
kobj
,
memblk
->
sysdev
.
kobj
.
name
);
return
error
;
}
int
__init
register_memblk_type
(
void
)
{
int
error
;
error
=
class_register
(
&
memblk_class
);
if
(
!
error
)
{
error
=
driver_register
(
&
memblk_driver
);
if
(
error
)
class_unregister
(
&
memblk_class
);
}
return
error
;
return
sysdev_class_register
(
&
memblk_class
);
}
postcore_initcall
(
register_memblk_type
);
drivers/base/node.c
View file @
be9e929d
...
...
@@ -9,15 +9,8 @@
#include <linux/node.h>
#include <linux/topology.h>
static
struct
class
node_class
=
{
.
name
=
"node"
,
};
static
struct
device_driver
node_driver
=
{
.
name
=
"node"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
node_class
=
{
set_kset_name
(
"node"
),
};
...
...
@@ -26,7 +19,7 @@ static ssize_t node_read_cpumap(struct device * dev, char * buf)
struct
node
*
node_dev
=
to_node
(
to_root
(
dev
));
return
sprintf
(
buf
,
"%lx
\n
"
,
node_dev
->
cpumap
);
}
static
DEVICE
_ATTR
(
cpumap
,
S_IRUGO
,
node_read_cpumap
,
NULL
);
static
SYSDEV
_ATTR
(
cpumap
,
S_IRUGO
,
node_read_cpumap
,
NULL
);
#define K(x) ((x) << (PAGE_SHIFT - 10))
static
ssize_t
node_read_meminfo
(
struct
device
*
dev
,
char
*
buf
)
...
...
@@ -52,7 +45,7 @@ static ssize_t node_read_meminfo(struct device * dev, char * buf)
nid
,
K
(
i
.
freeram
-
i
.
freehigh
));
}
#undef K
static
DEVICE
_ATTR
(
meminfo
,
S_IRUGO
,
node_read_meminfo
,
NULL
);
static
SYSDEV
_ATTR
(
meminfo
,
S_IRUGO
,
node_read_meminfo
,
NULL
);
/*
...
...
@@ -66,17 +59,13 @@ int __init register_node(struct node *node, int num, struct node *parent)
int
error
;
node
->
cpumap
=
node_to_cpumask
(
num
);
node
->
sysroot
.
id
=
num
;
if
(
parent
)
node
->
sysroot
.
dev
.
parent
=
&
parent
->
sysroot
.
sysdev
;
snprintf
(
node
->
sysroot
.
dev
.
name
,
DEVICE_NAME_SIZE
,
"Node %u"
,
num
);
snprintf
(
node
->
sysroot
.
dev
.
bus_id
,
BUS_ID_SIZE
,
"node%u"
,
num
);
node
->
sysroot
.
dev
.
driver
=
&
node_driver
;
node
->
sysroot
.
dev
.
bus
=
&
system_bus_type
;
error
=
sys_register_root
(
&
node
->
sysroot
);
node
->
sysdev
.
id
=
num
;
node
->
sysdev
.
cls
=
&
node_class
;
error
=
sys_device_register
(
&
node
->
sysdev
);
if
(
!
error
){
device_create_file
(
&
node
->
sysroot
.
dev
,
&
dev_
attr_cpumap
);
device_create_file
(
&
node
->
sysroot
.
dev
,
&
dev_
attr_meminfo
);
sys_device_create_file
(
&
node
->
sysroot
.
dev
,
&
attr_cpumap
);
sys_device_create_file
(
&
node
->
sysroot
.
dev
,
&
attr_meminfo
);
}
return
error
;
}
...
...
@@ -84,14 +73,6 @@ int __init register_node(struct node *node, int num, struct node *parent)
int
__init
register_node_type
(
void
)
{
int
error
;
error
=
class_register
(
&
node_class
);
if
(
!
error
)
{
error
=
driver_register
(
&
node_driver
);
if
(
error
)
class_unregister
(
&
node_class
);
}
return
error
;
return
sysdev_class_register
(
&
node_class
);
}
postcore_initcall
(
register_node_type
);
drivers/base/power.c
View file @
be9e929d
...
...
@@ -21,6 +21,21 @@
extern
struct
subsystem
devices_subsys
;
/**
* We handle system devices differently - we suspend and shut them
* down first and resume them first. That way, we do anything stupid like
* shutting down the interrupt controller before any devices..
*
* Note that there are not different stages for power management calls -
* they only get one called once when interrupts are disabled.
*/
extern
int
sysdev_shutdown
(
void
);
extern
int
sysdev_save
(
u32
state
);
extern
int
sysdev_suspend
(
u32
state
);
extern
int
sysdev_resume
(
void
);
extern
int
sysdev_restore
(
void
);
/**
* device_suspend - suspend/remove all devices on the device ree
* @state: state we're entering
...
...
@@ -50,6 +65,21 @@ int device_suspend(u32 state, u32 level)
}
}
up_write
(
&
devices_subsys
.
rwsem
);
/*
* Make sure system devices are suspended.
*/
switch
(
level
)
{
case
SUSPEND_SAVE_STATE
:
sysdev_save
(
state
);
break
;
case
SUSPEND_POWER_DOWN
:
sysdev_suspend
(
state
);
break
;
default:
break
;
}
return
error
;
}
...
...
@@ -65,6 +95,17 @@ void device_resume(u32 level)
{
struct
list_head
*
node
;
switch
(
level
)
{
case
RESUME_POWER_ON
:
sysdev_resume
();
break
;
case
RESUME_RESTORE_STATE
:
sysdev_restore
();
break
;
default:
break
;
}
down_write
(
&
devices_subsys
.
rwsem
);
list_for_each_prev
(
node
,
&
devices_subsys
.
kset
.
list
)
{
struct
device
*
dev
=
to_dev
(
node
);
...
...
@@ -98,6 +139,8 @@ void device_shutdown(void)
pr_debug
(
"Ignored.
\n
"
);
}
up_write
(
&
devices_subsys
.
rwsem
);
sysdev_shutdown
();
}
EXPORT_SYMBOL
(
device_suspend
);
...
...
drivers/base/sys.c
View file @
be9e929d
This diff is collapsed.
Click to expand it.
drivers/s390/block/xpram.c
View file @
be9e929d
...
...
@@ -34,7 +34,7 @@
#include <linux/blk.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h>
/* HDIO_GETGEO */
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <linux/bio.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/uaccess.h>
...
...
@@ -48,12 +48,14 @@
#define PRINT_WARN(x...) printk(KERN_WARNING XPRAM_NAME " warning:" x)
#define PRINT_ERR(x...) printk(KERN_ERR XPRAM_NAME " error:" x)
static
struct
sysdev_class
xpram_sysclass
=
{
set_kset_name
(
"xpram"
),
};
static
struct
sys_device
xpram_sys_device
=
{
.
name
=
"S/390 expanded memory RAM disk"
,
.
dev
=
{
.
name
=
"S/390 expanded memory RAM disk"
,
.
bus_id
=
"xpram"
,
},
.
id
=
0
,
.
cls
=
&
xpram_sysclass
,
};
typedef
struct
{
...
...
@@ -485,6 +487,7 @@ static void __exit xpram_exit(void)
unregister_blkdev
(
XPRAM_MAJOR
,
XPRAM_NAME
);
devfs_remove
(
"slram"
);
sys_device_unregister
(
&
xpram_sys_device
);
sysdev_class_unregister
(
&
xpram_sys_class
);
}
static
int
__init
xpram_init
(
void
)
...
...
@@ -502,9 +505,15 @@ static int __init xpram_init(void)
rc
=
xpram_setup_sizes
(
xpram_pages
);
if
(
rc
)
return
rc
;
rc
=
sys
_device_register
(
&
xpram_sys_device
);
rc
=
sys
dev_class_register
(
&
xpram_sysclass
);
if
(
rc
)
return
rc
;
rc
=
sys_device_register
(
&
xpram_sys_device
);
if
(
rc
)
{
sysdev_class_unregister
(
&
xpram_syclass
);
return
rc
;
}
rc
=
xpram_setup_blkdev
();
if
(
rc
)
sys_device_unregister
(
&
xpram_sys_device
);
...
...
fs/sysfs/file.c
View file @
be9e929d
...
...
@@ -84,7 +84,7 @@ static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer)
ssize_t
count
;
if
(
!
buffer
->
page
)
buffer
->
page
=
(
char
*
)
__get_free
_page
(
GFP_KERNEL
);
buffer
->
page
=
(
char
*
)
get_zeroed
_page
(
GFP_KERNEL
);
if
(
!
buffer
->
page
)
return
-
ENOMEM
;
...
...
@@ -174,7 +174,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char * buf, size_t count)
int
error
;
if
(
!
buffer
->
page
)
buffer
->
page
=
(
char
*
)
__get_free
_page
(
GFP_KERNEL
);
buffer
->
page
=
(
char
*
)
get_zeroed
_page
(
GFP_KERNEL
);
if
(
!
buffer
->
page
)
return
-
ENOMEM
;
...
...
include/linux/cpu.h
View file @
be9e929d
...
...
@@ -19,7 +19,7 @@
#ifndef _LINUX_CPU_H_
#define _LINUX_CPU_H_
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
#include <linux/node.h>
#include <asm/semaphore.h>
...
...
@@ -29,8 +29,6 @@ struct cpu {
};
extern
int
register_cpu
(
struct
cpu
*
,
int
,
struct
node
*
);
extern
struct
class
cpu_class
;
struct
notifier_block
;
#ifdef CONFIG_SMP
...
...
@@ -48,6 +46,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb)
{
}
#endif
/* CONFIG_SMP */
extern
struct
sysdev_class
cpu_sysdev_class
;
/* Stop CPUs going up and down. */
extern
struct
semaphore
cpucontrol
;
...
...
include/linux/cpufreq.h
View file @
be9e929d
...
...
@@ -205,10 +205,6 @@ struct freq_attr {
int
cpufreq_set_policy
(
struct
cpufreq_policy
*
policy
);
int
cpufreq_get_policy
(
struct
cpufreq_policy
*
policy
,
unsigned
int
cpu
);
#ifdef CONFIG_PM
int
cpufreq_restore
(
void
);
#endif
/* the proc_intf.c needs this */
int
cpufreq_parse_governor
(
char
*
str_governor
,
unsigned
int
*
policy
,
struct
cpufreq_governor
**
governor
);
...
...
include/linux/device.h
View file @
be9e929d
...
...
@@ -351,30 +351,6 @@ extern int (*platform_notify_remove)(struct device * dev);
extern
struct
device
*
get_device
(
struct
device
*
dev
);
extern
void
put_device
(
struct
device
*
dev
);
/* drivers/base/sys.c */
struct
sys_root
{
u32
id
;
struct
device
dev
;
struct
device
sysdev
;
};
extern
int
sys_register_root
(
struct
sys_root
*
);
extern
void
sys_unregister_root
(
struct
sys_root
*
);
struct
sys_device
{
char
*
name
;
u32
id
;
struct
sys_root
*
root
;
struct
device
dev
;
struct
class_device
class_dev
;
};
extern
int
sys_device_register
(
struct
sys_device
*
);
extern
void
sys_device_unregister
(
struct
sys_device
*
);
extern
struct
bus_type
system_bus_type
;
/* drivers/base/platform.c */
...
...
include/linux/kobject.h
View file @
be9e929d
...
...
@@ -118,6 +118,14 @@ static inline struct kobj_type * get_ktype(struct kobject * k)
extern
struct
kobject
*
kset_find_obj
(
struct
kset
*
,
const
char
*
);
/**
* Use this when initializing an embedded kset with no other
* fields to initialize.
*/
#define set_kset_name(str) .kset = { .kobj = { .name = str } }
struct
subsystem
{
struct
kset
kset
;
struct
rw_semaphore
rwsem
;
...
...
include/linux/list.h
View file @
be9e929d
...
...
@@ -296,6 +296,20 @@ static inline void list_splice_init(struct list_head *list,
pos = list_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
prefetch(pos->member.prev); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member), \
prefetch(pos->member.prev))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
...
...
include/linux/node.h
View file @
be9e929d
...
...
@@ -19,11 +19,11 @@
#ifndef _LINUX_NODE_H_
#define _LINUX_NODE_H_
#include <linux/
device
.h>
#include <linux/
sysdev
.h>
struct
node
{
unsigned
long
cpumap
;
/* Bitmap of CPUs on the Node */
struct
sys_
root
sysroot
;
struct
sys_
device
sysdev
;
};
extern
int
register_node
(
struct
node
*
,
int
,
struct
node
*
);
...
...
include/linux/sysdev.h
0 → 100644
View file @
be9e929d
/**
* System devices follow a slightly different driver model.
* They don't need to do dynammic driver binding, can't be probed,
* and don't reside on any type of peripheral bus.
* So, we represent and treat them a little differently.
*
* We still have a notion of a driver for a system device, because we still
* want to perform basic operations on these devices.
*
* We also support auxillary drivers binding to devices of a certain class.
*
* This allows configurable drivers to register themselves for devices of
* a certain type. And, it allows class definitions to reside in generic
* code while arch-specific code can register specific drivers.
*
* Auxillary drivers registered with a NULL cls are registered as drivers
* for all system devices, and get notification calls for each device.
*/
#ifndef _SYSDEV_H_
#define _SYSDEV_H_
#include <linux/kobject.h>
struct
sys_device
;
struct
sysdev_class
{
struct
list_head
drivers
;
/* Default operations for these types of devices */
int
(
*
shutdown
)(
struct
sys_device
*
);
int
(
*
save
)(
struct
sys_device
*
,
u32
state
);
int
(
*
suspend
)(
struct
sys_device
*
,
u32
state
);
int
(
*
resume
)(
struct
sys_device
*
);
int
(
*
restore
)(
struct
sys_device
*
);
struct
kset
kset
;
};
extern
int
sysdev_class_register
(
struct
sysdev_class
*
);
extern
void
sysdev_class_unregister
(
struct
sysdev_class
*
);
/**
* Auxillary system device drivers.
*/
struct
sysdev_driver
{
struct
list_head
entry
;
int
(
*
add
)(
struct
sys_device
*
);
int
(
*
remove
)(
struct
sys_device
*
);
int
(
*
shutdown
)(
struct
sys_device
*
);
int
(
*
save
)(
struct
sys_device
*
,
u32
state
);
int
(
*
suspend
)(
struct
sys_device
*
,
u32
state
);
int
(
*
resume
)(
struct
sys_device
*
);
int
(
*
restore
)(
struct
sys_device
*
);
};
extern
int
sysdev_driver_register
(
struct
sysdev_class
*
,
struct
sysdev_driver
*
);
extern
void
sysdev_driver_unregister
(
struct
sysdev_class
*
,
struct
sysdev_driver
*
);
/**
* sys_devices can be simplified a lot from regular devices, because they're
* simply not as versatile.
*/
struct
sys_device
{
u32
id
;
struct
sysdev_class
*
cls
;
struct
kobject
kobj
;
};
extern
int
sys_device_register
(
struct
sys_device
*
);
extern
void
sys_device_unregister
(
struct
sys_device
*
);
struct
sysdev_attribute
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
sys_device
*
,
char
*
);
ssize_t
(
*
store
)(
struct
sys_device
*
,
const
char
*
,
size_t
);
};
#define SYSDEV_ATTR(_name,_mode,_show,_store) \
struct sysdev_attribute attr_##_name = { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
};
extern
int
sysdev_create_file
(
struct
sys_device
*
,
struct
sysdev_attribute
*
);
extern
void
sysdev_remove_file
(
struct
sys_device
*
,
struct
sysdev_attribute
*
);
#endif
/* _SYSDEV_H_ */
kernel/cpufreq.c
View file @
be9e929d
...
...
@@ -49,8 +49,6 @@ static DECLARE_RWSEM (cpufreq_notifier_rwsem);
static
LIST_HEAD
(
cpufreq_governor_list
);
static
DECLARE_MUTEX
(
cpufreq_governor_sem
);
static
struct
class_interface
cpufreq_interface
;
static
int
cpufreq_cpu_get
(
unsigned
int
cpu
)
{
if
(
cpu
>=
NR_CPUS
)
...
...
@@ -113,24 +111,8 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
EXPORT_SYMBOL_GPL
(
cpufreq_parse_governor
);
/* forward declarations */
static
int
cpufreq_add_dev
(
struct
class_device
*
dev
);
static
void
cpufreq_remove_dev
(
struct
class_device
*
dev
);
/* drivers/base/cpu.c */
extern
struct
device_class
cpu_devclass
;
static
struct
class_interface
cpufreq_interface
=
{
.
class
=
&
cpu_class
,
.
add
=
&
cpufreq_add_dev
,
.
remove
=
&
cpufreq_remove_dev
,
};
static
inline
int
to_cpu_nr
(
struct
class_device
*
dev
)
{
struct
sys_device
*
cpu_sys_dev
=
container_of
(
dev
->
dev
,
struct
sys_device
,
dev
);
return
(
cpu_sys_dev
->
id
);
}
extern
struct
sysdev_class
cpu_sysdev_class
;
/**
...
...
@@ -331,9 +313,9 @@ static struct kobj_type ktype_cpufreq = {
*
* Adds the cpufreq interface for a CPU device.
*/
static
int
cpufreq_add_dev
(
struct
class_device
*
clas
s_dev
)
static
int
cpufreq_add_dev
(
struct
sys_device
*
sy
s_dev
)
{
unsigned
int
cpu
=
to_cpu_nr
(
class_dev
)
;
unsigned
int
cpu
=
sys_dev
->
id
;
int
ret
=
0
;
struct
cpufreq_policy
new_policy
;
struct
cpufreq_policy
*
policy
;
...
...
@@ -358,14 +340,12 @@ static int cpufreq_add_dev (struct class_device * class_dev)
memcpy
(
&
new_policy
,
policy
,
sizeof
(
struct
cpufreq_policy
));
class_set_devdata
(
class_dev
,
policy
);
up
(
&
cpufreq_driver_sem
);
init_MUTEX
(
&
policy
->
lock
);
/* prepare interface data */
policy
->
kobj
.
parent
=
&
clas
s_dev
->
kobj
;
policy
->
kobj
.
parent
=
&
sy
s_dev
->
kobj
;
policy
->
kobj
.
ktype
=
&
ktype_cpufreq
;
// policy->dev = dev->dev;
strlcpy
(
policy
->
kobj
.
name
,
"cpufreq"
,
KOBJ_NAME_LEN
);
ret
=
kobject_register
(
&
policy
->
kobj
);
...
...
@@ -396,12 +376,12 @@ static int cpufreq_add_dev (struct class_device * class_dev)
*
* Removes the cpufreq interface for a CPU device.
*/
static
void
cpufreq_remove_dev
(
struct
class_device
*
clas
s_dev
)
static
int
cpufreq_remove_dev
(
struct
sys_device
*
sy
s_dev
)
{
unsigned
int
cpu
=
to_cpu_nr
(
class_dev
)
;
unsigned
int
cpu
=
sys_dev
->
id
;
if
(
!
kobject_get
(
&
cpufreq_driver
->
policy
[
cpu
].
kobj
))
return
;
return
-
EFAULT
;
down
(
&
cpufreq_driver_sem
);
if
((
cpufreq_driver
->
target
)
&&
...
...
@@ -421,9 +401,17 @@ static void cpufreq_remove_dev (struct class_device * class_dev)
up
(
&
cpufreq_driver_sem
);
kobject_put
(
&
cpufreq_driver
->
policy
[
cpu
].
kobj
);
return
;
return
0
;
}
static
int
cpufreq_restore
(
struct
sys_device
*
);
static
struct
sysdev_driver
cpufreq_sysdev_driver
=
{
.
add
=
cpufreq_add_dev
,
.
remove
=
cpufreq_remove_dev
,
.
restore
=
cpufreq_restore
,
};
/*********************************************************************
* NOTIFIER LISTS INTERFACE *
...
...
@@ -843,7 +831,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
memset
(
cpufreq_driver
->
policy
,
0
,
NR_CPUS
*
sizeof
(
struct
cpufreq_policy
));
return
class_interface_register
(
&
cpufreq_interface
);
return
sysdev_driver_register
(
&
cpu_sysdev_class
,
&
cpufreq_sysdev_driver
);
}
EXPORT_SYMBOL_GPL
(
cpufreq_register_driver
);
...
...
@@ -861,7 +849,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
if
(
!
cpufreq_driver
||
(
driver
!=
cpufreq_driver
))
return
-
EINVAL
;
class_interface_unregister
(
&
cpufreq_interface
);
sysdev_driver_unregister
(
&
cpu_sysdev_class
,
&
cpufreq_sysdev_driver
);
down
(
&
cpufreq_driver_sem
);
kfree
(
cpufreq_driver
->
policy
);
...
...
@@ -874,41 +862,34 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
#ifdef CONFIG_PM
/**
* cpufreq_restore - restore the CPU clock frequency after resume
*
* Restore the CPU clock frequency so that our idea of the current
* frequency reflects the actual hardware.
*/
int
cpufreq_restore
(
void
)
static
int
cpufreq_restore
(
struct
sys_device
*
sysdev
)
{
struct
cpufreq_policy
policy
;
unsigned
int
i
;
int
cpu
=
sysdev
->
id
;
unsigned
int
ret
=
0
;
struct
cpufreq_policy
policy
;
if
(
in_interrupt
())
panic
(
"cpufreq_restore() called from interrupt context!"
);
if
(
!
try_module_get
(
cpufreq_driver
->
owner
))
goto
error_out
;
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
!
cpu_online
(
i
)
||
!
cpufreq_cpu_get
(
i
))
continue
;
if
(
cpu_online
(
cpu
)
&&
cpufreq_cpu_get
(
cpu
))
{
down
(
&
cpufreq_driver_sem
);
memcpy
(
&
policy
,
&
cpufreq_driver
->
policy
[
i
],
sizeof
(
struct
cpufreq_policy
));
memcpy
(
&
policy
,
&
cpufreq_driver
->
policy
[
cpu
],
sizeof
(
struct
cpufreq_policy
));
up
(
&
cpufreq_driver_sem
);
ret
+=
cpufreq_set_policy
(
&
policy
);
cpufreq_cpu_put
(
i
);
ret
=
cpufreq_set_policy
(
&
policy
);
cpufreq_cpu_put
(
cpu
);
}
module_put
(
cpufreq_driver
->
owner
);
error_out:
return
ret
;
}
EXPORT_SYMBOL_GPL
(
cpufreq_restore
);
#else
#define cpufreq_restore() do {} while (0)
static
int
cpufreq_restore
(
struct
sys_device
*
sysdev
)
{
return
0
;
}
#endif
/* CONFIG_PM */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment