diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-09-01 09:22:38 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-10-11 11:18:49 -0400 |
commit | ae027ead87b13cff99b4f48da7696aa4fe75393b (patch) | |
tree | 48dff058f4682b4938c5e7e004634938994de80b /arch/mips/txx9/generic/setup.c | |
parent | 21e77df215e58523a755b5dd006cb17610616f20 (diff) |
MIPS: TXx9: IOC LED support
Add leds-gpio platform device for controlling LEDs connected to IOC on
RBTX49XX and JMR3927 board.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/txx9/generic/setup.c')
-rw-r--r-- | arch/mips/txx9/generic/setup.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 118d716f7832..1ea06553a1e1 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
25 | #include <linux/mtd/physmap.h> | 25 | #include <linux/mtd/physmap.h> |
26 | #include <linux/leds.h> | ||
26 | #include <asm/bootinfo.h> | 27 | #include <asm/bootinfo.h> |
27 | #include <asm/time.h> | 28 | #include <asm/time.h> |
28 | #include <asm/reboot.h> | 29 | #include <asm/reboot.h> |
@@ -649,3 +650,113 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, | |||
649 | platform_device_put(pdev); | 650 | platform_device_put(pdev); |
650 | #endif | 651 | #endif |
651 | } | 652 | } |
653 | |||
654 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | ||
655 | static DEFINE_SPINLOCK(txx9_iocled_lock); | ||
656 | |||
657 | #define TXX9_IOCLED_MAXLEDS 8 | ||
658 | |||
659 | struct txx9_iocled_data { | ||
660 | struct gpio_chip chip; | ||
661 | u8 cur_val; | ||
662 | void __iomem *mmioaddr; | ||
663 | struct gpio_led_platform_data pdata; | ||
664 | struct gpio_led leds[TXX9_IOCLED_MAXLEDS]; | ||
665 | char names[TXX9_IOCLED_MAXLEDS][32]; | ||
666 | }; | ||
667 | |||
668 | static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) | ||
669 | { | ||
670 | struct txx9_iocled_data *data = | ||
671 | container_of(chip, struct txx9_iocled_data, chip); | ||
672 | return data->cur_val & (1 << offset); | ||
673 | } | ||
674 | |||
675 | static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, | ||
676 | int value) | ||
677 | { | ||
678 | struct txx9_iocled_data *data = | ||
679 | container_of(chip, struct txx9_iocled_data, chip); | ||
680 | unsigned long flags; | ||
681 | spin_lock_irqsave(&txx9_iocled_lock, flags); | ||
682 | if (value) | ||
683 | data->cur_val |= 1 << offset; | ||
684 | else | ||
685 | data->cur_val &= ~(1 << offset); | ||
686 | writeb(data->cur_val, data->mmioaddr); | ||
687 | mmiowb(); | ||
688 | spin_unlock_irqrestore(&txx9_iocled_lock, flags); | ||
689 | } | ||
690 | |||
691 | static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset) | ||
692 | { | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset, | ||
697 | int value) | ||
698 | { | ||
699 | txx9_iocled_set(chip, offset, value); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | void __init txx9_iocled_init(unsigned long baseaddr, | ||
704 | int basenum, unsigned int num, int lowactive, | ||
705 | const char *color, char **deftriggers) | ||
706 | { | ||
707 | struct txx9_iocled_data *iocled; | ||
708 | struct platform_device *pdev; | ||
709 | int i; | ||
710 | static char *default_triggers[] __initdata = { | ||
711 | "heartbeat", | ||
712 | "ide-disk", | ||
713 | "nand-disk", | ||
714 | NULL, | ||
715 | }; | ||
716 | |||
717 | if (!deftriggers) | ||
718 | deftriggers = default_triggers; | ||
719 | iocled = kzalloc(sizeof(*iocled), GFP_KERNEL); | ||
720 | if (!iocled) | ||
721 | return; | ||
722 | iocled->mmioaddr = ioremap(baseaddr, 1); | ||
723 | if (!iocled->mmioaddr) | ||
724 | return; | ||
725 | iocled->chip.get = txx9_iocled_get; | ||
726 | iocled->chip.set = txx9_iocled_set; | ||
727 | iocled->chip.direction_input = txx9_iocled_dir_in; | ||
728 | iocled->chip.direction_output = txx9_iocled_dir_out; | ||
729 | iocled->chip.label = "iocled"; | ||
730 | iocled->chip.base = basenum; | ||
731 | iocled->chip.ngpio = num; | ||
732 | if (gpiochip_add(&iocled->chip)) | ||
733 | return; | ||
734 | if (basenum < 0) | ||
735 | basenum = iocled->chip.base; | ||
736 | |||
737 | pdev = platform_device_alloc("leds-gpio", basenum); | ||
738 | if (!pdev) | ||
739 | return; | ||
740 | iocled->pdata.num_leds = num; | ||
741 | iocled->pdata.leds = iocled->leds; | ||
742 | for (i = 0; i < num; i++) { | ||
743 | struct gpio_led *led = &iocled->leds[i]; | ||
744 | snprintf(iocled->names[i], sizeof(iocled->names[i]), | ||
745 | "iocled:%s:%u", color, i); | ||
746 | led->name = iocled->names[i]; | ||
747 | led->gpio = basenum + i; | ||
748 | led->active_low = lowactive; | ||
749 | if (deftriggers && *deftriggers) | ||
750 | led->default_trigger = *deftriggers++; | ||
751 | } | ||
752 | pdev->dev.platform_data = &iocled->pdata; | ||
753 | if (platform_device_add(pdev)) | ||
754 | platform_device_put(pdev); | ||
755 | } | ||
756 | #else /* CONFIG_LEDS_GPIO */ | ||
757 | void __init txx9_iocled_init(unsigned long baseaddr, | ||
758 | int basenum, unsigned int num, int lowactive, | ||
759 | const char *color, char **deftriggers) | ||
760 | { | ||
761 | } | ||
762 | #endif /* CONFIG_LEDS_GPIO */ | ||