diff mbox

[PATCH-RFC,02/10] lib: add GENERIC_PCI_IOMAP

Message ID b5a1327dd8bb38f87cba7ae10b308ec3b63de66a.1322163031.git.mst@redhat.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Michael S. Tsirkin Nov. 24, 2011, 8:17 p.m. UTC
Many architectures want a generic pci_iomap but
not the rest of iomap.c. Split that to a separate .c
file and add a new config symbol. select automatically
by GENERIC_IOMAP.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/asm-generic/io.h        |    5 +--
 include/asm-generic/iomap.h     |    7 +----
 include/asm-generic/pci_iomap.h |   26 +++++++++++++++++++++
 lib/Kconfig                     |    4 +++
 lib/Makefile                    |    1 +
 lib/iomap.c                     |   38 +-----------------------------
 lib/pci_iomap.c                 |   48 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 85 insertions(+), 44 deletions(-)
 create mode 100644 include/asm-generic/pci_iomap.h
 create mode 100644 lib/pci_iomap.c

Comments

Arnd Bergmann Nov. 24, 2011, 10:07 p.m. UTC | #1
On Thursday 24 November 2011 22:17:02 Michael S. Tsirkin wrote:
> Many architectures want a generic pci_iomap but
> not the rest of iomap.c. Split that to a separate .c
> file and add a new config symbol. select automatically
> by GENERIC_IOMAP.
> 
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

Very nice!

Acked-by: Arnd Bergmann <arnd@arndb.de>
Stephen Rothwell Nov. 25, 2011, 12:54 a.m. UTC | #2
Hi Michael,

On Thu, 24 Nov 2011 22:17:02 +0200 "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
> index 9120887..c8a67345 100644
> --- a/include/asm-generic/io.h
> +++ b/include/asm-generic/io.h
> @@ -19,6 +19,8 @@
>  #include <asm-generic/iomap.h>
>  #endif
>  
> +#include <asm-generic/pci_iomap.h>
> +
>  #ifndef mmiowb
>  #define mmiowb() do {} while (0)
>  #endif
> @@ -283,9 +285,6 @@ static inline void writesb(const void __iomem *addr, const void *buf, int len)
>  #define __io_virt(x) ((void __force *) (x))
>  
>  #ifndef CONFIG_GENERIC_IOMAP
> -/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
> -struct pci_dev;
> -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
>  static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
>  {
>  }

Just wondering why you move pci_iomap but not pic_iounmap.  And also if
pci_iounmap is meant to stay here, then the "struct pci_dev" should
probably stay as well.

> diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
> index 98dcd76..fdcddcb 100644
> --- a/include/asm-generic/iomap.h
> +++ b/include/asm-generic/iomap.h
> @@ -69,16 +69,13 @@ extern void ioport_unmap(void __iomem *);
>  #ifdef CONFIG_PCI
>  /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
>  struct pci_dev;
> -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
>  extern void pci_iounmap(struct pci_dev *dev, void __iomem *);

Ditto with pci_iounmap.  Also the comment above really belongs with pci_iomap.

> diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
> new file mode 100644
> index 0000000..e08b3bd
> --- /dev/null
> +++ b/include/asm-generic/pci_iomap.h
> @@ -0,0 +1,26 @@
> +/* Generic I/O port emulation, based on MN10300 code
> + *
> + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
> + * Written by David Howells (dhowells@redhat.com)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public Licence
> + * as published by the Free Software Foundation; either version
> + * 2 of the Licence, or (at your option) any later version.
> + */
> +#ifndef __ASM_GENERIC_PCI_IOMAP_H
> +#define __ASM_GENERIC_PCI_IOMAP_H
> +
> +#ifdef CONFIG_PCI
> +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
> +struct pci_dev;

You could move this struct declaration above the ifdef and remove the
duplicate below.

