All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alan Cox <alan@linux.intel.com>
To: linux-kernel@vger.kernel.org, linux-pcmica@lists.infradead.org
Subject: [PATCH 5/5] pcmcia: add a new resource manager for non ISA systems
Date: Thu, 04 Dec 2014 21:31:22 +0000	[thread overview]
Message-ID: <20141204213108.1351.2478.stgit@localhost.localdomain> (raw)
In-Reply-To: <20141204212746.1351.89165.stgit@localhost.localdomain>

On a pure PCI platform we don't actually need all the complexity of the
rsrc_nonstatic manager, in fact we can just work directly with the pci
allocators and avoid all the complexity (and code bloat).

Signed-off-by: Alan Cox <alan@linux.intel.com>
---
 drivers/pcmcia/Kconfig    |   12 ++-
 drivers/pcmcia/Makefile   |    1 
 drivers/pcmcia/rsrc_pci.c |  172 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+), 3 deletions(-)
 create mode 100644 drivers/pcmcia/rsrc_pci.c

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index b0ce7cd..2bd21a6 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -69,7 +69,8 @@ config YENTA
 	tristate "CardBus yenta-compatible bridge support"
 	depends on PCI
 	select CARDBUS if !EXPERT
-	select PCCARD_NONSTATIC if PCMCIA != n
+	select PCCARD_NONSTATIC if PCMCIA != n && ISA
+	select PCCARD_PCI if PCMCIA !=n && !ISA
 	---help---
 	  This option enables support for CardBus host bridges.  Virtually
 	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
@@ -109,7 +110,8 @@ config YENTA_TOSHIBA
 config PD6729
 	tristate "Cirrus PD6729 compatible bridge support"
 	depends on PCMCIA && PCI
-	select PCCARD_NONSTATIC
+	select PCCARD_NONSTATIC if PCMCIA != n && ISA
+	select PCCARD_PCI if PCMCIA !=n && !ISA
 	help
 	  This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge
 	  device, found in some older laptops and PCMCIA card readers.
@@ -117,7 +119,8 @@ config PD6729
 config I82092
 	tristate "i82092 compatible bridge support"
 	depends on PCMCIA && PCI
-	select PCCARD_NONSTATIC
+	select PCCARD_NONSTATIC if PCMCIA != n && ISA
+	select PCCARD_PCI if PCMCIA !=n && !ISA
 	help
 	  This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device,
 	  found in some older laptops and more commonly in evaluation boards for the
@@ -289,6 +292,9 @@ config ELECTRA_CF
 	  Say Y here to support the CompactFlash controller on the
 	  PA Semi Electra eval board.
 
+config PCCARD_PCI
+	bool
+
 config PCCARD_NONSTATIC
 	bool
 
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 27e94b3..f1a7ca0 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PCMCIA)				+= pcmcia.o
 pcmcia_rsrc-y					+= rsrc_mgr.o
 pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC)		+= rsrc_nonstatic.o
 pcmcia_rsrc-$(CONFIG_PCCARD_IODYN)		+= rsrc_iodyn.o
+pcmcia_rsrc-$(CONFIG_PCCARD_PCI)		+= rsrc_pci.o
 obj-$(CONFIG_PCCARD)				+= pcmcia_rsrc.o
 
 
