aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud Patard <apatard@mandriva.com>2010-04-29 05:58:54 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-05-21 16:31:16 -0400
commitc197da9163a42e6faeb051f331868b9245836eef (patch)
treef0f29266fd2610bb061b9650e851a26cf6548086
parent96d660c482e03b2d7b6c0245b95a7cce537606c8 (diff)
MIPS: Loongson 2F: Add gpio/gpioilb support
Signed-off-by: Arnaud Patard <apatard@mandriva.com> To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1163/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/include/asm/mach-loongson/gpio.h35
-rw-r--r--arch/mips/loongson/common/Makefile1
-rw-r--r--arch/mips/loongson/common/gpio.c139
4 files changed, 177 insertions, 0 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 7e6fd1cbd3f8..cdaae942623d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1075,6 +1075,8 @@ config CPU_LOONGSON2F
1075 bool "Loongson 2F" 1075 bool "Loongson 2F"
1076 depends on SYS_HAS_CPU_LOONGSON2F 1076 depends on SYS_HAS_CPU_LOONGSON2F
1077 select CPU_LOONGSON2 1077 select CPU_LOONGSON2
1078 select GENERIC_GPIO
1079 select ARCH_REQUIRE_GPIOLIB
1078 help 1080 help
1079 The Loongson 2F processor implements the MIPS III instruction set 1081 The Loongson 2F processor implements the MIPS III instruction set
1080 with many extensions. 1082 with many extensions.
diff --git a/arch/mips/include/asm/mach-loongson/gpio.h b/arch/mips/include/asm/mach-loongson/gpio.h
new file mode 100644
index 000000000000..e30e73d443df
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/gpio.h
@@ -0,0 +1,35 @@
1/*
2 * STLS2F GPIO Support
3 *
4 * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
5 * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef __STLS2F_GPIO_H
14#define __STLS2F_GPIO_H
15
16#include <asm-generic/gpio.h>
17
18extern void gpio_set_value(unsigned gpio, int value);
19extern int gpio_get_value(unsigned gpio);
20extern int gpio_cansleep(unsigned gpio);
21
22/* The chip can do interrupt
23 * but it has not been tested and doc not clear
24 */
25static inline int gpio_to_irq(int gpio)
26{
27 return -EINVAL;
28}
29
30static inline int irq_to_gpio(int gpio)
31{
32 return -EINVAL;
33}
34
35#endif /* __STLS2F_GPIO_H */
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile
index 7668c4de1151..cdd2e812ba1a 100644
--- a/arch/mips/loongson/common/Makefile
+++ b/arch/mips/loongson/common/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ 5obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
6 pci.o bonito-irq.o mem.o machtype.o platform.o 6 pci.o bonito-irq.o mem.o machtype.o platform.o
7obj-$(CONFIG_GENERIC_GPIO) += gpio.o
7 8
8# 9#
9# Serial port support 10# Serial port support
diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c
new file mode 100644
index 000000000000..e8a0ffa935b4
--- /dev/null
+++ b/arch/mips/loongson/common/gpio.c
@@ -0,0 +1,139 @@
1/*
2 * STLS2F GPIO Support
3 *
4 * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
5 * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/spinlock.h>
17#include <linux/err.h>
18#include <asm/types.h>
19#include <loongson.h>
20#include <linux/gpio.h>
21
22#define STLS2F_N_GPIO 4
23#define STLS2F_GPIO_IN_OFFSET 16
24
25static DEFINE_SPINLOCK(gpio_lock);
26
27int gpio_get_value(unsigned gpio)
28{
29 u32 val;
30 u32 mask;
31
32 if (gpio >= STLS2F_N_GPIO)
33 return __gpio_get_value(gpio);
34
35 mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET);
36 spin_lock(&gpio_lock);
37 val = LOONGSON_GPIODATA;
38 spin_unlock(&gpio_lock);
39
40 return ((val & mask) != 0);
41}
42EXPORT_SYMBOL(gpio_get_value);
43
44void gpio_set_value(unsigned gpio, int state)
45{
46 u32 val;
47 u32 mask;
48
49 if (gpio >= STLS2F_N_GPIO) {
50 __gpio_set_value(gpio, state);
51 return ;
52 }
53
54 mask = 1 << gpio;
55
56 spin_lock(&gpio_lock);
57 val = LOONGSON_GPIODATA;
58 if (state)
59 val |= mask;
60 else
61 val &= (~mask);
62 LOONGSON_GPIODATA = val;
63 spin_unlock(&gpio_lock);
64}
65EXPORT_SYMBOL(gpio_set_value);
66
67int gpio_cansleep(unsigned gpio)
68{
69 if (gpio < STLS2F_N_GPIO)
70 return 0;
71 else
72 return __gpio_cansleep(gpio);
73}
74EXPORT_SYMBOL(gpio_cansleep);
75
76static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
77{
78 u32 temp;
79 u32 mask;
80
81 if (gpio >= STLS2F_N_GPIO)
82 return -EINVAL;
83
84 spin_lock(&gpio_lock);
85 mask = 1 << gpio;
86 temp = LOONGSON_GPIOIE;
87 temp |= mask;
88 LOONGSON_GPIOIE = temp;
89 spin_unlock(&gpio_lock);
90
91 return 0;
92}
93
94static int ls2f_gpio_direction_output(struct gpio_chip *chip,
95 unsigned gpio, int level)
96{
97 u32 temp;
98 u32 mask;
99
100 if (gpio >= STLS2F_N_GPIO)
101 return -EINVAL;
102
103 gpio_set_value(gpio, level);
104 spin_lock(&gpio_lock);
105 mask = 1 << gpio;
106 temp = LOONGSON_GPIOIE;
107 temp &= (~mask);
108 LOONGSON_GPIOIE = temp;
109 spin_unlock(&gpio_lock);
110
111 return 0;
112}
113
114static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
115{
116 return gpio_get_value(gpio);
117}
118
119static void ls2f_gpio_set_value(struct gpio_chip *chip,
120 unsigned gpio, int value)
121{
122 gpio_set_value(gpio, value);
123}
124
125static struct gpio_chip ls2f_chip = {
126 .label = "ls2f",
127 .direction_input = ls2f_gpio_direction_input,
128 .get = ls2f_gpio_get_value,
129 .direction_output = ls2f_gpio_direction_output,
130 .set = ls2f_gpio_set_value,
131 .base = 0,
132 .ngpio = STLS2F_N_GPIO,
133};
134
135static int __init ls2f_gpio_setup(void)
136{
137 return gpiochip_add(&ls2f_chip);
138}
139arch_initcall(ls2f_gpio_setup);