use squashfs on the gemini by default, remove broken flag
[openwrt.git] / target / linux / storm / patches / 1100-gpio.patch
1 --- /dev/null
2 +++ b/drivers/char/gemini_gpio_dev.c
3 @@ -0,0 +1,356 @@
4 +/*
5 + *     GPIO driver for Gemini board
6 + *     Provides /dev/gpio
7 + */
8 +
9 +#include <linux/version.h>
10 +#include <linux/kernel.h>
11 +#include <linux/module.h>
12 +#include <linux/init.h>
13 +#include <linux/proc_fs.h>
14 +#include <linux/fcntl.h>
15 +#include <linux/miscdevice.h>
16 +#include <asm/uaccess.h>       /* copy_to_user, copy_from_user */
17 +
18 +#include <asm/hardware.h>
19 +#include <asm/io.h>
20 +#include <asm/arch/sl2312.h>
21 +#include <asm/arch/irqs.h>
22 +#include <asm/arch/gemini_gpio.h>
23 +
24 +#define GEMINI_GPIO_BASE1              IO_ADDRESS(SL2312_GPIO_BASE)
25 +#define GEMINI_GPIO_BASE2              IO_ADDRESS(SL2312_GPIO_BASE1)
26 +
27 +#define GPIO_SET       2
28 +#define MAX_GPIO_LINE  32*GPIO_SET
29 +
30 +wait_queue_head_t gemini_gpio_wait[MAX_GPIO_LINE];
31 +
32 +enum GPIO_REG
33 +{
34 +    GPIO_DATA_OUT              = 0x00,
35 +    GPIO_DATA_IN               = 0x04,
36 +    GPIO_PIN_DIR               = 0x08,
37 +    GPIO_BY_PASS               = 0x0C,
38 +    GPIO_DATA_SET              = 0x10,
39 +    GPIO_DATA_CLEAR            = 0x14,
40 +    GPIO_PULL_ENABLE           = 0x18,
41 +    GPIO_PULL_TYPE                     = 0x1C,
42 +    GPIO_INT_ENABLE            = 0x20,
43 +    GPIO_INT_RAW_STATUS        = 0x24,
44 +    GPIO_INT_MASK_STATUS       = 0x28,
45 +    GPIO_INT_MASK                      = 0x2C,
46 +    GPIO_INT_CLEAR                     = 0x30,
47 +    GPIO_INT_TRIG                      = 0x34,
48 +    GPIO_INT_BOTH                      = 0x38,
49 +    GPIO_INT_POLAR                     = 0x3C
50 +};
51 +
52 +unsigned int regist_gpio_int0=0,regist_gpio_int1=0;
53 +
54 +/* defines a specific GPIO bit number and state */
55 +struct gpio_bit {
56 +       unsigned char bit;
57 +       unsigned char state;
58 +};
59 +
60 +#define GPIO_MAJOR    10
61 +#define GPIO_MINOR    127
62 +
63 +/*
64 + * ioctl calls that are permitted to the /dev/gpio interface
65 + */
66 +#define GPIO_GET_BIT   0x0000001
67 +#define GPIO_SET_BIT   0x0000002
68 +#define GPIO_GET_CONFIG        0x0000003
69 +#define GPIO_SET_CONFIG 0x0000004
70 +
71 +//#define GPIO_CONFIG_OUT  1
72 +//#define GPIO_CONFIG_IN   2
73 +
74 +
75 +
76 +#define DEVICE_NAME "gpio"
77 +
78 +//#define DEBUG
79 +
80 +/*
81 + * GPIO interface
82 + */
83 +
84 +/* /dev/gpio */
85 +static int gpio_ioctl(struct inode *inode, struct file *file,
86 +                     unsigned int cmd, unsigned long arg);
87 +
88 +/* /proc/driver/gpio */
89 +static int gpio_read_proc(char *page, char **start, off_t off,
90 +                         int count, int *eof, void *data);
91 +
92 +static unsigned char gpio_status;        /* bitmapped status byte.       */
93 +
94 +/* functions for set/get gpio lines on storlink cpu */
95 +
96 +void gpio_line_get(unsigned char pin, u32 * data)
97 +{
98 +       unsigned int set = pin >>5;             // each GPIO set has 32 pins
99 +       unsigned int status,addr;
100 +
101 +       addr = (set ? GEMINI_GPIO_BASE2:GEMINI_GPIO_BASE1) + GPIO_DATA_IN;
102 +       status = readl(addr);
103 +#ifdef DEBUG
104 +       printk("status = %08X, pin = %d, set = %d\n", status, pin, set);
105 +#endif
106 +       if (set)
107 +                       *data = (status&(1<<(pin-32)))?1:0;
108 +       else
109 +                       *data = (status&(1<<pin))?1:0;
110 +}
111 +
112 +void gpio_line_set(unsigned char pin, u32 high)
113 +{
114 +       unsigned char set = pin >>5;            // each GPIO set has 32 pins
115 +       unsigned int status=0,addr;
116 +
117 +       addr = (set ? GEMINI_GPIO_BASE2:GEMINI_GPIO_BASE1)+(high?GPIO_DATA_SET:GPIO_DATA_CLEAR);
118 +
119 +       status &= ~(1 << (pin %32));
120 +       status |= (1 << (pin % 32));
121 +       writel(status,addr);
122 +}
123 +
124 +/*
125 + * pin = [0..63]
126 + * mode =
127 + *                     1 -- OUT
128 + *                     2 -- IN
129 + */
130 +void gpio_line_config(unsigned char pin, unsigned char mode)
131 +{
132 +       unsigned char set = pin >>5;            // each GPIO set has 32 pins
133 +       unsigned int status,addr;
134 +
135 +       addr = (set ? GEMINI_GPIO_BASE2:GEMINI_GPIO_BASE1)+GPIO_PIN_DIR;
136 +       status = readl(addr);
137 +
138 +       status &= ~(1 << (pin %32));
139 +       if (mode == 1)
140 +                       status |= (1 << (pin % 32)); /* PinDir: 0 - input, 1 - output */
141 +
142 +       writel(status,addr);
143 +#if 0
144 +       /* enable pullup-high if mode is input */
145 +
146 +       addr = (set ? GEMINI_GPIO_BASE2:GEMINI_GPIO_BASE1)+GPIO_PULL_ENABLE;
147 +       status = readl(addr);
148 +
149 +       status &= ~(1 << (pin %32));
150 +       if (mode == 2) /* input */
151 +                       status |= (1 << (pin % 32)); /* PullEnable: 0 - disable, 1 - enable */
152 +
153 +       writel(status,addr);
154 +
155 +       addr = (set ? GEMINI_GPIO_BASE2:GEMINI_GPIO_BASE1)+GPIO_PULL_TYPE;
156 +       status = readl(addr);
157 +
158 +       status &= ~(1 << (pin %32));
159 +       if (mode == 2) /* input */
160 +                       status |= (1 << (pin % 32)); /* PullType: 0 - low, 1 - high */
161 +
162 +       writel(status,addr);
163 +#endif
164 +}
165 +
166 +#define GPIO_IS_OPEN             0x01    /* means /dev/gpio is in use     */
167 +
168 +/*
169 + *      Now all the various file operations that we export.
170 + */
171 +static int gpio_ioctl(struct inode *inode, struct file *file,
172 +                         unsigned int cmd, unsigned long arg)
173 +{
174 +               struct gpio_bit bit;
175 +               u32 val;
176 +
177 +               if (copy_from_user(&bit, (struct gpio_bit *)arg,
178 +                                                               sizeof(bit)))
179 +                               return -EFAULT;
180 +
181 +               switch (cmd) {
182 +
183 +                               case GPIO_GET_BIT:
184 +                                               gpio_line_get(bit.bit, &val);
185 +                                               bit.state = val;
186 +                                               return copy_to_user((void *)arg, &bit, sizeof(bit)) ? -EFAULT : 0;
187 +                               case GPIO_SET_BIT:
188 +                                               val = bit.state;
189 +                                               gpio_line_set(bit.bit, val);
190 +                                               return 0;
191 +                               case GPIO_GET_CONFIG:
192 +                                               // gpio_line_config(bit.bit, bit.state);
193 +                                               return copy_to_user((void *)arg, &bit, sizeof(bit)) ? -EFAULT : 0;
194 +                               case GPIO_SET_CONFIG:
195 +                                               val = bit.state;
196 +                                               gpio_line_config(bit.bit, bit.state);
197 +                                               return 0;
198 +               }
199 +               return -EINVAL;
200 +}
201 +
202 +
203 +static int gpio_open(struct inode *inode, struct file *file)
204 +{
205 +        if (gpio_status & GPIO_IS_OPEN)
206 +                return -EBUSY;
207 +
208 +        gpio_status |= GPIO_IS_OPEN;
209 +        return 0;
210 +}
211 +
212 +
213 +static int gpio_release(struct inode *inode, struct file *file)
214 +{
215 +        /*
216 +         * Turn off all interrupts once the device is no longer
217 +         * in use and clear the data.
218 +         */
219 +
220 +        gpio_status &= ~GPIO_IS_OPEN;
221 +        return 0;
222 +}
223 +
224 +
225 +/*
226 + *      The various file operations we support.
227 + */
228 +
229 +static struct file_operations gpio_fops = {
230 +        .owner          = THIS_MODULE,
231 +        .ioctl          = gpio_ioctl,
232 +        .open           = gpio_open,
233 +        .release        = gpio_release,
234 +};
235 +
236 +static struct miscdevice gpio_dev =
237 +{
238 +        .minor          = GPIO_MINOR,
239 +        .name           = "gpio",
240 +        .fops           = &gpio_fops,
241 +};
242 +
243 +
244 +
245 +
246 +#ifdef CONFIG_PROC_FS
247 +static struct proc_dir_entry *dir;
248 +
249 +/*
250 + *      Info exported via "/proc/driver/gpio".
251 + */
252 +static int gpio_get_status(char *buf)
253 +{
254 +    char *p = buf;
255 +       u32 val = 0;
256 +       int i;
257 +       int bit;
258 +#ifdef DEBUG
259 +       u32 addr;
260 +
261 +       for (i = 0; i < 0x20; i+=4 ) {
262 +                       addr = IO_ADDRESS(SL2312_GPIO_BASE) + i;
263 +                       val = readl(addr);
264 +                       p+=sprintf(p, "GPIO0: 0x%02X: %08X\n", i, val );
265 +       }
266 +       for (i = 0; i < 0x20; i+=4 ) {
267 +                       addr = IO_ADDRESS(SL2312_GPIO_BASE1) + i;
268 +                       val = readl(addr);
269 +                       p+=sprintf(p, "GPIO1: 0x%02X: %08X\n", i, val );
270 +       }
271 +#endif
272 +
273 +       for (i = 0; i < 32; i++) {
274 +                       gpio_line_get(i, &bit);
275 +                       if (bit)
276 +                                       val |= (1 << i);
277 +       }
278 +       p += sprintf(p, "gpio0\t: 0x%08x\n", val);
279 +
280 +       val = 0;
281 +       for (i = 32; i < 64; i++) {
282 +                       gpio_line_get(i, &bit);
283 +                       if (bit)
284 +                                       val |= (1 << i);
285 +       }
286 +       p += sprintf(p, "gpio1\t: 0x%08x\n", val);
287 +
288 +       return p - buf;
289 +}
290 +
291 +
292 +/* /proc/driver/gpio read op
293 + */
294 +static int gpio_read_proc(char *page, char **start, off_t off,
295 +                             int count, int *eof, void *data)
296 +{
297 +        int len = gpio_get_status (page);
298 +
299 +        if (len <= off+count)
300 +                       *eof = 1;
301 +        *start = page + off;
302 +        len -= off;
303 +        if ( len > count )
304 +                       len = count;
305 +        if ( len < 0 )
306 +                       len = 0;
307 +        return len;
308 +}
309 +#endif /* CONFIG_PROC_FS */
310 +
311 +
312 +static int __init gpio_init_module(void)
313 +{
314 +        int retval;
315 +#ifdef CONFIG_PROC_FS
316 +       struct proc_dir_entry *res;
317 +#endif
318 +
319 +        /* register /dev/gpio file ops */
320 +       //retval = register_chrdev(GPIO_MAJOR, DEVICE_NAME, &gpio_fops);
321 +       retval = misc_register(&gpio_dev);
322 +        if(retval < 0)
323 +                return retval;
324 +
325 +#ifdef CONFIG_PROC_FS
326 +       dir = proc_mkdir("driver/gpio", NULL);
327 +       if (!dir) {
328 +               misc_deregister(&gpio_dev);
329 +               return -ENOMEM;
330 +       }
331 +        /* register /proc/driver/gpio */
332 +       res = create_proc_entry("info", 0644, dir);
333 +       if (res) {
334 +               res->read_proc= gpio_read_proc;
335 +       } else {
336 +               misc_deregister(&gpio_dev);
337 +               return -ENOMEM;
338 +       }
339 +#endif
340 +
341 +       printk("%s: GPIO driver loaded\n", __FILE__);
342 +
343 +       return 0;
344 +}
345 +
346 +static void __exit gpio_cleanup_module(void)
347 +{
348 +       remove_proc_entry ("info", dir);
349 +        misc_deregister(&gpio_dev);
350 +
351 +       printk("%s: GPIO driver unloaded\n", __FILE__);
352 +}
353 +
354 +module_init(gpio_init_module);
355 +module_exit(gpio_cleanup_module);
356 +
357 +MODULE_AUTHOR("Jonas Majauskas");
358 +MODULE_LICENSE("GPL");
359 +
360 --- a/drivers/char/Kconfig
361 +++ b/drivers/char/Kconfig
362 @@ -1071,5 +1071,12 @@ config DEVPORT
363  
364  source "drivers/s390/char/Kconfig"
365  
366 +config GEMINI_GPIO_DEV
367 +       tristate "GPIO driver for Gemini board (provides /dev/gpio)"
368 +       depends on ARCH_SL2312
369 +       default n
370 +       help
371 +         GPIO driver for Gemini boards - SL3512, SL3516.
372 +
373  endmenu
374  
375 --- a/drivers/char/Makefile
376 +++ b/drivers/char/Makefile
377 @@ -116,6 +116,7 @@ obj-$(CONFIG_IPMI_HANDLER)  += ipmi/
378  
379  obj-$(CONFIG_HANGCHECK_TIMER)  += hangcheck-timer.o
380  obj-$(CONFIG_TCG_TPM)          += tpm/
381 +obj-$(CONFIG_GEMINI_GPIO_DEV)          += gemini_gpio_dev.o
382  
383  obj-$(CONFIG_PS3_FLASH)                += ps3flash.o
384