* Re: [PATCH 1/2] ARM: kirkwood: proper retain MAC address workaround on DT ethernet
From: Sebastian Hesselbarth @ 2013-05-26 20:06 UTC (permalink / raw)
To: David Miller
Cc: andrew, jason, netdev, linux-kernel, buytenh, Grant Likely,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20130525.210441.818472895703230779.davem@davemloft.net>
On 05/26/2013 06:04 AM, David Miller wrote:
> From: Sebastian Hesselbarth<sebastian.hesselbarth@gmail.com>
> Date: Wed, 22 May 2013 22:04:01 +0200
>
>> + memcpy((void *)p->value, reg, 6);
>
> This cast is completely unnecessary, non-void to void pointer casts
> are automatic.
>
> If it is necessary, because p->value is const, then you are trying
> to change something behind the OF layer's back and need to use
> the appropriate interface to change the property contents.
David,
good you mention it. I added Grant on Cc and will give a short
sum-up why I casted the const from property->value away here.
Maybe I overlooked the API for modifying the DT property but as
far as I've seen - there is no API for modifying it. And yes,
you are right, it is kind of an abuse of DT here.
As Kirkwoods loose their MAC address on clock gating, I was looking
for a place to store it early. (a) DT property "local-mac-address"
looked as a good place as it will allow the driver to find it without
any extra code. Of course, I am doing severaly sanity checks if it is
safe to overwrite it, i.e. no other MAC set, property is there, long
enough.
If Grant also NACKs modifying the DT we basically have two more options
left for Kirkwood: (b) have MAC stored early in two global arrays in
board init and reference that from mv643xx_eth or (c) leave the clock
ungated unconditionally on all Kirkwoods.
I can live with all three, just name it and I prepare a final patch set.
Sebastian
^ permalink raw reply
* Re: [PATCH] ppc: remove unused devm_ioremap_prot
From: Kyle McMartin @ 2013-05-26 16:26 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1369521875.3557.7.camel@pasglop>
On Sun, May 26, 2013 at 08:44:35AM +1000, Benjamin Herrenschmidt wrote:
> It's not used ... yet. It's needed if we ever are to implement
> something like devm_ioremap_wc(). I suspect if things like framebuffer
> or even IB drivers start using devm this will be needed.
>
> Any specific reason why you want to take it out ?
>
No particular reason...
ioremap on ppc64 came up in conversation with Adam Jackson, and I
noticed ppc64 had an interface nobody else had, figured it might have
been added, then forgotten.
regards, Kyle
^ permalink raw reply
* [PATCH v3, part2 10/20] PCI, PPC: use hotplug-safe iterators to walk PCI buses
From: Jiang Liu @ 2013-05-26 15:53 UTC (permalink / raw)
To: Bjorn Helgaas, Yinghai Lu
Cc: Gavin Shan, Toshi Kani, Jiang Liu, Greg Kroah-Hartman,
linuxppc-dev, linux-kernel, Rafael J . Wysocki, Yijing Wang,
Bill Pemberton, linux-pci, Gu Zheng, Paul Mackerras, Myron Stowe,
Jiang Liu
In-Reply-To: <1369583597-3801-1-git-send-email-jiang.liu@huawei.com>
Enhance PPC architecture specific code to use hotplug-safe iterators
to walk PCI buses.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Gavin Shan <shangw@linux.vnet.ibm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Bill Pemberton <wfp5p@virginia.edu>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
---
arch/powerpc/kernel/pci-common.c | 4 ++--
arch/powerpc/kernel/pci_64.c | 22 ++++++++--------------
2 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index f5c5c90..56ad3a4 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1386,7 +1386,7 @@ void __init pcibios_resource_survey(void)
struct pci_bus *b;
/* Allocate and assign resources */
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_allocate_bus_resources(b);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
@@ -1396,7 +1396,7 @@ void __init pcibios_resource_survey(void)
* bus available resources to avoid allocating things on top of them
*/
if (!pci_has_flag(PCI_PROBE_ONLY)) {
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_reserve_legacy_regions(b);
}
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 873050d..d71249b 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -207,10 +207,8 @@ void pcibios_setup_phb_io_space(struct pci_controller *hose)
long sys_pciconfig_iobase(long which, unsigned long in_bus,
unsigned long in_devfn)
{
- struct pci_controller* hose;
- struct list_head *ln;
- struct pci_bus *bus = NULL;
- struct device_node *hose_node;
+ struct pci_controller* hose = NULL;
+ struct pci_bus *bus;
/* Argh ! Please forgive me for that hack, but that's the
* simplest way to get existing XFree to not lockup on some
@@ -229,19 +227,15 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
/* That syscall isn't quite compatible with PCI domains, but it's
* used on pre-domains setup. We return the first match
*/
-
- for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
- bus = pci_bus_b(ln);
- if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+ for_each_pci_root_bus(bus)
+ if (in_bus >= bus->number && in_bus <= bus->busn_res.end) {
+ hose = pci_bus_to_host(bus);
+ pci_bus_put(bus);
break;
- bus = NULL;
- }
- if (bus == NULL || bus->dev.of_node == NULL)
+ }
+ if (hose == NULL)
return -ENODEV;
- hose_node = bus->dev.of_node;
- hose = PCI_DN(hose_node)->phb;
-
switch (which) {
case IOBASE_BRIDGE_NUMBER:
return (long)hose->first_busno;
--
1.8.1.2
^ permalink raw reply related
* [PATCH v3-resend 07/11] powerpc: uaccess s/might_sleep/might_fault/
From: Michael S. Tsirkin @ 2013-05-26 14:31 UTC (permalink / raw)
To: linux-kernel
Cc: Arnd Bergmann, Peter Zijlstra, Ingo Molnar, Paul Mackerras,
linuxppc-dev
In-Reply-To: <1369575487-26176-1-git-send-email-mst@redhat.com>
The only reason uaccess routines might sleep
is if they fault. Make this explicit.
Arnd Bergmann suggested that the following code
if (!is_kernel_addr((unsigned long)__pu_addr))
might_fault();
can be further simplified by adding a version of might_fault
that includes the kernel addr check.
Will be considered as a further optimization in future.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
arch/powerpc/include/asm/uaccess.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 4db4959..9485b43 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -178,7 +178,7 @@ do { \
long __pu_err; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
if (!is_kernel_addr((unsigned long)__pu_addr)) \
- might_sleep(); \
+ might_fault(); \
__chk_user_ptr(ptr); \
__put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
@@ -188,7 +188,7 @@ do { \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- might_sleep(); \
+ might_fault(); \
if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
__put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
@@ -268,7 +268,7 @@ do { \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
if (!is_kernel_addr((unsigned long)__gu_addr)) \
- might_sleep(); \
+ might_fault(); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
@@ -282,7 +282,7 @@ do { \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
if (!is_kernel_addr((unsigned long)__gu_addr)) \
- might_sleep(); \
+ might_fault(); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
@@ -294,7 +294,7 @@ do { \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- might_sleep(); \
+ might_fault(); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
@@ -419,14 +419,14 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to,
static inline unsigned long __copy_from_user(void *to,
const void __user *from, unsigned long size)
{
- might_sleep();
+ might_fault();
return __copy_from_user_inatomic(to, from, size);
}
static inline unsigned long __copy_to_user(void __user *to,
const void *from, unsigned long size)
{
- might_sleep();
+ might_fault();
return __copy_to_user_inatomic(to, from, size);
}
@@ -434,7 +434,7 @@ extern unsigned long __clear_user(void __user *addr, unsigned long size);
static inline unsigned long clear_user(void __user *addr, unsigned long size)
{
- might_sleep();
+ might_fault();
if (likely(access_ok(VERIFY_WRITE, addr, size)))
return __clear_user(addr, size);
if ((unsigned long)addr < TASK_SIZE) {
--
MST
^ permalink raw reply related
* [PATCH v2] arch: configuration issue, random return value when disable 'CONFIG_BUG'
From: Chen Gang @ 2013-05-26 4:43 UTC (permalink / raw)
To: Geert Uytterhoeven, Russell King - ARM Linux, Arnd Bergmann
Cc: Catalin Marinas, Linux-sh list, Peter Zijlstra, Heiko Carstens,
paulus@samba.org, H. Peter Anvin, Michel Lespinasse,
Hans-Christian Egtvedt, Linux-Arch, linux-s390, Yoshinori Sato,
Richard Weinberger, Helge Deller, the arch/x86 maintainers,
James E.J. Bottomley, mingo@redhat.com, Frederic Weisbecker,
Paul McKenney, Håvard Skinnemoen, Serge Hallyn,
Mike Frysinger, uml-devel, Will Deacon, Jeff Dike, Akinobu Mita,
uml-user, uclinux-dist-devel@blackfin.uclinux.org,
Thomas Gleixner, linux-arm-kernel@lists.infradead.org,
Parisc List, linux-kernel@vger.kernel.org, Richard Kuo,
Paul Mundt, Eric W. Biederman, linux-hexagon, Martin Schwidefsky,
linux390, Andrew Morton, linuxppc-dev@lists.ozlabs.org,
David Miller
In-Reply-To: <519EE9D6.9010707@asianux.com>
If user disable 'CONFIG_BUG' in menuconfig, many areas not only will
report compiling warnings, but also may return a random value from the
function when BUG().
In fact, most of architectures need always let 'CONFIG_BUG' enabled, so
'#ifdef CONFIG_BUG' is already not 'generic' enough in "include/asm-
generic/".
Also kernel has already provided the 'generic' implementation in
"include/asm-generic" when 'CONFIG_BUG' enabled. Even if we disable
'CONFIG_BUG', we also shall have to implement the BUG() in "include/asm-
generic", just like when 'CONFIG_BUG' enabled (at least, it is not the
minimal size implementation).
So need remove 'CONFIG_BUG', and let it always enabled everywhere, then
fix this issue.
The architectures which need their own architecture specific features
(e.g. minimal size implementation), can customize their own BUG() and
__WARN_TAINT() to give a better fix (e.g. use one inline asm code, then
followed by 'unreachable' function, or another more better fix ways).
Signed-off-by: Chen Gang <gang.chen@asianux.com>
---
arch/arm/Kconfig | 1 -
arch/avr32/Kconfig | 1 -
arch/blackfin/Kconfig | 1 -
arch/h8300/Kconfig | 1 -
arch/hexagon/Kconfig | 1 -
arch/parisc/Kconfig | 2 --
arch/powerpc/Kconfig | 1 -
arch/s390/Kconfig | 2 +-
arch/sh/Kconfig | 2 +-
arch/um/Kconfig.common | 1 -
arch/x86/Kconfig | 1 -
include/asm-generic/bug.h | 29 -----------------------------
init/Kconfig | 10 ----------
lib/Kconfig.debug | 2 +-
14 files changed, 3 insertions(+), 52 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a7fc5ea..ea4a146 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -265,7 +265,6 @@ config PHYS_OFFSET
config GENERIC_BUG
def_bool y
- depends on BUG
source "init/Kconfig"
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index bdc3558..7c9005a 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -55,7 +55,6 @@ config GENERIC_CALIBRATE_DELAY
config GENERIC_BUG
def_bool y
- depends on BUG
source "init/Kconfig"
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index a117652..637dc42 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -47,7 +47,6 @@ config GENERIC_CSUM
config GENERIC_BUG
def_bool y
- depends on BUG
config ZONE_DMA
def_bool y
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 303e4f9..88848da 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -56,7 +56,6 @@ config GENERIC_CALIBRATE_DELAY
config GENERIC_BUG
bool
- depends on BUG
config TIME_LOW_RES
bool
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 33a9792..f50cc8f 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -84,7 +84,6 @@ config STACKTRACE_SUPPORT
config GENERIC_BUG
def_bool y
- depends on BUG
menu "Machine selection"
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6507dab..5de1f8c 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -10,7 +10,6 @@ config PARISC
select RTC_CLASS
select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE
- select BUG
select HAVE_PERF_EVENTS
select GENERIC_ATOMIC64 if !64BIT
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
@@ -62,7 +61,6 @@ config ARCH_HAS_ILOG2_U64
config GENERIC_BUG
bool
default y
- depends on BUG
config GENERIC_HWEIGHT
bool
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c33e3ad..34f4ca9 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -187,7 +187,6 @@ config AUDIT_ARCH
config GENERIC_BUG
bool
default y
- depends on BUG
config SYS_SUPPORTS_APM_EMULATION
default y if PMAC_APM_EMU
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index da183c5..5d7b3db 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -29,7 +29,7 @@ config GENERIC_HWEIGHT
def_bool y
config GENERIC_BUG
- def_bool y if BUG
+ def_bool y
config GENERIC_BUG_RELATIVE_POINTERS
def_bool y
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 8c868cf..d555e7f 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -84,7 +84,7 @@ config RWSEM_XCHGADD_ALGORITHM
config GENERIC_BUG
def_bool y
- depends on BUG && SUPERH32
+ depends on SUPERH32
config GENERIC_CSUM
def_bool y
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index bceee66..7aae42a 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -53,7 +53,6 @@ config GENERIC_CALIBRATE_DELAY
config GENERIC_BUG
bool
default y
- depends on BUG
config HZ
int
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 723e42e..a36e1b4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -166,7 +166,6 @@ config GENERIC_ISA_DMA
config GENERIC_BUG
def_bool y
- depends on BUG
select GENERIC_BUG_RELATIVE_POINTERS if X86_64
config GENERIC_BUG_RELATIVE_POINTERS
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 7d10f96..5d50903 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -12,8 +12,6 @@
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
-#ifdef CONFIG_BUG
-
#ifdef CONFIG_GENERIC_BUG
struct bug_entry {
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
@@ -106,33 +104,6 @@ extern void warn_slowpath_null(const char *file, const int line);
unlikely(__ret_warn_on); \
})
-#else /* !CONFIG_BUG */
-#ifndef HAVE_ARCH_BUG
-#define BUG() do {} while(0)
-#endif
-
-#ifndef HAVE_ARCH_BUG_ON
-#define BUG_ON(condition) do { if (condition) ; } while(0)
-#endif
-
-#ifndef HAVE_ARCH_WARN_ON
-#define WARN_ON(condition) ({ \
- int __ret_warn_on = !!(condition); \
- unlikely(__ret_warn_on); \
-})
-#endif
-
-#ifndef WARN
-#define WARN(condition, format...) ({ \
- int __ret_warn_on = !!(condition); \
- unlikely(__ret_warn_on); \
-})
-#endif
-
-#define WARN_TAINT(condition, taint, format...) WARN_ON(condition)
-
-#endif
-
#define WARN_ON_ONCE(condition) ({ \
static bool __section(.data.unlikely) __warned; \
int __ret_warn_once = !!(condition); \
diff --git a/init/Kconfig b/init/Kconfig
index 7fb26a6..bc1dd49 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1360,16 +1360,6 @@ config PRINTK
very difficult to diagnose system problems, saying N here is
strongly discouraged.
-config BUG
- bool "BUG() support" if EXPERT
- default y
- help
- Disabling this option eliminates support for BUG and WARN, reducing
- the size of your kernel image and potentially quietly ignoring
- numerous fatal conditions. You should only consider disabling this
- option for embedded systems with no facilities for reporting errors.
- Just say Y.
-
config ELF_CORE
depends on COREDUMP
default y
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 566cf2b..54b3251 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -700,7 +700,7 @@ config HAVE_DEBUG_BUGVERBOSE
config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
- depends on BUG && (GENERIC_BUG || HAVE_DEBUG_BUGVERBOSE)
+ depends on GENERIC_BUG || HAVE_DEBUG_BUGVERBOSE
default y
help
Say Y here to make BUG() panics output the file name and line number
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH 1/2] ARM: kirkwood: proper retain MAC address workaround on DT ethernet
From: David Miller @ 2013-05-26 4:04 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: andrew, jason, netdev, linux-kernel, buytenh, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <1369253042-15082-1-git-send-email-sebastian.hesselbarth@gmail.com>
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Date: Wed, 22 May 2013 22:04:01 +0200
> + memcpy((void *)p->value, reg, 6);
This cast is completely unnecessary, non-void to void pointer casts
are automatic.
If it is necessary, because p->value is const, then you are trying
to change something behind the OF layer's back and need to use
the appropriate interface to change the property contents.
^ permalink raw reply
* Re: [PATCH] ppc: remove unused devm_ioremap_prot
From: Benjamin Herrenschmidt @ 2013-05-25 22:44 UTC (permalink / raw)
To: Kyle McMartin; +Cc: linuxppc-dev
In-Reply-To: <20130525165425.GC30204@redacted.bos.redhat.com>
On Sat, 2013-05-25 at 12:54 -0400, Kyle McMartin wrote:
> Added in 2008, but has never had any in-tree users, and no other
> architectures provide it. Also remove the header includes that
> the commit b41e5fff added to asm/io.h, and add an include of mutex.h
> for asm/eeh.h, which relied on io.h including device.h to provide
> it.
>
> Tested ppc64_defconfig in an xcompiler, and it passed... no promises
> I didn't introduce a header mess on some random variant though.
>
> Signed-off-by: Kyle McMartin <kyle@redhat.com>
It's not used ... yet. It's needed if we ever are to implement
something like devm_ioremap_wc(). I suspect if things like framebuffer
or even IB drivers start using devm this will be needed.
Any specific reason why you want to take it out ?
Cheers,
Ben.
> +++ b/arch/powerpc/include/asm/eeh.h
> @@ -23,6 +23,7 @@
>
> #include <linux/init.h>
> #include <linux/list.h>
> +#include <linux/mutex.h>
> #include <linux/string.h>
>
> struct pci_dev;
> diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
> index dd15e5e..ab503b6 100644
> --- a/arch/powerpc/include/asm/io.h
> +++ b/arch/powerpc/include/asm/io.h
> @@ -24,9 +24,6 @@ extern struct pci_dev *isa_bridge_pcidev;
> #define arch_has_dev_port() (isa_bridge_pcidev != NULL)
> #endif
>
> -#include <linux/device.h>
> -#include <linux/io.h>
> -
> #include <linux/compiler.h>
> #include <asm/page.h>
> #include <asm/byteorder.h>
> @@ -791,9 +788,6 @@ static inline void * bus_to_virt(unsigned long address)
>
> #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
>
> -void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
> - size_t size, unsigned long flags);
> -
> #endif /* __KERNEL__ */
>
> #endif /* _ASM_POWERPC_IO_H */
> diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
> index 4504332..bda49b4 100644
> --- a/arch/powerpc/lib/Makefile
> +++ b/arch/powerpc/lib/Makefile
> @@ -12,7 +12,6 @@ CFLAGS_REMOVE_feature-fixups.o = -pg
> obj-y := string.o alloc.o \
> checksum_$(CONFIG_WORD_SIZE).o crtsavres.o
> obj-$(CONFIG_PPC32) += div64.o copy_32.o
> -obj-$(CONFIG_HAS_IOMEM) += devres.o
>
> obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
> memcpy_64.o usercopy_64.o mem_64.o string.o \
> diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c
> deleted file mode 100644
> index 8df55fc..0000000
> --- a/arch/powerpc/lib/devres.c
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -/*
> - * Copyright (C) 2008 Freescale Semiconductor, Inc.
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version
> - * 2 of the License, or (at your option) any later version.
> - */
> -
> -#include <linux/device.h> /* devres_*(), devm_ioremap_release() */
> -#include <linux/gfp.h>
> -#include <linux/io.h> /* ioremap_prot() */
> -#include <linux/export.h> /* EXPORT_SYMBOL() */
> -
> -/**
> - * devm_ioremap_prot - Managed ioremap_prot()
> - * @dev: Generic device to remap IO address for
> - * @offset: BUS offset to map
> - * @size: Size of map
> - * @flags: Page flags
> - *
> - * Managed ioremap_prot(). Map is automatically unmapped on driver
> - * detach.
> - */
> -void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
> - size_t size, unsigned long flags)
> -{
> - void __iomem **ptr, *addr;
> -
> - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
> - if (!ptr)
> - return NULL;
> -
> - addr = ioremap_prot(offset, size, flags);
> - if (addr) {
> - *ptr = addr;
> - devres_add(dev, ptr);
> - } else
> - devres_free(ptr);
> -
> - return addr;
> -}
> -EXPORT_SYMBOL(devm_ioremap_prot);
^ permalink raw reply
* [PATCH] ppc: remove unused devm_ioremap_prot
From: Kyle McMartin @ 2013-05-25 16:54 UTC (permalink / raw)
To: linuxppc-dev
Added in 2008, but has never had any in-tree users, and no other
architectures provide it. Also remove the header includes that
the commit b41e5fff added to asm/io.h, and add an include of mutex.h
for asm/eeh.h, which relied on io.h including device.h to provide
it.
Tested ppc64_defconfig in an xcompiler, and it passed... no promises
I didn't introduce a header mess on some random variant though.
Signed-off-by: Kyle McMartin <kyle@redhat.com>
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/string.h>
struct pci_dev;
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index dd15e5e..ab503b6 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -24,9 +24,6 @@ extern struct pci_dev *isa_bridge_pcidev;
#define arch_has_dev_port() (isa_bridge_pcidev != NULL)
#endif
-#include <linux/device.h>
-#include <linux/io.h>
-
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/byteorder.h>
@@ -791,9 +788,6 @@ static inline void * bus_to_virt(unsigned long address)
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
-void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
- size_t size, unsigned long flags);
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_IO_H */
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 4504332..bda49b4 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -12,7 +12,6 @@ CFLAGS_REMOVE_feature-fixups.o = -pg
obj-y := string.o alloc.o \
checksum_$(CONFIG_WORD_SIZE).o crtsavres.o
obj-$(CONFIG_PPC32) += div64.o copy_32.o
-obj-$(CONFIG_HAS_IOMEM) += devres.o
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o string.o \
diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c
deleted file mode 100644
index 8df55fc..0000000
--- a/arch/powerpc/lib/devres.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/device.h> /* devres_*(), devm_ioremap_release() */
-#include <linux/gfp.h>
-#include <linux/io.h> /* ioremap_prot() */
-#include <linux/export.h> /* EXPORT_SYMBOL() */
-
-/**
- * devm_ioremap_prot - Managed ioremap_prot()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- * @flags: Page flags
- *
- * Managed ioremap_prot(). Map is automatically unmapped on driver
- * detach.
- */
-void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
- size_t size, unsigned long flags)
-{
- void __iomem **ptr, *addr;
-
- ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- addr = ioremap_prot(offset, size, flags);
- if (addr) {
- *ptr = addr;
- devres_add(dev, ptr);
- } else
- devres_free(ptr);
-
- return addr;
-}
-EXPORT_SYMBOL(devm_ioremap_prot);
^ permalink raw reply related
* [PATCH v3, part1 03/10] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead
From: Jiang Liu @ 2013-05-25 13:48 UTC (permalink / raw)
To: Bjorn Helgaas, Yinghai Lu
Cc: Neela Syam Kolli, sparclinux, Toshi Kani, Jiang Liu, linux-scsi,
David Airlie, Greg Kroah-Hartman, linuxppc-dev, linux-kernel,
James E.J. Bottomley, Rafael J . Wysocki, Yijing Wang, linux-pci,
Gu Zheng, Paul Mackerras, Andrew Morton, Myron Stowe,
David S. Miller, Jiang Liu
In-Reply-To: <1369489718-25869-1-git-send-email-jiang.liu@huawei.com>
From: Gu Zheng <guz.fnst@cn.fujitsu.com>
Use the new pci_alloc_dev(bus) to replace the existing using of
alloc_pci_dev(void).
v2:
Follow Bjorn's correction to move pci_bus_put() to
pci_release_dev() instead.
v3:
release reference to bus on error recovery path
Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: David Airlie <airlied@linux.ie>
Cc: Neela Syam Kolli <megaraidlinux@lsi.com>
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-scsi@vger.kernel.org
---
arch/powerpc/kernel/pci_of_scan.c | 3 +--
arch/sparc/kernel/pci.c | 3 +--
drivers/char/agp/alpha-agp.c | 2 +-
drivers/char/agp/parisc-agp.c | 2 +-
drivers/pci/iov.c | 8 +++++---
drivers/pci/probe.c | 5 +++--
drivers/scsi/megaraid.c | 2 +-
7 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index d2d407d..6b0ba58 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
const char *type;
struct pci_slot *slot;
- dev = alloc_pci_dev();
+ dev = pci_alloc_dev(bus);
if (!dev)
return NULL;
type = of_get_property(node, "device_type", NULL);
@@ -137,7 +137,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
- dev->bus = bus;
dev->dev.of_node = of_node_get(node);
dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 972892a..b16f624 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
const char *type;
u32 class;
- dev = alloc_pci_dev();
+ dev = pci_alloc_dev(bus);
if (!dev)
return NULL;
@@ -281,7 +281,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
printk(" create device, devfn: %x, type: %s\n",
devfn, type);
- dev->bus = bus;
dev->sysdata = node;
dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type;
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
index dd84af4..199b8e9 100644
--- a/drivers/char/agp/alpha-agp.c
+++ b/drivers/char/agp/alpha-agp.c
@@ -174,7 +174,7 @@ alpha_core_agp_setup(void)
/*
* Build a fake pci_dev struct
*/
- pdev = alloc_pci_dev();
+ pdev = pci_alloc_dev(NULL);
if (!pdev)
return -ENOMEM;
pdev->vendor = 0xffff;
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 94821ab..bf5d247 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
struct agp_bridge_data *bridge;
int error = 0;
- fake_bridge_dev = alloc_pci_dev();
+ fake_bridge_dev = pci_alloc_dev(NULL);
if (!fake_bridge_dev) {
error = -ENOMEM;
goto fail;
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index c93071d..2652ca0 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -75,18 +75,20 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
struct pci_dev *virtfn;
struct resource *res;
struct pci_sriov *iov = dev->sriov;
+ struct pci_bus *bus;
- virtfn = alloc_pci_dev();
+ virtfn = pci_alloc_dev(NULL);
if (!virtfn)
return -ENOMEM;
mutex_lock(&iov->dev->sriov->lock);
- virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
- if (!virtfn->bus) {
+ bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+ if (!bus) {
kfree(virtfn);
mutex_unlock(&iov->dev->sriov->lock);
return -ENOMEM;
}
+ virtfn->bus = pci_bus_get(bus);
virtfn->devfn = virtfn_devfn(dev, id);
virtfn->vendor = dev->vendor;
pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 26df9c8..d5d18a0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1130,6 +1130,7 @@ static void pci_release_dev(struct device *dev)
struct pci_dev *pci_dev;
pci_dev = to_pci_dev(dev);
+ pci_bus_put(pci_dev->bus);
pci_release_capabilities(pci_dev);
pci_release_of_node(pci_dev);
kfree(pci_dev);
@@ -1269,11 +1270,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
return NULL;
- dev = alloc_pci_dev();
+ dev = pci_alloc_dev(bus);
if (!dev)
return NULL;
- dev->bus = bus;
dev->devfn = devfn;
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
@@ -1281,6 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
pci_set_of_node(dev);
if (pci_setup_device(dev)) {
+ pci_bus_put(dev->bus);
kfree(dev);
return NULL;
}
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 846f475f..90c95a3 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -2026,7 +2026,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
static inline int
make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
{
- *pdev = alloc_pci_dev();
+ *pdev = pci_alloc_dev(NULL);
if( *pdev == NULL ) return -1;
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH 3/4] KVM: PPC: Add support for IOMMU in-kernel handling
From: David Gibson @ 2013-05-25 2:45 UTC (permalink / raw)
To: Scott Wood
Cc: kvm, Alexey Kardashevskiy, linux-kernel, kvm-ppc, Alexander Graf,
Paul Mackerras, linuxppc-dev
In-Reply-To: <1369256817.1374.29@scott-Lenovo-G560>
[-- Attachment #1: Type: text/plain, Size: 3168 bytes --]
On Wed, May 22, 2013 at 04:06:57PM -0500, Scott Wood wrote:
> On 05/20/2013 10:06:46 PM, Alexey Kardashevskiy wrote:
> >diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> >index 8465c2a..da6bf61 100644
> >--- a/arch/powerpc/kvm/powerpc.c
> >@@ -396,6 +396,7 @@ int kvm_dev_ioctl_check_extension(long ext)
> >+++ b/arch/powerpc/kvm/powerpc.c
> > break;
> > #endif
> > case KVM_CAP_SPAPR_MULTITCE:
> >+ case KVM_CAP_SPAPR_TCE_IOMMU:
> > r = 1;
> > break;
> > default:
>
> Don't advertise SPAPR capabilities if it's not book3s -- and
> probably there's some additional limitation that would be
> appropriate.
So, in the case of MULTITCE, that's not quite right. PR KVM can
emulate a PAPR system on a BookE machine, and there's no reason not to
allow TCE acceleration as well. We can't make it dependent on PAPR
mode being selected, because that's enabled per-vcpu, whereas these
capabilities are queried on the VM before the vcpus are created.
CAP_SPAPR_TCE_IOMMU should be dependent on the presence of suitable
host side hardware (i.e. a PAPR style IOMMU), though.
>
> >@@ -1025,6 +1026,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
> > r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
> > goto out;
> > }
> >+ case KVM_CREATE_SPAPR_TCE_IOMMU: {
> >+ struct kvm_create_spapr_tce_iommu create_tce_iommu;
> >+ struct kvm *kvm = filp->private_data;
> >+
> >+ r = -EFAULT;
> >+ if (copy_from_user(&create_tce_iommu, argp,
> >+ sizeof(create_tce_iommu)))
> >+ goto out;
> >+ r = kvm_vm_ioctl_create_spapr_tce_iommu(kvm,
> >&create_tce_iommu);
> >+ goto out;
> >+ }
> > #endif /* CONFIG_PPC_BOOK3S_64 */
> >
> > #ifdef CONFIG_KVM_BOOK3S_64_HV
> >diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> >index 5a2afda..450c82a 100644
> >--- a/include/uapi/linux/kvm.h
> >+++ b/include/uapi/linux/kvm.h
> >@@ -667,6 +667,7 @@ struct kvm_ppc_smmu_info {
> > #define KVM_CAP_PPC_RTAS 91
> > #define KVM_CAP_IRQ_XICS 92
> > #define KVM_CAP_SPAPR_MULTITCE (0x110000 + 89)
> >+#define KVM_CAP_SPAPR_TCE_IOMMU (0x110000 + 90)
>
> Hmm...
Ah, yeah, that needs to be fixed. Those were interim numbers so that
we didn't have to keep changing our internal trees as new upstream
ioctls got added to the list. We need to get a proper number for the
merge, though.
> >@@ -939,6 +940,9 @@ struct kvm_s390_ucas_mapping {
> > #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct
> >kvm_device_attr)
> > #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct
> >kvm_device_attr)
> >
> >+/* ioctl for SPAPR TCE IOMMU */
> >+#define KVM_CREATE_SPAPR_TCE_IOMMU _IOW(KVMIO, 0xe4, struct
> >kvm_create_spapr_tce_iommu)
>
> Shouldn't this go under the vm ioctl section?
>
> -Scott
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH RESEND v2 2/2] serial/mpc52xx_uart: add MPC5125 PSC support
From: Anatolij Gustschin @ 2013-05-24 18:24 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman
Cc: Matteo Facchinetti, Anatolij Gustschin, linuxppc-dev,
Vladimir Ermakov
In-Reply-To: <1369419899-2907-1-git-send-email-agust@denx.de>
From: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
Add MPC5125 PSC register layout structure, MPC5125 specific
psc_ops function set and the compatible string.
Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
Signed-off-by: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes in v2:
- split into two patches to simplify review
- minor coding style changes
- revise commit log
arch/powerpc/include/asm/mpc52xx_psc.h | 49 +++++++
drivers/tty/serial/mpc52xx_uart.c | 241 ++++++++++++++++++++++++++++++++
2 files changed, 290 insertions(+)
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index 2966df6..d0ece25 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -299,4 +299,53 @@ struct mpc512x_psc_fifo {
#define rxdata_32 rxdata.rxdata_32
};
+struct mpc5125_psc {
+ u8 mr1; /* PSC + 0x00 */
+ u8 reserved0[3];
+ u8 mr2; /* PSC + 0x04 */
+ u8 reserved1[3];
+ struct {
+ u16 status; /* PSC + 0x08 */
+ u8 reserved2[2];
+ u8 clock_select; /* PSC + 0x0c */
+ u8 reserved3[3];
+ } sr_csr;
+ u8 command; /* PSC + 0x10 */
+ u8 reserved4[3];
+ union { /* PSC + 0x14 */
+ u8 buffer_8;
+ u16 buffer_16;
+ u32 buffer_32;
+ } buffer;
+ struct {
+ u8 ipcr; /* PSC + 0x18 */
+ u8 reserved5[3];
+ u8 acr; /* PSC + 0x1c */
+ u8 reserved6[3];
+ } ipcr_acr;
+ struct {
+ u16 isr; /* PSC + 0x20 */
+ u8 reserved7[2];
+ u16 imr; /* PSC + 0x24 */
+ u8 reserved8[2];
+ } isr_imr;
+ u8 ctur; /* PSC + 0x28 */
+ u8 reserved9[3];
+ u8 ctlr; /* PSC + 0x2c */
+ u8 reserved10[3];
+ u32 ccr; /* PSC + 0x30 */
+ u32 ac97slots; /* PSC + 0x34 */
+ u32 ac97cmd; /* PSC + 0x38 */
+ u32 ac97data; /* PSC + 0x3c */
+ u8 reserved11[4];
+ u8 ip; /* PSC + 0x44 */
+ u8 reserved12[3];
+ u8 op1; /* PSC + 0x48 */
+ u8 reserved13[3];
+ u8 op0; /* PSC + 0x4c */
+ u8 reserved14[3];
+ u32 sicr; /* PSC + 0x50 */
+ u8 reserved15[4]; /* make eq. sizeof(mpc52xx_psc) */
+};
+
#endif /* __ASM_MPC52xx_PSC_H__ */
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 5aa87ac..9c3eab5 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -658,6 +658,246 @@ static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np)
port->irqflags = IRQF_SHARED;
port->irq = psc_fifoc_irq;
}
+#endif
+
+#ifdef CONFIG_PPC_MPC512x
+
+#define PSC_5125(port) ((struct mpc5125_psc __iomem *)((port)->membase))
+#define FIFO_5125(port) ((struct mpc512x_psc_fifo __iomem *)(PSC_5125(port)+1))
+
+static void mpc5125_psc_fifo_init(struct uart_port *port)
+{
+ /* /32 prescaler */
+ out_8(&PSC_5125(port)->mpc52xx_psc_clock_select, 0xdd);
+
+ out_be32(&FIFO_5125(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
+ out_be32(&FIFO_5125(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
+ out_be32(&FIFO_5125(port)->txalarm, 1);
+ out_be32(&FIFO_5125(port)->tximr, 0);
+
+ out_be32(&FIFO_5125(port)->rxcmd, MPC512x_PSC_FIFO_RESET_SLICE);
+ out_be32(&FIFO_5125(port)->rxcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
+ out_be32(&FIFO_5125(port)->rxalarm, 1);
+ out_be32(&FIFO_5125(port)->rximr, 0);
+
+ out_be32(&FIFO_5125(port)->tximr, MPC512x_PSC_FIFO_ALARM);
+ out_be32(&FIFO_5125(port)->rximr, MPC512x_PSC_FIFO_ALARM);
+}
+
+static int mpc5125_psc_raw_rx_rdy(struct uart_port *port)
+{
+ return !(in_be32(&FIFO_5125(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY);
+}
+
+static int mpc5125_psc_raw_tx_rdy(struct uart_port *port)
+{
+ return !(in_be32(&FIFO_5125(port)->txsr) & MPC512x_PSC_FIFO_FULL);
+}
+
+static int mpc5125_psc_rx_rdy(struct uart_port *port)
+{
+ return in_be32(&FIFO_5125(port)->rxsr) &
+ in_be32(&FIFO_5125(port)->rximr) & MPC512x_PSC_FIFO_ALARM;
+}
+
+static int mpc5125_psc_tx_rdy(struct uart_port *port)
+{
+ return in_be32(&FIFO_5125(port)->txsr) &
+ in_be32(&FIFO_5125(port)->tximr) & MPC512x_PSC_FIFO_ALARM;
+}
+
+static int mpc5125_psc_tx_empty(struct uart_port *port)
+{
+ return in_be32(&FIFO_5125(port)->txsr) & MPC512x_PSC_FIFO_EMPTY;
+}
+
+static void mpc5125_psc_stop_rx(struct uart_port *port)
+{
+ unsigned long rx_fifo_imr;
+
+ rx_fifo_imr = in_be32(&FIFO_5125(port)->rximr);
+ rx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
+ out_be32(&FIFO_5125(port)->rximr, rx_fifo_imr);
+}
+
+static void mpc5125_psc_start_tx(struct uart_port *port)
+{
+ unsigned long tx_fifo_imr;
+
+ tx_fifo_imr = in_be32(&FIFO_5125(port)->tximr);
+ tx_fifo_imr |= MPC512x_PSC_FIFO_ALARM;
+ out_be32(&FIFO_5125(port)->tximr, tx_fifo_imr);
+}
+
+static void mpc5125_psc_stop_tx(struct uart_port *port)
+{
+ unsigned long tx_fifo_imr;
+
+ tx_fifo_imr = in_be32(&FIFO_5125(port)->tximr);
+ tx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
+ out_be32(&FIFO_5125(port)->tximr, tx_fifo_imr);
+}
+
+static void mpc5125_psc_rx_clr_irq(struct uart_port *port)
+{
+ out_be32(&FIFO_5125(port)->rxisr, in_be32(&FIFO_5125(port)->rxisr));
+}
+
+static void mpc5125_psc_tx_clr_irq(struct uart_port *port)
+{
+ out_be32(&FIFO_5125(port)->txisr, in_be32(&FIFO_5125(port)->txisr));
+}
+
+static void mpc5125_psc_write_char(struct uart_port *port, unsigned char c)
+{
+ out_8(&FIFO_5125(port)->txdata_8, c);
+}
+
+static unsigned char mpc5125_psc_read_char(struct uart_port *port)
+{
+ return in_8(&FIFO_5125(port)->rxdata_8);
+}
+
+static void mpc5125_psc_cw_disable_ints(struct uart_port *port)
+{
+ port->read_status_mask =
+ in_be32(&FIFO_5125(port)->tximr) << 16 |
+ in_be32(&FIFO_5125(port)->rximr);
+ out_be32(&FIFO_5125(port)->tximr, 0);
+ out_be32(&FIFO_5125(port)->rximr, 0);
+}
+
+static void mpc5125_psc_cw_restore_ints(struct uart_port *port)
+{
+ out_be32(&FIFO_5125(port)->tximr,
+ (port->read_status_mask >> 16) & 0x7f);
+ out_be32(&FIFO_5125(port)->rximr, port->read_status_mask & 0x7f);
+}
+
+static inline void mpc5125_set_divisor(struct mpc5125_psc __iomem *psc,
+ u8 prescaler, unsigned int divisor)
+{
+ /* select prescaler */
+ out_8(&psc->mpc52xx_psc_clock_select, prescaler);
+ out_8(&psc->ctur, divisor >> 8);
+ out_8(&psc->ctlr, divisor & 0xff);
+}
+
+static unsigned int mpc5125_psc_set_baudrate(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
+{
+ unsigned int baud;
+ unsigned int divisor;
+
+ /*
+ * Calculate with a /16 prescaler here.
+ */
+
+ /* uartclk contains the ips freq */
+ baud = uart_get_baud_rate(port, new, old,
+ port->uartclk / (16 * 0xffff) + 1,
+ port->uartclk / 16);
+ divisor = (port->uartclk + 8 * baud) / (16 * baud);
+
+ /* enable the /16 prescaler and set the divisor */
+ mpc5125_set_divisor(PSC_5125(port), 0xdd, divisor);
+ return baud;
+}
+
+/*
+ * MPC5125 have compatible PSC FIFO Controller.
+ * Special init not needed.
+ */
+static u16 mpc5125_psc_get_status(struct uart_port *port)
+{
+ return in_be16(&PSC_5125(port)->mpc52xx_psc_status);
+}
+
+static u8 mpc5125_psc_get_ipcr(struct uart_port *port)
+{
+ return in_8(&PSC_5125(port)->mpc52xx_psc_ipcr);
+}
+
+static void mpc5125_psc_command(struct uart_port *port, u8 cmd)
+{
+ out_8(&PSC_5125(port)->command, cmd);
+}
+
+static void mpc5125_psc_set_mode(struct uart_port *port, u8 mr1, u8 mr2)
+{
+ out_8(&PSC_5125(port)->mr1, mr1);
+ out_8(&PSC_5125(port)->mr2, mr2);
+}
+
+static void mpc5125_psc_set_rts(struct uart_port *port, int state)
+{
+ if (state & TIOCM_RTS)
+ out_8(&PSC_5125(port)->op1, MPC52xx_PSC_OP_RTS);
+ else
+ out_8(&PSC_5125(port)->op0, MPC52xx_PSC_OP_RTS);
+}
+
+static void mpc5125_psc_enable_ms(struct uart_port *port)
+{
+ struct mpc5125_psc __iomem *psc = PSC_5125(port);
+
+ /* clear D_*-bits by reading them */
+ in_8(&psc->mpc52xx_psc_ipcr);
+ /* enable CTS and DCD as IPC interrupts */
+ out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
+
+ port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+}
+
+static void mpc5125_psc_set_sicr(struct uart_port *port, u32 val)
+{
+ out_be32(&PSC_5125(port)->sicr, val);
+}
+
+static void mpc5125_psc_set_imr(struct uart_port *port, u16 val)
+{
+ out_be16(&PSC_5125(port)->mpc52xx_psc_imr, val);
+}
+
+static u8 mpc5125_psc_get_mr1(struct uart_port *port)
+{
+ return in_8(&PSC_5125(port)->mr1);
+}
+
+static struct psc_ops mpc5125_psc_ops = {
+ .fifo_init = mpc5125_psc_fifo_init,
+ .raw_rx_rdy = mpc5125_psc_raw_rx_rdy,
+ .raw_tx_rdy = mpc5125_psc_raw_tx_rdy,
+ .rx_rdy = mpc5125_psc_rx_rdy,
+ .tx_rdy = mpc5125_psc_tx_rdy,
+ .tx_empty = mpc5125_psc_tx_empty,
+ .stop_rx = mpc5125_psc_stop_rx,
+ .start_tx = mpc5125_psc_start_tx,
+ .stop_tx = mpc5125_psc_stop_tx,
+ .rx_clr_irq = mpc5125_psc_rx_clr_irq,
+ .tx_clr_irq = mpc5125_psc_tx_clr_irq,
+ .write_char = mpc5125_psc_write_char,
+ .read_char = mpc5125_psc_read_char,
+ .cw_disable_ints = mpc5125_psc_cw_disable_ints,
+ .cw_restore_ints = mpc5125_psc_cw_restore_ints,
+ .set_baudrate = mpc5125_psc_set_baudrate,
+ .clock = mpc512x_psc_clock,
+ .fifoc_init = mpc512x_psc_fifoc_init,
+ .fifoc_uninit = mpc512x_psc_fifoc_uninit,
+ .get_irq = mpc512x_psc_get_irq,
+ .handle_irq = mpc512x_psc_handle_irq,
+ .get_status = mpc5125_psc_get_status,
+ .get_ipcr = mpc5125_psc_get_ipcr,
+ .command = mpc5125_psc_command,
+ .set_mode = mpc5125_psc_set_mode,
+ .set_rts = mpc5125_psc_set_rts,
+ .enable_ms = mpc5125_psc_enable_ms,
+ .set_sicr = mpc5125_psc_set_sicr,
+ .set_imr = mpc5125_psc_set_imr,
+ .get_mr1 = mpc5125_psc_get_mr1,
+};
static struct psc_ops mpc512x_psc_ops = {
.fifo_init = mpc512x_psc_fifo_init,
@@ -1381,6 +1621,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
#endif
#ifdef CONFIG_PPC_MPC512x
{ .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
+ { .compatible = "fsl,mpc5125-psc-uart", .data = &mpc5125_psc_ops, },
#endif
{},
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH RESEND v2 1/2] serial/mpc52xx_uart: prepare for adding MPC5125 PSC UART support
From: Anatolij Gustschin @ 2013-05-24 18:24 UTC (permalink / raw)
To: linux-serial, Greg Kroah-Hartman
Cc: Matteo Facchinetti, Anatolij Gustschin, linuxppc-dev,
Vladimir Ermakov
From: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
MPC5125 PSC controller has different register layout than MPC5121.
To support MPC5125 PSC in this driver we have to provide further
psc_ops functions for SoC specific register accesses.
Add new register access functions to the psc_ops structure and
provide MPC52xx and MPC512x specific implementation for them.
Then replace remaining direct register accesses in the driver by
appropriate psc_ops function calls. The subsequent patch can now
add MPC5125 specific set of psc_ops functions.
Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
Signed-off-by: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes in v2:
- split into two patches to simplify review
- minor coding style changes
- revise commit log
drivers/tty/serial/mpc52xx_uart.c | 161 +++++++++++++++++++++++++++----------
1 file changed, 119 insertions(+), 42 deletions(-)
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 018bad9..5aa87ac 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -122,6 +122,15 @@ struct psc_ops {
void (*fifoc_uninit)(void);
void (*get_irq)(struct uart_port *, struct device_node *);
irqreturn_t (*handle_irq)(struct uart_port *port);
+ u16 (*get_status)(struct uart_port *port);
+ u8 (*get_ipcr)(struct uart_port *port);
+ void (*command)(struct uart_port *port, u8 cmd);
+ void (*set_mode)(struct uart_port *port, u8 mr1, u8 mr2);
+ void (*set_rts)(struct uart_port *port, int state);
+ void (*enable_ms)(struct uart_port *port);
+ void (*set_sicr)(struct uart_port *port, u32 val);
+ void (*set_imr)(struct uart_port *port, u16 val);
+ u8 (*get_mr1)(struct uart_port *port);
};
/* setting the prescaler and divisor reg is common for all chips */
@@ -134,6 +143,65 @@ static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc,
out_8(&psc->ctlr, divisor & 0xff);
}
+static u16 mpc52xx_psc_get_status(struct uart_port *port)
+{
+ return in_be16(&PSC(port)->mpc52xx_psc_status);
+}
+
+static u8 mpc52xx_psc_get_ipcr(struct uart_port *port)
+{
+ return in_8(&PSC(port)->mpc52xx_psc_ipcr);
+}
+
+static void mpc52xx_psc_command(struct uart_port *port, u8 cmd)
+{
+ out_8(&PSC(port)->command, cmd);
+}
+
+static void mpc52xx_psc_set_mode(struct uart_port *port, u8 mr1, u8 mr2)
+{
+ out_8(&PSC(port)->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ out_8(&PSC(port)->mode, mr1);
+ out_8(&PSC(port)->mode, mr2);
+}
+
+static void mpc52xx_psc_set_rts(struct uart_port *port, int state)
+{
+ if (state)
+ out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
+ else
+ out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
+}
+
+static void mpc52xx_psc_enable_ms(struct uart_port *port)
+{
+ struct mpc52xx_psc __iomem *psc = PSC(port);
+
+ /* clear D_*-bits by reading them */
+ in_8(&psc->mpc52xx_psc_ipcr);
+ /* enable CTS and DCD as IPC interrupts */
+ out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
+
+ port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+}
+
+static void mpc52xx_psc_set_sicr(struct uart_port *port, u32 val)
+{
+ out_be32(&PSC(port)->sicr, val);
+}
+
+static void mpc52xx_psc_set_imr(struct uart_port *port, u16 val)
+{
+ out_be16(&PSC(port)->mpc52xx_psc_imr, val);
+}
+
+static u8 mpc52xx_psc_get_mr1(struct uart_port *port)
+{
+ out_8(&PSC(port)->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ return in_8(&PSC(port)->mode);
+}
+
#ifdef CONFIG_PPC_MPC52xx
#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
static void mpc52xx_psc_fifo_init(struct uart_port *port)
@@ -304,6 +372,15 @@ static struct psc_ops mpc52xx_psc_ops = {
.set_baudrate = mpc5200_psc_set_baudrate,
.get_irq = mpc52xx_psc_get_irq,
.handle_irq = mpc52xx_psc_handle_irq,
+ .get_status = mpc52xx_psc_get_status,
+ .get_ipcr = mpc52xx_psc_get_ipcr,
+ .command = mpc52xx_psc_command,
+ .set_mode = mpc52xx_psc_set_mode,
+ .set_rts = mpc52xx_psc_set_rts,
+ .enable_ms = mpc52xx_psc_enable_ms,
+ .set_sicr = mpc52xx_psc_set_sicr,
+ .set_imr = mpc52xx_psc_set_imr,
+ .get_mr1 = mpc52xx_psc_get_mr1,
};
static struct psc_ops mpc5200b_psc_ops = {
@@ -325,6 +402,15 @@ static struct psc_ops mpc5200b_psc_ops = {
.set_baudrate = mpc5200b_psc_set_baudrate,
.get_irq = mpc52xx_psc_get_irq,
.handle_irq = mpc52xx_psc_handle_irq,
+ .get_status = mpc52xx_psc_get_status,
+ .get_ipcr = mpc52xx_psc_get_ipcr,
+ .command = mpc52xx_psc_command,
+ .set_mode = mpc52xx_psc_set_mode,
+ .set_rts = mpc52xx_psc_set_rts,
+ .enable_ms = mpc52xx_psc_enable_ms,
+ .set_sicr = mpc52xx_psc_set_sicr,
+ .set_imr = mpc52xx_psc_set_imr,
+ .get_mr1 = mpc52xx_psc_get_mr1,
};
#endif /* CONFIG_MPC52xx */
@@ -595,8 +681,18 @@ static struct psc_ops mpc512x_psc_ops = {
.fifoc_uninit = mpc512x_psc_fifoc_uninit,
.get_irq = mpc512x_psc_get_irq,
.handle_irq = mpc512x_psc_handle_irq,
+ .get_status = mpc52xx_psc_get_status,
+ .get_ipcr = mpc52xx_psc_get_ipcr,
+ .command = mpc52xx_psc_command,
+ .set_mode = mpc52xx_psc_set_mode,
+ .set_rts = mpc52xx_psc_set_rts,
+ .enable_ms = mpc52xx_psc_enable_ms,
+ .set_sicr = mpc52xx_psc_set_sicr,
+ .set_imr = mpc52xx_psc_set_imr,
+ .get_mr1 = mpc52xx_psc_get_mr1,
};
-#endif
+#endif /* CONFIG_PPC_MPC512x */
+
static const struct psc_ops *psc_ops;
@@ -613,17 +709,14 @@ mpc52xx_uart_tx_empty(struct uart_port *port)
static void
mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- if (mctrl & TIOCM_RTS)
- out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
- else
- out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
+ psc_ops->set_rts(port, mctrl & TIOCM_RTS);
}
static unsigned int
mpc52xx_uart_get_mctrl(struct uart_port *port)
{
unsigned int ret = TIOCM_DSR;
- u8 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
+ u8 status = psc_ops->get_ipcr(port);
if (!(status & MPC52xx_PSC_CTS))
ret |= TIOCM_CTS;
@@ -673,15 +766,7 @@ mpc52xx_uart_stop_rx(struct uart_port *port)
static void
mpc52xx_uart_enable_ms(struct uart_port *port)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
-
- /* clear D_*-bits by reading them */
- in_8(&psc->mpc52xx_psc_ipcr);
- /* enable CTS and DCD as IPC interrupts */
- out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
-
- port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
- out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ psc_ops->enable_ms(port);
}
static void
@@ -691,9 +776,9 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
spin_lock_irqsave(&port->lock, flags);
if (ctl == -1)
- out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK);
+ psc_ops->command(port, MPC52xx_PSC_START_BRK);
else
- out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK);
+ psc_ops->command(port, MPC52xx_PSC_STOP_BRK);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -701,7 +786,6 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
static int
mpc52xx_uart_startup(struct uart_port *port)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
int ret;
if (psc_ops->clock) {
@@ -717,15 +801,15 @@ mpc52xx_uart_startup(struct uart_port *port)
return ret;
/* Reset/activate the port, clear and enable interrupts */
- out_8(&psc->command, MPC52xx_PSC_RST_RX);
- out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ psc_ops->command(port, MPC52xx_PSC_RST_RX);
+ psc_ops->command(port, MPC52xx_PSC_RST_TX);
- out_be32(&psc->sicr, 0); /* UART mode DCD ignored */
+ psc_ops->set_sicr(port, 0); /* UART mode DCD ignored */
psc_ops->fifo_init(port);
- out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
- out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_TX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_RX_ENABLE);
return 0;
}
@@ -733,15 +817,13 @@ mpc52xx_uart_startup(struct uart_port *port)
static void
mpc52xx_uart_shutdown(struct uart_port *port)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
-
/* Shut down the port. Leave TX active if on a console port */
- out_8(&psc->command, MPC52xx_PSC_RST_RX);
+ psc_ops->command(port, MPC52xx_PSC_RST_RX);
if (!uart_console(port))
- out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ psc_ops->command(port, MPC52xx_PSC_RST_TX);
port->read_status_mask = 0;
- out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ psc_ops->set_imr(port, port->read_status_mask);
if (psc_ops->clock)
psc_ops->clock(port, 0);
@@ -754,7 +836,6 @@ static void
mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
struct ktermios *old)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned long flags;
unsigned char mr1, mr2;
unsigned int j;
@@ -818,13 +899,11 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
"Some chars may have been lost.\n");
/* Reset the TX & RX */
- out_8(&psc->command, MPC52xx_PSC_RST_RX);
- out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ psc_ops->command(port, MPC52xx_PSC_RST_RX);
+ psc_ops->command(port, MPC52xx_PSC_RST_TX);
/* Send new mode settings */
- out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
- out_8(&psc->mode, mr1);
- out_8(&psc->mode, mr2);
+ psc_ops->set_mode(port, mr1, mr2);
baud = psc_ops->set_baudrate(port, new, old);
/* Update the per-port timeout */
@@ -834,8 +913,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
mpc52xx_uart_enable_ms(port);
/* Reenable TX & RX */
- out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
- out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_TX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_RX_ENABLE);
/* We're all set, release the lock */
spin_unlock_irqrestore(&port->lock, flags);
@@ -963,7 +1042,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
flag = TTY_NORMAL;
port->icount.rx++;
- status = in_be16(&PSC(port)->mpc52xx_psc_status);
+ status = psc_ops->get_status(port);
if (status & (MPC52xx_PSC_SR_PE |
MPC52xx_PSC_SR_FE |
@@ -983,7 +1062,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
}
/* Clear error condition */
- out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT);
+ psc_ops->command(port, MPC52xx_PSC_RST_ERR_STAT);
}
tty_insert_flip_char(tport, ch, flag);
@@ -1066,7 +1145,7 @@ mpc5xxx_uart_process_int(struct uart_port *port)
if (psc_ops->tx_rdy(port))
keepgoing |= mpc52xx_uart_int_tx_chars(port);
- status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
+ status = psc_ops->get_ipcr(port);
if (status & MPC52xx_PSC_D_DCD)
uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD));
@@ -1107,14 +1186,12 @@ static void __init
mpc52xx_console_get_options(struct uart_port *port,
int *baud, int *parity, int *bits, int *flow)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned char mr1;
pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
/* Read the mode registers */
- out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
- mr1 = in_8(&psc->mode);
+ mr1 = psc_ops->get_mr1(port);
/* CT{U,L}R are write-only ! */
*baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v2 1/2] serial/mpc52xx_uart: prepare for adding MPC5125 PSC UART support
From: Greg Kroah-Hartman @ 2013-05-24 17:57 UTC (permalink / raw)
To: Anatolij Gustschin
Cc: Matteo Facchinetti, linuxppc-dev, Vladimir Ermakov, linux-serial
In-Reply-To: <20130524194912.078467c2@crub>
On Fri, May 24, 2013 at 07:49:12PM +0200, Anatolij Gustschin wrote:
> On Wed, 17 Apr 2013 23:21:41 +0200
> Anatolij Gustschin <agust@denx.de> wrote:
>
> > From: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
> >
> > MPC5125 PSC controller has different register layout than MPC5121.
> > To support MPC5125 PSC in this driver we have to provide further
> > psc_ops functions for SoC specific register accesses.
> >
> > Add new register access functions to the psc_ops structure and
> > provide MPC52xx and MPC512x specific implementation for them.
> > Then replace remaining direct register accesses in the driver by
> > appropriate psc_ops function calls. The subsequent patch can now
> > add MPC5125 specific set of psc_ops functions.
> >
> > Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
> > Signed-off-by: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
> > ---
> >
> > Greg, with your Acked-by I can push these patches to my mpc5xxx tree.
> > But it is fine with me if you prefer to apply them to tty tree.
>
> ping ...
Sorry, I somehow lost this, so I can't see the original patch at all.
Care to resend it?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v2 1/2] serial/mpc52xx_uart: prepare for adding MPC5125 PSC UART support
From: Anatolij Gustschin @ 2013-05-24 17:49 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Matteo Facchinetti, linuxppc-dev, Vladimir Ermakov, linux-serial
In-Reply-To: <1366233702-20689-1-git-send-email-agust@denx.de>
On Wed, 17 Apr 2013 23:21:41 +0200
Anatolij Gustschin <agust@denx.de> wrote:
> From: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
>
> MPC5125 PSC controller has different register layout than MPC5121.
> To support MPC5125 PSC in this driver we have to provide further
> psc_ops functions for SoC specific register accesses.
>
> Add new register access functions to the psc_ops structure and
> provide MPC52xx and MPC512x specific implementation for them.
> Then replace remaining direct register accesses in the driver by
> appropriate psc_ops function calls. The subsequent patch can now
> add MPC5125 specific set of psc_ops functions.
>
> Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
> Signed-off-by: Matteo Facchinetti <matteo.facchinetti@sirius-es.it>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> ---
>
> Greg, with your Acked-by I can push these patches to my mpc5xxx tree.
> But it is fine with me if you prefer to apply them to tty tree.
ping ...
Thanks,
Anatolij
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Jason Gunthorpe @ 2013-05-24 17:33 UTC (permalink / raw)
To: Jason Cooper
Cc: Andrew Lunn, netdev, linux-kernel, linux-arm-kernel, linuxppc-dev,
David Miller, Lennert Buytenhek, Sebastian Hesselbarth
In-Reply-To: <20130524164636.GV31290@titan.lakedaemon.net>
On Fri, May 24, 2013 at 12:46:36PM -0400, Jason Cooper wrote:
> > Why are you not keen on this? It seems like normal device driver
> > practice, that is what the data field of of_device_id is typically
> > used for..
>
> I'm not keen on it because we don't have a document saying "All kirkwood
> SoCs need PSC1 set to X after reset." We know it, but have we tested
> the 6282?
I disagree. The manul is very clear how PSC1 must be set for proper
operation. Clk125BypassEn bit is used only for loopback testing, it
should never set for driver operation. Similarly PortReset must be
cleared for driver operation.
It is always safe for the driver to clear these bits, if it knows they
are available. In fact, I would argue the driver should always clear
these bits so that the bootloader isn't relied on to do it. It doesn't
matter if the SOC errantly sets the bit or not, it can *always* be
safely cleared.
Further, I compared my 88F6282/88F6283 manual against the public
88F6180/88F619x/88F6281 spec and confirmed that the PSC1 layout is the
same.
So all of these SOC's can share a driver compatible string.
AFAICT the only reason the driver doesn't touch PSC1 today is because
the PSC1 was introduced in a later IP revision and its presence isn't
auto-detectable.
The last bit of the puzzle to get bootloader independence on kirkwood
is to encode the phy interface type (GMII/RGMII/BASE-X) in the DT so
the entire PSC1 can be set by the driver..
Jason
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Sebastian Hesselbarth @ 2013-05-24 17:25 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Andrew Lunn, Jason Cooper, netdev@vger.kernel.org,
devicetree-discuss@lists.ozlabs.org, linux-kernel@vger.kernel.org,
Jason Gunthorpe, Lennert Buytenhek,
linuxppc-dev@lists.ozlabs.org list, David Miller,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20130524171300.GD18614@n2100.arm.linux.org.uk>
On 05/24/2013 07:13 PM, Russell King - ARM Linux wrote:
> Do you really want that on ARM? Given the fiasco with the location of
> the registers, are you sure you want to place more trust in that
> direction? Does it give you a warm fuzzy feeling to know that you
> might have to work out some way to patch vendor supplied bytecode?
Don't get me wrong. I want mv643xx_eth DT or even platform_data to
evolve to a fully self configured driver not depending on proper u-boot
setup at all.
But I don't want to go that road now and I wonder if it might be safer
for us (and PPC guys) if we start mv643xx_eth over from scratch one day.
For this patch set, I want a basic DT binding that works. Patching the
driver to play with kirkwood loosing the MAC and other important
registers is not my main concern here. If clearing that one bit doesn't
help for all kirkwood boards, I'd rather leave the non-gating
workaround.
mv643xx_eth not knowing DT for ARM is stalling last important bits for
Orion SoCs. I want this to go in first as with David another maintainer
is involved.
Sebastian
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Russell King - ARM Linux @ 2013-05-24 17:13 UTC (permalink / raw)
To: Jason Cooper
Cc: Andrew Lunn, netdev@vger.kernel.org, Linus Walleij,
linux-kernel@vger.kernel.org, David Miller, Jason Gunthorpe,
linux-arm-kernel@lists.infradead.org,
linuxppc-dev@lists.ozlabs.org list,
devicetree-discuss@lists.ozlabs.org, Lennert Buytenhek,
Sebastian Hesselbarth
In-Reply-To: <20130524170125.GX31290@titan.lakedaemon.net>
On Fri, May 24, 2013 at 01:01:25PM -0400, Jason Cooper wrote:
> On Fri, May 24, 2013 at 01:03:25PM +0200, Linus Walleij wrote:
> > IMO: if you want to go down that road, what you really want is not
> > ever more expressible device trees, but real open firmware,
> > or ACPI or UEFI that can interpret and run bytecode as some
> > "bios" for you. With DT coming from OF maybe this is a natural
> > progression of things, but one has to realize when we reach the
> > point where what we really want is a bios. Then your time is
> > likely better spent with Tianocore or something than with the
> > kernel.
>
> shudder. I like embedded systems because the *don't* have a bios.
Then you're into scenarios like I have with my laptop, where - those
of you who check the nightly build results will have noticed - one
of my serial ports doesn't always exist. That's because the ACPI data
in the BIOS is *wrong*. It reports that it has been enabled when it
hasn't, and the disassembled byte code is at fault here.
The fix? God knows. As far as I'm concerned as a user, or even as an
OS developer, it's unfixable without getting the ACPI data structures
changed, and that's not something I can do.
Do you really want that on ARM? Given the fiasco with the location of
the registers, are you sure you want to place more trust in that
direction? Does it give you a warm fuzzy feeling to know that you
might have to work out some way to patch vendor supplied bytecode?
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Jason Cooper @ 2013-05-24 17:03 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, linux-kernel, Jason Gunthorpe, Lennert Buytenhek,
linuxppc-dev, David Miller, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20130524165315.GX26249@lunn.ch>
On Fri, May 24, 2013 at 06:53:15PM +0200, Andrew Lunn wrote:
> > > Why are you not keen on this? It seems like normal device driver
> > > practice, that is what the data field of of_device_id is typically
> > > used for..
> >
> > I'm not keen on it because we don't have a document saying "All kirkwood
> > SoCs need PSC1 set to X after reset." We know it, but have we tested
> > the 6282?
>
> 6282 looses its MAC address, that much i know. I've no idea about
> PSC1, but if its MAC address behaviour is the same as 6281, is expect
> PSC1 is the same.
Do you have a board set up for testing you could try Sebastian's
forthcoming series on (with "marvell,kirkwood-eth")?
thx,
Jason.
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Jason Cooper @ 2013-05-24 17:01 UTC (permalink / raw)
To: Linus Walleij
Cc: Jason Gunthorpe, Andrew Lunn, netdev@vger.kernel.org,
devicetree-discuss@lists.ozlabs.org, linux-kernel@vger.kernel.org,
Lennert Buytenhek, linuxppc-dev@lists.ozlabs.org list,
David Miller, linux-arm-kernel@lists.infradead.org,
Sebastian Hesselbarth
In-Reply-To: <CACRpkdbsicPkPAiaQCOg2mQF2Ce2dg_K=BKqqx=FCdAH7Y+QBg@mail.gmail.com>
On Fri, May 24, 2013 at 01:03:25PM +0200, Linus Walleij wrote:
> On Fri, May 24, 2013 at 12:40 AM, Sebastian Hesselbarth
> <sebastian.hesselbarth@gmail.com> wrote:
> > On 05/23/2013 08:40 PM, Jason Cooper wrote:
>
> >> I think marvell,psc1_reset =<>; gives us the most flexibility in
> >> accurately describing the hardware.
> >
> >
> > IMHO using that is just another workaround for a broken driver. We
> > could hack the whole register setup in DT as it would still accurately
> > describe HW. Don't get me wrong, but I don't like it.
> >
> > Haven't checked how happy Linus Walleij is about pinctrl drivers with
> > reg values hacked in lately.
>
> One of the things I've been ranting about lately is that Linux
> subsystem maintainers have become de-facto device tree
> standard commite chairs. :-(
This is the first I've heard this rant. :(
To that end, I agree with you. My frustration boiled down to trying to
predict the future, which is futile. :-P
For our scenario, once we can confirm our least popular kirkwood
variant, the 6282, behaves the same as we've seen so far, then
"marvell,kirkwood-eth" is fine by me.
> So to the actual question:
>
> In general I think we need to draw a line and define what we
> mean with "describing the hardware" in a device tree.
>
> We have some consensus:
> - <reg> properties to describe regsiter BASE offset in physical
> memory and size.
> - Resources like IRQ, DMA channel, regulator, GPIO pin control
> handles, are passed using <&ersand> notation.
>
> And so it goes on.
>
> When it comes to defining different registers and their individual
> bits and the meaning of these and/or default values, I personally
> think that is making things harder for developers rather than
> simplifying things. I know that pinctrl-single is anyway doing this
> and I was talked into accepting it under circumstances where
> developers are being passed opaque machine-generated
> data that would otherwise be translated into unreadable header
> files littering the kernel.
>
> For a coder it is definately better if the *driver* know these
> details, but whether that is possible seems to depend on things
> like hardware development process.
Agree.
> IMO: if you want to go down that road, what you really want is not
> ever more expressible device trees, but real open firmware,
> or ACPI or UEFI that can interpret and run bytecode as some
> "bios" for you. With DT coming from OF maybe this is a natural
> progression of things, but one has to realize when we reach the
> point where what we really want is a bios. Then your time is
> likely better spent with Tianocore or something than with the
> kernel.
shudder. I like embedded systems because the *don't* have a bios.
thx,
Jason.
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Andrew Lunn @ 2013-05-24 16:53 UTC (permalink / raw)
To: Jason Cooper
Cc: Andrew Lunn, linux-kernel, Jason Gunthorpe, Lennert Buytenhek,
netdev, linuxppc-dev, David Miller, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20130524164636.GV31290@titan.lakedaemon.net>
> > Why are you not keen on this? It seems like normal device driver
> > practice, that is what the data field of of_device_id is typically
> > used for..
>
> I'm not keen on it because we don't have a document saying "All kirkwood
> SoCs need PSC1 set to X after reset." We know it, but have we tested
> the 6282?
6282 looses its MAC address, that much i know. I've no idea about
PSC1, but if its MAC address behaviour is the same as 6281, is expect
PSC1 is the same.
Andrew
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Jason Cooper @ 2013-05-24 16:53 UTC (permalink / raw)
To: Sebastian Hesselbarth
Cc: Andrew Lunn, linux-kernel, Jason Gunthorpe, Lennert Buytenhek,
netdev, linuxppc-dev, David Miller, linux-arm-kernel
In-Reply-To: <519E9ADA.3040204@gmail.com>
On Fri, May 24, 2013 at 12:40:26AM +0200, Sebastian Hesselbarth wrote:
> On 05/23/2013 08:40 PM, Jason Cooper wrote:
> >On Thu, May 23, 2013 at 11:53:57AM -0600, Jason Gunthorpe wrote:
> >>On Thu, May 23, 2013 at 01:23:39PM -0400, Jason Cooper wrote:
> >>>Shouldn't it rather be
> >>>
> >>> compatible = "marvell,kirkwood-eth", "marvell,orion-eth";
> >>
> >>Not sure about orion-eth?
Sorry, yep, one or the other.
> Jason, Jason,
For a second, I read this as "tsk tsk tsk..." ;-)
> sorry I didn't came back to this conversation earlier. I already
> reworked the patch to rely on
> of_device_is_compatible(.."marvell,kirkwood-eth"..). This is a
> kirkwood only thing as other Orions cannot do clock gating or
> retain critcal register content (Dove). I will stick with orion-eth
> for all other and maybe introduce new compatible strings (and new
> fixes) as soon as issues surface.
Okay, as I mentioned to Jason, I would like to test 6282 before we
settle on this path. Other than that, I'm fine with it.
> >>>I'm inclined to go with of_machine_is_compatible() since the only
> >>>concrete difference we know is that the tweak is needed on kirkwood and
> >>>nowhere else.
> >>
> >>But there is a larger problem here then just this one bit.
> >>
> >>The PSC1 register must be set properly for the board layout, and today
> >>we rely on the bootloader to set it. In fact, even with Sebastian's
> >>change the ethernet port won't work without bootloader
> >>intervention. The PortReset bit should also be cleared by the driver
> >>(and it is only present on some variants of this IP block,
> >>apparently).
>
> Actually, fixing modular scenarios is only for the sake of multiarch
> someday. I don't see the point in running current kernel without eth
> compiled in _on a NAS SoC_ ;)
Good point, but if the eth can be gated to save power, we shouldn't
limit the user's ability just because the SoC is primarily in NAS's.
thx,
Jason.
^ permalink raw reply
* Re: [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs
From: Jason Cooper @ 2013-05-24 16:46 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Andrew Lunn, linux-kernel, Lennert Buytenhek, netdev,
linuxppc-dev, David Miller, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20130523190140.GA4010@obsidianresearch.com>
On Thu, May 23, 2013 at 01:01:40PM -0600, Jason Gunthorpe wrote:
> On Thu, May 23, 2013 at 02:40:28PM -0400, Jason Cooper wrote:
>
> > > But there is a larger problem here then just this one bit.
> > >
> > > The PSC1 register must be set properly for the board layout, and today
> > > we rely on the bootloader to set it. In fact, even with Sebastian's
> > > change the ethernet port won't work without bootloader
> > > intervention. The PortReset bit should also be cleared by the driver
> > > (and it is only present on some variants of this IP block,
> > > apparently).
> > >
> > > We know that some Marvell SOC's wack the ethernet registers when they
> > > clock gate, and the flip of Clk125Bypass is another symptom of this
> > > general problem.
> > >
> > > So, long term, the PSC1 must be fully set by the driver, based on DT
> > > information describing the board (eg RGMII/MII/1000Base-X [SFP] Phy
> > > type), and the layout of this register seems to vary on a SOC by SOC
> > > basis.
> > >
> > > Thus, I think it is appropriate to call this variant of the eth IP
> > > 'marvell,kirkwood-eth' which indicates that the register block follows
> > > the kirkwood manual and the PSC1 register specifically has the
> > > kirkwood layout.
> >
> > Ok, so mv643xx_eth would match both "marvell,orion-eth" and
> > "marvell,kirkwood-eth", then write to PSC1 iff it sees a node matching
> > "marvell,kirkwood-eth". I'm not too keen on that, however, the matching
> > of the machine doesn't look to good, either.
>
> Why are you not keen on this? It seems like normal device driver
> practice, that is what the data field of of_device_id is typically
> used for..
I'm not keen on it because we don't have a document saying "All kirkwood
SoCs need PSC1 set to X after reset." We know it, but have we tested
the 6282?
That being said, if "marvell,kirkwood-eth" is the best we can do for
now, I'm all for it. I would just like to be reasonably certain that
the binding we are creating doesn't lock us into a difficult decision
later.
> There are more compatible strings than just kirkwood and orion in this
> driver, the whole TX_BW_CONTROL_OLD_LAYOUT/TX_BW_CONTROL_NEW_LAYOUT
> buisness (affecting PPC/MIPS) should also someday be captured with
> compatible strings rather than auto-detection too..
Agreed.
> > > The question is what other Marvell SOCs have the same PSC1 layout as
> > > kirkwood?
> >
> > I think marvell,psc1_reset = <>; gives us the most flexibility in
> > accurately describing the hardware.
>
> Agree, providing psc1_reset value is a good idea to setup the phy
> modes. If all 'orion' SOCs have the PSC1 value then we don't need the
> kirkwood differentiators, especially if things like the reset bit are
> in the same place.
>
> The same trick Sebastian used to capture the mac address could be used
> to capture the PSC1 value from the bootloader.
>
> Basically, I think any IP variants that have idential register layouts
> can share a compatible string, otherwise different layouts need
> different compatible strings, so the general format:
>
> compatible = "marvell,SOCNAME-eth", "marvell,<something>-eth";
>
> Seems very sane to me. At least this way if we discover more changes
> then the driver can match on the SOCNAME compatible string to find
> them.
After glancing a LinusW's email, I'm thinking this isn't the correct
path. I'll write more in my response to him.
thx,
Jason.
^ permalink raw reply
* [PATCH v3 07/11] powerpc: uaccess s/might_sleep/might_fault/
From: Michael S. Tsirkin @ 2013-05-24 14:18 UTC (permalink / raw)
To: linux-kernel; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <cover.1368702323.git.mst@redhat.com>
The only reason uaccess routines might sleep
is if they fault. Make this explicit.
Arnd Bergmann suggested that the following code
if (!is_kernel_addr((unsigned long)__pu_addr))
might_fault();
can be further simplified by adding a version of might_fault
that includes the kernel addr check.
Will be considered as a further optimization in future.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
arch/powerpc/include/asm/uaccess.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 4db4959..9485b43 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -178,7 +178,7 @@ do { \
long __pu_err; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
if (!is_kernel_addr((unsigned long)__pu_addr)) \
- might_sleep(); \
+ might_fault(); \
__chk_user_ptr(ptr); \
__put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
@@ -188,7 +188,7 @@ do { \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- might_sleep(); \
+ might_fault(); \
if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
__put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
@@ -268,7 +268,7 @@ do { \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
if (!is_kernel_addr((unsigned long)__gu_addr)) \
- might_sleep(); \
+ might_fault(); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
@@ -282,7 +282,7 @@ do { \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
if (!is_kernel_addr((unsigned long)__gu_addr)) \
- might_sleep(); \
+ might_fault(); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
@@ -294,7 +294,7 @@ do { \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- might_sleep(); \
+ might_fault(); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
@@ -419,14 +419,14 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to,
static inline unsigned long __copy_from_user(void *to,
const void __user *from, unsigned long size)
{
- might_sleep();
+ might_fault();
return __copy_from_user_inatomic(to, from, size);
}
static inline unsigned long __copy_to_user(void __user *to,
const void *from, unsigned long size)
{
- might_sleep();
+ might_fault();
return __copy_to_user_inatomic(to, from, size);
}
@@ -434,7 +434,7 @@ extern unsigned long __clear_user(void __user *addr, unsigned long size);
static inline unsigned long clear_user(void __user *addr, unsigned long size)
{
- might_sleep();
+ might_fault();
if (likely(access_ok(VERIFY_WRITE, addr, size)))
return __clear_user(addr, size);
if ((unsigned long)addr < TASK_SIZE) {
--
MST
^ permalink raw reply related
* Re: [PATCH 3/3] powerpc/vfio: Enable on pSeries platform
From: Alex Williamson @ 2013-05-24 14:03 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: kvm, linux-kernel, Paul Mackerras, linuxppc-dev, David Gibson
In-Reply-To: <1369107191-28547-4-git-send-email-aik@ozlabs.ru>
On Tue, 2013-05-21 at 13:33 +1000, Alexey Kardashevskiy wrote:
> The enables VFIO on the pSeries platform, enabling user space
> programs to access PCI devices directly.
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> Cc: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
> ---
> arch/powerpc/platforms/pseries/iommu.c | 4 ++++
> drivers/iommu/Kconfig | 2 +-
> drivers/vfio/Kconfig | 2 +-
> 3 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
> index 86ae364..23fc1dc 100644
> --- a/arch/powerpc/platforms/pseries/iommu.c
> +++ b/arch/powerpc/platforms/pseries/iommu.c
> @@ -614,6 +614,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
>
> iommu_table_setparms(pci->phb, dn, tbl);
> pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
> + iommu_register_group(tbl, pci_domain_nr(bus), 0);
>
> /* Divide the rest (1.75GB) among the children */
> pci->phb->dma_window_size = 0x80000000ul;
> @@ -658,6 +659,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
> ppci->phb->node);
> iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
> ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
> + iommu_register_group(tbl, pci_domain_nr(bus), 0);
> pr_debug(" created table: %p\n", ppci->iommu_table);
> }
> }
> @@ -684,6 +686,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
> phb->node);
> iommu_table_setparms(phb, dn, tbl);
> PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
> + iommu_register_group(tbl, pci_domain_nr(phb->bus), 0);
> set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
> return;
> }
> @@ -1184,6 +1187,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
> pci->phb->node);
> iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
> pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
> + iommu_register_group(tbl, pci_domain_nr(pci->phb->bus), 0);
> pr_debug(" created table: %p\n", pci->iommu_table);
> } else {
> pr_debug(" found DMA window, table: %p\n", pci->iommu_table);
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 3f3abde..01730b2 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -263,7 +263,7 @@ config SHMOBILE_IOMMU_L1SIZE
>
> config SPAPR_TCE_IOMMU
> bool "sPAPR TCE IOMMU Support"
> - depends on PPC_POWERNV
> + depends on PPC_POWERNV || PPC_PSERIES
> select IOMMU_API
> help
> Enables bits of IOMMU API required by VFIO. The iommu_ops
> diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
> index b464687..26b3d9d 100644
> --- a/drivers/vfio/Kconfig
> +++ b/drivers/vfio/Kconfig
> @@ -12,7 +12,7 @@ menuconfig VFIO
> tristate "VFIO Non-Privileged userspace driver framework"
> depends on IOMMU_API
> select VFIO_IOMMU_TYPE1 if X86
> - select VFIO_IOMMU_SPAPR_TCE if PPC_POWERNV
> + select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)
> help
> VFIO provides a framework for secure userspace device drivers.
> See Documentation/vfio.txt for more details.
^ permalink raw reply
* Re: [PATCH 2/3] powerpc/vfio: Implement IOMMU driver for VFIO
From: Alex Williamson @ 2013-05-24 14:03 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: kvm, linux-kernel, Paul Mackerras, linuxppc-dev, David Gibson
In-Reply-To: <1369107191-28547-3-git-send-email-aik@ozlabs.ru>
On Tue, 2013-05-21 at 13:33 +1000, Alexey Kardashevskiy wrote:
> VFIO implements platform independent stuff such as
> a PCI driver, BAR access (via read/write on a file descriptor
> or direct mapping when possible) and IRQ signaling.
>
> The platform dependent part includes IOMMU initialization
> and handling. This implements an IOMMU driver for VFIO
> which does mapping/unmapping pages for the guest IO and
> provides information about DMA window (required by a POWER
> guest).
>
> Cc: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
> ---
> Documentation/vfio.txt | 63 ++++++
> drivers/vfio/Kconfig | 6 +
> drivers/vfio/Makefile | 1 +
> drivers/vfio/vfio.c | 1 +
> drivers/vfio/vfio_iommu_spapr_tce.c | 377 +++++++++++++++++++++++++++++++++++
> include/uapi/linux/vfio.h | 34 ++++
> 6 files changed, 482 insertions(+)
> create mode 100644 drivers/vfio/vfio_iommu_spapr_tce.c
>
> diff --git a/Documentation/vfio.txt b/Documentation/vfio.txt
> index 8eda363..c55533c 100644
> --- a/Documentation/vfio.txt
> +++ b/Documentation/vfio.txt
> @@ -283,6 +283,69 @@ a direct pass through for VFIO_DEVICE_* ioctls. The read/write/mmap
> interfaces implement the device region access defined by the device's
> own VFIO_DEVICE_GET_REGION_INFO ioctl.
>
> +
> +PPC64 sPAPR implementation note
> +-------------------------------------------------------------------------------
> +
> +This implementation has some specifics:
> +
> +1) Only one IOMMU group per container is supported as an IOMMU group
> +represents the minimal entity which isolation can be guaranteed for and
> +groups are allocated statically, one per a Partitionable Endpoint (PE)
> +(PE is often a PCI domain but not always).
> +
> +2) The hardware supports so called DMA windows - the PCI address range
> +within which DMA transfer is allowed, any attempt to access address space
> +out of the window leads to the whole PE isolation.
> +
> +3) PPC64 guests are paravirtualized but not fully emulated. There is an API
> +to map/unmap pages for DMA, and it normally maps 1..32 pages per call and
> +currently there is no way to reduce the number of calls. In order to make things
> +faster, the map/unmap handling has been implemented in real mode which provides
> +an excellent performance which has limitations such as inability to do
> +locked pages accounting in real time.
> +
> +So 3 additional ioctls have been added:
> +
> + VFIO_IOMMU_SPAPR_TCE_GET_INFO - returns the size and the start
> + of the DMA window on the PCI bus.
> +
> + VFIO_IOMMU_ENABLE - enables the container. The locked pages accounting
> + is done at this point. This lets user first to know what
> + the DMA window is and adjust rlimit before doing any real job.
> +
> + VFIO_IOMMU_DISABLE - disables the container.
> +
> +
> +The code flow from the example above should be slightly changed:
> +
> + .....
> + /* Add the group to the container */
> + ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
> +
> + /* Enable the IOMMU model we want */
> + ioctl(container, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU)
> +
> + /* Get addition sPAPR IOMMU info */
> + vfio_iommu_spapr_tce_info spapr_iommu_info;
> + ioctl(container, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &spapr_iommu_info);
> +
> + if (ioctl(container, VFIO_IOMMU_ENABLE))
> + /* Cannot enable container, may be low rlimit */
> +
> + /* Allocate some space and setup a DMA mapping */
> + dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
> + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
> +
> + dma_map.size = 1024 * 1024;
> + dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
> + dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
> +
> + /* Check here is .iova/.size are within DMA window from spapr_iommu_info */
> +
> + ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
> + .....
> +
> -------------------------------------------------------------------------------
>
> [1] VFIO was originally an acronym for "Virtual Function I/O" in its
> diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
> index 7cd5dec..b464687 100644
> --- a/drivers/vfio/Kconfig
> +++ b/drivers/vfio/Kconfig
> @@ -3,10 +3,16 @@ config VFIO_IOMMU_TYPE1
> depends on VFIO
> default n
>
> +config VFIO_IOMMU_SPAPR_TCE
> + tristate
> + depends on VFIO && SPAPR_TCE_IOMMU
> + default n
> +
> menuconfig VFIO
> tristate "VFIO Non-Privileged userspace driver framework"
> depends on IOMMU_API
> select VFIO_IOMMU_TYPE1 if X86
> + select VFIO_IOMMU_SPAPR_TCE if PPC_POWERNV
> help
> VFIO provides a framework for secure userspace device drivers.
> See Documentation/vfio.txt for more details.
> diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile
> index 2398d4a..72bfabc 100644
> --- a/drivers/vfio/Makefile
> +++ b/drivers/vfio/Makefile
> @@ -1,3 +1,4 @@
> obj-$(CONFIG_VFIO) += vfio.o
> obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
> +obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
> obj-$(CONFIG_VFIO_PCI) += pci/
> diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
> index 295c48f..a819604 100644
> --- a/drivers/vfio/vfio.c
> +++ b/drivers/vfio/vfio.c
> @@ -1428,6 +1428,7 @@ static int __init vfio_init(void)
> * drivers.
> */
> request_module_nowait("vfio_iommu_type1");
> + request_module_nowait("vfio_iommu_spapr_tce");
>
> return 0;
>
> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
> new file mode 100644
> index 0000000..bdae7a0
> --- /dev/null
> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
> @@ -0,0 +1,377 @@
> +/*
> + * VFIO: IOMMU DMA mapping support for TCE on POWER
> + *
> + * Copyright (C) 2013 IBM Corp. All rights reserved.
> + * Author: Alexey Kardashevskiy <aik@ozlabs.ru>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Derived from original vfio_iommu_type1.c:
> + * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
> + * Author: Alex Williamson <alex.williamson@redhat.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +#include <linux/slab.h>
> +#include <linux/uaccess.h>
> +#include <linux/err.h>
> +#include <linux/vfio.h>
> +#include <asm/iommu.h>
> +#include <asm/tce.h>
> +
> +#define DRIVER_VERSION "0.1"
> +#define DRIVER_AUTHOR "aik@ozlabs.ru"
> +#define DRIVER_DESC "VFIO IOMMU SPAPR TCE"
> +
> +static void tce_iommu_detach_group(void *iommu_data,
> + struct iommu_group *iommu_group);
> +
> +/*
> + * VFIO IOMMU fd for SPAPR_TCE IOMMU implementation
> + *
> + * This code handles mapping and unmapping of user data buffers
> + * into DMA'ble space using the IOMMU
> + */
> +
> +/*
> + * The container descriptor supports only a single group per container.
> + * Required by the API as the container is not supplied with the IOMMU group
> + * at the moment of initialization.
> + */
> +struct tce_container {
> + struct mutex lock;
> + struct iommu_table *tbl;
> + bool enabled;
> +};
> +
> +static int tce_iommu_enable(struct tce_container *container)
> +{
> + int ret = 0;
> + unsigned long locked, lock_limit, npages;
> + struct iommu_table *tbl = container->tbl;
> +
> + if (!container->tbl)
> + return -ENXIO;
> +
> + if (!current->mm)
> + return -ESRCH; /* process exited */
> +
> + if (container->enabled)
> + return -EBUSY;
> +
> + /*
> + * When userspace pages are mapped into the IOMMU, they are effectively
> + * locked memory, so, theoretically, we need to update the accounting
> + * of locked pages on each map and unmap. For powerpc, the map unmap
> + * paths can be very hot, though, and the accounting would kill
> + * performance, especially since it would be difficult to impossible
> + * to handle the accounting in real mode only.
> + *
> + * To address that, rather than precisely accounting every page, we
> + * instead account for a worst case on locked memory when the iommu is
> + * enabled and disabled. The worst case upper bound on locked memory
> + * is the size of the whole iommu window, which is usually relatively
> + * small (compared to total memory sizes) on POWER hardware.
> + *
> + * Also we don't have a nice way to fail on H_PUT_TCE due to ulimits,
> + * that would effectively kill the guest at random points, much better
> + * enforcing the limit based on the max that the guest can map.
> + */
> + down_write(¤t->mm->mmap_sem);
> + npages = (tbl->it_size << IOMMU_PAGE_SHIFT) >> PAGE_SHIFT;
> + locked = current->mm->locked_vm + npages;
> + lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
> + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) {
> + pr_warn("RLIMIT_MEMLOCK (%ld) exceeded\n",
> + rlimit(RLIMIT_MEMLOCK));
> + ret = -ENOMEM;
> + } else {
> +
> + current->mm->locked_vm += npages;
> + container->enabled = true;
> + }
> + up_write(¤t->mm->mmap_sem);
> +
> + return ret;
> +}
> +
> +static void tce_iommu_disable(struct tce_container *container)
> +{
> + if (!container->enabled)
> + return;
> +
> + container->enabled = false;
> +
> + if (!container->tbl || !current->mm)
> + return;
> +
> + down_write(¤t->mm->mmap_sem);
> + current->mm->locked_vm -= (container->tbl->it_size <<
> + IOMMU_PAGE_SHIFT) >> PAGE_SHIFT;
> + up_write(¤t->mm->mmap_sem);
> +}
> +
> +static void *tce_iommu_open(unsigned long arg)
> +{
> + struct tce_container *container;
> +
> + if (arg != VFIO_SPAPR_TCE_IOMMU) {
> + pr_err("tce_vfio: Wrong IOMMU type\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + container = kzalloc(sizeof(*container), GFP_KERNEL);
> + if (!container)
> + return ERR_PTR(-ENOMEM);
> +
> + mutex_init(&container->lock);
> +
> + return container;
> +}
> +
> +static void tce_iommu_release(void *iommu_data)
> +{
> + struct tce_container *container = iommu_data;
> +
> + WARN_ON(container->tbl && !container->tbl->it_group);
> + tce_iommu_disable(container);
> +
> + if (container->tbl && container->tbl->it_group)
> + tce_iommu_detach_group(iommu_data, container->tbl->it_group);
> +
> + mutex_destroy(&container->lock);
> +
> + kfree(container);
> +}
> +
> +static long tce_iommu_ioctl(void *iommu_data,
> + unsigned int cmd, unsigned long arg)
> +{
> + struct tce_container *container = iommu_data;
> + unsigned long minsz;
> + long ret;
> +
> + switch (cmd) {
> + case VFIO_CHECK_EXTENSION:
> + return (arg == VFIO_SPAPR_TCE_IOMMU) ? 1 : 0;
> +
> + case VFIO_IOMMU_SPAPR_TCE_GET_INFO: {
> + struct vfio_iommu_spapr_tce_info info;
> + struct iommu_table *tbl = container->tbl;
> +
> + if (WARN_ON(!tbl))
> + return -ENXIO;
> +
> + minsz = offsetofend(struct vfio_iommu_spapr_tce_info,
> + dma32_window_size);
> +
> + if (copy_from_user(&info, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (info.argsz < minsz)
> + return -EINVAL;
> +
> + info.dma32_window_start = tbl->it_offset << IOMMU_PAGE_SHIFT;
> + info.dma32_window_size = tbl->it_size << IOMMU_PAGE_SHIFT;
> + info.flags = 0;
> +
> + if (copy_to_user((void __user *)arg, &info, minsz))
> + return -EFAULT;
> +
> + return 0;
> + }
> + case VFIO_IOMMU_MAP_DMA: {
> + struct vfio_iommu_type1_dma_map param;
> + struct iommu_table *tbl = container->tbl;
> + unsigned long tce, i;
> +
> + if (!tbl)
> + return -ENXIO;
> +
> + BUG_ON(!tbl->it_group);
> +
> + minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
> +
> + if (copy_from_user(¶m, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (param.argsz < minsz)
> + return -EINVAL;
> +
> + if (param.flags & ~(VFIO_DMA_MAP_FLAG_READ |
> + VFIO_DMA_MAP_FLAG_WRITE))
> + return -EINVAL;
> +
> + if ((param.size & ~IOMMU_PAGE_MASK) ||
> + (param.vaddr & ~IOMMU_PAGE_MASK))
> + return -EINVAL;
> +
> + /* iova is checked by the IOMMU API */
> + tce = param.vaddr;
> + if (param.flags & VFIO_DMA_MAP_FLAG_READ)
> + tce |= TCE_PCI_READ;
> + if (param.flags & VFIO_DMA_MAP_FLAG_WRITE)
> + tce |= TCE_PCI_WRITE;
> +
> + ret = iommu_tce_put_param_check(tbl, param.iova, tce);
> + if (ret)
> + return ret;
> +
> + for (i = 0; i < (param.size >> IOMMU_PAGE_SHIFT); ++i) {
> + ret = iommu_put_tce_user_mode(tbl,
> + (param.iova >> IOMMU_PAGE_SHIFT) + i,
> + tce);
> + if (ret)
> + break;
> + tce += IOMMU_PAGE_SIZE;
> + }
> + if (ret)
> + iommu_clear_tces_and_put_pages(tbl,
> + param.iova >> IOMMU_PAGE_SHIFT, i);
> +
> + iommu_flush_tce(tbl);
> +
> + return ret;
> + }
> + case VFIO_IOMMU_UNMAP_DMA: {
> + struct vfio_iommu_type1_dma_unmap param;
> + struct iommu_table *tbl = container->tbl;
> +
> + if (WARN_ON(!tbl))
> + return -ENXIO;
> +
> + minsz = offsetofend(struct vfio_iommu_type1_dma_unmap,
> + size);
> +
> + if (copy_from_user(¶m, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (param.argsz < minsz)
> + return -EINVAL;
> +
> + /* No flag is supported now */
> + if (param.flags)
> + return -EINVAL;
> +
> + if (param.size & ~IOMMU_PAGE_MASK)
> + return -EINVAL;
> +
> + ret = iommu_tce_clear_param_check(tbl, param.iova, 0,
> + param.size >> IOMMU_PAGE_SHIFT);
> + if (ret)
> + return ret;
> +
> + ret = iommu_clear_tces_and_put_pages(tbl,
> + param.iova >> IOMMU_PAGE_SHIFT,
> + param.size >> IOMMU_PAGE_SHIFT);
> + iommu_flush_tce(tbl);
> +
> + return ret;
> + }
> + case VFIO_IOMMU_ENABLE:
> + mutex_lock(&container->lock);
> + ret = tce_iommu_enable(container);
> + mutex_unlock(&container->lock);
> + return ret;
> +
> +
> + case VFIO_IOMMU_DISABLE:
> + mutex_lock(&container->lock);
> + tce_iommu_disable(container);
> + mutex_unlock(&container->lock);
> + return 0;
> + }
> +
> + return -ENOTTY;
> +}
> +
> +static int tce_iommu_attach_group(void *iommu_data,
> + struct iommu_group *iommu_group)
> +{
> + int ret;
> + struct tce_container *container = iommu_data;
> + struct iommu_table *tbl = iommu_group_get_iommudata(iommu_group);
> +
> + BUG_ON(!tbl);
> + mutex_lock(&container->lock);
> +
> + /* pr_debug("tce_vfio: Attaching group #%u to iommu %p\n",
> + iommu_group_id(iommu_group), iommu_group); */
> + if (container->tbl) {
> + pr_warn("tce_vfio: Only one group per IOMMU container is allowed, existing id=%d, attaching id=%d\n",
> + iommu_group_id(container->tbl->it_group),
> + iommu_group_id(iommu_group));
> + ret = -EBUSY;
> + } else if (container->enabled) {
> + pr_err("tce_vfio: attaching group #%u to enabled container\n",
> + iommu_group_id(iommu_group));
> + ret = -EBUSY;
> + } else {
> + ret = iommu_take_ownership(tbl);
> + if (!ret)
> + container->tbl = tbl;
> + }
> +
> + mutex_unlock(&container->lock);
> +
> + return ret;
> +}
> +
> +static void tce_iommu_detach_group(void *iommu_data,
> + struct iommu_group *iommu_group)
> +{
> + struct tce_container *container = iommu_data;
> + struct iommu_table *tbl = iommu_group_get_iommudata(iommu_group);
> +
> + BUG_ON(!tbl);
> + mutex_lock(&container->lock);
> + if (tbl != container->tbl) {
> + pr_warn("tce_vfio: detaching group #%u, expected group is #%u\n",
> + iommu_group_id(iommu_group),
> + iommu_group_id(tbl->it_group));
> + } else {
> + if (container->enabled) {
> + pr_warn("tce_vfio: detaching group #%u from enabled container, forcing disable\n",
> + iommu_group_id(tbl->it_group));
> + tce_iommu_disable(container);
> + }
> +
> + /* pr_debug("tce_vfio: detaching group #%u from iommu %p\n",
> + iommu_group_id(iommu_group), iommu_group); */
> + container->tbl = NULL;
> + iommu_release_ownership(tbl);
> + }
> + mutex_unlock(&container->lock);
> +}
> +
> +const struct vfio_iommu_driver_ops tce_iommu_driver_ops = {
> + .name = "iommu-vfio-powerpc",
> + .owner = THIS_MODULE,
> + .open = tce_iommu_open,
> + .release = tce_iommu_release,
> + .ioctl = tce_iommu_ioctl,
> + .attach_group = tce_iommu_attach_group,
> + .detach_group = tce_iommu_detach_group,
> +};
> +
> +static int __init tce_iommu_init(void)
> +{
> + return vfio_register_iommu_driver(&tce_iommu_driver_ops);
> +}
> +
> +static void __exit tce_iommu_cleanup(void)
> +{
> + vfio_unregister_iommu_driver(&tce_iommu_driver_ops);
> +}
> +
> +module_init(tce_iommu_init);
> +module_exit(tce_iommu_cleanup);
> +
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR(DRIVER_AUTHOR);
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 284ff24..87ee4f4 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -22,6 +22,7 @@
> /* Extensions */
>
> #define VFIO_TYPE1_IOMMU 1
> +#define VFIO_SPAPR_TCE_IOMMU 2
>
> /*
> * The IOCTL interface is designed for extensibility by embedding the
> @@ -375,4 +376,37 @@ struct vfio_iommu_type1_dma_unmap {
>
> #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
>
> +/*
> + * IOCTLs to enable/disable IOMMU container usage.
> + * No parameters are supported.
> + */
> +#define VFIO_IOMMU_ENABLE _IO(VFIO_TYPE, VFIO_BASE + 15)
> +#define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16)
> +
> +/* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */
> +
> +/*
> + * The SPAPR TCE info struct provides the information about the PCI bus
> + * address ranges available for DMA, these values are programmed into
> + * the hardware so the guest has to know that information.
> + *
> + * The DMA 32 bit window start is an absolute PCI bus address.
> + * The IOVA address passed via map/unmap ioctls are absolute PCI bus
> + * addresses too so the window works as a filter rather than an offset
> + * for IOVA addresses.
> + *
> + * A flag will need to be added if other page sizes are supported,
> + * so as defined here, it is always 4k.
> + */
> +struct vfio_iommu_spapr_tce_info {
> + __u32 argsz;
> + __u32 flags; /* reserved for future use */
> + __u32 dma32_window_start; /* 32 bit window start (bytes) */
> + __u32 dma32_window_size; /* 32 bit window size (bytes) */
> +};
> +
> +#define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
> +
> +/* ***************************************************************** */
> +
> #endif /* _UAPIVFIO_H */
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox