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

PCMCIA: sa1111: wrap soc_pcmcia_socket to contain sa1111 specific data

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

authored by

Russell King - ARM Linux and committed by
Dominik Brodowski
701a5dc0 da4f0073

+123 -40
+12 -7
drivers/pcmcia/pxa2xx_base.c
··· 228 228 #define SKT_DEV_INFO_SIZE(n) \ 229 229 (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) 230 230 231 - static int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) 231 + int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) 232 232 { 233 233 skt->res_skt.start = _PCMCIA(skt->nr); 234 234 skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; ··· 253 253 return soc_pcmcia_add_one(skt); 254 254 } 255 255 256 + void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops) 257 + { 258 + /* Provide our PXA2xx specific timing routines. */ 259 + ops->set_timing = pxa2xx_pcmcia_set_timing; 260 + #ifdef CONFIG_CPU_FREQ 261 + ops->frequency_change = pxa2xx_pcmcia_frequency_change; 262 + #endif 263 + } 264 + 256 265 int __pxa2xx_drv_pcmcia_probe(struct device *dev) 257 266 { 258 - int i, ret; 267 + int i, ret = 0; 259 268 struct pcmcia_low_level *ops; 260 269 struct skt_dev_info *sinfo; 261 270 struct soc_pcmcia_socket *skt; ··· 274 265 275 266 ops = (struct pcmcia_low_level *)dev->platform_data; 276 267 277 - /* Provide our PXA2xx specific timing routines. */ 278 - ops->set_timing = pxa2xx_pcmcia_set_timing; 279 - #ifdef CONFIG_CPU_FREQ 280 - ops->frequency_change = pxa2xx_pcmcia_frequency_change; 281 - #endif 268 + pxa2xx_drv_pcmcia_ops(ops); 282 269 283 270 sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); 284 271 if (!sinfo)
+3
drivers/pcmcia/pxa2xx_base.h
··· 1 1 /* temporary measure */ 2 2 extern int __pxa2xx_drv_pcmcia_probe(struct device *); 3 3 4 + int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); 5 + void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); 6 +
+6 -4
drivers/pcmcia/pxa2xx_lubbock.c
··· 32 32 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 33 33 const socket_state_t *state) 34 34 { 35 + struct sa1111_pcmcia_socket *s = to_skt(skt); 35 36 unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set; 36 37 int ret = 0; 37 38 ··· 150 149 151 150 if (ret == 0) { 152 151 lubbock_set_misc_wr(misc_mask, misc_set); 153 - sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); 152 + sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 154 153 } 155 154 156 155 #if 1 ··· 176 175 * Switch to 5V, Configure socket with 5V voltage 177 176 */ 178 177 lubbock_set_misc_wr(misc_mask, 0); 179 - sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0); 178 + sa1111_set_io(s->dev, pa_dwr_mask, 0); 180 179 181 180 /* 182 181 * It takes about 100ms to turn off Vcc. ··· 229 228 /* Set CF Socket 1 power to standby mode. */ 230 229 lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); 231 230 232 - sadev->dev.platform_data = &lubbock_pcmcia_ops; 233 - ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); 231 + pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); 232 + ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, 233 + pxa2xx_drv_pcmcia_add_one); 234 234 } 235 235 236 236 return ret;
+6 -1
drivers/pcmcia/sa1100_badge4.c
··· 134 134 135 135 .socket_init = sa1111_pcmcia_socket_init, 136 136 .socket_suspend = sa1111_pcmcia_socket_suspend, 137 + 138 + .first = 0, 139 + .nr = 2, 137 140 }; 138 141 139 142 int pcmcia_badge4_init(struct device *dev) ··· 149 146 __func__, 150 147 badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); 151 148 152 - ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2); 149 + sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); 150 + ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, 151 + sa11xx_drv_pcmcia_add_one); 153 152 } 154 153 155 154 return ret;
+14 -6
drivers/pcmcia/sa1100_jornada720.c
··· 24 24 25 25 static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 26 26 { 27 + struct sa1111_pcmcia_socket *s = to_skt(skt); 27 28 unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; 28 29 29 30 /* ··· 32 31 */ 33 32 GRER |= 0x00000002; 34 33 /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ 35 - sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0); 36 - sa1111_set_io(SA1111_DEV(skt->dev), pin, 0); 37 - sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0); 34 + sa1111_set_io_dir(s->dev, pin, 0, 0); 35 + sa1111_set_io(s->dev, pin, 0); 36 + sa1111_set_sleep_io(s->dev, pin, 0); 38 37 39 38 return sa1111_pcmcia_hw_init(skt); 40 39 } ··· 42 41 static int 43 42 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 44 43 { 44 + struct sa1111_pcmcia_socket *s = to_skt(skt); 45 45 unsigned int pa_dwr_mask, pa_dwr_set; 46 46 int ret; 47 47 ··· 99 97 unsigned long flags; 100 98 101 99 local_irq_save(flags); 102 - sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); 100 + sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 103 101 local_irq_restore(flags); 104 102 } 105 103 ··· 115 113 116 114 .socket_init = sa1111_pcmcia_socket_init, 117 115 .socket_suspend = sa1111_pcmcia_socket_suspend, 116 + 117 + .first = 0, 118 + .nr = 2, 118 119 }; 119 120 120 121 int __devinit pcmcia_jornada720_init(struct device *dev) 121 122 { 122 123 int ret = -ENODEV; 123 124 124 - if (machine_is_jornada720()) 125 - ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2); 125 + if (machine_is_jornada720()) { 126 + sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); 127 + ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops, 128 + sa11xx_drv_pcmcia_add_one); 129 + } 126 130 127 131 return ret; 128 132 }
+7 -2
drivers/pcmcia/sa1100_neponset.c
··· 43 43 static int 44 44 neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 45 45 { 46 + struct sa1111_pcmcia_socket *s = to_skt(skt); 46 47 unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set; 47 48 int ret; 48 49 ··· 100 99 NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; 101 100 102 101 local_irq_restore(flags); 103 - sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); 102 + sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 104 103 } 105 104 106 105 return 0; ··· 122 121 .configure_socket = neponset_pcmcia_configure_socket, 123 122 .socket_init = neponset_pcmcia_socket_init, 124 123 .socket_suspend = sa1111_pcmcia_socket_suspend, 124 + .first = 0, 125 + .nr = 2, 125 126 }; 126 127 127 128 int pcmcia_neponset_init(struct sa1111_dev *sadev) ··· 138 135 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); 139 136 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); 140 137 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); 141 - ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2); 138 + sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); 139 + ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, 140 + sa11xx_drv_pcmcia_add_one); 142 141 } 143 142 144 143 return ret;
+45 -13
drivers/pcmcia/sa1111_generic.c
··· 30 30 31 31 int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 32 32 { 33 - if (skt->irq == NO_IRQ) 34 - skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT; 35 - 36 33 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 37 34 } 38 35 ··· 40 43 41 44 void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 42 45 { 43 - struct sa1111_dev *sadev = SA1111_DEV(skt->dev); 44 - unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR); 46 + struct sa1111_pcmcia_socket *s = to_skt(skt); 47 + unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); 45 48 46 49 switch (skt->nr) { 47 50 case 0: ··· 68 71 69 72 int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 70 73 { 71 - struct sa1111_dev *sadev = SA1111_DEV(skt->dev); 74 + struct sa1111_pcmcia_socket *s = to_skt(skt); 72 75 unsigned int pccr_skt_mask, pccr_set_mask, val; 73 76 unsigned long flags; 74 77 ··· 97 100 pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; 98 101 99 102 local_irq_save(flags); 100 - val = sa1111_readl(sadev->mapbase + SA1111_PCCR); 103 + val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); 101 104 val &= ~pccr_skt_mask; 102 105 val |= pccr_set_mask & pccr_skt_mask; 103 - sa1111_writel(val, sadev->mapbase + SA1111_PCCR); 106 + sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); 104 107 local_irq_restore(flags); 105 108 106 109 return 0; ··· 116 119 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); 117 120 } 118 121 122 + int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, 123 + int (*add)(struct soc_pcmcia_socket *)) 124 + { 125 + struct sa1111_pcmcia_socket *s; 126 + int i, ret = 0; 127 + 128 + s = kzalloc(sizeof(*s) * ops->nr, GFP_KERNEL); 129 + if (!s) 130 + return -ENODEV; 131 + 132 + for (i = 0; i < ops->nr; i++) { 133 + s = kzalloc(sizeof(*s), GFP_KERNEL); 134 + if (!s) 135 + return -ENOMEM; 136 + 137 + s->soc.nr = ops->first + i; 138 + s->soc.irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT; 139 + s->soc.ops = ops; 140 + s->soc.socket.owner = ops->owner; 141 + s->soc.socket.dev.parent = &dev->dev; 142 + s->dev = dev; 143 + 144 + ret = add(&s->soc); 145 + if (ret == 0) { 146 + s->next = dev_get_drvdata(&dev->dev); 147 + dev_set_drvdata(&dev->dev, s); 148 + } else 149 + kfree(s); 150 + } 151 + 152 + return ret; 153 + } 154 + 119 155 static int pcmcia_probe(struct sa1111_dev *dev) 120 156 { 121 157 void __iomem *base; 158 + 159 + dev_set_drvdata(&dev->dev, NULL); 122 160 123 161 if (!request_mem_region(dev->res.start, 512, 124 162 SA1111_DRIVER_NAME(dev))) ··· 184 152 185 153 static int __devexit pcmcia_remove(struct sa1111_dev *dev) 186 154 { 187 - struct skt_dev_info *sinfo = dev_get_drvdata(&dev->dev); 188 - int i; 155 + struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev); 189 156 190 157 dev_set_drvdata(&dev->dev, NULL); 191 158 192 - for (i = 0; i < sinfo->nskt; i++) 193 - soc_pcmcia_remove_one(&sinfo->skt[i]); 159 + for (; next = s->next, s; s = next) { 160 + soc_pcmcia_remove_one(&s->soc); 161 + kfree(s); 162 + } 194 163 195 - kfree(sinfo); 196 164 release_mem_region(dev->res.start, 512); 197 165 return 0; 198 166 }
+14
drivers/pcmcia/sa1111_generic.h
··· 1 1 #include "soc_common.h" 2 2 #include "sa11xx_base.h" 3 3 4 + struct sa1111_pcmcia_socket { 5 + struct soc_pcmcia_socket soc; 6 + struct sa1111_dev *dev; 7 + struct sa1111_pcmcia_socket *next; 8 + }; 9 + 10 + static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s) 11 + { 12 + return container_of(s, struct sa1111_pcmcia_socket, soc); 13 + } 14 + 15 + int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, 16 + int (*add)(struct soc_pcmcia_socket *)); 17 + 4 18 extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *); 5 19 extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *); 6 20 extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
+14 -7
drivers/pcmcia/sa11xx_base.c
··· 171 171 #define SKT_DEV_INFO_SIZE(n) \ 172 172 (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) 173 173 174 - static int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) 174 + int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) 175 175 { 176 176 skt->res_skt.start = _PCMCIA(skt->nr); 177 177 skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; ··· 195 195 196 196 return soc_pcmcia_add_one(skt); 197 197 } 198 + EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one); 198 199 199 - int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, 200 - int first, int nr) 200 + void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops) 201 201 { 202 - struct skt_dev_info *sinfo; 203 - struct soc_pcmcia_socket *skt; 204 - int i; 205 - 206 202 /* 207 203 * set default MECR calculation if the board specific 208 204 * code did not specify one... ··· 212 216 #ifdef CONFIG_CPU_FREQ 213 217 ops->frequency_change = sa1100_pcmcia_frequency_change; 214 218 #endif 219 + } 220 + EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops); 221 + 222 + int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, 223 + int first, int nr) 224 + { 225 + struct skt_dev_info *sinfo; 226 + struct soc_pcmcia_socket *skt; 227 + int i, ret = 0; 228 + 229 + sa11xx_drv_pcmcia_ops(ops); 215 230 216 231 sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); 217 232 if (!sinfo)
+2
drivers/pcmcia/sa11xx_base.h
··· 118 118 } 119 119 120 120 121 + int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); 122 + void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); 121 123 extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr); 122 124 123 125 #endif /* !defined(_PCMCIA_SA1100_H) */