aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/txx9/generic/setup.c
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-09-01 09:22:38 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-10-11 11:18:49 -0400
commitae027ead87b13cff99b4f48da7696aa4fe75393b (patch)
tree48dff058f4682b4938c5e7e004634938994de80b /arch/mips/txx9/generic/setup.c
parent21e77df215e58523a755b5dd006cb17610616f20 (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.c111
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)
655static DEFINE_SPINLOCK(txx9_iocled_lock);
656
657#define TXX9_IOCLED_MAXLEDS 8
658
659struct 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
668static 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
675static 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
691static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset)
692{
693 return 0;
694}
695
696static 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
703void __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 */
757void __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 */