diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2014-02-27 08:29:22 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-02-27 08:56:19 -0500 |
commit | e4ecf2bda239ddef5f4edd0e05d48bfdf88a475d (patch) | |
tree | cda31855444c116394cec653eef7ffbc833823b9 | |
parent | d1cb3ecf327066137fb6245b13030cde60241dd6 (diff) |
ARM: plat-versatile: convert LEDs to platform device
The LEDs were initialized unconditionally with an fs_initcall()
which doesn't play well with multiplatform. Convert the driver
to a platform device and convert all boards with these LEDs
to register a platform device and pass the register as a
resource instead.
Tested successfully on the Versatile/AB and RealView PB1176.
Cc: Bryan Wu <cooloney@gmail.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | arch/arm/mach-realview/core.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-realview/core.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/realview_eb.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/realview_pb1176.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/realview_pb11mp.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/realview_pba8.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/realview_pbx.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-versatile/core.c | 16 | ||||
-rw-r--r-- | arch/arm/plat-versatile/leds.c | 49 |
9 files changed, 65 insertions, 21 deletions
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 1d5ee5c9a1dc..960b8dd78c44 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -148,6 +148,21 @@ struct platform_device realview_cf_device = { | |||
148 | }, | 148 | }, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static struct resource realview_leds_resources[] = { | ||
152 | { | ||
153 | .start = REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET, | ||
154 | .end = REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET + 4, | ||
155 | .flags = IORESOURCE_MEM, | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | struct platform_device realview_leds_device = { | ||
160 | .name = "versatile-leds", | ||
161 | .id = -1, | ||
162 | .num_resources = ARRAY_SIZE(realview_leds_resources), | ||
163 | .resource = realview_leds_resources, | ||
164 | }; | ||
165 | |||
151 | static struct resource realview_i2c_resource = { | 166 | static struct resource realview_i2c_resource = { |
152 | .start = REALVIEW_I2C_BASE, | 167 | .start = REALVIEW_I2C_BASE, |
153 | .end = REALVIEW_I2C_BASE + SZ_4K - 1, | 168 | .end = REALVIEW_I2C_BASE + SZ_4K - 1, |
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 602ca5ec52c5..13dc830ef469 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h | |||
@@ -37,6 +37,7 @@ struct machine_desc; | |||
37 | 37 | ||
38 | extern struct platform_device realview_flash_device; | 38 | extern struct platform_device realview_flash_device; |
39 | extern struct platform_device realview_cf_device; | 39 | extern struct platform_device realview_cf_device; |
40 | extern struct platform_device realview_leds_device; | ||
40 | extern struct platform_device realview_i2c_device; | 41 | extern struct platform_device realview_i2c_device; |
41 | extern struct mmci_platform_data realview_mmc0_plat_data; | 42 | extern struct mmci_platform_data realview_mmc0_plat_data; |
42 | extern struct mmci_platform_data realview_mmc1_plat_data; | 43 | extern struct mmci_platform_data realview_mmc1_plat_data; |
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index c85ddb2a0ad0..6bb070e80128 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
@@ -452,6 +452,7 @@ static void __init realview_eb_init(void) | |||
452 | realview_flash_register(&realview_eb_flash_resource, 1); | 452 | realview_flash_register(&realview_eb_flash_resource, 1); |
453 | platform_device_register(&realview_i2c_device); | 453 | platform_device_register(&realview_i2c_device); |
454 | platform_device_register(&char_lcd_device); | 454 | platform_device_register(&char_lcd_device); |
455 | platform_device_register(&realview_leds_device); | ||
455 | eth_device_register(); | 456 | eth_device_register(); |
456 | realview_usb_register(realview_eb_isp1761_resources); | 457 | realview_usb_register(realview_eb_isp1761_resources); |
457 | 458 | ||
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index c5eade76461b..173f2c15de49 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c | |||
@@ -367,6 +367,7 @@ static void __init realview_pb1176_init(void) | |||
367 | realview_usb_register(realview_pb1176_isp1761_resources); | 367 | realview_usb_register(realview_pb1176_isp1761_resources); |
368 | platform_device_register(&pmu_device); | 368 | platform_device_register(&pmu_device); |
369 | platform_device_register(&char_lcd_device); | 369 | platform_device_register(&char_lcd_device); |
370 | platform_device_register(&realview_leds_device); | ||
370 | 371 | ||
371 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 372 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { |
372 | struct amba_device *d = amba_devs[i]; | 373 | struct amba_device *d = amba_devs[i]; |
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index f4b0962578fe..bde7e6b1fd44 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c | |||
@@ -347,6 +347,7 @@ static void __init realview_pb11mp_init(void) | |||
347 | realview_eth_register(NULL, realview_pb11mp_smsc911x_resources); | 347 | realview_eth_register(NULL, realview_pb11mp_smsc911x_resources); |
348 | platform_device_register(&realview_i2c_device); | 348 | platform_device_register(&realview_i2c_device); |
349 | platform_device_register(&realview_cf_device); | 349 | platform_device_register(&realview_cf_device); |
350 | platform_device_register(&realview_leds_device); | ||
350 | realview_usb_register(realview_pb11mp_isp1761_resources); | 351 | realview_usb_register(realview_pb11mp_isp1761_resources); |
351 | platform_device_register(&pmu_device); | 352 | platform_device_register(&pmu_device); |
352 | 353 | ||
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 10a3e1d76891..4e57a8599265 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c | |||
@@ -289,6 +289,7 @@ static void __init realview_pba8_init(void) | |||
289 | realview_eth_register(NULL, realview_pba8_smsc911x_resources); | 289 | realview_eth_register(NULL, realview_pba8_smsc911x_resources); |
290 | platform_device_register(&realview_i2c_device); | 290 | platform_device_register(&realview_i2c_device); |
291 | platform_device_register(&realview_cf_device); | 291 | platform_device_register(&realview_cf_device); |
292 | platform_device_register(&realview_leds_device); | ||
292 | realview_usb_register(realview_pba8_isp1761_resources); | 293 | realview_usb_register(realview_pba8_isp1761_resources); |
293 | platform_device_register(&pmu_device); | 294 | platform_device_register(&pmu_device); |
294 | 295 | ||
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index 9d75493e3f0c..72c96caebefa 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c | |||
@@ -385,6 +385,7 @@ static void __init realview_pbx_init(void) | |||
385 | realview_eth_register(NULL, realview_pbx_smsc911x_resources); | 385 | realview_eth_register(NULL, realview_pbx_smsc911x_resources); |
386 | platform_device_register(&realview_i2c_device); | 386 | platform_device_register(&realview_i2c_device); |
387 | platform_device_register(&realview_cf_device); | 387 | platform_device_register(&realview_cf_device); |
388 | platform_device_register(&realview_leds_device); | ||
388 | realview_usb_register(realview_pbx_isp1761_resources); | 389 | realview_usb_register(realview_pbx_isp1761_resources); |
389 | 390 | ||
390 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 391 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { |
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index a335126ae18f..b31878570a00 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -310,6 +310,21 @@ static struct platform_device char_lcd_device = { | |||
310 | .resource = char_lcd_resources, | 310 | .resource = char_lcd_resources, |
311 | }; | 311 | }; |
312 | 312 | ||
313 | static struct resource leds_resources[] = { | ||
314 | { | ||
315 | .start = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET, | ||
316 | .end = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET + 4, | ||
317 | .flags = IORESOURCE_MEM, | ||
318 | }, | ||
319 | }; | ||
320 | |||
321 | static struct platform_device leds_device = { | ||
322 | .name = "versatile-leds", | ||
323 | .id = -1, | ||
324 | .num_resources = ARRAY_SIZE(leds_resources), | ||
325 | .resource = leds_resources, | ||
326 | }; | ||
327 | |||
313 | /* | 328 | /* |
314 | * Clock handling | 329 | * Clock handling |
315 | */ | 330 | */ |
@@ -795,6 +810,7 @@ void __init versatile_init(void) | |||
795 | platform_device_register(&versatile_i2c_device); | 810 | platform_device_register(&versatile_i2c_device); |
796 | platform_device_register(&smc91x_device); | 811 | platform_device_register(&smc91x_device); |
797 | platform_device_register(&char_lcd_device); | 812 | platform_device_register(&char_lcd_device); |
813 | platform_device_register(&leds_device); | ||
798 | 814 | ||
799 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 815 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { |
800 | struct amba_device *d = amba_devs[i]; | 816 | struct amba_device *d = amba_devs[i]; |
diff --git a/arch/arm/plat-versatile/leds.c b/arch/arm/plat-versatile/leds.c index 2018f307f32e..80553022d661 100644 --- a/arch/arm/plat-versatile/leds.c +++ b/arch/arm/plat-versatile/leds.c | |||
@@ -7,22 +7,14 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/module.h> | ||
10 | #include <linux/io.h> | 11 | #include <linux/io.h> |
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
12 | #include <linux/leds.h> | 13 | #include <linux/leds.h> |
13 | 14 | #include <linux/platform_device.h> | |
14 | #include <mach/hardware.h> | ||
15 | #include <mach/platform.h> | ||
16 | |||
17 | #ifdef VERSATILE_SYS_BASE | ||
18 | #define LEDREG (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) | ||
19 | #endif | ||
20 | |||
21 | #ifdef REALVIEW_SYS_BASE | ||
22 | #define LEDREG (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET) | ||
23 | #endif | ||
24 | 15 | ||
25 | struct versatile_led { | 16 | struct versatile_led { |
17 | void __iomem *base; | ||
26 | struct led_classdev cdev; | 18 | struct led_classdev cdev; |
27 | u8 mask; | 19 | u8 mask; |
28 | }; | 20 | }; |
@@ -50,30 +42,37 @@ static void versatile_led_set(struct led_classdev *cdev, | |||
50 | { | 42 | { |
51 | struct versatile_led *led = container_of(cdev, | 43 | struct versatile_led *led = container_of(cdev, |
52 | struct versatile_led, cdev); | 44 | struct versatile_led, cdev); |
53 | u32 reg = readl(LEDREG); | 45 | u32 reg = readl(led->base); |
54 | 46 | ||
55 | if (b != LED_OFF) | 47 | if (b != LED_OFF) |
56 | reg |= led->mask; | 48 | reg |= led->mask; |
57 | else | 49 | else |
58 | reg &= ~led->mask; | 50 | reg &= ~led->mask; |
59 | writel(reg, LEDREG); | 51 | writel(reg, led->base); |
60 | } | 52 | } |
61 | 53 | ||
62 | static enum led_brightness versatile_led_get(struct led_classdev *cdev) | 54 | static enum led_brightness versatile_led_get(struct led_classdev *cdev) |
63 | { | 55 | { |
64 | struct versatile_led *led = container_of(cdev, | 56 | struct versatile_led *led = container_of(cdev, |
65 | struct versatile_led, cdev); | 57 | struct versatile_led, cdev); |
66 | u32 reg = readl(LEDREG); | 58 | u32 reg = readl(led->base); |
67 | 59 | ||
68 | return (reg & led->mask) ? LED_FULL : LED_OFF; | 60 | return (reg & led->mask) ? LED_FULL : LED_OFF; |
69 | } | 61 | } |
70 | 62 | ||
71 | static int __init versatile_leds_init(void) | 63 | static int versatile_leds_probe(struct platform_device *dev) |
72 | { | 64 | { |
73 | int i; | 65 | int i; |
66 | struct resource *res; | ||
67 | void __iomem *base; | ||
68 | |||
69 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
70 | base = devm_ioremap_resource(&dev->dev, res); | ||
71 | if (IS_ERR(base)) | ||
72 | return PTR_ERR(base); | ||
74 | 73 | ||
75 | /* All off */ | 74 | /* All off */ |
76 | writel(0, LEDREG); | 75 | writel(0, base); |
77 | for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { | 76 | for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { |
78 | struct versatile_led *led; | 77 | struct versatile_led *led; |
79 | 78 | ||
@@ -81,6 +80,7 @@ static int __init versatile_leds_init(void) | |||
81 | if (!led) | 80 | if (!led) |
82 | break; | 81 | break; |
83 | 82 | ||
83 | led->base = base; | ||
84 | led->cdev.name = versatile_leds[i].name; | 84 | led->cdev.name = versatile_leds[i].name; |
85 | led->cdev.brightness_set = versatile_led_set; | 85 | led->cdev.brightness_set = versatile_led_set; |
86 | led->cdev.brightness_get = versatile_led_get; | 86 | led->cdev.brightness_get = versatile_led_get; |
@@ -96,8 +96,15 @@ static int __init versatile_leds_init(void) | |||
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* | 99 | static struct platform_driver versatile_leds_driver = { |
100 | * Since we may have triggers on any subsystem, defer registration | 100 | .driver = { |
101 | * until after subsystem_init. | 101 | .name = "versatile-leds", |
102 | */ | 102 | }, |
103 | fs_initcall(versatile_leds_init); | 103 | .probe = versatile_leds_probe, |
104 | }; | ||
105 | |||
106 | module_platform_driver(versatile_leds_driver); | ||
107 | |||
108 | MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); | ||
109 | MODULE_DESCRIPTION("ARM Versatile LED driver"); | ||
110 | MODULE_LICENSE("GPL v2"); | ||