Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * PCMCIA 16-bit resource management functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * The initial developer of the original code is David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (C) 1999	     David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Copyright (C) 2004-2010   Dominik Brodowski
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <pcmcia/ss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <pcmcia/cisreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "cs_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* Access speed for IO windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int io_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) module_param(io_speed, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) int pcmcia_validate_mem(struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (s->resource_ops->validate_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return s->resource_ops->validate_mem(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	/* if there is no callback, we can assume that everything is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 				 int low, struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (s->resource_ops->find_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		return s->resource_ops->find_mem(base, num, align, low, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * release_io_space() - release IO ports allocated with alloc_io_space()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @s: pcmcia socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @res: resource to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static void release_io_space(struct pcmcia_socket *s, struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	resource_size_t num = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	dev_dbg(&s->dev, "release_io_space for %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	for (i = 0; i < MAX_IO_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if (!s->io[i].res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		if ((s->io[i].res->start <= res->start) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		    (s->io[i].res->end >= res->end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			s->io[i].InUse -= num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			if (res->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			res->start = res->end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			res->flags = IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			/* Free the window if no one else is using it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			if (s->io[i].InUse == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 				release_resource(s->io[i].res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 				kfree(s->io[i].res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				s->io[i].res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * alloc_io_space() - allocate IO ports for use by a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * @s: pcmcia socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * @res: resource to allocate (begin: begin, end: size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * @lines: number of IO lines decoded by the PCMCIA card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * Special stuff for managing IO windows, because they are scarce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			unsigned int lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	unsigned int align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	unsigned int base = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	unsigned int num = res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	res->flags |= IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	dev_dbg(&s->dev, "alloc_io_space request for %pR, %d lines\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		res, lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	align = base ? (lines ? 1<<lines : 0) : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	if (align && (align < num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		if (base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			dev_dbg(&s->dev, "odd IO request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			while (align && (align < num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				align <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (base & ~(align-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		dev_dbg(&s->dev, "odd IO request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				&res->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	res->start = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	res->end = res->start + num - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (res->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		ret = request_resource(res->parent, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			dev_warn(&s->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 				"request_resource %pR failed: %d\n", res, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			res->parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			release_io_space(s, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * pcmcia_access_config() - read or write card configuration registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * pcmcia_access_config() reads and writes configuration registers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * attribute memory.  Memory window 0 is reserved for this and the tuple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * reading services. Drivers must use pcmcia_read_config_byte() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * pcmcia_write_config_byte().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int pcmcia_access_config(struct pcmcia_device *p_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 				off_t where, u8 *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				int (*accessf) (struct pcmcia_socket *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 						int attr, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 						unsigned int len, void *ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct pcmcia_socket *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (!(c->state & CONFIG_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		dev_dbg(&p_dev->dev, "Configuration isn't locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	addr = (p_dev->config_base + where) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ret = accessf(s, 1, addr, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * pcmcia_read_config_byte() - read a byte from a card configuration register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * pcmcia_read_config_byte() reads a byte from a configuration register in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * attribute memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	return pcmcia_access_config(p_dev, where, val, pcmcia_read_cis_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) EXPORT_SYMBOL(pcmcia_read_config_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  * pcmcia_write_config_byte() - write a byte to a card configuration register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * pcmcia_write_config_byte() writes a byte to a configuration register in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * attribute memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) EXPORT_SYMBOL(pcmcia_write_config_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * pcmcia_map_mem_page() - modify iomem window to point to a different offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * @res: iomem resource already enabled by pcmcia_request_window()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  * @offset: card_offset to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * pcmcia_map_mem_page() modifies what can be read and written by accessing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * an iomem range previously enabled by pcmcia_request_window(), by setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * the card_offset value to @offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	unsigned int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (w >= MAX_WIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	s->win[w].card_start = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	ret = s->ops->set_mem_map(s, &s->win[w]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		dev_warn(&p_dev->dev, "failed to set_mem_map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) EXPORT_SYMBOL(pcmcia_map_mem_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  * pcmcia_fixup_iowidth() - reduce io width to 8bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  * pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  * IO width to 8bit after having called pcmcia_enable_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * previously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	pccard_io_map io_off = { 0, 0, 0, 0, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	pccard_io_map io_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (!(s->state & SOCKET_PRESENT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		!(p_dev->function_config->state & CONFIG_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	io_on.speed = io_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	for (i = 0; i < MAX_IO_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		if (!s->io[i].res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		io_off.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		io_on.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		io_on.start = s->io[i].res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		io_on.stop = s->io[i].res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		s->ops->set_io_map(s, &io_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		msleep(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		s->ops->set_io_map(s, &io_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) EXPORT_SYMBOL(pcmcia_fixup_iowidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * pcmcia_fixup_vpp() - set Vpp to a new voltage level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * @new_vpp: new Vpp voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  * a new voltage level between calls to pcmcia_enable_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  * and pcmcia_disable_device().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	if (!(s->state & SOCKET_PRESENT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		!(p_dev->function_config->state & CONFIG_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	s->socket.Vpp = new_vpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (s->ops->set_socket(s, &s->socket)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		dev_warn(&p_dev->dev, "Unable to set VPP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	p_dev->vpp = new_vpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) EXPORT_SYMBOL(pcmcia_fixup_vpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  * pcmcia_release_configuration() - physically disable a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * pcmcia_release_configuration() is the 1:1 counterpart to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  * pcmcia_enable_device(): If a PCMCIA device is no longer used by any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * driver, the Vpp voltage is set to 0, IRQs will no longer be generated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  * and I/O ranges will be disabled. As pcmcia_release_io() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  * pcmcia_release_window() still need to be called, device drivers are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  * expected to call pcmcia_disable_device() instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int pcmcia_release_configuration(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	pccard_io_map io = { 0, 0, 0, 0, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (p_dev->_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		p_dev->_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		if (--(s->lock_count) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			s->socket.Vpp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			s->socket.io_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			s->ops->set_socket(s, &s->socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	if (c->state & CONFIG_LOCKED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		c->state &= ~CONFIG_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		if (c->state & CONFIG_IO_REQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			for (i = 0; i < MAX_IO_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 				if (!s->io[i].res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 				s->io[i].Config--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 				if (s->io[i].Config != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 				io.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				s->ops->set_io_map(s, &io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * pcmcia_release_io() - release I/O allocated by a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  * pcmcia_release_io() releases the I/O ranges allocated by a PCMCIA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  * device.  This may be invoked some time after a card ejection has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  * already dumped the actual socket configuration, so if the client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * "stale", we don't bother checking the port ranges against the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * current socket values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int pcmcia_release_io(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (!p_dev->_io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	release_io_space(s, &c->io[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (c->io[1].end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		release_io_space(s, &c->io[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	p_dev->_io = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	c->state &= ~CONFIG_IO_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) } /* pcmcia_release_io */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  * pcmcia_release_window() - release reserved iomem for PCMCIA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  * @res: iomem resource to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  * pcmcia_release_window() releases &struct resource *res which was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  * previously reserved by calling pcmcia_request_window().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	pccard_mem_map *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	unsigned int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	dev_dbg(&p_dev->dev, "releasing window %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (w >= MAX_WIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	win = &s->win[w];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (!(p_dev->_win & CLIENT_WIN_REQ(w))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		dev_dbg(&p_dev->dev, "not releasing unknown window\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	/* Shut down memory window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	win->flags &= ~MAP_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	s->ops->set_mem_map(s, win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	s->state &= ~SOCKET_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	/* Release system memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	if (win->res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		release_resource(win->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		kfree(win->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		win->res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	res->start = res->end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	res->flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	p_dev->_win &= ~CLIENT_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) } /* pcmcia_release_window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) EXPORT_SYMBOL(pcmcia_release_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  * pcmcia_enable_device() - set up and activate a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  * pcmcia_enable_device() physically enables a PCMCIA device. It parses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)  * the flags passed to in @flags and stored in @p_dev->flags and sets up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  * the Vpp voltage, enables the speaker line, I/O ports and store proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  * values to configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int pcmcia_enable_device(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	unsigned int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	pccard_io_map iomap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	unsigned char status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	unsigned char ext_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	unsigned char option = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	unsigned int flags = p_dev->config_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (!(s->state & SOCKET_PRESENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (c->state & CONFIG_LOCKED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		dev_dbg(&p_dev->dev, "Configuration is locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	/* Do power control.  We don't allow changes in Vcc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	s->socket.Vpp = p_dev->vpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	if (s->ops->set_socket(s, &s->socket)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		dev_warn(&p_dev->dev, "Unable to set socket state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	/* Pick memory or I/O card, DMA mode, interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	if (p_dev->_io || flags & CONF_ENABLE_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		flags |= CONF_ENABLE_IOCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (flags & CONF_ENABLE_IOCARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		s->socket.flags |= SS_IOCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (flags & CONF_ENABLE_ZVCARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		s->socket.flags |= SS_ZVCARD | SS_IOCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (flags & CONF_ENABLE_SPKR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		s->socket.flags |= SS_SPKR_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		status = CCSR_AUDIO_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		if (!(p_dev->config_regs & PRESENT_STATUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			dev_warn(&p_dev->dev, "speaker requested, but "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 					      "PRESENT_STATUS not set!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (flags & CONF_ENABLE_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		s->socket.io_irq = s->pcmcia_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		s->socket.io_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (flags & CONF_ENABLE_ESR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		p_dev->config_regs |= PRESENT_EXT_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		ext_status = ESR_REQ_ATTN_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	s->ops->set_socket(s, &s->socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	s->lock_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	dev_dbg(&p_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		"enable_device: V %d, flags %x, base %x, regs %x, idx %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		p_dev->vpp, flags, p_dev->config_base, p_dev->config_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		p_dev->config_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	/* Set up CIS configuration registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	base = p_dev->config_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (p_dev->config_regs & PRESENT_COPY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		u16 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		dev_dbg(&p_dev->dev, "clearing CISREG_SCR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	if (p_dev->config_regs & PRESENT_PIN_REPLACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		u16 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		dev_dbg(&p_dev->dev, "clearing CISREG_PRR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	if (p_dev->config_regs & PRESENT_OPTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		if (s->functions == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 			option = p_dev->config_index & COR_CONFIG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			option = p_dev->config_index & COR_MFC_CONFIG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			option |= COR_FUNC_ENA|COR_IREQ_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			if (p_dev->config_regs & PRESENT_IOBASE_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 				option |= COR_ADDR_DECODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		if ((flags & CONF_ENABLE_IRQ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			!(flags & CONF_ENABLE_PULSE_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			option |= COR_LEVEL_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		msleep(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (p_dev->config_regs & PRESENT_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	if (p_dev->config_regs & PRESENT_EXT_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 					&ext_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	if (p_dev->config_regs & PRESENT_IOBASE_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		u8 b = c->io[0].start & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		b = (c->io[0].start >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	if (p_dev->config_regs & PRESENT_IOSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	/* Configure I/O windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	if (c->state & CONFIG_IO_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		iomap.speed = io_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		for (i = 0; i < MAX_IO_WIN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			if (s->io[i].res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 				iomap.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 				iomap.flags = MAP_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 				case IO_DATA_PATH_WIDTH_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 					iomap.flags |= MAP_16BIT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 				case IO_DATA_PATH_WIDTH_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 					iomap.flags |= MAP_AUTOSZ; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 				iomap.start = s->io[i].res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 				iomap.stop = s->io[i].res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 				s->ops->set_io_map(s, &iomap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 				s->io[i].Config++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	c->state |= CONFIG_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	p_dev->_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) } /* pcmcia_enable_device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) EXPORT_SYMBOL(pcmcia_enable_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)  * pcmcia_request_io() attempts to reserve the IO port ranges specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)  * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)  * "start" value is the requested start of the IO port resource; "end"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)  * reflects the number of ports requested. The number of IO lines requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)  * is specified in &struct pcmcia_device @p_dev->io_lines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int pcmcia_request_io(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	config_t *c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	dev_dbg(&p_dev->dev, "pcmcia_request_io: %pR , %pR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		&c->io[0], &c->io[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	if (!(s->state & SOCKET_PRESENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		dev_dbg(&p_dev->dev, "pcmcia_request_io: No card present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	if (c->state & CONFIG_LOCKED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		dev_dbg(&p_dev->dev, "Configuration is locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (c->state & CONFIG_IO_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		dev_dbg(&p_dev->dev, "IO already configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	ret = alloc_io_space(s, &c->io[0], p_dev->io_lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	if (c->io[1].end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		ret = alloc_io_space(s, &c->io[1], p_dev->io_lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 			struct resource tmp = c->io[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 			/* release the previously allocated resource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			release_io_space(s, &c->io[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			/* but preserve the settings, for they worked... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			c->io[0].end = resource_size(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			c->io[0].start = tmp.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			c->io[0].flags = tmp.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		c->io[1].start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	c->state |= CONFIG_IO_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	p_dev->_io = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	dev_dbg(&p_dev->dev, "pcmcia_request_io succeeded: %pR , %pR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		&c->io[0], &c->io[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) } /* pcmcia_request_io */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) EXPORT_SYMBOL(pcmcia_request_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)  * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)  * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)  * @handler: IRQ handler to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)  * pcmcia_request_irq() is a wrapper around request_irq() which allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)  * the PCMCIA core to clean up the registration in pcmcia_disable_device().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)  * Drivers are free to use request_irq() directly, but then they need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)  * call free_irq() themselfves, too. Also, only %IRQF_SHARED capable IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)  * handlers are allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 				    irq_handler_t handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	if (!p_dev->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 			p_dev->devname, p_dev->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		p_dev->_irq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) EXPORT_SYMBOL(pcmcia_request_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) #ifdef CONFIG_PCMCIA_PROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* mask of IRQs already reserved by other cards, we should avoid using them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static u8 pcmcia_used_irq[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static irqreturn_t test_action(int cpl, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)  * pcmcia_setup_isa_irq() - determine whether an ISA IRQ can be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)  * @p_dev - the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)  * locking note: must be called with ops_mutex locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	unsigned int try, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	u32 mask = s->irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	for (try = 0; try < 64; try++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		irq = try % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 		if (irq > NR_IRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		/* marked as available by driver, not blocked by userspace? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		if (!((mask >> irq) & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		/* avoid an IRQ which is already used by another PCMCIA card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		if ((try < 32) && pcmcia_used_irq[irq])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		/* register the correct driver, if possible, to check whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		 * registering a dummy handle works, i.e. if the IRQ isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		 * marked as used by the kernel resource management core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		ret = request_irq(irq, test_action, type, p_dev->devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 				  p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 			free_irq(irq, p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 			p_dev->irq = s->pcmcia_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 			pcmcia_used_irq[irq]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) void pcmcia_cleanup_irq(struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	pcmcia_used_irq[s->pcmcia_irq]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	s->pcmcia_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) #else /* CONFIG_PCMCIA_PROBE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) void pcmcia_cleanup_irq(struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	s->pcmcia_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) #endif  /* CONFIG_PCMCIA_PROBE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)  * pcmcia_setup_irq() - determine IRQ to be used for device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)  * @p_dev - the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)  * locking note: must be called with ops_mutex locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) int pcmcia_setup_irq(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	if (p_dev->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	/* already assigned? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	if (s->pcmcia_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 		p_dev->irq = s->pcmcia_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	/* prefer an exclusive ISA irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	if (!pcmcia_setup_isa_irq(p_dev, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	/* but accept a shared ISA irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	/* but use the PCI irq otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	if (s->pci_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		p_dev->irq = s->pcmcia_irq = s->pci_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)  * pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)  * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)  * @res: &struct resource pointing to p_dev->resource[2..5]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)  * @speed: access speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)  * pcmcia_request_window() attepts to reserve an iomem ranges specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)  * &struct resource @res pointing to one of the entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)  * &struct pcmcia_device @p_dev->resource[2..5]. The "start" value is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)  * requested start of the IO mem resource; "end" reflects the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)  * requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 			unsigned int speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	pccard_mem_map *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	u_long align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	dev_dbg(&p_dev->dev, "request_window %pR %d\n", res, speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	if (!(s->state & SOCKET_PRESENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 		dev_dbg(&p_dev->dev, "No card present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	/* Window size defaults to smallest available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	if (res->end == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		res->end = s->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	if (res->end & (s->map_size-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 		dev_dbg(&p_dev->dev, "invalid map size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	if ((res->start && (s->features & SS_CAP_STATIC_MAP)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	    (res->start & (align-1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		dev_dbg(&p_dev->dev, "invalid base address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	if (res->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	/* Allocate system memory window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	for (w = 0; w < MAX_WIN; w++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		if (!(s->state & SOCKET_WIN_REQ(w)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	if (w == MAX_WIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 		dev_dbg(&p_dev->dev, "all windows are used already\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 	win = &s->win[w];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	if (!(s->features & SS_CAP_STATIC_MAP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 		win->res = pcmcia_find_mem_region(res->start, res->end, align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 						0, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		if (!win->res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 			dev_dbg(&p_dev->dev, "allocating mem region failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 			mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	p_dev->_win |= CLIENT_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	/* Configure the socket controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 	win->map = w+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	win->flags = res->flags & WIN_FLAGS_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 	win->speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	win->card_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	if (s->ops->set_mem_map(s, win) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 		dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 		mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 	s->state |= SOCKET_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 	/* Return window handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 	if (s->features & SS_CAP_STATIC_MAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		res->start = win->static_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 		res->start = win->res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 	/* convert to new-style resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 	res->end += res->start - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	res->flags &= ~WIN_FLAGS_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 	res->flags |= (win->map << 2) | IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	res->parent = win->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 	if (win->res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 		request_resource(&iomem_resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) } /* pcmcia_request_window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) EXPORT_SYMBOL(pcmcia_request_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)  * pcmcia_disable_device() - disable and clean up a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)  * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)  * pcmcia_disable_device() is the driver-callable counterpart to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)  * pcmcia_enable_device(): If a PCMCIA device is no longer used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)  * drivers are expected to clean up and disable the device by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)  * this function. Any I/O ranges (iomem and ioports) will be released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)  * the Vpp voltage will be set to 0, and IRQs will no longer be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)  * generated -- at least if there is no other card function (of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)  * multifunction devices) being used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) void pcmcia_disable_device(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 	dev_dbg(&p_dev->dev, "disabling device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	for (i = 0; i < MAX_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 		struct resource *res = p_dev->resource[MAX_IO_WIN + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 		if (res->flags & WIN_FLAGS_REQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 			pcmcia_release_window(p_dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 	pcmcia_release_configuration(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 	pcmcia_release_io(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	if (p_dev->_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 		free_irq(p_dev->irq, p_dev->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 		p_dev->_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) EXPORT_SYMBOL(pcmcia_disable_device);