> +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
> +#else
> +struct pci_dev;
> +static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
> +{
> +	return NULL;
> +}
> +#endif
> +
> +#endif /* __ASM_GENERIC_IO_H */
> diff --git a/lib/iomap.c b/lib/iomap.c
> index 5dbcb4b..ada922a 100644
> --- a/lib/iomap.c
> +++ b/lib/iomap.c
> @@ -242,45 +242,11 @@ EXPORT_SYMBOL(ioport_unmap);
>  #endif /* CONFIG_HAS_IOPORT */
>  
>  #ifdef CONFIG_PCI
> -/**
> - * pci_iomap - create a virtual mapping cookie for a PCI BAR
> - * @dev: PCI device that owns the BAR
> - * @bar: BAR number
> - * @maxlen: length of the memory to map
> - *
> - * Using this function you will get a __iomem address to your device BAR.
> - * You can access it using ioread*() and iowrite*(). These functions hide
> - * the details if this is a MMIO or PIO address space and will just do what
> - * you expect from them in the correct way.
> - *
> - * @maxlen specifies the maximum length to map. If you want to get access to
> - * the complete BAR without checking for its length first, pass %0 here.
> - * */
> -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
> -{
> -	resource_size_t start = pci_resource_start(dev, bar);
> -	resource_size_t len = pci_resource_len(dev, bar);
> -	unsigned long flags = pci_resource_flags(dev, bar);
> -
> -	if (!len || !start)
> -		return NULL;
> -	if (maxlen && len > maxlen)
> -		len = maxlen;
> -	if (flags & IORESOURCE_IO)
> -		return ioport_map(start, len);
> -	if (flags & IORESOURCE_MEM) {
> -		if (flags & IORESOURCE_CACHEABLE)
> -			return ioremap(start, len);
> -		return ioremap_nocache(start, len);
> -	}
> -	/* What? */
> -	return NULL;
> -}
> -
> +/* Hide the details if this is a MMIO or PIO address space and just do what
> + * you expect in the correct way. */
>  void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
>  {
>  	IO_COND(addr, /* nothing */, iounmap(addr));
>  }
> -EXPORT_SYMBOL(pci_iomap);
>  EXPORT_SYMBOL(pci_iounmap);

Ditto with pci_iounmap

> diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
> new file mode 100644
> index 0000000..40b26cb
> --- /dev/null
> +++ b/lib/pci_iomap.c
> @@ -0,0 +1,48 @@
> +/*
> + * Implement the default iomap interfaces
> + *
> + * (C) Copyright 2004 Linus Torvalds
> + */
> +#include <linux/pci.h>
> +#include <linux/io.h>
> +
> +#include <linux/module.h>

If this is relative to (at least) v3.2-rc1, then you should use export.h
instead of module.h
Stephen Rothwell Nov. 25, 2011, 12:59 a.m. UTC | #3
Hi Michael,

On Fri, 25 Nov 2011 11:54:55 +1100 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> Just wondering why you move pci_iomap but not pic_iounmap.

I figured this out.  Arches have their own.
Michael S. Tsirkin Nov. 27, 2011, 5:12 p.m. UTC | #4
On Fri, Nov 25, 2011 at 11:54:55AM +1100, Stephen Rothwell wrote:
> Hi Michael,
> 
> On Thu, 24 Nov 2011 22:17:02 +0200 "Michael S. Tsirkin" <mst@redhat.com> wrote:
> >
> > diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
> > index 9120887..c8a67345 100644
> > --- a/include/asm-generic/io.h
> > +++ b/include/asm-generic/io.h
> > @@ -19,6 +19,8 @@
> >  #include <asm-generic/iomap.h>
> >  #endif
> >  
> > +#include <asm-generic/pci_iomap.h>
> > +
> >  #ifndef mmiowb
> >  #define mmiowb() do {} while (0)
> >  #endif
> > @@ -283,9 +285,6 @@ static inline void writesb(const void __iomem *addr, const void *buf, int len)
> >  #define __io_virt(x) ((void __force *) (x))
> >  
> >  #ifndef CONFIG_GENERIC_IOMAP
> > -/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
> > -struct pci_dev;
> > -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
> >  static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
> >  {
> >  }
> 
> Just wondering why you move pci_iomap but not pic_iounmap.

unmap is implemented significantly different between architectures.


>  And also if
> pci_iounmap is meant to stay here, then the "struct pci_dev" should
> probably stay as well.

Right. I'll fix that.

> > diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
> > index 98dcd76..fdcddcb 100644
> > --- a/include/asm-generic/iomap.h
> > +++ b/include/asm-generic/iomap.h
> > @@ -69,16 +69,13 @@ extern void ioport_unmap(void __iomem *);
> >  #ifdef CONFIG_PCI
> >  /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
> >  struct pci_dev;
> > -extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
> >  extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
> 
> Ditto with pci_iounmap.

Answered above :)

>  Also the comment above really belongs with pci_iomap.

Right, I'll correct the comment.

> > diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
> > new file mode 100644
> > index 0000000..e08b3bd
> > --- /dev/null
> > +++ b/include/asm-generic/pci_iomap.h
> > @@ -0,0 +1,26 @@
> > +/* Generic I/O port emulation, based on MN10300 code
> > + *
> > + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
> > + * Written by David Howells (dhowells@redhat.com)
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public Licence
> > + * as published by the Free Software Foundation; either version
> > + * 2 of the Licence, or (at your option) any later version.
> > + */
> > +#ifndef __ASM_GENERIC_PCI_IOMAP_H
> > +#define __ASM_GENERIC_PCI_IOMAP_H
> > +
> > +#ifdef CONFIG_PCI
> > +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
> > +struct pci_dev;
> 
> You could move this struct declaration above the ifdef and remove the
> duplicate below.

Good point. Will do.

> > +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
> > +#else
> > +struct pci_dev;
> > +static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
> > +{
> > +	return NULL;
> > +}
> > +#endif
> > +
> > +#endif /* __ASM_GENERIC_IO_H */
> > diff --git a/lib/iomap.c b/lib/iomap.c
> > index 5dbcb4b..ada922a 100644
> > --- a/lib/iomap.c
> > +++ b/lib/iomap.c
> > @@ -242,45 +242,11 @@ EXPORT_SYMBOL(ioport_unmap);
> >  #endif /* CONFIG_HAS_IOPORT */
> >  
> >  #ifdef CONFIG_PCI
> > -/**
> > - * pci_iomap - create a virtual mapping cookie for a PCI BAR
> > - * @dev: PCI device that owns the BAR
> > - * @bar: BAR number
> > - * @maxlen: length of the memory to map
> > - *
> > - * Using this function you will get a __iomem address to your device BAR.
> > - * You can access it using ioread*() and iowrite*(). These functions hide
> > - * the details if this is a MMIO or PIO address space and will just do what
> > - * you expect from them in the correct way.
> > - *
> > - * @maxlen specifies the maximum length to map. If you want to get access to
> > - * the complete BAR without checking for its length first, pass %0 here.
> > - * */
> > -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
> > -{
> > -	resource_size_t start = pci_resource_start(dev, bar);
> > -	resource_size_t len = pci_resource_len(dev, bar);
> > -	unsigned long flags = pci_resource_flags(dev, bar);
> > -
> > -	if (!len || !start)
> > -		return NULL;
> > -	if (maxlen && len > maxlen)
> > -		len = maxlen;
> > -	if (flags & IORESOURCE_IO)
> > -		return ioport_map(start, len);
> > -	if (flags & IORESOURCE_MEM) {
> > -		if (flags & IORESOURCE_CACHEABLE)
> > -			return ioremap(start, len);
> > -		return ioremap_nocache(start, len);
> > -	}
> > -	/* What? */
> > -	return NULL;
> > -}
> > -
> > +/* Hide the details if this is a MMIO or PIO address space and just do what
> > + * you expect in the correct way. */
> >  void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
> >  {
> >  	IO_COND(addr, /* nothing */, iounmap(addr));
> >  }
> > -EXPORT_SYMBOL(pci_iomap);
> >  EXPORT_SYMBOL(pci_iounmap);
> 
> Ditto with pci_iounmap

Answered above.

> > diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
> > new file mode 100644
> > index 0000000..40b26cb
> > --- /dev/null
> > +++ b/lib/pci_iomap.c
> > @@ -0,0 +1,48 @@
> > +/*
> > + * Implement the default iomap interfaces
> > + *
> > + * (C) Copyright 2004 Linus Torvalds
> > + */
> > +#include <linux/pci.h>
> > +#include <linux/io.h>
> > +
> > +#include <linux/module.h>
> 
> If this is relative to (at least) v3.2-rc1, then you should use export.h
> instead of module.h

I just copied lib/iomap.c
Will fix, thanks for the comments.

> -- 
> Cheers,
> Stephen Rothwell                    sfr@canb.auug.org.au
> http://www.canb.auug.org.au/~sfr/
diff mbox

Patch

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 9120887..c8a67345 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -19,6 +19,8 @@ 
 #include <asm-generic/iomap.h>
 #endif
 
+#include <asm-generic/pci_iomap.h>
+
 #ifndef mmiowb
 #define mmiowb() do {} while (0)
 #endif
@@ -283,9 +285,6 @@  static inline void writesb(const void __iomem *addr, const void *buf, int len)
 #define __io_virt(x) ((void __force *) (x))
 
 #ifndef CONFIG_GENERIC_IOMAP
-/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
-struct pci_dev;
-extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
 {
 }
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 98dcd76..fdcddcb 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -69,16 +69,13 @@  extern void ioport_unmap(void __iomem *);
 #ifdef CONFIG_PCI
 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
-extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
 extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
 #else
 struct pci_dev;
-static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
-{
-	return NULL;
-}
 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
 { }
 #endif
 
+#include <asm-generic/pci_iomap.h>
+
 #endif
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
new file mode 100644
index 0000000..e08b3bd
--- /dev/null
+++ b/include/asm-generic/pci_iomap.h
@@ -0,0 +1,26 @@ 
+/* Generic I/O port emulation, based on MN10300 code
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef __ASM_GENERIC_PCI_IOMAP_H
+#define __ASM_GENERIC_PCI_IOMAP_H
+
+#ifdef CONFIG_PCI
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+#else
+struct pci_dev;
+static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+	return NULL;
+}
+#endif
+
+#endif /* __ASM_GENERIC_IO_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 0058927..36884b4 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -19,8 +19,12 @@  config RATIONAL
 config GENERIC_FIND_FIRST_BIT
 	bool
 
+config GENERIC_PCI_IOMAP
+	bool
+
 config GENERIC_IOMAP
 	bool
+	select GENERIC_PCI_IOMAP
 
 config CRC_CCITT
 	tristate "CRC-CCITT functions"
diff --git a/lib/Makefile b/lib/Makefile
index a4da283..609b2adc 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,7 @@  endif
 
 lib-$(CONFIG_HOTPLUG) += kobject_uevent.o
 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
+obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o
 obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
 obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o
 obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
diff --git a/lib/iomap.c b/lib/iomap.c
index 5dbcb4b..ada922a 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -242,45 +242,11 @@  EXPORT_SYMBOL(ioport_unmap);
 #endif /* CONFIG_HAS_IOPORT */
 
 #ifdef CONFIG_PCI
-/**
- * pci_iomap - create a virtual mapping cookie for a PCI BAR
- * @dev: PCI device that owns the BAR
- * @bar: BAR number
- * @maxlen: length of the memory to map
- *
- * Using this function you will get a __iomem address to your device BAR.
- * You can access it using ioread*() and iowrite*(). These functions hide
- * the details if this is a MMIO or PIO address space and will just do what
- * you expect from them in the correct way.
- *
- * @maxlen specifies the maximum length to map. If you want to get access to
- * the complete BAR without checking for its length first, pass %0 here.
- * */
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
-{
-	resource_size_t start = pci_resource_start(dev, bar);
-	resource_size_t len = pci_resource_len(dev, bar);
-	unsigned long flags = pci_resource_flags(dev, bar);
-
-	if (!len || !start)
-		return NULL;
-	if (maxlen && len > maxlen)
-		len = maxlen;
-	if (flags & IORESOURCE_IO)
-		return ioport_map(start, len);
-	if (flags & IORESOURCE_MEM) {
-		if (flags & IORESOURCE_CACHEABLE)
-			return ioremap(start, len);
-		return ioremap_nocache(start, len);
-	}
-	/* What? */
-	return NULL;
-}
-
+/* Hide the details if this is a MMIO or PIO address space and just do what
+ * you expect in the correct way. */
 void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
 {
 	IO_COND(addr, /* nothing */, iounmap(addr));
 }
-EXPORT_SYMBOL(pci_iomap);
 EXPORT_SYMBOL(pci_iounmap);
 #endif /* CONFIG_PCI */
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
new file mode 100644
index 0000000..40b26cb
--- /dev/null
+++ b/lib/pci_iomap.c
@@ -0,0 +1,48 @@ 
+/*
+ * Implement the default iomap interfaces
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ */
+#include <linux/pci.h>
+#include <linux/io.h>
+
+#include <linux/module.h>
+
+#ifdef CONFIG_PCI
+/**
+ * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * @dev: PCI device that owns the BAR
+ * @bar: BAR number
+ * @maxlen: length of the memory to map
+ *
+ * Using this function you will get a __iomem address to your device BAR.
+ * You can access it using ioread*() and iowrite*(). These functions hide
+ * the details if this is a MMIO or PIO address space and will just do what
+ * you expect from them in the correct way.
+ *
+ * @maxlen specifies the maximum length to map. If you want to get access to
+ * the complete BAR without checking for its length first, pass %0 here.
+ * */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	resource_size_t start = pci_resource_start(dev, bar);
+	resource_size_t len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len || !start)
+		return NULL;
+	if (maxlen && len > maxlen)
+		len = maxlen;
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	/* What? */
+	return NULL;
+}
+
+EXPORT_SYMBOL(pci_iomap);
+#endif /* CONFIG_PCI */