Allow subsystems to avoid using sysdevs for defining "core" PM callbacks
Subsystems (12)
cover Allow subsystems to avoid using sysdevs for defining "core" PM callbacks
Hi,
There are multiple problems with sysdevs, or struct sys_device objects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)
Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
This is a proof of concept, so the patches have not been tested. Please be extrememly careful, because they touch sensitive code, so to speak. In the majority of cases the changes are rather straightforward, but there are some more interesting cases as well (io_apic.c most importantly).
Please have a look and tell me what you think.
Thanks,
Rafael
RFC PATCH 1/2 Introduce struct syscore_ops and related functionality
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects.
--- drivers/base/Makefile | 2 drivers/base/syscore.c | 102 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 39 ++++++++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 159 insertions(+), 1 deletion(-)
include/linux/syscore_ops.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +extern void syscore_shutdown (void ); + +#endif
drivers/base/syscore.c new file +102 -0
102 lines not on this page · raw message
kernel/power/suspend.c +4 -0
@@ -22,6 +22,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h> #include "power.h"
@@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_tBUG_ON (!irqs_disabled ()); error =sysdev_suspend (PMSG_SUSPEND ); +if (!error) + error =syscore_suspend ();if (!error) {if (!(suspend_test (TEST_CORE ) ||pm_wakeup_pending ())) { error = suspend_ops->enter (state); events_check_enabled = false; } +syscore_resume ();sysdev_resume (); }
kernel/power/hibernate.c +9 -0
@@ -23,6 +23,7 @@#include <linux/cpu.h> #include <linux/freezer.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <scsi/scsi_scan.h> #include <asm/suspend.h>
@@ -272,6 +273,8 @@ static int create_image(int platform_modlocal_irq_disable (); error =sysdev_suspend (PMSG_FREEZE ); +if (!error) + error =syscore_suspend ();if (error) {printk (KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n" );
@@ -295,6 +298,7 @@ static int create_image(int platform_mod } Power_up: +syscore_resume ();sysdev_resume ();/* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup.
@@ -403,6 +407,8 @@ static int resume_target_kernel(bool plalocal_irq_disable (); error =sysdev_suspend (PMSG_QUIESCE ); +if (!error) + error =syscore_suspend ();if (error) goto Enable_irqs;
@@ -429,6 +435,7 @@ static int resume_target_kernel(bool plarestore_processor_state ();touch_softlockup_watchdog (); +syscore_resume ();sysdev_resume (); Enable_irqs:
@@ -516,6 +523,7 @@ int hibernation_platform_enter(void)local_irq_disable ();sysdev_suspend (PMSG_HIBERNATE ); +syscore_suspend ();if (pm_wakeup_pending ()) { error = -EAGAIN ; goto Power_up;
@@ -526,6 +534,7 @@ int hibernation_platform_enter(void)while (1 ); Power_up: +syscore_resume ();sysdev_resume ();local_irq_enable ();enable_nonboot_cpus ();
kernel/sys.c +4 -0
@@ -37,6 +37,7 @@#include <linux/ptrace.h> #include <linux/fs_struct.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <linux/compat.h> #include <linux/syscalls.h>
@@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state =SYSTEM_RESTART ;device_shutdown ();sysdev_shutdown (); +syscore_shutdown (); }/**
@@ -336,6 +338,7 @@ void kernel_halt(void) {kernel_shutdown_prepare (SYSTEM_HALT );sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "System halted.\n" );kmsg_dump (KMSG_DUMP_HALT );machine_halt ();
@@ -355,6 +358,7 @@ void kernel_power_off(void)pm_power_off_prepare ();disable_nonboot_cpus ();sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "Power down.\n" );kmsg_dump (KMSG_DUMP_POWEROFF );machine_power_off ();
drivers/base/Makefile +1 -1
@@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o
RFC PATCH 1/2 Introduce struct syscore_ops and related functionality
In reply to Rafael J. WysockiSome subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects.
--- drivers/base/Makefile | 2 drivers/base/syscore.c | 102 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 39 ++++++++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 159 insertions(+), 1 deletion(-)
include/linux/syscore_ops.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +extern void syscore_shutdown (void ); + +#endif
drivers/base/syscore.c new file +102 -0
102 lines not on this page · raw message
kernel/power/suspend.c +4 -0
@@ -22,6 +22,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h> #include "power.h"
@@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_tBUG_ON (!irqs_disabled ()); error =sysdev_suspend (PMSG_SUSPEND ); +if (!error) + error =syscore_suspend ();if (!error) {if (!(suspend_test (TEST_CORE ) ||pm_wakeup_pending ())) { error = suspend_ops->enter (state); events_check_enabled = false; } +syscore_resume ();sysdev_resume (); }
kernel/power/hibernate.c +9 -0
@@ -23,6 +23,7 @@#include <linux/cpu.h> #include <linux/freezer.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <scsi/scsi_scan.h> #include <asm/suspend.h>
@@ -272,6 +273,8 @@ static int create_image(int platform_modlocal_irq_disable (); error =sysdev_suspend (PMSG_FREEZE ); +if (!error) + error =syscore_suspend ();if (error) {printk (KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n" );
@@ -295,6 +298,7 @@ static int create_image(int platform_mod } Power_up: +syscore_resume ();sysdev_resume ();/* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup.
@@ -403,6 +407,8 @@ static int resume_target_kernel(bool plalocal_irq_disable (); error =sysdev_suspend (PMSG_QUIESCE ); +if (!error) + error =syscore_suspend ();if (error) goto Enable_irqs;
@@ -429,6 +435,7 @@ static int resume_target_kernel(bool plarestore_processor_state ();touch_softlockup_watchdog (); +syscore_resume ();sysdev_resume (); Enable_irqs:
@@ -516,6 +523,7 @@ int hibernation_platform_enter(void)local_irq_disable ();sysdev_suspend (PMSG_HIBERNATE ); +syscore_suspend ();if (pm_wakeup_pending ()) { error = -EAGAIN ; goto Power_up;
@@ -526,6 +534,7 @@ int hibernation_platform_enter(void)while (1 ); Power_up: +syscore_resume ();sysdev_resume ();local_irq_enable ();enable_nonboot_cpus ();
kernel/sys.c +4 -0
@@ -37,6 +37,7 @@#include <linux/ptrace.h> #include <linux/fs_struct.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <linux/compat.h> #include <linux/syscalls.h>
@@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state =SYSTEM_RESTART ;device_shutdown ();sysdev_shutdown (); +syscore_shutdown (); }/**
@@ -336,6 +338,7 @@ void kernel_halt(void) {kernel_shutdown_prepare (SYSTEM_HALT );sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "System halted.\n" );kmsg_dump (KMSG_DUMP_HALT );machine_halt ();
@@ -355,6 +358,7 @@ void kernel_power_off(void)pm_power_off_prepare ();disable_nonboot_cpus ();sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "Power down.\n" );kmsg_dump (KMSG_DUMP_POWEROFF );machine_power_off ();
drivers/base/Makefile +1 -1
@@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o
Re: [RFC][PATCH 1/2] Introduce struct syscore_ops and related functionality
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.
...
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0
It's true that the existing sys.c file lies in drivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file in drivers/base/power?
Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )
drivers/base/syscore.c line 67
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;
If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in sysdev_suspend does.
drivers/base/syscore.c line 72
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}
Alan Stern
Re: [linux-pm] [RFC][PATCH 1/2] Introduce struct syscore_ops and related functionality
In reply to Rafael J. WysockiQuoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.
...
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0
It's true that the existing sys.c file lies in drivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file in drivers/base/power?
Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )
drivers/base/syscore.c line 67
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;
If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in sysdev_suspend does.
drivers/base/syscore.c line 72
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}
Alan Stern
Re: [linux-pm] [RFC][PATCH 1/2] Introduce struct syscore_ops and related functionality
Quoted 16 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
Quoted 10 lines
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?
I didn't, because shutdown() doesn't really belong in there (well, depending).
Quoted 11 lines
Quoted 11 lines
drivers/base/syscore.c new file +11
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void ) +{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) {
Quoted 8 lines
drivers/base/syscore.c line 67
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.
Right, thanks a lot!
Quoted 5 lines
drivers/base/syscore.c line 72
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}
Rafael
Re: [RFC][PATCH 1/2] Introduce struct syscore_ops and related functionality
In reply to Alan SternQuoted 16 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
Quoted 10 lines
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?
I didn't, because shutdown() doesn't really belong in there (well, depending).
Quoted 11 lines
Quoted 11 lines
drivers/base/syscore.c new file +11
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void ) +{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) {
Quoted 8 lines
drivers/base/syscore.c line 67
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.
Right, thanks a lot!
Quoted 5 lines
drivers/base/syscore.c line 72
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}
Rafael
RFC PATCH 1/2 Introduce struct syscore_ops and related functionality
In reply to Alan SternQuoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.
Quoted 5 lines
drivers/base/syscore.c
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}
Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in syscore_shutdown() and added some debug statements.
Thanks,
Rafael
---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects.
--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)
include/linux/syscore_ops.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif +extern void syscore_shutdown (void ); + +#endif
drivers/base/syscore.c new file +107 -0
107 lines not on this page · raw message
kernel/power/suspend.c +4 -0
@@ -22,6 +22,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h> #include "power.h"
@@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_tBUG_ON (!irqs_disabled ()); error =sysdev_suspend (PMSG_SUSPEND ); +if (!error) + error =syscore_suspend ();if (!error) {if (!(suspend_test (TEST_CORE ) ||pm_wakeup_pending ())) { error = suspend_ops->enter (state); events_check_enabled = false; } +syscore_resume ();sysdev_resume (); }
kernel/power/hibernate.c +9 -0
@@ -23,6 +23,7 @@#include <linux/cpu.h> #include <linux/freezer.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <scsi/scsi_scan.h> #include <asm/suspend.h>
@@ -272,6 +273,8 @@ static int create_image(int platform_modlocal_irq_disable (); error =sysdev_suspend (PMSG_FREEZE ); +if (!error) + error =syscore_suspend ();if (error) {printk (KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n" );
@@ -295,6 +298,7 @@ static int create_image(int platform_mod } Power_up: +syscore_resume ();sysdev_resume ();/* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup.
@@ -403,6 +407,8 @@ static int resume_target_kernel(bool plalocal_irq_disable (); error =sysdev_suspend (PMSG_QUIESCE ); +if (!error) + error =syscore_suspend ();if (error) goto Enable_irqs;
@@ -429,6 +435,7 @@ static int resume_target_kernel(bool plarestore_processor_state ();touch_softlockup_watchdog (); +syscore_resume ();sysdev_resume (); Enable_irqs:
@@ -516,6 +523,7 @@ int hibernation_platform_enter(void)local_irq_disable ();sysdev_suspend (PMSG_HIBERNATE ); +syscore_suspend ();if (pm_wakeup_pending ()) { error = -EAGAIN ; goto Power_up;
@@ -526,6 +534,7 @@ int hibernation_platform_enter(void)while (1 ); Power_up: +syscore_resume ();sysdev_resume ();local_irq_enable ();enable_nonboot_cpus ();
kernel/sys.c +4 -0
@@ -37,6 +37,7 @@#include <linux/ptrace.h> #include <linux/fs_struct.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <linux/compat.h> #include <linux/syscalls.h>
@@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state =SYSTEM_RESTART ;device_shutdown ();sysdev_shutdown (); +syscore_shutdown (); }/**
@@ -336,6 +338,7 @@ void kernel_halt(void) {kernel_shutdown_prepare (SYSTEM_HALT );sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "System halted.\n" );kmsg_dump (KMSG_DUMP_HALT );machine_halt ();
@@ -355,6 +358,7 @@ void kernel_power_off(void)pm_power_off_prepare ();disable_nonboot_cpus ();sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "Power down.\n" );kmsg_dump (KMSG_DUMP_POWEROFF );machine_power_off ();
drivers/base/Makefile +1 -1
@@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o
RFC PATCH 1/2 Introduce struct syscore_ops and related functionality
In reply to Alan SternQuoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.
Quoted 5 lines
drivers/base/syscore.c
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}
Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in syscore_shutdown() and added some debug statements.
Thanks,
Rafael
---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects.
--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)
include/linux/syscore_ops.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif +extern void syscore_shutdown (void ); + +#endif
drivers/base/syscore.c new file +107 -0
107 lines not on this page · raw message
kernel/power/suspend.c +4 -0
@@ -22,6 +22,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h> #include "power.h"
@@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_tBUG_ON (!irqs_disabled ()); error =sysdev_suspend (PMSG_SUSPEND ); +if (!error) + error =syscore_suspend ();if (!error) {if (!(suspend_test (TEST_CORE ) ||pm_wakeup_pending ())) { error = suspend_ops->enter (state); events_check_enabled = false; } +syscore_resume ();sysdev_resume (); }
kernel/power/hibernate.c +9 -0
@@ -23,6 +23,7 @@#include <linux/cpu.h> #include <linux/freezer.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <scsi/scsi_scan.h> #include <asm/suspend.h>
@@ -272,6 +273,8 @@ static int create_image(int platform_modlocal_irq_disable (); error =sysdev_suspend (PMSG_FREEZE ); +if (!error) + error =syscore_suspend ();if (error) {printk (KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n" );
@@ -295,6 +298,7 @@ static int create_image(int platform_mod } Power_up: +syscore_resume ();sysdev_resume ();/* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup.
@@ -403,6 +407,8 @@ static int resume_target_kernel(bool plalocal_irq_disable (); error =sysdev_suspend (PMSG_QUIESCE ); +if (!error) + error =syscore_suspend ();if (error) goto Enable_irqs;
@@ -429,6 +435,7 @@ static int resume_target_kernel(bool plarestore_processor_state ();touch_softlockup_watchdog (); +syscore_resume ();sysdev_resume (); Enable_irqs:
@@ -516,6 +523,7 @@ int hibernation_platform_enter(void)local_irq_disable ();sysdev_suspend (PMSG_HIBERNATE ); +syscore_suspend ();if (pm_wakeup_pending ()) { error = -EAGAIN ; goto Power_up;
@@ -526,6 +534,7 @@ int hibernation_platform_enter(void)while (1 ); Power_up: +syscore_resume ();sysdev_resume ();local_irq_enable ();enable_nonboot_cpus ();
kernel/sys.c +4 -0
@@ -37,6 +37,7 @@#include <linux/ptrace.h> #include <linux/fs_struct.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <linux/compat.h> #include <linux/syscalls.h>
@@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state =SYSTEM_RESTART ;device_shutdown ();sysdev_shutdown (); +syscore_shutdown (); }/**
@@ -336,6 +338,7 @@ void kernel_halt(void) {kernel_shutdown_prepare (SYSTEM_HALT );sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "System halted.\n" );kmsg_dump (KMSG_DUMP_HALT );machine_halt ();
@@ -355,6 +358,7 @@ void kernel_power_off(void)pm_power_off_prepare ();disable_nonboot_cpus ();sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "Power down.\n" );kmsg_dump (KMSG_DUMP_POWEROFF );machine_power_off ();
drivers/base/Makefile +1 -1
@@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o
Re: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
Quoted 104 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +16
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { + struct list_head node; + int (*suspend)(void);
include/linux/syscore_ops.h line 26
Quoted 10 lines
include/linux/syscore_ops.h new file +10
-0+void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif
Minor nit, provide inline functions for these when CONFIG_PM_SLEEP is not defined so the code still builds?
Other than that, this looks great to me, thanks for doing this. Do you want me to take it through my tree, or yours?
thanks,
greg k-h
Re: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
In reply to Rafael J. WysockiQuoted 104 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +16
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { + struct list_head node; + int (*suspend)(void);
include/linux/syscore_ops.h line 26
Quoted 10 lines
include/linux/syscore_ops.h new file +10
-0+void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif
Minor nit, provide inline functions for these when CONFIG_PM_SLEEP is not defined so the code still builds?
Other than that, this looks great to me, thanks for doing this. Do you want me to take it through my tree, or yours?
thanks,
greg k-h
Re: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
Quoted 110 lines · Greg KH
Quoted 109 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +21
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops);
Quoted 8 lines
include/linux/syscore_ops.h line 26
Quoted 5 lines
include/linux/syscore_ops.h new file +5
-0+extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif Minor nit, provide inline functions for these when
CONFIG_PM_SLEEPis not defined so the code still builds?
The code using them depends on CONFIG_PM_SLEEP and they are nobody else's business. :-)
I could avoid using the #ifdef here, but I thought I'd make it clear that these things were only available when CONFIG_PM_SLEEP was set.
Quoted 1 line
Other than that, this looks great to me, thanks for doing this.
No problem. :-)
Quoted 1 line
Do you want me to take it through my tree, or yours?
I can handle it if you give me an ack.
Do you think I should push [1/2] alone for 2.6.39 or wait for the patches converting subsystems to use this stuff to be ready? I think it'll take some time to prepare them, especialy for things in the ARM tree that use sysdevs in some interesting ways ...
Thanks,
Rafael
Re: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
In reply to Greg KHQuoted 110 lines · Greg KH
Quoted 109 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +21
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops);
Quoted 8 lines
include/linux/syscore_ops.h line 26
Quoted 5 lines
include/linux/syscore_ops.h new file +5
-0+extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif Minor nit, provide inline functions for these when
CONFIG_PM_SLEEPis not defined so the code still builds?
The code using them depends on CONFIG_PM_SLEEP and they are nobody else's business. :-)
I could avoid using the #ifdef here, but I thought I'd make it clear that these things were only available when CONFIG_PM_SLEEP was set.
Quoted 1 line
Other than that, this looks great to me, thanks for doing this.
No problem. :-)
Quoted 1 line
Do you want me to take it through my tree, or yours?
I can handle it if you give me an ack.
Do you think I should push [1/2] alone for 2.6.39 or wait for the patches converting subsystems to use this stuff to be ready? I think it'll take some time to prepare them, especialy for things in the ARM tree that use sysdevs in some interesting ways ...
Thanks,
Rafael
Greg KH
Acked-byRe: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
Quoted 120 lines · Rafael J. Wysocki
Quoted 110 lines · Greg KH
Quoted 109 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +21
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops);Quoted 8 lines
include/linux/syscore_ops.h line 26
Quoted 5 lines
include/linux/syscore_ops.h new file +5
-0+extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif Minor nit, provide inline functions for these when
CONFIG_PM_SLEEPis not defined so the code still builds?
Quoted 2 lines
The code using them depends on
CONFIG_PM_SLEEPand they are nobody else's business. :-)
Ah, ok.
Quoted 2 lines
I could avoid using the #ifdef here, but I thought I'd make it clear that these things were only available when
CONFIG_PM_SLEEPwas set.
That's fine.
Quoted 7 lines
Quoted 1 line
Other than that, this looks great to me, thanks for doing this.
No problem. :-)
Quoted 1 line
Do you want me to take it through my tree, or yours?
I can handle it if you give me an ack.
Quoted 4 lines
Do you think I should push [1/2] alone for 2.6.39 or wait for the patches converting subsystems to use this stuff to be ready? I think it'll take some time to prepare them, especialy for things in the ARM tree that use sysdevs in some interesting ways ...
Send it for .39, and then start converting everyone over to using it. It's easier once the code is in place to handle the different trees, that way you don't have to worry about ordering issues.
thanks,
greg k-h
Greg KH
Acked-byRe: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
In reply to Rafael J. WysockiQuoted 120 lines · Rafael J. Wysocki
Quoted 110 lines · Greg KH
Quoted 109 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +21
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops);Quoted 8 lines
include/linux/syscore_ops.h line 26
Quoted 5 lines
include/linux/syscore_ops.h new file +5
-0+extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif Minor nit, provide inline functions for these when
CONFIG_PM_SLEEPis not defined so the code still builds?
Quoted 2 lines
The code using them depends on
CONFIG_PM_SLEEPand they are nobody else's business. :-)
Ah, ok.
Quoted 2 lines
I could avoid using the #ifdef here, but I thought I'd make it clear that these things were only available when
CONFIG_PM_SLEEPwas set.
That's fine.
Quoted 7 lines
Quoted 1 line
Other than that, this looks great to me, thanks for doing this.
No problem. :-)
Quoted 1 line
Do you want me to take it through my tree, or yours?
I can handle it if you give me an ack.
Quoted 4 lines
Do you think I should push [1/2] alone for 2.6.39 or wait for the patches converting subsystems to use this stuff to be ready? I think it'll take some time to prepare them, especialy for things in the ARM tree that use sysdevs in some interesting ways ...
Send it for .39, and then start converting everyone over to using it. It's easier once the code is in place to handle the different trees, that way you don't have to worry about ordering issues.
thanks,
greg k-h
Re: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
Quoted 141 lines · Greg KH
Quoted 120 lines · Rafael J. Wysocki
Quoted 110 lines · Greg KH
Quoted 109 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +21
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops);Quoted 8 lines
include/linux/syscore_ops.h line 26
Quoted 5 lines
include/linux/syscore_ops.h new file +5
-0+extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif Minor nit, provide inline functions for these when
CONFIG_PM_SLEEPis not defined so the code still builds?Quoted 2 lines
The code using them depends on
CONFIG_PM_SLEEPand they are nobody else's business. :-)Ah, ok.
Quoted 2 lines
I could avoid using the #ifdef here, but I thought I'd make it clear that these things were only available when
CONFIG_PM_SLEEPwas set.That's fine.
Quoted 7 lines
Quoted 1 line
Other than that, this looks great to me, thanks for doing this.
No problem. :-)
Quoted 1 line
Do you want me to take it through my tree, or yours?
I can handle it if you give me an ack.
Quoted 8 lines
Quoted 4 lines
Do you think I should push [1/2] alone for 2.6.39 or wait for the patches converting subsystems to use this stuff to be ready? I think it'll take some time to prepare them, especialy for things in the ARM tree that use sysdevs in some interesting ways ...
Send it for .39, and then start converting everyone over to using it. It's easier once the code is in place to handle the different trees, that way you don't have to worry about ordering issues.
OK, I will.
Thanks,
Rafael
Re: [RFC][Update][PATCH 1/2] Introduce struct syscore_ops and related functionality
In reply to Greg KHQuoted 141 lines · Greg KH
Quoted 120 lines · Rafael J. Wysocki
Quoted 110 lines · Greg KH
Quoted 109 lines · Rafael J. Wysocki
Quoted 47 lines · Alan Stern
Quoted 11 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects....
drivers/base/syscore.c
Quoted 4 lines
Index:
linux-2.6/drivers/base/syscore.c
===================================================================drivers/base/syscore.c new file +0
-0It's true that the existing
sys.cfile lies indrivers/base; this is presumably because it handles a bunch of class-related registration stuff. Now you're getting rid of all that, leaving just the power-related operations, so doesn't it make more sense to put this file indrivers/base/power?Quoted 6 lines
drivers/base/syscore.c new file +6
-0+/** +* syscore_suspend - Execute all the registered system core suspend callbacks. +* +* This function is executed with one CPU on-line and disabled interrupts. +*/ +int syscore_suspend (void )drivers/base/syscore.c line 69
Quoted 10 lines
drivers/base/syscore.c new file +10
-0+{ +struct syscore_ops *ops; + +list_for_each_entry_reverse (ops, &syscore_ops_list, node) +if (ops->suspend) { +int ret = ops->suspend (); +if (ret) { +pr_err ("PM: System core suspend callback " +"%pF failed.\n" , ops->suspend); +return ret;If an error occurs, you need to go back and resume all the things that were suspended. At least, that's what the code in
sysdev_suspenddoes.Quoted 5 lines
drivers/base/syscore.c line 70
Quoted 5 lines
drivers/base/syscore.c new file +5
-0+ } + } + +return 0 ; +}Below is a new version of the patch. I've taken your comment on the failing suspend into account, fix the list traversal direction in
syscore_shutdown()and added some debug statements.Thanks,
Rafael---
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut
syscore_opsobjects.--- drivers/base/Makefile | 2 drivers/base/syscore.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 154 insertions(+), 1 deletion(-)Index:
linux-2.6/include/linux/syscore_ops.h
===================================================================include/linux/syscore_ops.h new file +21
-0@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops);Quoted 8 lines
include/linux/syscore_ops.h line 26
Quoted 5 lines
include/linux/syscore_ops.h new file +5
-0+extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif Minor nit, provide inline functions for these when
CONFIG_PM_SLEEPis not defined so the code still builds?Quoted 2 lines
The code using them depends on
CONFIG_PM_SLEEPand they are nobody else's business. :-)Ah, ok.
Quoted 2 lines
I could avoid using the #ifdef here, but I thought I'd make it clear that these things were only available when
CONFIG_PM_SLEEPwas set.That's fine.
Quoted 7 lines
Quoted 1 line
Other than that, this looks great to me, thanks for doing this.
No problem. :-)
Quoted 1 line
Do you want me to take it through my tree, or yours?
I can handle it if you give me an ack.
Quoted 8 lines
Quoted 4 lines
Do you think I should push [1/2] alone for 2.6.39 or wait for the patches converting subsystems to use this stuff to be ready? I think it'll take some time to prepare them, especialy for things in the ARM tree that use sysdevs in some interesting ways ...
Send it for .39, and then start converting everyone over to using it. It's easier once the code is in place to handle the different trees, that way you don't have to worry about ordering issues.
OK, I will.
Thanks,
Rafael
RFC PATCH 2/2 Convert several sysdev users to using struct syscore_ops
In reply to Rafael J. WysockiSome subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs specifically for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct syscore_ops objects for this purpose instead.
--- arch/x86/kernel/amd_iommu_init.c | 26 ++-------- arch/x86/kernel/apic/apic.c | 29 +++-------- arch/x86/kernel/apic/io_apic.c | 97 ++++++++++++++++++--------------------- arch/x86/kernel/i8237.c | 30 ++---------- arch/x86/kernel/i8259.c | 33 ++++--------- arch/x86/kernel/pci-gart_64.c | 32 ++---------- arch/x86/oprofile/nmi_int.c | 44 ++++------------- drivers/acpi/pci_link.c | 30 +++--------- drivers/pci/intel-iommu.c | 38 +++------------ kernel/time/timekeeping.c | 27 +++------- 10 files changed, 121 insertions(+), 265 deletions(-)
arch/x86/kernel/amd_iommu_init.c +6 -20
@@ -21,7 +21,7 @@#include <linux/acpi.h> #include <linux/list.h> #include <linux/slab.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/msi.h> #include <asm/pci-direct.h>
@@ -1260,7 +1260,7 @@ static void disable_iommus(void)* disable suspend until real resume implemented */ -static int amd_iommu_resume (struct sys_device *dev) +static void amd_iommu_resume (void ) {struct amd_iommu *iommu;
@@ -1276,11 +1276,9 @@ static int amd_iommu_resume(struct sys_d*/ amd_iommu_flush_all_devices ();amd_iommu_flush_all_domains (); - -return 0 ; } -static int amd_iommu_suspend (struct sys_device *dev,pm_message_t state) +static int amd_iommu_suspend (void ) {/* disable IOMMUs to go out of the way for BIOS */ disable_iommus ();
@@ -1288,17 +1286,11 @@ static int amd_iommu_suspend(struct sys_return 0 ; } -static struct sysdev_class amd_iommu_sysdev_class = { - .name ="amd_iommu" , +static struct syscore_ops amd_iommu_syscore_ops = { .suspend = amd_iommu_suspend, .resume = amd_iommu_resume, }; -static struct sys_device device_amd_iommu = { - .id =0 , - .cls = &amd_iommu_sysdev_class, -}; -/* * This is the core init function for AMD IOMMU hardware in the system. * This function is called from the generic x86 DMA layer initialization
@@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void) goto free; } - ret =sysdev_class_register (&amd_iommu_sysdev_class); -if (ret) - goto free; - - ret =sysdev_register (&device_amd_iommu); -if (ret) - goto free; - ret =amd_iommu_init_devices ();if (ret) goto free;
@@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void)amd_iommu_init_notifier (); +register_syscore_ops (&amd_iommu_syscore_ops); +if (iommu_pass_through) goto out;
arch/x86/kernel/apic/apic.c +8 -21
@@ -24,7 +24,7 @@#include <linux/ftrace.h> #include <linux/ioport.h> #include <linux/module.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/timex.h> #include <linux/dmar.h>
@@ -2036,7 +2036,7 @@ static struct {unsigned int apic_thmr; } apic_pm_state; -static int lapic_suspend (struct sys_device *dev,pm_message_t state) +static int lapic_suspend (void ) {unsigned long flags;int maxlvt;
@@ -2074,7 +2074,7 @@ static int lapic_suspend(struct sys_devireturn 0 ; } -static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;
@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);if (intr_remapping_enabled) {
@@ -2152,8 +2152,6 @@ static int lapic_resume(struct sys_devic } restore:local_irq_restore (flags); - -return ret; }/*
@@ -2161,17 +2159,11 @@ restore:* are needed on every CPU up until machine_halt/restart/poweroff. */ -static struct sysdev_class lapic_sysclass = { - .name ="lapic" , +static struct syscore_ops lapic_syscore_ops = { .resume = lapic_resume, .suspend = lapic_suspend, }; -static struct sys_device device_lapic = { - .id =0 , - .cls = &lapic_sysclass, -}; -static void __cpuinit apic_pm_activate (void ) { apic_pm_state.active =1 ;
@@ -2179,16 +2171,11 @@ static void __cpuinit apic_pm_activate(vstatic int __init init_lapic_sysfs (void ) { -int error; - -if (!cpu_has_apic) -return 0 ;/* XXX: remove suspend/resume procs if !apic_pm_state.active? */ +if (cpu_has_apic) +register_syscore_ops (&lapic_syscore_ops); - error =sysdev_class_register (&lapic_sysclass); -if (!error) - error =sysdev_register (&device_lapic); -return error; +return 0 ; }/* local apic needs to resume before other devices access its registers. */
arch/x86/kernel/apic/io_apic.c +46 -51
142 lines not on this page · raw message
arch/x86/kernel/i8237.c +7 -23
@@ -10,7 +10,7 @@*/ #include <linux/init.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <asm/dma.h>
@@ -21,7 +21,7 @@* in asm/dma.h. */ -static int i8237A_resume (struct sys_device *dev) +static void i8237A_resume (void ) {unsigned long flags;int i;
@@ -41,31 +41,15 @@ static int i8237A_resume(struct sys_devienable_dma (4 );release_dma_lock (flags); - -return 0 ; } -static int i8237A_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class i8237_sysdev_class = { - .name ="i8237" , - .suspend = i8237A_suspend, +static struct syscore_ops i8237_syscore_ops = { .resume = i8237A_resume, }; -static struct sys_device device_i8237A = { - .id =0 , - .cls = &i8237_sysdev_class, -}; - -static int __init i8237A_init_sysfs (void ) +static int __init i8237A_init_ops (void ) { -int error =sysdev_class_register (&i8237_sysdev_class); -if (!error) - error =sysdev_register (&device_i8237A); -return error; +register_syscore_ops (&i8237_syscore_ops); +return 0 ; } -device_initcall (i8237A_init_sysfs); +device_initcall (i8237A_init_ops);
arch/x86/kernel/i8259.c +10 -23
@@ -8,7 +8,7 @@#include <linux/random.h> #include <linux/init.h> #include <linux/kernel_stat.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/bitops.h> #include <linux/acpi.h> #include <linux/io.h>
@@ -245,20 +245,19 @@ static void save_ELCR(char *trigger) trigger[1 ] =inb (0x4d1 ) &0xDE ; } -static int i8259A_resume (struct sys_device *dev) +static void i8259A_resume (void ) {init_8259A (i8259A_auto_eoi);restore_ELCR (irq_trigger); -return 0 ; } -static int i8259A_suspend (struct sys_device *dev,pm_message_t state) +static int i8259A_suspend (void ) {save_ELCR (irq_trigger);return 0 ; } -static int i8259A_shutdown (struct sys_device *dev) +static void i8259A_shutdown (void ) {/* Put the i8259A into a quiescent state that * the kernel initialization code can get it
@@ -266,21 +265,14 @@ static int i8259A_shutdown(struct sys_de*/ outb (0xff ,PIC_MASTER_IMR );/* mask all of 8259A-1 */ outb (0xff ,PIC_SLAVE_IMR );/* mask all of 8259A-1 */ -return 0 ; } -static struct sysdev_class i8259_sysdev_class = { - .name ="i8259" , +static struct syscore_ops i8259_syscore_ops = { .suspend = i8259A_suspend, .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; -static struct sys_device device_i8259A = { - .id =0 , - .cls = &i8259_sysdev_class, -}; -static void mask_8259A (void ) {unsigned long flags;
@@ -399,17 +391,12 @@ struct legacy_pic default_legacy_pic = {struct legacy_pic *legacy_pic = &default_legacy_pic; -static int __init i8259A_init_sysfs (void ) +static int __init i8259A_init_ops (void ) { -int error; - -if (legacy_pic != &default_legacy_pic) -return 0 ; +if (legacy_pic == &default_legacy_pic) +register_syscore_ops (&i8259_syscore_ops); - error =sysdev_class_register (&i8259_sysdev_class); -if (!error) - error =sysdev_register (&device_i8259A); -return error; +return 0 ; } -device_initcall (i8259A_init_sysfs); +device_initcall (i8259A_init_ops);
arch/x86/kernel/pci-gart_64.c +7 -25
@@ -27,7 +27,7 @@#include <linux/kdebug.h> #include <linux/scatterlist.h> #include <linux/iommu-helper.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/io.h> #include <linux/gfp.h> #include <asm/atomic.h>
@@ -589,7 +589,7 @@ void set_up_gart_resume(u32 aper_order, aperture_alloc = aper_alloc; } -static void gart_fixup_northbridges (struct sys_device *dev) +static void gart_fixup_northbridges (void ) {int i;
@@ -613,33 +613,20 @@ static void gart_fixup_northbridges(stru } } -static int gart_resume (struct sys_device *dev) +static void gart_resume (void ) {pr_info ("PCI-DMA: Resuming GART IOMMU\n" ); -gart_fixup_northbridges (dev); +gart_fixup_northbridges ();enable_gart_translations (); - -return 0 ; } -static int gart_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class gart_sysdev_class = { - .name ="gart" , - .suspend = gart_suspend, +static struct syscore_ops gart_syscore_ops = { .resume = gart_resume, }; -static struct sys_device device_gart = { - .cls = &gart_sysdev_class, -}; -/* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason.
@@ -650,7 +637,7 @@ static __init int init_amd_gatt(struct aunsigned aper_base, new_aper_base;struct pci_dev *dev;void *gatt; -int i, error; +int i;pr_info ("PCI-DMA: Disabling AGP.\n" );
@@ -685,12 +672,7 @@ static __init int init_amd_gatt(struct a agp_gatt_table = gatt; - error =sysdev_class_register (&gart_sysdev_class); -if (!error) - error =sysdev_register (&device_gart); -if (error) -panic ("Could not register gart_sysdev -- " -"would corrupt data on next suspend" ); +register_syscore_ops (&gart_syscore_ops);flush_gart ();
arch/x86/oprofile/nmi_int.c +12 -32
89 lines not on this page · raw message
drivers/acpi/pci_link.c +8 -22
@@ -29,7 +29,7 @@* for IRQ management (e.g. start()->_SRS). */ -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h>
@@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct areturn 0 ; } -static int irqrouter_resume (struct sys_device *dev) +static void irqrouter_resume (void ) {struct acpi_pci_link *link;list_for_each_entry (link, &acpi_link_list, list) {acpi_pci_link_resume (link); } -return 0 ; }static int acpi_pci_link_remove (struct acpi_device *device,int type)
@@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(c__setup ("acpi_irq_balance" , acpi_irq_balance_set); -/* FIXME: we will remove this interface after all drivers call pci_disable_device */ -static struct sysdev_class irqrouter_sysdev_class = { - .name ="irqrouter" , +static struct syscore_ops irqrouter_syscore_ops = { .resume = irqrouter_resume, }; -static struct sys_device device_irqrouter = { - .id =0 , - .cls = &irqrouter_sysdev_class, -}; - -static int __init irqrouter_init_sysfs (void ) +static int __init irqrouter_init_ops (void ) { -int error; +if (!acpi_disabled && !acpi_noirq) +register_syscore_ops (&irqrouter_syscore_ops); -if (acpi_disabled || acpi_noirq) -return 0 ; - - error =sysdev_class_register (&irqrouter_sysdev_class); -if (!error) - error =sysdev_register (&device_irqrouter); - -return error; +return 0 ; } -device_initcall (irqrouter_init_sysfs); +device_initcall (irqrouter_init_ops);static int __init acpi_pci_link_init (void ) {
drivers/pci/intel-iommu.c +9 -29
@@ -36,7 +36,7 @@#include <linux/iova.h> #include <linux/iommu.h> #include <linux/intel-iommu.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/tboot.h> #include <linux/dmi.h> #include <asm/cacheflush.h>
@@ -3135,7 +3135,7 @@ static void iommu_flush_all(void) } } -static int iommu_suspend (struct sys_device *dev,pm_message_t state) +static int iommu_suspend (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3175,7 +3175,7 @@ nomem:return -ENOMEM ; } -static int iommu_resume (struct sys_device *dev) +static void iommu_resume (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3183,7 +3183,7 @@ static int iommu_resume(struct sys_devicif (init_iommu_hw ()) {WARN (1 ,"IOMMU setup failed, DMAR can not resume!\n" ); -return -EIO ; +return ; }for_each_active_iommu (iommu, drhd) {
@@ -3204,40 +3204,20 @@ static int iommu_resume(struct sys_devicfor_each_active_iommu (iommu, drhd) kfree(iommu->iommu_state); - - return 0; } -static struct sysdev_class iommu_sysclass = { - .name ="iommu" , +static struct syscore_ops iommu_syscore_ops = { .resume = iommu_resume, .suspend = iommu_suspend, }; -static struct sys_device device_iommu = { - .cls = &iommu_sysclass, -}; - -static int __init init_iommu_sysfs (void ) +static void __init init_iommu_pm_ops (void ) { -int error; - - error =sysdev_class_register (&iommu_sysclass); -if (error) -return error; - - error =sysdev_register (&device_iommu); -if (error) -sysdev_class_unregister (&iommu_sysclass); - -return error; +register_syscore_ops (&iommu_syscore_ops); }#else -static int __init init_iommu_sysfs (void ) -{ -return 0 ; -} +static inline int init_iommu_pm_ops (void ) { }#endif /* CONFIG_PM */ /*
@@ -3320,7 +3300,7 @@ int __init intel_iommu_init(void)#endif dma_ops = &intel_dma_ops; -init_iommu_sysfs (); +init_iommu_pm_ops ();register_iommu (&intel_iommu_ops);
kernel/time/timekeeping.c +8 -19
@@ -14,7 +14,7 @@#include <linux/init.h> #include <linux/mm.h> #include <linux/sched.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/clocksource.h> #include <linux/jiffies.h> #include <linux/time.h>
@@ -561,13 +561,12 @@ static struct timespec timekeeping_suspe/** * timekeeping_resume - Resumes the generic timekeeping subsystem. -* @dev: unused * * This is for the generic clocksource timekeeping. * xtime/wall_to_monotonic/jiffies/etc are * still managed by arch specific suspend/resume code. */ -static int timekeeping_resume (struct sys_device *dev) +static void timekeeping_resume (void ) {unsigned long flags;struct timespec ts;
@@ -596,11 +595,9 @@ static int timekeeping_resume(struct sys/* Resume hrtimers */ hres_timers_resume (); - -return 0 ; } -static int timekeeping_suspend (struct sys_device *dev,pm_message_t state) +static int timekeeping_suspend (void ) {unsigned long flags;
@@ -618,26 +615,18 @@ static int timekeeping_suspend(struct sy }/* sysfs resume/suspend bits for timekeeping */ -static struct sysdev_class timekeeping_sysclass = { - .name ="timekeeping" , +static struct syscore_ops timekeeping_syscore_ops = { .resume = timekeeping_resume, .suspend = timekeeping_suspend, }; -static struct sys_device device_timer = { - .id =0 , - .cls = &timekeeping_sysclass, -}; - -static int __init timekeeping_init_device (void ) +static int __init timekeeping_init_ops (void ) { -int error =sysdev_class_register (&timekeeping_sysclass); -if (!error) - error =sysdev_register (&device_timer); -return error; +register_syscore_ops (&timekeeping_syscore_ops); +return 0 ; } -device_initcall (timekeeping_init_device); +device_initcall (timekeeping_init_ops);/* * If the error is already larger, we look ahead even further
RFC PATCH 2/2 Convert several sysdev users to using struct syscore_ops
In reply to Rafael J. WysockiSome subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs specifically for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct syscore_ops objects for this purpose instead.
--- arch/x86/kernel/amd_iommu_init.c | 26 ++-------- arch/x86/kernel/apic/apic.c | 29 +++-------- arch/x86/kernel/apic/io_apic.c | 97 ++++++++++++++++++--------------------- arch/x86/kernel/i8237.c | 30 ++---------- arch/x86/kernel/i8259.c | 33 ++++--------- arch/x86/kernel/pci-gart_64.c | 32 ++---------- arch/x86/oprofile/nmi_int.c | 44 ++++------------- drivers/acpi/pci_link.c | 30 +++--------- drivers/pci/intel-iommu.c | 38 +++------------ kernel/time/timekeeping.c | 27 +++------- 10 files changed, 121 insertions(+), 265 deletions(-)
arch/x86/kernel/amd_iommu_init.c +6 -20
@@ -21,7 +21,7 @@#include <linux/acpi.h> #include <linux/list.h> #include <linux/slab.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/msi.h> #include <asm/pci-direct.h>
@@ -1260,7 +1260,7 @@ static void disable_iommus(void)* disable suspend until real resume implemented */ -static int amd_iommu_resume (struct sys_device *dev) +static void amd_iommu_resume (void ) {struct amd_iommu *iommu;
@@ -1276,11 +1276,9 @@ static int amd_iommu_resume(struct sys_d*/ amd_iommu_flush_all_devices ();amd_iommu_flush_all_domains (); - -return 0 ; } -static int amd_iommu_suspend (struct sys_device *dev,pm_message_t state) +static int amd_iommu_suspend (void ) {/* disable IOMMUs to go out of the way for BIOS */ disable_iommus ();
@@ -1288,17 +1286,11 @@ static int amd_iommu_suspend(struct sys_return 0 ; } -static struct sysdev_class amd_iommu_sysdev_class = { - .name ="amd_iommu" , +static struct syscore_ops amd_iommu_syscore_ops = { .suspend = amd_iommu_suspend, .resume = amd_iommu_resume, }; -static struct sys_device device_amd_iommu = { - .id =0 , - .cls = &amd_iommu_sysdev_class, -}; -/* * This is the core init function for AMD IOMMU hardware in the system. * This function is called from the generic x86 DMA layer initialization
@@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void) goto free; } - ret =sysdev_class_register (&amd_iommu_sysdev_class); -if (ret) - goto free; - - ret =sysdev_register (&device_amd_iommu); -if (ret) - goto free; - ret =amd_iommu_init_devices ();if (ret) goto free;
@@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void)amd_iommu_init_notifier (); +register_syscore_ops (&amd_iommu_syscore_ops); +if (iommu_pass_through) goto out;
arch/x86/kernel/apic/apic.c +8 -21
@@ -24,7 +24,7 @@#include <linux/ftrace.h> #include <linux/ioport.h> #include <linux/module.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/timex.h> #include <linux/dmar.h>
@@ -2036,7 +2036,7 @@ static struct {unsigned int apic_thmr; } apic_pm_state; -static int lapic_suspend (struct sys_device *dev,pm_message_t state) +static int lapic_suspend (void ) {unsigned long flags;int maxlvt;
@@ -2074,7 +2074,7 @@ static int lapic_suspend(struct sys_devireturn 0 ; } -static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;
@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);if (intr_remapping_enabled) {
@@ -2152,8 +2152,6 @@ static int lapic_resume(struct sys_devic } restore:local_irq_restore (flags); - -return ret; }/*
@@ -2161,17 +2159,11 @@ restore:* are needed on every CPU up until machine_halt/restart/poweroff. */ -static struct sysdev_class lapic_sysclass = { - .name ="lapic" , +static struct syscore_ops lapic_syscore_ops = { .resume = lapic_resume, .suspend = lapic_suspend, }; -static struct sys_device device_lapic = { - .id =0 , - .cls = &lapic_sysclass, -}; -static void __cpuinit apic_pm_activate (void ) { apic_pm_state.active =1 ;
@@ -2179,16 +2171,11 @@ static void __cpuinit apic_pm_activate(vstatic int __init init_lapic_sysfs (void ) { -int error; - -if (!cpu_has_apic) -return 0 ;/* XXX: remove suspend/resume procs if !apic_pm_state.active? */ +if (cpu_has_apic) +register_syscore_ops (&lapic_syscore_ops); - error =sysdev_class_register (&lapic_sysclass); -if (!error) - error =sysdev_register (&device_lapic); -return error; +return 0 ; }/* local apic needs to resume before other devices access its registers. */
arch/x86/kernel/apic/io_apic.c +46 -51
142 lines not on this page · raw message
arch/x86/kernel/i8237.c +7 -23
@@ -10,7 +10,7 @@*/ #include <linux/init.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <asm/dma.h>
@@ -21,7 +21,7 @@* in asm/dma.h. */ -static int i8237A_resume (struct sys_device *dev) +static void i8237A_resume (void ) {unsigned long flags;int i;
@@ -41,31 +41,15 @@ static int i8237A_resume(struct sys_devienable_dma (4 );release_dma_lock (flags); - -return 0 ; } -static int i8237A_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class i8237_sysdev_class = { - .name ="i8237" , - .suspend = i8237A_suspend, +static struct syscore_ops i8237_syscore_ops = { .resume = i8237A_resume, }; -static struct sys_device device_i8237A = { - .id =0 , - .cls = &i8237_sysdev_class, -}; - -static int __init i8237A_init_sysfs (void ) +static int __init i8237A_init_ops (void ) { -int error =sysdev_class_register (&i8237_sysdev_class); -if (!error) - error =sysdev_register (&device_i8237A); -return error; +register_syscore_ops (&i8237_syscore_ops); +return 0 ; } -device_initcall (i8237A_init_sysfs); +device_initcall (i8237A_init_ops);
arch/x86/kernel/i8259.c +10 -23
@@ -8,7 +8,7 @@#include <linux/random.h> #include <linux/init.h> #include <linux/kernel_stat.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/bitops.h> #include <linux/acpi.h> #include <linux/io.h>
@@ -245,20 +245,19 @@ static void save_ELCR(char *trigger) trigger[1 ] =inb (0x4d1 ) &0xDE ; } -static int i8259A_resume (struct sys_device *dev) +static void i8259A_resume (void ) {init_8259A (i8259A_auto_eoi);restore_ELCR (irq_trigger); -return 0 ; } -static int i8259A_suspend (struct sys_device *dev,pm_message_t state) +static int i8259A_suspend (void ) {save_ELCR (irq_trigger);return 0 ; } -static int i8259A_shutdown (struct sys_device *dev) +static void i8259A_shutdown (void ) {/* Put the i8259A into a quiescent state that * the kernel initialization code can get it
@@ -266,21 +265,14 @@ static int i8259A_shutdown(struct sys_de*/ outb (0xff ,PIC_MASTER_IMR );/* mask all of 8259A-1 */ outb (0xff ,PIC_SLAVE_IMR );/* mask all of 8259A-1 */ -return 0 ; } -static struct sysdev_class i8259_sysdev_class = { - .name ="i8259" , +static struct syscore_ops i8259_syscore_ops = { .suspend = i8259A_suspend, .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; -static struct sys_device device_i8259A = { - .id =0 , - .cls = &i8259_sysdev_class, -}; -static void mask_8259A (void ) {unsigned long flags;
@@ -399,17 +391,12 @@ struct legacy_pic default_legacy_pic = {struct legacy_pic *legacy_pic = &default_legacy_pic; -static int __init i8259A_init_sysfs (void ) +static int __init i8259A_init_ops (void ) { -int error; - -if (legacy_pic != &default_legacy_pic) -return 0 ; +if (legacy_pic == &default_legacy_pic) +register_syscore_ops (&i8259_syscore_ops); - error =sysdev_class_register (&i8259_sysdev_class); -if (!error) - error =sysdev_register (&device_i8259A); -return error; +return 0 ; } -device_initcall (i8259A_init_sysfs); +device_initcall (i8259A_init_ops);
arch/x86/kernel/pci-gart_64.c +7 -25
@@ -27,7 +27,7 @@#include <linux/kdebug.h> #include <linux/scatterlist.h> #include <linux/iommu-helper.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/io.h> #include <linux/gfp.h> #include <asm/atomic.h>
@@ -589,7 +589,7 @@ void set_up_gart_resume(u32 aper_order, aperture_alloc = aper_alloc; } -static void gart_fixup_northbridges (struct sys_device *dev) +static void gart_fixup_northbridges (void ) {int i;
@@ -613,33 +613,20 @@ static void gart_fixup_northbridges(stru } } -static int gart_resume (struct sys_device *dev) +static void gart_resume (void ) {pr_info ("PCI-DMA: Resuming GART IOMMU\n" ); -gart_fixup_northbridges (dev); +gart_fixup_northbridges ();enable_gart_translations (); - -return 0 ; } -static int gart_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class gart_sysdev_class = { - .name ="gart" , - .suspend = gart_suspend, +static struct syscore_ops gart_syscore_ops = { .resume = gart_resume, }; -static struct sys_device device_gart = { - .cls = &gart_sysdev_class, -}; -/* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason.
@@ -650,7 +637,7 @@ static __init int init_amd_gatt(struct aunsigned aper_base, new_aper_base;struct pci_dev *dev;void *gatt; -int i, error; +int i;pr_info ("PCI-DMA: Disabling AGP.\n" );
@@ -685,12 +672,7 @@ static __init int init_amd_gatt(struct a agp_gatt_table = gatt; - error =sysdev_class_register (&gart_sysdev_class); -if (!error) - error =sysdev_register (&device_gart); -if (error) -panic ("Could not register gart_sysdev -- " -"would corrupt data on next suspend" ); +register_syscore_ops (&gart_syscore_ops);flush_gart ();
arch/x86/oprofile/nmi_int.c +12 -32
89 lines not on this page · raw message
drivers/acpi/pci_link.c +8 -22
@@ -29,7 +29,7 @@* for IRQ management (e.g. start()->_SRS). */ -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h>
@@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct areturn 0 ; } -static int irqrouter_resume (struct sys_device *dev) +static void irqrouter_resume (void ) {struct acpi_pci_link *link;list_for_each_entry (link, &acpi_link_list, list) {acpi_pci_link_resume (link); } -return 0 ; }static int acpi_pci_link_remove (struct acpi_device *device,int type)
@@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(c__setup ("acpi_irq_balance" , acpi_irq_balance_set); -/* FIXME: we will remove this interface after all drivers call pci_disable_device */ -static struct sysdev_class irqrouter_sysdev_class = { - .name ="irqrouter" , +static struct syscore_ops irqrouter_syscore_ops = { .resume = irqrouter_resume, }; -static struct sys_device device_irqrouter = { - .id =0 , - .cls = &irqrouter_sysdev_class, -}; - -static int __init irqrouter_init_sysfs (void ) +static int __init irqrouter_init_ops (void ) { -int error; +if (!acpi_disabled && !acpi_noirq) +register_syscore_ops (&irqrouter_syscore_ops); -if (acpi_disabled || acpi_noirq) -return 0 ; - - error =sysdev_class_register (&irqrouter_sysdev_class); -if (!error) - error =sysdev_register (&device_irqrouter); - -return error; +return 0 ; } -device_initcall (irqrouter_init_sysfs); +device_initcall (irqrouter_init_ops);static int __init acpi_pci_link_init (void ) {
drivers/pci/intel-iommu.c +9 -29
@@ -36,7 +36,7 @@#include <linux/iova.h> #include <linux/iommu.h> #include <linux/intel-iommu.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/tboot.h> #include <linux/dmi.h> #include <asm/cacheflush.h>
@@ -3135,7 +3135,7 @@ static void iommu_flush_all(void) } } -static int iommu_suspend (struct sys_device *dev,pm_message_t state) +static int iommu_suspend (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3175,7 +3175,7 @@ nomem:return -ENOMEM ; } -static int iommu_resume (struct sys_device *dev) +static void iommu_resume (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3183,7 +3183,7 @@ static int iommu_resume(struct sys_devicif (init_iommu_hw ()) {WARN (1 ,"IOMMU setup failed, DMAR can not resume!\n" ); -return -EIO ; +return ; }for_each_active_iommu (iommu, drhd) {
@@ -3204,40 +3204,20 @@ static int iommu_resume(struct sys_devicfor_each_active_iommu (iommu, drhd) kfree(iommu->iommu_state); - - return 0; } -static struct sysdev_class iommu_sysclass = { - .name ="iommu" , +static struct syscore_ops iommu_syscore_ops = { .resume = iommu_resume, .suspend = iommu_suspend, }; -static struct sys_device device_iommu = { - .cls = &iommu_sysclass, -}; - -static int __init init_iommu_sysfs (void ) +static void __init init_iommu_pm_ops (void ) { -int error; - - error =sysdev_class_register (&iommu_sysclass); -if (error) -return error; - - error =sysdev_register (&device_iommu); -if (error) -sysdev_class_unregister (&iommu_sysclass); - -return error; +register_syscore_ops (&iommu_syscore_ops); }#else -static int __init init_iommu_sysfs (void ) -{ -return 0 ; -} +static inline int init_iommu_pm_ops (void ) { }#endif /* CONFIG_PM */ /*
@@ -3320,7 +3300,7 @@ int __init intel_iommu_init(void)#endif dma_ops = &intel_dma_ops; -init_iommu_sysfs (); +init_iommu_pm_ops ();register_iommu (&intel_iommu_ops);
kernel/time/timekeeping.c +8 -19
@@ -14,7 +14,7 @@#include <linux/init.h> #include <linux/mm.h> #include <linux/sched.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/clocksource.h> #include <linux/jiffies.h> #include <linux/time.h>
@@ -561,13 +561,12 @@ static struct timespec timekeeping_suspe/** * timekeeping_resume - Resumes the generic timekeeping subsystem. -* @dev: unused * * This is for the generic clocksource timekeeping. * xtime/wall_to_monotonic/jiffies/etc are * still managed by arch specific suspend/resume code. */ -static int timekeeping_resume (struct sys_device *dev) +static void timekeeping_resume (void ) {unsigned long flags;struct timespec ts;
@@ -596,11 +595,9 @@ static int timekeeping_resume(struct sys/* Resume hrtimers */ hres_timers_resume (); - -return 0 ; } -static int timekeeping_suspend (struct sys_device *dev,pm_message_t state) +static int timekeeping_suspend (void ) {unsigned long flags;
@@ -618,26 +615,18 @@ static int timekeeping_suspend(struct sy }/* sysfs resume/suspend bits for timekeeping */ -static struct sysdev_class timekeeping_sysclass = { - .name ="timekeeping" , +static struct syscore_ops timekeeping_syscore_ops = { .resume = timekeeping_resume, .suspend = timekeeping_suspend, }; -static struct sys_device device_timer = { - .id =0 , - .cls = &timekeeping_sysclass, -}; - -static int __init timekeeping_init_device (void ) +static int __init timekeeping_init_ops (void ) { -int error =sysdev_class_register (&timekeeping_sysclass); -if (!error) - error =sysdev_register (&device_timer); -return error; +register_syscore_ops (&timekeeping_syscore_ops); +return 0 ; } -device_initcall (timekeeping_init_device); +device_initcall (timekeeping_init_ops);/* * If the error is already larger, we look ahead even further
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
Quoted 6 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs specifically for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct
syscore_opsobjects for this purpose instead.
:)
Do you want to resend this with a signed-off-by and your first one so I can apply it to my tree, or do you want to take it through yours?
thanks again for doing this.
greg k-h
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
In reply to Rafael J. WysockiQuoted 6 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs specifically for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct
syscore_opsobjects for this purpose instead.
:)
Do you want to resend this with a signed-off-by and your first one so I can apply it to my tree, or do you want to take it through yours?
thanks again for doing this.
greg k-h
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
Quoted 11 lines · Greg KH
Quoted 6 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs specifically for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct
syscore_opsobjects for this purpose instead.Heavily-Acked-by Greg Kroah-Hartman <[email protected]>:)
Heh, thanks!
Quoted 2 lines
Do you want to resend this with a signed-off-by and your first one so I can apply it to my tree, or do you want to take it through yours?
Well, I'm going to resend with sign-offs anyway. Besides, I'm not sure if I should split [2/2] into a few smaller patches. At least the stuff outside of arch/x86 should be done in separate patches IMHO.
Apart from this, there are other architectures using sysdevs for defining "very late" and "very early" PM callbacks, ARM in particular (that one is going to be fun to untangle).
I thought about two different possible ways forward:
(1) Push [1/2] and the patches converting things that x86 depends on first, followed perhaps by a patch introducing something like CONFIG_ARCH_NO_SYSDEV_OPS that would simply disable sysdev_{suspend|resume|shutdown}() (x86 would set it). The other arches might then be converted over time.
(2) Prepare patches converting everything that can be converted in the tree and push them all in one shot.
The advantage of (1) is that we can start making changes RSN and the advantage of (2) seems to be that we may avoid some potential suspend/resume ordering issues on non-x86 architectures that may arise in principle if some subsystems are converted to using struct syscore_ops while the others are not (syscore_suspend() is executed after sysdev_suspend(), so if we move something from the latter to the former, it may end up being executed after things that it was executed before previously).
Please let me know what your opinion is.
Quoted 1 line
thanks again for doing this.
No big deal really. :-)
Thanks,
Rafael
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
In reply to Greg KHQuoted 11 lines · Greg KH
Quoted 6 lines · Rafael J. Wysocki
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs specifically for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct
syscore_opsobjects for this purpose instead.Heavily-Acked-by Greg Kroah-Hartman <[email protected]>:)
Heh, thanks!
Quoted 2 lines
Do you want to resend this with a signed-off-by and your first one so I can apply it to my tree, or do you want to take it through yours?
Well, I'm going to resend with sign-offs anyway. Besides, I'm not sure if I should split [2/2] into a few smaller patches. At least the stuff outside of arch/x86 should be done in separate patches IMHO.
Apart from this, there are other architectures using sysdevs for defining "very late" and "very early" PM callbacks, ARM in particular (that one is going to be fun to untangle).
I thought about two different possible ways forward:
(1) Push [1/2] and the patches converting things that x86 depends on first, followed perhaps by a patch introducing something like CONFIG_ARCH_NO_SYSDEV_OPS that would simply disable sysdev_{suspend|resume|shutdown}() (x86 would set it). The other arches might then be converted over time.
(2) Prepare patches converting everything that can be converted in the tree and push them all in one shot.
The advantage of (1) is that we can start making changes RSN and the advantage of (2) seems to be that we may avoid some potential suspend/resume ordering issues on non-x86 architectures that may arise in principle if some subsystems are converted to using struct syscore_ops while the others are not (syscore_suspend() is executed after sysdev_suspend(), so if we move something from the latter to the former, it may end up being executed after things that it was executed before previously).
Please let me know what your opinion is.
Quoted 1 line
thanks again for doing this.
No big deal really. :-)
Thanks,
Rafael
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
Quoted 19 lines · Rafael J. Wysocki
I thought about two different possible ways forward:
(1) Push [1/2] and the patches converting things that x86 depends on first, followed perhaps by a patch introducing something like
CONFIG_ARCH_NO_SYSDEV_OPSthat would simply disable sysdev_{suspend|resume|shutdown}() (x86 would set it). The other arches might then be converted over time.(2) Prepare patches converting everything that can be converted in the tree and push them all in one shot.
The advantage of (1) is that we can start making changes RSN and the advantage of (2) seems to be that we may avoid some potential suspend/resume ordering issues on non-x86 architectures that may arise in principle if some subsystems are converted to using struct
syscore_opswhile the others are not (syscore_suspend()is executed aftersysdev_suspend(), so if we move something from the latter to the former, it may end up being executed after things that it was executed before previously).
Quoted 1 line
Please let me know what your opinion is.
Hm, I would prefer (1) as that lets us get this moving sooner, and "flag days" are never good to have. If there are problems that arise because of it, as you have noted, it will be simple just to convert the parts that were using the "old" methods to the new ones to fix the issue, right?
thanks,
greg k-h
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
In reply to Rafael J. WysockiQuoted 19 lines · Rafael J. Wysocki
I thought about two different possible ways forward:
(1) Push [1/2] and the patches converting things that x86 depends on first, followed perhaps by a patch introducing something like
CONFIG_ARCH_NO_SYSDEV_OPSthat would simply disable sysdev_{suspend|resume|shutdown}() (x86 would set it). The other arches might then be converted over time.(2) Prepare patches converting everything that can be converted in the tree and push them all in one shot.
The advantage of (1) is that we can start making changes RSN and the advantage of (2) seems to be that we may avoid some potential suspend/resume ordering issues on non-x86 architectures that may arise in principle if some subsystems are converted to using struct
syscore_opswhile the others are not (syscore_suspend()is executed aftersysdev_suspend(), so if we move something from the latter to the former, it may end up being executed after things that it was executed before previously).
Quoted 1 line
Please let me know what your opinion is.
Hm, I would prefer (1) as that lets us get this moving sooner, and "flag days" are never good to have. If there are problems that arise because of it, as you have noted, it will be simple just to convert the parts that were using the "old" methods to the new ones to fix the issue, right?
thanks,
greg k-h
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
Quoted 20 lines · Greg KH
Quoted 19 lines · Rafael J. Wysocki
I thought about two different possible ways forward:
(1) Push [1/2] and the patches converting things that x86 depends on first, followed perhaps by a patch introducing something like
CONFIG_ARCH_NO_SYSDEV_OPSthat would simply disable sysdev_{suspend|resume|shutdown}() (x86 would set it). The other arches might then be converted over time.(2) Prepare patches converting everything that can be converted in the tree and push them all in one shot.
The advantage of (1) is that we can start making changes RSN and the advantage of (2) seems to be that we may avoid some potential suspend/resume ordering issues on non-x86 architectures that may arise in principle if some subsystems are converted to using struct
syscore_opswhile the others are not (syscore_suspend()is executed aftersysdev_suspend(), so if we move something from the latter to the former, it may end up being executed after things that it was executed before previously).
Quoted 7 lines
Quoted 1 line
Please let me know what your opinion is.
Hm, I would prefer (1) as that lets us get this moving sooner, and "flag days" are never good to have. If there are problems that arise because of it, as you have noted, it will be simple just to convert the parts that were using the "old" methods to the new ones to fix the issue, right?
Yes, I agree.
Thanks,
Rafael
Re: [RFC][PATCH 2/2] Convert several sysdev users to using struct syscore_ops
In reply to Greg KHQuoted 20 lines · Greg KH
Quoted 19 lines · Rafael J. Wysocki
I thought about two different possible ways forward:
(1) Push [1/2] and the patches converting things that x86 depends on first, followed perhaps by a patch introducing something like
CONFIG_ARCH_NO_SYSDEV_OPSthat would simply disable sysdev_{suspend|resume|shutdown}() (x86 would set it). The other arches might then be converted over time.(2) Prepare patches converting everything that can be converted in the tree and push them all in one shot.
The advantage of (1) is that we can start making changes RSN and the advantage of (2) seems to be that we may avoid some potential suspend/resume ordering issues on non-x86 architectures that may arise in principle if some subsystems are converted to using struct
syscore_opswhile the others are not (syscore_suspend()is executed aftersysdev_suspend(), so if we move something from the latter to the former, it may end up being executed after things that it was executed before previously).
Quoted 7 lines
Quoted 1 line
Please let me know what your opinion is.
Hm, I would prefer (1) as that lets us get this moving sooner, and "flag days" are never good to have. If there are problems that arise because of it, as you have noted, it will be simple just to convert the parts that were using the "old" methods to the new ones to fix the issue, right?
Yes, I agree.
Thanks,
Rafael
Quoted 27 lines · Rafael J. Wysocki
There are multiple problems with sysdevs, or struct
sys_deviceobjects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
Quoted 7 lines
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
Do I read that right? We get rid of the entire dance of creating sysdevs/sysdev_classes and the pointless and broken stuff in /sys?
We just dynamically maintain a list of devices/operations, which is list-executed when needed?
These new "core" operations are not included in every device but only global per subsystem, just like the sysdev_class did earlier?
Looks all like a nice plan to me.
Thanks,
Kay
Quoted 27 lines · Rafael J. Wysocki
There are multiple problems with sysdevs, or struct
sys_deviceobjects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
Quoted 7 lines
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
Do I read that right? We get rid of the entire dance of creating sysdevs/sysdev_classes and the pointless and broken stuff in /sys?
We just dynamically maintain a list of devices/operations, which is list-executed when needed?
These new "core" operations are not included in every device but only global per subsystem, just like the sysdev_class did earlier?
Looks all like a nice plan to me.
Thanks,
Kay
Quoted 36 lines · Kay Sievers
Quoted 27 lines · Rafael J. Wysocki
There are multiple problems with sysdevs, or struct
sys_deviceobjects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
Quoted 7 lines
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
Quoted 2 lines
Do I read that right? We get rid of the entire dance of creating sysdevs/sysdev_classes and the pointless and broken stuff in /sys?
That's the plan at least.
Quoted 5 lines
We just dynamically maintain a list of devices/operations, which is list-executed when needed?
These new "core" operations are not included in every device but only global per subsystem, just like the
sysdev_classdid earlier?
Yup.
Quoted 1 line
Looks all like a nice plan to me.
Good. :-)
Thanks,
Rafael
Quoted 36 lines · Kay Sievers
Quoted 27 lines · Rafael J. Wysocki
There are multiple problems with sysdevs, or struct
sys_deviceobjects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
Quoted 7 lines
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
Quoted 2 lines
Do I read that right? We get rid of the entire dance of creating sysdevs/sysdev_classes and the pointless and broken stuff in /sys?
That's the plan at least.
Quoted 5 lines
We just dynamically maintain a list of devices/operations, which is list-executed when needed?
These new "core" operations are not included in every device but only global per subsystem, just like the
sysdev_classdid earlier?
Yup.
Quoted 1 line
Looks all like a nice plan to me.
Good. :-)
Thanks,
Rafael
cover Allow subsystems to avoid using sysdevs for defining "core" PM callbacks
In reply to Rafael J. WysockiHi,
Quoted 35 lines · Rafael J. Wysocki
There are multiple problems with sysdevs, or struct
sys_deviceobjects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
Quoted 4 lines
This is a proof of concept, so the patches have not been tested. Please be extrememly careful, because they touch sensitive code, so to speak. In the majority of cases the changes are rather straightforward, but there are some more interesting cases as well (
io_apic.cmost importantly).
Since Greg likes the idea and there haven't been any objections so far, here's the official submission. The patches have been tested on HP nx6325 and Toshiba Portege R500.
Patch [1/8] is regareded as 2.6.38 material, following Greg's advice. The other patches in the set are regarded as 2.6.39 material. The last one obviously depends on all of the previous ones.
[1/8] - Introduce struct syscore_ops for registering operations to be run on
one CPU during suspend/resume/shutdown.
[2/8] - Convert sysdev users in arch/x86 to using struct syscore_ops.
[3/8] - Make ACPI use struct syscore_ops for irqrouter_resume().
[4/8] - Make timekeeping use struct syscore_ops for suspend/resume.
[5/8] - Make Intel IOMMU use struct syscore_ops for suspend/resume.
[6/8] - Make KVM use struct syscore_ops for suspend/resume.
[7/8] - Make cpufreq use struct syscore_ops for boot CPU suspend/resume.
[8/8] - Introduce config switch allowing architectures to skip sysdev
suspend/resume/shutdown code.
If there are no objectsions, I'd like to push these patches through the suspend tree.
Thanks,
Rafael
PATCH 1/8 PM / Core: Introcude struct syscore_ops
From: Rafael J. Wysocki <[email protected]>
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects.
--- drivers/base/Makefile | 2 drivers/base/syscore.c | 117 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 ++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 164 insertions(+), 1 deletion(-)
include/linux/syscore_ops.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif +extern void syscore_shutdown (void ); + +#endif
drivers/base/syscore.c new file +117 -0
117 lines not on this page · raw message
kernel/power/suspend.c +4 -0
@@ -22,6 +22,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h> #include "power.h"
@@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_tBUG_ON (!irqs_disabled ()); error =sysdev_suspend (PMSG_SUSPEND ); +if (!error) + error =syscore_suspend ();if (!error) {if (!(suspend_test (TEST_CORE ) ||pm_wakeup_pending ())) { error = suspend_ops->enter (state); events_check_enabled = false; } +syscore_resume ();sysdev_resume (); }
kernel/power/hibernate.c +9 -0
@@ -23,6 +23,7 @@#include <linux/cpu.h> #include <linux/freezer.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <scsi/scsi_scan.h> #include <asm/suspend.h>
@@ -272,6 +273,8 @@ static int create_image(int platform_modlocal_irq_disable (); error =sysdev_suspend (PMSG_FREEZE ); +if (!error) + error =syscore_suspend ();if (error) {printk (KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n" );
@@ -295,6 +298,7 @@ static int create_image(int platform_mod } Power_up: +syscore_resume ();sysdev_resume ();/* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup.
@@ -403,6 +407,8 @@ static int resume_target_kernel(bool plalocal_irq_disable (); error =sysdev_suspend (PMSG_QUIESCE ); +if (!error) + error =syscore_suspend ();if (error) goto Enable_irqs;
@@ -429,6 +435,7 @@ static int resume_target_kernel(bool plarestore_processor_state ();touch_softlockup_watchdog (); +syscore_resume ();sysdev_resume (); Enable_irqs:
@@ -516,6 +523,7 @@ int hibernation_platform_enter(void)local_irq_disable ();sysdev_suspend (PMSG_HIBERNATE ); +syscore_suspend ();if (pm_wakeup_pending ()) { error = -EAGAIN ; goto Power_up;
@@ -526,6 +534,7 @@ int hibernation_platform_enter(void)while (1 ); Power_up: +syscore_resume ();sysdev_resume ();local_irq_enable ();enable_nonboot_cpus ();
kernel/sys.c +4 -0
@@ -37,6 +37,7 @@#include <linux/ptrace.h> #include <linux/fs_struct.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <linux/compat.h> #include <linux/syscalls.h>
@@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state =SYSTEM_RESTART ;device_shutdown ();sysdev_shutdown (); +syscore_shutdown (); }/**
@@ -336,6 +338,7 @@ void kernel_halt(void) {kernel_shutdown_prepare (SYSTEM_HALT );sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "System halted.\n" );kmsg_dump (KMSG_DUMP_HALT );machine_halt ();
@@ -355,6 +358,7 @@ void kernel_power_off(void)pm_power_off_prepare ();disable_nonboot_cpus ();sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "Power down.\n" );kmsg_dump (KMSG_DUMP_POWEROFF );machine_power_off ();
drivers/base/Makefile +1 -1
@@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o
PATCH 1/8 PM / Core: Introcude struct syscore_ops
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary.
For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects.
--- drivers/base/Makefile | 2 drivers/base/syscore.c | 117 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 ++++++++++ kernel/power/hibernate.c | 9 +++ kernel/power/suspend.c | 4 + kernel/sys.c | 4 + 6 files changed, 164 insertions(+), 1 deletion(-)
include/linux/syscore_ops.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* syscore_ops.h - System core operations. +* +* Copyright (C) 2011 Rafael J. Wysocki <[email protected]>, Novell Inc. +* +* This file is released under the GPLv2. +*/ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include <linux/list.h> + +struct syscore_ops { +struct list_head node; +int (*suspend)(void ); +void (*resume)(void ); +void (*shutdown)(void ); +}; + +extern void register_syscore_ops (struct syscore_ops *ops); +extern void unregister_syscore_ops (struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend (void ); +extern void syscore_resume (void ); +#endif +extern void syscore_shutdown (void ); + +#endif
drivers/base/syscore.c new file +117 -0
117 lines not on this page · raw message
kernel/power/suspend.c +4 -0
@@ -22,6 +22,7 @@#include <linux/mm.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h> #include "power.h"
@@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_tBUG_ON (!irqs_disabled ()); error =sysdev_suspend (PMSG_SUSPEND ); +if (!error) + error =syscore_suspend ();if (!error) {if (!(suspend_test (TEST_CORE ) ||pm_wakeup_pending ())) { error = suspend_ops->enter (state); events_check_enabled = false; } +syscore_resume ();sysdev_resume (); }
kernel/power/hibernate.c +9 -0
@@ -23,6 +23,7 @@#include <linux/cpu.h> #include <linux/freezer.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <scsi/scsi_scan.h> #include <asm/suspend.h>
@@ -272,6 +273,8 @@ static int create_image(int platform_modlocal_irq_disable (); error =sysdev_suspend (PMSG_FREEZE ); +if (!error) + error =syscore_suspend ();if (error) {printk (KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n" );
@@ -295,6 +298,7 @@ static int create_image(int platform_mod } Power_up: +syscore_resume ();sysdev_resume ();/* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup.
@@ -403,6 +407,8 @@ static int resume_target_kernel(bool plalocal_irq_disable (); error =sysdev_suspend (PMSG_QUIESCE ); +if (!error) + error =syscore_suspend ();if (error) goto Enable_irqs;
@@ -429,6 +435,7 @@ static int resume_target_kernel(bool plarestore_processor_state ();touch_softlockup_watchdog (); +syscore_resume ();sysdev_resume (); Enable_irqs:
@@ -516,6 +523,7 @@ int hibernation_platform_enter(void)local_irq_disable ();sysdev_suspend (PMSG_HIBERNATE ); +syscore_suspend ();if (pm_wakeup_pending ()) { error = -EAGAIN ; goto Power_up;
@@ -526,6 +534,7 @@ int hibernation_platform_enter(void)while (1 ); Power_up: +syscore_resume ();sysdev_resume ();local_irq_enable ();enable_nonboot_cpus ();
kernel/sys.c +4 -0
@@ -37,6 +37,7 @@#include <linux/ptrace.h> #include <linux/fs_struct.h> #include <linux/gfp.h> +#include <linux/syscore_ops.h> #include <linux/compat.h> #include <linux/syscalls.h>
@@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state =SYSTEM_RESTART ;device_shutdown ();sysdev_shutdown (); +syscore_shutdown (); }/**
@@ -336,6 +338,7 @@ void kernel_halt(void) {kernel_shutdown_prepare (SYSTEM_HALT );sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "System halted.\n" );kmsg_dump (KMSG_DUMP_HALT );machine_halt ();
@@ -355,6 +358,7 @@ void kernel_power_off(void)pm_power_off_prepare ();disable_nonboot_cpus ();sysdev_shutdown (); +syscore_shutdown ();printk (KERN_EMERG "Power down.\n" );kmsg_dump (KMSG_DUMP_POWEROFF );machine_power_off ();
drivers/base/Makefile +1 -1
@@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o
PATCH 2/8 x86: Use syscore_ops instead of sysdev classes and sysdevs
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Some subsystems in the x86 tree need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs or sysdev drivers for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct syscore_ops objects for this purpose instead.
Generally, there are three categories of subsystems that use sysdevs for implementing PM operations: (1) subsystems whose suspend/resume callbacks ignore their arguments entirely (the majority), (2) subsystems whose suspend/resume callbacks use their struct sys_device argument, but don't really need to do that, because they can be implemented differently in an arguably simpler way (io_apic.c), and (3) subsystems whose suspend/resume callbacks use their struct sys_device argument, but the value of that argument is always the same and could be ignored (microcode_core.c). In all of these cases the subsystems in question may be readily converted to using struct syscore_ops objects for power management and shutdown.
--- arch/x86/kernel/amd_iommu_init.c | 26 ++-------- arch/x86/kernel/apic/apic.c | 29 +++-------- arch/x86/kernel/apic/io_apic.c | 97 ++++++++++++++++++--------------------- arch/x86/kernel/cpu/mcheck/mce.c | 21 ++++---- arch/x86/kernel/cpu/mtrr/main.c | 10 ++-- arch/x86/kernel/i8237.c | 30 ++---------- arch/x86/kernel/i8259.c | 33 ++++--------- arch/x86/kernel/microcode_core.c | 34 +++++-------- arch/x86/kernel/pci-gart_64.c | 32 ++---------- arch/x86/oprofile/nmi_int.c | 44 ++++------------- 10 files changed, 127 insertions(+), 229 deletions(-)
arch/x86/kernel/amd_iommu_init.c +6 -20
@@ -21,7 +21,7 @@#include <linux/acpi.h> #include <linux/list.h> #include <linux/slab.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/msi.h> #include <asm/pci-direct.h>
@@ -1260,7 +1260,7 @@ static void disable_iommus(void)* disable suspend until real resume implemented */ -static int amd_iommu_resume (struct sys_device *dev) +static void amd_iommu_resume (void ) {struct amd_iommu *iommu;
@@ -1276,11 +1276,9 @@ static int amd_iommu_resume(struct sys_d*/ amd_iommu_flush_all_devices ();amd_iommu_flush_all_domains (); - -return 0 ; } -static int amd_iommu_suspend (struct sys_device *dev,pm_message_t state) +static int amd_iommu_suspend (void ) {/* disable IOMMUs to go out of the way for BIOS */ disable_iommus ();
@@ -1288,17 +1286,11 @@ static int amd_iommu_suspend(struct sys_return 0 ; } -static struct sysdev_class amd_iommu_sysdev_class = { - .name ="amd_iommu" , +static struct syscore_ops amd_iommu_syscore_ops = { .suspend = amd_iommu_suspend, .resume = amd_iommu_resume, }; -static struct sys_device device_amd_iommu = { - .id =0 , - .cls = &amd_iommu_sysdev_class, -}; -/* * This is the core init function for AMD IOMMU hardware in the system. * This function is called from the generic x86 DMA layer initialization
@@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void) goto free; } - ret =sysdev_class_register (&amd_iommu_sysdev_class); -if (ret) - goto free; - - ret =sysdev_register (&device_amd_iommu); -if (ret) - goto free; - ret =amd_iommu_init_devices ();if (ret) goto free;
@@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void)amd_iommu_init_notifier (); +register_syscore_ops (&amd_iommu_syscore_ops); +if (iommu_pass_through) goto out;
arch/x86/kernel/apic/apic.c +8 -21
@@ -24,7 +24,7 @@#include <linux/ftrace.h> #include <linux/ioport.h> #include <linux/module.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/timex.h> #include <linux/dmar.h>
@@ -2036,7 +2036,7 @@ static struct {unsigned int apic_thmr; } apic_pm_state; -static int lapic_suspend (struct sys_device *dev,pm_message_t state) +static int lapic_suspend (void ) {unsigned long flags;int maxlvt;
@@ -2074,7 +2074,7 @@ static int lapic_suspend(struct sys_devireturn 0 ; } -static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;
@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);if (intr_remapping_enabled) {
@@ -2152,8 +2152,6 @@ static int lapic_resume(struct sys_devic } restore:local_irq_restore (flags); - -return ret; }/*
@@ -2161,17 +2159,11 @@ restore:* are needed on every CPU up until machine_halt/restart/poweroff. */ -static struct sysdev_class lapic_sysclass = { - .name ="lapic" , +static struct syscore_ops lapic_syscore_ops = { .resume = lapic_resume, .suspend = lapic_suspend, }; -static struct sys_device device_lapic = { - .id =0 , - .cls = &lapic_sysclass, -}; -static void __cpuinit apic_pm_activate (void ) { apic_pm_state.active =1 ;
@@ -2179,16 +2171,11 @@ static void __cpuinit apic_pm_activate(vstatic int __init init_lapic_sysfs (void ) { -int error; - -if (!cpu_has_apic) -return 0 ;/* XXX: remove suspend/resume procs if !apic_pm_state.active? */ +if (cpu_has_apic) +register_syscore_ops (&lapic_syscore_ops); - error =sysdev_class_register (&lapic_sysclass); -if (!error) - error =sysdev_register (&device_lapic); -return error; +return 0 ; }/* local apic needs to resume before other devices access its registers. */
arch/x86/kernel/apic/io_apic.c +46 -51
142 lines not on this page · raw message
arch/x86/kernel/i8237.c +7 -23
@@ -10,7 +10,7 @@*/ #include <linux/init.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <asm/dma.h>
@@ -21,7 +21,7 @@* in asm/dma.h. */ -static int i8237A_resume (struct sys_device *dev) +static void i8237A_resume (void ) {unsigned long flags;int i;
@@ -41,31 +41,15 @@ static int i8237A_resume(struct sys_devienable_dma (4 );release_dma_lock (flags); - -return 0 ; } -static int i8237A_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class i8237_sysdev_class = { - .name ="i8237" , - .suspend = i8237A_suspend, +static struct syscore_ops i8237_syscore_ops = { .resume = i8237A_resume, }; -static struct sys_device device_i8237A = { - .id =0 , - .cls = &i8237_sysdev_class, -}; - -static int __init i8237A_init_sysfs (void ) +static int __init i8237A_init_ops (void ) { -int error =sysdev_class_register (&i8237_sysdev_class); -if (!error) - error =sysdev_register (&device_i8237A); -return error; +register_syscore_ops (&i8237_syscore_ops); +return 0 ; } -device_initcall (i8237A_init_sysfs); +device_initcall (i8237A_init_ops);
arch/x86/kernel/i8259.c +10 -23
@@ -8,7 +8,7 @@#include <linux/random.h> #include <linux/init.h> #include <linux/kernel_stat.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/bitops.h> #include <linux/acpi.h> #include <linux/io.h>
@@ -245,20 +245,19 @@ static void save_ELCR(char *trigger) trigger[1 ] =inb (0x4d1 ) &0xDE ; } -static int i8259A_resume (struct sys_device *dev) +static void i8259A_resume (void ) {init_8259A (i8259A_auto_eoi);restore_ELCR (irq_trigger); -return 0 ; } -static int i8259A_suspend (struct sys_device *dev,pm_message_t state) +static int i8259A_suspend (void ) {save_ELCR (irq_trigger);return 0 ; } -static int i8259A_shutdown (struct sys_device *dev) +static void i8259A_shutdown (void ) {/* Put the i8259A into a quiescent state that * the kernel initialization code can get it
@@ -266,21 +265,14 @@ static int i8259A_shutdown(struct sys_de*/ outb (0xff ,PIC_MASTER_IMR );/* mask all of 8259A-1 */ outb (0xff ,PIC_SLAVE_IMR );/* mask all of 8259A-1 */ -return 0 ; } -static struct sysdev_class i8259_sysdev_class = { - .name ="i8259" , +static struct syscore_ops i8259_syscore_ops = { .suspend = i8259A_suspend, .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; -static struct sys_device device_i8259A = { - .id =0 , - .cls = &i8259_sysdev_class, -}; -static void mask_8259A (void ) {unsigned long flags;
@@ -399,17 +391,12 @@ struct legacy_pic default_legacy_pic = {struct legacy_pic *legacy_pic = &default_legacy_pic; -static int __init i8259A_init_sysfs (void ) +static int __init i8259A_init_ops (void ) { -int error; - -if (legacy_pic != &default_legacy_pic) -return 0 ; +if (legacy_pic == &default_legacy_pic) +register_syscore_ops (&i8259_syscore_ops); - error =sysdev_class_register (&i8259_sysdev_class); -if (!error) - error =sysdev_register (&device_i8259A); -return error; +return 0 ; } -device_initcall (i8259A_init_sysfs); +device_initcall (i8259A_init_ops);
arch/x86/kernel/pci-gart_64.c +7 -25
@@ -27,7 +27,7 @@#include <linux/kdebug.h> #include <linux/scatterlist.h> #include <linux/iommu-helper.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/io.h> #include <linux/gfp.h> #include <asm/atomic.h>
@@ -589,7 +589,7 @@ void set_up_gart_resume(u32 aper_order, aperture_alloc = aper_alloc; } -static void gart_fixup_northbridges (struct sys_device *dev) +static void gart_fixup_northbridges (void ) {int i;
@@ -613,33 +613,20 @@ static void gart_fixup_northbridges(stru } } -static int gart_resume (struct sys_device *dev) +static void gart_resume (void ) {pr_info ("PCI-DMA: Resuming GART IOMMU\n" ); -gart_fixup_northbridges (dev); +gart_fixup_northbridges ();enable_gart_translations (); - -return 0 ; } -static int gart_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class gart_sysdev_class = { - .name ="gart" , - .suspend = gart_suspend, +static struct syscore_ops gart_syscore_ops = { .resume = gart_resume, }; -static struct sys_device device_gart = { - .cls = &gart_sysdev_class, -}; -/* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason.
@@ -650,7 +637,7 @@ static __init int init_amd_gatt(struct aunsigned aper_base, new_aper_base;struct pci_dev *dev;void *gatt; -int i, error; +int i;pr_info ("PCI-DMA: Disabling AGP.\n" );
@@ -685,12 +672,7 @@ static __init int init_amd_gatt(struct a agp_gatt_table = gatt; - error =sysdev_class_register (&gart_sysdev_class); -if (!error) - error =sysdev_register (&device_gart); -if (error) -panic ("Could not register gart_sysdev -- " -"would corrupt data on next suspend" ); +register_syscore_ops (&gart_syscore_ops);flush_gart ();
arch/x86/oprofile/nmi_int.c +12 -32
89 lines not on this page · raw message
arch/x86/kernel/cpu/mcheck/mce.c +12 -9
@@ -21,6 +21,7 @@#include <linux/percpu.h> #include <linux/string.h> #include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/ctype.h> #include <linux/sched.h>
@@ -1749,14 +1750,14 @@ static int mce_disable_error_reporting(vreturn 0 ; } -static int mce_suspend (struct sys_device *dev,pm_message_t state) +static int mce_suspend (void ) {return mce_disable_error_reporting (); } -static int mce_shutdown (struct sys_device *dev) +static void mce_shutdown (void ) { -return mce_disable_error_reporting (); +mce_disable_error_reporting (); }/*
@@ -1764,14 +1765,18 @@ static int mce_shutdown(struct sys_devic* Only one CPU is active at this time, the others get re-added later using * CPU hotplug: */ -static int mce_resume (struct sys_device *dev) +static void mce_resume (void ) {__mcheck_cpu_init_generic ();__mcheck_cpu_init_vendor (__this_cpu_ptr (&cpu_info)); - -return 0 ; } +static struct syscore_ops mce_syscore_ops = { + .suspend = mce_suspend, + .shutdown = mce_shutdown, + .resume = mce_resume, +}; +static void mce_cpu_restart (void *data) {del_timer_sync (&__get_cpu_var (mce_timer));
@@ -1808,9 +1813,6 @@ static void mce_enable_ce(void *all) }static struct sysdev_class mce_sysclass = { - .suspend = mce_suspend, - .shutdown = mce_shutdown, - .resume = mce_resume, .name ="machinecheck" , };
@@ -2139,6 +2141,7 @@ static __init int mcheck_init_device(voireturn err; } +register_syscore_ops (&mce_syscore_ops);register_hotcpu_notifier (&mce_cpu_notifier);misc_register (&mce_log_device);
arch/x86/kernel/cpu/mtrr/main.c +5 -5
@@ -45,6 +45,7 @@#include <linux/cpu.h> #include <linux/pci.h> #include <linux/smp.h> +#include <linux/syscore_ops.h> #include <asm/processor.h> #include <asm/e820.h>
@@ -630,7 +631,7 @@ struct mtrr_value {static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES ]; -static int mtrr_save (struct sys_device *sysdev,pm_message_t state) +static int mtrr_save (void ) {int i;
@@ -642,7 +643,7 @@ static int mtrr_save(struct sys_device *return 0 ; } -static int mtrr_restore (struct sys_device *sysdev) +static void mtrr_restore (void ) {int i;
@@ -653,12 +654,11 @@ static int mtrr_restore(struct sys_devic mtrr_value[i].ltype); } } -return 0 ; } -static struct sysdev_driver mtrr_sysdev_driver = { +static struct syscore_ops mtrr_syscore_ops = { .suspend = mtrr_save, .resume = mtrr_restore, };
@@ -839,7 +839,7 @@ static int __init mtrr_init_finialize(vo* TBD: is there any system with such CPU which supports * suspend/resume? If no, we should remove the code. */ -sysdev_driver_register (&cpu_sysdev_class, &mtrr_sysdev_driver); +register_syscore_ops (&mtrr_syscore_ops);return 0 ; }
arch/x86/kernel/microcode_core.c +14 -20
@@ -82,6 +82,7 @@#include <linux/cpu.h> #include <linux/fs.h> #include <linux/mm.h> +#include <linux/syscore_ops.h> #include <asm/microcode.h> #include <asm/processor.h>
@@ -436,33 +437,25 @@ static int mc_sysdev_remove(struct sys_dreturn 0 ; } -static int mc_sysdev_resume (struct sys_device *dev) +static struct sysdev_driver mc_sysdev_driver = { + .add = mc_sysdev_add, + .remove = mc_sysdev_remove, +}; + +/** +* mc_bp_resume - Update boot CPU microcode during resume. +*/ +static void mc_bp_resume (void ) { -int cpu = dev->id; +int cpu =smp_processor_id ();struct ucode_cpu_info *uci = ucode_cpu_info + cpu; -if (!cpu_online (cpu)) -return 0 ; - -/* -* All non-bootup cpus are still disabled, -* so only CPU 0 will apply ucode here. -* -* Moreover, there can be no concurrent -* updates from any other places at this point. -*/ -WARN_ON (cpu !=0 ); -if (uci->valid && uci->mc) microcode_ops->apply_microcode (cpu); - -return 0 ; } -static struct sysdev_driver mc_sysdev_driver = { - .add = mc_sysdev_add, - .remove = mc_sysdev_remove, - .resume = mc_sysdev_resume, +static struct syscore_ops mc_syscore_ops = { + .resume = mc_bp_resume, }; static __cpuinit int
@@ -540,6 +533,7 @@ static int __init microcode_init(void)if (error)return error; +register_syscore_ops (&mc_syscore_ops);register_hotcpu_notifier (&mc_cpu_notifier); pr_info("Microcode Update Driver: v" MICROCODE_VERSION
PATCH 2/8 x86: Use syscore_ops instead of sysdev classes and sysdevs
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Some subsystems in the x86 tree need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs or sysdev drivers for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct syscore_ops objects for this purpose instead.
Generally, there are three categories of subsystems that use sysdevs for implementing PM operations: (1) subsystems whose suspend/resume callbacks ignore their arguments entirely (the majority), (2) subsystems whose suspend/resume callbacks use their struct sys_device argument, but don't really need to do that, because they can be implemented differently in an arguably simpler way (io_apic.c), and (3) subsystems whose suspend/resume callbacks use their struct sys_device argument, but the value of that argument is always the same and could be ignored (microcode_core.c). In all of these cases the subsystems in question may be readily converted to using struct syscore_ops objects for power management and shutdown.
--- arch/x86/kernel/amd_iommu_init.c | 26 ++-------- arch/x86/kernel/apic/apic.c | 29 +++-------- arch/x86/kernel/apic/io_apic.c | 97 ++++++++++++++++++--------------------- arch/x86/kernel/cpu/mcheck/mce.c | 21 ++++---- arch/x86/kernel/cpu/mtrr/main.c | 10 ++-- arch/x86/kernel/i8237.c | 30 ++---------- arch/x86/kernel/i8259.c | 33 ++++--------- arch/x86/kernel/microcode_core.c | 34 +++++-------- arch/x86/kernel/pci-gart_64.c | 32 ++---------- arch/x86/oprofile/nmi_int.c | 44 ++++------------- 10 files changed, 127 insertions(+), 229 deletions(-)
arch/x86/kernel/amd_iommu_init.c +6 -20
@@ -21,7 +21,7 @@#include <linux/acpi.h> #include <linux/list.h> #include <linux/slab.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/msi.h> #include <asm/pci-direct.h>
@@ -1260,7 +1260,7 @@ static void disable_iommus(void)* disable suspend until real resume implemented */ -static int amd_iommu_resume (struct sys_device *dev) +static void amd_iommu_resume (void ) {struct amd_iommu *iommu;
@@ -1276,11 +1276,9 @@ static int amd_iommu_resume(struct sys_d*/ amd_iommu_flush_all_devices ();amd_iommu_flush_all_domains (); - -return 0 ; } -static int amd_iommu_suspend (struct sys_device *dev,pm_message_t state) +static int amd_iommu_suspend (void ) {/* disable IOMMUs to go out of the way for BIOS */ disable_iommus ();
@@ -1288,17 +1286,11 @@ static int amd_iommu_suspend(struct sys_return 0 ; } -static struct sysdev_class amd_iommu_sysdev_class = { - .name ="amd_iommu" , +static struct syscore_ops amd_iommu_syscore_ops = { .suspend = amd_iommu_suspend, .resume = amd_iommu_resume, }; -static struct sys_device device_amd_iommu = { - .id =0 , - .cls = &amd_iommu_sysdev_class, -}; -/* * This is the core init function for AMD IOMMU hardware in the system. * This function is called from the generic x86 DMA layer initialization
@@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void) goto free; } - ret =sysdev_class_register (&amd_iommu_sysdev_class); -if (ret) - goto free; - - ret =sysdev_register (&device_amd_iommu); -if (ret) - goto free; - ret =amd_iommu_init_devices ();if (ret) goto free;
@@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void)amd_iommu_init_notifier (); +register_syscore_ops (&amd_iommu_syscore_ops); +if (iommu_pass_through) goto out;
arch/x86/kernel/apic/apic.c +8 -21
@@ -24,7 +24,7 @@#include <linux/ftrace.h> #include <linux/ioport.h> #include <linux/module.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/timex.h> #include <linux/dmar.h>
@@ -2036,7 +2036,7 @@ static struct {unsigned int apic_thmr; } apic_pm_state; -static int lapic_suspend (struct sys_device *dev,pm_message_t state) +static int lapic_suspend (void ) {unsigned long flags;int maxlvt;
@@ -2074,7 +2074,7 @@ static int lapic_suspend(struct sys_devireturn 0 ; } -static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;
@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);if (intr_remapping_enabled) {
@@ -2152,8 +2152,6 @@ static int lapic_resume(struct sys_devic } restore:local_irq_restore (flags); - -return ret; }/*
@@ -2161,17 +2159,11 @@ restore:* are needed on every CPU up until machine_halt/restart/poweroff. */ -static struct sysdev_class lapic_sysclass = { - .name ="lapic" , +static struct syscore_ops lapic_syscore_ops = { .resume = lapic_resume, .suspend = lapic_suspend, }; -static struct sys_device device_lapic = { - .id =0 , - .cls = &lapic_sysclass, -}; -static void __cpuinit apic_pm_activate (void ) { apic_pm_state.active =1 ;
@@ -2179,16 +2171,11 @@ static void __cpuinit apic_pm_activate(vstatic int __init init_lapic_sysfs (void ) { -int error; - -if (!cpu_has_apic) -return 0 ;/* XXX: remove suspend/resume procs if !apic_pm_state.active? */ +if (cpu_has_apic) +register_syscore_ops (&lapic_syscore_ops); - error =sysdev_class_register (&lapic_sysclass); -if (!error) - error =sysdev_register (&device_lapic); -return error; +return 0 ; }/* local apic needs to resume before other devices access its registers. */
arch/x86/kernel/apic/io_apic.c +46 -51
142 lines not on this page · raw message
arch/x86/kernel/i8237.c +7 -23
@@ -10,7 +10,7 @@*/ #include <linux/init.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <asm/dma.h>
@@ -21,7 +21,7 @@* in asm/dma.h. */ -static int i8237A_resume (struct sys_device *dev) +static void i8237A_resume (void ) {unsigned long flags;int i;
@@ -41,31 +41,15 @@ static int i8237A_resume(struct sys_devienable_dma (4 );release_dma_lock (flags); - -return 0 ; } -static int i8237A_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class i8237_sysdev_class = { - .name ="i8237" , - .suspend = i8237A_suspend, +static struct syscore_ops i8237_syscore_ops = { .resume = i8237A_resume, }; -static struct sys_device device_i8237A = { - .id =0 , - .cls = &i8237_sysdev_class, -}; - -static int __init i8237A_init_sysfs (void ) +static int __init i8237A_init_ops (void ) { -int error =sysdev_class_register (&i8237_sysdev_class); -if (!error) - error =sysdev_register (&device_i8237A); -return error; +register_syscore_ops (&i8237_syscore_ops); +return 0 ; } -device_initcall (i8237A_init_sysfs); +device_initcall (i8237A_init_ops);
arch/x86/kernel/i8259.c +10 -23
@@ -8,7 +8,7 @@#include <linux/random.h> #include <linux/init.h> #include <linux/kernel_stat.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/bitops.h> #include <linux/acpi.h> #include <linux/io.h>
@@ -245,20 +245,19 @@ static void save_ELCR(char *trigger) trigger[1 ] =inb (0x4d1 ) &0xDE ; } -static int i8259A_resume (struct sys_device *dev) +static void i8259A_resume (void ) {init_8259A (i8259A_auto_eoi);restore_ELCR (irq_trigger); -return 0 ; } -static int i8259A_suspend (struct sys_device *dev,pm_message_t state) +static int i8259A_suspend (void ) {save_ELCR (irq_trigger);return 0 ; } -static int i8259A_shutdown (struct sys_device *dev) +static void i8259A_shutdown (void ) {/* Put the i8259A into a quiescent state that * the kernel initialization code can get it
@@ -266,21 +265,14 @@ static int i8259A_shutdown(struct sys_de*/ outb (0xff ,PIC_MASTER_IMR );/* mask all of 8259A-1 */ outb (0xff ,PIC_SLAVE_IMR );/* mask all of 8259A-1 */ -return 0 ; } -static struct sysdev_class i8259_sysdev_class = { - .name ="i8259" , +static struct syscore_ops i8259_syscore_ops = { .suspend = i8259A_suspend, .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; -static struct sys_device device_i8259A = { - .id =0 , - .cls = &i8259_sysdev_class, -}; -static void mask_8259A (void ) {unsigned long flags;
@@ -399,17 +391,12 @@ struct legacy_pic default_legacy_pic = {struct legacy_pic *legacy_pic = &default_legacy_pic; -static int __init i8259A_init_sysfs (void ) +static int __init i8259A_init_ops (void ) { -int error; - -if (legacy_pic != &default_legacy_pic) -return 0 ; +if (legacy_pic == &default_legacy_pic) +register_syscore_ops (&i8259_syscore_ops); - error =sysdev_class_register (&i8259_sysdev_class); -if (!error) - error =sysdev_register (&device_i8259A); -return error; +return 0 ; } -device_initcall (i8259A_init_sysfs); +device_initcall (i8259A_init_ops);
arch/x86/kernel/pci-gart_64.c +7 -25
@@ -27,7 +27,7 @@#include <linux/kdebug.h> #include <linux/scatterlist.h> #include <linux/iommu-helper.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/io.h> #include <linux/gfp.h> #include <asm/atomic.h>
@@ -589,7 +589,7 @@ void set_up_gart_resume(u32 aper_order, aperture_alloc = aper_alloc; } -static void gart_fixup_northbridges (struct sys_device *dev) +static void gart_fixup_northbridges (void ) {int i;
@@ -613,33 +613,20 @@ static void gart_fixup_northbridges(stru } } -static int gart_resume (struct sys_device *dev) +static void gart_resume (void ) {pr_info ("PCI-DMA: Resuming GART IOMMU\n" ); -gart_fixup_northbridges (dev); +gart_fixup_northbridges ();enable_gart_translations (); - -return 0 ; } -static int gart_suspend (struct sys_device *dev,pm_message_t state) -{ -return 0 ; -} - -static struct sysdev_class gart_sysdev_class = { - .name ="gart" , - .suspend = gart_suspend, +static struct syscore_ops gart_syscore_ops = { .resume = gart_resume, }; -static struct sys_device device_gart = { - .cls = &gart_sysdev_class, -}; -/* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason.
@@ -650,7 +637,7 @@ static __init int init_amd_gatt(struct aunsigned aper_base, new_aper_base;struct pci_dev *dev;void *gatt; -int i, error; +int i;pr_info ("PCI-DMA: Disabling AGP.\n" );
@@ -685,12 +672,7 @@ static __init int init_amd_gatt(struct a agp_gatt_table = gatt; - error =sysdev_class_register (&gart_sysdev_class); -if (!error) - error =sysdev_register (&device_gart); -if (error) -panic ("Could not register gart_sysdev -- " -"would corrupt data on next suspend" ); +register_syscore_ops (&gart_syscore_ops);flush_gart ();
arch/x86/oprofile/nmi_int.c +12 -32
89 lines not on this page · raw message
arch/x86/kernel/cpu/mcheck/mce.c +12 -9
@@ -21,6 +21,7 @@#include <linux/percpu.h> #include <linux/string.h> #include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/ctype.h> #include <linux/sched.h>
@@ -1749,14 +1750,14 @@ static int mce_disable_error_reporting(vreturn 0 ; } -static int mce_suspend (struct sys_device *dev,pm_message_t state) +static int mce_suspend (void ) {return mce_disable_error_reporting (); } -static int mce_shutdown (struct sys_device *dev) +static void mce_shutdown (void ) { -return mce_disable_error_reporting (); +mce_disable_error_reporting (); }/*
@@ -1764,14 +1765,18 @@ static int mce_shutdown(struct sys_devic* Only one CPU is active at this time, the others get re-added later using * CPU hotplug: */ -static int mce_resume (struct sys_device *dev) +static void mce_resume (void ) {__mcheck_cpu_init_generic ();__mcheck_cpu_init_vendor (__this_cpu_ptr (&cpu_info)); - -return 0 ; } +static struct syscore_ops mce_syscore_ops = { + .suspend = mce_suspend, + .shutdown = mce_shutdown, + .resume = mce_resume, +}; +static void mce_cpu_restart (void *data) {del_timer_sync (&__get_cpu_var (mce_timer));
@@ -1808,9 +1813,6 @@ static void mce_enable_ce(void *all) }static struct sysdev_class mce_sysclass = { - .suspend = mce_suspend, - .shutdown = mce_shutdown, - .resume = mce_resume, .name ="machinecheck" , };
@@ -2139,6 +2141,7 @@ static __init int mcheck_init_device(voireturn err; } +register_syscore_ops (&mce_syscore_ops);register_hotcpu_notifier (&mce_cpu_notifier);misc_register (&mce_log_device);
arch/x86/kernel/cpu/mtrr/main.c +5 -5
@@ -45,6 +45,7 @@#include <linux/cpu.h> #include <linux/pci.h> #include <linux/smp.h> +#include <linux/syscore_ops.h> #include <asm/processor.h> #include <asm/e820.h>
@@ -630,7 +631,7 @@ struct mtrr_value {static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES ]; -static int mtrr_save (struct sys_device *sysdev,pm_message_t state) +static int mtrr_save (void ) {int i;
@@ -642,7 +643,7 @@ static int mtrr_save(struct sys_device *return 0 ; } -static int mtrr_restore (struct sys_device *sysdev) +static void mtrr_restore (void ) {int i;
@@ -653,12 +654,11 @@ static int mtrr_restore(struct sys_devic mtrr_value[i].ltype); } } -return 0 ; } -static struct sysdev_driver mtrr_sysdev_driver = { +static struct syscore_ops mtrr_syscore_ops = { .suspend = mtrr_save, .resume = mtrr_restore, };
@@ -839,7 +839,7 @@ static int __init mtrr_init_finialize(vo* TBD: is there any system with such CPU which supports * suspend/resume? If no, we should remove the code. */ -sysdev_driver_register (&cpu_sysdev_class, &mtrr_sysdev_driver); +register_syscore_ops (&mtrr_syscore_ops);return 0 ; }
arch/x86/kernel/microcode_core.c +14 -20
@@ -82,6 +82,7 @@#include <linux/cpu.h> #include <linux/fs.h> #include <linux/mm.h> +#include <linux/syscore_ops.h> #include <asm/microcode.h> #include <asm/processor.h>
@@ -436,33 +437,25 @@ static int mc_sysdev_remove(struct sys_dreturn 0 ; } -static int mc_sysdev_resume (struct sys_device *dev) +static struct sysdev_driver mc_sysdev_driver = { + .add = mc_sysdev_add, + .remove = mc_sysdev_remove, +}; + +/** +* mc_bp_resume - Update boot CPU microcode during resume. +*/ +static void mc_bp_resume (void ) { -int cpu = dev->id; +int cpu =smp_processor_id ();struct ucode_cpu_info *uci = ucode_cpu_info + cpu; -if (!cpu_online (cpu)) -return 0 ; - -/* -* All non-bootup cpus are still disabled, -* so only CPU 0 will apply ucode here. -* -* Moreover, there can be no concurrent -* updates from any other places at this point. -*/ -WARN_ON (cpu !=0 ); -if (uci->valid && uci->mc) microcode_ops->apply_microcode (cpu); - -return 0 ; } -static struct sysdev_driver mc_sysdev_driver = { - .add = mc_sysdev_add, - .remove = mc_sysdev_remove, - .resume = mc_sysdev_resume, +static struct syscore_ops mc_syscore_ops = { + .resume = mc_bp_resume, }; static __cpuinit int
@@ -540,6 +533,7 @@ static int __init microcode_init(void)if (error)return error; +register_syscore_ops (&mc_syscore_ops);register_hotcpu_notifier (&mc_cpu_notifier); pr_info("Microcode Update Driver: v" MICROCODE_VERSION
Re: [PATCH 2/8] x86: Use syscore_ops instead of sysdev classes and sysdevs
arch/x86/kernel/apic/apic.c static int lapic_resume(struct sys_devic · line 2088
Quoted 13 lines · Rafael J. Wysocki
arch/x86/kernel/apic/apic.c +2
-2-static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);
That want's the following on top:
@@ -2079,8 +2079,7 @@ static void lapic_resume(void)
{
unsigned int l, h;
unsigned long flags;
- int maxlvt;
- int ret = 0;
+ int maxlvt, ret;
struct IO_APIC_route_entry **ioapic_entries = NULL;
if (!apic_pm_state.active)
@@ -2091,7 +2090,6 @@ static void lapic_resume(void)
ioapic_entries = alloc_ioapic_entries();
if (!ioapic_entries) {
WARN(1, "Alloc ioapic_entries in lapic resume failed.");
- ret = -ENOMEM;
goto restore;
}
Otherwise, Reviewed-by: Thomas Gleixner <[email protected]>
Thanks,
tglx
Re: [PATCH 2/8] x86: Use syscore_ops instead of sysdev classes and sysdevs
In reply to Rafael J. Wysockiarch/x86/kernel/apic/apic.c static int lapic_resume(struct sys_devic · line 2088
Quoted 13 lines · Rafael J. Wysocki
arch/x86/kernel/apic/apic.c +2
-2-static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);
That want's the following on top:
@@ -2079,8 +2079,7 @@ static void lapic_resume(void)
{
unsigned int l, h;
unsigned long flags;
- int maxlvt;
- int ret = 0;
+ int maxlvt, ret;
struct IO_APIC_route_entry **ioapic_entries = NULL;
if (!apic_pm_state.active)
@@ -2091,7 +2090,6 @@ static void lapic_resume(void)
ioapic_entries = alloc_ioapic_entries();
if (!ioapic_entries) {
WARN(1, "Alloc ioapic_entries in lapic resume failed.");
- ret = -ENOMEM;
goto restore;
}
Otherwise, Reviewed-by: Thomas Gleixner <[email protected]>
Thanks,
tglx
Re: [PATCH 2/8] x86: Use syscore_ops instead of sysdev classes and sysdevs
Quoted 28 lines · Thomas Gleixner
arch/x86/kernel/apic/apic.c static int lapic_resume(struct sys_devic · line 2088
Quoted 13 lines · Rafael J. Wysocki
arch/x86/kernel/apic/apic.c +2
-2-static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);That want's the following on top:
(quoted diff) +1
-2@@ -2079,8 +2079,7 @@ static void lapic_resume(void) { unsigned int l, h; unsigned long flags; - int maxlvt; - int ret = 0; + int maxlvt, ret; struct IO_APIC_route_entry **ioapic_entries = NULL; if (!apic_pm_state.active)
Review static void lapic_resume(void) · line 2094
Quoted 6 lines
(quoted diff) +0
-1@@ -2091,7 +2090,6 @@ static void lapic_resume(void) ioapic_entries = alloc_ioapic_entries(); if (!ioapic_entries) { WARN(1, "Alloc ioapic_entries in lapic resume failed."); - ret = -ENOMEM; goto restore; }
Right, I'll fold it into the final version of the patch.
Quoted 1 line
Otherwise, Reviewed-by: Thomas Gleixner <[email protected]>
Thanks!
Rafael
Re: [PATCH 2/8] x86: Use syscore_ops instead of sysdev classes and sysdevs
In reply to Thomas GleixnerQuoted 28 lines · Thomas Gleixner
arch/x86/kernel/apic/apic.c static int lapic_resume(struct sys_devic · line 2088
Quoted 13 lines · Rafael J. Wysocki
arch/x86/kernel/apic/apic.c +2
-2-static int lapic_resume (struct sys_device *dev) +static void lapic_resume (void ) {unsigned int l, h;unsigned long flags;@@ -2083,7 +2083,7 @@ static int lapic_resume(struct sys_devicstruct IO_APIC_route_entry **ioapic_entries =NULL ;if (!apic_pm_state.active) -return 0 ; +return ;local_irq_save (flags);That want's the following on top:
(quoted diff) +1
-2@@ -2079,8 +2079,7 @@ static void lapic_resume(void) { unsigned int l, h; unsigned long flags; - int maxlvt; - int ret = 0; + int maxlvt, ret; struct IO_APIC_route_entry **ioapic_entries = NULL; if (!apic_pm_state.active)
Review static void lapic_resume(void) · line 2094
Quoted 6 lines
(quoted diff) +0
-1@@ -2091,7 +2090,6 @@ static void lapic_resume(void) ioapic_entries = alloc_ioapic_entries(); if (!ioapic_entries) { WARN(1, "Alloc ioapic_entries in lapic resume failed."); - ret = -ENOMEM; goto restore; }
Right, I'll fold it into the final version of the patch.
Quoted 1 line
Otherwise, Reviewed-by: Thomas Gleixner <[email protected]>
Thanks!
Rafael
PATCH 3/8 ACPI: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
ACPI uses a sysdev class and a sysdev for executing irqrouter_resume() before turning on interrupts on the boot CPU. However, since irqrouter_resume() ignores its argument, the entire mechanism may be replaced with a struct syscore_ops object which is considerably simpler.
--- drivers/acpi/pci_link.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-)
drivers/acpi/pci_link.c +8 -22
@@ -29,7 +29,7 @@* for IRQ management (e.g. start()->_SRS). */ -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h>
@@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct areturn 0 ; } -static int irqrouter_resume (struct sys_device *dev) +static void irqrouter_resume (void ) {struct acpi_pci_link *link;list_for_each_entry (link, &acpi_link_list, list) {acpi_pci_link_resume (link); } -return 0 ; }static int acpi_pci_link_remove (struct acpi_device *device,int type)
@@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(c__setup ("acpi_irq_balance" , acpi_irq_balance_set); -/* FIXME: we will remove this interface after all drivers call pci_disable_device */ -static struct sysdev_class irqrouter_sysdev_class = { - .name ="irqrouter" , +static struct syscore_ops irqrouter_syscore_ops = { .resume = irqrouter_resume, }; -static struct sys_device device_irqrouter = { - .id =0 , - .cls = &irqrouter_sysdev_class, -}; - -static int __init irqrouter_init_sysfs (void ) +static int __init irqrouter_init_ops (void ) { -int error; +if (!acpi_disabled && !acpi_noirq) +register_syscore_ops (&irqrouter_syscore_ops); -if (acpi_disabled || acpi_noirq) -return 0 ; - - error =sysdev_class_register (&irqrouter_sysdev_class); -if (!error) - error =sysdev_register (&device_irqrouter); - -return error; +return 0 ; } -device_initcall (irqrouter_init_sysfs); +device_initcall (irqrouter_init_ops);static int __init acpi_pci_link_init (void ) {
PATCH 3/8 ACPI: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
ACPI uses a sysdev class and a sysdev for executing irqrouter_resume() before turning on interrupts on the boot CPU. However, since irqrouter_resume() ignores its argument, the entire mechanism may be replaced with a struct syscore_ops object which is considerably simpler.
--- drivers/acpi/pci_link.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-)
drivers/acpi/pci_link.c +8 -22
@@ -29,7 +29,7 @@* for IRQ management (e.g. start()->_SRS). */ -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h>
@@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct areturn 0 ; } -static int irqrouter_resume (struct sys_device *dev) +static void irqrouter_resume (void ) {struct acpi_pci_link *link;list_for_each_entry (link, &acpi_link_list, list) {acpi_pci_link_resume (link); } -return 0 ; }static int acpi_pci_link_remove (struct acpi_device *device,int type)
@@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(c__setup ("acpi_irq_balance" , acpi_irq_balance_set); -/* FIXME: we will remove this interface after all drivers call pci_disable_device */ -static struct sysdev_class irqrouter_sysdev_class = { - .name ="irqrouter" , +static struct syscore_ops irqrouter_syscore_ops = { .resume = irqrouter_resume, }; -static struct sys_device device_irqrouter = { - .id =0 , - .cls = &irqrouter_sysdev_class, -}; - -static int __init irqrouter_init_sysfs (void ) +static int __init irqrouter_init_ops (void ) { -int error; +if (!acpi_disabled && !acpi_noirq) +register_syscore_ops (&irqrouter_syscore_ops); -if (acpi_disabled || acpi_noirq) -return 0 ; - - error =sysdev_class_register (&irqrouter_sysdev_class); -if (!error) - error =sysdev_register (&device_irqrouter); - -return error; +return 0 ; } -device_initcall (irqrouter_init_sysfs); +device_initcall (irqrouter_init_ops);static int __init acpi_pci_link_init (void ) {
Re: [PATCH 3/8] ACPI: Use syscore_ops instead of sysdev class and sysdev
applied
thanks,
Len Brown, Intel Open Source Technology Center
PATCH 4/8 timekeeping: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
The timekeeping subsystem uses a sysdev class and a sysdev for executing timekeeping_suspend() after interrupts have been turned off on the boot CPU (during system suspend) and for executing timekeeping_resume() before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a struct syscore_ops object which is simpler.
--- kernel/time/timekeeping.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-)
kernel/time/timekeeping.c +8 -19
@@ -14,7 +14,7 @@#include <linux/init.h> #include <linux/mm.h> #include <linux/sched.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/clocksource.h> #include <linux/jiffies.h> #include <linux/time.h>
@@ -561,13 +561,12 @@ static struct timespec timekeeping_suspe/** * timekeeping_resume - Resumes the generic timekeeping subsystem. -* @dev: unused * * This is for the generic clocksource timekeeping. * xtime/wall_to_monotonic/jiffies/etc are * still managed by arch specific suspend/resume code. */ -static int timekeeping_resume (struct sys_device *dev) +static void timekeeping_resume (void ) {unsigned long flags;struct timespec ts;
@@ -596,11 +595,9 @@ static int timekeeping_resume(struct sys/* Resume hrtimers */ hres_timers_resume (); - -return 0 ; } -static int timekeeping_suspend (struct sys_device *dev,pm_message_t state) +static int timekeeping_suspend (void ) {unsigned long flags;
@@ -618,26 +615,18 @@ static int timekeeping_suspend(struct sy }/* sysfs resume/suspend bits for timekeeping */ -static struct sysdev_class timekeeping_sysclass = { - .name ="timekeeping" , +static struct syscore_ops timekeeping_syscore_ops = { .resume = timekeeping_resume, .suspend = timekeeping_suspend, }; -static struct sys_device device_timer = { - .id =0 , - .cls = &timekeeping_sysclass, -}; - -static int __init timekeeping_init_device (void ) +static int __init timekeeping_init_ops (void ) { -int error =sysdev_class_register (&timekeeping_sysclass); -if (!error) - error =sysdev_register (&device_timer); -return error; +register_syscore_ops (&timekeeping_syscore_ops); +return 0 ; } -device_initcall (timekeeping_init_device); +device_initcall (timekeeping_init_ops);/* * If the error is already larger, we look ahead even further
PATCH 4/8 timekeeping: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
The timekeeping subsystem uses a sysdev class and a sysdev for executing timekeeping_suspend() after interrupts have been turned off on the boot CPU (during system suspend) and for executing timekeeping_resume() before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a struct syscore_ops object which is simpler.
--- kernel/time/timekeeping.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-)
kernel/time/timekeeping.c +8 -19
@@ -14,7 +14,7 @@#include <linux/init.h> #include <linux/mm.h> #include <linux/sched.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/clocksource.h> #include <linux/jiffies.h> #include <linux/time.h>
@@ -561,13 +561,12 @@ static struct timespec timekeeping_suspe/** * timekeeping_resume - Resumes the generic timekeeping subsystem. -* @dev: unused * * This is for the generic clocksource timekeeping. * xtime/wall_to_monotonic/jiffies/etc are * still managed by arch specific suspend/resume code. */ -static int timekeeping_resume (struct sys_device *dev) +static void timekeeping_resume (void ) {unsigned long flags;struct timespec ts;
@@ -596,11 +595,9 @@ static int timekeeping_resume(struct sys/* Resume hrtimers */ hres_timers_resume (); - -return 0 ; } -static int timekeeping_suspend (struct sys_device *dev,pm_message_t state) +static int timekeeping_suspend (void ) {unsigned long flags;
@@ -618,26 +615,18 @@ static int timekeeping_suspend(struct sy }/* sysfs resume/suspend bits for timekeeping */ -static struct sysdev_class timekeeping_sysclass = { - .name ="timekeeping" , +static struct syscore_ops timekeeping_syscore_ops = { .resume = timekeeping_resume, .suspend = timekeeping_suspend, }; -static struct sys_device device_timer = { - .id =0 , - .cls = &timekeeping_sysclass, -}; - -static int __init timekeeping_init_device (void ) +static int __init timekeeping_init_ops (void ) { -int error =sysdev_class_register (&timekeeping_sysclass); -if (!error) - error =sysdev_register (&device_timer); -return error; +register_syscore_ops (&timekeeping_syscore_ops); +return 0 ; } -device_initcall (timekeeping_init_device); +device_initcall (timekeeping_init_ops);/* * If the error is already larger, we look ahead even further
Re: [PATCH 4/8] timekeeping: Use syscore_ops instead of sysdev class and sysdev
Quoted 11 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
The timekeeping subsystem uses a sysdev class and a sysdev for executing
timekeeping_suspend()after interrupts have been turned off on the boot CPU (during system suspend) and for executingtimekeeping_resume()before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a structsyscore_opsobject which is simpler.Signed-off-by Rafael J. Wysocki <[email protected]>
Re: [PATCH 4/8] timekeeping: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 11 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
The timekeeping subsystem uses a sysdev class and a sysdev for executing
timekeeping_suspend()after interrupts have been turned off on the boot CPU (during system suspend) and for executingtimekeeping_resume()before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a structsyscore_opsobject which is simpler.Signed-off-by Rafael J. Wysocki <[email protected]>
Re: [PATCH 4/8] timekeeping: Use syscore_ops instead of sysdev class and sysdev
Quoted 11 lines · Thomas Gleixner
Quoted 10 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
The timekeeping subsystem uses a sysdev class and a sysdev for executing
timekeeping_suspend()after interrupts have been turned off on the boot CPU (during system suspend) and for executingtimekeeping_resume()before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a structsyscore_opsobject which is simpler.
Quoted 3 lines
Quoted 1 line
Signed-off-by Rafael J. Wysocki <[email protected]>Reviewed-by Thomas Gleixner <[email protected]>
Thanks!
Rafael
Re: [PATCH 4/8] timekeeping: Use syscore_ops instead of sysdev class and sysdev
In reply to Thomas GleixnerQuoted 11 lines · Thomas Gleixner
Quoted 10 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
The timekeeping subsystem uses a sysdev class and a sysdev for executing
timekeeping_suspend()after interrupts have been turned off on the boot CPU (during system suspend) and for executingtimekeeping_resume()before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a structsyscore_opsobject which is simpler.
Quoted 3 lines
Quoted 1 line
Signed-off-by Rafael J. Wysocki <[email protected]>Reviewed-by Thomas Gleixner <[email protected]>
Thanks!
Rafael
PATCH 5/8 PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
The Intel IOMMU subsystem uses a sysdev class and a sysdev for executing iommu_suspend() after interrupts have been turned off on the boot CPU (during system suspend) and for executing iommu_resume() before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a struct syscore_ops object which is simpler.
--- drivers/pci/intel-iommu.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-)
drivers/pci/intel-iommu.c +9 -29
@@ -36,7 +36,7 @@#include <linux/iova.h> #include <linux/iommu.h> #include <linux/intel-iommu.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/tboot.h> #include <linux/dmi.h> #include <asm/cacheflush.h>
@@ -3135,7 +3135,7 @@ static void iommu_flush_all(void) } } -static int iommu_suspend (struct sys_device *dev,pm_message_t state) +static int iommu_suspend (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3175,7 +3175,7 @@ nomem:return -ENOMEM ; } -static int iommu_resume (struct sys_device *dev) +static void iommu_resume (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3183,7 +3183,7 @@ static int iommu_resume(struct sys_devicif (init_iommu_hw ()) {WARN (1 ,"IOMMU setup failed, DMAR can not resume!\n" ); -return -EIO ; +return ; }for_each_active_iommu (iommu, drhd) {
@@ -3204,40 +3204,20 @@ static int iommu_resume(struct sys_devicfor_each_active_iommu (iommu, drhd) kfree(iommu->iommu_state); - - return 0; } -static struct sysdev_class iommu_sysclass = { - .name ="iommu" , +static struct syscore_ops iommu_syscore_ops = { .resume = iommu_resume, .suspend = iommu_suspend, }; -static struct sys_device device_iommu = { - .cls = &iommu_sysclass, -}; - -static int __init init_iommu_sysfs (void ) +static void __init init_iommu_pm_ops (void ) { -int error; - - error =sysdev_class_register (&iommu_sysclass); -if (error) -return error; - - error =sysdev_register (&device_iommu); -if (error) -sysdev_class_unregister (&iommu_sysclass); - -return error; +register_syscore_ops (&iommu_syscore_ops); }#else -static int __init init_iommu_sysfs (void ) -{ -return 0 ; -} +static inline int init_iommu_pm_ops (void ) { }#endif /* CONFIG_PM */ /*
@@ -3320,7 +3300,7 @@ int __init intel_iommu_init(void)#endif dma_ops = &intel_dma_ops; -init_iommu_sysfs (); +init_iommu_pm_ops ();register_iommu (&intel_iommu_ops);
PATCH 5/8 PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
The Intel IOMMU subsystem uses a sysdev class and a sysdev for executing iommu_suspend() after interrupts have been turned off on the boot CPU (during system suspend) and for executing iommu_resume() before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a struct syscore_ops object which is simpler.
--- drivers/pci/intel-iommu.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-)
drivers/pci/intel-iommu.c +9 -29
@@ -36,7 +36,7 @@#include <linux/iova.h> #include <linux/iommu.h> #include <linux/intel-iommu.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/tboot.h> #include <linux/dmi.h> #include <asm/cacheflush.h>
@@ -3135,7 +3135,7 @@ static void iommu_flush_all(void) } } -static int iommu_suspend (struct sys_device *dev,pm_message_t state) +static int iommu_suspend (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3175,7 +3175,7 @@ nomem:return -ENOMEM ; } -static int iommu_resume (struct sys_device *dev) +static void iommu_resume (void ) {struct dmar_drhd_unit *drhd;struct intel_iommu *iommu =NULL ;
@@ -3183,7 +3183,7 @@ static int iommu_resume(struct sys_devicif (init_iommu_hw ()) {WARN (1 ,"IOMMU setup failed, DMAR can not resume!\n" ); -return -EIO ; +return ; }for_each_active_iommu (iommu, drhd) {
@@ -3204,40 +3204,20 @@ static int iommu_resume(struct sys_devicfor_each_active_iommu (iommu, drhd) kfree(iommu->iommu_state); - - return 0; } -static struct sysdev_class iommu_sysclass = { - .name ="iommu" , +static struct syscore_ops iommu_syscore_ops = { .resume = iommu_resume, .suspend = iommu_suspend, }; -static struct sys_device device_iommu = { - .cls = &iommu_sysclass, -}; - -static int __init init_iommu_sysfs (void ) +static void __init init_iommu_pm_ops (void ) { -int error; - - error =sysdev_class_register (&iommu_sysclass); -if (error) -return error; - - error =sysdev_register (&device_iommu); -if (error) -sysdev_class_unregister (&iommu_sysclass); - -return error; +register_syscore_ops (&iommu_syscore_ops); }#else -static int __init init_iommu_sysfs (void ) -{ -return 0 ; -} +static inline int init_iommu_pm_ops (void ) { }#endif /* CONFIG_PM */ /*
@@ -3320,7 +3300,7 @@ int __init intel_iommu_init(void)#endif dma_ops = &intel_dma_ops; -init_iommu_sysfs (); +init_iommu_pm_ops ();register_iommu (&intel_iommu_ops);
Re: [PATCH 5/8] PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
Quoted 6 lines · Rafael J. Wysocki
drivers/pci/intel-iommu.c +1
-4-static int __init init_iommu_sysfs (void ) -{ - return 0; -} +static inline int init_iommu_pm_ops (void ) { }#endif /*
CONFIG_PM*/
drivers/pci/intel-iommu.c:3391: warning: no return statement in function returning non-void
s/static inline int/static inline void/
-Tony
Re: [PATCH 5/8] PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 6 lines · Rafael J. Wysocki
drivers/pci/intel-iommu.c +1
-4-static int __init init_iommu_sysfs (void ) -{ - return 0; -} +static inline int init_iommu_pm_ops (void ) { }#endif /*
CONFIG_PM*/
drivers/pci/intel-iommu.c:3391: warning: no return statement in function returning non-void
s/static inline int/static inline void/
-Tony
Re: [PATCH 5/8] PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
Quoted 11 lines · Tony Luck
Review
Quoted 6 lines · Rafael J. Wysocki
(quoted diff) +1
-4-static int __init init_iommu_sysfs(void) -{ - return 0; -} +static inline int init_iommu_pm_ops(void) { } #endif /* CONFIG_PM */
drivers/pci/intel-iommu.c:3391: warning: no return statement in function returning non-void
Quoted 3 lines
s/static inline int/static inline void/
Reported-by Tony Luck <[email protected]>
I guess you mean the following?
Rafael
---
From: Rafael J. Wysocki <[email protected]>
If CONFIG_PM is not set, init_iommu_pm_ops() introduced by commit 134fac3f457f3dd753ecdb25e6da3e5f6629f696 (PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev) is not defined appropriately. Fix this issue.
--- drivers/pci/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/intel-iommu.c +1 -1
@@ -3388,7 +3388,7 @@ static void __init init_iommu_pm_ops(voi }#else -static inline int init_iommu_pm_ops (void ) { } +static inline void init_iommu_pm_ops (void ) {}#endif /* CONFIG_PM */ /*
Re: [PATCH 5/8] PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
Quoted 1 line
I guess you mean the following?
Rafael
Exactly.
Thanks
-Tony
---
From: Rafael J. Wysocki <[email protected]>
If CONFIG_PM is not set, init_iommu_pm_ops() introduced by commit 134fac3f457f3dd753ecdb25e6da3e5f6629f696 (PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev) is not defined appropriately. Fix this issue.
--- drivers/pci/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/intel-iommu.c +1 -1
@@ -3388,7 +3388,7 @@ static void __init init_iommu_pm_ops(voi }#else -static inline int init_iommu_pm_ops (void ) { } +static inline void init_iommu_pm_ops (void ) {}#endif /* CONFIG_PM */ /*
RE: [PATCH 5/8] PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 1 line
I guess you mean the following?
Rafael
Exactly.
Thanks
-Tony
---
From: Rafael J. Wysocki <[email protected]>
If CONFIG_PM is not set, init_iommu_pm_ops() introduced by commit 134fac3f457f3dd753ecdb25e6da3e5f6629f696 (PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev) is not defined appropriately. Fix this issue.
--- drivers/pci/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/intel-iommu.c +1 -1
@@ -3388,7 +3388,7 @@ static void __init init_iommu_pm_ops(voi }#else -static inline int init_iommu_pm_ops (void ) { } +static inline void init_iommu_pm_ops (void ) {}#endif /* CONFIG_PM */ /*
Re: [PATCH 5/8] PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev
In reply to Tony LuckQuoted 11 lines · Tony Luck
Review
Quoted 6 lines · Rafael J. Wysocki
(quoted diff) +1
-4-static int __init init_iommu_sysfs(void) -{ - return 0; -} +static inline int init_iommu_pm_ops(void) { } #endif /* CONFIG_PM */
drivers/pci/intel-iommu.c:3391: warning: no return statement in function returning non-void
Quoted 3 lines
s/static inline int/static inline void/
Reported-by Tony Luck <[email protected]>
I guess you mean the following?
Rafael
---
From: Rafael J. Wysocki <[email protected]>
If CONFIG_PM is not set, init_iommu_pm_ops() introduced by commit 134fac3f457f3dd753ecdb25e6da3e5f6629f696 (PCI / Intel IOMMU: Use syscore_ops instead of sysdev class and sysdev) is not defined appropriately. Fix this issue.
--- drivers/pci/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/intel-iommu.c +1 -1
@@ -3388,7 +3388,7 @@ static void __init init_iommu_pm_ops(voi }#else -static inline int init_iommu_pm_ops (void ) { } +static inline void init_iommu_pm_ops (void ) {}#endif /* CONFIG_PM */ /*
PATCH 6/8 KVM: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
KVM uses a sysdev class and a sysdev for executing kvm_suspend() after interrupts have been turned off on the boot CPU (during system suspend) and for executing kvm_resume() before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a struct syscore_ops object which is simpler.
--- virt/kvm/kvm_main.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-)
virt/kvm/kvm_main.c +8 -26
@@ -30,7 +30,7 @@#include <linux/debugfs.h> #include <linux/highmem.h> #include <linux/file.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/cpu.h> #include <linux/sched.h> #include <linux/cpumask.h>
@@ -2392,33 +2392,26 @@ static void kvm_exit_debug(void)debugfs_remove (kvm_debugfs_dir); } -static int kvm_suspend (struct sys_device *dev,pm_message_t state) +static int kvm_suspend (void ) {if (kvm_usage_count)hardware_disable_nolock (NULL );return 0 ; } -static int kvm_resume (struct sys_device *dev) +static void kvm_resume (void ) {if (kvm_usage_count) {WARN_ON (spin_is_locked (&kvm_lock));hardware_enable_nolock (NULL ); } -return 0 ; } -static struct sysdev_class kvm_sysdev_class = { - .name ="kvm" , +static struct syscore_ops kvm_syscore_ops = { .suspend = kvm_suspend, .resume = kvm_resume, }; -static struct sys_device kvm_sysdev = { - .id =0 , - .cls = &kvm_sysdev_class, -}; -struct page *bad_page;pfn_t bad_pfn;
@@ -2502,14 +2495,6 @@ int kvm_init(void *opaque, unsigned vcpu goto out_free_2;register_reboot_notifier (&kvm_reboot_notifier); - r =sysdev_class_register (&kvm_sysdev_class); -if (r) - goto out_free_3; - - r =sysdev_register (&kvm_sysdev); -if (r) - goto out_free_4; -/* A kmem cache lets us meet the alignment requirements of fx_save. */ if (!vcpu_align) vcpu_align = __alignof__(struct kvm_vcpu );
@@ -2517,7 +2502,7 @@ int kvm_init(void *opaque, unsigned vcpu 0, NULL);if (!kvm_vcpu_cache) { r = -ENOMEM ; - goto out_free_5; + goto out_free_3; } r =kvm_async_pf_init ();
@@ -2534,6 +2519,8 @@ int kvm_init(void *opaque, unsigned vcpu goto out_unreg; } +register_syscore_ops (&kvm_syscore_ops); + kvm_preempt_ops.sched_in = kvm_sched_in; kvm_preempt_ops.sched_out = kvm_sched_out;
@@ -2545,10 +2532,6 @@ out_unreg:kvm_async_pf_deinit (); out_free:kmem_cache_destroy (kvm_vcpu_cache); -out_free_5: -sysdev_unregister (&kvm_sysdev); -out_free_4: -sysdev_class_unregister (&kvm_sysdev_class); out_free_3:unregister_reboot_notifier (&kvm_reboot_notifier);unregister_cpu_notifier (&kvm_cpu_notifier);
@@ -2576,8 +2559,7 @@ void kvm_exit(void)misc_deregister (&kvm_dev);kmem_cache_destroy (kvm_vcpu_cache);kvm_async_pf_deinit (); -sysdev_unregister (&kvm_sysdev); -sysdev_class_unregister (&kvm_sysdev_class); +unregister_syscore_ops (&kvm_syscore_ops);unregister_reboot_notifier (&kvm_reboot_notifier);unregister_cpu_notifier (&kvm_cpu_notifier);on_each_cpu (hardware_disable_nolock,NULL ,1 );
PATCH 6/8 KVM: Use syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
KVM uses a sysdev class and a sysdev for executing kvm_suspend() after interrupts have been turned off on the boot CPU (during system suspend) and for executing kvm_resume() before turning on interrupts on the boot CPU (during system resume). However, since both of these functions ignore their arguments, the entire mechanism may be replaced with a struct syscore_ops object which is simpler.
--- virt/kvm/kvm_main.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-)
virt/kvm/kvm_main.c +8 -26
@@ -30,7 +30,7 @@#include <linux/debugfs.h> #include <linux/highmem.h> #include <linux/file.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/cpu.h> #include <linux/sched.h> #include <linux/cpumask.h>
@@ -2392,33 +2392,26 @@ static void kvm_exit_debug(void)debugfs_remove (kvm_debugfs_dir); } -static int kvm_suspend (struct sys_device *dev,pm_message_t state) +static int kvm_suspend (void ) {if (kvm_usage_count)hardware_disable_nolock (NULL );return 0 ; } -static int kvm_resume (struct sys_device *dev) +static void kvm_resume (void ) {if (kvm_usage_count) {WARN_ON (spin_is_locked (&kvm_lock));hardware_enable_nolock (NULL ); } -return 0 ; } -static struct sysdev_class kvm_sysdev_class = { - .name ="kvm" , +static struct syscore_ops kvm_syscore_ops = { .suspend = kvm_suspend, .resume = kvm_resume, }; -static struct sys_device kvm_sysdev = { - .id =0 , - .cls = &kvm_sysdev_class, -}; -struct page *bad_page;pfn_t bad_pfn;
@@ -2502,14 +2495,6 @@ int kvm_init(void *opaque, unsigned vcpu goto out_free_2;register_reboot_notifier (&kvm_reboot_notifier); - r =sysdev_class_register (&kvm_sysdev_class); -if (r) - goto out_free_3; - - r =sysdev_register (&kvm_sysdev); -if (r) - goto out_free_4; -/* A kmem cache lets us meet the alignment requirements of fx_save. */ if (!vcpu_align) vcpu_align = __alignof__(struct kvm_vcpu );
@@ -2517,7 +2502,7 @@ int kvm_init(void *opaque, unsigned vcpu 0, NULL);if (!kvm_vcpu_cache) { r = -ENOMEM ; - goto out_free_5; + goto out_free_3; } r =kvm_async_pf_init ();
@@ -2534,6 +2519,8 @@ int kvm_init(void *opaque, unsigned vcpu goto out_unreg; } +register_syscore_ops (&kvm_syscore_ops); + kvm_preempt_ops.sched_in = kvm_sched_in; kvm_preempt_ops.sched_out = kvm_sched_out;
@@ -2545,10 +2532,6 @@ out_unreg:kvm_async_pf_deinit (); out_free:kmem_cache_destroy (kvm_vcpu_cache); -out_free_5: -sysdev_unregister (&kvm_sysdev); -out_free_4: -sysdev_class_unregister (&kvm_sysdev_class); out_free_3:unregister_reboot_notifier (&kvm_reboot_notifier);unregister_cpu_notifier (&kvm_cpu_notifier);
@@ -2576,8 +2559,7 @@ void kvm_exit(void)misc_deregister (&kvm_dev);kmem_cache_destroy (kvm_vcpu_cache);kvm_async_pf_deinit (); -sysdev_unregister (&kvm_sysdev); -sysdev_class_unregister (&kvm_sysdev_class); +unregister_syscore_ops (&kvm_syscore_ops);unregister_reboot_notifier (&kvm_reboot_notifier);unregister_cpu_notifier (&kvm_cpu_notifier);on_each_cpu (hardware_disable_nolock,NULL ,1 );
PATCH 7/8 cpufreq: Use syscore_ops for boot CPU suspend/resume
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
The cpufreq subsystem uses sysdev suspend and resume for executing cpufreq_suspend() and cpufreq_resume(), respectively, during system suspend, after interrupts have been switched off on the boot CPU, and during system resume, while interrupts are still off on the boot CPU. In both cases the other CPUs are off-line at the relevant point (either they have been switched off via CPU hotplug during suspend, or they haven't been switched on yet during resume). For this reason, although it may seem that cpufreq_suspend() and cpufreq_resume() are executed for all CPUs in the system, they are only called for the boot CPU in fact, which is quite confusing.
To remove the confusion and to prepare for elimiating sysdev suspend and resume operations from the kernel enirely, convernt cpufreq to using a struct syscore_ops object for the boot CPU suspend and resume and rename the callbacks so that their names reflect their purpose. In addition, put some explanatory remarks into their kerneldoc comments.
--- drivers/cpufreq/cpufreq.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-)
drivers/cpufreq/cpufreq.c +23 -20
@@ -28,6 +28,7 @@#include <linux/cpu.h> #include <linux/completion.h> #include <linux/mutex.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h>
@@ -1340,23 +1341,27 @@ out: }EXPORT_SYMBOL (cpufreq_get); +static struct sysdev_driver cpufreq_sysdev_driver = { + .add = cpufreq_add_dev, + .remove = cpufreq_remove_dev, +}; +/** -* cpufreq_suspend - let the low level driver prepare for suspend +* cpufreq_bp_suspend - Prepare the boot CPU for system suspend. +* +* This function is only executed for the boot processor. The other CPUs +* have been put offline by means of CPU hotplug. */ - -static int cpufreq_suspend (struct sys_device *sysdev,pm_message_t pmsg) +static int cpufreq_bp_suspend (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("suspending cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; -/* we may be lax here as interrupts are off. Nonetheless * we need to grab the correct cpu policy, as to check * whether we really run on this CPU.
@@ -1383,7 +1388,7 @@ out: }/** -* cpufreq_resume - restore proper CPU frequency handling after resume +* cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. * * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
@@ -1391,19 +1396,19 @@ out:* what we believe it to be. This is a bit later than when it * should be, but nonethteless it's better than calling * cpufreq_driver->get() here which might re-enable interrupts... +* +* This function is only executed for the boot CPU. The other CPUs have not +* been turned on yet. */ -static int cpufreq_resume (struct sys_device *sysdev) +static void cpufreq_bp_resume (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("resuming cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; -/* we may be lax here as interrupts are off. Nonetheless * we need to grab the correct cpu policy, as to check * whether we really run on this CPU.
@@ -1411,7 +1416,7 @@ static int cpufreq_resume(struct sys_dev cpu_policy =cpufreq_cpu_get (cpu);if (!cpu_policy) -return -EINVAL ; +return ;/* only handle each CPU group once */ if (unlikely (cpu_policy->cpu != cpu))
@@ -1430,14 +1435,11 @@ static int cpufreq_resume(struct sys_dev fail:cpufreq_cpu_put (cpu_policy); -return ret; } -static struct sysdev_driver cpufreq_sysdev_driver = { - .add = cpufreq_add_dev, - .remove = cpufreq_remove_dev, - .suspend = cpufreq_suspend, - .resume = cpufreq_resume, +static struct syscore_ops cpufreq_syscore_ops = { + .suspend = cpufreq_bp_suspend, + .resume = cpufreq_bp_resume, };
@@ -2002,6 +2004,7 @@ static int __init cpufreq_core_init(void cpufreq_global_kobject =kobject_create_and_add ("cpufreq" , &cpu_sysdev_class.kset.kobj);BUG_ON (!cpufreq_global_kobject); +register_syscore_ops (&cpufreq_syscore_ops);return 0 ; }
PATCH 7/8 cpufreq: Use syscore_ops for boot CPU suspend/resume
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
The cpufreq subsystem uses sysdev suspend and resume for executing cpufreq_suspend() and cpufreq_resume(), respectively, during system suspend, after interrupts have been switched off on the boot CPU, and during system resume, while interrupts are still off on the boot CPU. In both cases the other CPUs are off-line at the relevant point (either they have been switched off via CPU hotplug during suspend, or they haven't been switched on yet during resume). For this reason, although it may seem that cpufreq_suspend() and cpufreq_resume() are executed for all CPUs in the system, they are only called for the boot CPU in fact, which is quite confusing.
To remove the confusion and to prepare for elimiating sysdev suspend and resume operations from the kernel enirely, convernt cpufreq to using a struct syscore_ops object for the boot CPU suspend and resume and rename the callbacks so that their names reflect their purpose. In addition, put some explanatory remarks into their kerneldoc comments.
--- drivers/cpufreq/cpufreq.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-)
drivers/cpufreq/cpufreq.c +23 -20
@@ -28,6 +28,7 @@#include <linux/cpu.h> #include <linux/completion.h> #include <linux/mutex.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h>
@@ -1340,23 +1341,27 @@ out: }EXPORT_SYMBOL (cpufreq_get); +static struct sysdev_driver cpufreq_sysdev_driver = { + .add = cpufreq_add_dev, + .remove = cpufreq_remove_dev, +}; +/** -* cpufreq_suspend - let the low level driver prepare for suspend +* cpufreq_bp_suspend - Prepare the boot CPU for system suspend. +* +* This function is only executed for the boot processor. The other CPUs +* have been put offline by means of CPU hotplug. */ - -static int cpufreq_suspend (struct sys_device *sysdev,pm_message_t pmsg) +static int cpufreq_bp_suspend (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("suspending cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; -/* we may be lax here as interrupts are off. Nonetheless * we need to grab the correct cpu policy, as to check * whether we really run on this CPU.
@@ -1383,7 +1388,7 @@ out: }/** -* cpufreq_resume - restore proper CPU frequency handling after resume +* cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. * * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
@@ -1391,19 +1396,19 @@ out:* what we believe it to be. This is a bit later than when it * should be, but nonethteless it's better than calling * cpufreq_driver->get() here which might re-enable interrupts... +* +* This function is only executed for the boot CPU. The other CPUs have not +* been turned on yet. */ -static int cpufreq_resume (struct sys_device *sysdev) +static void cpufreq_bp_resume (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("resuming cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; -/* we may be lax here as interrupts are off. Nonetheless * we need to grab the correct cpu policy, as to check * whether we really run on this CPU.
@@ -1411,7 +1416,7 @@ static int cpufreq_resume(struct sys_dev cpu_policy =cpufreq_cpu_get (cpu);if (!cpu_policy) -return -EINVAL ; +return ;/* only handle each CPU group once */ if (unlikely (cpu_policy->cpu != cpu))
@@ -1430,14 +1435,11 @@ static int cpufreq_resume(struct sys_dev fail:cpufreq_cpu_put (cpu_policy); -return ret; } -static struct sysdev_driver cpufreq_sysdev_driver = { - .add = cpufreq_add_dev, - .remove = cpufreq_remove_dev, - .suspend = cpufreq_suspend, - .resume = cpufreq_resume, +static struct syscore_ops cpufreq_syscore_ops = { + .suspend = cpufreq_bp_suspend, + .resume = cpufreq_bp_resume, };
@@ -2002,6 +2004,7 @@ static int __init cpufreq_core_init(void cpufreq_global_kobject =kobject_create_and_add ("cpufreq" , &cpu_sysdev_class.kset.kobj);BUG_ON (!cpufreq_global_kobject); +register_syscore_ops (&cpufreq_syscore_ops);return 0 ; }
[Update, v2] Re: [PATCH 7/8] cpufreq: Use syscore_ops for boot CPU suspend/resume
Quoted 13 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
The cpufreq subsystem uses sysdev suspend and resume for executing
cpufreq_suspend()andcpufreq_resume(), respectively, during system suspend, after interrupts have been switched off on the boot CPU, and during system resume, while interrupts are still off on the boot CPU. In both cases the other CPUs are off-line at the relevant point (either they have been switched off via CPU hotplug during suspend, or they haven't been switched on yet during resume). For this reason, although it may seem thatcpufreq_suspend()andcpufreq_resume()are executed for all CPUs in the system, they are only called for the boot CPU in fact, which is quite confusing.
Quoted 6 lines
To remove the confusion and to prepare for elimiating sysdev suspend and resume operations from the kernel enirely, convernt cpufreq to using a struct
syscore_opsobject for the boot CPU suspend and resume and rename the callbacks so that their names reflect their purpose. In addition, put some explanatory remarks into their kerneldoc comments.
I had to modify this patch, because the previous version had problems with systems that don't support cpufreq. The updated patch (which is appended) also simplifies the code even further.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: cpufreq: Use syscore_ops for boot CPU suspend/resume (v2)
The cpufreq subsystem uses sysdev suspend and resume for executing cpufreq_suspend() and cpufreq_resume(), respectively, during system suspend, after interrupts have been switched off on the boot CPU, and during system resume, while interrupts are still off on the boot CPU. In both cases the other CPUs are off-line at the relevant point (either they have been switched off via CPU hotplug during suspend, or they haven't been switched on yet during resume). For this reason, although it may seem that cpufreq_suspend() and cpufreq_resume() are executed for all CPUs in the system, they are only called for the boot CPU in fact, which is quite confusing.
To remove the confusion and to prepare for elimiating sysdev suspend and resume operations from the kernel enirely, convernt cpufreq to using a struct syscore_ops object for the boot CPU suspend and resume and rename the callbacks so that their names reflect their purpose. In addition, put some explanatory remarks into their kerneldoc comments.
--- drivers/cpufreq/cpufreq.c | 66 ++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 40 deletions(-)
drivers/cpufreq/cpufreq.c +26 -40
@@ -28,6 +28,7 @@#include <linux/cpu.h> #include <linux/completion.h> #include <linux/mutex.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h>
@@ -1340,35 +1341,31 @@ out: }EXPORT_SYMBOL (cpufreq_get); +static struct sysdev_driver cpufreq_sysdev_driver = { + .add = cpufreq_add_dev, + .remove = cpufreq_remove_dev, +}; +/** -* cpufreq_suspend - let the low level driver prepare for suspend +* cpufreq_bp_suspend - Prepare the boot CPU for system suspend. +* +* This function is only executed for the boot processor. The other CPUs +* have been put offline by means of CPU hotplug. */ - -static int cpufreq_suspend (struct sys_device *sysdev,pm_message_t pmsg) +static int cpufreq_bp_suspend (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("suspending cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; - -/* we may be lax here as interrupts are off. Nonetheless -* we need to grab the correct cpu policy, as to check -* whether we really run on this CPU. -*/ - +/* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy =cpufreq_cpu_get (cpu);if (!cpu_policy) -return -EINVAL ; - -/* only handle each CPU group once */ -if (unlikely (cpu_policy->cpu != cpu)) - goto out; +return 0 ;if (cpufreq_driver->suspend) { ret = cpufreq_driver->suspend (cpu_policy);
@@ -1377,13 +1374,12 @@ static int cpufreq_suspend(struct sys_de "step on CPU %u\n", cpu_policy->cpu); } -out:cpufreq_cpu_put (cpu_policy);return ret; }/** -* cpufreq_resume - restore proper CPU frequency handling after resume +* cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. * * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
@@ -1391,31 +1387,23 @@ out:* what we believe it to be. This is a bit later than when it * should be, but nonethteless it's better than calling * cpufreq_driver->get() here which might re-enable interrupts... +* +* This function is only executed for the boot CPU. The other CPUs have not +* been turned on yet. */ -static int cpufreq_resume (struct sys_device *sysdev) +static void cpufreq_bp_resume (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("resuming cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; - -/* we may be lax here as interrupts are off. Nonetheless -* we need to grab the correct cpu policy, as to check -* whether we really run on this CPU. -*/ - +/* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy =cpufreq_cpu_get (cpu);if (!cpu_policy) -return -EINVAL ; - -/* only handle each CPU group once */ -if (unlikely (cpu_policy->cpu != cpu)) - goto fail; +return ;if (cpufreq_driver->resume) { ret = cpufreq_driver->resume (cpu_policy);
@@ -1430,14 +1418,11 @@ static int cpufreq_resume(struct sys_dev fail:cpufreq_cpu_put (cpu_policy); -return ret; } -static struct sysdev_driver cpufreq_sysdev_driver = { - .add = cpufreq_add_dev, - .remove = cpufreq_remove_dev, - .suspend = cpufreq_suspend, - .resume = cpufreq_resume, +static struct syscore_ops cpufreq_syscore_ops = { + .suspend = cpufreq_bp_suspend, + .resume = cpufreq_bp_resume, };
@@ -2002,6 +1987,7 @@ static int __init cpufreq_core_init(void cpufreq_global_kobject =kobject_create_and_add ("cpufreq" , &cpu_sysdev_class.kset.kobj);BUG_ON (!cpufreq_global_kobject); +register_syscore_ops (&cpufreq_syscore_ops);return 0 ; }
[Update, v2] Re: [PATCH 7/8] cpufreq: Use syscore_ops for boot CPU suspend/resume
In reply to Rafael J. WysockiQuoted 13 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
The cpufreq subsystem uses sysdev suspend and resume for executing
cpufreq_suspend()andcpufreq_resume(), respectively, during system suspend, after interrupts have been switched off on the boot CPU, and during system resume, while interrupts are still off on the boot CPU. In both cases the other CPUs are off-line at the relevant point (either they have been switched off via CPU hotplug during suspend, or they haven't been switched on yet during resume). For this reason, although it may seem thatcpufreq_suspend()andcpufreq_resume()are executed for all CPUs in the system, they are only called for the boot CPU in fact, which is quite confusing.
Quoted 6 lines
To remove the confusion and to prepare for elimiating sysdev suspend and resume operations from the kernel enirely, convernt cpufreq to using a struct
syscore_opsobject for the boot CPU suspend and resume and rename the callbacks so that their names reflect their purpose. In addition, put some explanatory remarks into their kerneldoc comments.
I had to modify this patch, because the previous version had problems with systems that don't support cpufreq. The updated patch (which is appended) also simplifies the code even further.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: cpufreq: Use syscore_ops for boot CPU suspend/resume (v2)
The cpufreq subsystem uses sysdev suspend and resume for executing cpufreq_suspend() and cpufreq_resume(), respectively, during system suspend, after interrupts have been switched off on the boot CPU, and during system resume, while interrupts are still off on the boot CPU. In both cases the other CPUs are off-line at the relevant point (either they have been switched off via CPU hotplug during suspend, or they haven't been switched on yet during resume). For this reason, although it may seem that cpufreq_suspend() and cpufreq_resume() are executed for all CPUs in the system, they are only called for the boot CPU in fact, which is quite confusing.
To remove the confusion and to prepare for elimiating sysdev suspend and resume operations from the kernel enirely, convernt cpufreq to using a struct syscore_ops object for the boot CPU suspend and resume and rename the callbacks so that their names reflect their purpose. In addition, put some explanatory remarks into their kerneldoc comments.
--- drivers/cpufreq/cpufreq.c | 66 ++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 40 deletions(-)
drivers/cpufreq/cpufreq.c +26 -40
@@ -28,6 +28,7 @@#include <linux/cpu.h> #include <linux/completion.h> #include <linux/mutex.h> +#include <linux/syscore_ops.h> #include <trace/events/power.h>
@@ -1340,35 +1341,31 @@ out: }EXPORT_SYMBOL (cpufreq_get); +static struct sysdev_driver cpufreq_sysdev_driver = { + .add = cpufreq_add_dev, + .remove = cpufreq_remove_dev, +}; +/** -* cpufreq_suspend - let the low level driver prepare for suspend +* cpufreq_bp_suspend - Prepare the boot CPU for system suspend. +* +* This function is only executed for the boot processor. The other CPUs +* have been put offline by means of CPU hotplug. */ - -static int cpufreq_suspend (struct sys_device *sysdev,pm_message_t pmsg) +static int cpufreq_bp_suspend (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("suspending cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; - -/* we may be lax here as interrupts are off. Nonetheless -* we need to grab the correct cpu policy, as to check -* whether we really run on this CPU. -*/ - +/* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy =cpufreq_cpu_get (cpu);if (!cpu_policy) -return -EINVAL ; - -/* only handle each CPU group once */ -if (unlikely (cpu_policy->cpu != cpu)) - goto out; +return 0 ;if (cpufreq_driver->suspend) { ret = cpufreq_driver->suspend (cpu_policy);
@@ -1377,13 +1374,12 @@ static int cpufreq_suspend(struct sys_de "step on CPU %u\n", cpu_policy->cpu); } -out:cpufreq_cpu_put (cpu_policy);return ret; }/** -* cpufreq_resume - restore proper CPU frequency handling after resume +* cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. * * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
@@ -1391,31 +1387,23 @@ out:* what we believe it to be. This is a bit later than when it * should be, but nonethteless it's better than calling * cpufreq_driver->get() here which might re-enable interrupts... +* +* This function is only executed for the boot CPU. The other CPUs have not +* been turned on yet. */ -static int cpufreq_resume (struct sys_device *sysdev) +static void cpufreq_bp_resume (void ) {int ret =0 ; -int cpu = sysdev->id; +int cpu =smp_processor_id ();struct cpufreq_policy *cpu_policy;dprintk ("resuming cpu %u\n" , cpu); -if (!cpu_online (cpu)) -return 0 ; - -/* we may be lax here as interrupts are off. Nonetheless -* we need to grab the correct cpu policy, as to check -* whether we really run on this CPU. -*/ - +/* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy =cpufreq_cpu_get (cpu);if (!cpu_policy) -return -EINVAL ; - -/* only handle each CPU group once */ -if (unlikely (cpu_policy->cpu != cpu)) - goto fail; +return ;if (cpufreq_driver->resume) { ret = cpufreq_driver->resume (cpu_policy);
@@ -1430,14 +1418,11 @@ static int cpufreq_resume(struct sys_dev fail:cpufreq_cpu_put (cpu_policy); -return ret; } -static struct sysdev_driver cpufreq_sysdev_driver = { - .add = cpufreq_add_dev, - .remove = cpufreq_remove_dev, - .suspend = cpufreq_suspend, - .resume = cpufreq_resume, +static struct syscore_ops cpufreq_syscore_ops = { + .suspend = cpufreq_bp_suspend, + .resume = cpufreq_bp_resume, };
@@ -2002,6 +1987,7 @@ static int __init cpufreq_core_init(void cpufreq_global_kobject =kobject_create_and_add ("cpufreq" , &cpu_sysdev_class.kset.kobj);BUG_ON (!cpufreq_global_kobject); +register_syscore_ops (&cpufreq_syscore_ops);return 0 ; }
PATCH 8/8 Introduce ARCH_NO_SYSDEV_OPS config option
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Introduce option allowing architectures where sysdev operations used during system suspend, resume and shutdown have been completely replaced with struct sycore_ops operations to avoid building sysdev code that will never be used. Making callbacks in struct sys_device and struct sysdev_driver depend on ARCH_NO_SYSDEV_OPS allows us to verify if all of the references have been actually removed from the code the given architecture depends on.
Make x86 set ARCH_NO_SYSDEV_OPS.
--- arch/x86/Kconfig | 3 +++ drivers/base/sys.c | 3 ++- include/linux/device.h | 4 ++++ include/linux/pm.h | 10 ++++++++-- include/linux/sysdev.h | 7 +++++-- 5 files changed, 22 insertions(+), 5 deletions(-)
include/linux/pm.h +8 -2
@@ -529,13 +529,19 @@ struct dev_power_domain {*/ #ifdef CONFIG_PM_SLEEP -extern void device_pm_lock (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS +extern int sysdev_suspend (pm_message_t state);extern int sysdev_resume (void ); +#else +static inline int sysdev_suspend (pm_message_t state) {return 0 ; } +static inline int sysdev_resume (void ) {return 0 ; } +#endif + +extern void device_pm_lock (void );extern void dpm_resume_noirq (pm_message_t state);extern void dpm_resume_end (pm_message_t state);extern void device_pm_unlock (void ); -extern int sysdev_suspend (pm_message_t state);extern int dpm_suspend_noirq (pm_message_t state);extern int dpm_suspend_start (pm_message_t state);
include/linux/sysdev.h +5 -2
@@ -33,12 +33,13 @@ struct sysdev_class {const char *name;struct list_head drivers;struct sysdev_class_attribute **attrs; - +struct kset kset; +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* Default operations for these types of devices */ int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); -struct kset kset; +#endif };struct sysdev_class_attribute {
@@ -76,9 +77,11 @@ struct sysdev_driver {struct list_head entry;int (*add)(struct sys_device *);int (*remove)(struct sys_device *); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); +#endif };
include/linux/device.h +4 -0
@@ -635,8 +635,12 @@ static inline int devtmpfs_mount(const c/* drivers/base/power/shutdown.c */ extern void device_shutdown (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* drivers/base/sys.c */ extern void sysdev_shutdown (void ); +#else +static inline void sysdev_shutdown (void ) { } +#endif /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string (const struct device *dev);
arch/x86/Kconfig +3 -0
@@ -184,6 +184,9 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y +config ARCH_NO_SYSDEV_OPS + def_bool y + config ZONE_DMA32 bool default X86_64
drivers/base/sys.c +2 -1
@@ -302,7 +302,7 @@ void sysdev_unregister(struct sys_device } - +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /** * sysdev_shutdown - Shut down all system devices. *
@@ -497,6 +497,7 @@ int sysdev_resume(void) return 0; }EXPORT_SYMBOL_GPL (sysdev_resume); +#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */ int __init system_bus_init (void ) {
PATCH 8/8 Introduce ARCH_NO_SYSDEV_OPS config option
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Introduce option allowing architectures where sysdev operations used during system suspend, resume and shutdown have been completely replaced with struct sycore_ops operations to avoid building sysdev code that will never be used. Making callbacks in struct sys_device and struct sysdev_driver depend on ARCH_NO_SYSDEV_OPS allows us to verify if all of the references have been actually removed from the code the given architecture depends on.
Make x86 set ARCH_NO_SYSDEV_OPS.
--- arch/x86/Kconfig | 3 +++ drivers/base/sys.c | 3 ++- include/linux/device.h | 4 ++++ include/linux/pm.h | 10 ++++++++-- include/linux/sysdev.h | 7 +++++-- 5 files changed, 22 insertions(+), 5 deletions(-)
include/linux/pm.h +8 -2
@@ -529,13 +529,19 @@ struct dev_power_domain {*/ #ifdef CONFIG_PM_SLEEP -extern void device_pm_lock (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS +extern int sysdev_suspend (pm_message_t state);extern int sysdev_resume (void ); +#else +static inline int sysdev_suspend (pm_message_t state) {return 0 ; } +static inline int sysdev_resume (void ) {return 0 ; } +#endif + +extern void device_pm_lock (void );extern void dpm_resume_noirq (pm_message_t state);extern void dpm_resume_end (pm_message_t state);extern void device_pm_unlock (void ); -extern int sysdev_suspend (pm_message_t state);extern int dpm_suspend_noirq (pm_message_t state);extern int dpm_suspend_start (pm_message_t state);
include/linux/sysdev.h +5 -2
@@ -33,12 +33,13 @@ struct sysdev_class {const char *name;struct list_head drivers;struct sysdev_class_attribute **attrs; - +struct kset kset; +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* Default operations for these types of devices */ int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); -struct kset kset; +#endif };struct sysdev_class_attribute {
@@ -76,9 +77,11 @@ struct sysdev_driver {struct list_head entry;int (*add)(struct sys_device *);int (*remove)(struct sys_device *); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); +#endif };
include/linux/device.h +4 -0
@@ -635,8 +635,12 @@ static inline int devtmpfs_mount(const c/* drivers/base/power/shutdown.c */ extern void device_shutdown (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* drivers/base/sys.c */ extern void sysdev_shutdown (void ); +#else +static inline void sysdev_shutdown (void ) { } +#endif /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string (const struct device *dev);
arch/x86/Kconfig +3 -0
@@ -184,6 +184,9 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y +config ARCH_NO_SYSDEV_OPS + def_bool y + config ZONE_DMA32 bool default X86_64
drivers/base/sys.c +2 -1
@@ -302,7 +302,7 @@ void sysdev_unregister(struct sys_device } - +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /** * sysdev_shutdown - Shut down all system devices. *
@@ -497,6 +497,7 @@ int sysdev_resume(void) return 0; }EXPORT_SYMBOL_GPL (sysdev_resume); +#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */ int __init system_bus_init (void ) {
Re: [PATCH 8/8] Introduce ARCH_NO_SYSDEV_OPS config option
arch/x86/Kconfig config ARCH_HIBERNATION_POSSIBLE · line 189
Quoted 11 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
===================================================================arch/x86/Kconfig +3
-0@@ -184,6 +184,9 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y +config ARCH_NO_SYSDEV_OPS + def_bool y +
Can we please put that in drivers/base/Kconfig and let the arch Kconfig select it?
Thanks,
tglx
[Update] Re: [PATCH 8/8] Introduce ARCH_NO_SYSDEV_OPS config option
Quoted 9 lines · Thomas Gleixner
Quoted 8 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
===================================================================arch/x86/Kconfig +0
-0@@ -184,6 +184,9 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y
Quoted 6 lines
arch/x86/Kconfig config ARCH_HIBERNATION_POSSIBLE · line 189
Quoted 3 lines
arch/x86/Kconfig +3
-0+config ARCH_NO_SYSDEV_OPS + def_bool y +Can we please put that in
drivers/base/Kconfigand let the archKconfigselect it?
Sure. Updated patch follows.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: Introduce ARCH_NO_SYSDEV_OPS config option (v2)
Introduce Kconfig option allowing architectures where sysdev operations used during system suspend, resume and shutdown have been completely replaced with struct sycore_ops operations to avoid building sysdev code that will never be used.
Make callbacks in struct sys_device and struct sysdev_driver depend on ARCH_NO_SYSDEV_OPS to allows us to verify if all of the references have been actually removed from the code the given architecture depends on.
Make x86 select ARCH_NO_SYSDEV_OPS.
--- arch/x86/Kconfig | 1 + drivers/base/Kconfig | 6 ++++++ drivers/base/sys.c | 3 ++- include/linux/device.h | 4 ++++ include/linux/pm.h | 10 ++++++++-- include/linux/sysdev.h | 7 +++++-- 6 files changed, 26 insertions(+), 5 deletions(-)
include/linux/pm.h +8 -2
@@ -529,13 +529,19 @@ struct dev_power_domain {*/ #ifdef CONFIG_PM_SLEEP -extern void device_pm_lock (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS +extern int sysdev_suspend (pm_message_t state);extern int sysdev_resume (void ); +#else +static inline int sysdev_suspend (pm_message_t state) {return 0 ; } +static inline int sysdev_resume (void ) {return 0 ; } +#endif + +extern void device_pm_lock (void );extern void dpm_resume_noirq (pm_message_t state);extern void dpm_resume_end (pm_message_t state);extern void device_pm_unlock (void ); -extern int sysdev_suspend (pm_message_t state);extern int dpm_suspend_noirq (pm_message_t state);extern int dpm_suspend_start (pm_message_t state);
include/linux/sysdev.h +5 -2
@@ -33,12 +33,13 @@ struct sysdev_class {const char *name;struct list_head drivers;struct sysdev_class_attribute **attrs; - +struct kset kset; +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* Default operations for these types of devices */ int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); -struct kset kset; +#endif };struct sysdev_class_attribute {
@@ -76,9 +77,11 @@ struct sysdev_driver {struct list_head entry;int (*add)(struct sys_device *);int (*remove)(struct sys_device *); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); +#endif };
include/linux/device.h +4 -0
@@ -635,8 +635,12 @@ static inline int devtmpfs_mount(const c/* drivers/base/power/shutdown.c */ extern void device_shutdown (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* drivers/base/sys.c */ extern void sysdev_shutdown (void ); +#else +static inline void sysdev_shutdown (void ) { } +#endif /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string (const struct device *dev);
arch/x86/Kconfig +1 -0
@@ -67,6 +67,7 @@ config X86 select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select USE_GENERIC_SMP_HELPERS if SMP + select ARCH_NO_SYSDEV_OPS config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS)
drivers/base/sys.c +2 -1
@@ -302,7 +302,7 @@ void sysdev_unregister(struct sys_device } - +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /** * sysdev_shutdown - Shut down all system devices. *
@@ -497,6 +497,7 @@ int sysdev_resume(void) return 0; }EXPORT_SYMBOL_GPL (sysdev_resume); +#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */ int __init system_bus_init (void ) {
drivers/base/Kconfig +6 -0
@@ -168,4 +168,10 @@ config SYS_HYPERVISOR bool default n +config ARCH_NO_SYSDEV_OPS + bool + ---help--- + To be set by architectures that don't use sysdev or sysdev driver + power management (suspend/resume) and shutdown operations. + endmenu
[Update] Re: [PATCH 8/8] Introduce ARCH_NO_SYSDEV_OPS config option
In reply to Thomas GleixnerQuoted 9 lines · Thomas Gleixner
Quoted 8 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
===================================================================arch/x86/Kconfig +0
-0@@ -184,6 +184,9 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y
Quoted 6 lines
arch/x86/Kconfig config ARCH_HIBERNATION_POSSIBLE · line 189
Quoted 3 lines
arch/x86/Kconfig +3
-0+config ARCH_NO_SYSDEV_OPS + def_bool y +Can we please put that in
drivers/base/Kconfigand let the archKconfigselect it?
Sure. Updated patch follows.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: Introduce ARCH_NO_SYSDEV_OPS config option (v2)
Introduce Kconfig option allowing architectures where sysdev operations used during system suspend, resume and shutdown have been completely replaced with struct sycore_ops operations to avoid building sysdev code that will never be used.
Make callbacks in struct sys_device and struct sysdev_driver depend on ARCH_NO_SYSDEV_OPS to allows us to verify if all of the references have been actually removed from the code the given architecture depends on.
Make x86 select ARCH_NO_SYSDEV_OPS.
--- arch/x86/Kconfig | 1 + drivers/base/Kconfig | 6 ++++++ drivers/base/sys.c | 3 ++- include/linux/device.h | 4 ++++ include/linux/pm.h | 10 ++++++++-- include/linux/sysdev.h | 7 +++++-- 6 files changed, 26 insertions(+), 5 deletions(-)
include/linux/pm.h +8 -2
@@ -529,13 +529,19 @@ struct dev_power_domain {*/ #ifdef CONFIG_PM_SLEEP -extern void device_pm_lock (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS +extern int sysdev_suspend (pm_message_t state);extern int sysdev_resume (void ); +#else +static inline int sysdev_suspend (pm_message_t state) {return 0 ; } +static inline int sysdev_resume (void ) {return 0 ; } +#endif + +extern void device_pm_lock (void );extern void dpm_resume_noirq (pm_message_t state);extern void dpm_resume_end (pm_message_t state);extern void device_pm_unlock (void ); -extern int sysdev_suspend (pm_message_t state);extern int dpm_suspend_noirq (pm_message_t state);extern int dpm_suspend_start (pm_message_t state);
include/linux/sysdev.h +5 -2
@@ -33,12 +33,13 @@ struct sysdev_class {const char *name;struct list_head drivers;struct sysdev_class_attribute **attrs; - +struct kset kset; +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* Default operations for these types of devices */ int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); -struct kset kset; +#endif };struct sysdev_class_attribute {
@@ -76,9 +77,11 @@ struct sysdev_driver {struct list_head entry;int (*add)(struct sys_device *);int (*remove)(struct sys_device *); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS int (*shutdown)(struct sys_device *);int (*suspend)(struct sys_device *,pm_message_t state);int (*resume)(struct sys_device *); +#endif };
include/linux/device.h +4 -0
@@ -635,8 +635,12 @@ static inline int devtmpfs_mount(const c/* drivers/base/power/shutdown.c */ extern void device_shutdown (void ); +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /* drivers/base/sys.c */ extern void sysdev_shutdown (void ); +#else +static inline void sysdev_shutdown (void ) { } +#endif /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string (const struct device *dev);
arch/x86/Kconfig +1 -0
@@ -67,6 +67,7 @@ config X86 select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select USE_GENERIC_SMP_HELPERS if SMP + select ARCH_NO_SYSDEV_OPS config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS)
drivers/base/sys.c +2 -1
@@ -302,7 +302,7 @@ void sysdev_unregister(struct sys_device } - +#ifndef CONFIG_ARCH_NO_SYSDEV_OPS /** * sysdev_shutdown - Shut down all system devices. *
@@ -497,6 +497,7 @@ int sysdev_resume(void) return 0; }EXPORT_SYMBOL_GPL (sysdev_resume); +#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */ int __init system_bus_init (void ) {
drivers/base/Kconfig +6 -0
@@ -168,4 +168,10 @@ config SYS_HYPERVISOR bool default n +config ARCH_NO_SYSDEV_OPS + bool + ---help--- + To be set by architectures that don't use sysdev or sysdev driver + power management (suspend/resume) and shutdown operations. + endmenu
PATCH 1/1 Allow subsystems to avoid using sysdevs for defining "core" PM callbacks
In reply to Rafael J. WysockiQuoted 64 lines · Rafael J. Wysocki
Hi,
Quoted 35 lines · Rafael J. Wysocki
There are multiple problems with sysdevs, or struct
sys_deviceobjects to be precise, that are so annoying that some people have started to think of removind them entirely from the kernel. To me, personally, the most obvious issue is the way sysdevs are used for defining suspend/resume callbacks to be executed with one CPU on-line and interrupts disabled. Greg and Kay may tell you more about the other problems with sysdevs. :-)Some subsystems need to carry out certain operations during suspend after we've disabled non-boot CPUs and interrupts have been switched off on the only on-line one. Currently, the only way to achieve that is to define sysdev suspend/resume callbacks, but this is cumbersome and inefficient. Namely, to do that, one has to define a sysdev class providing the callbacks and a sysdev actually using them, which is excessively complicated. Moreover, the sysdev suspend/resume callbacks take arguments that are not really used by the majority of subsystems defining sysdev suspend/resume callbacks (or even if they are used, they don't really _need_ to be used, so they are simply unnecessary). Of course, if a sysdev is only defined to provide suspend/resume (and maybe shutdown) callbacks, there's no real reason why it should show up in sysfs.
For this reason, I thought it would be a good idea to provide a simpler interface for subsystems to define "very late" suspend callbacks and "very early" resume callbacks (and "very late" shutdown callbacks as well) without the entire bloat related to sysdevs. The interface is introduced by the first of the following patches, while the second patch converts some sysdev users related to the x86 architecture to using the new interface.
I believe that call sysdev users who need to define suspend/resume/shutdown callbacks may be converted to using the interface provided by the first patch, which in turn should allow us to convert the remaining sysdev functionality into "normal" struct device interfaces. Still, even if that turns out to be too complicated, the bloat reduction resulting from the second patch kind of shows that moving at least some sysdev users to a simpler interface (like in the first patch) is a good idea anyway.
Quoted 4 lines
This is a proof of concept, so the patches have not been tested. Please be extrememly careful, because they touch sensitive code, so to speak. In the majority of cases the changes are rather straightforward, but there are some more interesting cases as well (
io_apic.cmost importantly).Since Greg likes the idea and there haven't been any objections so far, here's the official submission. The patches have been tested on HP nx6325 and Toshiba Portege R500.
Patch [1/8] is regareded as 2.6.38 material, following Greg's advice. The other patches in the set are regarded as 2.6.39 material. The last one obviously depends on all of the previous ones.
[1/8] - Introduce struct
syscore_opsfor registering operations to be run on
one CPU during suspend/resume/shutdown.[2/8] - Convert sysdev users in
arch/x86to using structsyscore_ops.[3/8] - Make ACPI use struct
syscore_opsforirqrouter_resume().[4/8] - Make timekeeping use struct
syscore_opsfor suspend/resume.[5/8] - Make Intel IOMMU use struct
syscore_opsfor suspend/resume.[6/8] - Make KVM use struct
syscore_opsfor suspend/resume.
Quoted 7 lines
[7/8] - Make cpufreq use struct
syscore_opsfor boot CPU suspend/resume.[8/8] - Introduce config switch allowing architectures to skip sysdev
suspend/resume/shutdown code.If there are no objectsions, I'd like to push these patches through the suspend tree.
A little followup with two ARM-related patches.
[9/10] - Make sh drivers use struct syscore_ops for suspend/resume (instead of
sysdevs).
[10/10] - Use struct syscore_ops for suspend/resume (instead of sysdevs) in
core ARM code.
Thanks,
Rafael
PATCH 9/10 sh: Use struct syscore_ops instead of sysdev class and sysdev
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct syscore_ops instead of a sysdev classes and sysdevs for power managment.
This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
--- drivers/sh/clk/core.c | 68 +++++++-------------------- drivers/sh/intc/core.c | 108 ++++++++++++++------------------------------ drivers/sh/intc/internals.h | 2 3 files changed, 53 insertions(+), 125 deletions(-)
Index: linux-2.6/drivers/sh/clk/core.c =================================--- linux-2.6.orig/drivers/sh/clk/core.c +++ linux-2.6/drivers/sh/clk/core.c
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -630,68 +630,36 @@ long clk_round_parent(struct clk *clk, u
EXPORT_SYMBOL_GPL(clk_round_parent);
#ifdef CONFIG_PM
-static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) +static void clks_core_resume(void)
{
- static pm_message_t prev_state;
struct clk *clkp;
- switch (state.event) {
- case PM_EVENT_ON:
- /* Resumeing from hibernation */
- if (prev_state.event != PM_EVENT_FREEZE)
- break;
-
- list_for_each_entry(clkp, &clock_list, node) {
- if (likely(clkp->ops)) {
- unsigned long rate = clkp->rate;
-
- if (likely(clkp->ops->set_parent))
- clkp->ops->set_parent(clkp,
- clkp->parent);
- if (likely(clkp->ops->set_rate))
- clkp->ops->set_rate(clkp, rate);
- else if (likely(clkp->ops->recalc))
- clkp->rate = clkp->ops->recalc(clkp);
- }
+ list_for_each_entry(clkp, &clock_list, node) {
+ if (likely(clkp->ops)) {
+ unsigned long rate = clkp->rate;
+
+ if (likely(clkp->ops->set_parent))
+ clkp->ops->set_parent(clkp,
+ clkp->parent);
+ if (likely(clkp->ops->set_rate))
+ clkp->ops->set_rate(clkp, rate);
+ else if (likely(clkp->ops->recalc))
+ clkp->rate = clkp->ops->recalc(clkp);
}
- break;
- case PM_EVENT_FREEZE:
- break;
- case PM_EVENT_SUSPEND:
- break;
}
-
- prev_state = state;
- return 0;
-}
-
-static int clks_sysdev_resume(struct sys_device *dev) -{
- return clks_sysdev_suspend(dev, PMSG_ON);
}
-static struct sysdev_class clks_sysdev_class = {
- .name = "clks",
-};
-
-static struct sysdev_driver clks_sysdev_driver = {
- .suspend = clks_sysdev_suspend,
- .resume = clks_sysdev_resume,
-};
-
-static struct sys_device clks_sysdev_dev = {
- .cls = &clks_sysdev_class,
+static struct syscore_ops clks_syscore_ops = {
+ .resume = clks_core_resume,
};
-static int __init clk_sysdev_init(void)
+static int __init clk_syscore_init(void)
{
- sysdev_class_register(&clks_sysdev_class);
- sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
- sysdev_register(&clks_sysdev_dev);
+ register_syscore_ops(&clks_syscore_ops);
return 0;
}
-subsys_initcall(clk_sysdev_init);
+subsys_initcall(clk_syscore_init);
#endif
/*
Index: linux-2.6/drivers/sh/intc/core.c =================================--- linux-2.6.orig/drivers/sh/intc/core.c +++ linux-2.6/drivers/sh/intc/core.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/sh_intc.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/radix-tree.h>
@@ -376,108 +376,70 @@ err0:
return -ENOMEM;
}
-static ssize_t
-show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) +static int intc_suspend(void)
{
struct intc_desc_int *d;
- d = container_of(dev, struct intc_desc_int, sysdev);
+ list_for_each_entry(d, &intc_list, list) {
+ int irq;
- return sprintf(buf, "%s\n", d->chip.name);
-}
+ /* enable wakeup irqs belonging to this intc controller */
+ for_each_active_irq(irq) {
+ struct irq_data *data;
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+
+ data = irq_get_irq_data(irq);
+ chip = irq_data_get_irq_chip(data);
+ if (chip != &d->chip)
+ continue;
+ desc = irq_to_desc(irq);
+ if ((desc->status & IRQ_WAKEUP))
+ chip->irq_enable(data);
+ }
+ }
-static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
+ return 0;
+}
-static int intc_suspend(struct sys_device *dev, pm_message_t state) +static void intc_resume(void)
{
struct intc_desc_int *d;
- struct irq_data *data;
- struct irq_desc *desc;
- struct irq_chip *chip;
- int irq;
-
- /* get intc controller associated with this sysdev */
- d = container_of(dev, struct intc_desc_int, sysdev);
-
- switch (state.event) {
- case PM_EVENT_ON:
- if (d->state.event != PM_EVENT_FREEZE)
- break;
+
+ list_for_each_entry(d, &intc_list, list) {
+ int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_data *data;
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+
data = irq_get_irq_data(irq);
chip = irq_data_get_irq_chip(data);
-
/*
* This will catch the redirect and VIRQ cases
* due to the dummy_irq_chip being inserted. */
if (chip != &d->chip)
continue;
+ desc = irq_to_desc(irq);
if (desc->status & IRQ_DISABLED)
chip->irq_disable(data);
else
chip->irq_enable(data);
}
- break;
- case PM_EVENT_FREEZE:
- /* nothing has to be done */
- break;
- case PM_EVENT_SUSPEND:
- /* enable wakeup irqs belonging to this intc controller */
- for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
- data = irq_get_irq_data(irq);
- chip = irq_data_get_irq_chip(data);
-
- if (chip != &d->chip)
- continue;
- if ((desc->status & IRQ_WAKEUP))
- chip->irq_enable(data);
- }
- break;
}
-
- d->state = state;
-
- return 0;
}
-static int intc_resume(struct sys_device *dev)
-{
- return intc_suspend(dev, PMSG_ON);
-}
-
-struct sysdev_class intc_sysdev_class = {
- .name = "intc",
+struct syscore_ops intc_syscore_ops = {
.suspend = intc_suspend,
.resume = intc_resume,
};
-/* register this intc as sysdev to allow suspend/resume */ -static int __init register_intc_sysdevs(void) +static int __init intc_syscore_init(void)
{
- struct intc_desc_int *d;
- int error;
+ register_syscore_ops(&intc_syscore_ops);
- error = sysdev_class_register(&intc_sysdev_class);
- if (!error) {
- list_for_each_entry(d, &intc_list, list) {
- d->sysdev.id = d->index;
- d->sysdev.cls = &intc_sysdev_class;
- error = sysdev_register(&d->sysdev);
- if (error = 0)
- error = sysdev_create_file(&d->sysdev,
- &attr_name);
- if (error)
- break;
- }
- }
-
- if (error)
- pr_err("sysdev registration error\n");
-
- return error;
+ return 0;
}
-device_initcall(register_intc_sysdevs); +device_initcall(intc_syscore_init);
Index: linux-2.6/drivers/sh/intc/internals.h =================================--- linux-2.6.orig/drivers/sh/intc/internals.h +++ linux-2.6/drivers/sh/intc/internals.h
@@ -51,9 +51,7 @@ struct intc_subgroup_entry {
struct intc_desc_int {
struct list_head list;
- struct sys_device sysdev;
struct radix_tree_root tree;
- pm_message_t state;
raw_spinlock_t lock;
unsigned int index;
unsigned long *reg;
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 13 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
Quoted 4 lines
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 14 lines · Paul Mundt
Quoted 13 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
Quoted 7 lines
Quoted 4 lines
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: Drivers / sh: Use struct syscore_ops instead of sysdev class and sysdev (v2)
Convert the SuperH clocks framework and shared interrupt handling code to using struct syscore_ops instead of a sysdev classes and sysdevs for power managment.
This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
--- drivers/sh/clk/core.c | 68 +++++++-------------------- drivers/sh/intc/core.c | 108 ++++++++++++++------------------------------ drivers/sh/intc/internals.h | 5 -- drivers/sh/intc/userimask.c | 9 +++ 4 files changed, 63 insertions(+), 127 deletions(-)
Index: linux-2.6/drivers/sh/clk/core.c =================================--- linux-2.6.orig/drivers/sh/clk/core.c +++ linux-2.6/drivers/sh/clk/core.c
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -630,68 +630,36 @@ long clk_round_parent(struct clk *clk, u
EXPORT_SYMBOL_GPL(clk_round_parent);
#ifdef CONFIG_PM
-static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) +static void clks_core_resume(void)
{
- static pm_message_t prev_state;
struct clk *clkp;
- switch (state.event) {
- case PM_EVENT_ON:
- /* Resumeing from hibernation */
- if (prev_state.event != PM_EVENT_FREEZE)
- break;
-
- list_for_each_entry(clkp, &clock_list, node) {
- if (likely(clkp->ops)) {
- unsigned long rate = clkp->rate;
-
- if (likely(clkp->ops->set_parent))
- clkp->ops->set_parent(clkp,
- clkp->parent);
- if (likely(clkp->ops->set_rate))
- clkp->ops->set_rate(clkp, rate);
- else if (likely(clkp->ops->recalc))
- clkp->rate = clkp->ops->recalc(clkp);
- }
+ list_for_each_entry(clkp, &clock_list, node) {
+ if (likely(clkp->ops)) {
+ unsigned long rate = clkp->rate;
+
+ if (likely(clkp->ops->set_parent))
+ clkp->ops->set_parent(clkp,
+ clkp->parent);
+ if (likely(clkp->ops->set_rate))
+ clkp->ops->set_rate(clkp, rate);
+ else if (likely(clkp->ops->recalc))
+ clkp->rate = clkp->ops->recalc(clkp);
}
- break;
- case PM_EVENT_FREEZE:
- break;
- case PM_EVENT_SUSPEND:
- break;
}
-
- prev_state = state;
- return 0;
-}
-
-static int clks_sysdev_resume(struct sys_device *dev) -{
- return clks_sysdev_suspend(dev, PMSG_ON);
}
-static struct sysdev_class clks_sysdev_class = {
- .name = "clks",
-};
-
-static struct sysdev_driver clks_sysdev_driver = {
- .suspend = clks_sysdev_suspend,
- .resume = clks_sysdev_resume,
-};
-
-static struct sys_device clks_sysdev_dev = {
- .cls = &clks_sysdev_class,
+static struct syscore_ops clks_syscore_ops = {
+ .resume = clks_core_resume,
};
-static int __init clk_sysdev_init(void)
+static int __init clk_syscore_init(void)
{
- sysdev_class_register(&clks_sysdev_class);
- sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
- sysdev_register(&clks_sysdev_dev);
+ register_syscore_ops(&clks_syscore_ops);
return 0;
}
-subsys_initcall(clk_sysdev_init);
+subsys_initcall(clk_syscore_init);
#endif
/*
Index: linux-2.6/drivers/sh/intc/core.c =================================--- linux-2.6.orig/drivers/sh/intc/core.c +++ linux-2.6/drivers/sh/intc/core.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/sh_intc.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/radix-tree.h>
@@ -376,108 +376,70 @@ err0:
return -ENOMEM;
}
-static ssize_t
-show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) +static int intc_suspend(void)
{
struct intc_desc_int *d;
- d = container_of(dev, struct intc_desc_int, sysdev);
+ list_for_each_entry(d, &intc_list, list) {
+ int irq;
- return sprintf(buf, "%s\n", d->chip.name);
-}
+ /* enable wakeup irqs belonging to this intc controller */
+ for_each_active_irq(irq) {
+ struct irq_data *data;
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+
+ data = irq_get_irq_data(irq);
+ chip = irq_data_get_irq_chip(data);
+ if (chip != &d->chip)
+ continue;
+ desc = irq_to_desc(irq);
+ if ((desc->status & IRQ_WAKEUP))
+ chip->irq_enable(data);
+ }
+ }
-static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
+ return 0;
+}
-static int intc_suspend(struct sys_device *dev, pm_message_t state) +static void intc_resume(void)
{
struct intc_desc_int *d;
- struct irq_data *data;
- struct irq_desc *desc;
- struct irq_chip *chip;
- int irq;
-
- /* get intc controller associated with this sysdev */
- d = container_of(dev, struct intc_desc_int, sysdev);
-
- switch (state.event) {
- case PM_EVENT_ON:
- if (d->state.event != PM_EVENT_FREEZE)
- break;
+
+ list_for_each_entry(d, &intc_list, list) {
+ int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_data *data;
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+
data = irq_get_irq_data(irq);
chip = irq_data_get_irq_chip(data);
-
/*
* This will catch the redirect and VIRQ cases
* due to the dummy_irq_chip being inserted. */
if (chip != &d->chip)
continue;
+ desc = irq_to_desc(irq);
if (desc->status & IRQ_DISABLED)
chip->irq_disable(data);
else
chip->irq_enable(data);
}
- break;
- case PM_EVENT_FREEZE:
- /* nothing has to be done */
- break;
- case PM_EVENT_SUSPEND:
- /* enable wakeup irqs belonging to this intc controller */
- for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
- data = irq_get_irq_data(irq);
- chip = irq_data_get_irq_chip(data);
-
- if (chip != &d->chip)
- continue;
- if ((desc->status & IRQ_WAKEUP))
- chip->irq_enable(data);
- }
- break;
}
-
- d->state = state;
-
- return 0;
}
-static int intc_resume(struct sys_device *dev)
-{
- return intc_suspend(dev, PMSG_ON);
-}
-
-struct sysdev_class intc_sysdev_class = {
- .name = "intc",
+struct syscore_ops intc_syscore_ops = {
.suspend = intc_suspend,
.resume = intc_resume,
};
-/* register this intc as sysdev to allow suspend/resume */ -static int __init register_intc_sysdevs(void) +static int __init intc_syscore_init(void)
{
- struct intc_desc_int *d;
- int error;
+ register_syscore_ops(&intc_syscore_ops);
- error = sysdev_class_register(&intc_sysdev_class);
- if (!error) {
- list_for_each_entry(d, &intc_list, list) {
- d->sysdev.id = d->index;
- d->sysdev.cls = &intc_sysdev_class;
- error = sysdev_register(&d->sysdev);
- if (error = 0)
- error = sysdev_create_file(&d->sysdev,
- &attr_name);
- if (error)
- break;
- }
- }
-
- if (error)
- pr_err("sysdev registration error\n");
-
- return error;
+ return 0;
}
-device_initcall(register_intc_sysdevs); +device_initcall(intc_syscore_init);
Index: linux-2.6/drivers/sh/intc/internals.h =================================--- linux-2.6.orig/drivers/sh/intc/internals.h +++ linux-2.6/drivers/sh/intc/internals.h
@@ -4,7 +4,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/radix-tree.h>
-#include <linux/sysdev.h>
+#include <linux/module.h>
#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -51,9 +51,7 @@ struct intc_subgroup_entry {
struct intc_desc_int {
struct list_head list;
- struct sys_device sysdev;
struct radix_tree_root tree;
- pm_message_t state;
raw_spinlock_t lock;
unsigned int index;
unsigned long *reg;
@@ -158,7 +156,6 @@ void _intc_enable(struct irq_data *data,
extern struct list_head intc_list;
extern raw_spinlock_t intc_big_lock;
extern unsigned int nr_intc_controllers;
-extern struct sysdev_class intc_sysdev_class;
unsigned int intc_get_dfl_prio_level(void);
unsigned int intc_get_prio_level(unsigned int irq);
Index: linux-2.6/drivers/sh/intc/userimask.c =================================--- linux-2.6.orig/drivers/sh/intc/userimask.c +++ linux-2.6/drivers/sh/intc/userimask.c
@@ -57,12 +57,21 @@ store_intc_userimask(struct sysdev_class
static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR,
show_intc_userimask, store_intc_userimask);
+static struct sysdev_class intc_sysdev_class = {
+ .name = "intc",
+};
static int __init userimask_sysdev_init(void)
{
+ int error;
+
if (unlikely(!uimask))
return -ENXIO;
+ error = sysdev_class_register(&intc_sysdev_class);
+ if (error)
+ return error;
+
return sysdev_class_create_file(&intc_sysdev_class, &attr_userimask);
}
late_initcall(userimask_sysdev_init);
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>
Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.
It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
If you need the userspace visibility, better just add a "struct bus_type" with a proper name for your subsystem and register a "struct device" with the bus_type assigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
Thanks,
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 48 lines · Kay Sievers
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
Quoted 6 lines
If you need the userspace visibility, better just add a "struct
bus_type" with a proper name for your subsystem and register a "struct device" with thebus_typeassigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.
I don't really think that's going to be useful in this particular case. The reason is, first, because the struct device would cause lots of other stuff to show up in sysfs which would be totally redundant and confusing and, second, because the things exported here are simply static attributes, pretty much like the stuff in /sys/power/.
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 62 lines · Rafael J. Wysocki
Quoted 48 lines · Kay Sievers
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
Quoted 6 lines
If you need the userspace visibility, better just add a "struct
bus_type" with a proper name for your subsystem and register a "struct device" with thebus_typeassigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.I don't really think that's going to be useful in this particular case. The reason is, first, because the struct device would cause lots of other stuff to show up in sysfs which would be totally redundant and confusing and, second, because the things exported here are simply static attributes, pretty much like the stuff in
/sys/power/.
Quoted 3 lines
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases. Userspace is not meant to learn subsystem specific rules for every new thing. There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up. That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 63 lines · Kay Sievers
Quoted 62 lines · Rafael J. Wysocki
Quoted 48 lines · Kay Sievers
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
Quoted 6 lines
If you need the userspace visibility, better just add a "struct
bus_type" with a proper name for your subsystem and register a "struct device" with thebus_typeassigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.I don't really think that's going to be useful in this particular case. The reason is, first, because the struct device would cause lots of other stuff to show up in sysfs which would be totally redundant and confusing and, second, because the things exported here are simply static attributes, pretty much like the stuff in
/sys/power/.
Quoted 7 lines
Quoted 3 lines
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Still, I won't let you change the things in /sys/power to struct devices, sorry about that. ;-)
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
Quoted 7 lines
Quoted 3 lines
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 7 lines · Rafael J. Wysocki
Quoted 6 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
Quoted 5 lines
Quoted 3 lines
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)
Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a bus_type, and use struct device for all of them, Parent them to /sys/devices/system/ if they should keep their location and layout.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
Quoted 5 lines
Quoted 3 lines
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Quoted 5 lines
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
On usual boxes it's udev/libudev and all the stuff around it. But andreoid has the same stuff in their own way of doing it. So it's not about an implementation in userspace, it's about a sane event and classification interface for kernel-exported devices. Again tis is not about any other stuff in /sys, only the "devices", and we want to have only a single type, and a single way to handle it in userspace.
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Quoted 5 lines
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Because they are devices, and there is a lot to win, if the kernel exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 6 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
This is starting to get silly. In the case of interrupt controllers as with clocksources the bus abstraction is completely meaningless. I could register a type of "system" bus, but how would that be any different from what we have from sysdevs already today? All it does is force people to duplicate crap all over the place instead and pretend like extra busses exist in order to fit some arbitrary definition of how the driver model should work.
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with /sys/power or making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.
The comment at the top of sys.c says:
* sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example arch/sh/kernel/cpu/sh4/sq.c -- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother. I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 33 lines · Paul Mundt
Quoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 6 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
This is starting to get silly. In the case of interrupt controllers as with clocksources the bus abstraction is completely meaningless. I could register a type of "system" bus, but how would that be any different from what we have from sysdevs already today? All it does is force people to duplicate crap all over the place instead and pretend like extra busses exist in order to fit some arbitrary definition of how the driver model should work.
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with
/sys/poweror making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.
Quoted 3 lines
The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
Quoted 18 lines
Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example
arch/sh/kernel/cpu/sh4/sq.c-- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother. I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Quoted 5 lines
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Nope, a device has a "name", a "subsystem" and a "devpath", has well-defined core-maintained properties at the device directory. It is not some random custom directory which people can put where they like it. Userspace has expectations about devices which need to be met, and that can only happen if these devices are "struct device".
All real devices sort into a hierarchy, possibly in different parent locations, and have a single point of classification which is the devices/ directory and contains symlinks. Only that way we can cope with it in userspace.
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
Thanks,
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 1 line · Kay Sievers
On Wed, 2011-03-23 at 06:49 +0900, Paul Mundt wrote:
...
Quoted 18 lines
Quoted 18 lines
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with
/sys/poweror making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Quoted 6 lines
Quoted 6 lines
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example
arch/sh/kernel/cpu/sh4/sq.c-- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother.
The reason why is, if I understand it correctly, because user space tools generally expect /sys/devices/ to be consistent in terms of the representation of things and /sys/devices/system/ currently violates that expectation which leads to all sorts of problems with device discovery, hotplug etc.
Now, whether or not to convert all the things currently exported through sysdevs to struct device objects is not too obvious to me. I think it simply may be better to move them into a different direcory in sysfs (presumably creating one for this purpose).
Quoted 21 lines
Quoted 9 lines
I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Nope, a device has a "name", a "subsystem" and a "devpath", has well-defined core-maintained properties at the device directory. It is not some random custom directory which people can put where they like it. Userspace has expectations about devices which need to be met, and that can only happen if these devices are "struct device".
All real devices sort into a hierarchy, possibly in different parent locations, and have a single point of classification which is the devices/ directory and contains symlinks. Only that way we can cope with it in userspace.
Quoted 7 lines
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
I really think you shouldn't say "sysfs" when you in fact you mean "/sys/devices/". :-)
Now, I can easily understand arguments about representing everything under /sys/devices/ by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment in sys.c, presumably outside of /sys/devices/.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 67 lines · Rafael J. Wysocki
Quoted 1 line · Kay Sievers
On Wed, 2011-03-23 at 06:49 +0900, Paul Mundt wrote:
...
Quoted 18 lines
Quoted 18 lines
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with
/sys/poweror making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Quoted 6 lines
Quoted 6 lines
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example
arch/sh/kernel/cpu/sh4/sq.c-- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother.The reason why is, if I understand it correctly, because user space tools generally expect
/sys/devices/to be consistent in terms of the representation of things and/sys/devices/system/currently violates that expectation which leads to all sorts of problems with device discovery, hotplug etc.Now, whether or not to convert all the things currently exported through sysdevs to struct device objects is not too obvious to me. I think it simply may be better to move them into a different direcory in sysfs (presumably creating one for this purpose).
Quoted 21 lines
Quoted 9 lines
I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Nope, a device has a "name", a "subsystem" and a "devpath", has well-defined core-maintained properties at the device directory. It is not some random custom directory which people can put where they like it. Userspace has expectations about devices which need to be met, and that can only happen if these devices are "struct device".
All real devices sort into a hierarchy, possibly in different parent locations, and have a single point of classification which is the devices/ directory and contains symlinks. Only that way we can cope with it in userspace.
Quoted 7 lines
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
Quoted 7 lines
I really think you shouldn't say "sysfs" when you in fact you mean "
/sys/devices/". :-)Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.
No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are available
That all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
When we started to clean up /sys (again only talking about devices, not other stuff) we had:
/block/*
/class/<subsys>/*
/bus/<subsys>/devices/*
/devices/system/<subsys>/*
which are 4 different exports of exactly the same thing, a "device". "Block" we converted to "class" already, "class" will be converted to "bus", and "bus" will be renamed to "subsystem". All the current names will be kept as compat symlinks, just as we did for "block". After that, _all_ devices have a "subsystem" and a subsystem global directory where people can add custom stuff shared by all devices-of-the-same-type. Ev
You can also argument from the other side, if a kernel device export is not worth the few bytes of /sys/devices/ and a "subsystem" (struct bus_type) it should not be in /sys at all, especially not hidden somehwere outside of /sys/devices when it is something remotely close to a device.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 2 lines · Kay Sievers
Quoted 1 line · Rafael J. Wysocki
On Tuesday, March 22, 2011, Kay Sievers wrote:
...
Quoted 31 lines
Quoted 5 lines
Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are availableThat all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Quoted 7 lines
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
That all is cool, but I'm not sure how it is related to things like available_clocksource and current_clocksource (which happen to be located under /sys/devices/system/clocksource/clocksource0/ being simply a path in sysfs).
Quoted 4 lines
When we started to clean up /sys (again only talking about devices, not other stuff) we had:
/block/*
/class/<subsys>/*
Quoted 8 lines
/bus/<subsys>/devices/*
/devices/system/<subsys>/*
which are 4 different exports of exactly the same thing, a "device". "Block" we converted to "class" already, "class" will be converted to "bus", and "bus" will be renamed to "subsystem". All the current names will be kept as compat symlinks, just as we did for "block". After that, _all_ devices have a "subsystem" and a subsystem global directory where people can add custom stuff shared by all devices-of-the-same-type. Ev
OK, sounds good.
Quoted 5 lines
You can also argument from the other side, if a kernel device export is not worth the few bytes of
/sys/devices/and a "subsystem" (structbus_type) it should not be in /sys at all, especially not hidden somehwere outside of/sys/deviceswhen it is something remotely close to a device.
Well, Greg apparently thinks that available_clocksource and current_clocksource could be located under /sys/bus/clock/. Perhaps other attributes now exported through sysdevs could be moved to places like this?
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 39 lines · Rafael J. Wysocki
Quoted 2 lines · Kay Sievers
Quoted 1 line · Rafael J. Wysocki
On Tuesday, March 22, 2011, Kay Sievers wrote:
...
Quoted 35 lines
Quoted 5 lines
Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are availableThat all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
Quoted 8 lines
Quoted 3 lines
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
That all is cool, but I'm not sure how it is related to things like
available_clocksourceandcurrent_clocksource(which happen to be located under/sys/devices/system/clocksource/clocksource0/being simply a path in sysfs).
Sure, it isn't related to clocksource at all. I didn't really get the idea that there are users that just fake core devices only to get a place to put a couple of attributes. I was still in the context of the $SUBJECT of this thread.
This stuff should just stay away from devices, not sysdev, not "struct device".
For other things like CPUs, which are fine to be represented as driver core devices, all the above is still valid, and they should be real devices and have their own subsystem, which exposes them to coldplug and usual event handling.
Quoted 3 lines
Well, Greg apparently thinks that
available_clocksourceandcurrent_clocksourcecould be located under/sys/bus/clock/. Perhaps other attributes now exported through sysdevs could be moved to places like this?
Sure, we could do that. All such subsystems have a directory to put subsystem-global stuff. In this case it would be a subsystem without any registered device. But it leaves us open to add real devices to it later, which might be the case for some similar subsystems.
The other option would be /sys/kernel/clocksource/ with the few attributes to create.
We should decide if "clocksource" is kind of "device-related" or not. Do you have any list of subsystems besides "clocksource", which would help to get a bigger picture what we should expect?
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 71 lines · Kay Sievers
Quoted 39 lines · Rafael J. Wysocki
Quoted 2 lines · Kay Sievers
Quoted 1 line · Rafael J. Wysocki
On Tuesday, March 22, 2011, Kay Sievers wrote:
...
Quoted 35 lines
Quoted 5 lines
Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are availableThat all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
Quoted 8 lines
Quoted 3 lines
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
That all is cool, but I'm not sure how it is related to things like
available_clocksourceandcurrent_clocksource(which happen to be located under/sys/devices/system/clocksource/clocksource0/being simply a path in sysfs).Sure, it isn't related to clocksource at all. I didn't really get the idea that there are users that just fake core devices only to get a place to put a couple of attributes. I was still in the context of the $SUBJECT of this thread.
This stuff should just stay away from devices, not sysdev, not "struct device".
For other things like CPUs, which are fine to be represented as driver core devices, all the above is still valid, and they should be real devices and have their own subsystem, which exposes them to coldplug and usual event handling.
Quoted 3 lines
Well, Greg apparently thinks that
available_clocksourceandcurrent_clocksourcecould be located under/sys/bus/clock/. Perhaps other attributes now exported through sysdevs could be moved to places like this?Sure, we could do that. All such subsystems have a directory to put subsystem-global stuff. In this case it would be a subsystem without any registered device. But it leaves us open to add real devices to it later, which might be the case for some similar subsystems.
Quoted 6 lines
The other option would be
/sys/kernel/clocksource/with the few attributes to create.We should decide if "clocksource" is kind of "device-related" or not. Do you have any list of subsystems besides "clocksource", which would help to get a bigger picture what we should expect?
Not at the moment. I'll prepare one while working on syscore_ops patches for the non-x86 architectures.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 71 lines · Kay Sievers
Quoted 39 lines · Rafael J. Wysocki
Quoted 2 lines · Kay Sievers
Quoted 1 line · Rafael J. Wysocki
On Tuesday, March 22, 2011, Kay Sievers wrote:
...
Quoted 35 lines
Quoted 5 lines
Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are availableThat all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
Quoted 8 lines
Quoted 3 lines
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
That all is cool, but I'm not sure how it is related to things like
available_clocksourceandcurrent_clocksource(which happen to be located under/sys/devices/system/clocksource/clocksource0/being simply a path in sysfs).Sure, it isn't related to clocksource at all. I didn't really get the idea that there are users that just fake core devices only to get a place to put a couple of attributes. I was still in the context of the $SUBJECT of this thread.
This stuff should just stay away from devices, not sysdev, not "struct device".
For other things like CPUs, which are fine to be represented as driver core devices, all the above is still valid, and they should be real devices and have their own subsystem, which exposes them to coldplug and usual event handling.
Quoted 3 lines
Well, Greg apparently thinks that
available_clocksourceandcurrent_clocksourcecould be located under/sys/bus/clock/. Perhaps other attributes now exported through sysdevs could be moved to places like this?Sure, we could do that. All such subsystems have a directory to put subsystem-global stuff. In this case it would be a subsystem without any registered device. But it leaves us open to add real devices to it later, which might be the case for some similar subsystems.
Quoted 6 lines
The other option would be
/sys/kernel/clocksource/with the few attributes to create.We should decide if "clocksource" is kind of "device-related" or not. Do you have any list of subsystems besides "clocksource", which would help to get a bigger picture what we should expect?
Not at the moment. I'll prepare one while working on syscore_ops patches for the non-x86 architectures.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 39 lines · Rafael J. Wysocki
Quoted 2 lines · Kay Sievers
Quoted 1 line · Rafael J. Wysocki
On Tuesday, March 22, 2011, Kay Sievers wrote:
...
Quoted 35 lines
Quoted 5 lines
Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are availableThat all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
Quoted 8 lines
Quoted 3 lines
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
That all is cool, but I'm not sure how it is related to things like
available_clocksourceandcurrent_clocksource(which happen to be located under/sys/devices/system/clocksource/clocksource0/being simply a path in sysfs).
Sure, it isn't related to clocksource at all. I didn't really get the idea that there are users that just fake core devices only to get a place to put a couple of attributes. I was still in the context of the $SUBJECT of this thread.
This stuff should just stay away from devices, not sysdev, not "struct device".
For other things like CPUs, which are fine to be represented as driver core devices, all the above is still valid, and they should be real devices and have their own subsystem, which exposes them to coldplug and usual event handling.
Quoted 3 lines
Well, Greg apparently thinks that
available_clocksourceandcurrent_clocksourcecould be located under/sys/bus/clock/. Perhaps other attributes now exported through sysdevs could be moved to places like this?
Sure, we could do that. All such subsystems have a directory to put subsystem-global stuff. In this case it would be a subsystem without any registered device. But it leaves us open to add real devices to it later, which might be the case for some similar subsystems.
The other option would be /sys/kernel/clocksource/ with the few attributes to create.
We should decide if "clocksource" is kind of "device-related" or not. Do you have any list of subsystems besides "clocksource", which would help to get a bigger picture what we should expect?
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 2 lines · Kay Sievers
Quoted 1 line · Rafael J. Wysocki
On Tuesday, March 22, 2011, Kay Sievers wrote:
...
Quoted 31 lines
Quoted 5 lines
Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are availableThat all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Quoted 7 lines
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
That all is cool, but I'm not sure how it is related to things like available_clocksource and current_clocksource (which happen to be located under /sys/devices/system/clocksource/clocksource0/ being simply a path in sysfs).
Quoted 4 lines
When we started to clean up /sys (again only talking about devices, not other stuff) we had:
/block/*
/class/<subsys>/*
Quoted 8 lines
/bus/<subsys>/devices/*
/devices/system/<subsys>/*
which are 4 different exports of exactly the same thing, a "device". "Block" we converted to "class" already, "class" will be converted to "bus", and "bus" will be renamed to "subsystem". All the current names will be kept as compat symlinks, just as we did for "block". After that, _all_ devices have a "subsystem" and a subsystem global directory where people can add custom stuff shared by all devices-of-the-same-type. Ev
OK, sounds good.
Quoted 5 lines
You can also argument from the other side, if a kernel device export is not worth the few bytes of
/sys/devices/and a "subsystem" (structbus_type) it should not be in /sys at all, especially not hidden somehwere outside of/sys/deviceswhen it is something remotely close to a device.
Well, Greg apparently thinks that available_clocksource and current_clocksource could be located under /sys/bus/clock/. Perhaps other attributes now exported through sysdevs could be moved to places like this?
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 10 lines · Kay Sievers
When we started to clean up /sys (again only talking about devices, not other stuff) we had:
/block/*
/class/<subsys>/*
/bus/<subsys>/devices/*
/devices/system/<subsys>/*
which are 4 different exports of exactly the same thing, a "device". "Block" we converted to "class" already, "class" will be converted to "bus", and "bus" will be renamed to "subsystem". All the current names will be kept as compat symlinks, just as we did for "block".
I bet userspace will end up failing with that and need updating yet again, inspite of the symlinks.
While Linus complains about the churn in the ARM subtree, I'd like to officially complain about the pointless churn in sysfs which actively breaks (and sometimes prevents) userspace booting when you upgrade kernels.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 10 lines · Kay Sievers
When we started to clean up /sys (again only talking about devices, not other stuff) we had:
/block/*
/class/<subsys>/*
/bus/<subsys>/devices/*
/devices/system/<subsys>/*
which are 4 different exports of exactly the same thing, a "device". "Block" we converted to "class" already, "class" will be converted to "bus", and "bus" will be renamed to "subsystem". All the current names will be kept as compat symlinks, just as we did for "block".
I bet userspace will end up failing with that and need updating yet again, inspite of the symlinks.
While Linus complains about the churn in the ARM subtree, I'd like to officially complain about the pointless churn in sysfs which actively breaks (and sometimes prevents) userspace booting when you upgrade kernels.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 67 lines · Rafael J. Wysocki
Quoted 1 line · Kay Sievers
On Wed, 2011-03-23 at 06:49 +0900, Paul Mundt wrote:
...
Quoted 18 lines
Quoted 18 lines
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with
/sys/poweror making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Quoted 6 lines
Quoted 6 lines
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example
arch/sh/kernel/cpu/sh4/sq.c-- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother.The reason why is, if I understand it correctly, because user space tools generally expect
/sys/devices/to be consistent in terms of the representation of things and/sys/devices/system/currently violates that expectation which leads to all sorts of problems with device discovery, hotplug etc.Now, whether or not to convert all the things currently exported through sysdevs to struct device objects is not too obvious to me. I think it simply may be better to move them into a different direcory in sysfs (presumably creating one for this purpose).
Quoted 21 lines
Quoted 9 lines
I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Nope, a device has a "name", a "subsystem" and a "devpath", has well-defined core-maintained properties at the device directory. It is not some random custom directory which people can put where they like it. Userspace has expectations about devices which need to be met, and that can only happen if these devices are "struct device".
All real devices sort into a hierarchy, possibly in different parent locations, and have a single point of classification which is the devices/ directory and contains symlinks. Only that way we can cope with it in userspace.
Quoted 7 lines
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
Quoted 7 lines
I really think you shouldn't say "sysfs" when you in fact you mean "
/sys/devices/". :-)Now, I can easily understand arguments about representing everything under
/sys/devices/by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment insys.c, presumably outside of/sys/devices/.
No, please. We have all we need. Let's do one example, which you might apply to any other thing, because you never know what's the next big thing in hardware. We need to be a future-proof-as-possible, and that's not some second-class out-of-scope sysfs directory.
Lets' take CPUs:
- they send events when registered
- they want to export device specific properties
- userspace wants to take actions when such devices are available
That all fits properly into the driver model in theory. Unless you do coldplug and bootup a box.
These devices are already there before userspace even starts, hence we find all these devices and "trigger" an fake uevent for all of them at bootup. That will match execute all the rules specified for that device, just as it would be hotplugges in that moment, hence we call it coldplug, which works for all devices with the hotplug code, even when they are never hot-pluggable.
What we do for coldplug is that we iterate over all flat lists of subsystems and find the devices lists and trigger the event by poking in the "uevent" sysfs file. Now all the sysdevs do not have a subsystem to find, and do not have a standard "uevent" file.
Back to the CPUs, we have all the nice device directories which could have all the CPU features in properties we need to make autoloading of cpufreq, governer, kvm possible (patch exists from Andi Kleen already)
But these dumb CPU sysfs device directories are completely invisible for the *usual* logic, and should just join the model and all will just work out-of-the-box.
When we started to clean up /sys (again only talking about devices, not other stuff) we had:
/block/*
/class/<subsys>/*
/bus/<subsys>/devices/*
/devices/system/<subsys>/*
which are 4 different exports of exactly the same thing, a "device". "Block" we converted to "class" already, "class" will be converted to "bus", and "bus" will be renamed to "subsystem". All the current names will be kept as compat symlinks, just as we did for "block". After that, _all_ devices have a "subsystem" and a subsystem global directory where people can add custom stuff shared by all devices-of-the-same-type. Ev
You can also argument from the other side, if a kernel device export is not worth the few bytes of /sys/devices/ and a "subsystem" (struct bus_type) it should not be in /sys at all, especially not hidden somehwere outside of /sys/devices when it is something remotely close to a device.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 1 line · Kay Sievers
On Wed, 2011-03-23 at 06:49 +0900, Paul Mundt wrote:
...
Quoted 18 lines
Quoted 18 lines
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with
/sys/poweror making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Quoted 6 lines
Quoted 6 lines
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example
arch/sh/kernel/cpu/sh4/sq.c-- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother.
The reason why is, if I understand it correctly, because user space tools generally expect /sys/devices/ to be consistent in terms of the representation of things and /sys/devices/system/ currently violates that expectation which leads to all sorts of problems with device discovery, hotplug etc.
Now, whether or not to convert all the things currently exported through sysdevs to struct device objects is not too obvious to me. I think it simply may be better to move them into a different direcory in sysfs (presumably creating one for this purpose).
Quoted 21 lines
Quoted 9 lines
I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Nope, a device has a "name", a "subsystem" and a "devpath", has well-defined core-maintained properties at the device directory. It is not some random custom directory which people can put where they like it. Userspace has expectations about devices which need to be met, and that can only happen if these devices are "struct device".
All real devices sort into a hierarchy, possibly in different parent locations, and have a single point of classification which is the devices/ directory and contains symlinks. Only that way we can cope with it in userspace.
Quoted 7 lines
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
I really think you shouldn't say "sysfs" when you in fact you mean "/sys/devices/". :-)
Now, I can easily understand arguments about representing everything under /sys/devices/ by struct device objects, no question about that. However, I also think there should be a place for things like those mentioned in the comment in sys.c, presumably outside of /sys/devices/.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 8 lines · Kay Sievers
Quoted 3 lines · Paul Mundt
The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
So far I haven't heard any rationale for why it doesn't. Exporting CPU state to userspace certainly makes sense, and the sysdev model has worked reasonably for CPUs, memory nodes, etc.
Quoted 8 lines
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
As long as CPU state is present in sysfs people will be tied to it for per-CPU kobjects and the like, and until something concrete is proposed for what to do about these cases there's not much chance of sysdevs going away.
Once cpufreq, timekeeping, and NUMA node state have migrated to whatever the driver model folks find acceptable, I'll happily follow suit.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 8 lines · Paul Mundt
Quoted 2 lines · Kay Sievers
Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
So far I haven't heard any rationale for why it doesn't. Exporting CPU state to userspace certainly makes sense, and the sysdev model has worked reasonably for CPUs, memory nodes, etc.
FWIW it'd be really helpful to have CPUs (or at least SoCs) be regular struct devices for integration with the regulator API so we can have all things that might use a regulator (like DVFS) be struct devices but...
Quoted 2 lines
Once cpufreq, timekeeping, and NUMA node state have migrated to whatever the driver model folks find acceptable, I'll happily follow suit.
...we're not precisely there yet :/
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 6 lines · Mark Brown
Quoted 4 lines · Paul Mundt
Quoted 2 lines · Kay Sievers
Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
Quoted 8 lines
Quoted 3 lines
So far I haven't heard any rationale for why it doesn't. Exporting CPU state to userspace certainly makes sense, and the sysdev model has worked reasonably for CPUs, memory nodes, etc.
FWIW it'd be really helpful to have CPUs (or at least SoCs) be regular struct devices for integration with the regulator API so we can have all things that might use a regulator (like DVFS) be struct devices but...
Sure, that makes sense. The easiest would probably be to just replace the struct cpu sysdev with a struct device pointer and fix up drivers/base/cpu.c accordingly. The linux/cpu.h API is unfortunately rather coupled to the idea of having a sysdev, but this is purely for attributes and attribute groups and primarily impacts powerpc, so the conversion shouldn't be too painful. For simple topology registration the bulk of the architectures ultimately don't care what's backing the struct cpu within the sysfs context.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Mark BrownQuoted 6 lines · Mark Brown
Quoted 4 lines · Paul Mundt
Quoted 2 lines · Kay Sievers
Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
Quoted 8 lines
Quoted 3 lines
So far I haven't heard any rationale for why it doesn't. Exporting CPU state to userspace certainly makes sense, and the sysdev model has worked reasonably for CPUs, memory nodes, etc.
FWIW it'd be really helpful to have CPUs (or at least SoCs) be regular struct devices for integration with the regulator API so we can have all things that might use a regulator (like DVFS) be struct devices but...
Sure, that makes sense. The easiest would probably be to just replace the struct cpu sysdev with a struct device pointer and fix up drivers/base/cpu.c accordingly. The linux/cpu.h API is unfortunately rather coupled to the idea of having a sysdev, but this is purely for attributes and attribute groups and primarily impacts powerpc, so the conversion shouldn't be too painful. For simple topology registration the bulk of the architectures ultimately don't care what's backing the struct cpu within the sysfs context.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Paul MundtQuoted 8 lines · Paul Mundt
Quoted 2 lines · Kay Sievers
Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
So far I haven't heard any rationale for why it doesn't. Exporting CPU state to userspace certainly makes sense, and the sysdev model has worked reasonably for CPUs, memory nodes, etc.
FWIW it'd be really helpful to have CPUs (or at least SoCs) be regular struct devices for integration with the regulator API so we can have all things that might use a regulator (like DVFS) be struct devices but...
Quoted 2 lines
Once cpufreq, timekeeping, and NUMA node state have migrated to whatever the driver model folks find acceptable, I'll happily follow suit.
...we're not precisely there yet :/
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 8 lines · Kay Sievers
Quoted 3 lines · Paul Mundt
The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
So far I haven't heard any rationale for why it doesn't. Exporting CPU state to userspace certainly makes sense, and the sysdev model has worked reasonably for CPUs, memory nodes, etc.
Quoted 8 lines
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
As long as CPU state is present in sysfs people will be tied to it for per-CPU kobjects and the like, and until something concrete is proposed for what to do about these cases there's not much chance of sysdevs going away.
Once cpufreq, timekeeping, and NUMA node state have migrated to whatever the driver model folks find acceptable, I'll happily follow suit.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Paul MundtQuoted 33 lines · Paul Mundt
Quoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 6 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
This is starting to get silly. In the case of interrupt controllers as with clocksources the bus abstraction is completely meaningless. I could register a type of "system" bus, but how would that be any different from what we have from sysdevs already today? All it does is force people to duplicate crap all over the place instead and pretend like extra busses exist in order to fit some arbitrary definition of how the driver model should work.
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with
/sys/poweror making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.
Quoted 3 lines
The comment at the top of
sys.csays:*
sys.c- pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
Which is what we need to get rid of. It does not make any sense on the global picture to have anything like that exported to userspace.
Quoted 18 lines
Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example
arch/sh/kernel/cpu/sh4/sq.c-- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother. I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Quoted 5 lines
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Nope, a device has a "name", a "subsystem" and a "devpath", has well-defined core-maintained properties at the device directory. It is not some random custom directory which people can put where they like it. Userspace has expectations about devices which need to be met, and that can only happen if these devices are "struct device".
All real devices sort into a hierarchy, possibly in different parent locations, and have a single point of classification which is the devices/ directory and contains symlinks. Only that way we can cope with it in userspace.
People should really stop messing around in /sys for optimization purposes. We have a common device model, and need to use it. Sysdevs do not fit into that model.
I can't tell how that fits into your use case, but please use something else than sysfs, if you need device information exported, but you can't use "struct device".
Thanks,
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 6 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
This is starting to get silly. In the case of interrupt controllers as with clocksources the bus abstraction is completely meaningless. I could register a type of "system" bus, but how would that be any different from what we have from sysdevs already today? All it does is force people to duplicate crap all over the place instead and pretend like extra busses exist in order to fit some arbitrary definition of how the driver model should work.
You talk about inventing special interfaces to bypass the device model, but that's not the case here. Rolling my own interface with kobjects and attribute groups as with /sys/power or making an arbitrary bus type for a single class of system devices seems infinitely more hackish than the current sysdev model.
The comment at the top of sys.c says:
* sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
Which is precisely where I would expect interrupt controllers and timers and CPUs to go. I'm not going to make an IRQ bus or a timer bus and arbitrarily map some things there and some things somewhere else in the name of some abstraction insanity. These interrupt controllers all have consistent attributes that make the sysdev class model work well, but there are also many other types of interrupt controllers on the same CPUs that use a different abstraction.
Beyond that, we also have sysdev class utilization for DMA controllers, per-CPU store queues, etc, etc. all of which would need to be converted to something else (see for example arch/sh/kernel/cpu/sh4/sq.c -- which in turn was modelled after the cpufreq code, which also would need to change to something else). It's not entirely obvious how to convert these things, or why one should even bother. I can live with the struct device overhead even if I find it to be a meaningless abstraction in this case, but what sort of bus/class model to shoe horn these things in to is rather beyond me.
Indeed it seems to me that these are precisely the sorts of things that sysdevs are intended for, which is why I elected to use them from the onset. Simply saying "don't use sysdevs" and "pretend like you have some sort of a magical pseudo-bus that's not a system bus" doesn't quite do it for me.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 5 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
So it looks like the the problem is that the exported attributes happen to be under /sys/devices/. Would it still be a problem if they were somewhere else?
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
OK, I understand that.
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like /sys/platform/ (in analogy with /sys/firmware/)?
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Quoted 8 lines
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
No, I don't.
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.
Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
Quoted 6 lines
Quoted 1 line
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of /sys/devices/ ?
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
Quoted 6 lines
On usual boxes it's udev/libudev and all the stuff around it. But andreoid has the same stuff in their own way of doing it. So it's not about an implementation in userspace, it's about a sane event and classification interface for kernel-exported devices. Again tis is not about any other stuff in /sys, only the "devices", and we want to have only a single type, and a single way to handle it in userspace.
OK
Quoted 17 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Quoted 5 lines
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Quoted 4 lines
Because they are devices, and there is a lot to win, if the kernel exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under /sys/devices/ been represented by struct device objects and there are good reasons to do that.
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 15 lines · Rafael J. Wysocki
Quoted 14 lines · Kay Sievers
Quoted 12 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Quoted 7 lines
Quoted 3 lines
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
So it looks like the the problem is that the exported attributes happen to be under
/sys/devices/. Would it still be a problem if they were somewhere else?
We are not going to invent another location for any devices. They need to stay in /devices if they are devices. And all devices need to be "struct device".
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
Quoted 5 lines
OK, I understand that.
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like
/sys/platform/(in analogy with/sys/firmware/)?
No, add a subsystem (bus_type) for any of them, and register them. There is no such thing as "devices which do not fit the device model", they are all fine there. Please stop optimizing single bytes and creating a mess in /sys. Every device is a "struct device".
Think of "struct bus_type" as "struct subsystem", we will rename that when we are ready. It is just a group of devices which are of the same type, it has nothing to do with a bus in the sense of hardware.
We need unified exports of _all devices to userspace, not custom layouts in /sys.
There's is a pretty much outdated Documentation/sysfs-rules.txt, wich covers part of the history and the plans.
Quoted 11 lines
Quoted 11 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
No, I don't.
Then all is fine. All other stuff is more like /proc, and can never be really unified. All we care about is devices, which have common methods for userspace to trigger and consume, and need to be unified. Power specific control files seems all fine in its kobject use.
Quoted 11 lines
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
It should be pretty straight-forward. We will need to do that for CPUs I guess, because the interface is kinda commonly used.
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
Quoted 7 lines
Quoted 3 lines
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
Quoted 7 lines
Quoted 4 lines
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of
/sys/devices/?
No, no device directory can be outside of /sys/devices.
Quoted 41 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
Quoted 6 lines
On usual boxes it's udev/libudev and all the stuff around it. But andreoid has the same stuff in their own way of doing it. So it's not about an implementation in userspace, it's about a sane event and classification interface for kernel-exported devices. Again tis is not about any other stuff in /sys, only the "devices", and we want to have only a single type, and a single way to handle it in userspace.
OK
Quoted 17 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Quoted 5 lines
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Quoted 4 lines
Because they are devices, and there is a lot to win, if the kernel exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under
/sys/devices/been represented by struct device objects and there are good reasons to do that.
Quoted 5 lines
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
We can just keep the same location for anything that is expected to be in /sys/devices/system. All outside visible difference is that these devices (then struct device) also have a "subsystem" (bus_type) which carries the flat list of devices, the devices have a "uevent" file and with that they are coldpluggable, event re-triggerable, could have modalias, ... and all the other 1000 things that just work today, and what we need for many of them. They are then just handled like any other exported device too.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 20 lines · Kay Sievers
Quoted 19 lines · Rafael J. Wysocki
Quoted 17 lines · Kay Sievers
Quoted 7 lines · Rafael J. Wysocki
Quoted 6 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
Quoted 5 lines
Quoted 3 lines
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
Quoted 7 lines
Quoted 3 lines
So it looks like the the problem is that the exported attributes happen to be under
/sys/devices/. Would it still be a problem if they were somewhere else?We are not going to invent another location for any devices. They need to stay in /devices if they are devices. And all devices need to be "struct device".
_They_ _are_ _not_ _devices_.
Please take clocksource as an example. It needs to export two attributes, available_clocksource and current_clocksource, which are _useful_ user space interfaces. Why the heck are you trying to convince me it's a good idea to create a special bus type and struct device _specifically_ for exporting them?!
Moreover, is there anything device-alike in those two attributes? I don't really think so.
So please stop arguing this way, because it simply isn't going to fly and people will always say a big fat "no" to such ideas, for a good reason.
Quoted 13 lines
Quoted 13 lines
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
OK, I understand that.
Quoted 8 lines
Quoted 3 lines
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like
/sys/platform/(in analogy with/sys/firmware/)?No, add a subsystem (
bus_type) for any of them, and register them. There is no such thing as "devices which do not fit the device model", they are all fine there. Please stop optimizing single bytes and creating a mess in /sys. Every device is a "struct device".
Again. Those things are _not_ devices. Am I not clear enough?
Quoted 9 lines
Think of "struct
bus_type" as "struct subsystem", we will rename that when we are ready. It is just a group of devices which are of the same type, it has nothing to do with a bus in the sense of hardware.We need unified exports of
_alldevices to userspace, not custom layouts in /sys.There's is a pretty much outdated
Documentation/sysfs-rules.txt, wich covers part of the history and the plans.
You seem to be thinking that anything exported through sysfs needs to be device, which I don't think is event approximately correct (what about /sys/firmware/ or /sys/kernel/ or /sys/fs/ , for a few examples?).
Think this way: it is useful (and IMHO correct) to export some things to user space that without necessarily regarding them as "devices", physical or not. Some of them _happen_ to be exported through sysdevs, but that doesn't really mean the _are_ devices. They are simply _software_ interfaces to things that have no device representation and don't _need_ one.
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
No, I don't.
Then all is fine. All other stuff is more like /proc, and can never be really unified.
YES! And _that_'s precisely what I'm (and Paul is) talking about.
Quoted 3 lines
All we care about is devices, which have common methods for userspace to trigger and consume, and need to be unified. Power specific control files seems all fine in its kobject use.
I understand that, really.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.
Quoted 5 lines
Quoted 2 lines
Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
It should be pretty straight-forward. We will need to do that for CPUs I guess, because the interface is kinda commonly used.
No. CPUs are _very_ special.
Quoted 22 lines
Quoted 22 lines
Quoted 21 lines
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
Quoted 5 lines
Quoted 3 lines
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Quoted 4 lines
Quoted 2 lines
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of
/sys/devices/?No, no device directory can be outside of
/sys/devices.
Sorry, I'm repeating that for the last time. I'm not talking about devices. I'm talking about _totally_ _random_ _stuff_ which is "like /proc, and can never be really unified" (your own words) which _happens_ to be exported through the sysdev interface, because that happend to be _easy_ at one point. Can we agree on that at least?
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 25 lines · Rafael J. Wysocki
Quoted 24 lines · Kay Sievers
Quoted 22 lines · Rafael J. Wysocki
Quoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 5 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
So it looks like the the problem is that the exported attributes happen to be under
/sys/devices/. Would it still be a problem if they were somewhere else?
Quoted 5 lines
Quoted 3 lines
We are not going to invent another location for any devices. They need to stay in /devices if they are devices. And all devices need to be "struct device".
_They_ _are_ _not_ _devices_.
Ah, I see. Then they should not ever have been created as a sysdev in the first place. I thought you did only talk about stuff that needs pm_ops. If they don't do anything like a device, they need to go somewhere else, yes.
Quoted 10 lines
Please take clocksource as an example. It needs to export two attributes,
available_clocksourceandcurrent_clocksource, which are _useful_ user space interfaces. Why the heck are you trying to convince me it's a good idea to create a special bus type and struct device _specifically_ for exporting them?!Moreover, is there anything device-alike in those two attributes? I don't really think so.
So please stop arguing this way, because it simply isn't going to fly and people will always say a big fat "no" to such ideas, for a good reason.
I never expected anything like that to use a sysdev. I'm not tryin gto convince you about anything, I'm just surprised what people do, well I'm not after all the years. :)
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
OK, I understand that.
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like
/sys/platform/(in analogy with/sys/firmware/)?
Quoted 6 lines
Quoted 4 lines
No, add a subsystem (
bus_type) for any of them, and register them. There is no such thing as "devices which do not fit the device model", they are all fine there. Please stop optimizing single bytes and creating a mess in /sys. Every device is a "struct device".Again. Those things are _not_ devices. Am I not clear enough?
No that wasn't clear. They need to leave the driver core then, if they are not devices. :)
Quoted 7 lines
Quoted 7 lines
Think of "struct
bus_type" as "struct subsystem", we will rename that when we are ready. It is just a group of devices which are of the same type, it has nothing to do with a bus in the sense of hardware.We need unified exports of
_alldevices to userspace, not custom layouts in /sys.
Quoted 6 lines
Quoted 2 lines
There's is a pretty much outdated
Documentation/sysfs-rules.txt, wich covers part of the history and the plans.You seem to be thinking that anything exported through sysfs needs to be device, which I don't think is event approximately correct (what about
/sys/firmware/or/sys/kernel/or/sys/fs/, for a few examples?).
All fine. Again, I'm only talking about "devices", which is class/, block/, bus/, dev/, devices/ in /sys.
Quoted 5 lines
Think this way: it is useful (and IMHO correct) to export some things to user space that without necessarily regarding them as "devices", physical or not. Some of them _happen_ to be exported through sysdevs, but that doesn't really mean the _are_ devices. They are simply _software_ interfaces to things that have no device representation and don't _need_ one.
Fine, they need to leave the driver core stuff alone, and not pretend to be a device.
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
No, I don't.
Then all is fine. All other stuff is more like /proc, and can never be really unified.
YES! And _that_'s precisely what I'm (and Paul is) talking about.
Good.
Quoted 15 lines
Quoted 3 lines
All we care about is devices, which have common methods for userspace to trigger and consume, and need to be unified. Power specific control files seems all fine in its kobject use.
I understand that, really.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
It should be pretty straight-forward. We will need to do that for CPUs I guess, because the interface is kinda commonly used.
No. CPUs are _very_ special.
Not in the view of the driver core or the associated user space interfaces. They are just like any other device.
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
Quoted 6 lines
Quoted 1 line
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of
/sys/devices/?
Quoted 7 lines
Quoted 1 line
No, no device directory can be outside of
/sys/devices.Sorry, I'm repeating that for the last time. I'm not talking about devices. I'm talking about _totally_ _random_ _stuff_ which is "like /proc, and can never be really unified" (your own words) which _happens_ to be exported through the sysdev interface, because that happend to be _easy_ at one point. Can we agree on that at least?
Sure, they should leave the driver core alone, and should never been a sysdev or any other device in the first place. We should not create anything for them.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 25 lines · Rafael J. Wysocki
Quoted 24 lines · Kay Sievers
Quoted 22 lines · Rafael J. Wysocki
Quoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 5 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
So it looks like the the problem is that the exported attributes happen to be under
/sys/devices/. Would it still be a problem if they were somewhere else?
Quoted 5 lines
Quoted 3 lines
We are not going to invent another location for any devices. They need to stay in /devices if they are devices. And all devices need to be "struct device".
_They_ _are_ _not_ _devices_.
Ah, I see. Then they should not ever have been created as a sysdev in the first place. I thought you did only talk about stuff that needs pm_ops. If they don't do anything like a device, they need to go somewhere else, yes.
Quoted 10 lines
Please take clocksource as an example. It needs to export two attributes,
available_clocksourceandcurrent_clocksource, which are _useful_ user space interfaces. Why the heck are you trying to convince me it's a good idea to create a special bus type and struct device _specifically_ for exporting them?!Moreover, is there anything device-alike in those two attributes? I don't really think so.
So please stop arguing this way, because it simply isn't going to fly and people will always say a big fat "no" to such ideas, for a good reason.
I never expected anything like that to use a sysdev. I'm not tryin gto convince you about anything, I'm just surprised what people do, well I'm not after all the years. :)
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
OK, I understand that.
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like
/sys/platform/(in analogy with/sys/firmware/)?
Quoted 6 lines
Quoted 4 lines
No, add a subsystem (
bus_type) for any of them, and register them. There is no such thing as "devices which do not fit the device model", they are all fine there. Please stop optimizing single bytes and creating a mess in /sys. Every device is a "struct device".Again. Those things are _not_ devices. Am I not clear enough?
No that wasn't clear. They need to leave the driver core then, if they are not devices. :)
Quoted 7 lines
Quoted 7 lines
Think of "struct
bus_type" as "struct subsystem", we will rename that when we are ready. It is just a group of devices which are of the same type, it has nothing to do with a bus in the sense of hardware.We need unified exports of
_alldevices to userspace, not custom layouts in /sys.
Quoted 6 lines
Quoted 2 lines
There's is a pretty much outdated
Documentation/sysfs-rules.txt, wich covers part of the history and the plans.You seem to be thinking that anything exported through sysfs needs to be device, which I don't think is event approximately correct (what about
/sys/firmware/or/sys/kernel/or/sys/fs/, for a few examples?).
All fine. Again, I'm only talking about "devices", which is class/, block/, bus/, dev/, devices/ in /sys.
Quoted 5 lines
Think this way: it is useful (and IMHO correct) to export some things to user space that without necessarily regarding them as "devices", physical or not. Some of them _happen_ to be exported through sysdevs, but that doesn't really mean the _are_ devices. They are simply _software_ interfaces to things that have no device representation and don't _need_ one.
Fine, they need to leave the driver core stuff alone, and not pretend to be a device.
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
No, I don't.
Then all is fine. All other stuff is more like /proc, and can never be really unified.
YES! And _that_'s precisely what I'm (and Paul is) talking about.
Good.
Quoted 15 lines
Quoted 3 lines
All we care about is devices, which have common methods for userspace to trigger and consume, and need to be unified. Power specific control files seems all fine in its kobject use.
I understand that, really.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
It should be pretty straight-forward. We will need to do that for CPUs I guess, because the interface is kinda commonly used.
No. CPUs are _very_ special.
Not in the view of the driver core or the associated user space interfaces. They are just like any other device.
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
Quoted 6 lines
Quoted 1 line
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of
/sys/devices/?
Quoted 7 lines
Quoted 1 line
No, no device directory can be outside of
/sys/devices.Sorry, I'm repeating that for the last time. I'm not talking about devices. I'm talking about _totally_ _random_ _stuff_ which is "like /proc, and can never be really unified" (your own words) which _happens_ to be exported through the sysdev interface, because that happend to be _easy_ at one point. Can we agree on that at least?
Sure, they should leave the driver core alone, and should never been a sysdev or any other device in the first place. We should not create anything for them.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 20 lines · Kay Sievers
Quoted 19 lines · Rafael J. Wysocki
Quoted 17 lines · Kay Sievers
Quoted 7 lines · Rafael J. Wysocki
Quoted 6 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
Quoted 5 lines
Quoted 3 lines
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
Quoted 7 lines
Quoted 3 lines
So it looks like the the problem is that the exported attributes happen to be under
/sys/devices/. Would it still be a problem if they were somewhere else?We are not going to invent another location for any devices. They need to stay in /devices if they are devices. And all devices need to be "struct device".
_They_ _are_ _not_ _devices_.
Please take clocksource as an example. It needs to export two attributes, available_clocksource and current_clocksource, which are _useful_ user space interfaces. Why the heck are you trying to convince me it's a good idea to create a special bus type and struct device _specifically_ for exporting them?!
Moreover, is there anything device-alike in those two attributes? I don't really think so.
So please stop arguing this way, because it simply isn't going to fly and people will always say a big fat "no" to such ideas, for a good reason.
Quoted 13 lines
Quoted 13 lines
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
OK, I understand that.
Quoted 8 lines
Quoted 3 lines
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like
/sys/platform/(in analogy with/sys/firmware/)?No, add a subsystem (
bus_type) for any of them, and register them. There is no such thing as "devices which do not fit the device model", they are all fine there. Please stop optimizing single bytes and creating a mess in /sys. Every device is a "struct device".
Again. Those things are _not_ devices. Am I not clear enough?
Quoted 9 lines
Think of "struct
bus_type" as "struct subsystem", we will rename that when we are ready. It is just a group of devices which are of the same type, it has nothing to do with a bus in the sense of hardware.We need unified exports of
_alldevices to userspace, not custom layouts in /sys.There's is a pretty much outdated
Documentation/sysfs-rules.txt, wich covers part of the history and the plans.
You seem to be thinking that anything exported through sysfs needs to be device, which I don't think is event approximately correct (what about /sys/firmware/ or /sys/kernel/ or /sys/fs/ , for a few examples?).
Think this way: it is useful (and IMHO correct) to export some things to user space that without necessarily regarding them as "devices", physical or not. Some of them _happen_ to be exported through sysdevs, but that doesn't really mean the _are_ devices. They are simply _software_ interfaces to things that have no device representation and don't _need_ one.
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
No, I don't.
Then all is fine. All other stuff is more like /proc, and can never be really unified.
YES! And _that_'s precisely what I'm (and Paul is) talking about.
Quoted 3 lines
All we care about is devices, which have common methods for userspace to trigger and consume, and need to be unified. Power specific control files seems all fine in its kobject use.
I understand that, really.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.
Quoted 5 lines
Quoted 2 lines
Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
It should be pretty straight-forward. We will need to do that for CPUs I guess, because the interface is kinda commonly used.
No. CPUs are _very_ special.
Quoted 22 lines
Quoted 22 lines
Quoted 21 lines
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
Quoted 5 lines
Quoted 3 lines
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Quoted 4 lines
Quoted 2 lines
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of
/sys/devices/?No, no device directory can be outside of
/sys/devices.
Sorry, I'm repeating that for the last time. I'm not talking about devices. I'm talking about _totally_ _random_ _stuff_ which is "like /proc, and can never be really unified" (your own words) which _happens_ to be exported through the sysdev interface, because that happend to be _easy_ at one point. Can we agree on that at least?
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 15 lines · Rafael J. Wysocki
Quoted 14 lines · Kay Sievers
Quoted 12 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Quoted 7 lines
Quoted 3 lines
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
So it looks like the the problem is that the exported attributes happen to be under
/sys/devices/. Would it still be a problem if they were somewhere else?
We are not going to invent another location for any devices. They need to stay in /devices if they are devices. And all devices need to be "struct device".
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
Quoted 5 lines
OK, I understand that.
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like
/sys/platform/(in analogy with/sys/firmware/)?
No, add a subsystem (bus_type) for any of them, and register them. There is no such thing as "devices which do not fit the device model", they are all fine there. Please stop optimizing single bytes and creating a mess in /sys. Every device is a "struct device".
Think of "struct bus_type" as "struct subsystem", we will rename that when we are ready. It is just a group of devices which are of the same type, it has nothing to do with a bus in the sense of hardware.
We need unified exports of _all devices to userspace, not custom layouts in /sys.
There's is a pretty much outdated Documentation/sysfs-rules.txt, wich covers part of the history and the plans.
Quoted 11 lines
Quoted 11 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
No, I don't.
Then all is fine. All other stuff is more like /proc, and can never be really unified. All we care about is devices, which have common methods for userspace to trigger and consume, and need to be unified. Power specific control files seems all fine in its kobject use.
Quoted 11 lines
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
It should be pretty straight-forward. We will need to do that for CPUs I guess, because the interface is kinda commonly used.
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
Quoted 7 lines
Quoted 3 lines
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
Quoted 7 lines
Quoted 4 lines
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of
/sys/devices/?
No, no device directory can be outside of /sys/devices.
Quoted 41 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
Quoted 6 lines
On usual boxes it's udev/libudev and all the stuff around it. But andreoid has the same stuff in their own way of doing it. So it's not about an implementation in userspace, it's about a sane event and classification interface for kernel-exported devices. Again tis is not about any other stuff in /sys, only the "devices", and we want to have only a single type, and a single way to handle it in userspace.
OK
Quoted 17 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Quoted 5 lines
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Quoted 4 lines
Because they are devices, and there is a lot to win, if the kernel exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under
/sys/devices/been represented by struct device objects and there are good reasons to do that.
Quoted 5 lines
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
We can just keep the same location for anything that is expected to be in /sys/devices/system. All outside visible difference is that these devices (then struct device) also have a "subsystem" (bus_type) which carries the flat list of devices, the devices have a "uevent" file and with that they are coldpluggable, event re-triggerable, could have modalias, ... and all the other 1000 things that just work today, and what we need for many of them. They are then just handled like any other exported device too.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 11 lines · Rafael J. Wysocki
Quoted 4 lines · Kay Sievers
Quoted 1 line
Because they are devices, and there is a lot to win, if the kernel
exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under
/sys/devices/been represented by struct device objects and there are good reasons to do that.
Quoted 5 lines
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
Ok, now that we sorted the misunderstanding out, let's start this topic from here again. (I really read your reply as: "let's move the CPUS somewhere else")
What's the list of stuff you discovered using sysdevs, which is not a device at all, and has never more than a single instance of stuff of the same type? The clocksource?
And let's find some place for them to put their properties instead of messing around with device from the driver core.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 18 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 4 lines · Kay Sievers
Quoted 1 line
Because they are devices, and there is a lot to win, if the kernel
exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under
/sys/devices/been represented by struct device objects and there are good reasons to do that.Quoted 5 lines
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
Quoted 3 lines
Ok, now that we sorted the misunderstanding out, let's start this topic from here again. (I really read your reply as: "let's move the CPUS somewhere else")
Well, I didn't mean that. :-)
Quoted 6 lines
What's the list of stuff you discovered using sysdevs, which is not a device at all, and has never more than a single instance of stuff of the same type? The clocksource?
And let's find some place for them to put their properties instead of messing around with device from the driver core.
On x86 the clocksource will be the only remaining one after my changes recently posted. In fact, it will be the only remaining one except for the CPUs. :-)
The other architectures are a mixed bag, though. First, there's some exported stuff similar to the clocksource. For one example, there's the "leds" sysdev in arch/arm/kernel/leds.c that appears to export one attribute (in addition to implementing suspend/resume/shutdown which I'm going to move to syscore_ops). Second, there's some outright abuse here-and-there that may be removed entirely. Finally, there are things that probably may be converted to struct devices, in the powerpc tree in particular IIRC.
IMHO all of these things will have to be considered on the case-by-case basis and discussed with the appropriate maintainers.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 18 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 4 lines · Kay Sievers
Quoted 1 line
Because they are devices, and there is a lot to win, if the kernel
exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under
/sys/devices/been represented by struct device objects and there are good reasons to do that.Quoted 5 lines
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
Quoted 3 lines
Ok, now that we sorted the misunderstanding out, let's start this topic from here again. (I really read your reply as: "let's move the CPUS somewhere else")
Well, I didn't mean that. :-)
Quoted 6 lines
What's the list of stuff you discovered using sysdevs, which is not a device at all, and has never more than a single instance of stuff of the same type? The clocksource?
And let's find some place for them to put their properties instead of messing around with device from the driver core.
On x86 the clocksource will be the only remaining one after my changes recently posted. In fact, it will be the only remaining one except for the CPUs. :-)
The other architectures are a mixed bag, though. First, there's some exported stuff similar to the clocksource. For one example, there's the "leds" sysdev in arch/arm/kernel/leds.c that appears to export one attribute (in addition to implementing suspend/resume/shutdown which I'm going to move to syscore_ops). Second, there's some outright abuse here-and-there that may be removed entirely. Finally, there are things that probably may be converted to struct devices, in the powerpc tree in particular IIRC.
IMHO all of these things will have to be considered on the case-by-case basis and discussed with the appropriate maintainers.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 11 lines · Rafael J. Wysocki
Quoted 4 lines · Kay Sievers
Quoted 1 line
Because they are devices, and there is a lot to win, if the kernel
exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under
/sys/devices/been represented by struct device objects and there are good reasons to do that.
Quoted 5 lines
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
Ok, now that we sorted the misunderstanding out, let's start this topic from here again. (I really read your reply as: "let's move the CPUS somewhere else")
What's the list of stuff you discovered using sysdevs, which is not a device at all, and has never more than a single instance of stuff of the same type? The clocksource?
And let's find some place for them to put their properties instead of messing around with device from the driver core.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 12 lines · Kay Sievers
Quoted 11 lines · Rafael J. Wysocki
Quoted 9 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Quoted 5 lines
Quoted 1 line
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
So it looks like the the problem is that the exported attributes happen to be under /sys/devices/. Would it still be a problem if they were somewhere else?
Quoted 10 lines
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
OK, I understand that.
Now, there's stuff that doesn't really match the "device" model. Where is the right place to export that? Perhaps we should add something like /sys/platform/ (in analogy with /sys/firmware/)?
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Quoted 8 lines
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
No, I don't.
Quoted 8 lines
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a
bus_type, and use struct device for all of them, Parent them to/sys/devices/system/if they should keep their location and layout.
Well, I'll be watching what happens to the patch trying to do that, but I'm not going to bet anything on its success. ;-)
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
Quoted 6 lines
Quoted 1 line
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Well, as I said, would it be OK if the things in question happened to be located somewhere outside of /sys/devices/ ?
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
Quoted 6 lines
On usual boxes it's udev/libudev and all the stuff around it. But andreoid has the same stuff in their own way of doing it. So it's not about an implementation in userspace, it's about a sane event and classification interface for kernel-exported devices. Again tis is not about any other stuff in /sys, only the "devices", and we want to have only a single type, and a single way to handle it in userspace.
OK
Quoted 17 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Quoted 5 lines
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Quoted 4 lines
Because they are devices, and there is a lot to win, if the kernel exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
If I understand you correctly, the goal is to have everything under /sys/devices/ been represented by struct device objects and there are good reasons to do that.
In that case we either have to move the things exported via sysdevs somewhere else (presumably having to create that "somewhere" before), or we have to introduce struct device objects specifically for exporting them. I don't really think the latter approach will be very popular, so quite likely we'll need to have a plan for moving those things to different locations.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 7 lines · Rafael J. Wysocki
Quoted 6 lines · Kay Sievers
Quoted 4 lines · Rafael J. Wysocki
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
Quoted 5 lines
Quoted 3 lines
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Sure, "devices" are devices, and devices have well-defines set of properties, not some magic directory, people can mess around with the way they like.
Quoted 6 lines
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Not for "devices". There are rules for devices, which are defined by the driver core, and the sysdev stuff needs to go, because it does not fit into that model.
Quoted 7 lines
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Oh, don't get me wrong, this is all is about "devices" not any other controls.
Quoted 2 lines
Still, I won't let you change the things in
/sys/powerto struct devices, sorry about that. ;-)
Fine as long as they are power specific things, and not "devices". You don't have sysdevs there, right? :)
Quoted 4 lines
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Nope, register a bus_type, and use struct device for all of them, Parent them to /sys/devices/system/ if they should keep their location and layout.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
Quoted 5 lines
Quoted 3 lines
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
It has. As for CPUs. We can not do proper CPU-dependent module autoloading, because the events happen before userspace runs, and clodplug can not see the broken sysdevs, because they have no events to re-trigger, like all others have.
Quoted 5 lines
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
On usual boxes it's udev/libudev and all the stuff around it. But andreoid has the same stuff in their own way of doing it. So it's not about an implementation in userspace, it's about a sane event and classification interface for kernel-exported devices. Again tis is not about any other stuff in /sys, only the "devices", and we want to have only a single type, and a single way to handle it in userspace.
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Quoted 5 lines
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Because they are devices, and there is a lot to win, if the kernel exports all "devices" in the same way. This is not about saving an inode in /sys, it's the ability to do runtime device configuration with common tools.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 63 lines · Kay Sievers
Quoted 62 lines · Rafael J. Wysocki
Quoted 48 lines · Kay Sievers
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
Quoted 6 lines
If you need the userspace visibility, better just add a "struct
bus_type" with a proper name for your subsystem and register a "struct device" with thebus_typeassigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.I don't really think that's going to be useful in this particular case. The reason is, first, because the struct device would cause lots of other stuff to show up in sysfs which would be totally redundant and confusing and, second, because the things exported here are simply static attributes, pretty much like the stuff in
/sys/power/.
Quoted 7 lines
Quoted 3 lines
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases.
Why exactly? Do they actually hurt anyone and if so then how?
Quoted 2 lines
Userspace is not meant to learn subsystem specific rules for every new thing.
That depends a good deal of who's writing the user space in question. If that's the same person who's working on the particular part of the kernel, I don't see a big problem.
Quoted 5 lines
There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Oh, good to know. It's changed a bit since I last heard. Never mind.
Still, I won't let you change the things in /sys/power to struct devices, sorry about that. ;-)
And I wonder how are you going to deal with clocksource exporting things via the sysdev interface right now. I'd simply create two directories and put the two files into them and be done with that, but I guess that wouldn't fit into the model somehow, right?
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
Quoted 7 lines
Quoted 3 lines
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up.
I'd say the case at hand has nothing to do with that.
Quoted 2 lines
That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
My impression is that when you say "user space", you actually mean some _specific_ user space, don't you?
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Well, it's not a "device wants to export something". It's platform code wanting to export some information related to the platform and I really don't see a reason why it should create bus types and device objects _specifically_ for that. It's just too wasteful, both in terms of memory and time needed for handling that in the device core.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 62 lines · Rafael J. Wysocki
Quoted 48 lines · Kay Sievers
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
Quoted 6 lines
If you need the userspace visibility, better just add a "struct
bus_type" with a proper name for your subsystem and register a "struct device" with thebus_typeassigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.I don't really think that's going to be useful in this particular case. The reason is, first, because the struct device would cause lots of other stuff to show up in sysfs which would be totally redundant and confusing and, second, because the things exported here are simply static attributes, pretty much like the stuff in
/sys/power/.
Quoted 3 lines
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
That's absolutely not the point. Please don't get yourself into that thinking. If people want to "export stuff to userspace", they must not invent new things. We need to get rid of the silly special cases. Userspace is not meant to learn subsystem specific rules for every new thing. There is _one_ way to export device attributes, and that is "struct device" today.
If that's to expensive for anybody, just don't use sysfs. It's the rule we have today. :)
Quoted 10 lines
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
That's not the point. It's about a single way to retrieve information about devices, extendability, and coldplug during bootup, where existing devices need to be handled only after userspace is up. That is just a case of "hotplug" that has the same codepath for userspace, even when the devices can never really come and go.
Quoted 6 lines
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Yeah , absolutely. But if any device wants to export anything is _must_ be a "struct device" today. If that does not fit, it must not use sysfs at all.
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Kay SieversQuoted 48 lines · Kay Sievers
Quoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
Quoted 6 lines
If you need the userspace visibility, better just add a "struct
bus_type" with a proper name for your subsystem and register a "struct device" with thebus_typeassigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.
I don't really think that's going to be useful in this particular case. The reason is, first, because the struct device would cause lots of other stuff to show up in sysfs which would be totally redundant and confusing and, second, because the things exported here are simply static attributes, pretty much like the stuff in /sys/power/.
Perhaps there's a more straightforward way to make some files show up in sysfs on a specific path than defininig an otherwise useless bus type and device object?
Quoted 6 lines
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There's no hotplug involved or anything remotely like that AFAICS. There are simply static files as I said above, they are created early during system initialization and simply stay there.
Quoted 3 lines
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
It's not a "device being a sysdev", it's sysdevs being used for creating a user space interface, which isn't broken by itself.
Thanks,
Rafael
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Paul MundtQuoted 34 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Quoted 8 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, they don't fit into the model. They have been a dumb hack from the first day, and never integrated into the kenrel driver core or hotplug properly.
If you need the userspace visibility, better just add a "struct bus_type" with a proper name for your subsystem and register a "struct device" with the bus_type assigned for all of them, instead of using the broken concept of sydevs. You can even make them show up
in /sys/devices/system/<bus_type name>/<struct device name>/ if you want to.
That way userspace can properly enumerate them in a flat list in /sys/bus/<bus_type name>/devices/*, and gets proper events on module load and during system coldplug, and can hook into the usual hotplug pathes to set/get these values instead of crawling magicly defined and decoupled locations in /sys which can not express proper hierarchy, classicication, or anything else that all other devices can just do.
There is really no reason for any device being a magic and conceptually broken sysdev today - just to be different from any other device the kernel exports to userspace.
Thanks,
Kay
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Paul MundtQuoted 29 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.
Quoted 4 lines
It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Hmm. So you actually want those empty directories to show up in sysfs? I didn't think they were really useful ...
Quoted 3 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
OK
Quoted 4 lines
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, there is. They are simply unusable in other situations, but I agree we'll need to find a clean way to replace them where there's a good reason to use them.
Updated patch follows.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: Drivers / sh: Use struct syscore_ops instead of sysdevs
Convert the SuperH clocks framework and shared interrupt handling code to using struct syscore_ops instead of a sysdev classes and sysdevs for power managment.
This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
--- drivers/sh/clk/core.c | 68 ++++++++----------------------- drivers/sh/intc/core.c | 95 +++++++++++++++++++++----------------------- drivers/sh/intc/internals.h | 1 3 files changed, 65 insertions(+), 99 deletions(-)
Index: linux-2.6/drivers/sh/clk/core.c =================================--- linux-2.6.orig/drivers/sh/clk/core.c +++ linux-2.6/drivers/sh/clk/core.c
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -630,68 +630,36 @@ long clk_round_parent(struct clk *clk, u
EXPORT_SYMBOL_GPL(clk_round_parent);
#ifdef CONFIG_PM
-static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) +static void clks_core_resume(void)
{
- static pm_message_t prev_state;
struct clk *clkp;
- switch (state.event) {
- case PM_EVENT_ON:
- /* Resumeing from hibernation */
- if (prev_state.event != PM_EVENT_FREEZE)
- break;
-
- list_for_each_entry(clkp, &clock_list, node) {
- if (likely(clkp->ops)) {
- unsigned long rate = clkp->rate;
-
- if (likely(clkp->ops->set_parent))
- clkp->ops->set_parent(clkp,
- clkp->parent);
- if (likely(clkp->ops->set_rate))
- clkp->ops->set_rate(clkp, rate);
- else if (likely(clkp->ops->recalc))
- clkp->rate = clkp->ops->recalc(clkp);
- }
+ list_for_each_entry(clkp, &clock_list, node) {
+ if (likely(clkp->ops)) {
+ unsigned long rate = clkp->rate;
+
+ if (likely(clkp->ops->set_parent))
+ clkp->ops->set_parent(clkp,
+ clkp->parent);
+ if (likely(clkp->ops->set_rate))
+ clkp->ops->set_rate(clkp, rate);
+ else if (likely(clkp->ops->recalc))
+ clkp->rate = clkp->ops->recalc(clkp);
}
- break;
- case PM_EVENT_FREEZE:
- break;
- case PM_EVENT_SUSPEND:
- break;
}
-
- prev_state = state;
- return 0;
-}
-
-static int clks_sysdev_resume(struct sys_device *dev) -{
- return clks_sysdev_suspend(dev, PMSG_ON);
}
-static struct sysdev_class clks_sysdev_class = {
- .name = "clks",
-};
-
-static struct sysdev_driver clks_sysdev_driver = {
- .suspend = clks_sysdev_suspend,
- .resume = clks_sysdev_resume,
-};
-
-static struct sys_device clks_sysdev_dev = {
- .cls = &clks_sysdev_class,
+static struct syscore_ops clks_syscore_ops = {
+ .resume = clks_core_resume,
};
-static int __init clk_sysdev_init(void)
+static int __init clk_syscore_init(void)
{
- sysdev_class_register(&clks_sysdev_class);
- sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
- sysdev_register(&clks_sysdev_dev);
+ register_syscore_ops(&clks_syscore_ops);
return 0;
}
-subsys_initcall(clk_sysdev_init);
+subsys_initcall(clk_syscore_init);
#endif
/*
Index: linux-2.6/drivers/sh/intc/core.c =================================--- linux-2.6.orig/drivers/sh/intc/core.c +++ linux-2.6/drivers/sh/intc/core.c
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/sh_intc.h>
#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/radix-tree.h>
@@ -376,91 +377,89 @@ err0:
return -ENOMEM;
}
-static ssize_t
-show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) +static int intc_suspend(void)
{
struct intc_desc_int *d;
- d = container_of(dev, struct intc_desc_int, sysdev);
+ list_for_each_entry(d, &intc_list, list) {
+ int irq;
- return sprintf(buf, "%s\n", d->chip.name);
-}
+ /* enable wakeup irqs belonging to this intc controller */
+ for_each_active_irq(irq) {
+ struct irq_data *data;
+ struct irq_desc *desc;
+ struct irq_chip *chip;
-static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
+ data = irq_get_irq_data(irq);
+ chip = irq_data_get_irq_chip(data);
+ if (chip != &d->chip)
+ continue;
+ desc = irq_to_desc(irq);
+ if ((desc->status & IRQ_WAKEUP))
+ chip->irq_enable(data);
+ }
+ }
+
+ return 0;
+}
-static int intc_suspend(struct sys_device *dev, pm_message_t state) +static void intc_resume(void)
{
struct intc_desc_int *d;
- struct irq_data *data;
- struct irq_desc *desc;
- struct irq_chip *chip;
- int irq;
-
- /* get intc controller associated with this sysdev */
- d = container_of(dev, struct intc_desc_int, sysdev);
- switch (state.event) {
- case PM_EVENT_ON:
- if (d->state.event != PM_EVENT_FREEZE)
- break;
+ list_for_each_entry(d, &intc_list, list) {
+ int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_data *data;
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+
data = irq_get_irq_data(irq);
chip = irq_data_get_irq_chip(data);
-
/*
* This will catch the redirect and VIRQ cases
* due to the dummy_irq_chip being inserted. */
if (chip != &d->chip)
continue;
+ desc = irq_to_desc(irq);
if (desc->status & IRQ_DISABLED)
chip->irq_disable(data);
else
chip->irq_enable(data);
}
- break;
- case PM_EVENT_FREEZE:
- /* nothing has to be done */
- break;
- case PM_EVENT_SUSPEND:
- /* enable wakeup irqs belonging to this intc controller */
- for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
- data = irq_get_irq_data(irq);
- chip = irq_data_get_irq_chip(data);
-
- if (chip != &d->chip)
- continue;
- if ((desc->status & IRQ_WAKEUP))
- chip->irq_enable(data);
- }
- break;
}
-
- d->state = state;
-
- return 0;
}
-static int intc_resume(struct sys_device *dev)
-{
- return intc_suspend(dev, PMSG_ON);
-}
+struct syscore_ops intc_syscore_ops = {
+ .suspend = intc_suspend,
+ .resume = intc_resume,
+};
struct sysdev_class intc_sysdev_class = {
.name = "intc",
- .suspend = intc_suspend,
- .resume = intc_resume,
};
-/* register this intc as sysdev to allow suspend/resume */
+static ssize_t
+show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) +{
+ struct intc_desc_int *d;
+
+ d = container_of(dev, struct intc_desc_int, sysdev);
+
+ return sprintf(buf, "%s\n", d->chip.name);
+}
+
+static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
+
static int __init register_intc_sysdevs(void)
{
struct intc_desc_int *d;
int error;
+ register_syscore_ops(&intc_syscore_ops);
+
error = sysdev_class_register(&intc_sysdev_class);
if (!error) {
list_for_each_entry(d, &intc_list, list) {
Index: linux-2.6/drivers/sh/intc/internals.h =================================--- linux-2.6.orig/drivers/sh/intc/internals.h +++ linux-2.6/drivers/sh/intc/internals.h
@@ -53,7 +53,6 @@ struct intc_desc_int {
struct list_head list;
struct sys_device sysdev;
struct radix_tree_root tree;
- pm_message_t state;
raw_spinlock_t lock;
unsigned int index;
unsigned long *reg;
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 14 lines · Rafael J. Wysocki
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Quoted 7 lines
Signed-off-by Rafael J. Wysocki <[email protected]>--- drivers/sh/clk/core.c | 68 ++++++++----------------------- drivers/sh/intc/core.c | 95 +++++++++++++++++++++----------------------- drivers/sh/intc/internals.h | 1 3 files changed, 65 insertions(+), 99 deletions(-)
This one looks good, and seems to work fine. Applied, thanks.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
Quoted 15 lines · Paul Mundt
Quoted 14 lines · Rafael J. Wysocki
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Quoted 8 lines
Quoted 7 lines
Signed-off-by Rafael J. Wysocki <[email protected]>--- drivers/sh/clk/core.c | 68 ++++++++----------------------- drivers/sh/intc/core.c | 95 +++++++++++++++++++++----------------------- drivers/sh/intc/internals.h | 1 3 files changed, 65 insertions(+), 99 deletions(-)This one looks good, and seems to work fine. Applied, thanks.
Cool, thanks!
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Paul MundtQuoted 15 lines · Paul Mundt
Quoted 14 lines · Rafael J. Wysocki
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Quoted 8 lines
Quoted 7 lines
Signed-off-by Rafael J. Wysocki <[email protected]>--- drivers/sh/clk/core.c | 68 ++++++++----------------------- drivers/sh/intc/core.c | 95 +++++++++++++++++++++----------------------- drivers/sh/intc/internals.h | 1 3 files changed, 65 insertions(+), 99 deletions(-)This one looks good, and seems to work fine. Applied, thanks.
Cool, thanks!
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 14 lines · Rafael J. Wysocki
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Quoted 7 lines
Signed-off-by Rafael J. Wysocki <[email protected]>--- drivers/sh/clk/core.c | 68 ++++++++----------------------- drivers/sh/intc/core.c | 95 +++++++++++++++++++++----------------------- drivers/sh/intc/internals.h | 1 3 files changed, 65 insertions(+), 99 deletions(-)
This one looks good, and seems to work fine. Applied, thanks.
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Paul MundtQuoted 29 lines · Paul Mundt
Quoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.
Quoted 4 lines
It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
Hmm. So you actually want those empty directories to show up in sysfs? I didn't think they were really useful ...
Quoted 3 lines
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
OK
Quoted 4 lines
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.
Yes, there is. They are simply unusable in other situations, but I agree we'll need to find a clean way to replace them where there's a good reason to use them.
Updated patch follows.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: Drivers / sh: Use struct syscore_ops instead of sysdevs
Convert the SuperH clocks framework and shared interrupt handling code to using struct syscore_ops instead of a sysdev classes and sysdevs for power managment.
This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
--- drivers/sh/clk/core.c | 68 ++++++++----------------------- drivers/sh/intc/core.c | 95 +++++++++++++++++++++----------------------- drivers/sh/intc/internals.h | 1 3 files changed, 65 insertions(+), 99 deletions(-)
drivers/sh/clk/core.c +18 -50
@@ -21,7 +21,7 @@#include <linux/module.h> #include <linux/mutex.h> #include <linux/list.h> -#include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/seq_file.h> #include <linux/err.h> #include <linux/io.h>
@@ -630,68 +630,36 @@ long clk_round_parent(struct clk *clk, uEXPORT_SYMBOL_GPL (clk_round_parent);#ifdef CONFIG_PM -static int clks_sysdev_suspend (struct sys_device *dev,pm_message_t state) +static void clks_core_resume (void ) { -static pm_message_t prev_state;struct clk *clkp; -switch (state.event) { -case PM_EVENT_ON : -/* Resumeing from hibernation */ -if (prev_state.event !=PM_EVENT_FREEZE ) -break ; - -list_for_each_entry (clkp, &clock_list, node) { -if (likely (clkp->ops)) { -unsigned long rate = clkp->rate; - -if (likely (clkp->ops->set_parent)) - clkp->ops->set_parent (clkp, - clkp->parent); -if (likely (clkp->ops->set_rate)) - clkp->ops->set_rate (clkp, rate); -else if (likely (clkp->ops->recalc)) - clkp->rate = clkp->ops->recalc (clkp); - } +list_for_each_entry (clkp, &clock_list, node) { +if (likely (clkp->ops)) { +unsigned long rate = clkp->rate; + +if (likely (clkp->ops->set_parent)) + clkp->ops->set_parent (clkp, + clkp->parent); +if (likely (clkp->ops->set_rate)) + clkp->ops->set_rate (clkp, rate); +else if (likely (clkp->ops->recalc)) + clkp->rate = clkp->ops->recalc (clkp); } -break ; -case PM_EVENT_FREEZE : -break ; -case PM_EVENT_SUSPEND : -break ; } - - prev_state = state; -return 0 ; -} - -static int clks_sysdev_resume (struct sys_device *dev) -{ -return clks_sysdev_suspend (dev,PMSG_ON ); } -static struct sysdev_class clks_sysdev_class = { - .name ="clks" , -}; - -static struct sysdev_driver clks_sysdev_driver = { - .suspend = clks_sysdev_suspend, - .resume = clks_sysdev_resume, -}; - -static struct sys_device clks_sysdev_dev = { - .cls = &clks_sysdev_class, +static struct syscore_ops clks_syscore_ops = { + .resume = clks_core_resume, }; -static int __init clk_sysdev_init (void ) +static int __init clk_syscore_init (void ) { -sysdev_class_register (&clks_sysdev_class); -sysdev_driver_register (&clks_sysdev_class, &clks_sysdev_driver); -sysdev_register (&clks_sysdev_dev); +register_syscore_ops (&clks_syscore_ops);return 0 ; } -subsys_initcall (clk_sysdev_init); +subsys_initcall (clk_syscore_init);#endif /*
drivers/sh/intc/core.c +47 -48
144 lines not on this page · raw message
drivers/sh/intc/internals.h +0 -1
@@ -53,7 +53,6 @@ struct intc_desc_int {struct list_head list;struct sys_device sysdev;struct radix_tree_root tree; -pm_message_t state;raw_spinlock_t lock;unsigned int index;unsigned long *reg;
Re: [PATCH 9/10] sh: Use struct syscore_ops instead of sysdev class and sysdev
In reply to Rafael J. WysockiQuoted 20 lines · Rafael J. Wysocki
Quoted 19 lines · Paul Mundt
Quoted 17 lines · R. J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Convert the SuperH clocks framework and shared interrupt handling code to using struct
syscore_opsinstead of a sysdev classes and sysdevs for power managment.This reduces the code size significantly and simplifies it. The optimizations causing things not to be restored after creating a hibernation image are removed, but they might lead to undesirable effects during resume from hibernation (e.g. the clocks would be left as the boot kernel set them, which might be not the same way as the hibernated kernel had seen them before the hibernation).
This also is necessary for removing sysdevs from the kernel entirely in the future.
Signed-off-by Rafael J. Wysocki <[email protected]>
Quoted 8 lines
Quoted 2 lines
This misses the use of the sysdev class by the userimask code, though I'm open to suggestions for alternatives.
For now, I'd simply move the sysdev class definition to
userimask.c, like in the patch below. The current goal is to eliminate the suspend/resume and shutdown operations from sysdevs (and sysdev drivers), the next step will be to replace the remaining sysdevs with alternative mechanisms.
It's not quite that straightforward, you've also killed off the name attribute for each of the intc sysdevs, so we no longer have a visible way to map a given intc controller number to the controller name in a user visible way.
I'm not opposed to the syscore thing for suspend/resume ops, but I'm not willing to trash the userimask and name mapping interface in the process with no alternatives.
userimask was the first global configuration item I added, but there are other per-controller and global configuration knobs that I plan to export through the interface, so there really needs to be a compelling reason for moving off of sysdevs.