aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 19:42:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 19:42:48 -0500
commit40ba587923ae67090d9f141c1d3c951be5c1420e (patch)
tree342a72fc0ee13a0d2496ef970b64dfeadf1355d2 /drivers
parent54c2c5761febcca46c8037d3a81612991e6c209a (diff)
parent6b550f9495947fc279d12c38feaf98500e8d0646 (diff)
Merge branch 'akpm' (aka "Andrew's patch-bomb")
Andrew elucidates: - First installmeant of MM. We have a HUGE number of MM patches this time. It's crazy. - MAINTAINERS updates - backlight updates - leds - checkpatch updates - misc ELF stuff - rtc updates - reiserfs - procfs - some misc other bits * akpm: (124 commits) user namespace: make signal.c respect user namespaces workqueue: make alloc_workqueue() take printf fmt and args for name procfs: add hidepid= and gid= mount options procfs: parse mount options procfs: introduce the /proc/<pid>/map_files/ directory procfs: make proc_get_link to use dentry instead of inode signal: add block_sigmask() for adding sigmask to current->blocked sparc: make SA_NOMASK a synonym of SA_NODEFER reiserfs: don't lock root inode searching reiserfs: don't lock journal_init() reiserfs: delay reiserfs lock until journal initialization reiserfs: delete comments referring to the BKL drivers/rtc/interface.c: fix alarm rollover when day or month is out-of-range drivers/rtc/rtc-twl.c: add DT support for RTC inside twl4030/twl6030 drivers/rtc/: remove redundant spi driver bus initialization drivers/rtc/rtc-jz4740.c: make jz4740_rtc_driver static drivers/rtc/rtc-mc13xxx.c: make mc13xxx_rtc_idtable static rtc: convert drivers/rtc/* to use module_platform_driver() drivers/rtc/rtc-wm831x.c: convert to devm_kzalloc() drivers/rtc/rtc-wm831x.c: remove unused period IRQ handler ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/leds/Kconfig8
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-88pm860x.c12
-rw-r--r--drivers/leds/leds-adp5520.c12
-rw-r--r--drivers/leds/leds-ams-delta.c13
-rw-r--r--drivers/leds/leds-asic3.c16
-rw-r--r--drivers/leds/leds-atmel-pwm.c17
-rw-r--r--drivers/leds/leds-bd2802.c15
-rw-r--r--drivers/leds/leds-cobalt-qube.c17
-rw-r--r--drivers/leds/leds-da903x.c12
-rw-r--r--drivers/leds/leds-dac124s085.c13
-rw-r--r--drivers/leds/leds-fsg.c15
-rw-r--r--drivers/leds/leds-gpio.c16
-rw-r--r--drivers/leds/leds-hp6xx.c17
-rw-r--r--drivers/leds/leds-lm3530.c13
-rw-r--r--drivers/leds/leds-lp3944.c13
-rw-r--r--drivers/leds/leds-lp5521.c20
-rw-r--r--drivers/leds/leds-lp5523.c22
-rw-r--r--drivers/leds/leds-lt3593.c16
-rw-r--r--drivers/leds/leds-mc13783.c14
-rw-r--r--drivers/leds/leds-netxbig.c39
-rw-r--r--drivers/leds/leds-ns2.c15
-rw-r--r--drivers/leds/leds-pca9532.c14
-rw-r--r--drivers/leds/leds-pca955x.c13
-rw-r--r--drivers/leds/leds-pwm.c13
-rw-r--r--drivers/leds/leds-rb532.c16
-rw-r--r--drivers/leds/leds-regulator.c12
-rw-r--r--drivers/leds/leds-renesas-tpu.c13
-rw-r--r--drivers/leds/leds-s3c24xx.c13
-rw-r--r--drivers/leds/leds-tca6507.c779
-rw-r--r--drivers/leds/leds-wm831x-status.c17
-rw-r--r--drivers/leds/leds-wm8350.c19
-rw-r--r--drivers/rtc/interface.c4
-rw-r--r--drivers/rtc/rtc-88pm860x.c12
-rw-r--r--drivers/rtc/rtc-ab8500.c136
-rw-r--r--drivers/rtc/rtc-bfin.c13
-rw-r--r--drivers/rtc/rtc-bq4802.c13
-rw-r--r--drivers/rtc/rtc-cmos.c2
-rw-r--r--drivers/rtc/rtc-dm355evm.c12
-rw-r--r--drivers/rtc/rtc-ds1286.c13
-rw-r--r--drivers/rtc/rtc-ds1511.c15
-rw-r--r--drivers/rtc/rtc-ds1553.c13
-rw-r--r--drivers/rtc/rtc-ds1742.c13
-rw-r--r--drivers/rtc/rtc-jz4740.c14
-rw-r--r--drivers/rtc/rtc-lpc32xx.c12
-rw-r--r--drivers/rtc/rtc-m41t93.c1
-rw-r--r--drivers/rtc/rtc-m41t94.c1
-rw-r--r--drivers/rtc/rtc-m48t35.c13
-rw-r--r--drivers/rtc/rtc-m48t59.c13
-rw-r--r--drivers/rtc/rtc-m48t86.c13
-rw-r--r--drivers/rtc/rtc-max6902.c1
-rw-r--r--drivers/rtc/rtc-max8925.c12
-rw-r--r--drivers/rtc/rtc-max8998.c12
-rw-r--r--drivers/rtc/rtc-mc13xxx.c2
-rw-r--r--drivers/rtc/rtc-mpc5121.c12
-rw-r--r--drivers/rtc/rtc-mrst.c13
-rw-r--r--drivers/rtc/rtc-mxc.c123
-rw-r--r--drivers/rtc/rtc-pcf2123.c1
-rw-r--r--drivers/rtc/rtc-pcf50633.c12
-rw-r--r--drivers/rtc/rtc-pm8xxx.c12
-rw-r--r--drivers/rtc/rtc-rs5c348.c1
-rw-r--r--drivers/rtc/rtc-s3c.c16
-rw-r--r--drivers/rtc/rtc-sa1100.c13
-rw-r--r--drivers/rtc/rtc-spear.c12
-rw-r--r--drivers/rtc/rtc-stk17ta8.c13
-rw-r--r--drivers/rtc/rtc-stmp3xxx.c13
-rw-r--r--drivers/rtc/rtc-twl.c10
-rw-r--r--drivers/rtc/rtc-v3020.c13
-rw-r--r--drivers/rtc/rtc-vr41xx.c13
-rw-r--r--drivers/rtc/rtc-vt8500.c12
-rw-r--r--drivers/rtc/rtc-wm831x.c36
-rw-r--r--drivers/rtc/rtc-wm8350.c12
-rw-r--r--drivers/video/backlight/88pm860x_bl.c12
-rw-r--r--drivers/video/backlight/Kconfig8
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/adp5520_bl.c12
-rw-r--r--drivers/video/backlight/adx_bl.c182
-rw-r--r--drivers/video/backlight/backlight.c6
-rw-r--r--drivers/video/backlight/da903x_bl.c12
-rw-r--r--drivers/video/backlight/ep93xx_bl.c13
-rw-r--r--drivers/video/backlight/generic_bl.c13
-rw-r--r--drivers/video/backlight/jornada720_bl.c13
-rw-r--r--drivers/video/backlight/jornada720_lcd.c13
-rw-r--r--drivers/video/backlight/lcd.c26
-rw-r--r--drivers/video/backlight/ld9040.c71
-rw-r--r--drivers/video/backlight/max8925_bl.c12
-rw-r--r--drivers/video/backlight/omap1_bl.c13
-rw-r--r--drivers/video/backlight/pcf50633-backlight.c12
-rw-r--r--drivers/video/backlight/platform_lcd.c22
-rw-r--r--drivers/video/backlight/pwm_bl.c33
-rw-r--r--drivers/video/backlight/wm831x_bl.c12
91 files changed, 1172 insertions, 1236 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 1b75a56ebd08..897a77dfa9d7 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -388,6 +388,14 @@ config LEDS_RENESAS_TPU
388 pin function. The latter to support brightness control. 388 pin function. The latter to support brightness control.
389 Brightness control is supported but hardware blinking is not. 389 Brightness control is supported but hardware blinking is not.
390 390
391config LEDS_TCA6507
392 tristate "LED Support for TCA6507 I2C chip"
393 depends on LEDS_CLASS && I2C
394 help
395 This option enables support for LEDs connected to TC6507
396 LED driver chips accessed via the I2C bus.
397 Driver support brightness control and hardware-assisted blinking.
398
391config LEDS_TRIGGERS 399config LEDS_TRIGGERS
392 bool "LED Trigger support" 400 bool "LED Trigger support"
393 depends on LEDS_CLASS 401 depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index e4f6bf568880..5c9dc4b000d5 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
25obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o 25obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o
26obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o 26obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o
27obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o 27obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
28obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
28obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 29obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
29obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o 30obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
30obj-$(CONFIG_LEDS_FSG) += leds-fsg.o 31obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 0810604dc701..4ca00624bd18 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -238,17 +238,7 @@ static struct platform_driver pm860x_led_driver = {
238 .remove = pm860x_led_remove, 238 .remove = pm860x_led_remove,
239}; 239};
240 240
241static int __devinit pm860x_led_init(void) 241module_platform_driver(pm860x_led_driver);
242{
243 return platform_driver_register(&pm860x_led_driver);
244}
245module_init(pm860x_led_init);
246
247static void __devexit pm860x_led_exit(void)
248{
249 platform_driver_unregister(&pm860x_led_driver);
250}
251module_exit(pm860x_led_exit);
252 242
253MODULE_DESCRIPTION("LED driver for Marvell PM860x"); 243MODULE_DESCRIPTION("LED driver for Marvell PM860x");
254MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 244MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
index 7ba4c7b5b97e..b1400db3f839 100644
--- a/drivers/leds/leds-adp5520.c
+++ b/drivers/leds/leds-adp5520.c
@@ -213,17 +213,7 @@ static struct platform_driver adp5520_led_driver = {
213 .remove = __devexit_p(adp5520_led_remove), 213 .remove = __devexit_p(adp5520_led_remove),
214}; 214};
215 215
216static int __init adp5520_led_init(void) 216module_platform_driver(adp5520_led_driver);
217{
218 return platform_driver_register(&adp5520_led_driver);
219}
220module_init(adp5520_led_init);
221
222static void __exit adp5520_led_exit(void)
223{
224 platform_driver_unregister(&adp5520_led_driver);
225}
226module_exit(adp5520_led_exit);
227 217
228MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 218MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
229MODULE_DESCRIPTION("LEDS ADP5520(01) Driver"); 219MODULE_DESCRIPTION("LEDS ADP5520(01) Driver");
diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c
index 8c00937bf7e7..07428357c83f 100644
--- a/drivers/leds/leds-ams-delta.c
+++ b/drivers/leds/leds-ams-delta.c
@@ -118,18 +118,7 @@ static struct platform_driver ams_delta_led_driver = {
118 }, 118 },
119}; 119};
120 120
121static int __init ams_delta_led_init(void) 121module_platform_driver(ams_delta_led_driver);
122{
123 return platform_driver_register(&ams_delta_led_driver);
124}
125
126static void __exit ams_delta_led_exit(void)
127{
128 platform_driver_unregister(&ams_delta_led_driver);
129}
130
131module_init(ams_delta_led_init);
132module_exit(ams_delta_led_exit);
133 122
134MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>"); 123MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
135MODULE_DESCRIPTION("Amstrad Delta LED driver"); 124MODULE_DESCRIPTION("Amstrad Delta LED driver");
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index 48d9fe61bdfc..525a92492837 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -179,21 +179,9 @@ static struct platform_driver asic3_led_driver = {
179 }, 179 },
180}; 180};
181 181
182MODULE_ALIAS("platform:leds-asic3"); 182module_platform_driver(asic3_led_driver);
183
184static int __init asic3_led_init(void)
185{
186 return platform_driver_register(&asic3_led_driver);
187}
188
189static void __exit asic3_led_exit(void)
190{
191 platform_driver_unregister(&asic3_led_driver);
192}
193
194module_init(asic3_led_init);
195module_exit(asic3_led_exit);
196 183
197MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); 184MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
198MODULE_DESCRIPTION("HTC ASIC3 LED driver"); 185MODULE_DESCRIPTION("HTC ASIC3 LED driver");
199MODULE_LICENSE("GPL"); 186MODULE_LICENSE("GPL");
187MODULE_ALIAS("platform:leds-asic3");
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 109c875ea233..800243b6037e 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -134,29 +134,18 @@ static int __exit pwmled_remove(struct platform_device *pdev)
134 return 0; 134 return 0;
135} 135}
136 136
137/* work with hotplug and coldplug */
138MODULE_ALIAS("platform:leds-atmel-pwm");
139
140static struct platform_driver pwmled_driver = { 137static struct platform_driver pwmled_driver = {
141 .driver = { 138 .driver = {
142 .name = "leds-atmel-pwm", 139 .name = "leds-atmel-pwm",
143 .owner = THIS_MODULE, 140 .owner = THIS_MODULE,
144 }, 141 },
145 /* REVISIT add suspend() and resume() methods */ 142 /* REVISIT add suspend() and resume() methods */
143 .probe = pwmled_probe,
146 .remove = __exit_p(pwmled_remove), 144 .remove = __exit_p(pwmled_remove),
147}; 145};
148 146
149static int __init modinit(void) 147module_platform_driver(pwmled_driver);
150{
151 return platform_driver_probe(&pwmled_driver, pwmled_probe);
152}
153module_init(modinit);
154
155static void __exit modexit(void)
156{
157 platform_driver_unregister(&pwmled_driver);
158}
159module_exit(modexit);
160 148
161MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness"); 149MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");
162MODULE_LICENSE("GPL"); 150MODULE_LICENSE("GPL");
151MODULE_ALIAS("platform:leds-atmel-pwm");
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index ea2185531f82..591cbdf5a046 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -688,8 +688,7 @@ static int __devinit bd2802_probe(struct i2c_client *client,
688 i2c_set_clientdata(client, led); 688 i2c_set_clientdata(client, led);
689 689
690 /* Configure RESET GPIO (L: RESET, H: RESET cancel) */ 690 /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
691 gpio_request(pdata->reset_gpio, "RGB_RESETB"); 691 gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "RGB_RESETB");
692 gpio_direction_output(pdata->reset_gpio, 1);
693 692
694 /* Tacss = min 0.1ms */ 693 /* Tacss = min 0.1ms */
695 udelay(100); 694 udelay(100);
@@ -813,17 +812,7 @@ static struct i2c_driver bd2802_i2c_driver = {
813 .id_table = bd2802_id, 812 .id_table = bd2802_id,
814}; 813};
815 814
816static int __init bd2802_init(void) 815module_i2c_driver(bd2802_i2c_driver);
817{
818 return i2c_add_driver(&bd2802_i2c_driver);
819}
820module_init(bd2802_init);
821
822static void __exit bd2802_exit(void)
823{
824 i2c_del_driver(&bd2802_i2c_driver);
825}
826module_exit(bd2802_exit);
827 816
828MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); 817MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
829MODULE_DESCRIPTION("BD2802 LED driver"); 818MODULE_DESCRIPTION("BD2802 LED driver");
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c
index da5fb016b1a5..6a8725cc7b4d 100644
--- a/drivers/leds/leds-cobalt-qube.c
+++ b/drivers/leds/leds-cobalt-qube.c
@@ -75,9 +75,6 @@ static int __devexit cobalt_qube_led_remove(struct platform_device *pdev)
75 return 0; 75 return 0;
76} 76}
77 77
78/* work with hotplug and coldplug */
79MODULE_ALIAS("platform:cobalt-qube-leds");
80
81static struct platform_driver cobalt_qube_led_driver = { 78static struct platform_driver cobalt_qube_led_driver = {
82 .probe = cobalt_qube_led_probe, 79 .probe = cobalt_qube_led_probe,
83 .remove = __devexit_p(cobalt_qube_led_remove), 80 .remove = __devexit_p(cobalt_qube_led_remove),
@@ -87,19 +84,9 @@ static struct platform_driver cobalt_qube_led_driver = {
87 }, 84 },
88}; 85};
89 86
90static int __init cobalt_qube_led_init(void) 87module_platform_driver(cobalt_qube_led_driver);
91{
92 return platform_driver_register(&cobalt_qube_led_driver);
93}
94
95static void __exit cobalt_qube_led_exit(void)
96{
97 platform_driver_unregister(&cobalt_qube_led_driver);
98}
99
100module_init(cobalt_qube_led_init);
101module_exit(cobalt_qube_led_exit);
102 88
103MODULE_LICENSE("GPL"); 89MODULE_LICENSE("GPL");
104MODULE_DESCRIPTION("Front LED support for Cobalt Server"); 90MODULE_DESCRIPTION("Front LED support for Cobalt Server");
105MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 91MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
92MODULE_ALIAS("platform:cobalt-qube-leds");
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
index f28931cf6781..d9cd73ebd6c4 100644
--- a/drivers/leds/leds-da903x.c
+++ b/drivers/leds/leds-da903x.c
@@ -158,17 +158,7 @@ static struct platform_driver da903x_led_driver = {
158 .remove = __devexit_p(da903x_led_remove), 158 .remove = __devexit_p(da903x_led_remove),
159}; 159};
160 160
161static int __init da903x_led_init(void) 161module_platform_driver(da903x_led_driver);
162{
163 return platform_driver_register(&da903x_led_driver);
164}
165module_init(da903x_led_init);
166
167static void __exit da903x_led_exit(void)
168{
169 platform_driver_unregister(&da903x_led_driver);
170}
171module_exit(da903x_led_exit);
172 162
173MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034"); 163MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
174MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" 164MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
index 31cf0d60a9a5..d56c14269ff0 100644
--- a/drivers/leds/leds-dac124s085.c
+++ b/drivers/leds/leds-dac124s085.c
@@ -131,18 +131,7 @@ static struct spi_driver dac124s085_driver = {
131 }, 131 },
132}; 132};
133 133
134static int __init dac124s085_leds_init(void) 134module_spi_driver(dac124s085_driver);
135{
136 return spi_register_driver(&dac124s085_driver);
137}
138
139static void __exit dac124s085_leds_exit(void)
140{
141 spi_unregister_driver(&dac124s085_driver);
142}
143
144module_init(dac124s085_leds_init);
145module_exit(dac124s085_leds_exit);
146 135
147MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>"); 136MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
148MODULE_DESCRIPTION("DAC124S085 LED driver"); 137MODULE_DESCRIPTION("DAC124S085 LED driver");
diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c
index 49aceffaa5b6..b9053fa6e253 100644
--- a/drivers/leds/leds-fsg.c
+++ b/drivers/leds/leds-fsg.c
@@ -224,20 +224,7 @@ static struct platform_driver fsg_led_driver = {
224 }, 224 },
225}; 225};
226 226
227 227module_platform_driver(fsg_led_driver);
228static int __init fsg_led_init(void)
229{
230 return platform_driver_register(&fsg_led_driver);
231}
232
233static void __exit fsg_led_exit(void)
234{
235 platform_driver_unregister(&fsg_led_driver);
236}
237
238
239module_init(fsg_led_init);
240module_exit(fsg_led_exit);
241 228
242MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>"); 229MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
243MODULE_DESCRIPTION("Freecom FSG-3 LED driver"); 230MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 399a86f2013a..7df74cb97e70 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -293,21 +293,9 @@ static struct platform_driver gpio_led_driver = {
293 }, 293 },
294}; 294};
295 295
296MODULE_ALIAS("platform:leds-gpio"); 296module_platform_driver(gpio_led_driver);
297
298static int __init gpio_led_init(void)
299{
300 return platform_driver_register(&gpio_led_driver);
301}
302
303static void __exit gpio_led_exit(void)
304{
305 platform_driver_unregister(&gpio_led_driver);
306}
307
308module_init(gpio_led_init);
309module_exit(gpio_led_exit);
310 297
311MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>"); 298MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
312MODULE_DESCRIPTION("GPIO LED driver"); 299MODULE_DESCRIPTION("GPIO LED driver");
313MODULE_LICENSE("GPL"); 300MODULE_LICENSE("GPL");
301MODULE_ALIAS("platform:leds-gpio");
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c
index bcfbd3a60eab..366b6055e330 100644
--- a/drivers/leds/leds-hp6xx.c
+++ b/drivers/leds/leds-hp6xx.c
@@ -79,9 +79,6 @@ static int hp6xxled_remove(struct platform_device *pdev)
79 return 0; 79 return 0;
80} 80}
81 81
82/* work with hotplug and coldplug */
83MODULE_ALIAS("platform:hp6xx-led");
84
85static struct platform_driver hp6xxled_driver = { 82static struct platform_driver hp6xxled_driver = {
86 .probe = hp6xxled_probe, 83 .probe = hp6xxled_probe,
87 .remove = hp6xxled_remove, 84 .remove = hp6xxled_remove,
@@ -91,19 +88,9 @@ static struct platform_driver hp6xxled_driver = {
91 }, 88 },
92}; 89};
93 90
94static int __init hp6xxled_init(void) 91module_platform_driver(hp6xxled_driver);
95{
96 return platform_driver_register(&hp6xxled_driver);
97}
98
99static void __exit hp6xxled_exit(void)
100{
101 platform_driver_unregister(&hp6xxled_driver);
102}
103
104module_init(hp6xxled_init);
105module_exit(hp6xxled_exit);
106 92
107MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); 93MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
108MODULE_DESCRIPTION("HP Jornada 6xx LED driver"); 94MODULE_DESCRIPTION("HP Jornada 6xx LED driver");
109MODULE_LICENSE("GPL"); 95MODULE_LICENSE("GPL");
96MODULE_ALIAS("platform:hp6xx-led");
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 0630e4f4b286..45e6878d7374 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -457,18 +457,7 @@ static struct i2c_driver lm3530_i2c_driver = {
457 }, 457 },
458}; 458};
459 459
460static int __init lm3530_init(void) 460module_i2c_driver(lm3530_i2c_driver);
461{
462 return i2c_add_driver(&lm3530_i2c_driver);
463}
464
465static void __exit lm3530_exit(void)
466{
467 i2c_del_driver(&lm3530_i2c_driver);
468}
469
470module_init(lm3530_init);
471module_exit(lm3530_exit);
472 461
473MODULE_DESCRIPTION("Back Light driver for LM3530"); 462MODULE_DESCRIPTION("Back Light driver for LM3530");
474MODULE_LICENSE("GPL v2"); 463MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index 9010c054615e..b8f9f0a5d431 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -453,18 +453,7 @@ static struct i2c_driver lp3944_driver = {
453 .id_table = lp3944_id, 453 .id_table = lp3944_id,
454}; 454};
455 455
456static int __init lp3944_module_init(void) 456module_i2c_driver(lp3944_driver);
457{
458 return i2c_add_driver(&lp3944_driver);
459}
460
461static void __exit lp3944_module_exit(void)
462{
463 i2c_del_driver(&lp3944_driver);
464}
465
466module_init(lp3944_module_init);
467module_exit(lp3944_module_exit);
468 457
469MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 458MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
470MODULE_DESCRIPTION("LP3944 Fun Light Chip"); 459MODULE_DESCRIPTION("LP3944 Fun Light Chip");
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index cb641f1b3342..d62a7982a5e6 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -797,25 +797,7 @@ static struct i2c_driver lp5521_driver = {
797 .id_table = lp5521_id, 797 .id_table = lp5521_id,
798}; 798};
799 799
800static int __init lp5521_init(void) 800module_i2c_driver(lp5521_driver);
801{
802 int ret;
803
804 ret = i2c_add_driver(&lp5521_driver);
805
806 if (ret < 0)
807 printk(KERN_ALERT "Adding lp5521 driver failed\n");
808
809 return ret;
810}
811
812static void __exit lp5521_exit(void)
813{
814 i2c_del_driver(&lp5521_driver);
815}
816
817module_init(lp5521_init);
818module_exit(lp5521_exit);
819 801
820MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo"); 802MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo");
821MODULE_DESCRIPTION("LP5521 LED engine"); 803MODULE_DESCRIPTION("LP5521 LED engine");
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 5971e309b234..73e791ae7259 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -870,8 +870,6 @@ static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
870 return 0; 870 return 0;
871} 871}
872 872
873static struct i2c_driver lp5523_driver;
874
875static int __devinit lp5523_probe(struct i2c_client *client, 873static int __devinit lp5523_probe(struct i2c_client *client,
876 const struct i2c_device_id *id) 874 const struct i2c_device_id *id)
877{ 875{
@@ -1021,25 +1019,7 @@ static struct i2c_driver lp5523_driver = {
1021 .id_table = lp5523_id, 1019 .id_table = lp5523_id,
1022}; 1020};
1023 1021
1024static int __init lp5523_init(void) 1022module_i2c_driver(lp5523_driver);
1025{
1026 int ret;
1027
1028 ret = i2c_add_driver(&lp5523_driver);
1029
1030 if (ret < 0)
1031 printk(KERN_ALERT "Adding lp5523 driver failed\n");
1032
1033 return ret;
1034}
1035
1036static void __exit lp5523_exit(void)
1037{
1038 i2c_del_driver(&lp5523_driver);
1039}
1040
1041module_init(lp5523_init);
1042module_exit(lp5523_exit);
1043 1023
1044MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>"); 1024MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
1045MODULE_DESCRIPTION("LP5523 LED engine"); 1025MODULE_DESCRIPTION("LP5523 LED engine");
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index 53f67b8ce55d..e311a96c4469 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -199,21 +199,9 @@ static struct platform_driver lt3593_led_driver = {
199 }, 199 },
200}; 200};
201 201
202MODULE_ALIAS("platform:leds-lt3593"); 202module_platform_driver(lt3593_led_driver);
203
204static int __init lt3593_led_init(void)
205{
206 return platform_driver_register(&lt3593_led_driver);
207}
208
209static void __exit lt3593_led_exit(void)
210{
211 platform_driver_unregister(&lt3593_led_driver);
212}
213
214module_init(lt3593_led_init);
215module_exit(lt3593_led_exit);
216 203
217MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 204MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
218MODULE_DESCRIPTION("LED driver for LT3593 controllers"); 205MODULE_DESCRIPTION("LED driver for LT3593 controllers");
219MODULE_LICENSE("GPL"); 206MODULE_LICENSE("GPL");
207MODULE_ALIAS("platform:leds-lt3593");
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index b3393a9f2139..8bc491541550 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -275,7 +275,7 @@ static int __devinit mc13783_led_probe(struct platform_device *pdev)
275 return -ENODEV; 275 return -ENODEV;
276 } 276 }
277 277
278 if (pdata->num_leds < 1 || pdata->num_leds > MC13783_LED_MAX) { 278 if (pdata->num_leds < 1 || pdata->num_leds > (MC13783_LED_MAX + 1)) {
279 dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds); 279 dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds);
280 return -EINVAL; 280 return -EINVAL;
281 } 281 }
@@ -385,17 +385,7 @@ static struct platform_driver mc13783_led_driver = {
385 .remove = __devexit_p(mc13783_led_remove), 385 .remove = __devexit_p(mc13783_led_remove),
386}; 386};
387 387
388static int __init mc13783_led_init(void) 388module_platform_driver(mc13783_led_driver);
389{
390 return platform_driver_register(&mc13783_led_driver);
391}
392module_init(mc13783_led_init);
393
394static void __exit mc13783_led_exit(void)
395{
396 platform_driver_unregister(&mc13783_led_driver);
397}
398module_exit(mc13783_led_exit);
399 389
400MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC"); 390MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC");
401MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>"); 391MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index f2e51c134399..d8433f2d53bc 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -81,35 +81,23 @@ static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
81 81
82 /* Configure address GPIOs. */ 82 /* Configure address GPIOs. */
83 for (i = 0; i < gpio_ext->num_addr; i++) { 83 for (i = 0; i < gpio_ext->num_addr; i++) {
84 err = gpio_request(gpio_ext->addr[i], "GPIO extension addr"); 84 err = gpio_request_one(gpio_ext->addr[i], GPIOF_OUT_INIT_LOW,
85 "GPIO extension addr");
85 if (err) 86 if (err)
86 goto err_free_addr; 87 goto err_free_addr;
87 err = gpio_direction_output(gpio_ext->addr[i], 0);
88 if (err) {
89 gpio_free(gpio_ext->addr[i]);
90 goto err_free_addr;
91 }
92 } 88 }
93 /* Configure data GPIOs. */ 89 /* Configure data GPIOs. */
94 for (i = 0; i < gpio_ext->num_data; i++) { 90 for (i = 0; i < gpio_ext->num_data; i++) {
95 err = gpio_request(gpio_ext->data[i], "GPIO extension data"); 91 err = gpio_request_one(gpio_ext->data[i], GPIOF_OUT_INIT_LOW,
92 "GPIO extension data");
96 if (err) 93 if (err)
97 goto err_free_data; 94 goto err_free_data;
98 err = gpio_direction_output(gpio_ext->data[i], 0);
99 if (err) {
100 gpio_free(gpio_ext->data[i]);
101 goto err_free_data;
102 }
103 } 95 }
104 /* Configure "enable select" GPIO. */ 96 /* Configure "enable select" GPIO. */
105 err = gpio_request(gpio_ext->enable, "GPIO extension enable"); 97 err = gpio_request_one(gpio_ext->enable, GPIOF_OUT_INIT_LOW,
98 "GPIO extension enable");
106 if (err) 99 if (err)
107 goto err_free_data; 100 goto err_free_data;
108 err = gpio_direction_output(gpio_ext->enable, 0);
109 if (err) {
110 gpio_free(gpio_ext->enable);
111 goto err_free_data;
112 }
113 101
114 return 0; 102 return 0;
115 103
@@ -429,21 +417,10 @@ static struct platform_driver netxbig_led_driver = {
429 .owner = THIS_MODULE, 417 .owner = THIS_MODULE,
430 }, 418 },
431}; 419};
432MODULE_ALIAS("platform:leds-netxbig");
433 420
434static int __init netxbig_led_init(void) 421module_platform_driver(netxbig_led_driver);
435{
436 return platform_driver_register(&netxbig_led_driver);
437}
438
439static void __exit netxbig_led_exit(void)
440{
441 platform_driver_unregister(&netxbig_led_driver);
442}
443
444module_init(netxbig_led_init);
445module_exit(netxbig_led_exit);
446 422
447MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); 423MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
448MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards"); 424MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards");
449MODULE_LICENSE("GPL"); 425MODULE_LICENSE("GPL");
426MODULE_ALIAS("platform:leds-netxbig");
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index 37b7d0cfe586..2f0a14421a73 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -323,21 +323,10 @@ static struct platform_driver ns2_led_driver = {
323 .owner = THIS_MODULE, 323 .owner = THIS_MODULE,
324 }, 324 },
325}; 325};
326MODULE_ALIAS("platform:leds-ns2");
327
328static int __init ns2_led_init(void)
329{
330 return platform_driver_register(&ns2_led_driver);
331}
332 326
333static void __exit ns2_led_exit(void) 327module_platform_driver(ns2_led_driver);
334{
335 platform_driver_unregister(&ns2_led_driver);
336}
337
338module_init(ns2_led_init);
339module_exit(ns2_led_exit);
340 328
341MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); 329MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
342MODULE_DESCRIPTION("Network Space v2 LED driver"); 330MODULE_DESCRIPTION("Network Space v2 LED driver");
343MODULE_LICENSE("GPL"); 331MODULE_LICENSE("GPL");
332MODULE_ALIAS("platform:leds-ns2");
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index a2c874623e35..ceccab44b5b8 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -489,20 +489,8 @@ static int pca9532_remove(struct i2c_client *client)
489 return 0; 489 return 0;
490} 490}
491 491
492static int __init pca9532_init(void) 492module_i2c_driver(pca9532_driver);
493{
494 return i2c_add_driver(&pca9532_driver);
495}
496
497static void __exit pca9532_exit(void)
498{
499 i2c_del_driver(&pca9532_driver);
500}
501 493
502MODULE_AUTHOR("Riku Voipio"); 494MODULE_AUTHOR("Riku Voipio");
503MODULE_LICENSE("GPL"); 495MODULE_LICENSE("GPL");
504MODULE_DESCRIPTION("PCA 9532 LED dimmer"); 496MODULE_DESCRIPTION("PCA 9532 LED dimmer");
505
506module_init(pca9532_init);
507module_exit(pca9532_exit);
508
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 66aa3e8e786f..dcc3bc3d38db 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -371,18 +371,7 @@ static struct i2c_driver pca955x_driver = {
371 .id_table = pca955x_id, 371 .id_table = pca955x_id,
372}; 372};
373 373
374static int __init pca955x_leds_init(void) 374module_i2c_driver(pca955x_driver);
375{
376 return i2c_add_driver(&pca955x_driver);
377}
378
379static void __exit pca955x_leds_exit(void)
380{
381 i2c_del_driver(&pca955x_driver);
382}
383
384module_init(pca955x_leds_init);
385module_exit(pca955x_leds_exit);
386 375
387MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>"); 376MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>");
388MODULE_DESCRIPTION("PCA955x LED driver"); 377MODULE_DESCRIPTION("PCA955x LED driver");
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 666daf77872e..3ed92f34bd44 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -135,18 +135,7 @@ static struct platform_driver led_pwm_driver = {
135 }, 135 },
136}; 136};
137 137
138static int __init led_pwm_init(void) 138module_platform_driver(led_pwm_driver);
139{
140 return platform_driver_register(&led_pwm_driver);
141}
142
143static void __exit led_pwm_exit(void)
144{
145 platform_driver_unregister(&led_pwm_driver);
146}
147
148module_init(led_pwm_init);
149module_exit(led_pwm_exit);
150 139
151MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); 140MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
152MODULE_DESCRIPTION("PWM LED driver for PXA"); 141MODULE_DESCRIPTION("PWM LED driver for PXA");
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
index c3525f37f73d..a7815b6cd856 100644
--- a/drivers/leds/leds-rb532.c
+++ b/drivers/leds/leds-rb532.c
@@ -57,21 +57,9 @@ static struct platform_driver rb532_led_driver = {
57 }, 57 },
58}; 58};
59 59
60static int __init rb532_led_init(void) 60module_platform_driver(rb532_led_driver);
61{
62 return platform_driver_register(&rb532_led_driver);
63}
64
65static void __exit rb532_led_exit(void)
66{
67 platform_driver_unregister(&rb532_led_driver);
68}
69
70module_init(rb532_led_init);
71module_exit(rb532_led_exit);
72
73MODULE_ALIAS("platform:rb532-led");
74 61
75MODULE_LICENSE("GPL"); 62MODULE_LICENSE("GPL");
76MODULE_DESCRIPTION("User LED support for Routerboard532"); 63MODULE_DESCRIPTION("User LED support for Routerboard532");
77MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>"); 64MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
65MODULE_ALIAS("platform:rb532-led");
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index 8497f56f8e46..df7e963bddd3 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -229,17 +229,7 @@ static struct platform_driver regulator_led_driver = {
229 .remove = __devexit_p(regulator_led_remove), 229 .remove = __devexit_p(regulator_led_remove),
230}; 230};
231 231
232static int __init regulator_led_init(void) 232module_platform_driver(regulator_led_driver);
233{
234 return platform_driver_register(&regulator_led_driver);
235}
236module_init(regulator_led_init);
237
238static void __exit regulator_led_exit(void)
239{
240 platform_driver_unregister(&regulator_led_driver);
241}
242module_exit(regulator_led_exit);
243 233
244MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 234MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
245MODULE_DESCRIPTION("Regulator driven LED driver"); 235MODULE_DESCRIPTION("Regulator driven LED driver");
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c
index 3ee540eb127e..32fe337d5c68 100644
--- a/drivers/leds/leds-renesas-tpu.c
+++ b/drivers/leds/leds-renesas-tpu.c
@@ -339,18 +339,7 @@ static struct platform_driver r_tpu_device_driver = {
339 } 339 }
340}; 340};
341 341
342static int __init r_tpu_init(void) 342module_platform_driver(r_tpu_device_driver);
343{
344 return platform_driver_register(&r_tpu_device_driver);
345}
346
347static void __exit r_tpu_exit(void)
348{
349 platform_driver_unregister(&r_tpu_device_driver);
350}
351
352module_init(r_tpu_init);
353module_exit(r_tpu_exit);
354 343
355MODULE_AUTHOR("Magnus Damm"); 344MODULE_AUTHOR("Magnus Damm");
356MODULE_DESCRIPTION("Renesas TPU LED Driver"); 345MODULE_DESCRIPTION("Renesas TPU LED Driver");
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 29f8b0f0e2c6..bd0a5ed49c42 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -121,18 +121,7 @@ static struct platform_driver s3c24xx_led_driver = {
121 }, 121 },
122}; 122};
123 123
124static int __init s3c24xx_led_init(void) 124module_platform_driver(s3c24xx_led_driver);
125{
126 return platform_driver_register(&s3c24xx_led_driver);
127}
128
129static void __exit s3c24xx_led_exit(void)
130{
131 platform_driver_unregister(&s3c24xx_led_driver);
132}
133
134module_init(s3c24xx_led_init);
135module_exit(s3c24xx_led_exit);
136 125
137MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 126MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
138MODULE_DESCRIPTION("S3C24XX LED driver"); 127MODULE_DESCRIPTION("S3C24XX LED driver");
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
new file mode 100644
index 000000000000..133f89fb7071
--- /dev/null
+++ b/drivers/leds/leds-tca6507.c
@@ -0,0 +1,779 @@
1/*
2 * leds-tca6507
3 *
4 * The TCA6507 is a programmable LED controller that can drive 7
5 * separate lines either by holding them low, or by pulsing them
6 * with modulated width.
7 * The modulation can be varied in a simple pattern to produce a blink or
8 * double-blink.
9 *
10 * This driver can configure each line either as a 'GPIO' which is out-only
11 * (no pull-up) or as an LED with variable brightness and hardware-assisted
12 * blinking.
13 *
14 * Apart from OFF and ON there are three programmable brightness levels which
15 * can be programmed from 0 to 15 and indicate how many 500usec intervals in
16 * each 8msec that the led is 'on'. The levels are named MASTER, BANK0 and
17 * BANK1.
18 *
19 * There are two different blink rates that can be programmed, each with
20 * separate time for rise, on, fall, off and second-off. Thus if 3 or more
21 * different non-trivial rates are required, software must be used for the extra
22 * rates. The two different blink rates must align with the two levels BANK0 and
23 * BANK1.
24 * This driver does not support double-blink so 'second-off' always matches
25 * 'off'.
26 *
27 * Only 16 different times can be programmed in a roughly logarithmic scale from
28 * 64ms to 16320ms. To be precise the possible times are:
29 * 0, 64, 128, 192, 256, 384, 512, 768,
30 * 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
31 *
32 * Times that cannot be closely matched with these must be
33 * handled in software. This driver allows 12.5% error in matching.
34 *
35 * This driver does not allow rise/fall rates to be set explicitly. When trying
36 * to match a given 'on' or 'off' period, an appropriate pair of 'change' and
37 * 'hold' times are chosen to get a close match. If the target delay is even,
38 * the 'change' number will be the smaller; if odd, the 'hold' number will be
39 * the smaller.
40
41 * Choosing pairs of delays with 12.5% errors allows us to match delays in the
42 * ranges: 56-72, 112-144, 168-216, 224-27504, 28560-36720.
43 * 26% of the achievable sums can be matched by multiple pairings. For example
44 * 1536 == 1536+0, 1024+512, or 768+768. This driver will always choose the
45 * pairing with the least maximum - 768+768 in this case. Other pairings are
46 * not available.
47 *
48 * Access to the 3 levels and 2 blinks are on a first-come, first-served basis.
49 * Access can be shared by multiple leds if they have the same level and
50 * either same blink rates, or some don't blink.
51 * When a led changes, it relinquishes access and tries again, so it might
52 * lose access to hardware blink.
53 * If a blink engine cannot be allocated, software blink is used.
54 * If the desired brightness cannot be allocated, the closest available non-zero
55 * brightness is used. As 'full' is always available, the worst case would be
56 * to have two different blink rates at '1', with Max at '2', then other leds
57 * will have to choose between '2' and '16'. Hopefully this is not likely.
58 *
59 * Each bank (BANK0 and BANK1) has two usage counts - LEDs using the brightness
60 * and LEDs using the blink. It can only be reprogrammed when the appropriate
61 * counter is zero. The MASTER level has a single usage count.
62 *
63 * Each Led has programmable 'on' and 'off' time as milliseconds. With each
64 * there is a flag saying if it was explicitly requested or defaulted.
65 * Similarly the banks know if each time was explicit or a default. Defaults
66 * are permitted to be changed freely - they are not recognised when matching.
67 *
68 *
69 * An led-tca6507 device must be provided with platform data. This data
70 * lists for each output: the name, default trigger, and whether the signal
71 * is being used as a GPiO rather than an led. 'struct led_plaform_data'
72 * is used for this. If 'name' is NULL, the output isn't used. If 'flags'
73 * is TCA6507_MAKE_CPIO, the output is a GPO.
74 * The "struct led_platform_data" can be embedded in a
75 * "struct tca6507_platform_data" which adds a 'gpio_base' for the GPiOs,
76 * and a 'setup' callback which is called once the GPiOs are available.
77 *
78 */
79
80#include <linux/module.h>
81#include <linux/slab.h>
82#include <linux/leds.h>
83#include <linux/err.h>
84#include <linux/i2c.h>
85#include <linux/gpio.h>
86#include <linux/workqueue.h>
87#include <linux/leds-tca6507.h>
88
89/* LED select registers determine the source that drives LED outputs */
90#define TCA6507_LS_LED_OFF 0x0 /* Output HI-Z (off) */
91#define TCA6507_LS_LED_OFF1 0x1 /* Output HI-Z (off) - not used */
92#define TCA6507_LS_LED_PWM0 0x2 /* Output LOW with Bank0 rate */
93#define TCA6507_LS_LED_PWM1 0x3 /* Output LOW with Bank1 rate */
94#define TCA6507_LS_LED_ON 0x4 /* Output LOW (on) */
95#define TCA6507_LS_LED_MIR 0x5 /* Output LOW with Master Intensity */
96#define TCA6507_LS_BLINK0 0x6 /* Blink at Bank0 rate */
97#define TCA6507_LS_BLINK1 0x7 /* Blink at Bank1 rate */
98
99enum {
100 BANK0,
101 BANK1,
102 MASTER,
103};
104static int bank_source[3] = {
105 TCA6507_LS_LED_PWM0,
106 TCA6507_LS_LED_PWM1,
107 TCA6507_LS_LED_MIR,
108};
109static int blink_source[2] = {
110 TCA6507_LS_BLINK0,
111 TCA6507_LS_BLINK1,
112};
113
114/* PWM registers */
115#define TCA6507_REG_CNT 11
116
117/*
118 * 0x00, 0x01, 0x02 encode the TCA6507_LS_* values, each output
119 * owns one bit in each register
120 */
121#define TCA6507_FADE_ON 0x03
122#define TCA6507_FULL_ON 0x04
123#define TCA6507_FADE_OFF 0x05
124#define TCA6507_FIRST_OFF 0x06
125#define TCA6507_SECOND_OFF 0x07
126#define TCA6507_MAX_INTENSITY 0x08
127#define TCA6507_MASTER_INTENSITY 0x09
128#define TCA6507_INITIALIZE 0x0A
129
130#define INIT_CODE 0x8
131
132#define TIMECODES 16
133static int time_codes[TIMECODES] = {
134 0, 64, 128, 192, 256, 384, 512, 768,
135 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
136};
137
138/* Convert an led.brightness level (0..255) to a TCA6507 level (0..15) */
139static inline int TO_LEVEL(int brightness)
140{
141 return brightness >> 4;
142}
143
144/* ...and convert back */
145static inline int TO_BRIGHT(int level)
146{
147 if (level)
148 return (level << 4) | 0xf;
149 return 0;
150}
151
152#define NUM_LEDS 7
153struct tca6507_chip {
154 int reg_set; /* One bit per register where
155 * a '1' means the register
156 * should be written */
157 u8 reg_file[TCA6507_REG_CNT];
158 /* Bank 2 is Master Intensity and doesn't use times */
159 struct bank {
160 int level;
161 int ontime, offtime;
162 int on_dflt, off_dflt;
163 int time_use, level_use;
164 } bank[3];
165 struct i2c_client *client;
166 struct work_struct work;
167 spinlock_t lock;
168
169 struct tca6507_led {
170 struct tca6507_chip *chip;
171 struct led_classdev led_cdev;
172 int num;
173 int ontime, offtime;
174 int on_dflt, off_dflt;
175 int bank; /* Bank used, or -1 */
176 int blink; /* Set if hardware-blinking */
177 } leds[NUM_LEDS];
178#ifdef CONFIG_GPIOLIB
179 struct gpio_chip gpio;
180 const char *gpio_name[NUM_LEDS];
181 int gpio_map[NUM_LEDS];
182#endif
183};
184
185static const struct i2c_device_id tca6507_id[] = {
186 { "tca6507" },
187 { }
188};
189MODULE_DEVICE_TABLE(i2c, tca6507_id);
190
191static int choose_times(int msec, int *c1p, int *c2p)
192{
193 /*
194 * Choose two timecodes which add to 'msec' as near as possible.
195 * The first returned is the 'on' or 'off' time. The second is to be
196 * used as a 'fade-on' or 'fade-off' time. If 'msec' is even,
197 * the first will not be smaller than the second. If 'msec' is odd,
198 * the first will not be larger than the second.
199 * If we cannot get a sum within 1/8 of 'msec' fail with -EINVAL,
200 * otherwise return the sum that was achieved, plus 1 if the first is
201 * smaller.
202 * If two possibilities are equally good (e.g. 512+0, 256+256), choose
203 * the first pair so there is more change-time visible (i.e. it is
204 * softer).
205 */
206 int c1, c2;
207 int tmax = msec * 9 / 8;
208 int tmin = msec * 7 / 8;
209 int diff = 65536;
210
211 /* We start at '1' to ensure we never even think of choosing a
212 * total time of '0'.
213 */
214 for (c1 = 1; c1 < TIMECODES; c1++) {
215 int t = time_codes[c1];
216 if (t*2 < tmin)
217 continue;
218 if (t > tmax)
219 break;
220 for (c2 = 0; c2 <= c1; c2++) {
221 int tt = t + time_codes[c2];
222 int d;
223 if (tt < tmin)
224 continue;
225 if (tt > tmax)
226 break;
227 /* This works! */
228 d = abs(msec - tt);
229 if (d >= diff)
230 continue;
231 /* Best yet */
232 *c1p = c1;
233 *c2p = c2;
234 diff = d;
235 if (d == 0)
236 return msec;
237 }
238 }
239 if (diff < 65536) {
240 int actual;
241 if (msec & 1) {
242 c1 = *c2p;
243 *c2p = *c1p;
244 *c1p = c1;
245 }
246 actual = time_codes[*c1p] + time_codes[*c2p];
247 if (*c1p < *c2p)
248 return actual + 1;
249 else
250 return actual;
251 }
252 /* No close match */
253 return -EINVAL;
254}
255
256/*
257 * Update the register file with the appropriate 3-bit state for
258 * the given led.
259 */
260static void set_select(struct tca6507_chip *tca, int led, int val)
261{
262 int mask = (1 << led);
263 int bit;
264
265 for (bit = 0; bit < 3; bit++) {
266 int n = tca->reg_file[bit] & ~mask;
267 if (val & (1 << bit))
268 n |= mask;
269 if (tca->reg_file[bit] != n) {
270 tca->reg_file[bit] = n;
271 tca->reg_set |= (1 << bit);
272 }
273 }
274}
275
276/* Update the register file with the appropriate 4-bit code for
277 * one bank or other. This can be used for timers, for levels, or
278 * for initialisation.
279 */
280static void set_code(struct tca6507_chip *tca, int reg, int bank, int new)
281{
282 int mask = 0xF;
283 int n;
284 if (bank) {
285 mask <<= 4;
286 new <<= 4;
287 }
288 n = tca->reg_file[reg] & ~mask;
289 n |= new;
290 if (tca->reg_file[reg] != n) {
291 tca->reg_file[reg] = n;
292 tca->reg_set |= 1 << reg;
293 }
294}
295
296/* Update brightness level. */
297static void set_level(struct tca6507_chip *tca, int bank, int level)
298{
299 switch (bank) {
300 case BANK0:
301 case BANK1:
302 set_code(tca, TCA6507_MAX_INTENSITY, bank, level);
303 break;
304 case MASTER:
305 set_code(tca, TCA6507_MASTER_INTENSITY, 0, level);
306 break;
307 }
308 tca->bank[bank].level = level;
309}
310
311/* Record all relevant time code for a given bank */
312static void set_times(struct tca6507_chip *tca, int bank)
313{
314 int c1, c2;
315 int result;
316
317 result = choose_times(tca->bank[bank].ontime, &c1, &c2);
318 dev_dbg(&tca->client->dev,
319 "Chose on times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
320 c2, time_codes[c2], tca->bank[bank].ontime);
321 set_code(tca, TCA6507_FADE_ON, bank, c2);
322 set_code(tca, TCA6507_FULL_ON, bank, c1);
323 tca->bank[bank].ontime = result;
324
325 result = choose_times(tca->bank[bank].offtime, &c1, &c2);
326 dev_dbg(&tca->client->dev,
327 "Chose off times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
328 c2, time_codes[c2], tca->bank[bank].offtime);
329 set_code(tca, TCA6507_FADE_OFF, bank, c2);
330 set_code(tca, TCA6507_FIRST_OFF, bank, c1);
331 set_code(tca, TCA6507_SECOND_OFF, bank, c1);
332 tca->bank[bank].offtime = result;
333
334 set_code(tca, TCA6507_INITIALIZE, bank, INIT_CODE);
335}
336
337/* Write all needed register of tca6507 */
338
339static void tca6507_work(struct work_struct *work)
340{
341 struct tca6507_chip *tca = container_of(work, struct tca6507_chip,
342 work);
343 struct i2c_client *cl = tca->client;
344 int set;
345 u8 file[TCA6507_REG_CNT];
346 int r;
347
348 spin_lock_irq(&tca->lock);
349 set = tca->reg_set;
350 memcpy(file, tca->reg_file, TCA6507_REG_CNT);
351 tca->reg_set = 0;
352 spin_unlock_irq(&tca->lock);
353
354 for (r = 0; r < TCA6507_REG_CNT; r++)
355 if (set & (1<<r))
356 i2c_smbus_write_byte_data(cl, r, file[r]);
357}
358
359static void led_release(struct tca6507_led *led)
360{
361 /* If led owns any resource, release it. */
362 struct tca6507_chip *tca = led->chip;
363 if (led->bank >= 0) {
364 struct bank *b = tca->bank + led->bank;
365 if (led->blink)
366 b->time_use--;
367 b->level_use--;
368 }
369 led->blink = 0;
370 led->bank = -1;
371}
372
373static int led_prepare(struct tca6507_led *led)
374{
375 /* Assign this led to a bank, configuring that bank if necessary. */
376 int level = TO_LEVEL(led->led_cdev.brightness);
377 struct tca6507_chip *tca = led->chip;
378 int c1, c2;
379 int i;
380 struct bank *b;
381 int need_init = 0;
382
383 led->led_cdev.brightness = TO_BRIGHT(level);
384 if (level == 0) {
385 set_select(tca, led->num, TCA6507_LS_LED_OFF);
386 return 0;
387 }
388
389 if (led->ontime == 0 || led->offtime == 0) {
390 /*
391 * Just set the brightness, choosing first usable bank.
392 * If none perfect, choose best.
393 * Count backwards so we check MASTER bank first
394 * to avoid wasting a timer.
395 */
396 int best = -1;/* full-on */
397 int diff = 15-level;
398
399 if (level == 15) {
400 set_select(tca, led->num, TCA6507_LS_LED_ON);
401 return 0;
402 }
403
404 for (i = MASTER; i >= BANK0; i--) {
405 int d;
406 if (tca->bank[i].level == level ||
407 tca->bank[i].level_use == 0) {
408 best = i;
409 break;
410 }
411 d = abs(level - tca->bank[i].level);
412 if (d < diff) {
413 diff = d;
414 best = i;
415 }
416 }
417 if (best == -1) {
418 /* Best brightness is full-on */
419 set_select(tca, led->num, TCA6507_LS_LED_ON);
420 led->led_cdev.brightness = LED_FULL;
421 return 0;
422 }
423
424 if (!tca->bank[best].level_use)
425 set_level(tca, best, level);
426
427 tca->bank[best].level_use++;
428 led->bank = best;
429 set_select(tca, led->num, bank_source[best]);
430 led->led_cdev.brightness = TO_BRIGHT(tca->bank[best].level);
431 return 0;
432 }
433
434 /*
435 * We have on/off time so we need to try to allocate a timing bank.
436 * First check if times are compatible with hardware and give up if
437 * not.
438 */
439 if (choose_times(led->ontime, &c1, &c2) < 0)
440 return -EINVAL;
441 if (choose_times(led->offtime, &c1, &c2) < 0)
442 return -EINVAL;
443
444 for (i = BANK0; i <= BANK1; i++) {
445 if (tca->bank[i].level_use == 0)
446 /* not in use - it is ours! */
447 break;
448 if (tca->bank[i].level != level)
449 /* Incompatible level - skip */
450 /* FIX: if timer matches we maybe should consider
451 * this anyway...
452 */
453 continue;
454
455 if (tca->bank[i].time_use == 0)
456 /* Timer not in use, and level matches - use it */
457 break;
458
459 if (!(tca->bank[i].on_dflt ||
460 led->on_dflt ||
461 tca->bank[i].ontime == led->ontime))
462 /* on time is incompatible */
463 continue;
464
465 if (!(tca->bank[i].off_dflt ||
466 led->off_dflt ||
467 tca->bank[i].offtime == led->offtime))
468 /* off time is incompatible */
469 continue;
470
471 /* looks like a suitable match */
472 break;
473 }
474
475 if (i > BANK1)
476 /* Nothing matches - how sad */
477 return -EINVAL;
478
479 b = &tca->bank[i];
480 if (b->level_use == 0)
481 set_level(tca, i, level);
482 b->level_use++;
483 led->bank = i;
484
485 if (b->on_dflt ||
486 !led->on_dflt ||
487 b->time_use == 0) {
488 b->ontime = led->ontime;
489 b->on_dflt = led->on_dflt;
490 need_init = 1;
491 }
492
493 if (b->off_dflt ||
494 !led->off_dflt ||
495 b->time_use == 0) {
496 b->offtime = led->offtime;
497 b->off_dflt = led->off_dflt;
498 need_init = 1;
499 }
500
501 if (need_init)
502 set_times(tca, i);
503
504 led->ontime = b->ontime;
505 led->offtime = b->offtime;
506
507 b->time_use++;
508 led->blink = 1;
509 led->led_cdev.brightness = TO_BRIGHT(b->level);
510 set_select(tca, led->num, blink_source[i]);
511 return 0;
512}
513
514static int led_assign(struct tca6507_led *led)
515{
516 struct tca6507_chip *tca = led->chip;
517 int err;
518 unsigned long flags;
519
520 spin_lock_irqsave(&tca->lock, flags);
521 led_release(led);
522 err = led_prepare(led);
523 if (err) {
524 /*
525 * Can only fail on timer setup. In that case we need to
526 * re-establish as steady level.
527 */
528 led->ontime = 0;
529 led->offtime = 0;
530 led_prepare(led);
531 }
532 spin_unlock_irqrestore(&tca->lock, flags);
533
534 if (tca->reg_set)
535 schedule_work(&tca->work);
536 return err;
537}
538
539static void tca6507_brightness_set(struct led_classdev *led_cdev,
540 enum led_brightness brightness)
541{
542 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led,
543 led_cdev);
544 led->led_cdev.brightness = brightness;
545 led->ontime = 0;
546 led->offtime = 0;
547 led_assign(led);
548}
549
550static int tca6507_blink_set(struct led_classdev *led_cdev,
551 unsigned long *delay_on,
552 unsigned long *delay_off)
553{
554 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led,
555 led_cdev);
556
557 if (*delay_on == 0)
558 led->on_dflt = 1;
559 else if (delay_on != &led_cdev->blink_delay_on)
560 led->on_dflt = 0;
561 led->ontime = *delay_on;
562
563 if (*delay_off == 0)
564 led->off_dflt = 1;
565 else if (delay_off != &led_cdev->blink_delay_off)
566 led->off_dflt = 0;
567 led->offtime = *delay_off;
568
569 if (led->ontime == 0)
570 led->ontime = 512;
571 if (led->offtime == 0)
572 led->offtime = 512;
573
574 if (led->led_cdev.brightness == LED_OFF)
575 led->led_cdev.brightness = LED_FULL;
576 if (led_assign(led) < 0) {
577 led->ontime = 0;
578 led->offtime = 0;
579 led->led_cdev.brightness = LED_OFF;
580 return -EINVAL;
581 }
582 *delay_on = led->ontime;
583 *delay_off = led->offtime;
584 return 0;
585}
586
587#ifdef CONFIG_GPIOLIB
588static void tca6507_gpio_set_value(struct gpio_chip *gc,
589 unsigned offset, int val)
590{
591 struct tca6507_chip *tca = container_of(gc, struct tca6507_chip, gpio);
592 unsigned long flags;
593
594 spin_lock_irqsave(&tca->lock, flags);
595 /*
596 * 'OFF' is floating high, and 'ON' is pulled down, so it has the
597 * inverse sense of 'val'.
598 */
599 set_select(tca, tca->gpio_map[offset],
600 val ? TCA6507_LS_LED_OFF : TCA6507_LS_LED_ON);
601 spin_unlock_irqrestore(&tca->lock, flags);
602 if (tca->reg_set)
603 schedule_work(&tca->work);
604}
605
606static int tca6507_gpio_direction_output(struct gpio_chip *gc,
607 unsigned offset, int val)
608{
609 tca6507_gpio_set_value(gc, offset, val);
610 return 0;
611}
612
613static int tca6507_probe_gpios(struct i2c_client *client,
614 struct tca6507_chip *tca,
615 struct tca6507_platform_data *pdata)
616{
617 int err;
618 int i = 0;
619 int gpios = 0;
620
621 for (i = 0; i < NUM_LEDS; i++)
622 if (pdata->leds.leds[i].name && pdata->leds.leds[i].flags) {
623 /* Configure as a gpio */
624 tca->gpio_name[gpios] = pdata->leds.leds[i].name;
625 tca->gpio_map[gpios] = i;
626 gpios++;
627 }
628
629 if (!gpios)
630 return 0;
631
632 tca->gpio.label = "gpio-tca6507";
633 tca->gpio.names = tca->gpio_name;
634 tca->gpio.ngpio = gpios;
635 tca->gpio.base = pdata->gpio_base;
636 tca->gpio.owner = THIS_MODULE;
637 tca->gpio.direction_output = tca6507_gpio_direction_output;
638 tca->gpio.set = tca6507_gpio_set_value;
639 tca->gpio.dev = &client->dev;
640 err = gpiochip_add(&tca->gpio);
641 if (err) {
642 tca->gpio.ngpio = 0;
643 return err;
644 }
645 if (pdata->setup)
646 pdata->setup(tca->gpio.base, tca->gpio.ngpio);
647 return 0;
648}
649
650static void tca6507_remove_gpio(struct tca6507_chip *tca)
651{
652 if (tca->gpio.ngpio) {
653 int err = gpiochip_remove(&tca->gpio);
654 dev_err(&tca->client->dev, "%s failed, %d\n",
655 "gpiochip_remove()", err);
656 }
657}
658#else /* CONFIG_GPIOLIB */
659static int tca6507_probe_gpios(struct i2c_client *client,
660 struct tca6507_chip *tca,
661 struct tca6507_platform_data *pdata)
662{
663 return 0;
664}
665static void tca6507_remove_gpio(struct tca6507_chip *tca)
666{
667}
668#endif /* CONFIG_GPIOLIB */
669
670static int __devinit tca6507_probe(struct i2c_client *client,
671 const struct i2c_device_id *id)
672{
673 struct tca6507_chip *tca;
674 struct i2c_adapter *adapter;
675 struct tca6507_platform_data *pdata;
676 int err;
677 int i = 0;
678
679 adapter = to_i2c_adapter(client->dev.parent);
680 pdata = client->dev.platform_data;
681
682 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
683 return -EIO;
684
685 if (!pdata || pdata->leds.num_leds != NUM_LEDS) {
686 dev_err(&client->dev, "Need %d entries in platform-data list\n",
687 NUM_LEDS);
688 return -ENODEV;
689 }
690 err = -ENOMEM;
691 tca = kzalloc(sizeof(*tca), GFP_KERNEL);
692 if (!tca)
693 goto exit;
694
695 tca->client = client;
696 INIT_WORK(&tca->work, tca6507_work);
697 spin_lock_init(&tca->lock);
698 i2c_set_clientdata(client, tca);
699
700 for (i = 0; i < NUM_LEDS; i++) {
701 struct tca6507_led *l = tca->leds + i;
702
703 l->chip = tca;
704 l->num = i;
705 if (pdata->leds.leds[i].name && !pdata->leds.leds[i].flags) {
706 l->led_cdev.name = pdata->leds.leds[i].name;
707 l->led_cdev.default_trigger
708 = pdata->leds.leds[i].default_trigger;
709 l->led_cdev.brightness_set = tca6507_brightness_set;
710 l->led_cdev.blink_set = tca6507_blink_set;
711 l->bank = -1;
712 err = led_classdev_register(&client->dev,
713 &l->led_cdev);
714 if (err < 0)
715 goto exit;
716 }
717 }
718 err = tca6507_probe_gpios(client, tca, pdata);
719 if (err)
720 goto exit;
721 /* set all registers to known state - zero */
722 tca->reg_set = 0x7f;
723 schedule_work(&tca->work);
724
725 return 0;
726exit:
727 while (i--)
728 if (tca->leds[i].led_cdev.name)
729 led_classdev_unregister(&tca->leds[i].led_cdev);
730 cancel_work_sync(&tca->work);
731 i2c_set_clientdata(client, NULL);
732 kfree(tca);
733 return err;
734}
735
736static int __devexit tca6507_remove(struct i2c_client *client)
737{
738 int i;
739 struct tca6507_chip *tca = i2c_get_clientdata(client);
740 struct tca6507_led *tca_leds = tca->leds;
741
742 for (i = 0; i < NUM_LEDS; i++) {
743 if (tca_leds[i].led_cdev.name)
744 led_classdev_unregister(&tca_leds[i].led_cdev);
745 }
746 tca6507_remove_gpio(tca);
747 cancel_work_sync(&tca->work);
748 i2c_set_clientdata(client, NULL);
749 kfree(tca);
750
751 return 0;
752}
753
754static struct i2c_driver tca6507_driver = {
755 .driver = {
756 .name = "leds-tca6507",
757 .owner = THIS_MODULE,
758 },
759 .probe = tca6507_probe,
760 .remove = __devexit_p(tca6507_remove),
761 .id_table = tca6507_id,
762};
763
764static int __init tca6507_leds_init(void)
765{
766 return i2c_add_driver(&tca6507_driver);
767}
768
769static void __exit tca6507_leds_exit(void)
770{
771 i2c_del_driver(&tca6507_driver);
772}
773
774module_init(tca6507_leds_init);
775module_exit(tca6507_leds_exit);
776
777MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
778MODULE_DESCRIPTION("TCA6507 LED/GPO driver");
779MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index b1eb34c3e81f..74a24cf897c3 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -237,7 +237,8 @@ static int wm831x_status_probe(struct platform_device *pdev)
237 goto err; 237 goto err;
238 } 238 }
239 239
240 drvdata = kzalloc(sizeof(struct wm831x_status), GFP_KERNEL); 240 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status),
241 GFP_KERNEL);
241 if (!drvdata) 242 if (!drvdata)
242 return -ENOMEM; 243 return -ENOMEM;
243 dev_set_drvdata(&pdev->dev, drvdata); 244 dev_set_drvdata(&pdev->dev, drvdata);
@@ -300,7 +301,6 @@ static int wm831x_status_probe(struct platform_device *pdev)
300 301
301err_led: 302err_led:
302 led_classdev_unregister(&drvdata->cdev); 303 led_classdev_unregister(&drvdata->cdev);
303 kfree(drvdata);
304err: 304err:
305 return ret; 305 return ret;
306} 306}
@@ -311,7 +311,6 @@ static int wm831x_status_remove(struct platform_device *pdev)
311 311
312 device_remove_file(drvdata->cdev.dev, &dev_attr_src); 312 device_remove_file(drvdata->cdev.dev, &dev_attr_src);
313 led_classdev_unregister(&drvdata->cdev); 313 led_classdev_unregister(&drvdata->cdev);
314 kfree(drvdata);
315 314
316 return 0; 315 return 0;
317} 316}
@@ -325,17 +324,7 @@ static struct platform_driver wm831x_status_driver = {
325 .remove = wm831x_status_remove, 324 .remove = wm831x_status_remove,
326}; 325};
327 326
328static int __devinit wm831x_status_init(void) 327module_platform_driver(wm831x_status_driver);
329{
330 return platform_driver_register(&wm831x_status_driver);
331}
332module_init(wm831x_status_init);
333
334static void wm831x_status_exit(void)
335{
336 platform_driver_unregister(&wm831x_status_driver);
337}
338module_exit(wm831x_status_exit);
339 328
340MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 329MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
341MODULE_DESCRIPTION("WM831x status LED driver"); 330MODULE_DESCRIPTION("WM831x status LED driver");
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index 4a1276578352..918d4baff1c7 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -227,7 +227,7 @@ static int wm8350_led_probe(struct platform_device *pdev)
227 goto err_isink; 227 goto err_isink;
228 } 228 }
229 229
230 led = kzalloc(sizeof(*led), GFP_KERNEL); 230 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
231 if (led == NULL) { 231 if (led == NULL) {
232 ret = -ENOMEM; 232 ret = -ENOMEM;
233 goto err_dcdc; 233 goto err_dcdc;
@@ -259,12 +259,10 @@ static int wm8350_led_probe(struct platform_device *pdev)
259 259
260 ret = led_classdev_register(&pdev->dev, &led->cdev); 260 ret = led_classdev_register(&pdev->dev, &led->cdev);
261 if (ret < 0) 261 if (ret < 0)
262 goto err_led; 262 goto err_dcdc;
263 263
264 return 0; 264 return 0;
265 265
266 err_led:
267 kfree(led);
268 err_dcdc: 266 err_dcdc:
269 regulator_put(dcdc); 267 regulator_put(dcdc);
270 err_isink: 268 err_isink:
@@ -281,7 +279,6 @@ static int wm8350_led_remove(struct platform_device *pdev)
281 wm8350_led_disable(led); 279 wm8350_led_disable(led);
282 regulator_put(led->dcdc); 280 regulator_put(led->dcdc);
283 regulator_put(led->isink); 281 regulator_put(led->isink);
284 kfree(led);
285 return 0; 282 return 0;
286} 283}
287 284
@@ -295,17 +292,7 @@ static struct platform_driver wm8350_led_driver = {
295 .shutdown = wm8350_led_shutdown, 292 .shutdown = wm8350_led_shutdown,
296}; 293};
297 294
298static int __devinit wm8350_led_init(void) 295module_platform_driver(wm8350_led_driver);
299{
300 return platform_driver_register(&wm8350_led_driver);
301}
302module_init(wm8350_led_init);
303
304static void wm8350_led_exit(void)
305{
306 platform_driver_unregister(&wm8350_led_driver);
307}
308module_exit(wm8350_led_exit);
309 296
310MODULE_AUTHOR("Mark Brown"); 297MODULE_AUTHOR("Mark Brown");
311MODULE_DESCRIPTION("WM8350 LED driver"); 298MODULE_DESCRIPTION("WM8350 LED driver");
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 8e286259a007..8a1c031391d6 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -228,11 +228,11 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
228 alarm->time.tm_hour = now.tm_hour; 228 alarm->time.tm_hour = now.tm_hour;
229 229
230 /* For simplicity, only support date rollover for now */ 230 /* For simplicity, only support date rollover for now */
231 if (alarm->time.tm_mday == -1) { 231 if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) {
232 alarm->time.tm_mday = now.tm_mday; 232 alarm->time.tm_mday = now.tm_mday;
233 missing = day; 233 missing = day;
234 } 234 }
235 if (alarm->time.tm_mon == -1) { 235 if ((unsigned)alarm->time.tm_mon >= 12) {
236 alarm->time.tm_mon = now.tm_mon; 236 alarm->time.tm_mon = now.tm_mon;
237 if (missing == none) 237 if (missing == none)
238 missing = month; 238 missing = month;
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index 64b847b7f970..f04761e6622d 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -410,17 +410,7 @@ static struct platform_driver pm860x_rtc_driver = {
410 .remove = __devexit_p(pm860x_rtc_remove), 410 .remove = __devexit_p(pm860x_rtc_remove),
411}; 411};
412 412
413static int __init pm860x_rtc_init(void) 413module_platform_driver(pm860x_rtc_driver);
414{
415 return platform_driver_register(&pm860x_rtc_driver);
416}
417module_init(pm860x_rtc_init);
418
419static void __exit pm860x_rtc_exit(void)
420{
421 platform_driver_unregister(&pm860x_rtc_driver);
422}
423module_exit(pm860x_rtc_exit);
424 414
425MODULE_DESCRIPTION("Marvell 88PM860x RTC driver"); 415MODULE_DESCRIPTION("Marvell 88PM860x RTC driver");
426MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 416MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index e346705aae92..a0a9810adf0b 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -90,7 +90,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
90 90
91 /* Early AB8500 chips will not clear the rtc read request bit */ 91 /* Early AB8500 chips will not clear the rtc read request bit */
92 if (abx500_get_chip_id(dev) == 0) { 92 if (abx500_get_chip_id(dev) == 0) {
93 msleep(1); 93 usleep_range(1000, 1000);
94 } else { 94 } else {
95 /* Wait for some cycles after enabling the rtc read in ab8500 */ 95 /* Wait for some cycles after enabling the rtc read in ab8500 */
96 while (time_before(jiffies, timeout)) { 96 while (time_before(jiffies, timeout)) {
@@ -102,7 +102,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
102 if (!(value & RTC_READ_REQUEST)) 102 if (!(value & RTC_READ_REQUEST))
103 break; 103 break;
104 104
105 msleep(1); 105 usleep_range(1000, 5000);
106 } 106 }
107 } 107 }
108 108
@@ -258,6 +258,109 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
258 return ab8500_rtc_irq_enable(dev, alarm->enabled); 258 return ab8500_rtc_irq_enable(dev, alarm->enabled);
259} 259}
260 260
261
262static int ab8500_rtc_set_calibration(struct device *dev, int calibration)
263{
264 int retval;
265 u8 rtccal = 0;
266
267 /*
268 * Check that the calibration value (which is in units of 0.5
269 * parts-per-million) is in the AB8500's range for RtcCalibration
270 * register. -128 (0x80) is not permitted because the AB8500 uses
271 * a sign-bit rather than two's complement, so 0x80 is just another
272 * representation of zero.
273 */
274 if ((calibration < -127) || (calibration > 127)) {
275 dev_err(dev, "RtcCalibration value outside permitted range\n");
276 return -EINVAL;
277 }
278
279 /*
280 * The AB8500 uses sign (in bit7) and magnitude (in bits0-7)
281 * so need to convert to this sort of representation before writing
282 * into RtcCalibration register...
283 */
284 if (calibration >= 0)
285 rtccal = 0x7F & calibration;
286 else
287 rtccal = ~(calibration - 1) | 0x80;
288
289 retval = abx500_set_register_interruptible(dev, AB8500_RTC,
290 AB8500_RTC_CALIB_REG, rtccal);
291
292 return retval;
293}
294
295static int ab8500_rtc_get_calibration(struct device *dev, int *calibration)
296{
297 int retval;
298 u8 rtccal = 0;
299
300 retval = abx500_get_register_interruptible(dev, AB8500_RTC,
301 AB8500_RTC_CALIB_REG, &rtccal);
302 if (retval >= 0) {
303 /*
304 * The AB8500 uses sign (in bit7) and magnitude (in bits0-7)
305 * so need to convert value from RtcCalibration register into
306 * a two's complement signed value...
307 */
308 if (rtccal & 0x80)
309 *calibration = 0 - (rtccal & 0x7F);
310 else
311 *calibration = 0x7F & rtccal;
312 }
313
314 return retval;
315}
316
317static ssize_t ab8500_sysfs_store_rtc_calibration(struct device *dev,
318 struct device_attribute *attr,
319 const char *buf, size_t count)
320{
321 int retval;
322 int calibration = 0;
323
324 if (sscanf(buf, " %i ", &calibration) != 1) {
325 dev_err(dev, "Failed to store RTC calibration attribute\n");
326 return -EINVAL;
327 }
328
329 retval = ab8500_rtc_set_calibration(dev, calibration);
330
331 return retval ? retval : count;
332}
333
334static ssize_t ab8500_sysfs_show_rtc_calibration(struct device *dev,
335 struct device_attribute *attr, char *buf)
336{
337 int retval = 0;
338 int calibration = 0;
339
340 retval = ab8500_rtc_get_calibration(dev, &calibration);
341 if (retval < 0) {
342 dev_err(dev, "Failed to read RTC calibration attribute\n");
343 sprintf(buf, "0\n");
344 return retval;
345 }
346
347 return sprintf(buf, "%d\n", calibration);
348}
349
350static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR,
351 ab8500_sysfs_show_rtc_calibration,
352 ab8500_sysfs_store_rtc_calibration);
353
354static int ab8500_sysfs_rtc_register(struct device *dev)
355{
356 return device_create_file(dev, &dev_attr_rtc_calibration);
357}
358
359static void ab8500_sysfs_rtc_unregister(struct device *dev)
360{
361 device_remove_file(dev, &dev_attr_rtc_calibration);
362}
363
261static irqreturn_t rtc_alarm_handler(int irq, void *data) 364static irqreturn_t rtc_alarm_handler(int irq, void *data)
262{ 365{
263 struct rtc_device *rtc = data; 366 struct rtc_device *rtc = data;
@@ -295,7 +398,7 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
295 return err; 398 return err;
296 399
297 /* Wait for reset by the PorRtc */ 400 /* Wait for reset by the PorRtc */
298 msleep(1); 401 usleep_range(1000, 5000);
299 402
300 err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC, 403 err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC,
301 AB8500_RTC_STAT_REG, &rtc_ctrl); 404 AB8500_RTC_STAT_REG, &rtc_ctrl);
@@ -308,6 +411,8 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
308 return -ENODEV; 411 return -ENODEV;
309 } 412 }
310 413
414 device_init_wakeup(&pdev->dev, true);
415
311 rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, 416 rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops,
312 THIS_MODULE); 417 THIS_MODULE);
313 if (IS_ERR(rtc)) { 418 if (IS_ERR(rtc)) {
@@ -316,8 +421,8 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
316 return err; 421 return err;
317 } 422 }
318 423
319 err = request_threaded_irq(irq, NULL, rtc_alarm_handler, 0, 424 err = request_threaded_irq(irq, NULL, rtc_alarm_handler,
320 "ab8500-rtc", rtc); 425 IRQF_NO_SUSPEND, "ab8500-rtc", rtc);
321 if (err < 0) { 426 if (err < 0) {
322 rtc_device_unregister(rtc); 427 rtc_device_unregister(rtc);
323 return err; 428 return err;
@@ -325,6 +430,13 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
325 430
326 platform_set_drvdata(pdev, rtc); 431 platform_set_drvdata(pdev, rtc);
327 432
433
434 err = ab8500_sysfs_rtc_register(&pdev->dev);
435 if (err) {
436 dev_err(&pdev->dev, "sysfs RTC failed to register\n");
437 return err;
438 }
439
328 return 0; 440 return 0;
329} 441}
330 442
@@ -333,6 +445,8 @@ static int __devexit ab8500_rtc_remove(struct platform_device *pdev)
333 struct rtc_device *rtc = platform_get_drvdata(pdev); 445 struct rtc_device *rtc = platform_get_drvdata(pdev);
334 int irq = platform_get_irq_byname(pdev, "ALARM"); 446 int irq = platform_get_irq_byname(pdev, "ALARM");
335 447
448 ab8500_sysfs_rtc_unregister(&pdev->dev);
449
336 free_irq(irq, rtc); 450 free_irq(irq, rtc);
337 rtc_device_unregister(rtc); 451 rtc_device_unregister(rtc);
338 platform_set_drvdata(pdev, NULL); 452 platform_set_drvdata(pdev, NULL);
@@ -349,18 +463,8 @@ static struct platform_driver ab8500_rtc_driver = {
349 .remove = __devexit_p(ab8500_rtc_remove), 463 .remove = __devexit_p(ab8500_rtc_remove),
350}; 464};
351 465
352static int __init ab8500_rtc_init(void) 466module_platform_driver(ab8500_rtc_driver);
353{
354 return platform_driver_register(&ab8500_rtc_driver);
355}
356
357static void __exit ab8500_rtc_exit(void)
358{
359 platform_driver_unregister(&ab8500_rtc_driver);
360}
361 467
362module_init(ab8500_rtc_init);
363module_exit(ab8500_rtc_exit);
364MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>"); 468MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>");
365MODULE_DESCRIPTION("AB8500 RTC Driver"); 469MODULE_DESCRIPTION("AB8500 RTC Driver");
366MODULE_LICENSE("GPL v2"); 470MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 90d866272c8e..abfc1a0c07d9 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -456,18 +456,7 @@ static struct platform_driver bfin_rtc_driver = {
456 .resume = bfin_rtc_resume, 456 .resume = bfin_rtc_resume,
457}; 457};
458 458
459static int __init bfin_rtc_init(void) 459module_platform_driver(bfin_rtc_driver);
460{
461 return platform_driver_register(&bfin_rtc_driver);
462}
463
464static void __exit bfin_rtc_exit(void)
465{
466 platform_driver_unregister(&bfin_rtc_driver);
467}
468
469module_init(bfin_rtc_init);
470module_exit(bfin_rtc_exit);
471 460
472MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); 461MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
473MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); 462MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c
index 128270ce355d..bf612ef22941 100644
--- a/drivers/rtc/rtc-bq4802.c
+++ b/drivers/rtc/rtc-bq4802.c
@@ -218,15 +218,4 @@ static struct platform_driver bq4802_driver = {
218 .remove = __devexit_p(bq4802_remove), 218 .remove = __devexit_p(bq4802_remove),
219}; 219};
220 220
221static int __init bq4802_init(void) 221module_platform_driver(bq4802_driver);
222{
223 return platform_driver_register(&bq4802_driver);
224}
225
226static void __exit bq4802_exit(void)
227{
228 platform_driver_unregister(&bq4802_driver);
229}
230
231module_init(bq4802_init);
232module_exit(bq4802_exit);
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 05beb6c1ca79..d7782aa09943 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -164,7 +164,7 @@ static inline unsigned char cmos_read_bank2(unsigned char addr)
164static inline void cmos_write_bank2(unsigned char val, unsigned char addr) 164static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
165{ 165{
166 outb(addr, RTC_PORT(2)); 166 outb(addr, RTC_PORT(2));
167 outb(val, RTC_PORT(2)); 167 outb(val, RTC_PORT(3));
168} 168}
169 169
170#else 170#else
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
index 2322c43af201..d4457afcba89 100644
--- a/drivers/rtc/rtc-dm355evm.c
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -161,16 +161,6 @@ static struct platform_driver rtc_dm355evm_driver = {
161 }, 161 },
162}; 162};
163 163
164static int __init dm355evm_rtc_init(void) 164module_platform_driver(rtc_dm355evm_driver);
165{
166 return platform_driver_register(&rtc_dm355evm_driver);
167}
168module_init(dm355evm_rtc_init);
169
170static void __exit dm355evm_rtc_exit(void)
171{
172 platform_driver_unregister(&rtc_dm355evm_driver);
173}
174module_exit(dm355evm_rtc_exit);
175 165
176MODULE_LICENSE("GPL"); 166MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index 68e6caf25496..990c3ff489bf 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -396,21 +396,10 @@ static struct platform_driver ds1286_platform_driver = {
396 .remove = __devexit_p(ds1286_remove), 396 .remove = __devexit_p(ds1286_remove),
397}; 397};
398 398
399static int __init ds1286_init(void) 399module_platform_driver(ds1286_platform_driver);
400{
401 return platform_driver_register(&ds1286_platform_driver);
402}
403
404static void __exit ds1286_exit(void)
405{
406 platform_driver_unregister(&ds1286_platform_driver);
407}
408 400
409MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); 401MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
410MODULE_DESCRIPTION("DS1286 RTC driver"); 402MODULE_DESCRIPTION("DS1286 RTC driver");
411MODULE_LICENSE("GPL"); 403MODULE_LICENSE("GPL");
412MODULE_VERSION(DRV_VERSION); 404MODULE_VERSION(DRV_VERSION);
413MODULE_ALIAS("platform:rtc-ds1286"); 405MODULE_ALIAS("platform:rtc-ds1286");
414
415module_init(ds1286_init);
416module_exit(ds1286_exit);
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 586c244a05d8..761f36bc83a9 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -580,20 +580,7 @@ static struct platform_driver ds1511_rtc_driver = {
580 }, 580 },
581}; 581};
582 582
583 static int __init 583module_platform_driver(ds1511_rtc_driver);
584ds1511_rtc_init(void)
585{
586 return platform_driver_register(&ds1511_rtc_driver);
587}
588
589 static void __exit
590ds1511_rtc_exit(void)
591{
592 platform_driver_unregister(&ds1511_rtc_driver);
593}
594
595module_init(ds1511_rtc_init);
596module_exit(ds1511_rtc_exit);
597 584
598MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>"); 585MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
599MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); 586MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 1350029044e6..6f0a1b530f2e 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -361,18 +361,7 @@ static struct platform_driver ds1553_rtc_driver = {
361 }, 361 },
362}; 362};
363 363
364static __init int ds1553_init(void) 364module_platform_driver(ds1553_rtc_driver);
365{
366 return platform_driver_register(&ds1553_rtc_driver);
367}
368
369static __exit void ds1553_exit(void)
370{
371 platform_driver_unregister(&ds1553_rtc_driver);
372}
373
374module_init(ds1553_init);
375module_exit(ds1553_exit);
376 365
377MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 366MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
378MODULE_DESCRIPTION("Dallas DS1553 RTC driver"); 367MODULE_DESCRIPTION("Dallas DS1553 RTC driver");
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index e3e0f92b60f0..76112667c507 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -240,18 +240,7 @@ static struct platform_driver ds1742_rtc_driver = {
240 }, 240 },
241}; 241};
242 242
243static __init int ds1742_init(void) 243module_platform_driver(ds1742_rtc_driver);
244{
245 return platform_driver_register(&ds1742_rtc_driver);
246}
247
248static __exit void ds1742_exit(void)
249{
250 platform_driver_unregister(&ds1742_rtc_driver);
251}
252
253module_init(ds1742_init);
254module_exit(ds1742_exit);
255 244
256MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 245MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
257MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); 246MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index b6473631d182..05ab227eeff7 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -345,7 +345,7 @@ static const struct dev_pm_ops jz4740_pm_ops = {
345#define JZ4740_RTC_PM_OPS NULL 345#define JZ4740_RTC_PM_OPS NULL
346#endif /* CONFIG_PM */ 346#endif /* CONFIG_PM */
347 347
348struct platform_driver jz4740_rtc_driver = { 348static struct platform_driver jz4740_rtc_driver = {
349 .probe = jz4740_rtc_probe, 349 .probe = jz4740_rtc_probe,
350 .remove = __devexit_p(jz4740_rtc_remove), 350 .remove = __devexit_p(jz4740_rtc_remove),
351 .driver = { 351 .driver = {
@@ -355,17 +355,7 @@ struct platform_driver jz4740_rtc_driver = {
355 }, 355 },
356}; 356};
357 357
358static int __init jz4740_rtc_init(void) 358module_platform_driver(jz4740_rtc_driver);
359{
360 return platform_driver_register(&jz4740_rtc_driver);
361}
362module_init(jz4740_rtc_init);
363
364static void __exit jz4740_rtc_exit(void)
365{
366 platform_driver_unregister(&jz4740_rtc_driver);
367}
368module_exit(jz4740_rtc_exit);
369 359
370MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 360MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
371MODULE_LICENSE("GPL"); 361MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index ae16250c762f..ecc1713b2b4f 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -396,17 +396,7 @@ static struct platform_driver lpc32xx_rtc_driver = {
396 }, 396 },
397}; 397};
398 398
399static int __init lpc32xx_rtc_init(void) 399module_platform_driver(lpc32xx_rtc_driver);
400{
401 return platform_driver_register(&lpc32xx_rtc_driver);
402}
403module_init(lpc32xx_rtc_init);
404
405static void __exit lpc32xx_rtc_exit(void)
406{
407 platform_driver_unregister(&lpc32xx_rtc_driver);
408}
409module_exit(lpc32xx_rtc_exit);
410 400
411MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); 401MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com");
412MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); 402MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC");
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index 7317d3b9a3d5..ef71132ff205 100644
--- a/drivers/rtc/rtc-m41t93.c
+++ b/drivers/rtc/rtc-m41t93.c
@@ -200,7 +200,6 @@ static int __devexit m41t93_remove(struct spi_device *spi)
200static struct spi_driver m41t93_driver = { 200static struct spi_driver m41t93_driver = {
201 .driver = { 201 .driver = {
202 .name = "rtc-m41t93", 202 .name = "rtc-m41t93",
203 .bus = &spi_bus_type,
204 .owner = THIS_MODULE, 203 .owner = THIS_MODULE,
205 }, 204 },
206 .probe = m41t93_probe, 205 .probe = m41t93_probe,
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c
index e259ed76ae85..2a4721f61797 100644
--- a/drivers/rtc/rtc-m41t94.c
+++ b/drivers/rtc/rtc-m41t94.c
@@ -147,7 +147,6 @@ static int __devexit m41t94_remove(struct spi_device *spi)
147static struct spi_driver m41t94_driver = { 147static struct spi_driver m41t94_driver = {
148 .driver = { 148 .driver = {
149 .name = "rtc-m41t94", 149 .name = "rtc-m41t94",
150 .bus = &spi_bus_type,
151 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
152 }, 151 },
153 .probe = m41t94_probe, 152 .probe = m41t94_probe,
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index 8e2a24e33ed6..f9e3b3583733 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -216,21 +216,10 @@ static struct platform_driver m48t35_platform_driver = {
216 .remove = __devexit_p(m48t35_remove), 216 .remove = __devexit_p(m48t35_remove),
217}; 217};
218 218
219static int __init m48t35_init(void) 219module_platform_driver(m48t35_platform_driver);
220{
221 return platform_driver_register(&m48t35_platform_driver);
222}
223
224static void __exit m48t35_exit(void)
225{
226 platform_driver_unregister(&m48t35_platform_driver);
227}
228 220
229MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); 221MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
230MODULE_DESCRIPTION("M48T35 RTC driver"); 222MODULE_DESCRIPTION("M48T35 RTC driver");
231MODULE_LICENSE("GPL"); 223MODULE_LICENSE("GPL");
232MODULE_VERSION(DRV_VERSION); 224MODULE_VERSION(DRV_VERSION);
233MODULE_ALIAS("platform:rtc-m48t35"); 225MODULE_ALIAS("platform:rtc-m48t35");
234
235module_init(m48t35_init);
236module_exit(m48t35_exit);
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index 28365388fb6c..30ebfec9fd2b 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -530,18 +530,7 @@ static struct platform_driver m48t59_rtc_driver = {
530 .remove = __devexit_p(m48t59_rtc_remove), 530 .remove = __devexit_p(m48t59_rtc_remove),
531}; 531};
532 532
533static int __init m48t59_rtc_init(void) 533module_platform_driver(m48t59_rtc_driver);
534{
535 return platform_driver_register(&m48t59_rtc_driver);
536}
537
538static void __exit m48t59_rtc_exit(void)
539{
540 platform_driver_unregister(&m48t59_rtc_driver);
541}
542
543module_init(m48t59_rtc_init);
544module_exit(m48t59_rtc_exit);
545 534
546MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>"); 535MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>");
547MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver"); 536MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver");
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index f981287d582b..863fb3363aa6 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -185,21 +185,10 @@ static struct platform_driver m48t86_rtc_platform_driver = {
185 .remove = __devexit_p(m48t86_rtc_remove), 185 .remove = __devexit_p(m48t86_rtc_remove),
186}; 186};
187 187
188static int __init m48t86_rtc_init(void) 188module_platform_driver(m48t86_rtc_platform_driver);
189{
190 return platform_driver_register(&m48t86_rtc_platform_driver);
191}
192
193static void __exit m48t86_rtc_exit(void)
194{
195 platform_driver_unregister(&m48t86_rtc_platform_driver);
196}
197 189
198MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); 190MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
199MODULE_DESCRIPTION("M48T86 RTC driver"); 191MODULE_DESCRIPTION("M48T86 RTC driver");
200MODULE_LICENSE("GPL"); 192MODULE_LICENSE("GPL");
201MODULE_VERSION(DRV_VERSION); 193MODULE_VERSION(DRV_VERSION);
202MODULE_ALIAS("platform:rtc-m48t86"); 194MODULE_ALIAS("platform:rtc-m48t86");
203
204module_init(m48t86_rtc_init);
205module_exit(m48t86_rtc_exit);
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 0ec3f588a255..1f6b3cc58e8a 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -154,7 +154,6 @@ static int __devexit max6902_remove(struct spi_device *spi)
154static struct spi_driver max6902_driver = { 154static struct spi_driver max6902_driver = {
155 .driver = { 155 .driver = {
156 .name = "rtc-max6902", 156 .name = "rtc-max6902",
157 .bus = &spi_bus_type,
158 .owner = THIS_MODULE, 157 .owner = THIS_MODULE,
159 }, 158 },
160 .probe = max6902_probe, 159 .probe = max6902_probe,
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
index 3bc046f427e0..4a5529346b47 100644
--- a/drivers/rtc/rtc-max8925.c
+++ b/drivers/rtc/rtc-max8925.c
@@ -299,17 +299,7 @@ static struct platform_driver max8925_rtc_driver = {
299 .remove = __devexit_p(max8925_rtc_remove), 299 .remove = __devexit_p(max8925_rtc_remove),
300}; 300};
301 301
302static int __init max8925_rtc_init(void) 302module_platform_driver(max8925_rtc_driver);
303{
304 return platform_driver_register(&max8925_rtc_driver);
305}
306module_init(max8925_rtc_init);
307
308static void __exit max8925_rtc_exit(void)
309{
310 platform_driver_unregister(&max8925_rtc_driver);
311}
312module_exit(max8925_rtc_exit);
313 303
314MODULE_DESCRIPTION("Maxim MAX8925 RTC driver"); 304MODULE_DESCRIPTION("Maxim MAX8925 RTC driver");
315MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 305MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c
index 2e48aa604273..7196f438c089 100644
--- a/drivers/rtc/rtc-max8998.c
+++ b/drivers/rtc/rtc-max8998.c
@@ -327,17 +327,7 @@ static struct platform_driver max8998_rtc_driver = {
327 .id_table = max8998_rtc_id, 327 .id_table = max8998_rtc_id,
328}; 328};
329 329
330static int __init max8998_rtc_init(void) 330module_platform_driver(max8998_rtc_driver);
331{
332 return platform_driver_register(&max8998_rtc_driver);
333}
334module_init(max8998_rtc_init);
335
336static void __exit max8998_rtc_exit(void)
337{
338 platform_driver_unregister(&max8998_rtc_driver);
339}
340module_exit(max8998_rtc_exit);
341 331
342MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); 332MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
343MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 333MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 9d0c3b478d55..546f6850bffb 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -399,7 +399,7 @@ static int __exit mc13xxx_rtc_remove(struct platform_device *pdev)
399 return 0; 399 return 0;
400} 400}
401 401
402const struct platform_device_id mc13xxx_rtc_idtable[] = { 402static const struct platform_device_id mc13xxx_rtc_idtable[] = {
403 { 403 {
404 .name = "mc13783-rtc", 404 .name = "mc13783-rtc",
405 }, { 405 }, {
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index da60915818b6..9d3caccfc250 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -418,17 +418,7 @@ static struct platform_driver mpc5121_rtc_driver = {
418 .remove = __devexit_p(mpc5121_rtc_remove), 418 .remove = __devexit_p(mpc5121_rtc_remove),
419}; 419};
420 420
421static int __init mpc5121_rtc_init(void) 421module_platform_driver(mpc5121_rtc_driver);
422{
423 return platform_driver_register(&mpc5121_rtc_driver);
424}
425module_init(mpc5121_rtc_init);
426
427static void __exit mpc5121_rtc_exit(void)
428{
429 platform_driver_unregister(&mpc5121_rtc_driver);
430}
431module_exit(mpc5121_rtc_exit);
432 422
433MODULE_LICENSE("GPL"); 423MODULE_LICENSE("GPL");
434MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>"); 424MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>");
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index bb21f443fb70..6cd6c7235344 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -537,18 +537,7 @@ static struct platform_driver vrtc_mrst_platform_driver = {
537 } 537 }
538}; 538};
539 539
540static int __init vrtc_mrst_init(void) 540module_platform_driver(vrtc_mrst_platform_driver);
541{
542 return platform_driver_register(&vrtc_mrst_platform_driver);
543}
544
545static void __exit vrtc_mrst_exit(void)
546{
547 platform_driver_unregister(&vrtc_mrst_platform_driver);
548}
549
550module_init(vrtc_mrst_init);
551module_exit(vrtc_mrst_exit);
552 541
553MODULE_AUTHOR("Jacob Pan; Feng Tang"); 542MODULE_AUTHOR("Jacob Pan; Feng Tang");
554MODULE_DESCRIPTION("Driver for Moorestown virtual RTC"); 543MODULE_DESCRIPTION("Driver for Moorestown virtual RTC");
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 39e41fbdf08b..5e1d64ee5228 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -155,7 +155,6 @@ static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
155{ 155{
156 struct rtc_time alarm_tm, now_tm; 156 struct rtc_time alarm_tm, now_tm;
157 unsigned long now, time; 157 unsigned long now, time;
158 int ret;
159 struct platform_device *pdev = to_platform_device(dev); 158 struct platform_device *pdev = to_platform_device(dev);
160 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 159 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
161 void __iomem *ioaddr = pdata->ioaddr; 160 void __iomem *ioaddr = pdata->ioaddr;
@@ -168,21 +167,33 @@ static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
168 alarm_tm.tm_hour = alrm->tm_hour; 167 alarm_tm.tm_hour = alrm->tm_hour;
169 alarm_tm.tm_min = alrm->tm_min; 168 alarm_tm.tm_min = alrm->tm_min;
170 alarm_tm.tm_sec = alrm->tm_sec; 169 alarm_tm.tm_sec = alrm->tm_sec;
171 rtc_tm_to_time(&now_tm, &now);
172 rtc_tm_to_time(&alarm_tm, &time); 170 rtc_tm_to_time(&alarm_tm, &time);
173 171
174 if (time < now) {
175 time += 60 * 60 * 24;
176 rtc_time_to_tm(time, &alarm_tm);
177 }
178
179 ret = rtc_tm_to_time(&alarm_tm, &time);
180
181 /* clear all the interrupt status bits */ 172 /* clear all the interrupt status bits */
182 writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR); 173 writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR);
183 set_alarm_or_time(dev, MXC_RTC_ALARM, time); 174 set_alarm_or_time(dev, MXC_RTC_ALARM, time);
184 175
185 return ret; 176 return 0;
177}
178
179static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
180 unsigned int enabled)
181{
182 struct platform_device *pdev = to_platform_device(dev);
183 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
184 void __iomem *ioaddr = pdata->ioaddr;
185 u32 reg;
186
187 spin_lock_irq(&pdata->rtc->irq_lock);
188 reg = readw(ioaddr + RTC_RTCIENR);
189
190 if (enabled)
191 reg |= bit;
192 else
193 reg &= ~bit;
194
195 writew(reg, ioaddr + RTC_RTCIENR);
196 spin_unlock_irq(&pdata->rtc->irq_lock);
186} 197}
187 198
188/* This function is the RTC interrupt service routine. */ 199/* This function is the RTC interrupt service routine. */
@@ -199,13 +210,12 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
199 /* clear interrupt sources */ 210 /* clear interrupt sources */
200 writew(status, ioaddr + RTC_RTCISR); 211 writew(status, ioaddr + RTC_RTCISR);
201 212
202 /* clear alarm interrupt if it has occurred */
203 if (status & RTC_ALM_BIT)
204 status &= ~RTC_ALM_BIT;
205
206 /* update irq data & counter */ 213 /* update irq data & counter */
207 if (status & RTC_ALM_BIT) 214 if (status & RTC_ALM_BIT) {
208 events |= (RTC_AF | RTC_IRQF); 215 events |= (RTC_AF | RTC_IRQF);
216 /* RTC alarm should be one-shot */
217 mxc_rtc_irq_enable(&pdev->dev, RTC_ALM_BIT, 0);
218 }
209 219
210 if (status & RTC_1HZ_BIT) 220 if (status & RTC_1HZ_BIT)
211 events |= (RTC_UF | RTC_IRQF); 221 events |= (RTC_UF | RTC_IRQF);
@@ -213,9 +223,6 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
213 if (status & PIT_ALL_ON) 223 if (status & PIT_ALL_ON)
214 events |= (RTC_PF | RTC_IRQF); 224 events |= (RTC_PF | RTC_IRQF);
215 225
216 if ((status & RTC_ALM_BIT) && rtc_valid_tm(&pdata->g_rtc_alarm))
217 rtc_update_alarm(&pdev->dev, &pdata->g_rtc_alarm);
218
219 rtc_update_irq(pdata->rtc, 1, events); 226 rtc_update_irq(pdata->rtc, 1, events);
220 spin_unlock_irq(&pdata->rtc->irq_lock); 227 spin_unlock_irq(&pdata->rtc->irq_lock);
221 228
@@ -242,26 +249,6 @@ static void mxc_rtc_release(struct device *dev)
242 spin_unlock_irq(&pdata->rtc->irq_lock); 249 spin_unlock_irq(&pdata->rtc->irq_lock);
243} 250}
244 251
245static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
246 unsigned int enabled)
247{
248 struct platform_device *pdev = to_platform_device(dev);
249 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
250 void __iomem *ioaddr = pdata->ioaddr;
251 u32 reg;
252
253 spin_lock_irq(&pdata->rtc->irq_lock);
254 reg = readw(ioaddr + RTC_RTCIENR);
255
256 if (enabled)
257 reg |= bit;
258 else
259 reg &= ~bit;
260
261 writew(reg, ioaddr + RTC_RTCIENR);
262 spin_unlock_irq(&pdata->rtc->irq_lock);
263}
264
265static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 252static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
266{ 253{
267 mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled); 254 mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled);
@@ -290,6 +277,17 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
290 */ 277 */
291static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) 278static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
292{ 279{
280 /*
281 * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only
282 */
283 if (cpu_is_mx1()) {
284 struct rtc_time tm;
285
286 rtc_time_to_tm(time, &tm);
287 tm.tm_year = 70;
288 rtc_tm_to_time(&tm, &time);
289 }
290
293 /* Avoid roll-over from reading the different registers */ 291 /* Avoid roll-over from reading the different registers */
294 do { 292 do {
295 set_alarm_or_time(dev, MXC_RTC_TIME, time); 293 set_alarm_or_time(dev, MXC_RTC_TIME, time);
@@ -324,21 +322,7 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
324 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 322 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
325 int ret; 323 int ret;
326 324
327 if (rtc_valid_tm(&alrm->time)) { 325 ret = rtc_update_alarm(dev, &alrm->time);
328 if (alrm->time.tm_sec > 59 ||
329 alrm->time.tm_hour > 23 ||
330 alrm->time.tm_min > 59)
331 return -EINVAL;
332
333 ret = rtc_update_alarm(dev, &alrm->time);
334 } else {
335 ret = rtc_valid_tm(&alrm->time);
336 if (ret)
337 return ret;
338
339 ret = rtc_update_alarm(dev, &alrm->time);
340 }
341
342 if (ret) 326 if (ret)
343 return ret; 327 return ret;
344 328
@@ -424,6 +408,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
424 pdata->irq = -1; 408 pdata->irq = -1;
425 } 409 }
426 410
411 if (pdata->irq >=0)
412 device_init_wakeup(&pdev->dev, 1);
413
427 rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, 414 rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops,
428 THIS_MODULE); 415 THIS_MODULE);
429 if (IS_ERR(rtc)) { 416 if (IS_ERR(rtc)) {
@@ -459,9 +446,39 @@ static int __exit mxc_rtc_remove(struct platform_device *pdev)
459 return 0; 446 return 0;
460} 447}
461 448
449#ifdef CONFIG_PM
450static int mxc_rtc_suspend(struct device *dev)
451{
452 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
453
454 if (device_may_wakeup(dev))
455 enable_irq_wake(pdata->irq);
456
457 return 0;
458}
459
460static int mxc_rtc_resume(struct device *dev)
461{
462 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
463
464 if (device_may_wakeup(dev))
465 disable_irq_wake(pdata->irq);
466
467 return 0;
468}
469
470static struct dev_pm_ops mxc_rtc_pm_ops = {
471 .suspend = mxc_rtc_suspend,
472 .resume = mxc_rtc_resume,
473};
474#endif
475
462static struct platform_driver mxc_rtc_driver = { 476static struct platform_driver mxc_rtc_driver = {
463 .driver = { 477 .driver = {
464 .name = "mxc_rtc", 478 .name = "mxc_rtc",
479#ifdef CONFIG_PM
480 .pm = &mxc_rtc_pm_ops,
481#endif
465 .owner = THIS_MODULE, 482 .owner = THIS_MODULE,
466 }, 483 },
467 .remove = __exit_p(mxc_rtc_remove), 484 .remove = __exit_p(mxc_rtc_remove),
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index 2ee3bbf7e5ea..b46c4004d8fe 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -340,7 +340,6 @@ static int __devexit pcf2123_remove(struct spi_device *spi)
340static struct spi_driver pcf2123_driver = { 340static struct spi_driver pcf2123_driver = {
341 .driver = { 341 .driver = {
342 .name = "rtc-pcf2123", 342 .name = "rtc-pcf2123",
343 .bus = &spi_bus_type,
344 .owner = THIS_MODULE, 343 .owner = THIS_MODULE,
345 }, 344 },
346 .probe = pcf2123_probe, 345 .probe = pcf2123_probe,
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index 0c423892923c..a20202f9ee57 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -294,17 +294,7 @@ static struct platform_driver pcf50633_rtc_driver = {
294 .remove = __devexit_p(pcf50633_rtc_remove), 294 .remove = __devexit_p(pcf50633_rtc_remove),
295}; 295};
296 296
297static int __init pcf50633_rtc_init(void) 297module_platform_driver(pcf50633_rtc_driver);
298{
299 return platform_driver_register(&pcf50633_rtc_driver);
300}
301module_init(pcf50633_rtc_init);
302
303static void __exit pcf50633_rtc_exit(void)
304{
305 platform_driver_unregister(&pcf50633_rtc_driver);
306}
307module_exit(pcf50633_rtc_exit);
308 298
309MODULE_DESCRIPTION("PCF50633 RTC driver"); 299MODULE_DESCRIPTION("PCF50633 RTC driver");
310MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); 300MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index d420e9d877e8..9f1d6bcbdf6c 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -532,17 +532,7 @@ static struct platform_driver pm8xxx_rtc_driver = {
532 }, 532 },
533}; 533};
534 534
535static int __init pm8xxx_rtc_init(void) 535module_platform_driver(pm8xxx_rtc_driver);
536{
537 return platform_driver_register(&pm8xxx_rtc_driver);
538}
539module_init(pm8xxx_rtc_init);
540
541static void __exit pm8xxx_rtc_exit(void)
542{
543 platform_driver_unregister(&pm8xxx_rtc_driver);
544}
545module_exit(pm8xxx_rtc_exit);
546 536
547MODULE_ALIAS("platform:rtc-pm8xxx"); 537MODULE_ALIAS("platform:rtc-pm8xxx");
548MODULE_DESCRIPTION("PMIC8xxx RTC driver"); 538MODULE_DESCRIPTION("PMIC8xxx RTC driver");
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index 971bc8e08da6..ce2ca8523ddd 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -229,7 +229,6 @@ static int __devexit rs5c348_remove(struct spi_device *spi)
229static struct spi_driver rs5c348_driver = { 229static struct spi_driver rs5c348_driver = {
230 .driver = { 230 .driver = {
231 .name = "rtc-rs5c348", 231 .name = "rtc-rs5c348",
232 .bus = &spi_bus_type,
233 .owner = THIS_MODULE, 232 .owner = THIS_MODULE,
234 }, 233 },
235 .probe = rs5c348_probe, 234 .probe = rs5c348_probe,
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 175067a17c46..aef40bd2957b 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -673,21 +673,7 @@ static struct platform_driver s3c_rtc_driver = {
673 }, 673 },
674}; 674};
675 675
676static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n"; 676module_platform_driver(s3c_rtc_driver);
677
678static int __init s3c_rtc_init(void)
679{
680 printk(banner);
681 return platform_driver_register(&s3c_rtc_driver);
682}
683
684static void __exit s3c_rtc_exit(void)
685{
686 platform_driver_unregister(&s3c_rtc_driver);
687}
688
689module_init(s3c_rtc_init);
690module_exit(s3c_rtc_exit);
691 677
692MODULE_DESCRIPTION("Samsung S3C RTC Driver"); 678MODULE_DESCRIPTION("Samsung S3C RTC Driver");
693MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 679MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index fc1ffe97fca1..4595d3e645a7 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -435,18 +435,7 @@ static struct platform_driver sa1100_rtc_driver = {
435 }, 435 },
436}; 436};
437 437
438static int __init sa1100_rtc_init(void) 438module_platform_driver(sa1100_rtc_driver);
439{
440 return platform_driver_register(&sa1100_rtc_driver);
441}
442
443static void __exit sa1100_rtc_exit(void)
444{
445 platform_driver_unregister(&sa1100_rtc_driver);
446}
447
448module_init(sa1100_rtc_init);
449module_exit(sa1100_rtc_exit);
450 439
451MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 440MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
452MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); 441MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index 893bac2bb21b..19a28a671a8e 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -516,17 +516,7 @@ static struct platform_driver spear_rtc_driver = {
516 }, 516 },
517}; 517};
518 518
519static int __init rtc_init(void) 519module_platform_driver(spear_rtc_driver);
520{
521 return platform_driver_register(&spear_rtc_driver);
522}
523module_init(rtc_init);
524
525static void __exit rtc_exit(void)
526{
527 platform_driver_unregister(&spear_rtc_driver);
528}
529module_exit(rtc_exit);
530 520
531MODULE_ALIAS("platform:rtc-spear"); 521MODULE_ALIAS("platform:rtc-spear");
532MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); 522MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index ed3e9b599031..7621116bd20d 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -370,18 +370,7 @@ static struct platform_driver stk17ta8_rtc_driver = {
370 }, 370 },
371}; 371};
372 372
373static __init int stk17ta8_init(void) 373module_platform_driver(stk17ta8_rtc_driver);
374{
375 return platform_driver_register(&stk17ta8_rtc_driver);
376}
377
378static __exit void stk17ta8_exit(void)
379{
380 platform_driver_unregister(&stk17ta8_rtc_driver);
381}
382
383module_init(stk17ta8_init);
384module_exit(stk17ta8_exit);
385 374
386MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>"); 375MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>");
387MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver"); 376MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver");
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c
index 7315068daa59..10287865e330 100644
--- a/drivers/rtc/rtc-stmp3xxx.c
+++ b/drivers/rtc/rtc-stmp3xxx.c
@@ -276,18 +276,7 @@ static struct platform_driver stmp3xxx_rtcdrv = {
276 }, 276 },
277}; 277};
278 278
279static int __init stmp3xxx_rtc_init(void) 279module_platform_driver(stmp3xxx_rtcdrv);
280{
281 return platform_driver_register(&stmp3xxx_rtcdrv);
282}
283
284static void __exit stmp3xxx_rtc_exit(void)
285{
286 platform_driver_unregister(&stmp3xxx_rtcdrv);
287}
288
289module_init(stmp3xxx_rtc_init);
290module_exit(stmp3xxx_rtc_exit);
291 280
292MODULE_DESCRIPTION("STMP3xxx RTC Driver"); 281MODULE_DESCRIPTION("STMP3xxx RTC Driver");
293MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " 282MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and "
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 20687d55e7a7..d43b4f6eb4e4 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -550,6 +550,11 @@ static int twl_rtc_resume(struct platform_device *pdev)
550#define twl_rtc_resume NULL 550#define twl_rtc_resume NULL
551#endif 551#endif
552 552
553static const struct of_device_id twl_rtc_of_match[] = {
554 {.compatible = "ti,twl4030-rtc", },
555 { },
556};
557MODULE_DEVICE_TABLE(of, twl_rtc_of_match);
553MODULE_ALIAS("platform:twl_rtc"); 558MODULE_ALIAS("platform:twl_rtc");
554 559
555static struct platform_driver twl4030rtc_driver = { 560static struct platform_driver twl4030rtc_driver = {
@@ -559,8 +564,9 @@ static struct platform_driver twl4030rtc_driver = {
559 .suspend = twl_rtc_suspend, 564 .suspend = twl_rtc_suspend,
560 .resume = twl_rtc_resume, 565 .resume = twl_rtc_resume,
561 .driver = { 566 .driver = {
562 .owner = THIS_MODULE, 567 .owner = THIS_MODULE,
563 .name = "twl_rtc", 568 .name = "twl_rtc",
569 .of_match_table = twl_rtc_of_match,
564 }, 570 },
565}; 571};
566 572
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index f71c3ce18036..bca5d677bc85 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -393,18 +393,7 @@ static struct platform_driver rtc_device_driver = {
393 }, 393 },
394}; 394};
395 395
396static __init int v3020_init(void) 396module_platform_driver(rtc_device_driver);
397{
398 return platform_driver_register(&rtc_device_driver);
399}
400
401static __exit void v3020_exit(void)
402{
403 platform_driver_unregister(&rtc_device_driver);
404}
405
406module_init(v3020_init);
407module_exit(v3020_exit);
408 397
409MODULE_DESCRIPTION("V3020 RTC"); 398MODULE_DESCRIPTION("V3020 RTC");
410MODULE_AUTHOR("Raphael Assenat"); 399MODULE_AUTHOR("Raphael Assenat");
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index c5698cda366a..fcbfdda2993b 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -405,15 +405,4 @@ static struct platform_driver rtc_platform_driver = {
405 }, 405 },
406}; 406};
407 407
408static int __init vr41xx_rtc_init(void) 408module_platform_driver(rtc_platform_driver);
409{
410 return platform_driver_register(&rtc_platform_driver);
411}
412
413static void __exit vr41xx_rtc_exit(void)
414{
415 platform_driver_unregister(&rtc_platform_driver);
416}
417
418module_init(vr41xx_rtc_init);
419module_exit(vr41xx_rtc_exit);
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index f93f412423c6..9e94fb147c26 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -311,17 +311,7 @@ static struct platform_driver vt8500_rtc_driver = {
311 }, 311 },
312}; 312};
313 313
314static int __init vt8500_rtc_init(void) 314module_platform_driver(vt8500_rtc_driver);
315{
316 return platform_driver_register(&vt8500_rtc_driver);
317}
318module_init(vt8500_rtc_init);
319
320static void __exit vt8500_rtc_exit(void)
321{
322 platform_driver_unregister(&vt8500_rtc_driver);
323}
324module_exit(vt8500_rtc_exit);
325 315
326MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); 316MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
327MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)"); 317MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)");
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index bdc909bd56da..3b6e6a67e765 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -324,15 +324,6 @@ static irqreturn_t wm831x_alm_irq(int irq, void *data)
324 return IRQ_HANDLED; 324 return IRQ_HANDLED;
325} 325}
326 326
327static irqreturn_t wm831x_per_irq(int irq, void *data)
328{
329 struct wm831x_rtc *wm831x_rtc = data;
330
331 rtc_update_irq(wm831x_rtc->rtc, 1, RTC_IRQF | RTC_UF);
332
333 return IRQ_HANDLED;
334}
335
336static const struct rtc_class_ops wm831x_rtc_ops = { 327static const struct rtc_class_ops wm831x_rtc_ops = {
337 .read_time = wm831x_rtc_readtime, 328 .read_time = wm831x_rtc_readtime,
338 .set_mmss = wm831x_rtc_set_mmss, 329 .set_mmss = wm831x_rtc_set_mmss,
@@ -405,11 +396,10 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
405{ 396{
406 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 397 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
407 struct wm831x_rtc *wm831x_rtc; 398 struct wm831x_rtc *wm831x_rtc;
408 int per_irq = platform_get_irq_byname(pdev, "PER");
409 int alm_irq = platform_get_irq_byname(pdev, "ALM"); 399 int alm_irq = platform_get_irq_byname(pdev, "ALM");
410 int ret = 0; 400 int ret = 0;
411 401
412 wm831x_rtc = kzalloc(sizeof(*wm831x_rtc), GFP_KERNEL); 402 wm831x_rtc = devm_kzalloc(&pdev->dev, sizeof(*wm831x_rtc), GFP_KERNEL);
413 if (wm831x_rtc == NULL) 403 if (wm831x_rtc == NULL)
414 return -ENOMEM; 404 return -ENOMEM;
415 405
@@ -433,14 +423,6 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
433 goto err; 423 goto err;
434 } 424 }
435 425
436 ret = request_threaded_irq(per_irq, NULL, wm831x_per_irq,
437 IRQF_TRIGGER_RISING, "RTC period",
438 wm831x_rtc);
439 if (ret != 0) {
440 dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n",
441 per_irq, ret);
442 }
443
444 ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, 426 ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq,
445 IRQF_TRIGGER_RISING, "RTC alarm", 427 IRQF_TRIGGER_RISING, "RTC alarm",
446 wm831x_rtc); 428 wm831x_rtc);
@@ -452,20 +434,16 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
452 return 0; 434 return 0;
453 435
454err: 436err:
455 kfree(wm831x_rtc);
456 return ret; 437 return ret;
457} 438}
458 439
459static int __devexit wm831x_rtc_remove(struct platform_device *pdev) 440static int __devexit wm831x_rtc_remove(struct platform_device *pdev)
460{ 441{
461 struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); 442 struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev);
462 int per_irq = platform_get_irq_byname(pdev, "PER");
463 int alm_irq = platform_get_irq_byname(pdev, "ALM"); 443 int alm_irq = platform_get_irq_byname(pdev, "ALM");
464 444
465 free_irq(alm_irq, wm831x_rtc); 445 free_irq(alm_irq, wm831x_rtc);
466 free_irq(per_irq, wm831x_rtc);
467 rtc_device_unregister(wm831x_rtc->rtc); 446 rtc_device_unregister(wm831x_rtc->rtc);
468 kfree(wm831x_rtc);
469 447
470 return 0; 448 return 0;
471} 449}
@@ -490,17 +468,7 @@ static struct platform_driver wm831x_rtc_driver = {
490 }, 468 },
491}; 469};
492 470
493static int __init wm831x_rtc_init(void) 471module_platform_driver(wm831x_rtc_driver);
494{
495 return platform_driver_register(&wm831x_rtc_driver);
496}
497module_init(wm831x_rtc_init);
498
499static void __exit wm831x_rtc_exit(void)
500{
501 platform_driver_unregister(&wm831x_rtc_driver);
502}
503module_exit(wm831x_rtc_exit);
504 472
505MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 473MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
506MODULE_DESCRIPTION("RTC driver for the WM831x series PMICs"); 474MODULE_DESCRIPTION("RTC driver for the WM831x series PMICs");
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 66421426e404..c2e52d15abb2 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -486,17 +486,7 @@ static struct platform_driver wm8350_rtc_driver = {
486 }, 486 },
487}; 487};
488 488
489static int __init wm8350_rtc_init(void) 489module_platform_driver(wm8350_rtc_driver);
490{
491 return platform_driver_register(&wm8350_rtc_driver);
492}
493module_init(wm8350_rtc_init);
494
495static void __exit wm8350_rtc_exit(void)
496{
497 platform_driver_unregister(&wm8350_rtc_driver);
498}
499module_exit(wm8350_rtc_exit);
500 490
501MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 491MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
502MODULE_DESCRIPTION("RTC driver for the WM8350"); 492MODULE_DESCRIPTION("RTC driver for the WM8350");
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index 1105fa1ed7f4..a1376dc73d71 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -270,17 +270,7 @@ static struct platform_driver pm860x_backlight_driver = {
270 .remove = pm860x_backlight_remove, 270 .remove = pm860x_backlight_remove,
271}; 271};
272 272
273static int __init pm860x_backlight_init(void) 273module_platform_driver(pm860x_backlight_driver);
274{
275 return platform_driver_register(&pm860x_backlight_driver);
276}
277module_init(pm860x_backlight_init);
278
279static void __exit pm860x_backlight_exit(void)
280{
281 platform_driver_unregister(&pm860x_backlight_driver);
282}
283module_exit(pm860x_backlight_exit);
284 274
285MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606"); 275MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
286MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 276MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 278aeaa92505..681b36929fe4 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -280,14 +280,6 @@ config BACKLIGHT_WM831X
280 If you have a backlight driven by the ISINK and DCDC of a 280 If you have a backlight driven by the ISINK and DCDC of a
281 WM831x PMIC say y to enable the backlight driver for it. 281 WM831x PMIC say y to enable the backlight driver for it.
282 282
283config BACKLIGHT_ADX
284 tristate "Avionic Design Xanthos Backlight Driver"
285 depends on ARCH_PXA_ADX
286 default y
287 help
288 Say Y to enable the backlight driver on Avionic Design Xanthos-based
289 boards.
290
291config BACKLIGHT_ADP5520 283config BACKLIGHT_ADP5520
292 tristate "Backlight Driver for ADP5520/ADP5501 using WLED" 284 tristate "Backlight Driver for ADP5520/ADP5501 using WLED"
293 depends on PMIC_ADP5520 285 depends on PMIC_ADP5520
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index fdd1fc4b2770..af5cf654ec7c 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -32,7 +32,6 @@ obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
32obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 32obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
33obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 33obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
34obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o 34obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
35obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
36obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o 35obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
37obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o 36obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
38obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o 37obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index dfb763e9147f..2e630bf1164c 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -384,17 +384,7 @@ static struct platform_driver adp5520_bl_driver = {
384 .resume = adp5520_bl_resume, 384 .resume = adp5520_bl_resume,
385}; 385};
386 386
387static int __init adp5520_bl_init(void) 387module_platform_driver(adp5520_bl_driver);
388{
389 return platform_driver_register(&adp5520_bl_driver);
390}
391module_init(adp5520_bl_init);
392
393static void __exit adp5520_bl_exit(void)
394{
395 platform_driver_unregister(&adp5520_bl_driver);
396}
397module_exit(adp5520_bl_exit);
398 388
399MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 389MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
400MODULE_DESCRIPTION("ADP5520(01) Backlight Driver"); 390MODULE_DESCRIPTION("ADP5520(01) Backlight Driver");
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
deleted file mode 100644
index c861c41af442..000000000000
--- a/drivers/video/backlight/adx_bl.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/*
2 * linux/drivers/video/backlight/adx.c
3 *
4 * Copyright (C) 2009 Avionic Design GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Written by Thierry Reding <thierry.reding@avionic-design.de>
11 */
12
13#include <linux/backlight.h>
14#include <linux/fb.h>
15#include <linux/gfp.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19
20/* register definitions */
21#define ADX_BACKLIGHT_CONTROL 0x00
22#define ADX_BACKLIGHT_CONTROL_ENABLE (1 << 0)
23#define ADX_BACKLIGHT_BRIGHTNESS 0x08
24#define ADX_BACKLIGHT_STATUS 0x10
25#define ADX_BACKLIGHT_ERROR 0x18
26
27struct adxbl {
28 void __iomem *base;
29};
30
31static int adx_backlight_update_status(struct backlight_device *bldev)
32{
33 struct adxbl *bl = bl_get_data(bldev);
34 u32 value;
35
36 value = bldev->props.brightness;
37 writel(value, bl->base + ADX_BACKLIGHT_BRIGHTNESS);
38
39 value = readl(bl->base + ADX_BACKLIGHT_CONTROL);
40
41 if (bldev->props.state & BL_CORE_FBBLANK)
42 value &= ~ADX_BACKLIGHT_CONTROL_ENABLE;
43 else
44 value |= ADX_BACKLIGHT_CONTROL_ENABLE;
45
46 writel(value, bl->base + ADX_BACKLIGHT_CONTROL);
47
48 return 0;
49}
50
51static int adx_backlight_get_brightness(struct backlight_device *bldev)
52{
53 struct adxbl *bl = bl_get_data(bldev);
54 u32 brightness;
55
56 brightness = readl(bl->base + ADX_BACKLIGHT_BRIGHTNESS);
57 return brightness & 0xff;
58}
59
60static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb)
61{
62 return 1;
63}
64
65static const struct backlight_ops adx_backlight_ops = {
66 .options = 0,
67 .update_status = adx_backlight_update_status,
68 .get_brightness = adx_backlight_get_brightness,
69 .check_fb = adx_backlight_check_fb,
70};
71
72static int __devinit adx_backlight_probe(struct platform_device *pdev)
73{
74 struct backlight_properties props;
75 struct backlight_device *bldev;
76 struct resource *res;
77 struct adxbl *bl;
78 int ret = 0;
79
80 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
81 if (!res) {
82 ret = -ENXIO;
83 goto out;
84 }
85
86 res = devm_request_mem_region(&pdev->dev, res->start,
87 resource_size(res), res->name);
88 if (!res) {
89 ret = -ENXIO;
90 goto out;
91 }
92
93 bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL);
94 if (!bl) {
95 ret = -ENOMEM;
96 goto out;
97 }
98
99 bl->base = devm_ioremap_nocache(&pdev->dev, res->start,
100 resource_size(res));
101 if (!bl->base) {
102 ret = -ENXIO;
103 goto out;
104 }
105
106 memset(&props, 0, sizeof(struct backlight_properties));
107 props.type = BACKLIGHT_RAW;
108 props.max_brightness = 0xff;
109 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
110 bl, &adx_backlight_ops, &props);
111 if (IS_ERR(bldev)) {
112 ret = PTR_ERR(bldev);
113 goto out;
114 }
115
116 bldev->props.brightness = 0xff;
117 bldev->props.power = FB_BLANK_UNBLANK;
118
119 platform_set_drvdata(pdev, bldev);
120
121out:
122 return ret;
123}
124
125static int __devexit adx_backlight_remove(struct platform_device *pdev)
126{
127 struct backlight_device *bldev;
128 int ret = 0;
129
130 bldev = platform_get_drvdata(pdev);
131 bldev->props.power = FB_BLANK_UNBLANK;
132 bldev->props.brightness = 0xff;
133 backlight_update_status(bldev);
134 backlight_device_unregister(bldev);
135 platform_set_drvdata(pdev, NULL);
136
137 return ret;
138}
139
140#ifdef CONFIG_PM
141static int adx_backlight_suspend(struct platform_device *pdev,
142 pm_message_t state)
143{
144 return 0;
145}
146
147static int adx_backlight_resume(struct platform_device *pdev)
148{
149 return 0;
150}
151#else
152#define adx_backlight_suspend NULL
153#define adx_backlight_resume NULL
154#endif
155
156static struct platform_driver adx_backlight_driver = {
157 .probe = adx_backlight_probe,
158 .remove = __devexit_p(adx_backlight_remove),
159 .suspend = adx_backlight_suspend,
160 .resume = adx_backlight_resume,
161 .driver = {
162 .name = "adx-backlight",
163 .owner = THIS_MODULE,
164 },
165};
166
167static int __init adx_backlight_init(void)
168{
169 return platform_driver_register(&adx_backlight_driver);
170}
171
172static void __exit adx_backlight_exit(void)
173{
174 platform_driver_unregister(&adx_backlight_driver);
175}
176
177module_init(adx_backlight_init);
178module_exit(adx_backlight_exit);
179
180MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
181MODULE_DESCRIPTION("Avionic Design Xanthos Backlight Driver");
182MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 7363c1b169e8..bf5b1ece7160 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -102,7 +102,7 @@ static void backlight_generate_event(struct backlight_device *bd,
102} 102}
103 103
104static ssize_t backlight_show_power(struct device *dev, 104static ssize_t backlight_show_power(struct device *dev,
105 struct device_attribute *attr,char *buf) 105 struct device_attribute *attr, char *buf)
106{ 106{
107 struct backlight_device *bd = to_backlight_device(dev); 107 struct backlight_device *bd = to_backlight_device(dev);
108 108
@@ -116,7 +116,7 @@ static ssize_t backlight_store_power(struct device *dev,
116 struct backlight_device *bd = to_backlight_device(dev); 116 struct backlight_device *bd = to_backlight_device(dev);
117 unsigned long power; 117 unsigned long power;
118 118
119 rc = strict_strtoul(buf, 0, &power); 119 rc = kstrtoul(buf, 0, &power);
120 if (rc) 120 if (rc)
121 return rc; 121 return rc;
122 122
@@ -150,7 +150,7 @@ static ssize_t backlight_store_brightness(struct device *dev,
150 struct backlight_device *bd = to_backlight_device(dev); 150 struct backlight_device *bd = to_backlight_device(dev);
151 unsigned long brightness; 151 unsigned long brightness;
152 152
153 rc = strict_strtoul(buf, 0, &brightness); 153 rc = kstrtoul(buf, 0, &brightness);
154 if (rc) 154 if (rc)
155 return rc; 155 return rc;
156 156
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index d68f14bbb687..abb4a06268f1 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -199,17 +199,7 @@ static struct platform_driver da903x_backlight_driver = {
199 .remove = da903x_backlight_remove, 199 .remove = da903x_backlight_remove,
200}; 200};
201 201
202static int __init da903x_backlight_init(void) 202module_platform_driver(da903x_backlight_driver);
203{
204 return platform_driver_register(&da903x_backlight_driver);
205}
206module_init(da903x_backlight_init);
207
208static void __exit da903x_backlight_exit(void)
209{
210 platform_driver_unregister(&da903x_backlight_driver);
211}
212module_exit(da903x_backlight_exit);
213 203
214MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034"); 204MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
215MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" 205MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index c74a6f4baa12..b62b8b9063b5 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/module.h>
17#include <linux/io.h> 16#include <linux/io.h>
18#include <linux/fb.h> 17#include <linux/fb.h>
19#include <linux/backlight.h> 18#include <linux/backlight.h>
@@ -144,17 +143,7 @@ static struct platform_driver ep93xxbl_driver = {
144 .resume = ep93xxbl_resume, 143 .resume = ep93xxbl_resume,
145}; 144};
146 145
147static int __init ep93xxbl_init(void) 146module_platform_driver(ep93xxbl_driver);
148{
149 return platform_driver_register(&ep93xxbl_driver);
150}
151module_init(ep93xxbl_init);
152
153static void __exit ep93xxbl_exit(void)
154{
155 platform_driver_unregister(&ep93xxbl_driver);
156}
157module_exit(ep93xxbl_exit);
158 147
159MODULE_DESCRIPTION("EP93xx Backlight Driver"); 148MODULE_DESCRIPTION("EP93xx Backlight Driver");
160MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); 149MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index adb191466d64..9ce6170c1860 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -132,18 +132,7 @@ static struct platform_driver genericbl_driver = {
132 }, 132 },
133}; 133};
134 134
135static int __init genericbl_init(void) 135module_platform_driver(genericbl_driver);
136{
137 return platform_driver_register(&genericbl_driver);
138}
139
140static void __exit genericbl_exit(void)
141{
142 platform_driver_unregister(&genericbl_driver);
143}
144
145module_init(genericbl_init);
146module_exit(genericbl_exit);
147 136
148MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 137MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
149MODULE_DESCRIPTION("Generic Backlight Driver"); 138MODULE_DESCRIPTION("Generic Backlight Driver");
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index de65d80159be..2f8af5d786ab 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -147,19 +147,8 @@ static struct platform_driver jornada_bl_driver = {
147 }, 147 },
148}; 148};
149 149
150static int __init jornada_bl_init(void) 150module_platform_driver(jornada_bl_driver);
151{
152 return platform_driver_register(&jornada_bl_driver);
153}
154
155static void __exit jornada_bl_exit(void)
156{
157 platform_driver_unregister(&jornada_bl_driver);
158}
159 151
160MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>"); 152MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");
161MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver"); 153MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");
162MODULE_LICENSE("GPL"); 154MODULE_LICENSE("GPL");
163
164module_init(jornada_bl_init);
165module_exit(jornada_bl_exit);
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
index d2ff658b4144..22d231a17e3c 100644
--- a/drivers/video/backlight/jornada720_lcd.c
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -135,19 +135,8 @@ static struct platform_driver jornada_lcd_driver = {
135 }, 135 },
136}; 136};
137 137
138static int __init jornada_lcd_init(void) 138module_platform_driver(jornada_lcd_driver);
139{
140 return platform_driver_register(&jornada_lcd_driver);
141}
142
143static void __exit jornada_lcd_exit(void)
144{
145 platform_driver_unregister(&jornada_lcd_driver);
146}
147 139
148MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); 140MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
149MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver"); 141MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
150MODULE_LICENSE("GPL"); 142MODULE_LICENSE("GPL");
151
152module_init(jornada_lcd_init);
153module_exit(jornada_lcd_exit);
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 71a11cadffc4..79c1b0d609a8 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -97,19 +97,16 @@ static ssize_t lcd_store_power(struct device *dev,
97 struct device_attribute *attr, const char *buf, size_t count) 97 struct device_attribute *attr, const char *buf, size_t count)
98{ 98{
99 int rc = -ENXIO; 99 int rc = -ENXIO;
100 char *endp;
101 struct lcd_device *ld = to_lcd_device(dev); 100 struct lcd_device *ld = to_lcd_device(dev);
102 int power = simple_strtoul(buf, &endp, 0); 101 unsigned long power;
103 size_t size = endp - buf;
104 102
105 if (isspace(*endp)) 103 rc = kstrtoul(buf, 0, &power);
106 size++; 104 if (rc)
107 if (size != count) 105 return rc;
108 return -EINVAL;
109 106
110 mutex_lock(&ld->ops_lock); 107 mutex_lock(&ld->ops_lock);
111 if (ld->ops && ld->ops->set_power) { 108 if (ld->ops && ld->ops->set_power) {
112 pr_debug("lcd: set power to %d\n", power); 109 pr_debug("lcd: set power to %lu\n", power);
113 ld->ops->set_power(ld, power); 110 ld->ops->set_power(ld, power);
114 rc = count; 111 rc = count;
115 } 112 }
@@ -136,19 +133,16 @@ static ssize_t lcd_store_contrast(struct device *dev,
136 struct device_attribute *attr, const char *buf, size_t count) 133 struct device_attribute *attr, const char *buf, size_t count)
137{ 134{
138 int rc = -ENXIO; 135 int rc = -ENXIO;
139 char *endp;
140 struct lcd_device *ld = to_lcd_device(dev); 136 struct lcd_device *ld = to_lcd_device(dev);
141 int contrast = simple_strtoul(buf, &endp, 0); 137 unsigned long contrast;
142 size_t size = endp - buf;
143 138
144 if (isspace(*endp)) 139 rc = kstrtoul(buf, 0, &contrast);
145 size++; 140 if (rc)
146 if (size != count) 141 return rc;
147 return -EINVAL;
148 142
149 mutex_lock(&ld->ops_lock); 143 mutex_lock(&ld->ops_lock);
150 if (ld->ops && ld->ops->set_contrast) { 144 if (ld->ops && ld->ops->set_contrast) {
151 pr_debug("lcd: set contrast to %d\n", contrast); 145 pr_debug("lcd: set contrast to %lu\n", contrast);
152 ld->ops->set_contrast(ld, contrast); 146 ld->ops->set_contrast(ld, contrast);
153 rc = count; 147 rc = count;
154 } 148 }
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index da9a5ce0ccb8..78dafc0c8fc5 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -31,6 +31,7 @@
31#include <linux/lcd.h> 31#include <linux/lcd.h>
32#include <linux/backlight.h> 32#include <linux/backlight.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/regulator/consumer.h>
34 35
35#include "ld9040_gamma.h" 36#include "ld9040_gamma.h"
36 37
@@ -53,8 +54,51 @@ struct ld9040 {
53 struct lcd_device *ld; 54 struct lcd_device *ld;
54 struct backlight_device *bd; 55 struct backlight_device *bd;
55 struct lcd_platform_data *lcd_pd; 56 struct lcd_platform_data *lcd_pd;
57
58 struct mutex lock;
59 bool enabled;
60};
61
62static struct regulator_bulk_data supplies[] = {
63 { .supply = "vdd3", },
64 { .supply = "vci", },
56}; 65};
57 66
67static void ld9040_regulator_enable(struct ld9040 *lcd)
68{
69 int ret = 0;
70 struct lcd_platform_data *pd = NULL;
71
72 pd = lcd->lcd_pd;
73 mutex_lock(&lcd->lock);
74 if (!lcd->enabled) {
75 ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
76 if (ret)
77 goto out;
78
79 lcd->enabled = true;
80 }
81 mdelay(pd->power_on_delay);
82out:
83 mutex_unlock(&lcd->lock);
84}
85
86static void ld9040_regulator_disable(struct ld9040 *lcd)
87{
88 int ret = 0;
89
90 mutex_lock(&lcd->lock);
91 if (lcd->enabled) {
92 ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
93 if (ret)
94 goto out;
95
96 lcd->enabled = false;
97 }
98out:
99 mutex_unlock(&lcd->lock);
100}
101
58static const unsigned short seq_swreset[] = { 102static const unsigned short seq_swreset[] = {
59 0x01, COMMAND_ONLY, 103 0x01, COMMAND_ONLY,
60 ENDDEF, 0x00 104 ENDDEF, 0x00
@@ -532,13 +576,8 @@ static int ld9040_power_on(struct ld9040 *lcd)
532 return -EFAULT; 576 return -EFAULT;
533 } 577 }
534 578
535 if (!pd->power_on) { 579 /* lcd power on */
536 dev_err(lcd->dev, "power_on is NULL.\n"); 580 ld9040_regulator_enable(lcd);
537 return -EFAULT;
538 } else {
539 pd->power_on(lcd->ld, 1);
540 mdelay(pd->power_on_delay);
541 }
542 581
543 if (!pd->reset) { 582 if (!pd->reset) {
544 dev_err(lcd->dev, "reset is NULL.\n"); 583 dev_err(lcd->dev, "reset is NULL.\n");
@@ -582,11 +621,8 @@ static int ld9040_power_off(struct ld9040 *lcd)
582 621
583 mdelay(pd->power_off_delay); 622 mdelay(pd->power_off_delay);
584 623
585 if (!pd->power_on) { 624 /* lcd power off */
586 dev_err(lcd->dev, "power_on is NULL.\n"); 625 ld9040_regulator_disable(lcd);
587 return -EFAULT;
588 } else
589 pd->power_on(lcd->ld, 0);
590 626
591 return 0; 627 return 0;
592} 628}
@@ -693,6 +729,14 @@ static int ld9040_probe(struct spi_device *spi)
693 goto out_free_lcd; 729 goto out_free_lcd;
694 } 730 }
695 731
732 mutex_init(&lcd->lock);
733
734 ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
735 if (ret) {
736 dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
737 goto out_free_lcd;
738 }
739
696 ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops); 740 ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
697 if (IS_ERR(ld)) { 741 if (IS_ERR(ld)) {
698 ret = PTR_ERR(ld); 742 ret = PTR_ERR(ld);
@@ -739,6 +783,8 @@ static int ld9040_probe(struct spi_device *spi)
739out_unregister_lcd: 783out_unregister_lcd:
740 lcd_device_unregister(lcd->ld); 784 lcd_device_unregister(lcd->ld);
741out_free_lcd: 785out_free_lcd:
786 regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
787
742 kfree(lcd); 788 kfree(lcd);
743 return ret; 789 return ret;
744} 790}
@@ -750,6 +796,7 @@ static int __devexit ld9040_remove(struct spi_device *spi)
750 ld9040_power(lcd, FB_BLANK_POWERDOWN); 796 ld9040_power(lcd, FB_BLANK_POWERDOWN);
751 backlight_device_unregister(lcd->bd); 797 backlight_device_unregister(lcd->bd);
752 lcd_device_unregister(lcd->ld); 798 lcd_device_unregister(lcd->ld);
799 regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
753 kfree(lcd); 800 kfree(lcd);
754 801
755 return 0; 802 return 0;
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index 7bbc802560ea..c915e3b53886 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -188,17 +188,7 @@ static struct platform_driver max8925_backlight_driver = {
188 .remove = __devexit_p(max8925_backlight_remove), 188 .remove = __devexit_p(max8925_backlight_remove),
189}; 189};
190 190
191static int __init max8925_backlight_init(void) 191module_platform_driver(max8925_backlight_driver);
192{
193 return platform_driver_register(&max8925_backlight_driver);
194}
195module_init(max8925_backlight_init);
196
197static void __exit max8925_backlight_exit(void)
198{
199 platform_driver_unregister(&max8925_backlight_driver);
200};
201module_exit(max8925_backlight_exit);
202 192
203MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925"); 193MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925");
204MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 194MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index 08d26a72394c..d8cde277ec83 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -195,18 +195,7 @@ static struct platform_driver omapbl_driver = {
195 }, 195 },
196}; 196};
197 197
198static int __init omapbl_init(void) 198module_platform_driver(omapbl_driver);
199{
200 return platform_driver_register(&omapbl_driver);
201}
202
203static void __exit omapbl_exit(void)
204{
205 platform_driver_unregister(&omapbl_driver);
206}
207
208module_init(omapbl_init);
209module_exit(omapbl_exit);
210 199
211MODULE_AUTHOR("Andrzej Zaborowski <balrog@zabor.org>"); 200MODULE_AUTHOR("Andrzej Zaborowski <balrog@zabor.org>");
212MODULE_DESCRIPTION("OMAP LCD Backlight driver"); 201MODULE_DESCRIPTION("OMAP LCD Backlight driver");
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index ef5628d60563..13e88b71daec 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -173,17 +173,7 @@ static struct platform_driver pcf50633_bl_driver = {
173 }, 173 },
174}; 174};
175 175
176static int __init pcf50633_bl_init(void) 176module_platform_driver(pcf50633_bl_driver);
177{
178 return platform_driver_register(&pcf50633_bl_driver);
179}
180module_init(pcf50633_bl_init);
181
182static void __exit pcf50633_bl_exit(void)
183{
184 platform_driver_unregister(&pcf50633_bl_driver);
185}
186module_exit(pcf50633_bl_exit);
187 177
188MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 178MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
189MODULE_DESCRIPTION("PCF50633 backlight driver"); 179MODULE_DESCRIPTION("PCF50633 backlight driver");
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index 302330acf628..f0bf491ed087 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -85,7 +85,8 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev)
85 return -EINVAL; 85 return -EINVAL;
86 } 86 }
87 87
88 plcd = kzalloc(sizeof(struct platform_lcd), GFP_KERNEL); 88 plcd = devm_kzalloc(&pdev->dev, sizeof(struct platform_lcd),
89 GFP_KERNEL);
89 if (!plcd) { 90 if (!plcd) {
90 dev_err(dev, "no memory for state\n"); 91 dev_err(dev, "no memory for state\n");
91 return -ENOMEM; 92 return -ENOMEM;
@@ -98,7 +99,7 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev)
98 if (IS_ERR(plcd->lcd)) { 99 if (IS_ERR(plcd->lcd)) {
99 dev_err(dev, "cannot register lcd device\n"); 100 dev_err(dev, "cannot register lcd device\n");
100 err = PTR_ERR(plcd->lcd); 101 err = PTR_ERR(plcd->lcd);
101 goto err_mem; 102 goto err;
102 } 103 }
103 104
104 platform_set_drvdata(pdev, plcd); 105 platform_set_drvdata(pdev, plcd);
@@ -106,8 +107,7 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev)
106 107
107 return 0; 108 return 0;
108 109
109 err_mem: 110 err:
110 kfree(plcd);
111 return err; 111 return err;
112} 112}
113 113
@@ -116,7 +116,6 @@ static int __devexit platform_lcd_remove(struct platform_device *pdev)
116 struct platform_lcd *plcd = platform_get_drvdata(pdev); 116 struct platform_lcd *plcd = platform_get_drvdata(pdev);
117 117
118 lcd_device_unregister(plcd->lcd); 118 lcd_device_unregister(plcd->lcd);
119 kfree(plcd);
120 119
121 return 0; 120 return 0;
122} 121}
@@ -157,18 +156,7 @@ static struct platform_driver platform_lcd_driver = {
157 .resume = platform_lcd_resume, 156 .resume = platform_lcd_resume,
158}; 157};
159 158
160static int __init platform_lcd_init(void) 159module_platform_driver(platform_lcd_driver);
161{
162 return platform_driver_register(&platform_lcd_driver);
163}
164
165static void __exit platform_lcd_cleanup(void)
166{
167 platform_driver_unregister(&platform_lcd_driver);
168}
169
170module_init(platform_lcd_init);
171module_exit(platform_lcd_cleanup);
172 160
173MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); 161MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
174MODULE_LICENSE("GPL v2"); 162MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 8b5b2a4124c7..7496d04e1d3c 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -169,10 +169,9 @@ static int pwm_backlight_remove(struct platform_device *pdev)
169} 169}
170 170
171#ifdef CONFIG_PM 171#ifdef CONFIG_PM
172static int pwm_backlight_suspend(struct platform_device *pdev, 172static int pwm_backlight_suspend(struct device *dev)
173 pm_message_t state)
174{ 173{
175 struct backlight_device *bl = platform_get_drvdata(pdev); 174 struct backlight_device *bl = dev_get_drvdata(dev);
176 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 175 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
177 176
178 if (pb->notify) 177 if (pb->notify)
@@ -184,40 +183,32 @@ static int pwm_backlight_suspend(struct platform_device *pdev,
184 return 0; 183 return 0;
185} 184}
186 185
187static int pwm_backlight_resume(struct platform_device *pdev) 186static int pwm_backlight_resume(struct device *dev)
188{ 187{
189 struct backlight_device *bl = platform_get_drvdata(pdev); 188 struct backlight_device *bl = dev_get_drvdata(dev);
190 189
191 backlight_update_status(bl); 190 backlight_update_status(bl);
192 return 0; 191 return 0;
193} 192}
194#else 193
195#define pwm_backlight_suspend NULL 194static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend,
196#define pwm_backlight_resume NULL 195 pwm_backlight_resume);
196
197#endif 197#endif
198 198
199static struct platform_driver pwm_backlight_driver = { 199static struct platform_driver pwm_backlight_driver = {
200 .driver = { 200 .driver = {
201 .name = "pwm-backlight", 201 .name = "pwm-backlight",
202 .owner = THIS_MODULE, 202 .owner = THIS_MODULE,
203#ifdef CONFIG_PM
204 .pm = &pwm_backlight_pm_ops,
205#endif
203 }, 206 },
204 .probe = pwm_backlight_probe, 207 .probe = pwm_backlight_probe,
205 .remove = pwm_backlight_remove, 208 .remove = pwm_backlight_remove,
206 .suspend = pwm_backlight_suspend,
207 .resume = pwm_backlight_resume,
208}; 209};
209 210
210static int __init pwm_backlight_init(void) 211module_platform_driver(pwm_backlight_driver);
211{
212 return platform_driver_register(&pwm_backlight_driver);
213}
214module_init(pwm_backlight_init);
215
216static void __exit pwm_backlight_exit(void)
217{
218 platform_driver_unregister(&pwm_backlight_driver);
219}
220module_exit(pwm_backlight_exit);
221 212
222MODULE_DESCRIPTION("PWM based Backlight Driver"); 213MODULE_DESCRIPTION("PWM based Backlight Driver");
223MODULE_LICENSE("GPL"); 214MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index fbe9e9316f3b..4e915f5eca99 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -236,17 +236,7 @@ static struct platform_driver wm831x_backlight_driver = {
236 .remove = wm831x_backlight_remove, 236 .remove = wm831x_backlight_remove,
237}; 237};
238 238
239static int __init wm831x_backlight_init(void) 239module_platform_driver(wm831x_backlight_driver);
240{
241 return platform_driver_register(&wm831x_backlight_driver);
242}
243module_init(wm831x_backlight_init);
244
245static void __exit wm831x_backlight_exit(void)
246{
247 platform_driver_unregister(&wm831x_backlight_driver);
248}
249module_exit(wm831x_backlight_exit);
250 240
251MODULE_DESCRIPTION("Backlight Driver for WM831x PMICs"); 241MODULE_DESCRIPTION("Backlight Driver for WM831x PMICs");
252MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com"); 242MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com");