diff options
Diffstat (limited to 'drivers/mfd/vexpress-sysreg.c')
-rw-r--r-- | drivers/mfd/vexpress-sysreg.c | 83 |
1 files changed, 61 insertions, 22 deletions
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 77048b18439e..a4a43230abcd 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #define SYS_ID_HBI_SHIFT 16 | 49 | #define SYS_ID_HBI_SHIFT 16 |
50 | #define SYS_PROCIDx_HBI_SHIFT 0 | 50 | #define SYS_PROCIDx_HBI_SHIFT 0 |
51 | 51 | ||
52 | #define SYS_LED_LED(n) (1 << (n)) | ||
53 | |||
52 | #define SYS_MCI_CARDIN (1 << 0) | 54 | #define SYS_MCI_CARDIN (1 << 0) |
53 | #define SYS_MCI_WPROT (1 << 1) | 55 | #define SYS_MCI_WPROT (1 << 1) |
54 | 56 | ||
@@ -336,34 +338,40 @@ void __init vexpress_sysreg_early_init(void __iomem *base) | |||
336 | 338 | ||
337 | void __init vexpress_sysreg_of_early_init(void) | 339 | void __init vexpress_sysreg_of_early_init(void) |
338 | { | 340 | { |
339 | struct device_node *node = of_find_compatible_node(NULL, NULL, | 341 | struct device_node *node; |
340 | "arm,vexpress-sysreg"); | 342 | |
343 | if (vexpress_sysreg_base) | ||
344 | return; | ||
341 | 345 | ||
346 | node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); | ||
342 | if (node) { | 347 | if (node) { |
343 | vexpress_sysreg_base = of_iomap(node, 0); | 348 | vexpress_sysreg_base = of_iomap(node, 0); |
344 | vexpress_sysreg_setup(node); | 349 | vexpress_sysreg_setup(node); |
345 | } else { | ||
346 | pr_info("vexpress-sysreg: No Device Tree node found."); | ||
347 | } | 350 | } |
348 | } | 351 | } |
349 | 352 | ||
350 | 353 | ||
354 | #define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \ | ||
355 | [VEXPRESS_GPIO_##_name] = { \ | ||
356 | .reg = _reg, \ | ||
357 | .value = _reg##_##_value, \ | ||
358 | } | ||
359 | |||
351 | static struct vexpress_sysreg_gpio { | 360 | static struct vexpress_sysreg_gpio { |
352 | unsigned long reg; | 361 | unsigned long reg; |
353 | u32 value; | 362 | u32 value; |
354 | } vexpress_sysreg_gpios[] = { | 363 | } vexpress_sysreg_gpios[] = { |
355 | [VEXPRESS_GPIO_MMC_CARDIN] = { | 364 | VEXPRESS_SYSREG_GPIO(MMC_CARDIN, SYS_MCI, CARDIN), |
356 | .reg = SYS_MCI, | 365 | VEXPRESS_SYSREG_GPIO(MMC_WPROT, SYS_MCI, WPROT), |
357 | .value = SYS_MCI_CARDIN, | 366 | VEXPRESS_SYSREG_GPIO(FLASH_WPn, SYS_FLASH, WPn), |
358 | }, | 367 | VEXPRESS_SYSREG_GPIO(LED0, SYS_LED, LED(0)), |
359 | [VEXPRESS_GPIO_MMC_WPROT] = { | 368 | VEXPRESS_SYSREG_GPIO(LED1, SYS_LED, LED(1)), |
360 | .reg = SYS_MCI, | 369 | VEXPRESS_SYSREG_GPIO(LED2, SYS_LED, LED(2)), |
361 | .value = SYS_MCI_WPROT, | 370 | VEXPRESS_SYSREG_GPIO(LED3, SYS_LED, LED(3)), |
362 | }, | 371 | VEXPRESS_SYSREG_GPIO(LED4, SYS_LED, LED(4)), |
363 | [VEXPRESS_GPIO_FLASH_WPn] = { | 372 | VEXPRESS_SYSREG_GPIO(LED5, SYS_LED, LED(5)), |
364 | .reg = SYS_FLASH, | 373 | VEXPRESS_SYSREG_GPIO(LED6, SYS_LED, LED(6)), |
365 | .value = SYS_FLASH_WPn, | 374 | VEXPRESS_SYSREG_GPIO(LED7, SYS_LED, LED(7)), |
366 | }, | ||
367 | }; | 375 | }; |
368 | 376 | ||
369 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | 377 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, |
@@ -372,12 +380,6 @@ static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | |||
372 | return 0; | 380 | return 0; |
373 | } | 381 | } |
374 | 382 | ||
375 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
376 | unsigned offset, int value) | ||
377 | { | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, | 383 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, |
382 | unsigned offset) | 384 | unsigned offset) |
383 | { | 385 | { |
@@ -401,6 +403,14 @@ static void vexpress_sysreg_gpio_set(struct gpio_chip *chip, | |||
401 | writel(reg_value, vexpress_sysreg_base + gpio->reg); | 403 | writel(reg_value, vexpress_sysreg_base + gpio->reg); |
402 | } | 404 | } |
403 | 405 | ||
406 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
407 | unsigned offset, int value) | ||
408 | { | ||
409 | vexpress_sysreg_gpio_set(chip, offset, value); | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
404 | static struct gpio_chip vexpress_sysreg_gpio_chip = { | 414 | static struct gpio_chip vexpress_sysreg_gpio_chip = { |
405 | .label = "vexpress-sysreg", | 415 | .label = "vexpress-sysreg", |
406 | .direction_input = vexpress_sysreg_gpio_direction_input, | 416 | .direction_input = vexpress_sysreg_gpio_direction_input, |
@@ -412,6 +422,30 @@ static struct gpio_chip vexpress_sysreg_gpio_chip = { | |||
412 | }; | 422 | }; |
413 | 423 | ||
414 | 424 | ||
425 | #define VEXPRESS_SYSREG_GREEN_LED(_name, _default_trigger, _gpio) \ | ||
426 | { \ | ||
427 | .name = "v2m:green:"_name, \ | ||
428 | .default_trigger = _default_trigger, \ | ||
429 | .gpio = VEXPRESS_GPIO_##_gpio, \ | ||
430 | } | ||
431 | |||
432 | struct gpio_led vexpress_sysreg_leds[] = { | ||
433 | VEXPRESS_SYSREG_GREEN_LED("user1", "heartbeat", LED0), | ||
434 | VEXPRESS_SYSREG_GREEN_LED("user2", "mmc0", LED1), | ||
435 | VEXPRESS_SYSREG_GREEN_LED("user3", "cpu0", LED2), | ||
436 | VEXPRESS_SYSREG_GREEN_LED("user4", "cpu1", LED3), | ||
437 | VEXPRESS_SYSREG_GREEN_LED("user5", "cpu2", LED4), | ||
438 | VEXPRESS_SYSREG_GREEN_LED("user6", "cpu3", LED5), | ||
439 | VEXPRESS_SYSREG_GREEN_LED("user7", "cpu4", LED6), | ||
440 | VEXPRESS_SYSREG_GREEN_LED("user8", "cpu5", LED7), | ||
441 | }; | ||
442 | |||
443 | struct gpio_led_platform_data vexpress_sysreg_leds_pdata = { | ||
444 | .num_leds = ARRAY_SIZE(vexpress_sysreg_leds), | ||
445 | .leds = vexpress_sysreg_leds, | ||
446 | }; | ||
447 | |||
448 | |||
415 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, | 449 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, |
416 | struct device_attribute *attr, char *buf) | 450 | struct device_attribute *attr, char *buf) |
417 | { | 451 | { |
@@ -456,6 +490,10 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) | |||
456 | return err; | 490 | return err; |
457 | } | 491 | } |
458 | 492 | ||
493 | platform_device_register_data(vexpress_sysreg_dev, "leds-gpio", | ||
494 | PLATFORM_DEVID_AUTO, &vexpress_sysreg_leds_pdata, | ||
495 | sizeof(vexpress_sysreg_leds_pdata)); | ||
496 | |||
459 | vexpress_sysreg_dev = &pdev->dev; | 497 | vexpress_sysreg_dev = &pdev->dev; |
460 | 498 | ||
461 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); | 499 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); |
@@ -478,6 +516,7 @@ static struct platform_driver vexpress_sysreg_driver = { | |||
478 | 516 | ||
479 | static int __init vexpress_sysreg_init(void) | 517 | static int __init vexpress_sysreg_init(void) |
480 | { | 518 | { |
519 | vexpress_sysreg_of_early_init(); | ||
481 | return platform_driver_register(&vexpress_sysreg_driver); | 520 | return platform_driver_register(&vexpress_sysreg_driver); |
482 | } | 521 | } |
483 | core_initcall(vexpress_sysreg_init); | 522 | core_initcall(vexpress_sysreg_init); |