Commit 328f5cc30290a92ea3ca62b2a63d2b9ebcb0d334

Authored by Rafael J. Wysocki
1 parent 5dd12af05c

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>

Showing 5 changed files with 58 additions and 94 deletions Side-by-side Diff

arch/arm/common/vic.c
... ... @@ -22,17 +22,16 @@
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.
... ... @@ -43,8 +42,6 @@
43 42 * @protect: Save for VIC_PROTECT.
44 43 */
45 44 struct vic_device {
46   - struct sys_device sysdev;
47   -
48 45 void __iomem *base;
49 46 int irq;
50 47 u32 resume_sources;
... ... @@ -59,11 +56,6 @@
59 56 static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
60 57  
61 58 static int vic_id;
62   -
63   -static inline struct vic_device *to_vic(struct sys_device *sys)
64   -{
65   - return container_of(sys, struct vic_device, sysdev);
66   -}
67 59 #endif /* CONFIG_PM */
68 60  
69 61 /**
70 62  
... ... @@ -85,10 +77,9 @@
85 77 writel(32, base + VIC_PL190_DEF_VECT_ADDR);
86 78 }
87 79  
88   -#if defined(CONFIG_PM)
89   -static int vic_class_resume(struct sys_device *dev)
  80 +#ifdef CONFIG_PM
  81 +static void resume_one_vic(struct vic_device *vic)
90 82 {
91   - struct vic_device *vic = to_vic(dev);
92 83 void __iomem *base = vic->base;
93 84  
94 85 printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
95 86  
96 87  
97 88  
... ... @@ -107,13 +98,18 @@
107 98  
108 99 writel(vic->soft_int, base + VIC_INT_SOFT);
109 100 writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR);
  101 +}
110 102  
111   - return 0;
  103 +static void vic_resume(void)
  104 +{
  105 + int id;
  106 +
  107 + for (id = vic_id - 1; id >= 0; id--)
  108 + resume_one_vic(vic_devices + id);
112 109 }
113 110  
114   -static int vic_class_suspend(struct sys_device *dev, pm_message_t state)
  111 +static void suspend_one_vic(struct vic_device *vic)
115 112 {
116   - struct vic_device *vic = to_vic(dev);
117 113 void __iomem *base = vic->base;
118 114  
119 115 printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base);
120 116  
121 117  
... ... @@ -128,14 +124,21 @@
128 124  
129 125 writel(vic->resume_irqs, base + VIC_INT_ENABLE);
130 126 writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
  127 +}
131 128  
  129 +static int vic_suspend(void)
  130 +{
  131 + int id;
  132 +
  133 + for (id = 0; id < vic_id; id++)
  134 + suspend_one_vic(vic_devices + id);
  135 +
132 136 return 0;
133 137 }
134 138  
135   -struct sysdev_class vic_class = {
136   - .name = "vic",
137   - .suspend = vic_class_suspend,
138   - .resume = vic_class_resume,
  139 +struct syscore_ops vic_syscore_ops = {
  140 + .suspend = vic_suspend,
  141 + .resume = vic_resume,
139 142 };
140 143  
141 144 /**
... ... @@ -147,30 +150,8 @@
147 150 */
148 151 static int __init vic_pm_init(void)
149 152 {
150   - struct vic_device *dev = vic_devices;
151   - int err;
152   - int id;
153   -
154   - if (vic_id == 0)
155   - return 0;
156   -
157   - err = sysdev_class_register(&vic_class);
158   - if (err) {
159   - printk(KERN_ERR "%s: cannot register class\n", __func__);
160   - return err;
161   - }
162   -
163   - for (id = 0; id < vic_id; id++, dev++) {
164   - dev->sysdev.id = id;
165   - dev->sysdev.cls = &vic_class;
166   -
167   - err = sysdev_register(&dev->sysdev);
168   - if (err) {
169   - printk(KERN_ERR "%s: failed to register device\n",
170   - __func__);
171   - return err;
172   - }
173   - }
  153 + if (vic_id > 0)
  154 + register_syscore_ops(&vic_syscore_ops);
174 155  
175 156 return 0;
176 157 }
arch/arm/include/asm/mach/time.h
... ... @@ -34,7 +34,6 @@
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);
arch/arm/kernel/leds.c
... ... @@ -10,6 +10,7 @@
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  
16 17  
17 18  
18 19  
19 20  
20 21  
21 22  
... ... @@ -69,36 +70,37 @@
69 70  
70 71 static SYSDEV_ATTR(event, 0200, NULL, leds_store);
71 72  
72   -static int leds_suspend(struct sys_device *dev, pm_message_t state)
  73 +static struct sysdev_class leds_sysclass = {
  74 + .name = "leds",
  75 +};
  76 +
  77 +static struct sys_device leds_device = {
  78 + .id = 0,
  79 + .cls = &leds_sysclass,
  80 +};
  81 +
  82 +static int leds_suspend(void)
73 83 {
74 84 leds_event(led_stop);
75 85 return 0;
76 86 }
77 87  
78   -static int leds_resume(struct sys_device *dev)
  88 +static void leds_resume(void)
79 89 {
80 90 leds_event(led_start);
81   - return 0;
82 91 }
83 92  
84   -static int leds_shutdown(struct sys_device *dev)
  93 +static void leds_shutdown(void)
85 94 {
86 95 leds_event(led_halted);
87   - return 0;
88 96 }
89 97  
90   -static struct sysdev_class leds_sysclass = {
91   - .name = "leds",
  98 +static struct syscore_ops leds_syscore_ops = {
92 99 .shutdown = leds_shutdown,
93 100 .suspend = leds_suspend,
94 101 .resume = leds_resume,
95 102 };
96 103  
97   -static struct sys_device leds_device = {
98   - .id = 0,
99   - .cls = &leds_sysclass,
100   -};
101   -
102 104 static int __init leds_init(void)
103 105 {
104 106 int ret;
... ... @@ -107,6 +109,8 @@
107 109 ret = sysdev_register(&leds_device);
108 110 if (ret == 0)
109 111 ret = sysdev_create_file(&leds_device, &attr_event);
  112 + if (ret == 0)
  113 + register_syscore_ops(&leds_syscore_ops);
110 114 return ret;
111 115 }
112 116  
arch/arm/kernel/time.c
... ... @@ -21,7 +21,7 @@
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  
28 28  
29 29  
30 30  
31 31  
32 32  
33 33  
34 34  
35 35  
36 36  
... ... @@ -115,48 +115,37 @@
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);
  120 + if (system_timer->suspend)
  121 + system_timer->suspend();
121 122  
122   - if (timer->suspend != NULL)
123   - timer->suspend();
124   -
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 {
arch/arm/vfp/vfpmodule.c
... ... @@ -398,9 +398,9 @@
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);
407 407  
408 408  
409 409  
410 410  
411 411  
... ... @@ -420,33 +420,24 @@
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) { }