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

[MIPS] rbtx4938: Add generic GPIO support

GPIO 0..15 are for TX4938 PIO pins, GPIO 16..18 are for FPGA-driven
chipselect signals for SPI devices.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Atsushi Nemoto and committed by
Ralf Baechle
3896b054 06cf5583

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