From 3c29976a6469b81a7858812dc2d4b8430d74004a Mon Sep 17 00:00:00 2001
From: Dominik Brodowski <linux@dominikbrodowski.net>
Date: Mon, 27 Jun 2005 16:28:46 -0700
Subject: [PATCH] [PATCH] pcmcia: mark parent bridge windows as resources
 available for PCMCIA devices

Automatically mark the parent PCI-PCI bridge windows as resources available
for PCMCIA usage.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 drivers/pcmcia/rsrc_mgr.c       |  2 +-
 drivers/pcmcia/rsrc_nonstatic.c | 58 +++++++++++++++++++++++++++++++++
 include/pcmcia/ss.h             |  3 +-
 3 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index b6843f8d300d..b9269e66281a 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -72,7 +72,7 @@ int pcmcia_adjust_resource_info(adjust_t *adj)
 			/* you can't use the old interface if the new
 			 * one was used before */
 			spin_lock_irqsave(&s->lock, flags);
-			if ((s->resource_setup_done) &&
+			if ((s->resource_setup_new) &&
 			    !(s->resource_setup_old)) {
 				spin_unlock_irqrestore(&s->lock, flags);
 				continue;
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 6b463609a3aa..c8f21796c592 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -768,6 +768,58 @@ static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj
 	return CS_UNSUPPORTED_FUNCTION;
 }
 
+#ifdef CONFIG_PCI
+static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
+{
+	struct resource *res;
+	int i, done = 0;
+
+	if (!s->cb_dev || !s->cb_dev->bus)
+		return -ENODEV;
+
+	for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
+		res = s->cb_dev->bus->resource[i];
+		if (!res)
+			continue;
+
+		if (res->flags & IORESOURCE_IO) {
+			if (res == &ioport_resource)
+				continue;
+			printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
+			       res->start, res->end);
+			if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
+				done |= IORESOURCE_IO;
+
+		}
+
+		if (res->flags & IORESOURCE_MEM) {
+			if (res == &iomem_resource)
+				continue;
+			printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
+			       res->start, res->end);
+			if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
+				done |= IORESOURCE_MEM;
+		}
+	}
+
+	/* if we got at least one of IO, and one of MEM, we can be glad and
+	 * activate the PCMCIA subsystem */
+	if (done & (IORESOURCE_MEM | IORESOURCE_IO))
+		s->resource_setup_done = 1;
+
+	return 0;
+}
+
+#else
+
+static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
+{
+	return -ENODEV;
+}
+
+#endif
+
+
 static int nonstatic_init(struct pcmcia_socket *s)
 {
 	struct socket_data *data;
@@ -782,6 +834,8 @@ static int nonstatic_init(struct pcmcia_socket *s)
 
 	s->resource_data = (void *) data;
 
+	nonstatic_autoadd_resources(s);
+
 	return 0;
 }
 
@@ -862,6 +916,8 @@ static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size
 		return -EINVAL;
 
 	ret = adjust_io(s, add, start_addr, end_addr);
+	if (!ret)
+		s->resource_setup_new = 1;
 
 	return ret ? ret : count;
 }
@@ -912,6 +968,8 @@ static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, siz
 		return -EINVAL;
 
 	ret = adjust_memory(s, add, start_addr, end_addr);
+	if (!ret)
+		s->resource_setup_new = 1;
 
 	return ret ? ret : count;
 }
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 67b867f31fe4..f8797767051d 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -216,8 +216,9 @@ struct pcmcia_socket {
 
 	/* is set to one if resource setup is done using adjust_resource_info() */
 	u8				resource_setup_old:1;
+	u8				resource_setup_new:1;
 
-	u8				reserved:6;
+	u8				reserved:5;
 
 	/* socket operations */
 	struct pccard_operations *	ops;
-- 
2.20.1