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

ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs

Convert the low level PCMCIA driver to gpiod APIs for controlling
the socket power.

Acked-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

+67 -28
+12
arch/arm/mach-sa1100/jornada720.c
··· 190 190 .resource = s1d13xxxfb_resources, 191 191 }; 192 192 193 + static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = { 194 + .dev_id = "1800", 195 + .table = { 196 + GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH), 197 + GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH), 198 + GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH), 199 + GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH), 200 + { }, 201 + }, 202 + }; 203 + 193 204 static struct resource sa1111_resources[] = { 194 205 [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN), 195 206 [1] = DEFINE_RES_IRQ(IRQ_GPIO1), ··· 276 265 udelay(20); /* give it some time to restart */ 277 266 278 267 gpiod_add_lookup_table(&jornada_ts_gpiod_table); 268 + gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table); 279 269 280 270 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 281 271 }
+55 -28
drivers/pcmcia/sa1111_jornada720.c
··· 6 6 * 7 7 */ 8 8 #include <linux/module.h> 9 - #include <linux/kernel.h> 10 9 #include <linux/device.h> 11 10 #include <linux/errno.h> 11 + #include <linux/gpio/consumer.h> 12 12 #include <linux/init.h> 13 13 #include <linux/io.h> 14 14 15 15 #include <mach/hardware.h> 16 - #include <asm/hardware/sa1111.h> 17 16 #include <asm/mach-types.h> 18 17 19 18 #include "sa1111_generic.h" 20 19 21 - /* Does SOCKET1_3V actually do anything? */ 22 - #define SOCKET0_POWER GPIO_GPIO0 23 - #define SOCKET0_3V GPIO_GPIO2 24 - #define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3) 25 - #define SOCKET1_3V GPIO_GPIO3 20 + /* 21 + * Socket 0 power: GPIO A0 22 + * Socket 0 3V: GPIO A2 23 + * Socket 1 power: GPIO A1 & GPIO A3 24 + * Socket 1 3V: GPIO A3 25 + * Does Socket 1 3V actually do anything? 26 + */ 27 + enum { 28 + J720_GPIO_PWR, 29 + J720_GPIO_3V, 30 + J720_GPIO_MAX, 31 + }; 32 + struct jornada720_data { 33 + struct gpio_desc *gpio[J720_GPIO_MAX]; 34 + }; 35 + 36 + static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 37 + { 38 + struct device *dev = skt->socket.dev.parent; 39 + struct jornada720_data *j; 40 + 41 + j = devm_kzalloc(dev, sizeof(*j), GFP_KERNEL); 42 + if (!j) 43 + return -ENOMEM; 44 + 45 + j->gpio[J720_GPIO_PWR] = devm_gpiod_get(dev, skt->nr ? "s1-power" : 46 + "s0-power", GPIOD_OUT_LOW); 47 + if (IS_ERR(j->gpio[J720_GPIO_PWR])) 48 + return PTR_ERR(j->gpio[J720_GPIO_PWR]); 49 + 50 + j->gpio[J720_GPIO_3V] = devm_gpiod_get(dev, skt->nr ? "s1-3v" : 51 + "s0-3v", GPIOD_OUT_LOW); 52 + if (IS_ERR(j->gpio[J720_GPIO_3V])) 53 + return PTR_ERR(j->gpio[J720_GPIO_3V]); 54 + 55 + skt->driver_data = j; 56 + 57 + return 0; 58 + } 26 59 27 60 static int 28 61 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 29 62 { 30 - struct sa1111_pcmcia_socket *s = to_skt(skt); 31 - unsigned int pa_dwr_mask, pa_dwr_set; 63 + struct jornada720_data *j = skt->driver_data; 64 + DECLARE_BITMAP(values, J720_GPIO_MAX) = { 0, }; 32 65 int ret; 33 66 34 67 printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__, ··· 69 36 70 37 switch (skt->nr) { 71 38 case 0: 72 - pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V; 73 - 74 39 switch (state->Vcc) { 75 40 default: 76 41 case 0: 77 - pa_dwr_set = 0; 42 + __assign_bit(J720_GPIO_PWR, values, 0); 43 + __assign_bit(J720_GPIO_3V, values, 0); 78 44 break; 79 45 case 33: 80 - pa_dwr_set = SOCKET0_POWER | SOCKET0_3V; 46 + __assign_bit(J720_GPIO_PWR, values, 1); 47 + __assign_bit(J720_GPIO_3V, values, 1); 81 48 break; 82 49 case 50: 83 - pa_dwr_set = SOCKET0_POWER; 50 + __assign_bit(J720_GPIO_PWR, values, 1); 51 + __assign_bit(J720_GPIO_3V, values, 0); 84 52 break; 85 53 } 86 54 break; 87 55 88 56 case 1: 89 - pa_dwr_mask = SOCKET1_POWER; 90 - 91 57 switch (state->Vcc) { 92 58 default: 93 59 case 0: 94 - pa_dwr_set = 0; 60 + __assign_bit(J720_GPIO_PWR, values, 0); 61 + __assign_bit(J720_GPIO_3V, values, 0); 95 62 break; 96 63 case 33: 97 - pa_dwr_set = SOCKET1_POWER; 98 - break; 99 64 case 50: 100 - pa_dwr_set = SOCKET1_POWER; 65 + __assign_bit(J720_GPIO_PWR, values, 1); 66 + __assign_bit(J720_GPIO_3V, values, 1); 101 67 break; 102 68 } 103 69 break; ··· 113 81 114 82 ret = sa1111_pcmcia_configure_socket(skt, state); 115 83 if (ret == 0) 116 - sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 84 + ret = gpiod_set_array_value_cansleep(J720_GPIO_MAX, j->gpio, 85 + NULL, values); 117 86 118 87 return ret; 119 88 } 120 89 121 90 static struct pcmcia_low_level jornada720_pcmcia_ops = { 122 91 .owner = THIS_MODULE, 92 + .hw_init = jornada720_pcmcia_hw_init, 123 93 .configure_socket = jornada720_pcmcia_configure_socket, 124 94 .first = 0, 125 95 .nr = 2, ··· 129 95 130 96 int pcmcia_jornada720_init(struct sa1111_dev *sadev) 131 97 { 132 - unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; 133 - 134 98 /* Fixme: why messing around with SA11x0's GPIO1? */ 135 99 GRER |= 0x00000002; 136 - 137 - /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ 138 - sa1111_set_io_dir(sadev, pin, 0, 0); 139 - sa1111_set_io(sadev, pin, 0); 140 - sa1111_set_sleep_io(sadev, pin, 0); 141 100 142 101 sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); 143 102 return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,