aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-07-29 08:06:42 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-09-29 11:20:21 -0400
commitfb49fa533f9d211994c33efb752ffa5b30033729 (patch)
tree675d26cf01c23d9623f274971a065b0dedb10f3a /drivers
parentcdb138080b78146d1cdadba9f5dadbeb97445b91 (diff)
pcmcia: split up modify_configuration() into two fixup functions
pcmcia_modify_configuration() was only used by two drivers to fix up one issue each: setting the Vpp to a different value, and reducing the IO width to 8 bit. Introduce two explicitly named functions handling these things, and remove one further typedef. CC: netdev@vger.kernel.org CC: linux-mtd@lists.infradead.org Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/maps/pcmciamtd.c8
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c5
-rw-r--r--drivers/pcmcia/pcmcia_resource.c128
3 files changed, 65 insertions, 76 deletions
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index fb3c5380aa84..31ce404baa3c 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -316,15 +316,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
316{ 316{
317 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; 317 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
318 struct pcmcia_device *link = dev->p_dev; 318 struct pcmcia_device *link = dev->p_dev;
319 modconf_t mod;
320 int ret;
321
322 mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID;
323 mod.Vcc = 0;
324 mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
325 319
326 DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); 320 DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
327 ret = pcmcia_modify_configuration(link, &mod); 321 pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
328} 322}
329 323
330 324
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index acc680739c89..395e586d7c0a 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -816,13 +816,10 @@ static int check_sig(struct pcmcia_device *link)
816 } 816 }
817 817
818 if (width) { 818 if (width) {
819 modconf_t mod = {
820 .Attributes = CONF_IO_CHANGE_WIDTH,
821 };
822 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); 819 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
823 820
824 smc91c92_suspend(link); 821 smc91c92_suspend(link);
825 pcmcia_modify_configuration(link, &mod); 822 pcmcia_fixup_iowidth(link);
826 smc91c92_resume(link); 823 smc91c92_resume(link);
827 return check_sig(link); 824 return check_sig(link);
828 } 825 }
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index bf16a1cf7399..14b1a951e1b6 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -226,92 +226,90 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
226EXPORT_SYMBOL(pcmcia_map_mem_page); 226EXPORT_SYMBOL(pcmcia_map_mem_page);
227 227
228 228
229/** pcmcia_modify_configuration 229/**
230 * pcmcia_fixup_iowidth() - reduce io width to 8bit
230 * 231 *
231 * Modify a locked socket configuration 232 * pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the
233 * IO width to 8bit after having called pcmcia_request_configuration()
234 * previously.
232 */ 235 */
233int pcmcia_modify_configuration(struct pcmcia_device *p_dev, 236int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev)
234 modconf_t *mod)
235{ 237{
236 struct pcmcia_socket *s; 238 struct pcmcia_socket *s = p_dev->socket;
237 config_t *c; 239 pccard_io_map io_off = { 0, 0, 0, 0, 1 };
238 int ret; 240 pccard_io_map io_on;
239 241 int i, ret = 0;
240 s = p_dev->socket;
241 242
242 mutex_lock(&s->ops_mutex); 243 mutex_lock(&s->ops_mutex);
243 c = p_dev->function_config;
244 244
245 if (!(s->state & SOCKET_PRESENT)) { 245 dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n");
246 dev_dbg(&p_dev->dev, "No card present\n"); 246
247 ret = -ENODEV; 247 if (!(s->state & SOCKET_PRESENT) ||
248 goto unlock; 248 !(p_dev->function_config->state & CONFIG_LOCKED)) {
249 } 249 dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
250 if (!(c->state & CONFIG_LOCKED)) {
251 dev_dbg(&p_dev->dev, "Configuration isnt't locked\n");
252 ret = -EACCES; 250 ret = -EACCES;
253 goto unlock; 251 goto unlock;
254 } 252 }
255 253
256 if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { 254 io_on.speed = io_speed;
257 dev_dbg(&p_dev->dev, 255 for (i = 0; i < MAX_IO_WIN; i++) {
258 "changing Vcc or IRQ is not allowed at this time\n"); 256 if (!s->io[i].res)
259 ret = -EINVAL; 257 continue;
260 goto unlock; 258 io_off.map = i;
261 } 259 io_on.map = i;
262 260
263 /* We only allow changing Vpp1 and Vpp2 to the same value */ 261 io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
264 if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && 262 io_on.start = s->io[i].res->start;
265 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { 263 io_on.stop = s->io[i].res->end;
266 if (mod->Vpp1 != mod->Vpp2) { 264
267 dev_dbg(&p_dev->dev, 265 s->ops->set_io_map(s, &io_off);
268 "Vpp1 and Vpp2 must be the same\n"); 266 mdelay(40);
269 ret = -EINVAL; 267 s->ops->set_io_map(s, &io_on);
270 goto unlock;
271 }
272 s->socket.Vpp = mod->Vpp1;
273 if (s->ops->set_socket(s, &s->socket)) {
274 dev_printk(KERN_WARNING, &p_dev->dev,
275 "Unable to set VPP\n");
276 ret = -EIO;
277 goto unlock;
278 }
279 } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
280 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
281 dev_dbg(&p_dev->dev,
282 "changing Vcc is not allowed at this time\n");
283 ret = -EINVAL;
284 goto unlock;
285 } 268 }
269unlock:
270 mutex_unlock(&s->ops_mutex);
286 271
287 if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { 272 return ret;
288 pccard_io_map io_off = { 0, 0, 0, 0, 1 }; 273}
289 pccard_io_map io_on; 274EXPORT_SYMBOL(pcmcia_fixup_iowidth);
290 int i;
291 275
292 io_on.speed = io_speed;
293 for (i = 0; i < MAX_IO_WIN; i++) {
294 if (!s->io[i].res)
295 continue;
296 io_off.map = i;
297 io_on.map = i;
298 276
299 io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8; 277/**
300 io_on.start = s->io[i].res->start; 278 * pcmcia_fixup_vpp() - set Vpp to a new voltage level
301 io_on.stop = s->io[i].res->end; 279 *
280 * pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to
281 * a new voltage level between calls to pcmcia_request_configuration()
282 * and pcmcia_disable_device().
283 */
284int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp)
285{
286 struct pcmcia_socket *s = p_dev->socket;
287 int ret = 0;
302 288
303 s->ops->set_io_map(s, &io_off); 289 mutex_lock(&s->ops_mutex);
304 mdelay(40); 290
305 s->ops->set_io_map(s, &io_on); 291 dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp);
306 } 292
293 if (!(s->state & SOCKET_PRESENT) ||
294 !(p_dev->function_config->state & CONFIG_LOCKED)) {
295 dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
296 ret = -EACCES;
297 goto unlock;
307 } 298 }
308 ret = 0; 299
300 s->socket.Vpp = new_vpp;
301 if (s->ops->set_socket(s, &s->socket)) {
302 dev_warn(&p_dev->dev, "Unable to set VPP\n");
303 ret = -EIO;
304 goto unlock;
305 }
306
309unlock: 307unlock:
310 mutex_unlock(&s->ops_mutex); 308 mutex_unlock(&s->ops_mutex);
311 309
312 return ret; 310 return ret;
313} /* modify_configuration */ 311}
314EXPORT_SYMBOL(pcmcia_modify_configuration); 312EXPORT_SYMBOL(pcmcia_fixup_vpp);
315 313
316 314
317int pcmcia_release_configuration(struct pcmcia_device *p_dev) 315int pcmcia_release_configuration(struct pcmcia_device *p_dev)