From d5bb2923cfa0a29c5854f9618703ff60849b949e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Feb 2011 13:12:10 +0100 Subject: [PATCH 1/4] drivers/char/pcmcia/ipwireless/main.c: Convert release_resource to release_region/release_mem_region Request_region should be used with release_region, not release_resource. This patch contains a number of changes, related to calls to request_region, request_mem_region, and the associated error handling code. 1. For the call to request_region, the variable io_resource storing the result is dropped. The call to release_resource at the end of the function is changed to a call to release_region with the first two arguments of request_region as its arguments. The same call to release_region is also added to release_ipwireless. 2. The first call to request_mem_region is now tested and ret is set to -EBUSY if the the call has failed. This call was associated with the initialization of ipw->attr_memory. But the error handling code was testing ipw->common_memory. The definition of release_ipwireless also suggests that this call should be associated with ipw->common_memory, not ipw->attr_memory. 3. The second call to request_mem_region is now tested and ret is set to -EBUSY if the the call has failed. 4. The various gotos to the error handling code is adjusted so that there is no need for ifs. 5. Return the value stored in the ret variable rather than -1. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,E; @@ ( *x = request_region(...) | *x = request_mem_region(...) ) ... when != release_region(x) when != x = E * release_resource(x); // Signed-off-by: Julia Lawall Signed-off-by: Jiri Kosina Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/ipwireless/main.c | 52 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 94b8eb4d691d..444155a305ae 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -78,7 +78,6 @@ static void signalled_reboot_callback(void *callback_data) static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) { struct ipw_dev *ipw = priv_data; - struct resource *io_resource; int ret; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; @@ -92,9 +91,12 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) if (ret) return ret; - io_resource = request_region(p_dev->resource[0]->start, - resource_size(p_dev->resource[0]), - IPWIRELESS_PCCARD_NAME); + if (!request_region(p_dev->resource[0]->start, + resource_size(p_dev->resource[0]), + IPWIRELESS_PCCARD_NAME)) { + ret = -EBUSY; + goto exit; + } p_dev->resource[2]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; @@ -105,22 +107,25 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr); if (ret != 0) - goto exit2; + goto exit1; ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100; - ipw->attr_memory = ioremap(p_dev->resource[2]->start, + ipw->common_memory = ioremap(p_dev->resource[2]->start, resource_size(p_dev->resource[2])); - request_mem_region(p_dev->resource[2]->start, - resource_size(p_dev->resource[2]), - IPWIRELESS_PCCARD_NAME); + if (!request_mem_region(p_dev->resource[2]->start, + resource_size(p_dev->resource[2]), + IPWIRELESS_PCCARD_NAME)) { + ret = -EBUSY; + goto exit2; + } p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; p_dev->resource[3]->end = 0; /* this used to be 0x1000 */ ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0); if (ret != 0) - goto exit2; + goto exit3; ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0); if (ret != 0) @@ -128,23 +133,28 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) ipw->attr_memory = ioremap(p_dev->resource[3]->start, resource_size(p_dev->resource[3])); - request_mem_region(p_dev->resource[3]->start, - resource_size(p_dev->resource[3]), - IPWIRELESS_PCCARD_NAME); + if (!request_mem_region(p_dev->resource[3]->start, + resource_size(p_dev->resource[3]), + IPWIRELESS_PCCARD_NAME)) { + ret = -EBUSY; + goto exit4; + } return 0; +exit4: + iounmap(ipw->attr_memory); exit3: + release_mem_region(p_dev->resource[2]->start, + resource_size(p_dev->resource[2])); exit2: - if (ipw->common_memory) { - release_mem_region(p_dev->resource[2]->start, - resource_size(p_dev->resource[2])); - iounmap(ipw->common_memory); - } + iounmap(ipw->common_memory); exit1: - release_resource(io_resource); + release_region(p_dev->resource[0]->start, + resource_size(p_dev->resource[0])); +exit: pcmcia_disable_device(p_dev); - return -1; + return ret; } static int config_ipwireless(struct ipw_dev *ipw) @@ -219,6 +229,8 @@ static int config_ipwireless(struct ipw_dev *ipw) static void release_ipwireless(struct ipw_dev *ipw) { + release_region(ipw->link->resource[0]->start, + resource_size(ipw->link->resource[0])); if (ipw->common_memory) { release_mem_region(ipw->link->resource[2]->start, resource_size(ipw->link->resource[2])); From 5b703683b6cc3cb97bbe6b1b14898b273eb59279 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 4 Feb 2011 09:03:43 +0100 Subject: [PATCH 2/4] pcmcia vs. MECR on pxa25x/sa1111 After 2.6.34 changes, __pxa2xx_drv_pcmcia_probe() was replaced by sa1111_pcmcia_add(). That unfortunately means that configure_sockets() is not called, leading to MECR not being set properly, leading to strange crashes. Tested on pxa255+sa1111, I do not have lubbock board nearby. Perhaps cleaner solution exists? Signed-off-by: Pavel Machek Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pxa2xx_base.c | 2 +- drivers/pcmcia/pxa2xx_base.h | 1 + drivers/pcmcia/pxa2xx_lubbock.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 3755e7c8c715..2c540542b5af 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -215,7 +215,7 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, } #endif -static void pxa2xx_configure_sockets(struct device *dev) +void pxa2xx_configure_sockets(struct device *dev) { struct pcmcia_low_level *ops = dev->platform_data; /* diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index bb62ea87b8f9..b609b45469ed 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h @@ -1,3 +1,4 @@ int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); +void pxa2xx_configure_sockets(struct device *dev); diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index b9f8c8fb42bd..25afe637c657 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -226,6 +226,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev) lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); + pxa2xx_configure_sockets(&sadev->dev); ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, pxa2xx_drv_pcmcia_add_one); } From 644e6e4a7fa6b11d59f24032997d90ea0d858d03 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:46:05 +0000 Subject: [PATCH 3/4] cm4000_cs: Fix undefined ops warning Signed-off-by: Alan Cox Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/cm4000_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 777181a2e603..bcbbc71febb7 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -830,8 +830,7 @@ static void monitor_card(unsigned long p) test_bit(IS_ANY_T1, &dev->flags))) { DEBUGP(4, dev, "Perform AUTOPPS\n"); set_bit(IS_AUTOPPS_ACT, &dev->flags); - ptsreq.protocol = ptsreq.protocol = - (0x01 << dev->proto); + ptsreq.protocol = (0x01 << dev->proto); ptsreq.flags = 0x01; ptsreq.pts1 = 0x00; ptsreq.pts2 = 0x00; From 33619f0d3ff715a2a5499520967d526ad931d70d Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 19 Feb 2011 12:35:15 +0100 Subject: [PATCH 4/4] pcmcia: re-enable Zoomed Video support Allow drivers to enable Zoomed Video support. Currently, this is only used by out-of-tree drivers (L64020 DVB driver in particular). CC: [for 2.6.37] Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 2 ++ include/pcmcia/ds.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 0bdda5b3ed55..42fbf1a75576 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -518,6 +518,8 @@ int pcmcia_enable_device(struct pcmcia_device *p_dev) flags |= CONF_ENABLE_IOCARD; if (flags & CONF_ENABLE_IOCARD) s->socket.flags |= SS_IOCARD; + if (flags & CONF_ENABLE_ZVCARD) + s->socket.flags |= SS_ZVCARD | SS_IOCARD; if (flags & CONF_ENABLE_SPKR) { s->socket.flags |= SS_SPKR_ENA; status = CCSR_AUDIO_ENA; diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 8479b66c067b..3fd5064dd43a 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -261,6 +261,7 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev); #define CONF_ENABLE_ESR 0x0008 #define CONF_ENABLE_IOCARD 0x0010 /* auto-enabled if IO resources or IRQ * (CONF_ENABLE_IRQ) in use */ +#define CONF_ENABLE_ZVCARD 0x0020 /* flags used by pcmcia_loop_config() autoconfiguration */ #define CONF_AUTO_CHECK_VCC 0x0100 /* check for matching Vcc? */