Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Arnaud Patard and committed by
Ralf Baechle
c197da91 96d660c4

+177
+2
arch/mips/Kconfig
··· 1075 1075 bool "Loongson 2F" 1076 1076 depends on SYS_HAS_CPU_LOONGSON2F 1077 1077 select CPU_LOONGSON2 1078 + select GENERIC_GPIO 1079 + select ARCH_REQUIRE_GPIOLIB 1078 1080 help 1079 1081 The Loongson 2F processor implements the MIPS III instruction set 1080 1082 with many extensions.
+35
arch/mips/include/asm/mach-loongson/gpio.h
··· 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 + 18 + extern void gpio_set_value(unsigned gpio, int value); 19 + extern int gpio_get_value(unsigned gpio); 20 + extern int gpio_cansleep(unsigned gpio); 21 + 22 + /* The chip can do interrupt 23 + * but it has not been tested and doc not clear 24 + */ 25 + static inline int gpio_to_irq(int gpio) 26 + { 27 + return -EINVAL; 28 + } 29 + 30 + static inline int irq_to_gpio(int gpio) 31 + { 32 + return -EINVAL; 33 + } 34 + 35 + #endif /* __STLS2F_GPIO_H */
+1
arch/mips/loongson/common/Makefile
··· 4 4 5 5 obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ 6 6 pci.o bonito-irq.o mem.o machtype.o platform.o 7 + obj-$(CONFIG_GENERIC_GPIO) += gpio.o 7 8 8 9 # 9 10 # Serial port support
+139
arch/mips/loongson/common/gpio.c
··· 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 + 25 + static DEFINE_SPINLOCK(gpio_lock); 26 + 27 + int 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 + } 42 + EXPORT_SYMBOL(gpio_get_value); 43 + 44 + void 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 + } 65 + EXPORT_SYMBOL(gpio_set_value); 66 + 67 + int gpio_cansleep(unsigned gpio) 68 + { 69 + if (gpio < STLS2F_N_GPIO) 70 + return 0; 71 + else 72 + return __gpio_cansleep(gpio); 73 + } 74 + EXPORT_SYMBOL(gpio_cansleep); 75 + 76 + static 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 + 94 + static 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 + 114 + static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 115 + { 116 + return gpio_get_value(gpio); 117 + } 118 + 119 + static void ls2f_gpio_set_value(struct gpio_chip *chip, 120 + unsigned gpio, int value) 121 + { 122 + gpio_set_value(gpio, value); 123 + } 124 + 125 + static 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 + 135 + static int __init ls2f_gpio_setup(void) 136 + { 137 + return gpiochip_add(&ls2f_chip); 138 + } 139 + arch_initcall(ls2f_gpio_setup);