diff --git a/drivers/pcmcia/rsrc_pci.c b/drivers/pcmcia/rsrc_pci.c
new file mode 100644
index 0000000..8934d3c
--- /dev/null
+++ b/drivers/pcmcia/rsrc_pci.c
@@ -0,0 +1,172 @@
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <pcmcia/ss.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+
+struct pcmcia_align_data {
+	unsigned long	mask;
+	unsigned long	offset;
+};
+
+static resource_size_t pcmcia_align(void *align_data,
+				const struct resource *res,
+				resource_size_t size, resource_size_t align)
+{
+	struct pcmcia_align_data *data = align_data;
+	resource_size_t start;
+
+	start = (res->start & ~data->mask) + data->offset;
+	if (start < res->start)
+		start += data->mask + 1;
+	return start;
+}
+
+static struct resource *find_io_region(struct pcmcia_socket *s,
+					unsigned long base, int num,
+					unsigned long align)
+{
+	struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
+						dev_name(&s->dev));
+	struct pcmcia_align_data data;
+	int ret;
+
+	data.mask = align - 1;
+	data.offset = base & data.mask;
+
+	ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
+					     base, 0, pcmcia_align, &data);
+	if (ret != 0) {
+		kfree(res);
+		res = NULL;
+	}
+	return res;
+}
+
+static int res_pci_find_io(struct pcmcia_socket *s, unsigned int attr,
+			unsigned int *base, unsigned int num,
+			unsigned int align, struct resource **parent)
+{
+	int i, ret = 0;
+
+	/* Check for an already-allocated window that must conflict with
+	 * what was asked for.  It is a hack because it does not catch all
+	 * potential conflicts, just the most obvious ones.
+	 */
+	for (i = 0; i < MAX_IO_WIN; i++) {
+		if (!s->io[i].res)
+			continue;
+
+		if (!*base)
+			continue;
+
+		if ((s->io[i].res->start & (align-1)) == *base)
+			return -EBUSY;
+	}
+
+	for (i = 0; i < MAX_IO_WIN; i++) {
+		struct resource *res = s->io[i].res;
+		unsigned int try;
+
+		if (res && (res->flags & IORESOURCE_BITS) !=
+			(attr & IORESOURCE_BITS))
+			continue;
+
+		if (!res) {
+			if (align == 0)
+				align = 0x10000;
+
+			res = s->io[i].res = find_io_region(s, *base, num,
+								align);
+			if (!res)
+				return -EINVAL;
+
+			*base = res->start;
+			s->io[i].res->flags =
+				((res->flags & ~IORESOURCE_BITS) |
+					(attr & IORESOURCE_BITS));
+			s->io[i].InUse = num;
+			*parent = res;
+			return 0;
+		}
+
+		/* Try to extend top of window */
+		try = res->end + 1;
+		if ((*base == 0) || (*base == try)) {
+			ret = adjust_resource(s->io[i].res, res->start,
+					      resource_size(res) + num);
+			if (ret)
+				continue;
+			*base = try;
+			s->io[i].InUse += num;
+			*parent = res;
+			return 0;
+		}
+
+		/* Try to extend bottom of window */
+		try = res->start - num;
+		if ((*base == 0) || (*base == try)) {
+			ret = adjust_resource(s->io[i].res,
+					      res->start - num,
+					      resource_size(res) + num);
+			if (ret)
+				continue;
+			*base = try;
+			s->io[i].InUse += num;
+			*parent = res;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static struct resource *res_pci_find_mem(u_long base, u_long num,
+		u_long align, int low, struct pcmcia_socket *s)
+{
+	struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
+						dev_name(&s->dev));
+	struct pcmcia_align_data data;
+	unsigned long min;
+	int ret;
+
+	if (align < 0x20000)
+		align = 0x20000;
+	data.mask = align - 1;
+	data.offset = base & data.mask;
+
+	min = 0;
+	if (!low)
+		min = 0x100000UL;
+
+	ret = pci_bus_alloc_resource(s->cb_dev->bus,
+			res, num, 1, min, 0,
+			pcmcia_align, &data);
+
+	if (ret != 0) {
+		kfree(res);
+		res = NULL;
+	}
+	return res;
+}
+
+
+static int res_pci_init(struct pcmcia_socket *s)
+{
+	if (!s->cb_dev || (!s->features & SS_CAP_PAGE_REGS)) {
+		dev_err(&s->dev, "not supported by res_pci\n");
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+struct pccard_resource_ops pccard_nonstatic_ops = {
+	.validate_mem = NULL,
+	.find_io = res_pci_find_io,
+	.find_mem = res_pci_find_mem,
+	.init = res_pci_init,
+	.exit = NULL,
+};
+EXPORT_SYMBOL(pccard_nonstatic_ops);


  parent reply	other threads:[~2014-12-04 21:31 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-04 21:28 [PATCH 0/5] pcmcia: 64bit fixes, anonymous cards, other bugs Alan Cox
2014-12-04 21:28 ` [PATCH 1/5] pcmcia: correct types Alan Cox
2014-12-04 21:29 ` [PATCH 2/5] pcmcia cis: on an out of range CIS read return 0xff, don't just warn Alan Cox
2014-12-04 21:30 ` [PATCH 3/5] pcmcia: Fix requery Alan Cox
2014-12-04 21:30 ` [PATCH 4/5] pcmcia: handle anonymous cards by generating a fake CIS Alan Cox
2015-06-14 19:52   ` Dominik Brodowski
2015-06-15 12:10     ` Alan Cox
2015-06-16  6:19       ` Dominik Brodowski
2014-12-04 21:31 ` Alan Cox [this message]
2015-05-30 14:40   ` [PATCH 5/5] pcmcia: add a new resource manager for non ISA systems Dominik Brodowski
2015-06-01 13:59     ` Alan Cox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141204213108.1351.2478.stgit@localhost.localdomain \
    --to=alan@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pcmica@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.