* [PATCH V5 2/4] DRIVERS: IRQCHIP: CROSSBAR: Add support for Crossbar IP
From: Thomas Gleixner @ 2014-02-04 16:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52EF7D85.5070705@ti.com>
On Mon, 3 Feb 2014, Sricharan R wrote:
> > I already have your reviewed-by tag for the first patch in this series.
> >
> > Kevin was pointing out that irqchip maintainer tag is needed for this patch as well
> > to be merged. We are planning to take this series through arm-soc tree.
> >
> > Can i please have your tag for this patch as well ?
Acked-by-me
^ permalink raw reply
* [RFC/RFT 1/2] ARM: mm: introduce arch hooks for dma address translation routines
From: Arnd Bergmann @ 2014-02-04 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391470107-15927-2-git-send-email-santosh.shilimkar@ti.com>
On Tuesday 04 February 2014, Santosh Shilimkar wrote:
> Currently arch specific DMA address translation routines can be enabled
> using only defines which makes impossible to use them in with
> multi-platform builds.
>
> Hence, introduce arch specific hooks for DMA address translations
> routines to be compatible with multi-platform builds:
> dma_addr_t (*arch_pfn_to_dma)(struct device *dev, unsigned long pfn);
> unsigned long (*arch_dma_to_pfn)(struct device *dev, dma_addr_t addr);
> void* (*arch_dma_to_virt)(struct device *dev, dma_addr_t addr);
> dma_addr_t (*arch_virt_to_dma)(struct device *dev, void *addr);
>
> In case if architecture won't use it - DMA address translation routines
> will fall-back to existing implementation.
> v
> Also, modify machines omap1, ks8695, iop13xx to use new DMA hooks.
I think this is going into a wrong direction. DMA translation is not
at all a platform-specific thing, but rather bus specific. The most
common scenario is that you have some 64-bit capable buses and some
buses that are limited to 32-bit DMA (or less if you are unfortunate).
We also can't rely on {pfn,phys,virt}_to_{bus,dma} and the reverse
to work anywhere outside of the dma_map_ops implementation, because
of IOMMUs in-between.
Of course we do need a proper solution for this problem, but we
can't make it a per-platform decision, and whatever the solution is
needs to take into account both nontrivial linear mappings (offset
or cropped) and IOMMUs, and set the appropriate dma_map_ops for
the device.
I guess for the legacy cases (omap1, iop13xx, ks8695), we can
hardcode dma_map_ops for all devices to get this right. For everything
else, I'd suggest defaulting to the arm_dma_ops unless we get
other information from DT. This means we have to create standardized
properties to handle any combination of these:
1. DMA is coherent
2. DMA space is offset from phys space
3. DMA space is smaller than 32-bit
4. DMA space is larger than 32-bit
5. DMA goes through an IOMMU
The dma-ranges property can deal with 2-4. Highbank already introduced
a "dma-coherent" flag for 1, and we can decide to generalize that.
I don't know what the state of IOMMU support is, but we have to come
up with something better than what we had on PowerPC, because we now
have to deal with a combination of different IOMMUs in the same system,
whereas the most complex case on PowerPC was some devices all going
through one IOMMU and the other devices being linearly mapped.
Arnd
^ permalink raw reply
* [PATCH] arm64: Add architecture support for PCI
From: Arnd Bergmann @ 2014-02-04 16:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPcvp5HN4pBysOdS5_ep_3Lp7GDDKw4YrgmKjYzBet7PtaOLUg@mail.gmail.com>
On Tuesday 04 February 2014, Andrew Murray wrote:
> On 4 February 2014 12:29, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > On Mon, Feb 03, 2014 at 10:34:40PM +0000, Andrew Murray wrote:
> >> On 3 February 2014 18:43, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >> > diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> >> > index 4cc813e..ce5bad2 100644
> >> > --- a/arch/arm64/include/asm/io.h
> >> > +++ b/arch/arm64/include/asm/io.h
> >> > @@ -120,9 +120,13 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
> >> > /*
> >> > * I/O port access primitives.
> >> > */
> >> > +#define arch_has_dev_port() (0)
> >> > #define IO_SPACE_LIMIT 0xffff
> >> > #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
> >> >
> >> > +#define ioport_map(port, nr) (PCI_IOBASE + ((port) & IO_SPACE_LIMIT))
> >> > +#define ioport_unmap(addr)
> >>
> >> I'm not sure that this will work. The in[bwl], out[bwl] macros in
> >> arch/arm64/include/asm/io.h already add the PCI_IOBASE offset.
> >>
> >> Instead of these two #defines, why not just enforce that
> >> GENERIC_PCI_IOMAP is enabled? Or at least wrap these defines with 'if
> >> (!config_enabled(CONFIG_GENERIC_PCI_IOMAP))' or similar.
> >
> > GENERIC_PCI_IOMAP is enabled for AArch64. We have select GENERIC_IOMAP in
> > arch/arm64/Kconfig which in turn selects GENERIC_PCI_IOMAP in lib/Kconfig.
>
> Sorry, it was intent to suggest using the ioport_[map|unmap] functions
> in lib/iomap.c instead of defining something similar here. I guess you
> will also need to also define CONFIG_HAS_IOPORT for this to happen.
We do want CONFIG_HAS_IOPORT, but I would say that we should not use
CONFIG_GENERIC_IOMAP. As I explained in another reply, enabling this
was probably a simple mistake, and we only need this if we want I/O
spaces that are /not/ memory mapped. IMHO any ARM64 system that doesn't
map its PCI I/O space into MMIO space can live without I/O port
access.
Arnd
^ permalink raw reply
* [RFC/RFT 2/2] ARM: keystone: Install hooks for dma address translation routines
From: Olof Johansson @ 2014-02-04 16:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402041702.00039.arnd@arndb.de>
On Tue, Feb 4, 2014 at 8:01 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 04 February 2014, Santosh Shilimkar wrote:
>> > PPC servers use "ibm,dma-window" to describe the assigned dma address
>> > space for busses/devices, but the window itself doesn't contain any
>> > information about the physical address mapping (since it goes through
>> > an iommu after that). It likely doesn't fit this particular use case,
>> > but it's something we should look at as a base in case we need to
>> > start looking at bindings for this instead of coding it per SoC. We'll
>> > know more once we've seen what a few of the implementations out there
>> > are.
>> >
>> Understood.
>
> I think you are looking for the "dma-ranges" property, which describes
> how a device DMA address space maps into the parent bus address space
> for inbound translations. It's not used much in Linux, but it is clearly
> specified. The "ibm,dma-window" property OTOH is for the corner case
> that you have a small per-partition DMA address space section, which is
> not how things are done on most systems these days.
Ah, that might very well be the case. And it looks like dma-ranges
handles this case already. At least based on the first draft proposal
for dma-ranges that I came across. :)
-Olof
^ permalink raw reply
* [PATCH v4 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Thomas Gleixner @ 2014-02-04 16:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391513453-21140-2-git-send-email-ivan.khoronzhuk@ti.com>
On Tue, 4 Feb 2014, Ivan Khoronzhuk wrote:
> + keystone_timer_writel(off, TCR);
> + /* here we have to be sure the timer has been disabled */
> + wmb();
We have explicit writew_relaxed and writew. Why open coding the
barriers?
Thanks,
tglx
^ permalink raw reply
* [PATCH v2 1/6] audit: Enable arm64 support
From: Richard Guy Briggs @ 2014-02-04 16:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140203160659.GA19292@madcap2.tricolour.ca>
On 14/02/03, Richard Guy Briggs wrote:
> On 14/02/03, AKASHI Takahiro wrote:
> > Richard,
>
> Takahiro,
Takahiro,
> > On 01/30/2014 07:36 AM, Richard Guy Briggs wrote:
> > >On 14/01/29, Richard Guy Briggs wrote:
> > >>On 14/01/27, AKASHI Takahiro wrote:
> > >>>[To audit maintainers]
> > >>>
> > >>>On 01/23/2014 11:18 PM, Catalin Marinas wrote:
> > >>>>On Fri, Jan 17, 2014 at 08:13:14AM +0000, AKASHI Takahiro wrote:
> > >>>>>--- a/include/uapi/linux/audit.h
> > >>>>>+++ b/include/uapi/linux/audit.h
> > >>>>>@@ -327,6 +327,8 @@ enum {
> > >>>>> /* distinguish syscall tables */
> > >>>>> #define __AUDIT_ARCH_64BIT 0x80000000
> > >>>>> #define __AUDIT_ARCH_LE 0x40000000
> > >>>>>+#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
> > >>>>>+#define AUDIT_ARCH_AARCH64EB (EM_AARCH64|__AUDIT_ARCH_64BIT)
> > >>>>> #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
> > >>>>> #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
> > >>>>> #define AUDIT_ARCH_ARMEB (EM_ARM)
> > >>>>>diff --git a/init/Kconfig b/init/Kconfig
> > >>>>>index 79383d3..3aae602 100644
> > >>>>>--- a/init/Kconfig
> > >>>>>+++ b/init/Kconfig
> > >>>>>@@ -284,7 +284,7 @@ config AUDIT
> > >>>>>
> > >>>>> config AUDITSYSCALL
> > >>>>> bool "Enable system-call auditing support"
> > >>>>>- depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
> > >>>>>+ depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT) || ARM64)
> > >>>>
> > >>>>The usual comment for such changes: could you please clean this up and
> > >>>>just use something like "depends on HAVE_ARCH_AUDITSYSCALL"?
> > >>>
> > >>>Do you agree to this change?
> > >>>
> > >>>If so, I can create a patch, but have some concerns:
> > >>>1) I can't verify it on other architectures than (arm &) arm64.
> > >>>2) Some architectures (microblaze, mips, openrisc) are not listed here, but
> > >>> their ptrace.c have a call to audit_syscall_entry/exit().
> > >>> (audit_syscall_entry/exit are null if !AUDITSYSCALL, though)
> > >>
> > >>I can try: ppc s390 x86_64 ppc64 i686 s390x
> > >
> > >These arches above all pass compile and basic tests with the following patches applied:
> > >
> > > audit: correct a type mismatch in audit_syscall_exit() pending (already upstream)
> > >
> > > audit: Modify a set of system calls in audit class definitions (already upstream)
> > >
> > > [PATCH v3] audit: Add generic compat syscall support
> > >
> > > [PATCH v2] audit: Enable arm64 support
> > > [PATCH v2] arm64: Add regs_return_value() in syscall.h
> > > [PATCH v2] arm64: Add audit support
> > > [PATCH v2] arm64: audit: Add 32-bit (compat) syscall support
> > > [PATCH v2] arm64: audit: Add makefile rule to create unistd_32.h for compat syscalls
> > > [PATCH v2] arm64: audit: Add audit hook in ptrace/syscall_trace
> >
> > I think that you missed Catalin's suggestion.
>
> I didn't miss his suggestions. I think they are a good way to go, but I
> wanted to make a test at referrable point in time to validate the work
> to that point and to avoid introducing errors by mis-interpreting ideas
> that were not yet fully-formed patches.
>
> > Please use the patch I will post after this message and try it again, please?
>
> I was certainly intending to do so.
I have tested the new sets from Catalin and you and everything passes ok.
> > Thanks,
> > -Takahiro AKASHI
> >
> > >>>So I'm afraid that the change might break someone's assumption.
> > >>>
> > >>>Thanks,
> > >>>-Takahiro AKASHI
> > >>
> > >>- RGB
> > >
> > >- RGB
>
> - RGB
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545
^ permalink raw reply
* [ath9k-devel] [PATCH 1/3] ath9k: Fix build error on ARM
From: Joe Perches @ 2014-02-04 16:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOpc7mFQZ3efZda0cC28BLATqRDJ99BRNu=ezQq8wa+dyFyOvA@mail.gmail.com>
On Tue, 2014-02-04 at 08:03 +0100, Holger Schurig wrote:
> Joe, look in linux/arch/arm/include/asm/delay.h. The macro udelay
> cannot handle large values because of lost-of-precision.
>
> IMHO udelay on ARM is broken, because it also cannot work with fast
> ARM processors (where bogomips >= 3355, which is in sight now). It's
> just not broken enought that someone did something against it ... so
> the current kludge is good enought.
Maybe something like this would be better?
---
arch/arm/include/asm/delay.h | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index dff714d..ac33c56 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -15,6 +15,8 @@
#ifndef __ASSEMBLY__
+#include <linux/printk.h>
+
struct delay_timer {
unsigned long (*read_current_timer)(void);
unsigned long freq;
@@ -51,11 +53,34 @@ extern void __bad_udelay(void);
#define __udelay(n) arm_delay_ops.udelay(n)
#define __const_udelay(n) arm_delay_ops.const_udelay(n)
+#ifdef DEBUG
+#define __udelay_debug_max_delay(n) \
+do { \
+ if (n > MAX_UDELAY_MS * 1000) { \
+ pr_debug("udelay(%d) too large - Convert to mdelay\n", n); \
+ dump_stack(); \
+ } \
+} while (0)
+#else
+#define __udelay_debug_max_delay(n) \
+ do {} while (0)
+#endif
+
#define udelay(n) \
- (__builtin_constant_p(n) ? \
- ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
- __const_udelay((n) * UDELAY_MULT)) : \
- __udelay(n))
+({ \
+ if (__builtin_constant_p(n)) { \
+ typeof n _n = n; \
+ while (_n > MAX_UDELAY_MS * 1000) { \
+ __const_udelay(MAX_UDELAY_MS * 1000 * UDELAY_MULT); \
+ _n -= MAX_UDELAY_MS * 1000; \
+ } \
+ if (_n) \
+ __const_udelay(_n * 1000 * UDELAY_MULT); \
+ } else { \
+ __udelay_debug_max_delay(n); \
+ __udelay(n); \
+ } \
+})
/* Loop-based definitions for assembly code. */
extern void __loop_delay(unsigned long loops);
^ permalink raw reply related
* [RFC/RFT 1/2] ARM: mm: introduce arch hooks for dma address translation routines
From: Santosh Shilimkar @ 2014-02-04 16:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402041715.54538.arnd@arndb.de>
On Tuesday 04 February 2014 11:15 AM, Arnd Bergmann wrote:
> On Tuesday 04 February 2014, Santosh Shilimkar wrote:
>> Currently arch specific DMA address translation routines can be enabled
>> using only defines which makes impossible to use them in with
>> multi-platform builds.
>>
>> Hence, introduce arch specific hooks for DMA address translations
>> routines to be compatible with multi-platform builds:
>> dma_addr_t (*arch_pfn_to_dma)(struct device *dev, unsigned long pfn);
>> unsigned long (*arch_dma_to_pfn)(struct device *dev, dma_addr_t addr);
>> void* (*arch_dma_to_virt)(struct device *dev, dma_addr_t addr);
>> dma_addr_t (*arch_virt_to_dma)(struct device *dev, void *addr);
>>
>> In case if architecture won't use it - DMA address translation routines
>> will fall-back to existing implementation.
>> v
>> Also, modify machines omap1, ks8695, iop13xx to use new DMA hooks.
>
> I think this is going into a wrong direction. DMA translation is not
> at all a platform-specific thing, but rather bus specific. The most
> common scenario is that you have some 64-bit capable buses and some
> buses that are limited to 32-bit DMA (or less if you are unfortunate).
>
I may be wrong but you could have 64 bit bus but 32 bit DMA controllers.
That is one of the case I am dealing with.
> We also can't rely on {pfn,phys,virt}_to_{bus,dma} and the reverse
> to work anywhere outside of the dma_map_ops implementation, because
> of IOMMUs in-between.
>
> Of course we do need a proper solution for this problem, but we
> can't make it a per-platform decision, and whatever the solution is
> needs to take into account both nontrivial linear mappings (offset
> or cropped) and IOMMUs, and set the appropriate dma_map_ops for
> the device.
>
> I guess for the legacy cases (omap1, iop13xx, ks8695), we can
> hardcode dma_map_ops for all devices to get this right. For everything
> else, I'd suggest defaulting to the arm_dma_ops unless we get
> other information from DT. This means we have to create standardized
> properties to handle any combination of these:
>
Thats the case and the $subject series doesn't change that.
> 1. DMA is coherent
> 2. DMA space is offset from phys space
> 3. DMA space is smaller than 32-bit
> 4. DMA space is larger than 32-bit
> 5. DMA goes through an IOMMU
>
> The dma-ranges property can deal with 2-4. Highbank already introduced
> a "dma-coherent" flag for 1, and we can decide to generalize that.
> I don't know what the state of IOMMU support is, but we have to come
> up with something better than what we had on PowerPC, because we now
> have to deal with a combination of different IOMMUs in the same system,
> whereas the most complex case on PowerPC was some devices all going
> through one IOMMU and the other devices being linearly mapped.
>
Just to be clear, the patch set is not fiddling with dma_ops as such.
The dma_ops needs few accessors to convert addresses and these accessors
are different on few platforms. And hence needs to be patched.
We will try to look at "dma-ranges" to see if it can address my case.
Thanks for the pointer
Regards,
Santosh
^ permalink raw reply
* [PATCH] arm64: Add architecture support for PCI
From: Catalin Marinas @ 2014-02-04 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3277167.UhkSU8Sf56@wuerfel>
On Tue, Feb 04, 2014 at 08:44:36AM +0000, Arnd Bergmann wrote:
> On Monday 03 February 2014 21:36:58 Liviu Dudau wrote:
> > On Mon, Feb 03, 2014 at 08:05:56PM +0000, Arnd Bergmann wrote:
> > > 2 MB was a compromise on arm32 to allow up to 32 PCI host bridges but not
> > > take up too much virtual space. On arm64 it should be at least as big.
> > > Could be more than that, although I don't see a reason why it should be,
> > > unless we expect to see systems with tons of host bridges, or buses
> > > that exceed 64KB of I/O space.
> >
> > I will increase the size to 2MB for v2.
>
> Thinking about this some more, I'd go a little higher. In case of
> pci_mv, we already register a 1MB region for one logical host
> (which has multiple I/O spaces behind an emulated bridge), so
> going to 16MB or more would let us handle multiple 1MB windows
> for some amount of future proofing.
>
> Maybe Catalin can assign us some virtual address space to use,
> with the constraints that it should be 16MB or more in an
> area that doesn't require additional kernel page table pages.
See below, 16MB and could be extended further if needed.
------------>8--------------------
>From 00521f109ac8a2589c9089a5feaaaa1be7f26108 Mon Sep 17 00:00:00 2001
From: Catalin Marinas <catalin.marinas@arm.com>
Date: Tue, 4 Feb 2014 16:37:59 +0000
Subject: [PATCH] arm64: Extend the PCI I/O space to 16MB
The patch moves the PCI I/O space (currently at 64K) before the
earlyprintk mapping and extends it to 16MB.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
Documentation/arm64/memory.txt | 16 ++++++++++------
arch/arm64/include/asm/io.h | 2 +-
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt
index 5e054bfe4dde..85e24c4f215c 100644
--- a/Documentation/arm64/memory.txt
+++ b/Documentation/arm64/memory.txt
@@ -35,11 +35,13 @@ ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
-ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
+ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space
+
+ffffffbffb000000 ffffffbffbbfffff 12MB [guard]
-ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
+ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
-ffffffbffbe10000 ffffffbcffffffff ~2MB [guard]
+ffffffbffbe00000 ffffffbffbffffff 2MB [guard]
ffffffbffc000000 ffffffbfffffffff 64MB modules
@@ -60,11 +62,13 @@ fffffdfc00000000 fffffdfdffffffff 8GB vmemmap
fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap]
-fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
+fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space
+
+fffffdfffb000000 fffffdfffbbfffff 12MB [guard]
-fffffdfffbe00000 fffffdfffbe0ffff 64KB PCI I/O space
+fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
-fffffdfffbe10000 fffffdfffbffffff ~2MB [guard]
+fffffdfffbe00000 fffffdfffbffffff 2MB [guard]
fffffdfffc000000 fffffdffffffffff 64MB modules
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 4cc813eddacb..7846a6bb0833 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -121,7 +121,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
* I/O port access primitives.
*/
#define IO_SPACE_LIMIT 0xffff
-#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
+#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M))
static inline u8 inb(unsigned long addr)
{
^ permalink raw reply related
* [PATCH 1/2] arm64: atomics: fix use of acquire + release for full barrier semantics
From: Peter Zijlstra @ 2014-02-04 16:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391516953-14541-1-git-send-email-will.deacon@arm.com>
On Tue, Feb 04, 2014 at 12:29:12PM +0000, Will Deacon wrote:
> @@ -112,17 +114,20 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
> unsigned long tmp;
> int oldval;
>
> + smp_mb();
> +
> asm volatile("// atomic_cmpxchg\n"
> -"1: ldaxr %w1, %2\n"
> +"1: ldxr %w1, %2\n"
> " cmp %w1, %w3\n"
> " b.ne 2f\n"
> -" stlxr %w0, %w4, %2\n"
> +" stxr %w0, %w4, %2\n"
> " cbnz %w0, 1b\n"
> "2:"
> : "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter)
> : "Ir" (old), "r" (new)
> : "cc", "memory");
>
> + smp_mb();
> return oldval;
> }
>
Any particular reason atomic_cmpxchg() doesn't use the proposed rel + mb
scheme? It would be a waste to have atomic_cmpxchg() be more expensive
than it needs to be.
^ permalink raw reply
* [PATCH 1/2] PM / OPP: Add support for 'boost' mode OPP
From: Nishanth Menon @ 2014-02-04 16:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJuA9aimVcxwKEQnSNpsEhZ7Rf-74+r8FOz09EpAZcoVEdi6GA@mail.gmail.com>
On 02/04/2014 09:59 AM, Thomas Abraham wrote:
> On Tue, Feb 4, 2014 at 8:45 PM, Nishanth Menon <nm@ti.com> wrote:
>> On 02/04/2014 03:41 AM, Thomas Abraham wrote:
>>> From: Thomas Abraham <thomas.ab@samsung.com>
>>>
>>> Commit 6f19efc0 ("cpufreq: Add boost frequency support in core") adds
>>> support for CPU boost mode. This patch adds support for finding available
>>> boost OPPs from device tree and marking them as usable in boost mode.
>>>
>>> Cc: Nishanth Menon <nm@ti.com>
>>> Cc: Lukasz Majewski <l.majewski@samsung.com>
>>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>>> ---
>>
>> Why is a cpufreq feature being pushed on to OPP library? you can very
>> well have a property boot-frequencies = < a b c > and be done with the
>> job.
>
> The boost-opp was not limited to be a cpu/cpufreq only feature. Any
> device (such as a bus) which has OPPs and if it can support optional
> boost OPPs, can utilize this feature. The boost OPPs also require a
> voltage to be associated with the frequency and hence the binding
> boost-frequencies would not be suffice. The code changes in this patch
> also do not have anything that is cpufreq specific.
>
if we have
operating-points = < Fa Va
Fb Vb
Fc Vc
Fd Vd
>;
boost-frequencies = <Fc Fd>;
you can easily pick up the voltages from the table.
The point being - there does not seem to be a need to modify the
existing definitions to introduce new OPP definitions.
a way to flip this over is to consider iMX6(see
arch/arm/mach-imx/mach-imx6q.) where OPP tuple <Fd Vd> can only be
enabled *iff* efuse register x has bit y set.
Would we want to introduce efuse offsets into OPP definitions? into
something like additional field definition 'efuse_controlled'?
>>
>> I agree with Rob's comment that this is something we have to discuss
>> in wider "add features to an OPP" discussion[1].
>
> Okay. I have read through the discussion in [1]. Thanks for the link.
> Assuming that the current OPP tuple format will not change, I do not
> feel the code changes in this patch will be hinder the outcome of the
> discussion in [1].
The context of that discussion is to consider what is the data form we
consider OPP as? should we consider OPP as a data that is extensible
(as in phandle with properties that we add on) OR should we consider
key, value pair which provides a key (frequency) into another table
for other data (like efuse bit map, boost set etc..).
Both approaches I mentioned will work, and will take additional code
to make it happen. But having custom properties like this limits
extensibility - that is not scalable for other property definitions
we'd like to make in the future.
>
> Regards,
> Thomas.
>
>>
>>
>> [1] http://marc.info/?t=139108946400001&r=1&w=2
>>
>>> drivers/base/power/opp.c | 69 +++++++++++++++++++++++++++++++++++++---------
>>> 1 file changed, 56 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
>>> index 2553867..de4d52d 100644
>>> --- a/drivers/base/power/opp.c
>>> +++ b/drivers/base/power/opp.c
>>> @@ -62,6 +62,7 @@ struct dev_pm_opp {
>>> struct list_head node;
>>>
>>> bool available;
>>> + bool boost;
>>> unsigned long rate;
>>> unsigned long u_volt;
>>>
>>> @@ -380,10 +381,12 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
>>> EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
>>>
>>> /**
>>> - * dev_pm_opp_add() - Add an OPP table from a table definitions
>>> + * dev_pm_opp_add_flags() - Add an OPP to device OPP list with flags
>>> * @dev: device for which we do this operation
>>> * @freq: Frequency in Hz for this OPP
>>> * @u_volt: Voltage in uVolts for this OPP
>>> + * @available: initial availability of the OPP with adding it to the list.
>>> + * @boost: availability of this opp in controller's boost operating mode.
>>> *
>>> * This function adds an opp definition to the opp list and returns status.
>>> * The opp is made available by default and it can be controlled using
>>> @@ -395,7 +398,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
>>> * that this function is *NOT* called under RCU protection or in contexts where
>>> * mutex cannot be locked.
>>> */
>>> -int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>>> +static int dev_pm_opp_add_flags(struct device *dev, unsigned long freq,
>>> + unsigned long u_volt, bool available, bool boost)
>>> {
>>> struct device_opp *dev_opp = NULL;
>>> struct dev_pm_opp *opp, *new_opp;
>>> @@ -441,7 +445,8 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>>> new_opp->dev_opp = dev_opp;
>>> new_opp->rate = freq;
>>> new_opp->u_volt = u_volt;
>>> - new_opp->available = true;
>>> + new_opp->available = available;
>>> + new_opp->boost = boost;
>>>
>>> /* Insert new OPP in order of increasing frequency */
>>> head = &dev_opp->opp_list;
>>> @@ -462,6 +467,27 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>>> srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp);
>>> return 0;
>>> }
>>> +
>>> +/**
>>> + * dev_pm_opp_add() - Add an OPP table from a table definitions
>>> + * @dev: device for which we do this operation
>>> + * @freq: Frequency in Hz for this OPP
>>> + * @u_volt: Voltage in uVolts for this OPP
>>> + *
>>> + * This function adds an opp definition to the opp list and returns status.
>>> + * The opp is made available by default and it can be controlled using
>>> + * dev_pm_opp_enable/disable functions.
>>> + *
>>> + * Locking: The internal device_opp and opp structures are RCU protected.
>>> + * Hence this function internally uses RCU updater strategy with mutex locks
>>> + * to keep the integrity of the internal data structures. Callers should ensure
>>> + * that this function is *NOT* called under RCU protection or in contexts where
>>> + * mutex cannot be locked.
>>> + */
>>> +int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
>>> +{
>>> + return dev_pm_opp_add_flags(dev, freq, u_volt, true, false);
>>> +}
>>> EXPORT_SYMBOL_GPL(dev_pm_opp_add);
>>>
>>> /**
>>> @@ -651,7 +677,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
>>>
>>> list_for_each_entry(opp, &dev_opp->opp_list, node) {
>>> if (opp->available) {
>>> - freq_table[i].driver_data = i;
>>> + freq_table[i].driver_data =
>>> + opp->boost ? CPUFREQ_BOOST_FREQ : i;
>>> freq_table[i].frequency = opp->rate / 1000;
>>> i++;
>>> }
>>> @@ -701,19 +728,14 @@ struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev)
>>> }
>>>
>>> #ifdef CONFIG_OF
>>> -/**
>>> - * of_init_opp_table() - Initialize opp table from device tree
>>> - * @dev: device pointer used to lookup device OPPs.
>>> - *
>>> - * Register the initial OPP table with the OPP library for given device.
>>> - */
>>> -int of_init_opp_table(struct device *dev)
>>> +static int of_parse_opp_table(struct device *dev, const char *prop_name,
>>> + bool boost)
>>> {
>>> const struct property *prop;
>>> const __be32 *val;
>>> int nr;
>>>
>>> - prop = of_find_property(dev->of_node, "operating-points", NULL);
>>> + prop = of_find_property(dev->of_node, prop_name, NULL);
>>> if (!prop)
>>> return -ENODEV;
>>> if (!prop->value)
>>> @@ -734,7 +756,7 @@ int of_init_opp_table(struct device *dev)
>>> unsigned long freq = be32_to_cpup(val++) * 1000;
>>> unsigned long volt = be32_to_cpup(val++);
>>>
>>> - if (dev_pm_opp_add(dev, freq, volt)) {
>>> + if (dev_pm_opp_add_flags(dev, freq, volt, true, boost)) {
>>> dev_warn(dev, "%s: Failed to add OPP %ld\n",
>>> __func__, freq);
>>> continue;
>>> @@ -744,5 +766,26 @@ int of_init_opp_table(struct device *dev)
>>>
>>> return 0;
>>> }
>>> +
>>> +/**
>>> + * of_init_opp_table() - Initialize opp table from device tree
>>> + * @dev: device pointer used to lookup device OPPs.
>>> + *
>>> + * Register the initial OPP table with the OPP library for given device.
>>> + * Additional "boost" operating points of the controller, if any, are
>>> + * specified with "boost-opp" property.
>>> + */
>>> +int of_init_opp_table(struct device *dev)
>>> +{
>>> + int ret;
>>> +
>>> + ret = of_parse_opp_table(dev, "operating-points", false);
>>> + if (!ret) {
>>> + ret = of_parse_opp_table(dev, "boost-opp", true);
>>> + if (ret == -ENODEV)
>>> + ret = 0;
>>> + }
>>> + return ret;
>>> +}
>>> EXPORT_SYMBOL_GPL(of_init_opp_table);
>>> #endif
>>>
>>
>>
>> --
>> Regards,
>> Nishanth Menon
--
Regards,
Nishanth Menon
^ permalink raw reply
* [PATCH 0/3] ARM: PCI: implement virtual PCI host controller
From: Will Deacon @ 2014-02-04 16:53 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This small set of patches brings PCI support to mach-virt based upon an
idealised host controller (see patch 2 for more details).
This has been tested with kvmtool, for which I have a corresponding set
of patches which you can find in my kvmtool/pci branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
Once the arm64 PCI patches from Liviu have stabilised, I plan to port
this host controller to work there as well.
The main issue I can see with this code is how to describe configuration
space in the device-tree. I'm following the ePAPR PCI bindings (SS == 0)
, but this adds an ugly 'case 0:' line in the pci range parser, which
also exists in mainline for the pcie-designware.c driver.
All feedback welcome,
Will
Will Deacon (3):
ARM: bios32: use pci_enable_resource to enable PCI resources
PCI: ARM: add support for virtual PCI host controller
ARM: mach-virt: allow PCI support to be selected
.../devicetree/bindings/pci/linux,pci-virt.txt | 38 ++++
arch/arm/kernel/bios32.c | 35 ++--
arch/arm/mach-virt/Kconfig | 1 +
drivers/pci/host/Kconfig | 7 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pci-virt.c | 200 +++++++++++++++++++++
6 files changed, 257 insertions(+), 25 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/linux,pci-virt.txt
create mode 100644 drivers/pci/host/pci-virt.c
--
1.8.2.2
^ permalink raw reply
* [PATCH 1/3] ARM: bios32: use pci_enable_resource to enable PCI resources
From: Will Deacon @ 2014-02-04 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391532784-1953-1-git-send-email-will.deacon@arm.com>
This patch moves bios32 over to using the generic code for enabling PCI
resources. All that's left to take care of is the case of PCI bridges,
which need to be enabled for both IO and MEMORY, regardless of the
resource types.
A side-effect of this change is that we no longer explicitly enable
devices when running in PCI_PROBE_ONLY mode. This stays closer to the
meaning of the option and prevents us from trying to enable devices
without any assigned resources (the core code refuses to enable
resources without parents).
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/kernel/bios32.c | 35 ++++++++++-------------------------
1 file changed, 10 insertions(+), 25 deletions(-)
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 317da88ae65b..9f3c76638689 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -608,40 +608,25 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
*/
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
+ int err;
+ u16 cmd;
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for (idx = 0; idx < 6; idx++) {
- /* Only set up the requested stuff */
- if (!(mask & (1 << idx)))
- continue;
+ if (pci_has_flag(PCI_PROBE_ONLY))
+ return 0;
- r = dev->resource + idx;
- if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because"
- " of resource collisions\n", pci_name(dev));
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
+ err = pci_enable_resources(dev, mask);
+ if (err)
+ return err;
/*
* Bridges (eg, cardbus bridges) need to be fully enabled
*/
- if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-
- if (cmd != old_cmd) {
- printk("PCI: enabling device %s (%04x -> %04x)\n",
- pci_name(dev), old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
+
return 0;
}
--
1.8.2.2
^ permalink raw reply related
* [PATCH 2/3] PCI: ARM: add support for virtual PCI host controller
From: Will Deacon @ 2014-02-04 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391532784-1953-1-git-send-email-will.deacon@arm.com>
This patch adds support for an extremely simple virtual PCI host
controller. The controller itself has no configuration registers, and
has its address spaces described entirely by the device-tree (using the
bindings described by ePAPR). This allows emulations, such as kvmtool,
to provide a simple means for a guest Linux instance to make use of
PCI devices.
Corresponding documentation is added for the DT binding.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
.../devicetree/bindings/pci/linux,pci-virt.txt | 38 ++++
drivers/pci/host/Kconfig | 7 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pci-virt.c | 200 +++++++++++++++++++++
4 files changed, 246 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/linux,pci-virt.txt
create mode 100644 drivers/pci/host/pci-virt.c
diff --git a/Documentation/devicetree/bindings/pci/linux,pci-virt.txt b/Documentation/devicetree/bindings/pci/linux,pci-virt.txt
new file mode 100644
index 000000000000..54668a283498
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/linux,pci-virt.txt
@@ -0,0 +1,38 @@
+* ARM Basic Virtual PCI controller
+
+PCI emulations, such as the virtio-pci implementations found in kvmtool
+and other para-virtualised systems, do not require driver support for
+complexities such as regulator and clock management. In fact, the
+controller may not even have a control interface visible to the
+operating system, instead presenting a set of fixed windows describing a
+subset of IO, Memory and Configuration spaces.
+
+Such a controller can be described purely in terms of the standardized
+device tree bindings communicated in pci.txt:
+
+- compatible : Must be "linux,pci-virt"
+
+- ranges : As described in IEEE Std 1275-1994, but must provide
+ at least a definition of the Configuration Space plus
+ one or both of IO and Memory Space.
+
+- #address-cells : Must be 3
+
+- #size-cells : Must be 2
+
+Configuration Space is assumed to be memory-mapped (as opposed to being
+accessed via an ioport) and laid out with a direct correspondence to the
+geography of a PCI bus address, by concatenating the various components
+to form a 24-bit offset:
+
+ cfg_offset(bus, device, function, register) =
+ bus << 16 | device << 11 | function << 8 | register
+
+Interrupt mapping is exactly as described in `Open Firmware Recommended
+Practice: Interrupt Mapping' and requires the following properties:
+
+- #interrupt-cells : Must be 1
+
+- interrupt-map : <see aforementioned specification>
+
+- interrupt-map-mask : <see aforementioned specification>
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 47d46c6d8468..fd4460573b81 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -33,4 +33,11 @@ config PCI_RCAR_GEN2
There are 3 internal PCI controllers available with a single
built-in EHCI/OHCI host controller present on each one.
+config PCI_VIRT_HOST
+ bool "Virtual PCI host controller"
+ depends on ARM && OF
+ help
+ Say Y here if you want to support a very simple virtual PCI
+ host controller, such as the one emulated by kvmtool.
+
endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 13fb3333aa05..9b6775d95d3b 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
+obj-$(CONFIG_PCI_VIRT_HOST) += pci-virt.o
diff --git a/drivers/pci/host/pci-virt.c b/drivers/pci/host/pci-virt.c
new file mode 100644
index 000000000000..ded01474453b
--- /dev/null
+++ b/drivers/pci/host/pci-virt.c
@@ -0,0 +1,200 @@
+/*
+ * Very basic PCI host controller driver targetting virtual machines
+ * (e.g. the PCI emulation provided by kvmtool).
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2014 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ *
+ * This driver currently supports (per instance):
+ * - A single controller
+ * - A single memory space and/or port space
+ * - A memory-mapped configuration space
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+struct virt_pci {
+ struct device *dev;
+
+ struct resource cfg;
+ struct resource io;
+ struct resource mem;
+
+ void __iomem *cfg_base;
+};
+
+static void __iomem *virt_pci_config_address(struct pci_bus *bus,
+ unsigned int devfn,
+ int where)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ struct virt_pci *pci = sys->private_data;
+ void __iomem *addr = pci->cfg_base;
+
+ /*
+ * We construct config space addresses by simply sandwiching
+ * together all of the PCI address components and using the
+ * result as an offset into a 16M region.
+ */
+ return addr + (((u32)bus->number << 16) | (devfn << 8) | where);
+}
+
+
+static int virt_pci_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ void __iomem *addr = virt_pci_config_address(bus, devfn, where);
+
+ switch (size) {
+ case 1:
+ *val = readb(addr);
+ break;
+ case 2:
+ *val = readw(addr);
+ break;
+ default:
+ *val = readl(addr);
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int virt_pci_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ void __iomem *addr = virt_pci_config_address(bus, devfn, where);
+
+ switch (size) {
+ case 1:
+ writeb(val, addr);
+ break;
+ case 2:
+ writew(val, addr);
+ break;
+ default:
+ writel(val, addr);
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops virt_pci_ops = {
+ .read = virt_pci_config_read,
+ .write = virt_pci_config_write,
+};
+
+static int virt_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ struct virt_pci *pci = sys->private_data;
+
+ if (resource_type(&pci->io)) {
+ pci_add_resource(&sys->resources, &pci->io);
+ pci_ioremap_io(nr * resource_size(&pci->io), pci->io.start);
+ }
+
+ if (resource_type(&pci->mem))
+ pci_add_resource(&sys->resources, &pci->mem);
+
+ pci->cfg_base = devm_ioremap_resource(pci->dev, &pci->cfg);
+ return !IS_ERR(pci->cfg_base);
+}
+
+static const struct of_device_id virt_pci_of_match[] = {
+ { .compatible = "linux,pci-virt" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, virt_pci_of_match);
+
+static int virt_pci_probe(struct platform_device *pdev)
+{
+ struct hw_pci hw;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ struct virt_pci *pci;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+
+ if (of_pci_range_parser_init(&parser, np)) {
+ dev_err(dev, "missing \"ranges\" property\n");
+ return -EINVAL;
+ }
+
+ pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
+ if (!pci)
+ return -ENOMEM;
+
+ pci->dev = dev;
+ for_each_of_pci_range(&parser, &range) {
+ u32 restype = range.flags & IORESOURCE_TYPE_BITS;
+
+ switch (restype) {
+ case IORESOURCE_IO:
+ if (resource_type(&pci->io))
+ dev_warn(dev,
+ "ignoring additional io resource\n");
+ else
+ of_pci_range_to_resource(&range, np, &pci->io);
+ break;
+ case IORESOURCE_MEM:
+ if (resource_type(&pci->mem))
+ dev_warn(dev,
+ "ignoring additional mem resource\n");
+ else
+ of_pci_range_to_resource(&range, np, &pci->mem);
+ break;
+ case 0: /* cfg */
+ if (resource_type(&pci->cfg)) {
+ dev_warn(dev,
+ "ignoring additional cfg resource\n");
+ } else {
+ of_pci_range_to_resource(&range, np, &pci->cfg);
+ pci->cfg.flags |= IORESOURCE_MEM;
+ }
+ break;
+ default:
+ dev_warn(dev,
+ "ignoring unknown/unsupported resource type %x\n",
+ restype);
+ }
+ }
+
+ memset(&hw, 0, sizeof(hw));
+ hw.nr_controllers = 1;
+ hw.private_data = (void **)&pci;
+ hw.setup = virt_pci_setup;
+ hw.map_irq = of_irq_parse_and_map_pci;
+ hw.ops = &virt_pci_ops;
+ pci_common_init_dev(dev, &hw);
+ return 0;
+}
+
+static struct platform_driver virt_pci_driver = {
+ .driver = {
+ .name = "pci-virt",
+ .owner = THIS_MODULE,
+ .of_match_table = virt_pci_of_match,
+ },
+ .probe = virt_pci_probe,
+};
+module_platform_driver(virt_pci_driver);
+
+MODULE_DESCRIPTION("Virtual PCI host driver");
+MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
+MODULE_LICENSE("GPLv2");
--
1.8.2.2
^ permalink raw reply related
* [PATCH 3/3] ARM: mach-virt: allow PCI support to be selected
From: Will Deacon @ 2014-02-04 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391532784-1953-1-git-send-email-will.deacon@arm.com>
mach-virt can make use of virtio-pci devices, which requires the guest
kernel to have PCI support selected.
This patch selects CONFIG_MIGHT_HAVE_PCI when CONFIG_ARCH_VIRT=y.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/mach-virt/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-virt/Kconfig b/arch/arm/mach-virt/Kconfig
index 081d46929436..f40fb55574cb 100644
--- a/arch/arm/mach-virt/Kconfig
+++ b/arch/arm/mach-virt/Kconfig
@@ -8,3 +8,4 @@ config ARCH_VIRT
select CPU_V7
select SPARSE_IRQ
select USE_OF
+ select MIGHT_HAVE_PCI
--
1.8.2.2
^ permalink raw reply related
* [PATCH v4 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Ivan Khoronzhuk @ 2014-02-04 16:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.02.1402041715220.24986@ionos.tec.linutronix.de>
It was so in v1. But it was decided to use explicit memory barriers,
because we're always sure the memory barriers are there and that
they're properly documented. Also in this case I don't need to add
keystone readl/writel relaxed function variants and to use mixed calls of
writel/writel_relaxed functions.
See:
http://www.spinics.net/lists/arm-kernel/msg294941.html
On 02/04/2014 06:24 PM, Thomas Gleixner wrote:
> On Tue, 4 Feb 2014, Ivan Khoronzhuk wrote:
>> + keystone_timer_writel(off, TCR);
>> + /* here we have to be sure the timer has been disabled */
>> + wmb();
> We have explicit writew_relaxed and writew. Why open coding the
> barriers?
>
> Thanks,
>
> tglx
--
Regards,
Ivan Khoronzhuk
^ permalink raw reply
* [PATCH 3/6] mfd: add bcm59056 pmu driver
From: Mark Brown @ 2014-02-04 16:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204143119.GA4627@beef>
On Tue, Feb 04, 2014 at 09:31:19AM -0500, Matt Porter wrote:
> On Tue, Feb 04, 2014 at 01:29:51PM +0000, Lee Jones wrote:
> > > +static struct i2c_driver bcm59056_i2c_driver = {
> > > + .driver = {
> > > + .name = "bcm59056",
> > > + .owner = THIS_MODULE,
> > > + .of_match_table = of_match_ptr(bcm59056_of_match),
> > No need to use of_match_ptr() here.
> Will remove.
What using of_match_ptr() should do is allow the compiler to figure out
that the table isn't used when DT is disabled and discard it without
ifdefs. Not sure if that actually works yet but that's the idea.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140204/867f1536/attachment.sig>
^ permalink raw reply
* [PATCH] dma: mv_xor: Silence a bunch of LPAE-related warnings
From: Jason Cooper @ 2014-02-04 17:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204052329.GN10628@intel.com>
On Tue, Feb 04, 2014 at 10:53:29AM +0530, Vinod Koul wrote:
> On Mon, Feb 03, 2014 at 05:13:23PM -0800, Olof Johansson wrote:
> > Enabling some of the mvebu platforms in the multiplatform config for ARM
> > enabled these drivers, which also triggered a bunch of warnings when LPAE
> > is enabled (thus making phys_addr_t 64-bit).
> >
> > Most changes are switching printk formats, but also a bit of changes to what
> > used to be array-based pointer arithmetic that could just be done with the
> > address types instead.
> >
> > The warnings were:
> >
> > drivers/dma/mv_xor.c: In function 'mv_xor_tx_submit':
> > drivers/dma/mv_xor.c:500:3: warning: format '%x' expects argument of type
> > 'unsigned int', but argument 4 has type 'dma_addr_t' [-Wformat]
> > drivers/dma/mv_xor.c: In function 'mv_xor_alloc_chan_resources':
> > drivers/dma/mv_xor.c:553:13: warning: cast to pointer from integer of
> > different size [-Wint-to-pointer-cast]
> > drivers/dma/mv_xor.c:555:4: warning: cast from pointer to integer of
> > different size [-Wpointer-to-int-cast]
> > drivers/dma/mv_xor.c: In function 'mv_xor_prep_dma_memcpy':
> > drivers/dma/mv_xor.c:584:2: warning: format '%x' expects argument of type
> > 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat]
> > drivers/dma/mv_xor.c:584:2: warning: format '%x' expects argument of type
> > 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat]
> > drivers/dma/mv_xor.c: In function 'mv_xor_prep_dma_xor':
> > drivers/dma/mv_xor.c:628:2: warning: format '%u' expects argument of type
> > 'unsigned int', but argument 7 has type 'dma_addr_t' [-Wformat]
> >
> > Signed-off-by: Olof Johansson <olof@lixom.net>
> Acked-by: Vinod Koul <vinod.koul@intel.com>
Olof, would you like me to queue it up? Or do you want to take it
directly?
Acked-by: Jason Cooper <jason@lakedaemon.net>
thx,
Jason.
> > ---
> > drivers/dma/mv_xor.c | 24 ++++++++++++------------
> > 1 file changed, 12 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
> > index 53fb0c8365b0..766b68ed505c 100644
> > --- a/drivers/dma/mv_xor.c
> > +++ b/drivers/dma/mv_xor.c
> > @@ -497,8 +497,8 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
> > if (!mv_can_chain(grp_start))
> > goto submit_done;
> >
> > - dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %x\n",
> > - old_chain_tail->async_tx.phys);
> > + dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %pa\n",
> > + &old_chain_tail->async_tx.phys);
> >
> > /* fix up the hardware chain */
> > mv_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys);
> > @@ -527,7 +527,8 @@ submit_done:
> > /* returns the number of allocated descriptors */
> > static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
> > {
> > - char *hw_desc;
> > + void *virt_desc;
> > + dma_addr_t dma_desc;
> > int idx;
> > struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
> > struct mv_xor_desc_slot *slot = NULL;
> > @@ -542,17 +543,16 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
> > " %d descriptor slots", idx);
> > break;
> > }
> > - hw_desc = (char *) mv_chan->dma_desc_pool_virt;
> > - slot->hw_desc = (void *) &hw_desc[idx * MV_XOR_SLOT_SIZE];
> > + virt_desc = mv_chan->dma_desc_pool_virt;
> > + slot->hw_desc = virt_desc + idx * MV_XOR_SLOT_SIZE;
> >
> > dma_async_tx_descriptor_init(&slot->async_tx, chan);
> > slot->async_tx.tx_submit = mv_xor_tx_submit;
> > INIT_LIST_HEAD(&slot->chain_node);
> > INIT_LIST_HEAD(&slot->slot_node);
> > INIT_LIST_HEAD(&slot->tx_list);
> > - hw_desc = (char *) mv_chan->dma_desc_pool;
> > - slot->async_tx.phys =
> > - (dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
> > + dma_desc = mv_chan->dma_desc_pool;
> > + slot->async_tx.phys = dma_desc + idx * MV_XOR_SLOT_SIZE;
> > slot->idx = idx++;
> >
> > spin_lock_bh(&mv_chan->lock);
> > @@ -582,8 +582,8 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
> > int slot_cnt;
> >
> > dev_dbg(mv_chan_to_devp(mv_chan),
> > - "%s dest: %x src %x len: %u flags: %ld\n",
> > - __func__, dest, src, len, flags);
> > + "%s dest: %pad src %pad len: %u flags: %ld\n",
> > + __func__, &dest, &src, len, flags);
> > if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
> > return NULL;
> >
> > @@ -626,8 +626,8 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
> > BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
> >
> > dev_dbg(mv_chan_to_devp(mv_chan),
> > - "%s src_cnt: %d len: dest %x %u flags: %ld\n",
> > - __func__, src_cnt, len, dest, flags);
> > + "%s src_cnt: %d len: %u dest %pad flags: %ld\n",
> > + __func__, src_cnt, len, &dest, flags);
> >
> > spin_lock_bh(&mv_chan->lock);
> > slot_cnt = mv_chan_xor_slot_count(len, src_cnt);
> > --
> > 1.8.4.1.601.g02b3b1d
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> --
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
From: Grant Likely @ 2014-02-04 17:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140121225740.GP18269@obsidianresearch.com>
On Tue, 21 Jan 2014 15:57:40 -0700, Jason Gunthorpe <jgunthorpe@obsidianresearch.com> wrote:
> On Wed, Jan 15, 2014 at 06:03:01PM +0100, boris brezillon wrote:
>
> > >>Pick a mode value that fits all the parameters of the connected
> > >>non-ONFI flash.
> > >>
> > >>This would be instead of defining each parameter
> > >>individually.. Provide some helpers to convert from a onfi mode number
> > >>to all the onfi defined timing parameters so that drivers can
> > >>configure the HW..
> > >
> > >Are you suggesting we should provide a function that converts these
> > >modes into a nand_timings struct, or just use the timing modes and
> > >let the NAND controller drivers configure its IP accordingly ?
>
> Either seems reasonable to me, but passing the ONFI mode directly from
> the NAND core to the driver seems a little safer..
I agree here. There are a lot of parameters being defined. If it can be
boiled down to an ONFI mode that will make for a much more robust
binding. Far fewer things to get wrong.
g.
^ permalink raw reply
* [RFC/RFT 1/2] ARM: mm: introduce arch hooks for dma address translation routines
From: Arnd Bergmann @ 2014-02-04 17:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F11788.4030500@ti.com>
On Tuesday 04 February 2014 11:38:32 Santosh Shilimkar wrote:
> On Tuesday 04 February 2014 11:15 AM, Arnd Bergmann wrote:
> > On Tuesday 04 February 2014, Santosh Shilimkar wrote:
> > I think this is going into a wrong direction. DMA translation is not
> > at all a platform-specific thing, but rather bus specific. The most
> > common scenario is that you have some 64-bit capable buses and some
> > buses that are limited to 32-bit DMA (or less if you are unfortunate).
> >
> I may be wrong but you could have 64 bit bus but 32 bit DMA controllers.
> That is one of the case I am dealing with.
You are absolutely right. In fact you could have any combination of
bus widths between a device and the RAM and the correct way to deal
with this is probably to follow the dma-ranges properties of each
device in-between and take the intersection (that may not be the
right term in English, but I think you know what I mean).
> > I guess for the legacy cases (omap1, iop13xx, ks8695), we can
> > hardcode dma_map_ops for all devices to get this right. For everything
> > else, I'd suggest defaulting to the arm_dma_ops unless we get
> > other information from DT. This means we have to create standardized
> > properties to handle any combination of these:
> >
> Thats the case and the $subject series doesn't change that.
>
> > 1. DMA is coherent
> > 2. DMA space is offset from phys space
> > 3. DMA space is smaller than 32-bit
> > 4. DMA space is larger than 32-bit
> > 5. DMA goes through an IOMMU
> >
> > The dma-ranges property can deal with 2-4. Highbank already introduced
> > a "dma-coherent" flag for 1, and we can decide to generalize that.
> > I don't know what the state of IOMMU support is, but we have to come
> > up with something better than what we had on PowerPC, because we now
> > have to deal with a combination of different IOMMUs in the same system,
> > whereas the most complex case on PowerPC was some devices all going
> > through one IOMMU and the other devices being linearly mapped.
> >
> Just to be clear, the patch set is not fiddling with dma_ops as such.
> The dma_ops needs few accessors to convert addresses and these accessors
> are different on few platforms. And hence needs to be patched.
well, iop13xx is certainly not going to be multiplatform any time
soon, so we don't have to worry about those. ks8695 won't be multiplatform
unless I do it I suspect. I don't know about the plans for OMAP1,
but since only the OHCI device is special there, it would be trivial
to do a separate dma_map_ops for that device, or to extend arm_dma_ops
to read the offset in a per-device variable as we probably have to
do for DT/multiplatform as well.
> We will try to look at "dma-ranges" to see if it can address my case.
> Thanks for the pointer
Ok.
Arnd
^ permalink raw reply
* UBI leb_write_unlock NULL pointer Oops (continuation) on ARM926
From: Bill Pringlemeir @ 2014-02-04 17:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <878utq51b4.fsf@nbsps.com>
On 4 Feb 2014, bpringlemeir at nbsps.com wrote:
> The ARM926 systems do not have proper 'lock free' idioms like
> 'ldrex/strex' and they try to do atomic operations by locking
> interrupts. I think that UbiFs/UBI maybe called on a 'data fault' or
> 'program fault' (in user space) when memory pressure is present. I have
> seen this occur in some sound drivers where the data source is coming
> from disk (or maybe the driver uses vmalloc() or something). So I think
> on occasion, the ltree_lookup() may not work or there is something weird
> with the atomic primatives and data/page faults.
https://www.google.ca/#q=site:infradead.org+leb_write_unlock+oops
http://lists.infradead.org/pipermail/linux-mtd/2013-May/046907.html
at91sam9g20 - arm926, different MTD driver. Linux 3.6.9
Code: e5903004 e58d2004 e1560003 0a00002a (e593200c)
0: e5903004 ldr r3, [r0, #4]
4: e58d2004 str r2, [sp, #4]
8: e1560003 cmp r6, r3
c: 0a00002a beq 0xbc
10: e593200c ldr r2, [r3, #12]
The code sequence looks identical and the Oops trace, etc is the same.
People from Pengutronix also indicated seeing the same type of Opps; I
think they deal with the IMX, but maybe this was on another board.
Regards,
Bill Pringlemeir.
^ permalink raw reply
* [PATCH 08/17] spi: pl022: Fully gate clocks at request inactivity
From: Mark Brown @ 2014-02-04 17:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391529538-21685-9-git-send-email-ulf.hansson@linaro.org>
On Tue, Feb 04, 2014 at 04:58:49PM +0100, Ulf Hansson wrote:
> Use clk_disable_unprepare and clk_prepare_enable from the runtime PM
> callbacks, to fully gate|ungate clocks. Potentially this will save more
> power, depending on the clock tree for the current SOC.
The same patch has already been applied (I noticed and fixed it while
doing unrelated code review).
> pinctrl_pm_select_default_state(dev);
> - clk_enable(pl022->clk);
> + clk_prepare_enable(pl022->clk);
Someone should really make this check errors though!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140204/c63f5f55/attachment.sig>
^ permalink raw reply
* [PATCH 3/6] mfd: add bcm59056 pmu driver
From: Lee Jones @ 2014-02-04 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204165906.GC22609@sirena.org.uk>
> > > > +static struct i2c_driver bcm59056_i2c_driver = {
> > > > + .driver = {
> > > > + .name = "bcm59056",
> > > > + .owner = THIS_MODULE,
> > > > + .of_match_table = of_match_ptr(bcm59056_of_match),
>
> > > No need to use of_match_ptr() here.
>
> > Will remove.
>
> What using of_match_ptr() should do is allow the compiler to figure out
> that the table isn't used when DT is disabled and discard it without
> ifdefs. Not sure if that actually works yet but that's the idea.
Right, but I'm guessing that as there is no support for platform data
then this device(s) is going to be DT only? If that's the case perhaps
a 'depends OF' might be in order. If that's not the case then I'm more
than happy to leave the of_match_ptr() in.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 3/6] mfd: add bcm59056 pmu driver
From: Mark Brown @ 2014-02-04 17:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204170832.GA5196@lee--X1>
On Tue, Feb 04, 2014 at 05:08:32PM +0000, Lee Jones wrote:
> > What using of_match_ptr() should do is allow the compiler to figure out
> > that the table isn't used when DT is disabled and discard it without
> > ifdefs. Not sure if that actually works yet but that's the idea.
> Right, but I'm guessing that as there is no support for platform data
> then this device(s) is going to be DT only? If that's the case perhaps
> a 'depends OF' might be in order. If that's not the case then I'm more
> than happy to leave the of_match_ptr() in.
Hey, we'll all be using ACPI soon! :P
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140204/9134d4b4/attachment.sig>
^ permalink raw reply
* [PATCH v3 2/5] ASoC: tda998x: add a codec driver for the TDA998x
From: Jean-Francois Moine @ 2014-02-04 17:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204133014.GA22609@sirena.org.uk>
On Tue, 4 Feb 2014 13:30:14 +0000
Mark Brown <broonie@kernel.org> wrote:
> On Sun, Jan 26, 2014 at 07:45:36PM +0100, Jean-Francois Moine wrote:
>
> > + /* load the optional CODEC */
> > + of_platform_populate(np, NULL, NULL, &client->dev);
> > +
>
> Why is this using of_platform_populate()? That's a very odd way of
> doing things.
The i2c does not populate the subnodes in the DT. I did not find why,
but, what is sure is that if of_platform_populate() is not called, the
tda CODEC module is not loaded.
You may find an other example in drivers/mfd/twl-core.c.
> > +config SND_SOC_TDA998X
> > + tristate
> > + depends on OF
> > + default y if DRM_I2C_NXP_TDA998X=y
> > + default m if DRM_I2C_NXP_TDA998X=m
> > +
>
> Make this visible if it can be selected from DT so it can be used with
> generic cards.
I don't understand. The tda CODEC can only be used with the TDA998x I2C
driver. It might have been included in the tda998x source as well.
> > +static int tda_get_encoder(struct tda_priv *priv)
> > +{
> > + struct snd_soc_codec *codec = priv->codec;
> > + struct device_node *np;
> > +
> > + /* get the parent tda998x device */
> > + np = of_get_parent(codec->dev->of_node);
> > + if (!np || !of_device_is_compatible(np, "nxp,tda998x")) {
> > + dev_err(codec->dev, "no or bad parent!\n");
> > + return -EINVAL;
> > + }
> > + priv->i2c_client = of_find_i2c_device_by_node(np);
> > + of_node_put(np);
> > + return 0;
> > +}
>
> Why does this need to be checked like this? We don't normally have this
> sort of code to check that the parent is correct.
In my previous submit, the tda CODEC was not declared inside the
tda998x I2c device, so, its location was searched from phandle.
Now, the CODEC is declared inside the tda998x as a node child. But, in
a bad DT, the tda CODEC could be declared anywhere, even inside a other
DRM I2C slave encoder, in which case, bad things would happen...
> > +static int tda_start_stop(struct tda_priv *priv)
> > +{
> > + int port;
> > +
> > + /* give the audio parameters to the HDMI encoder */
> > + if (priv->dai_id == AFMT_I2S)
> > + port = priv->ports[0];
> > + else
> > + port = priv->ports[1];
> > + tda998x_audio_update(priv->i2c_client, priv->dai_id, port);
> > + return 0;
> > +}
>
> What does this actually do? No information is being passed in to the
> core function here, not even any information on if it's starting or
> stopping. Looking at the rest of the code I can't help thinking it
> might be clearer to inline this possibly with a lookup helper, the code
> is very small and the lack of parameters makes it hard to follow.
I thought it was simple enough. The function tda_start_stop() is called
from 2 places:
- on audio start in tda_startup with the audio type (DAI id)
priv->dai_id = dai->id;
- on audio stop with a null audio type
priv->dai_id = 0; /* streaming stop */
On stream start, the DAI id is never null, as explained in the patch 1:
The audio format values in the encoder configuration interface are
changed to non null values so that the value 0 is used in the audio
function to indicate that audio streaming is stopped.
and on streaming stop the port is not meaningful.
I will add a null item in the enum (AFMT_NO_AUDIO).
> > +static const struct snd_soc_dapm_route tda_routes[] = {
> > + { "hdmi-out", NULL, "HDMI I2S Playback" },
> > + { "hdmi-out", NULL, "HDMI SPDIF Playback" },
> > +};
>
> S/PDIF.
Did you ever try that with debugfs?
BTW, this patch series may be delayed for some time: the tda998x driver
has to be reworked for DT support.
--
Ken ar c'henta? | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
^ 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