Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: Use struct syscore_ops instead of sysdevs for PM in common code

Convert some ARM architecture's common code to using
struct syscore_ops objects for power management instead of sysdev
classes and sysdevs.

This simplifies the code and reduces the kernel's memory footprint.
It also is necessary for removing sysdevs from the kernel entirely in
the future.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>

+68 -104
+26 -45
arch/arm/common/vic.c
··· 22 22 #include <linux/init.h> 23 23 #include <linux/list.h> 24 24 #include <linux/io.h> 25 - #include <linux/sysdev.h> 25 + #include <linux/syscore_ops.h> 26 26 #include <linux/device.h> 27 27 #include <linux/amba/bus.h> 28 28 29 29 #include <asm/mach/irq.h> 30 30 #include <asm/hardware/vic.h> 31 31 32 - #if defined(CONFIG_PM) 32 + #ifdef CONFIG_PM 33 33 /** 34 34 * struct vic_device - VIC PM device 35 - * @sysdev: The system device which is registered. 36 35 * @irq: The IRQ number for the base of the VIC. 37 36 * @base: The register base for the VIC. 38 37 * @resume_sources: A bitmask of interrupts for resume. ··· 42 43 * @protect: Save for VIC_PROTECT. 43 44 */ 44 45 struct vic_device { 45 - struct sys_device sysdev; 46 - 47 46 void __iomem *base; 48 47 int irq; 49 48 u32 resume_sources; ··· 56 59 static struct vic_device vic_devices[CONFIG_ARM_VIC_NR]; 57 60 58 61 static int vic_id; 59 - 60 - static inline struct vic_device *to_vic(struct sys_device *sys) 61 - { 62 - return container_of(sys, struct vic_device, sysdev); 63 - } 64 62 #endif /* CONFIG_PM */ 65 63 66 64 /** ··· 77 85 writel(32, base + VIC_PL190_DEF_VECT_ADDR); 78 86 } 79 87 80 - #if defined(CONFIG_PM) 81 - static int vic_class_resume(struct sys_device *dev) 88 + #ifdef CONFIG_PM 89 + static void resume_one_vic(struct vic_device *vic) 82 90 { 83 - struct vic_device *vic = to_vic(dev); 84 91 void __iomem *base = vic->base; 85 92 86 93 printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base); ··· 98 107 99 108 writel(vic->soft_int, base + VIC_INT_SOFT); 100 109 writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR); 101 - 102 - return 0; 103 110 } 104 111 105 - static int vic_class_suspend(struct sys_device *dev, pm_message_t state) 112 + static void vic_resume(void) 106 113 { 107 - struct vic_device *vic = to_vic(dev); 114 + int id; 115 + 116 + for (id = vic_id - 1; id >= 0; id--) 117 + resume_one_vic(vic_devices + id); 118 + } 119 + 120 + static void suspend_one_vic(struct vic_device *vic) 121 + { 108 122 void __iomem *base = vic->base; 109 123 110 124 printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base); ··· 124 128 125 129 writel(vic->resume_irqs, base + VIC_INT_ENABLE); 126 130 writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR); 131 + } 132 + 133 + static int vic_suspend(void) 134 + { 135 + int id; 136 + 137 + for (id = 0; id < vic_id; id++) 138 + suspend_one_vic(vic_devices + id); 127 139 128 140 return 0; 129 141 } 130 142 131 - struct sysdev_class vic_class = { 132 - .name = "vic", 133 - .suspend = vic_class_suspend, 134 - .resume = vic_class_resume, 143 + struct syscore_ops vic_syscore_ops = { 144 + .suspend = vic_suspend, 145 + .resume = vic_resume, 135 146 }; 136 147 137 148 /** ··· 150 147 */ 151 148 static int __init vic_pm_init(void) 152 149 { 153 - struct vic_device *dev = vic_devices; 154 - int err; 155 - int id; 156 - 157 - if (vic_id == 0) 158 - return 0; 159 - 160 - err = sysdev_class_register(&vic_class); 161 - if (err) { 162 - printk(KERN_ERR "%s: cannot register class\n", __func__); 163 - return err; 164 - } 165 - 166 - for (id = 0; id < vic_id; id++, dev++) { 167 - dev->sysdev.id = id; 168 - dev->sysdev.cls = &vic_class; 169 - 170 - err = sysdev_register(&dev->sysdev); 171 - if (err) { 172 - printk(KERN_ERR "%s: failed to register device\n", 173 - __func__); 174 - return err; 175 - } 176 - } 150 + if (vic_id > 0) 151 + register_syscore_ops(&vic_syscore_ops); 177 152 178 153 return 0; 179 154 }
-1
arch/arm/include/asm/mach/time.h
··· 34 34 * timer interrupt which may be pending. 35 35 */ 36 36 struct sys_timer { 37 - struct sys_device dev; 38 37 void (*init)(void); 39 38 void (*suspend)(void); 40 39 void (*resume)(void);
+25 -21
arch/arm/kernel/leds.c
··· 10 10 #include <linux/module.h> 11 11 #include <linux/init.h> 12 12 #include <linux/sysdev.h> 13 + #include <linux/syscore_ops.h> 13 14 14 15 #include <asm/leds.h> 15 16 ··· 70 69 71 70 static SYSDEV_ATTR(event, 0200, NULL, leds_store); 72 71 73 - static int leds_suspend(struct sys_device *dev, pm_message_t state) 74 - { 75 - leds_event(led_stop); 76 - return 0; 77 - } 78 - 79 - static int leds_resume(struct sys_device *dev) 80 - { 81 - leds_event(led_start); 82 - return 0; 83 - } 84 - 85 - static int leds_shutdown(struct sys_device *dev) 86 - { 87 - leds_event(led_halted); 88 - return 0; 89 - } 90 - 91 72 static struct sysdev_class leds_sysclass = { 92 73 .name = "leds", 93 - .shutdown = leds_shutdown, 94 - .suspend = leds_suspend, 95 - .resume = leds_resume, 96 74 }; 97 75 98 76 static struct sys_device leds_device = { 99 77 .id = 0, 100 78 .cls = &leds_sysclass, 79 + }; 80 + 81 + static int leds_suspend(void) 82 + { 83 + leds_event(led_stop); 84 + return 0; 85 + } 86 + 87 + static void leds_resume(void) 88 + { 89 + leds_event(led_start); 90 + } 91 + 92 + static void leds_shutdown(void) 93 + { 94 + leds_event(led_halted); 95 + } 96 + 97 + static struct syscore_ops leds_syscore_ops = { 98 + .shutdown = leds_shutdown, 99 + .suspend = leds_suspend, 100 + .resume = leds_resume, 101 101 }; 102 102 103 103 static int __init leds_init(void) ··· 109 107 ret = sysdev_register(&leds_device); 110 108 if (ret == 0) 111 109 ret = sysdev_create_file(&leds_device, &attr_event); 110 + if (ret == 0) 111 + register_syscore_ops(&leds_syscore_ops); 112 112 return ret; 113 113 } 114 114
+12 -23
arch/arm/kernel/time.c
··· 21 21 #include <linux/timex.h> 22 22 #include <linux/errno.h> 23 23 #include <linux/profile.h> 24 - #include <linux/sysdev.h> 24 + #include <linux/syscore_ops.h> 25 25 #include <linux/timer.h> 26 26 #include <linux/irq.h> 27 27 ··· 115 115 #endif 116 116 117 117 #if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) 118 - static int timer_suspend(struct sys_device *dev, pm_message_t state) 118 + static int timer_suspend(void) 119 119 { 120 - struct sys_timer *timer = container_of(dev, struct sys_timer, dev); 121 - 122 - if (timer->suspend != NULL) 123 - timer->suspend(); 120 + if (system_timer->suspend) 121 + system_timer->suspend(); 124 122 125 123 return 0; 126 124 } 127 125 128 - static int timer_resume(struct sys_device *dev) 126 + static void timer_resume(void) 129 127 { 130 - struct sys_timer *timer = container_of(dev, struct sys_timer, dev); 131 - 132 - if (timer->resume != NULL) 133 - timer->resume(); 134 - 135 - return 0; 128 + if (system_timer->resume) 129 + system_timer->resume(); 136 130 } 137 131 #else 138 132 #define timer_suspend NULL 139 133 #define timer_resume NULL 140 134 #endif 141 135 142 - static struct sysdev_class timer_sysclass = { 143 - .name = "timer", 136 + static struct syscore_ops timer_syscore_ops = { 144 137 .suspend = timer_suspend, 145 138 .resume = timer_resume, 146 139 }; 147 140 148 - static int __init timer_init_sysfs(void) 141 + static int __init timer_init_syscore_ops(void) 149 142 { 150 - int ret = sysdev_class_register(&timer_sysclass); 151 - if (ret == 0) { 152 - system_timer->dev.cls = &timer_sysclass; 153 - ret = sysdev_register(&system_timer->dev); 154 - } 143 + register_syscore_ops(&timer_syscore_ops); 155 144 156 - return ret; 145 + return 0; 157 146 } 158 147 159 - device_initcall(timer_init_sysfs); 148 + device_initcall(timer_init_syscore_ops); 160 149 161 150 void __init time_init(void) 162 151 {
+5 -14
arch/arm/vfp/vfpmodule.c
··· 398 398 } 399 399 400 400 #ifdef CONFIG_PM 401 - #include <linux/sysdev.h> 401 + #include <linux/syscore_ops.h> 402 402 403 - static int vfp_pm_suspend(struct sys_device *dev, pm_message_t state) 403 + static int vfp_pm_suspend(void) 404 404 { 405 405 struct thread_info *ti = current_thread_info(); 406 406 u32 fpexc = fmrx(FPEXC); ··· 420 420 return 0; 421 421 } 422 422 423 - static int vfp_pm_resume(struct sys_device *dev) 423 + static void vfp_pm_resume(void) 424 424 { 425 425 /* ensure we have access to the vfp */ 426 426 vfp_enable(NULL); 427 427 428 428 /* and disable it to ensure the next usage restores the state */ 429 429 fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); 430 - 431 - return 0; 432 430 } 433 431 434 - static struct sysdev_class vfp_pm_sysclass = { 435 - .name = "vfp", 432 + static struct syscore_ops vfp_pm_syscore_ops = { 436 433 .suspend = vfp_pm_suspend, 437 434 .resume = vfp_pm_resume, 438 435 }; 439 436 440 - static struct sys_device vfp_pm_sysdev = { 441 - .cls = &vfp_pm_sysclass, 442 - }; 443 - 444 437 static void vfp_pm_init(void) 445 438 { 446 - sysdev_class_register(&vfp_pm_sysclass); 447 - sysdev_register(&vfp_pm_sysdev); 439 + register_syscore_ops(&vfp_pm_syscore_ops); 448 440 } 449 - 450 441 451 442 #else 452 443 static inline void vfp_pm_init(void) { }