diff options
-rw-r--r-- | arch/mips/Kconfig | 1 | ||||
-rw-r--r-- | arch/mips/configs/rbhma4500_defconfig | 1 | ||||
-rw-r--r-- | arch/mips/tx4938/toshiba_rbtx4938/setup.c | 104 |
3 files changed, 106 insertions, 0 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 24661d60bc8f..823a6285c55a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -660,6 +660,7 @@ config TOSHIBA_RBTX4938 | |||
660 | select SYS_SUPPORTS_BIG_ENDIAN | 660 | select SYS_SUPPORTS_BIG_ENDIAN |
661 | select SYS_SUPPORTS_KGDB | 661 | select SYS_SUPPORTS_KGDB |
662 | select GENERIC_HARDIRQS_NO__DO_IRQ | 662 | select GENERIC_HARDIRQS_NO__DO_IRQ |
663 | select GENERIC_GPIO | ||
663 | help | 664 | help |
664 | This Toshiba board is based on the TX4938 processor. Say Y here to | 665 | This Toshiba board is based on the TX4938 processor. Say Y here to |
665 | support this machine type | 666 | support this machine type |
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index b0abd16fae29..6e10c15cecf7 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig | |||
@@ -80,6 +80,7 @@ CONFIG_DMA_NONCOHERENT=y | |||
80 | CONFIG_DMA_NEED_PCI_MAP_STATE=y | 80 | CONFIG_DMA_NEED_PCI_MAP_STATE=y |
81 | CONFIG_GENERIC_ISA_DMA=y | 81 | CONFIG_GENERIC_ISA_DMA=y |
82 | CONFIG_I8259=y | 82 | CONFIG_I8259=y |
83 | CONFIG_GENERIC_GPIO=y | ||
83 | # CONFIG_CPU_BIG_ENDIAN is not set | 84 | # CONFIG_CPU_BIG_ENDIAN is not set |
84 | CONFIG_CPU_LITTLE_ENDIAN=y | 85 | CONFIG_CPU_LITTLE_ENDIAN=y |
85 | CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y | 86 | CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y |
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index f5d1ce739fcc..12b9f4f9c3a2 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/gpio.h> | ||
32 | #include <asm/tx4938/rbtx4938.h> | 33 | #include <asm/tx4938/rbtx4938.h> |
33 | #ifdef CONFIG_SERIAL_TXX9 | 34 | #ifdef CONFIG_SERIAL_TXX9 |
34 | #include <linux/tty.h> | 35 | #include <linux/tty.h> |
@@ -1057,3 +1058,106 @@ static int __init rbtx4938_ne_init(void) | |||
1057 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; | 1058 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; |
1058 | } | 1059 | } |
1059 | device_initcall(rbtx4938_ne_init); | 1060 | device_initcall(rbtx4938_ne_init); |
1061 | |||
1062 | /* GPIO support */ | ||
1063 | |||
1064 | static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); | ||
1065 | |||
1066 | static void rbtx4938_spi_gpio_set(unsigned gpio, int value) | ||
1067 | { | ||
1068 | u8 val; | ||
1069 | unsigned long flags; | ||
1070 | gpio -= 16; | ||
1071 | spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); | ||
1072 | val = *rbtx4938_spics_ptr; | ||
1073 | if (value) | ||
1074 | val |= 1 << gpio; | ||
1075 | else | ||
1076 | val &= ~(1 << gpio); | ||
1077 | *rbtx4938_spics_ptr = val; | ||
1078 | mmiowb(); | ||
1079 | spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); | ||
1080 | } | ||
1081 | |||
1082 | static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value) | ||
1083 | { | ||
1084 | rbtx4938_spi_gpio_set(gpio, value); | ||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | static DEFINE_SPINLOCK(tx4938_gpio_lock); | ||
1089 | |||
1090 | static int tx4938_gpio_get(unsigned gpio) | ||
1091 | { | ||
1092 | return tx4938_pioptr->din & (1 << gpio); | ||
1093 | } | ||
1094 | |||
1095 | static void tx4938_gpio_set_raw(unsigned gpio, int value) | ||
1096 | { | ||
1097 | u32 val; | ||
1098 | val = tx4938_pioptr->dout; | ||
1099 | if (value) | ||
1100 | val |= 1 << gpio; | ||
1101 | else | ||
1102 | val &= ~(1 << gpio); | ||
1103 | tx4938_pioptr->dout = val; | ||
1104 | } | ||
1105 | |||
1106 | static void tx4938_gpio_set(unsigned gpio, int value) | ||
1107 | { | ||
1108 | unsigned long flags; | ||
1109 | spin_lock_irqsave(&tx4938_gpio_lock, flags); | ||
1110 | tx4938_gpio_set_raw(gpio, value); | ||
1111 | mmiowb(); | ||
1112 | spin_unlock_irqrestore(&tx4938_gpio_lock, flags); | ||
1113 | } | ||
1114 | |||
1115 | static int tx4938_gpio_dir_in(unsigned gpio) | ||
1116 | { | ||
1117 | spin_lock_irq(&tx4938_gpio_lock); | ||
1118 | tx4938_pioptr->dir &= ~(1 << gpio); | ||
1119 | mmiowb(); | ||
1120 | spin_unlock_irq(&tx4938_gpio_lock); | ||
1121 | return 0; | ||
1122 | } | ||
1123 | |||
1124 | static int tx4938_gpio_dir_out(unsigned int gpio, int value) | ||
1125 | { | ||
1126 | spin_lock_irq(&tx4938_gpio_lock); | ||
1127 | tx4938_gpio_set_raw(gpio, value); | ||
1128 | tx4938_pioptr->dir |= 1 << gpio; | ||
1129 | mmiowb(); | ||
1130 | spin_unlock_irq(&tx4938_gpio_lock); | ||
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1134 | int gpio_direction_input(unsigned gpio) | ||
1135 | { | ||
1136 | if (gpio < 16) | ||
1137 | return tx4938_gpio_dir_in(gpio); | ||
1138 | return -EINVAL; | ||
1139 | } | ||
1140 | |||
1141 | int gpio_direction_output(unsigned gpio, int value) | ||
1142 | { | ||
1143 | if (gpio < 16) | ||
1144 | return tx4938_gpio_dir_out(gpio, value); | ||
1145 | if (gpio < 16 + 3) | ||
1146 | return rbtx4938_spi_gpio_dir_out(gpio, value); | ||
1147 | return -EINVAL; | ||
1148 | } | ||
1149 | |||
1150 | int gpio_get_value(unsigned gpio) | ||
1151 | { | ||
1152 | if (gpio < 16) | ||
1153 | return tx4938_gpio_get(gpio); | ||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | void gpio_set_value(unsigned gpio, int value) | ||
1158 | { | ||
1159 | if (gpio < 16) | ||
1160 | tx4938_gpio_set(gpio, value); | ||
1161 | else | ||
1162 | rbtx4938_spi_gpio_set(gpio, value); | ||
1163 | } | ||