* [PATCH 15/16] ARM: vexpress/dcscb: handle platform coherency exit/setup and CCI
From: Lorenzo Pieralisi @ 2013-01-14 12:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F10EF4.9070909@ti.com>
On Sat, Jan 12, 2013 at 07:21:24AM +0000, Santosh Shilimkar wrote:
> On Saturday 12 January 2013 12:58 AM, Nicolas Pitre wrote:
> > On Fri, 11 Jan 2013, Santosh Shilimkar wrote:
> >
> >> On Thursday 10 January 2013 05:50 AM, Nicolas Pitre wrote:
> >>> From: Dave Martin <dave.martin@linaro.org>
> >>>
> >>> + /*
> >>> + * Flush the local CPU cache.
> >>> + *
> >>> + * A15/A7 can hit in the cache with SCTLR.C=0, so we don't need
> >>> + * a preliminary flush here for those CPUs. At least, that's
> >>> + * the theory -- without the extra flush, Linux explodes on
> >>> + * RTSM (maybe not needed anymore, to be investigated).
> >>> + */
> >> This is expected if the entire code is not in one stack frame and the
> >> additional flush is needed to avoid possible stack corruption. This
> >> issue has been discussed in past on the list.
> >
> > I missed that. Do you have a reference or pointer handy?
> >
> > What is strange is that this is 100% reproducible on RTSM while this
> > apparently is not an issue on real hardware so far.
> >
> I tried searching archives and realized the discussion was in private
> email thread. There are some bits and pieces on list but not all the
> information.
>
> The main issue RMK pointed out is- An additional L1 flush needed
> to avoid the effective change of view of memory when the C bit is
> turned off, and the cache is no longer searched for local CPU accesses.
>
> In your case dcscb_power_down() has updated the stack which can be hit
> in cache line and hence cache is dirty now. Then cpu_proc_fin() clears
> the C-bit and hence for sub sequent calls the L1 cache won't be
> searched. You then call flush_cache_all() which again updates the
> stack but avoids searching the L1 cache. So it overwrites previous
> saved stack frame. This seems to be an issue in your case as well.
On A15/A7 even with the C bit cleared the D-cache is searched, the
situation above cannot happen and if it does we are facing a HW/model bug.
If this code is run on A9 then we have a problem since there, when the C bit
is cleared D-cache is not searched (and that's why the sequence above
should be written in assembly with no data access whatsoever), but on
A15/A7 we do not.
I have been running this code on TC2 for hours on end with nary a problem.
The sequence:
- clear C bit
- clean D-cache
- exit SMP
must be written in assembly with no data access whatsoever to make it
portable across v7 implementations. I think I will write some docs and
add them to the kernel to avoid further discussion on this topic.
FYI, the thread Santosh mentioned:
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-May/099791.html
Lorenzo
^ permalink raw reply
* [PATCH 04/14] usb: phy: nop: Handle power supply regulator for the PHY
From: Russell King - ARM Linux @ 2013-01-14 12:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F3F12B.4080906@ti.com>
On Mon, Jan 14, 2013 at 01:51:07PM +0200, Roger Quadros wrote:
> On 01/14/2013 01:25 PM, Russell King - ARM Linux wrote:
> > Also consider... is dev_err() appropriate for an "error", for which you
> > print a message and continue as if nothing went wrong. To me that sounds
> > more like a warning than an error, so maybe dev_warn() would be more
> > appropriate?
> >
> I used dev_dbg(), because we don't treat not getting the power supply
> regulator as that serious.
This comment is about what you do when regulator_enable() and the like
returns non-zero.
^ permalink raw reply
* [PATCHv2 1/4] clockevents: Add generic timer broadcast receiver
From: Mark Rutland @ 2013-01-14 12:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301141247020.7475@ionos>
On Mon, Jan 14, 2013 at 11:50:55AM +0000, Thomas Gleixner wrote:
> On Mon, 14 Jan 2013, Mark Rutland wrote:
>
> > On Mon, Jan 14, 2013 at 11:06:31AM +0000, Thomas Gleixner wrote:
> > > On Wed, 9 Jan 2013, Mark Rutland wrote:
> > > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
> > > > +extern int tick_receive_broadcast(void);
> > > > +#else
> > > > +static inline int tick_receive_broadcast(void)
> > > > +{
> > > > + return 0;
> > > > +}
> > >
> > > What's the inline function for? If an arch does not have broadcasting
> > > support it should not have a receive broadcast function call either.
> >
> > That was how this was originally structured [1], but Santosh suggested this
> > would break the build for !GENERIC_CLOCKEVENTS_BROADCAST [1]. It means that the
> > arch-specific receive path (i.e. IPI handler) doesn't have to be #ifdef'd,
> > which makes it less ugly.
>
> Hmm. If you want to keep the IPI around unconditionally the inline
> makes some sense, though the question is whether keeping an unused IPI
> around makes sense in the first place. I'd rather see a warning that
> an unexpected IPI happened than a silent inline function being called.
How about I add a warning (e.g. "Impossible timer broadcast received.") and
return -EOPNOTSUPP when !GENERIC_CLOCKEVENTS_BROADCAST?
> > > Is anything going to use the return value?
> >
> > I'd added this after looking at the x86 lapic timers, where interrupts might
> > remain pending over a kexec, and lapic interrupts come up before timers are
> > registered. The return value is useful for shutting down the timer in that case
> > (see x86's local_apic_timer_interrupt).
>
> Right, though then you need to check for evt->event_handler as well.
I thought this previously also [1], but I couldn't find any path such that a
tick_cpu_device would have an evtdev without an event_handler. We always set the
handler before setting evtdev, and alway wipe evtdev before wiping the handler.
Have I missed something?
> Thanks,
>
> tglx
>
Thanks,
Mark.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2012-December/138092.html
^ permalink raw reply
* [PATCH v2] mm: dmapool: use provided gfp flags for all dma_alloc_coherent() calls
From: Soeren Moch @ 2013-01-14 11:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1353421905-3112-1-git-send-email-m.szyprowski@samsung.com>
On 20.11.2012 15:31, Marek Szyprowski wrote:
> dmapool always calls dma_alloc_coherent() with GFP_ATOMIC flag,
> regardless the flags provided by the caller. This causes excessive
> pruning of emergency memory pools without any good reason. Additionaly,
> on ARM architecture any driver which is using dmapools will sooner or
> later trigger the following error:
> "ERROR: 256 KiB atomic DMA coherent pool is too small!
> Please increase it with coherent_pool= kernel parameter!".
> Increasing the coherent pool size usually doesn't help much and only
> delays such error, because all GFP_ATOMIC DMA allocations are always
> served from the special, very limited memory pool.
>
> This patch changes the dmapool code to correctly use gfp flags provided
> by the dmapool caller.
>
> Reported-by: Soeren Moch <smoch@web.de>
> Reported-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Tested-by: Andrew Lunn <andrew@lunn.ch>
> Tested-by: Soeren Moch <smoch@web.de>
Now I tested linux-3.7.1 (this patch is included there) on my Marvell
Kirkwood system. I still see
ERROR: 1024 KiB atomic DMA coherent pool is too small!
Please increase it with coherent_pool= kernel parameter!
after several hours of runtime under heavy load with SATA and
DVB-Sticks (em28xx / drxk and dib0700).
As already reported earlier this patch improved the behavior compared to
linux-3.6.x and 3.7.0 (error after several ten minutes runtime), but
I still see a regression compared to linux-3.5.x. With this kernel the
same system with same workload runs flawlessly.
Regards,
Soeren
^ permalink raw reply
* [PATCH 04/14] usb: phy: nop: Handle power supply regulator for the PHY
From: Roger Quadros @ 2013-01-14 11:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114112549.GY23505@n2100.arm.linux.org.uk>
On 01/14/2013 01:25 PM, Russell King - ARM Linux wrote:
> On Mon, Jan 14, 2013 at 11:54:42AM +0200, Roger Quadros wrote:
>> On 01/11/2013 07:17 PM, Russell King - ARM Linux wrote:
>>> On Thu, Jan 10, 2013 at 06:51:24PM +0200, Roger Quadros wrote:
>>>> We use "vcc" as the supply name for the PHY's power supply.
>>>> The power supply will be enabled during .init() and disabled
>>>> during .shutdown()
>>>>
>>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>>> ---
>>>> drivers/usb/otg/nop-usb-xceiv.c | 18 ++++++++++++++++++
>>>> 1 files changed, 18 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
>>>> index 163f972..1c6db10 100644
>>>> --- a/drivers/usb/otg/nop-usb-xceiv.c
>>>> +++ b/drivers/usb/otg/nop-usb-xceiv.c
>>>> @@ -33,11 +33,13 @@
>>>> #include <linux/usb/nop-usb-xceiv.h>
>>>> #include <linux/slab.h>
>>>> #include <linux/clk.h>
>>>> +#include <linux/regulator/consumer.h>
>>>>
>>>> struct nop_usb_xceiv {
>>>> struct usb_phy phy;
>>>> struct device *dev;
>>>> struct clk *clk;
>>>> + struct regulator *vcc;
>>>> };
>>>>
>>>> static struct platform_device *pd;
>>>> @@ -70,6 +72,11 @@ static int nop_init(struct usb_phy *phy)
>>>> {
>>>> struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev);
>>>>
>>>> + if (nop->vcc) {
>>>> + if (regulator_enable(nop->vcc))
>>>> + dev_err(phy->dev, "Failed to enable power\n");
>>>> + }
>>>> +
>>>> if (nop->clk)
>>>> clk_enable(nop->clk);
>>>>
>>>> @@ -82,6 +89,11 @@ static void nop_shutdown(struct usb_phy *phy)
>>>>
>>>> if (nop->clk)
>>>> clk_disable(nop->clk);
>>>> +
>>>> + if (nop->vcc) {
>>>> + if (regulator_disable(nop->vcc))
>>>> + dev_err(phy->dev, "Failed to disable power\n");
>>>> + }
>>>> }
>>>>
>>>> static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
>>>> @@ -157,6 +169,12 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)
>>>> }
>>>> }
>>>>
>>>> + nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
>>>> + if (IS_ERR(nop->vcc)) {
>>>> + dev_dbg(&pdev->dev, "Error getting vcc regulator\n");
>>>> + nop->vcc = NULL;
>>>> + }
>>>
>>> Is it really appropriate for drivers to do this kind of thing with
>>> pointer-returning functions (I mean, setting the pointer to NULL on
>>> error, rather than just using a test for IS_ERR() in the above
>>> locations). You are imposing driver-local assumptions on an API.
>>>
>>> Practically it probably doesn't make much difference but given the
>>> amount of mistakes that we have with IS_ERR_OR_NULL()...
>>>
>> Makes sense. I'll convert it to use IS_ERR_OR_NULL() throughout.
>
> IS_ERR_OR_NULL() is going to be deprecated and removed. Please take a
> look at how these APIs work.
OK. I misunderstood what you meant earlier.
>
> If regulator support is not enabled, then devm_regulator_get() returns
> NULL, and all the other regulator functions become no-ops. This is not
> an error. Do you need the driver to error out if CONFIG_REGULATOR is
> disabled?
>
No, in fact even if CONFIG_REGULATOR is enabled and regulator_get()
fails, we just print a debug message and continue as usual. So
CONFIG_REGULATOR disabled _and_ regulator_get() error are handled in the
same way.
> If regulator support is enabled, then it can return a pointer-error
> value (as defined when IS_ERR() is true, and _in that case only_ can it
> be decoded by PTR_ERR() - PTR_ERR() is _only_ valid when IS_ERR()
> returns true - it is _not_ valid for all the cases that IS_ERR_OR_NULL()
> returns true.) Otherwise, it returns a cookie as far as the driver is
> concerned for the regulator suitable for passing into the other regulator
> APIs.
>
> By having the driver do something different, and make use of NULL as its
> own special sentinel, it's placing additional interpretations on the API,
> which can lead to bugs. Don't do this.
Agreed.
>
> If you can start making use of 'nop' vcc/clk members before they've been
> "got" then initialize them to ERR_PTR(-EINVAL) first.
>
> Also consider that when using the devm interfaces, you can do:
>
>
> nop->clk = devm_clk_get(&pdev->dev, ...);
> nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
>
> if (IS_ERR(nop->clk))
> dev_dbg(&pdev->dev, "unable to get clock: %d\n",
> PTR_ERR(nop->clk));
>
> if (IS_ERR(nop->vcc))
> dev_dbg(&pdev->dev, "unable to get vcc regulator: %d\n",
> PTR_ERR(nop->vcc));
> ...
> if (!IS_ERR(nop->clk))
> clk_enable(nop->clk);
OK I get it now. The only case where nop->clk or nop->vcc will be NULL
is if the framework is not enabled. It is fine to call the
regulator/clock APIs with NULL pointers in that case.
>
> You may also consider that if you're going to print a warning for
> regulator_enable(), that you should print the error code as well, so that
> you know the reason why the failure happened.
OK.
>
> Also consider... is dev_err() appropriate for an "error", for which you
> print a message and continue as if nothing went wrong. To me that sounds
> more like a warning than an error, so maybe dev_warn() would be more
> appropriate?
>
I used dev_dbg(), because we don't treat not getting the power supply
regulator as that serious.
--
cheers,
-roger
^ permalink raw reply
* [PATCHv2 1/4] clockevents: Add generic timer broadcast receiver
From: Thomas Gleixner @ 2013-01-14 11:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114112951.GC7990@e106331-lin.cambridge.arm.com>
On Mon, 14 Jan 2013, Mark Rutland wrote:
> On Mon, Jan 14, 2013 at 11:06:31AM +0000, Thomas Gleixner wrote:
> > On Wed, 9 Jan 2013, Mark Rutland wrote:
> > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
> > > +extern int tick_receive_broadcast(void);
> > > +#else
> > > +static inline int tick_receive_broadcast(void)
> > > +{
> > > + return 0;
> > > +}
> >
> > What's the inline function for? If an arch does not have broadcasting
> > support it should not have a receive broadcast function call either.
>
> That was how this was originally structured [1], but Santosh suggested this
> would break the build for !GENERIC_CLOCKEVENTS_BROADCAST [1]. It means that the
> arch-specific receive path (i.e. IPI handler) doesn't have to be #ifdef'd,
> which makes it less ugly.
Hmm. If you want to keep the IPI around unconditionally the inline
makes some sense, though the question is whether keeping an unused IPI
around makes sense in the first place. I'd rather see a warning that
an unexpected IPI happened than a silent inline function being called.
> > Is anything going to use the return value?
>
> I'd added this after looking at the x86 lapic timers, where interrupts might
> remain pending over a kexec, and lapic interrupts come up before timers are
> registered. The return value is useful for shutting down the timer in that case
> (see x86's local_apic_timer_interrupt).
Right, though then you need to check for evt->event_handler as well.
Thanks,
tglx
^ permalink raw reply
* [PATCHv2 1/4] clockevents: Add generic timer broadcast receiver
From: Mark Rutland @ 2013-01-14 11:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301141204421.7475@ionos>
On Mon, Jan 14, 2013 at 11:06:31AM +0000, Thomas Gleixner wrote:
> On Wed, 9 Jan 2013, Mark Rutland wrote:
> > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
> > +extern int tick_receive_broadcast(void);
> > +#else
> > +static inline int tick_receive_broadcast(void)
> > +{
> > + return 0;
> > +}
>
> What's the inline function for? If an arch does not have broadcasting
> support it should not have a receive broadcast function call either.
That was how this was originally structured [1], but Santosh suggested this
would break the build for !GENERIC_CLOCKEVENTS_BROADCAST [1]. It means that the
arch-specific receive path (i.e. IPI handler) doesn't have to be #ifdef'd,
which makes it less ugly.
I'm happy to have it the other way, with #ifdef'd IPI handlers.
>
> > +#endif
> > +
> > #ifdef CONFIG_GENERIC_CLOCKEVENTS
> > extern void clockevents_notify(unsigned long reason, void *arg);
> > #else
> > diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
> > index f113755..5079bb7 100644
> > --- a/kernel/time/tick-broadcast.c
> > +++ b/kernel/time/tick-broadcast.c
> > @@ -125,6 +125,18 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
> > return ret;
> > }
> >
> > +int tick_receive_broadcast(void)
> > +{
> > + struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
> > + struct clock_event_device *evt = td->evtdev;
> > +
> > + if (!evt)
> > + return -ENODEV;
>
> Is anything going to use the return value?
I'd added this after looking at the x86 lapic timers, where interrupts might
remain pending over a kexec, and lapic interrupts come up before timers are
registered. The return value is useful for shutting down the timer in that case
(see x86's local_apic_timer_interrupt).
If you don't agree I'll remove the return value.
>
> Thanks,
>
> tglx
>
Thanks,
Mark.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2012-December/138486.html
^ permalink raw reply
* [PATCH 01/14] mfd: omap-usb-host: Consolidate OMAP USB-HS platform data
From: Roger Quadros @ 2013-01-14 11:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130111181331.GM14149@atomide.com>
On 01/11/2013 08:13 PM, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [130111 01:43]:
>> Tony,
>>
>> On 01/11/2013 01:45 AM, Tony Lindgren wrote:
>>> * Roger Quadros <rogerq@ti.com> [130110 08:54]:
>>>> Let's have a single platform data structure for the OMAP's High-Speed
>>>> USB host subsystem instead of having 3 separate ones i.e. one for
>>>> board data, one for USB Host (UHH) module and one for USB-TLL module.
>>>>
>>>> This makes the code much simpler and avoids creating multiple copies of
>>>> platform data.
>>>
>>> I can apply just this patch alone into an immutable branch that
>>> we all can merge in as needed as long as we have acks for the USB
>>> and MFD parts.
>>>
>>> Or does this one need to be changed based on Alan's comments
>>> on the EHCI lib related changes?
>>>
>>
>> This does not depend on EHCI lib based changes but it depends on the
>> OMAP USB Host cleanup series posted earlier.
>
> Can we first apply just the minimal platform_data + board file + clock
> changes?
>
We could, but I'll then have to make changes to the patches in the first
series and re-post them. Do you want me to do that?
> That way I can apply those to some immutable tree for everybody to use,
> and we cut off the dependency to the driver changes for the rest of the
> patches. And then I'm off the hook for the rest of the patches :)
>
Or you could just ack this patch ;). The platform data is specific to
USB host only :)
--
cheers,
-roger
^ permalink raw reply
* [PATCH 04/14] usb: phy: nop: Handle power supply regulator for the PHY
From: Russell King - ARM Linux @ 2013-01-14 11:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F3D5E2.4000102@ti.com>
On Mon, Jan 14, 2013 at 11:54:42AM +0200, Roger Quadros wrote:
> On 01/11/2013 07:17 PM, Russell King - ARM Linux wrote:
> > On Thu, Jan 10, 2013 at 06:51:24PM +0200, Roger Quadros wrote:
> >> We use "vcc" as the supply name for the PHY's power supply.
> >> The power supply will be enabled during .init() and disabled
> >> during .shutdown()
> >>
> >> Signed-off-by: Roger Quadros <rogerq@ti.com>
> >> ---
> >> drivers/usb/otg/nop-usb-xceiv.c | 18 ++++++++++++++++++
> >> 1 files changed, 18 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
> >> index 163f972..1c6db10 100644
> >> --- a/drivers/usb/otg/nop-usb-xceiv.c
> >> +++ b/drivers/usb/otg/nop-usb-xceiv.c
> >> @@ -33,11 +33,13 @@
> >> #include <linux/usb/nop-usb-xceiv.h>
> >> #include <linux/slab.h>
> >> #include <linux/clk.h>
> >> +#include <linux/regulator/consumer.h>
> >>
> >> struct nop_usb_xceiv {
> >> struct usb_phy phy;
> >> struct device *dev;
> >> struct clk *clk;
> >> + struct regulator *vcc;
> >> };
> >>
> >> static struct platform_device *pd;
> >> @@ -70,6 +72,11 @@ static int nop_init(struct usb_phy *phy)
> >> {
> >> struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev);
> >>
> >> + if (nop->vcc) {
> >> + if (regulator_enable(nop->vcc))
> >> + dev_err(phy->dev, "Failed to enable power\n");
> >> + }
> >> +
> >> if (nop->clk)
> >> clk_enable(nop->clk);
> >>
> >> @@ -82,6 +89,11 @@ static void nop_shutdown(struct usb_phy *phy)
> >>
> >> if (nop->clk)
> >> clk_disable(nop->clk);
> >> +
> >> + if (nop->vcc) {
> >> + if (regulator_disable(nop->vcc))
> >> + dev_err(phy->dev, "Failed to disable power\n");
> >> + }
> >> }
> >>
> >> static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
> >> @@ -157,6 +169,12 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)
> >> }
> >> }
> >>
> >> + nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
> >> + if (IS_ERR(nop->vcc)) {
> >> + dev_dbg(&pdev->dev, "Error getting vcc regulator\n");
> >> + nop->vcc = NULL;
> >> + }
> >
> > Is it really appropriate for drivers to do this kind of thing with
> > pointer-returning functions (I mean, setting the pointer to NULL on
> > error, rather than just using a test for IS_ERR() in the above
> > locations). You are imposing driver-local assumptions on an API.
> >
> > Practically it probably doesn't make much difference but given the
> > amount of mistakes that we have with IS_ERR_OR_NULL()...
> >
> Makes sense. I'll convert it to use IS_ERR_OR_NULL() throughout.
IS_ERR_OR_NULL() is going to be deprecated and removed. Please take a
look at how these APIs work.
If regulator support is not enabled, then devm_regulator_get() returns
NULL, and all the other regulator functions become no-ops. This is not
an error. Do you need the driver to error out if CONFIG_REGULATOR is
disabled?
If regulator support is enabled, then it can return a pointer-error
value (as defined when IS_ERR() is true, and _in that case only_ can it
be decoded by PTR_ERR() - PTR_ERR() is _only_ valid when IS_ERR()
returns true - it is _not_ valid for all the cases that IS_ERR_OR_NULL()
returns true.) Otherwise, it returns a cookie as far as the driver is
concerned for the regulator suitable for passing into the other regulator
APIs.
By having the driver do something different, and make use of NULL as its
own special sentinel, it's placing additional interpretations on the API,
which can lead to bugs. Don't do this.
If you can start making use of 'nop' vcc/clk members before they've been
"got" then initialize them to ERR_PTR(-EINVAL) first.
Also consider that when using the devm interfaces, you can do:
nop->clk = devm_clk_get(&pdev->dev, ...);
nop->vcc = devm_regulator_get(&pdev->dev, "vcc");
if (IS_ERR(nop->clk))
dev_dbg(&pdev->dev, "unable to get clock: %d\n",
PTR_ERR(nop->clk));
if (IS_ERR(nop->vcc))
dev_dbg(&pdev->dev, "unable to get vcc regulator: %d\n",
PTR_ERR(nop->vcc));
...
if (!IS_ERR(nop->clk))
clk_enable(nop->clk);
You may also consider that if you're going to print a warning for
regulator_enable(), that you should print the error code as well, so that
you know the reason why the failure happened.
Also consider... is dev_err() appropriate for an "error", for which you
print a message and continue as if nothing went wrong. To me that sounds
more like a warning than an error, so maybe dev_warn() would be more
appropriate?
^ permalink raw reply
* [PATCH v2 0/3] Use helper clockevents_config_and_register()
From: Thomas Gleixner @ 2013-01-14 11:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201301122114.07278.arnd@arndb.de>
On Sat, 12 Jan 2013, Arnd Bergmann wrote:
> On Saturday 12 January 2013, Shawn Guo wrote:
> > The clockevent core is able to figure out the best mult and shift,
> > calculate min_delta_ns and max_delta_ns, with the necessary info passed
> > into clockevents_config_and_register(). Use this handy helper to make
> > the drivers less error prone and save some LOC.
> >
> > Changes since v1:
> > - Add one patch to export clockevents_config_and_register for fixing
> > the error [1] reported by Fengguang.
> > - Add Acked-by and Tested-by tags given by people (Thanks!)
> >
> > [1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/209152
>
> Very nice series!
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Arnd, can you take the whole lot via the ARM tree? The export should
not cause any conflicts, and if it does Linus should be able to solve
it :)
Thanks,
tglx
^ permalink raw reply
* [PATCH v2] ARM: let CPUs not being able to run in ARM mode enter in THUMB mode
From: Uwe Kleine-König @ 2013-01-14 11:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357904397-8476-1-git-send-email-u.kleine-koenig@pengutronix.de>
Some ARM cores are not capable to run in ARM mode (e.g. Cortex-M3). So
obviously these cannot enter the kernel in ARM mode. Make an exception
for them and let them enter in THUMB mode.
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
Changes since (implicit) v1,
id: 1357904397-8476-1-git-send-email-u.kleine-koenig at pengutronix.de:
- drop modification to entry for MMU machines
- don't select user-visible symbols
- rename THUMBONLY_CPU to CPU_THUMBONLY
- move CPU_THUMBONLY definition further down in arch/arm/mm/Kconfig
arch/arm/Kconfig | 3 ++-
arch/arm/kernel/head-nommu.S | 8 +++++++-
arch/arm/mm/Kconfig | 9 ++++++++-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 67874b8..e04c779 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1656,8 +1656,9 @@ config HZ
default 100
config THUMB2_KERNEL
- bool "Compile the kernel in Thumb-2 mode"
+ bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY
depends on CPU_V7 && !CPU_V6 && !CPU_V6K
+ default y if CPU_THUMBONLY
select AEABI
select ARM_ASM_UNIFIED
select ARM_UNWIND
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 3782320..e8ecae2 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -32,15 +32,21 @@
* numbers for r1.
*
*/
- .arm
__HEAD
+
+#ifdef CONFIG_CPU_THUMBONLY
+ .thumb
+ENTRY(stext)
+#else
+ .arm
ENTRY(stext)
THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM.
THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
THUMB( .thumb ) @ switch to Thumb now.
THUMB(1: )
+#endif
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
@ and irqs disabled
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 3fd629d..8defd63 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -397,6 +397,13 @@ config CPU_V7
select CPU_PABRT_V7
select CPU_TLB_V7 if MMU
+config CPU_THUMBONLY
+ bool
+ # There are no CPUs available with MMU that don't implement an ARM ISA:
+ depends on !MMU
+ help
+ Select this if your CPU doesn't support the 32 bit ARM instructions.
+
# Figure out what processor architecture version we should be using.
# This defines the compiler instruction set which depends on the machine type.
config CPU_32v3
@@ -608,7 +615,7 @@ config ARCH_DMA_ADDR_T_64BIT
bool
config ARM_THUMB
- bool "Support Thumb user binaries"
+ bool "Support Thumb user binaries" if !CPU_THUMBONLY
depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
default y
help
--
1.7.10.4
^ permalink raw reply related
* [PATCHv2 3/4] clockevents: Add generic timer broadcast function
From: Thomas Gleixner @ 2013-01-14 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357742770-15028-4-git-send-email-mark.rutland@arm.com>
On Wed, 9 Jan 2013, Mark Rutland wrote:
> Currently, the timer broadcast mechanism is defined by a function
> pointer on struct clock_event_device. As the fundamental mechanism for
> broadcast is architecture-specific, this means that clock_event_device
> drivers cannot be shared across multiple architectures.
>
> This patch adds an (optional) architecture-specific function for timer
> tick broadcast, allowing drivers which may require broadcast
> functionality to be shared across multiple architectures.
Looks good.
If you fixup the first one of the series, I'll take the generic
patches and provide a branch to pull for the ARM folks, so the ARM
part can go via their tree.
Thanks,
tglx
^ permalink raw reply
* [PATCH v5 02/14] ARM: Section based HYP idmap
From: Gleb Natapov @ 2013-01-14 11:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114104952.GA4939@mudshark.cambridge.arm.com>
On Mon, Jan 14, 2013 at 10:49:53AM +0000, Will Deacon wrote:
> On Mon, Jan 14, 2013 at 10:27:21AM +0000, Gleb Natapov wrote:
> > On Tue, Jan 08, 2013 at 01:38:48PM -0500, Christoffer Dall wrote:
> > > Add a method (hyp_idmap_setup) to populate a hyp pgd with an
> > > identity mapping of the code contained in the .hyp.idmap.text
> > > section.
> > >
> > > Offer a method to drop this identity mapping through
> > > hyp_idmap_teardown.
> > >
> > > Make all the above depend on CONFIG_ARM_VIRT_EXT and CONFIG_ARM_LPAE.
> > >
> > > Cc: Will Deacon <will.deacon@arm.com>
> > > Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
> > > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > > Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
> > > ---
> > > arch/arm/include/asm/idmap.h | 1 +
> > > arch/arm/include/asm/pgtable-3level-hwdef.h | 1 +
> > > arch/arm/kernel/vmlinux.lds.S | 6 +++
> > > arch/arm/mm/idmap.c | 54 ++++++++++++++++++++++-----
> > > 4 files changed, 50 insertions(+), 12 deletions(-)
>
> [...]
>
> > > -static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
> > > +static void identity_mapping_add(pgd_t *pgd, const char *text_start,
> > > + const char *text_end, unsigned long prot)
> > > {
> > > - unsigned long prot, next;
> > > + unsigned long addr, end;
> > > + unsigned long next;
> > > +
> > > + addr = virt_to_phys(text_start);
> > > + end = virt_to_phys(text_end);
> > How does this work with phys addresses greater than 32bit (with
> > LPAE)? This was the same before the patch too, but I am still
> > curious. Since __virt_to_phys() returns unsigned long kernel cannot be
> > put in high memory, right?
>
> Well, AArch32 (arch/arm/) only supports 32-bit virtual addresses by virtue
> of the fact that our registers are only 32 bits wide, so we can't
> identity-map physical addresses above the 4GB boundary.
>
Ah, of course. This is ident map so by definition it cannot map phys
addresses above 4G. And since __virt_to_phys() suppose to work only on
ident map it's OK to returns unsigned long.
> You may want to look at the keystone patches from TI for insight about
> kernels at high (>32-bit) addresses, although I've not seen any activity
> around that for some time now (which is a pity, because the code-patching
> stuff was in a good shape).
>
> Will
--
Gleb.
^ permalink raw reply
* [PATCH 0/9] ARM: PRIMA2: bringup new CSR SiRFmarco SMP SoC
From: Arnd Bergmann @ 2013-01-14 11:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGsJ_4wxJR0y1OXEjN1wYY2BTfPXe=WJ7QC8anQMLYuywT5B2A@mail.gmail.com>
On Sunday 06 January 2013, Barry Song wrote:
> except those from Mark, would you kindly give more feedbacks about
> this series? after this, i'd like to send out a series about SiRF
> firmware based on trustzone.
Hi Barry,
Sorry for the late reply. I have looked at the patches and have no
further comments besides what Mark already mentioned.
Patch 4/9 will unfortunately conflict with the removal of struct sys_timer,
but we can probably handle that, or you base your patches on top of
the timer/cleanup branch in arm-soc.
Arnd
^ permalink raw reply
* [PATCHv2 1/4] clockevents: Add generic timer broadcast receiver
From: Thomas Gleixner @ 2013-01-14 11:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357742770-15028-2-git-send-email-mark.rutland@arm.com>
On Wed, 9 Jan 2013, Mark Rutland wrote:
> +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
> +extern int tick_receive_broadcast(void);
> +#else
> +static inline int tick_receive_broadcast(void)
> +{
> + return 0;
> +}
What's the inline function for? If an arch does not have broadcasting
support it should not have a receive broadcast function call either.
> +#endif
> +
> #ifdef CONFIG_GENERIC_CLOCKEVENTS
> extern void clockevents_notify(unsigned long reason, void *arg);
> #else
> diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
> index f113755..5079bb7 100644
> --- a/kernel/time/tick-broadcast.c
> +++ b/kernel/time/tick-broadcast.c
> @@ -125,6 +125,18 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
> return ret;
> }
>
> +int tick_receive_broadcast(void)
> +{
> + struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
> + struct clock_event_device *evt = td->evtdev;
> +
> + if (!evt)
> + return -ENODEV;
Is anything going to use the return value?
Thanks,
tglx
^ permalink raw reply
* [PATCH v3 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Felipe Balbi @ 2013-01-14 11:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F3E5E8.2000905@pengutronix.de>
On Mon, Jan 14, 2013 at 12:03:04PM +0100, Marc Kleine-Budde wrote:
> On 01/14/2013 11:53 AM, Felipe Balbi wrote:
> > Hi,
> >
> > On Mon, Jan 14, 2013 at 11:50:41AM +0100, Marc Kleine-Budde wrote:
> >> On 01/14/2013 11:39 AM, Felipe Balbi wrote:
> >>> On Mon, Jan 14, 2013 at 11:34:05AM +0100, Marc Kleine-Budde wrote:
> >>>> On 01/14/2013 11:24 AM, Felipe Balbi wrote:
> >>>>> On Mon, Jan 14, 2013 at 11:18:53AM +0100, Marc Kleine-Budde wrote:
> >>>>>> On 01/14/2013 11:16 AM, Felipe Balbi wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> On Mon, Jan 14, 2013 at 06:12:39PM +0800, Peter Chen wrote:
> >>>>>>>> @@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
> >>>>>>>>
> >>>>>>>> return fsl_udc_resume(NULL);
> >>>>>>>> }
> >>>>>>>> -
> >>>>>>>> /*-------------------------------------------------------------------------
> >>>>>>>> Register entry point for the peripheral controller driver
> >>>>>>>> --------------------------------------------------------------------------*/
> >>>>>>>> -
> >>>>>>>> +static const struct platform_device_id fsl_udc_devtype[] = {
> >>>>>>>> + {
> >>>>>>>> + .name = "imx-udc-mx25",
> >>>>>>>> + .driver_data = IMX25_UDC,
> >>>>>>>> + }, {
> >>>>>>>> + .name = "imx-udc-mx27",
> >>>>>>>> + .driver_data = IMX27_UDC,
> >>>>>>>> + }, {
> >>>>>>>> + .name = "imx-udc-mx31",
> >>>>>>>> + .driver_data = IMX31_UDC,
> >>>>>>>> + }, {
> >>>>>>>> + .name = "imx-udc-mx35",
> >>>>>>>> + .driver_data = IMX35_UDC,
> >>>>>>>> + }, {
> >>>>>>>> + .name = "imx-udc-mx51",
> >>>>>>>> + .driver_data = IMX51_UDC,
> >>>>>>>> + }
> >>>>>>>> +};
> >>>>>>>
> >>>>>>> I wonder if your driver-data is actually needed since you can use string
> >>>>>>> comparisson to achieve the exact same outcome.
> >>>>>>
> >>>>>> Why use a string compare, if the kernel infrastructure already does this
> >>>>>> for you?
> >>>>>
> >>>>> what do you mean ? What kernel infrastructure is doing waht for me ?
> >>>>
> >>>> The kernel infrastructure is doing the string compare for you to match
> >>>> the device against the driver (via platform_device_id->name). You get
> >>>> the a pointer to the driver_data for free. So you don't need any string
> >>>> compare in the driver later.
> >>>
> >>> but current driver data is just duplicating name with an integer, it's
> >>> pretty useless driver data.
> >>
> >> I don't think so - another argument:
> >> Less code. As struct platform_device_id is a static array the space is
> >> allocated anyway. So it doesn't make any difference if driver_data is
> >> NULL or not. Later you just need to make an integer comparison instead
> >> of a call to a strcmp(), if you have a switch/case and IMX*_UDC is an
> >> enum, the compiler will warn you if you've missed an IMX variant.
> >
> > fair enough, but then don't create a different enum value for each imx
> > instance if they're mostly the same. Differentiate only what's actually
> > different.
>
> Usually there isn't any Changelog between IP cores used in the different
> fsl processors (at least available outside of fsl), that makes it quite
> difficult to say if something found on one imx is really the same as on
> the other one. And they (usually) don't provide any versioning
> information in a register or the documentation.
>
> just my 2?
$SUBJECT is trying to differentiate a single feature (or maybe two) to
replace cpu_is_xxx(), then expose that on driver_data without creating
one enum value for each release from fsl.
--
balbi
-------------- 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/20130114/ade53040/attachment.sig>
^ permalink raw reply
* [PATCH v3 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Marc Kleine-Budde @ 2013-01-14 11:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114105357.GH10874@arwen.pp.htv.fi>
On 01/14/2013 11:53 AM, Felipe Balbi wrote:
> Hi,
>
> On Mon, Jan 14, 2013 at 11:50:41AM +0100, Marc Kleine-Budde wrote:
>> On 01/14/2013 11:39 AM, Felipe Balbi wrote:
>>> On Mon, Jan 14, 2013 at 11:34:05AM +0100, Marc Kleine-Budde wrote:
>>>> On 01/14/2013 11:24 AM, Felipe Balbi wrote:
>>>>> On Mon, Jan 14, 2013 at 11:18:53AM +0100, Marc Kleine-Budde wrote:
>>>>>> On 01/14/2013 11:16 AM, Felipe Balbi wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Mon, Jan 14, 2013 at 06:12:39PM +0800, Peter Chen wrote:
>>>>>>>> @@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
>>>>>>>>
>>>>>>>> return fsl_udc_resume(NULL);
>>>>>>>> }
>>>>>>>> -
>>>>>>>> /*-------------------------------------------------------------------------
>>>>>>>> Register entry point for the peripheral controller driver
>>>>>>>> --------------------------------------------------------------------------*/
>>>>>>>> -
>>>>>>>> +static const struct platform_device_id fsl_udc_devtype[] = {
>>>>>>>> + {
>>>>>>>> + .name = "imx-udc-mx25",
>>>>>>>> + .driver_data = IMX25_UDC,
>>>>>>>> + }, {
>>>>>>>> + .name = "imx-udc-mx27",
>>>>>>>> + .driver_data = IMX27_UDC,
>>>>>>>> + }, {
>>>>>>>> + .name = "imx-udc-mx31",
>>>>>>>> + .driver_data = IMX31_UDC,
>>>>>>>> + }, {
>>>>>>>> + .name = "imx-udc-mx35",
>>>>>>>> + .driver_data = IMX35_UDC,
>>>>>>>> + }, {
>>>>>>>> + .name = "imx-udc-mx51",
>>>>>>>> + .driver_data = IMX51_UDC,
>>>>>>>> + }
>>>>>>>> +};
>>>>>>>
>>>>>>> I wonder if your driver-data is actually needed since you can use string
>>>>>>> comparisson to achieve the exact same outcome.
>>>>>>
>>>>>> Why use a string compare, if the kernel infrastructure already does this
>>>>>> for you?
>>>>>
>>>>> what do you mean ? What kernel infrastructure is doing waht for me ?
>>>>
>>>> The kernel infrastructure is doing the string compare for you to match
>>>> the device against the driver (via platform_device_id->name). You get
>>>> the a pointer to the driver_data for free. So you don't need any string
>>>> compare in the driver later.
>>>
>>> but current driver data is just duplicating name with an integer, it's
>>> pretty useless driver data.
>>
>> I don't think so - another argument:
>> Less code. As struct platform_device_id is a static array the space is
>> allocated anyway. So it doesn't make any difference if driver_data is
>> NULL or not. Later you just need to make an integer comparison instead
>> of a call to a strcmp(), if you have a switch/case and IMX*_UDC is an
>> enum, the compiler will warn you if you've missed an IMX variant.
>
> fair enough, but then don't create a different enum value for each imx
> instance if they're mostly the same. Differentiate only what's actually
> different.
Usually there isn't any Changelog between IP cores used in the different
fsl processors (at least available outside of fsl), that makes it quite
difficult to say if something found on one imx is really the same as on
the other one. And they (usually) don't provide any versioning
information in a register or the documentation.
just my 2?
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130114/a34cc75b/attachment-0001.sig>
^ permalink raw reply
* Introducing Aggressive Low Memory Booster [1]
From: Bartlomiej Zolnierkiewicz @ 2013-01-14 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358091177.96940.YahooMailNeo@web160103.mail.bf1.yahoo.com>
On Sunday 13 January 2013 16:32:57 PINTU KUMAR wrote:
> Hi,
>
> Here I am trying to introduce a new feature in kernel called "Aggressive Low Memory Booster".
> The main advantage of this will be to boost the available free memory of the system to "certain level" during extremely low memory condition.
>
> Please provide your comments to improve further.
Could you please post the code somewhere so it can be reviewed?
Thanks,
--
Bartlomiej Zolnierkiewicz
Samsung Poland R&D Center
> Can it be used along with vmpressure_fd ???
>
>
> It can be invoked as follows:
> a) Automatically by kernel memory management when the memory threshold falls below 10MB.
> b) From user space program/scripts by passing the "required amount of memory to be reclaimed".
> Example: echo 100 > /dev/shrinkmem
> c) using sys interface - /sys/kernel/debug/shrinkallmem
> d) using an ioctl call and returning number of pages reclaimed.
> e) using a new system call - shrinkallmem(&nrpages);
> f) During CMA to reclaim and shrink a specific CMA regions.
>
>
> I have developed a kernel module to verify the (b) part.
>
> Here is the snapshot of the write call:
> +static ssize_t shrinkmem_write(struct file *file, const char *buff,
> + size_t length, loff_t *pos)
> +{
> + int ret = -1;
> + unsigned long memsize = 0;
> + unsigned long nr_reclaim = 0;
> + unsigned long pages = 0;
> + ret = kstrtoul_from_user(buff, length, 0, &memsize);
> + if (ret < 0) {
> + printk(KERN_ERR "[SHRINKMEM]: kstrtoul_from_user: Failed !\n");
> + return -1;
> + }
> + printk(KERN_INFO "[SHRINKMEM]: memsize(in MB) = %ld\n",
> + (unsigned long)memsize);
> + memsize = memsize*(1024UL*1024UL);
> + nr_reclaim = memsize / PAGE_SIZE;
> + pages = shrink_all_memory(nr_reclaim);
> + printk(KERN_INFO "<SHRINKMEM>: Number of Pages Freed: %lu\n", pages);
> + return pages;
> +}
> Please note: This requires CONFIG_HIBERNATION to be permanently enabled in the kernel.
>
>
> Several experiments have been performed on Ubuntu(kernel 3.3) to verify it under low memory conditions.
>
> Following are some results obtained:
> -------------------------------------
>
> Node 0, zone DMA 290 115 0 0 0 0 0 0 0 0 0
> Node 0, zone Normal 304 540 116 13 2 2 0 0 0 0 0
> =========================
> total used free shared buffers cached
> Mem: 497 487 10 0 63 303
> -/+ buffers/cache: 120 376
> Swap: 1458 34 1424
> Total: 1956 522 1434
> =========================
> Total Memory Freed: 342 MB
> Total Memory Freed: 53 MB
> Total Memory Freed: 23 MB
> Total Memory Freed: 10 MB
> Total Memory Freed: 15 MB
> Total Memory Freed: -1 MB
> Node 0, zone DMA 6 6 7 8 10 9 7 4 1 0 0
> Node 0, zone Normal 2129 2612 2166 1723 1260 759 359 108 10 0 0
> =========================
> total used free shared buffers cached
> Mem: 497 47 449 0 0 5
> -/+ buffers/cache: 41 455
> Swap: 1458 97 1361
> Total: 1956 145 1811
> =========================
>
> It was verified using a sample shell script "reclaim_memory.sh" which keeps recovering memory by doing "echo 500 > /dev/shrinkmem" until no further reclaim is possible.
>
> The experiments were performed with various scenarios as follows:
> a) Just after the boot up - (could recover around 150MB with 512MB RAM)
> b) After running many applications include youtube videos, large tar files download -
>
> [until free mem becomes < 10MB]
> [Could recover around 300MB in one shot]
> c) Run reclaim, while download is in progress and video still playing - (Not applications killed)
>
> d) revoke all background applications again, after running reclaim - (No impact, normal behavior)
> [Just it took little extra time to launch, as if it was launched for first time]
>
>
> Please see more discussions on this in the last year mailing list:
>
> https://lkml.org/lkml/2012/4/15/35
>
>
> Thank You!
> With regards,
> Pintu Kumar
> Samsung - India
^ permalink raw reply
* [PATCH v3 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Felipe Balbi @ 2013-01-14 10:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F3E301.7040509@pengutronix.de>
Hi,
On Mon, Jan 14, 2013 at 11:50:41AM +0100, Marc Kleine-Budde wrote:
> On 01/14/2013 11:39 AM, Felipe Balbi wrote:
> > On Mon, Jan 14, 2013 at 11:34:05AM +0100, Marc Kleine-Budde wrote:
> >> On 01/14/2013 11:24 AM, Felipe Balbi wrote:
> >>> On Mon, Jan 14, 2013 at 11:18:53AM +0100, Marc Kleine-Budde wrote:
> >>>> On 01/14/2013 11:16 AM, Felipe Balbi wrote:
> >>>>> Hi,
> >>>>>
> >>>>> On Mon, Jan 14, 2013 at 06:12:39PM +0800, Peter Chen wrote:
> >>>>>> @@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
> >>>>>>
> >>>>>> return fsl_udc_resume(NULL);
> >>>>>> }
> >>>>>> -
> >>>>>> /*-------------------------------------------------------------------------
> >>>>>> Register entry point for the peripheral controller driver
> >>>>>> --------------------------------------------------------------------------*/
> >>>>>> -
> >>>>>> +static const struct platform_device_id fsl_udc_devtype[] = {
> >>>>>> + {
> >>>>>> + .name = "imx-udc-mx25",
> >>>>>> + .driver_data = IMX25_UDC,
> >>>>>> + }, {
> >>>>>> + .name = "imx-udc-mx27",
> >>>>>> + .driver_data = IMX27_UDC,
> >>>>>> + }, {
> >>>>>> + .name = "imx-udc-mx31",
> >>>>>> + .driver_data = IMX31_UDC,
> >>>>>> + }, {
> >>>>>> + .name = "imx-udc-mx35",
> >>>>>> + .driver_data = IMX35_UDC,
> >>>>>> + }, {
> >>>>>> + .name = "imx-udc-mx51",
> >>>>>> + .driver_data = IMX51_UDC,
> >>>>>> + }
> >>>>>> +};
> >>>>>
> >>>>> I wonder if your driver-data is actually needed since you can use string
> >>>>> comparisson to achieve the exact same outcome.
> >>>>
> >>>> Why use a string compare, if the kernel infrastructure already does this
> >>>> for you?
> >>>
> >>> what do you mean ? What kernel infrastructure is doing waht for me ?
> >>
> >> The kernel infrastructure is doing the string compare for you to match
> >> the device against the driver (via platform_device_id->name). You get
> >> the a pointer to the driver_data for free. So you don't need any string
> >> compare in the driver later.
> >
> > but current driver data is just duplicating name with an integer, it's
> > pretty useless driver data.
>
> I don't think so - another argument:
> Less code. As struct platform_device_id is a static array the space is
> allocated anyway. So it doesn't make any difference if driver_data is
> NULL or not. Later you just need to make an integer comparison instead
> of a call to a strcmp(), if you have a switch/case and IMX*_UDC is an
> enum, the compiler will warn you if you've missed an IMX variant.
fair enough, but then don't create a different enum value for each imx
instance if they're mostly the same. Differentiate only what's actually
different.
--
balbi
-------------- 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/20130114/e755c1c5/attachment.sig>
^ permalink raw reply
* [PATCH v3 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Marc Kleine-Budde @ 2013-01-14 10:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114103952.GF10874@arwen.pp.htv.fi>
On 01/14/2013 11:39 AM, Felipe Balbi wrote:
> On Mon, Jan 14, 2013 at 11:34:05AM +0100, Marc Kleine-Budde wrote:
>> On 01/14/2013 11:24 AM, Felipe Balbi wrote:
>>> On Mon, Jan 14, 2013 at 11:18:53AM +0100, Marc Kleine-Budde wrote:
>>>> On 01/14/2013 11:16 AM, Felipe Balbi wrote:
>>>>> Hi,
>>>>>
>>>>> On Mon, Jan 14, 2013 at 06:12:39PM +0800, Peter Chen wrote:
>>>>>> @@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
>>>>>>
>>>>>> return fsl_udc_resume(NULL);
>>>>>> }
>>>>>> -
>>>>>> /*-------------------------------------------------------------------------
>>>>>> Register entry point for the peripheral controller driver
>>>>>> --------------------------------------------------------------------------*/
>>>>>> -
>>>>>> +static const struct platform_device_id fsl_udc_devtype[] = {
>>>>>> + {
>>>>>> + .name = "imx-udc-mx25",
>>>>>> + .driver_data = IMX25_UDC,
>>>>>> + }, {
>>>>>> + .name = "imx-udc-mx27",
>>>>>> + .driver_data = IMX27_UDC,
>>>>>> + }, {
>>>>>> + .name = "imx-udc-mx31",
>>>>>> + .driver_data = IMX31_UDC,
>>>>>> + }, {
>>>>>> + .name = "imx-udc-mx35",
>>>>>> + .driver_data = IMX35_UDC,
>>>>>> + }, {
>>>>>> + .name = "imx-udc-mx51",
>>>>>> + .driver_data = IMX51_UDC,
>>>>>> + }
>>>>>> +};
>>>>>
>>>>> I wonder if your driver-data is actually needed since you can use string
>>>>> comparisson to achieve the exact same outcome.
>>>>
>>>> Why use a string compare, if the kernel infrastructure already does this
>>>> for you?
>>>
>>> what do you mean ? What kernel infrastructure is doing waht for me ?
>>
>> The kernel infrastructure is doing the string compare for you to match
>> the device against the driver (via platform_device_id->name). You get
>> the a pointer to the driver_data for free. So you don't need any string
>> compare in the driver later.
>
> but current driver data is just duplicating name with an integer, it's
> pretty useless driver data.
I don't think so - another argument:
Less code. As struct platform_device_id is a static array the space is
allocated anyway. So it doesn't make any difference if driver_data is
NULL or not. Later you just need to make an integer comparison instead
of a call to a strcmp(), if you have a switch/case and IMX*_UDC is an
enum, the compiler will warn you if you've missed an IMX variant.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130114/fb23c595/attachment.sig>
^ permalink raw reply
* [PATCH v5 02/14] ARM: Section based HYP idmap
From: Will Deacon @ 2013-01-14 10:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114102721.GB4751@redhat.com>
On Mon, Jan 14, 2013 at 10:27:21AM +0000, Gleb Natapov wrote:
> On Tue, Jan 08, 2013 at 01:38:48PM -0500, Christoffer Dall wrote:
> > Add a method (hyp_idmap_setup) to populate a hyp pgd with an
> > identity mapping of the code contained in the .hyp.idmap.text
> > section.
> >
> > Offer a method to drop this identity mapping through
> > hyp_idmap_teardown.
> >
> > Make all the above depend on CONFIG_ARM_VIRT_EXT and CONFIG_ARM_LPAE.
> >
> > Cc: Will Deacon <will.deacon@arm.com>
> > Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
> > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
> > ---
> > arch/arm/include/asm/idmap.h | 1 +
> > arch/arm/include/asm/pgtable-3level-hwdef.h | 1 +
> > arch/arm/kernel/vmlinux.lds.S | 6 +++
> > arch/arm/mm/idmap.c | 54 ++++++++++++++++++++++-----
> > 4 files changed, 50 insertions(+), 12 deletions(-)
[...]
> > -static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
> > +static void identity_mapping_add(pgd_t *pgd, const char *text_start,
> > + const char *text_end, unsigned long prot)
> > {
> > - unsigned long prot, next;
> > + unsigned long addr, end;
> > + unsigned long next;
> > +
> > + addr = virt_to_phys(text_start);
> > + end = virt_to_phys(text_end);
> How does this work with phys addresses greater than 32bit (with
> LPAE)? This was the same before the patch too, but I am still
> curious. Since __virt_to_phys() returns unsigned long kernel cannot be
> put in high memory, right?
Well, AArch32 (arch/arm/) only supports 32-bit virtual addresses by virtue
of the fact that our registers are only 32 bits wide, so we can't
identity-map physical addresses above the 4GB boundary.
You may want to look at the keystone patches from TI for insight about
kernels at high (>32-bit) addresses, although I've not seen any activity
around that for some time now (which is a pity, because the code-patching
stuff was in a good shape).
Will
^ permalink raw reply
* [PATCH 0/4] gpio: introduce descriptor-based interface
From: Arnd Bergmann @ 2013-01-14 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F3DC2B.6000603@nvidia.com>
On Monday 14 January 2013, Alex Courbot wrote:
> On 01/10/2013 07:08 PM, Arnd Bergmann wrote:
> > I found two that provide the generic gpio interfaces when gpiolib
> > is disabled, but use gpiolib otherwise for the same hardware,
> > arch/m68k/include/asm/mcfgpio.h and arch/blackfin/include/asm/gpio.h.
> > I would assume that we can simply remove the non-gpiolib shortcut
> > here at cost of a small overhead.
>
> I performed a search on my side too (checking configurations options
> which select GENERIC_GPIO but not ARCH_REQUIRE_GPIOLIB) and found the
> same list. This takes some time btw - many platforms use this combo to
> make GPIO support optional. Can I ask how you figured out these two archs?
I basically grepped for GENERIC_GPIO and looked at
the individual implementations.
> > Then there are a bunch that use gpiolib but have a nontrivial
> > implementation of gpio_get_value and other functions. I'm not sure
> > if these are a problematic with your code.
>
> AFAICT these all implement an inline path that bypasses GPIOlib when the
> GPIO number is known at compile time, for faster bitbanging I presume.
> It should be totally harmless to keep them. Unfortunately, I don't think
> it would be possible to have a similar trick using handlers.
Right, makes sense.
Arnd
^ permalink raw reply
* [PATCH 1/6] ARM: common: vic: Parse interrupt and resume masks from device tree
From: Tomasz Figa @ 2013-01-14 10:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F35AA1.1010902@gmail.com>
Hi Rob,
2013/1/14 Rob Herring <robherring2@gmail.com>:
> On 01/12/2013 07:10 PM, Tomasz Figa wrote:
>> This patch extends vic_of_init to parse valid interrupt sources
>> and resume sources masks from device tree.
>>
>> If mask values are not specified in device tree, all sources
>> are assumed to be valid, as before this patch.
>>
>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>> ---
>> Documentation/devicetree/bindings/arm/vic.txt | 6 ++++++
>> arch/arm/common/vic.c | 7 ++++++-
>> 2 files changed, 12 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
>> index 266716b..bb7137c 100644
>> --- a/Documentation/devicetree/bindings/arm/vic.txt
>> +++ b/Documentation/devicetree/bindings/arm/vic.txt
>> @@ -18,6 +18,9 @@ Required properties:
>> Optional properties:
>>
>> - interrupts : Interrupt source for parent controllers if the VIC is nested.
>> +- interrupt-mask : Bit mask of valid interrupt sources (defaults to all valid)
>
> Can you explain why this is needed and is not just the OR of all
> interrupts described in the DT?
Well, it depends what you mean with interrupts described in the DT.
Basically this mask is used for sanity checks of request_irq calls,
by denying interrupts non-existent on given platform.
>> +- wakeup-mask : Bit mask of interrupt sources that can wake up the system
>> + (defaults to all allowed)
>
> Seems like this would be all VIC interrupts unless the wake-up handling
> is done in some shadow controller. If the former is true, then wake-up
> capability is really a property of individual devices. If the later,
> then this property would belong in that shadow controller.
Yes, there is a shadow controller used for configuring which of the available
wake-up signals shall be used.
Still, I don't see how I should model it in the device tree, since its VIC whose
set_irq_wake callback is called.
Before Device Tree, both interrupt and wake-up masks were being passed
as arguments to vic_init function. This is what made me add them as
DT attributes of VIC.
Best regards,
Tomasz Figa
P.S. Rob, sorry for the original message. I have clicked "reply"
instead of "reply to all" in the mobile GMail client.
> Rob
>
>>
>> Example:
>>
>> @@ -26,4 +29,7 @@ Example:
>> interrupt-controller;
>> #interrupt-cells = <1>;
>> reg = <0x60000 0x1000>;
>> +
>> + interrupt-mask = <0xffffff7f>;
>> + wakeup-mask = <0x0000ff7f>;
>> };
>> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
>> index e4df17c..c2889da 100644
>> --- a/arch/arm/common/vic.c
>> +++ b/arch/arm/common/vic.c
>> @@ -407,6 +407,8 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
>> int __init vic_of_init(struct device_node *node, struct device_node *parent)
>> {
>> void __iomem *regs;
>> + u32 interrupt_mask = ~0;
>> + u32 wakeup_mask = ~0;
>>
>> if (WARN(parent, "non-root VICs are not supported"))
>> return -EINVAL;
>> @@ -415,10 +417,13 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
>> if (WARN_ON(!regs))
>> return -EIO;
>>
>> + of_property_read_u32(node, "interrupt-mask", &interrupt_mask);
>> + of_property_read_u32(node, "wakeup-mask", &wakeup_mask);
>> +
>> /*
>> * Passing -1 as first IRQ makes the simple domain allocate descriptors
>> */
>> - __vic_init(regs, -1, ~0, ~0, node);
>> + __vic_init(regs, -1, interrupt_mask, wakeup_mask, node);
>>
>> return 0;
>> }
>>
>
^ permalink raw reply
* [PATCH 4/4] ARM: tegra: Set SCU base address dynamically from DT
From: Hiroshi Doyu @ 2013-01-14 10:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50CF258E.2080207@gmail.com>
Rob Herring <robherring2@gmail.com> wrote @ Mon, 17 Dec 2012 15:00:46 +0100:
> On 12/17/2012 12:18 AM, Hiroshi Doyu wrote:
> > Set Snoop Control Unit(SCU) register base address dynamically from DT.
> >
> > Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
> > ---
> > arch/arm/mach-tegra/platsmp.c | 23 ++++++++++++++++++++---
> > 1 file changed, 20 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
> > index 1b926df..45c0b79 100644
> > --- a/arch/arm/mach-tegra/platsmp.c
> > +++ b/arch/arm/mach-tegra/platsmp.c
> > @@ -18,6 +18,8 @@
> > #include <linux/jiffies.h>
> > #include <linux/smp.h>
> > #include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> >
> > #include <asm/cacheflush.h>
> > #include <asm/hardware/gic.h>
> > @@ -36,7 +38,7 @@
> >
> > extern void tegra_secondary_startup(void);
> >
> > -static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
> > +static void __iomem *scu_base;
> >
> > #define EVP_CPU_RESET_VECTOR \
> > (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
> > @@ -143,14 +145,28 @@ done:
> > return status;
> > }
> >
> > +static const struct of_device_id cortex_a9_scu_match[] __initconst = {
> > + { .compatible = "arm,cortex-a9-scu", },
> > + {}
> > +};
> > +
> > /*
> > * Initialise the CPU possible map early - this describes the CPUs
> > * which may be present or become present in the system.
> > */
> > static void __init tegra_smp_init_cpus(void)
> > {
> > - unsigned int i, ncores = scu_get_core_count(scu_base);
> > + struct device_node *np;
> > + unsigned int i, ncores = 1;
> > +
> > + np = of_find_matching_node(NULL, cortex_a9_scu_match);
> > + if (!np)
> > + return;
> > + scu_base = of_iomap(np, 0);
>
> Did you actually test this? Unless something changed, ioremap does not
> work this early. The only reason to have it mapped this early is to get
> the core count, but that doesn't work on A15 or A7. So we really need to
> get core count/mask in a standard way. At least some work to get core
> count from DT went into 3.8.
>
> BTW, you can get the scu address on the A9 by reading cp15 register:
>
> /* Get SCU base */
> asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
>
> It's still probably good to have the DT node, but the reg property can
> be optional in this case.
>
> We need to move away from having the DT matching code within the
> platforms. This should all be moved to the scu code in a scu_of_init
> function that could be called from common code.
If we can get SCU base address from CP15, do we still need SCU entry
in DT? If not, the following would be the only API to get SCU base?
>From 9bbecb50759f39d9c762977145407ea4f8a4d5ac Mon Sep 17 00:00:00 2001
From: Hiroshi Doyu <hdoyu@nvidia.com>
Date: Mon, 14 Jan 2013 12:35:33 +0200
Subject: [PATCH 1/1] ARM: Add API to detect SCU base address from CP15
Add API to detect SCU base address from CP15.
Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
---
arch/arm/include/asm/smp_scu.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index 4eb6d00..6015ede 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -6,6 +6,20 @@
#define SCU_PM_POWEROFF 3
#ifndef __ASSEMBLER__
+static inline phys_addr_t scu_get_base(void)
+{
+ phys_addr_t pa;
+ unsigned long part_number = read_cpuid_part_number();
+
+ switch (part_number) {
+ case ARM_CPU_PART_CORTEX_A9:
+ /* Get SCU physical base */
+ asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa));
+ return pa;
+ default:
+ return 0;
+ }
+}
unsigned int scu_get_core_count(void __iomem *);
void scu_enable(void __iomem *);
int scu_power_mode(void __iomem *, unsigned int);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Felipe Balbi @ 2013-01-14 10:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F3DF1D.3040706@pengutronix.de>
On Mon, Jan 14, 2013 at 11:34:05AM +0100, Marc Kleine-Budde wrote:
> On 01/14/2013 11:24 AM, Felipe Balbi wrote:
> > On Mon, Jan 14, 2013 at 11:18:53AM +0100, Marc Kleine-Budde wrote:
> >> On 01/14/2013 11:16 AM, Felipe Balbi wrote:
> >>> Hi,
> >>>
> >>> On Mon, Jan 14, 2013 at 06:12:39PM +0800, Peter Chen wrote:
> >>>> @@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
> >>>>
> >>>> return fsl_udc_resume(NULL);
> >>>> }
> >>>> -
> >>>> /*-------------------------------------------------------------------------
> >>>> Register entry point for the peripheral controller driver
> >>>> --------------------------------------------------------------------------*/
> >>>> -
> >>>> +static const struct platform_device_id fsl_udc_devtype[] = {
> >>>> + {
> >>>> + .name = "imx-udc-mx25",
> >>>> + .driver_data = IMX25_UDC,
> >>>> + }, {
> >>>> + .name = "imx-udc-mx27",
> >>>> + .driver_data = IMX27_UDC,
> >>>> + }, {
> >>>> + .name = "imx-udc-mx31",
> >>>> + .driver_data = IMX31_UDC,
> >>>> + }, {
> >>>> + .name = "imx-udc-mx35",
> >>>> + .driver_data = IMX35_UDC,
> >>>> + }, {
> >>>> + .name = "imx-udc-mx51",
> >>>> + .driver_data = IMX51_UDC,
> >>>> + }
> >>>> +};
> >>>
> >>> I wonder if your driver-data is actually needed since you can use string
> >>> comparisson to achieve the exact same outcome.
> >>
> >> Why use a string compare, if the kernel infrastructure already does this
> >> for you?
> >
> > what do you mean ? What kernel infrastructure is doing waht for me ?
>
> The kernel infrastructure is doing the string compare for you to match
> the device against the driver (via platform_device_id->name). You get
> the a pointer to the driver_data for free. So you don't need any string
> compare in the driver later.
but current driver data is just duplicating name with an integer, it's
pretty useless driver data.
--
balbi
-------------- 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/20130114/f338144b/attachment.sig>
^ 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