* [PATCH v6 00/12] iommu/exynos: Fixes and Enhancements of System MMU driver with DT
From: KyongHo Cho @ 2013-01-16 16:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50EC9C71.7010909@gmail.com>
On Wed, Jan 9, 2013 at 7:23 AM, Sylwester Nawrocki
<sylvester.nawrocki@gmail.com> wrote:
> On 01/07/2013 11:45 AM, KyongHo Cho wrote:
>>>
>>> > The current exynos-iommu(System MMU) driver does not work autonomously
>>> > since it is lack of support for power management of peripheral blocks.
>>> > For example, MFC device driver must ensure that its System MMU is
>>
>> disabled
>>>
>>> > before MFC block is power-down not to invalidate IOTLB in the System
>>> > MMU
>>> > when I/O memory mapping is changed. Because A System MMU is resides
>>
>> in the
>>>
>>> > same H/W block, access to control registers of System MMU while the H/W
>>> > block is turned off must be prohibited.
>>> >
>>> > This set of changes solves the above problem with setting each System
>>
>> MMUs
>>>
>>> > as the parent of the device which owns the System MMU to recieve the
>>> > information when the device is turned off or turned on.
>>>
>>>
>>> I intend to make Exynos4412 FIMC-LITEn (Exynos5 CAMIFn) devices child
>>> devices of the FIMC-IS (camera ISP) platform device. This patch reflects
>>> that: http://patchwork.linuxtv.org/patch/16046
>>>
>>> This is required since AFAIK FIMC-LITE depends on clocks from FIMC-IS.
>>> By setting fimc-is device as the parent fimc-lite's dependency on it is
>>> resolved without any hacks between these drivers.
>>>
>>> Then how this tree will look like after your sysmmu related
>>> re-parenting:
>>>
>>> fimc-is
>>> / \
>>> fimc-lite0 fimc-lite1
>>>
>>>
>>> ?
>>
>>
>> First of all, I think that clock dependency shuold be resolved with
>> setting the parent of clock descriptor of fimc-lite to the clock
>> descriptor of fimc-is.
>
>
> I'll need to investigate it more, but AFAIU there is more than one clock
> for the FIMC-IS device that needs to be enabled before FIMC-LITE can be
> used. IOW FIMC-LITE must be activated after FIMC-IS, and deactivated before
> FIMC-IS is (runtime) suspended.
>
> So I'm afraid I can't simply alter the clock tree for the sake of the
> subsystem dependencies - it's not a one-to-one relation and it doesn't
> sound right.
I have just little knowledge about FIMC-IS.
I don't understand why the sequence of power gating or suspend/resume
is important.
Are you concerning about the dependency of clock gating?
If the drivers of FIMC-IS and FIMC-LITE are not dependent upon each other,
I think it is just enough to add them to the same power domain.
I will check the clock description in the devicetree.
>
>> If you are concerning about power management, it is simply resolved with
>> putting fimc-lite to the power domain of fimc-is.
>
>
> Yes, these devices are already registered to same power domain (ISP).
>
>
>> The above tree will be changed like below after probing System MMU:
>> sysmmu-fimc-is
>> I
>> fimc-is
>>
>> sysmmu-fimc-lite0
>> I
>> fimc-lite0
>>
>> sysmmu-fimc-lite1
>> I
>> fimc-lite1
>
>
> I'm just concerned that this iommu driver would drop previous parent
> configurations and introduce its own. There might be other devices for
> which this would be harmful. Didn't you consider just moving any existing
> device's parent and setting it as iommu's parent, so the tree looks like
>
> sysmmu-fimc-is
> |
> fimc-is
> / \
> sysmmu-fimc-lite0 sysmmu-fimc-lite1
> | |
> fimc-lite0 fimc-lite1
>
> ?
>
> But it's not really much better...
Thanks for the proposal. I will consider to insert System MMU in the
existing dpm and rpm tree
without breaking the existing tree.
I did not find a better solution to guarantee that the System MMU is
always resumed
before its master (like fimc-lite0) is resumed and suspended after its
master is suspended.
It must be guaranteed in terms of APM and Runtime PM.
>>> > Another big change to the driver is the support for devicetree.
>>> > The bindings for System MMU is described in
>>> > Documentation/devicetree/bindings/arm/samsung/system-mmu.txt
>>>
>>>
>>> Yes, and there is no patch adding this file in this series. Let me paste
>>> it here:
>>>
>>> From 88987ff5b77acc7211b9f537a6ef6ea38e3efdd0 Mon Sep 17 00:00:00 2001
>>> From: KyongHo Cho <pullip.cho@samsung.com
>>> <mailto:pullip.cho@samsung.com>>
>>>
>>> Date: Tue, 11 Dec 2012 14:06:25 +0900
>>> Subject: [PATCH] ARM: EXYNOS: add System MMU definition to DT
>>>
>>> This commit adds System MMU nodes to DT of Exynos SoCs.
>>>
>>> Signed-off-by: KyongHo Cho <pullip.cho@samsung.com
>>
>> <mailto:pullip.cho@samsung.com>>
>>>
>>> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com
>>
>> <mailto:kgene.kim@samsung.com>>
>>
>>> ---
>>> .../devicetree/bindings/arm/exynos/system-mmu.txt | 86 ++++++++++++
>>> arch/arm/boot/dts/exynos4210.dtsi | 96 +++++++++++++
>>> arch/arm/boot/dts/exynos4x12.dtsi | 124
>>
>> +++++++++++++++++
>>>
>>> arch/arm/boot/dts/exynos5250.dtsi | 147
>>
>> +++++++++++++++++++-
>>>
>>> 4 files changed, 451 insertions(+), 2 deletions(-)
>>> create mode 100644
>>
>> Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
>>>
>>>
>>> diff --git
>>
>> a/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
>> b/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
>>>
>>> new file mode 100644
>>> index 0000000..b33d682
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
>>> @@ -0,0 +1,86 @@
>>> +* Samsung Exynos System MMU
>>> +
>>> +Samsung's Exynos architecture includes System MMU that enables
>>> scattered
>>> +physical chunks to be visible as a contiguous region to DMA-capabile
>>
>> peripheral
>>>
>>> +devices like MFC, FIMC, FIMD, GScaler, FIMC-IS and so forth.
>>> +
>>> +System MMU is a sort of IOMMU and support identical translation table
>>
>> format to
>>>
>>> +ARMv7 translation tables with minimum set of page properties
>>
>> including access
>>>
>>> +permissions, shareability and security protection. In addition System
>>
>> MMU has
>>>
>>> +another capabilities like L2 TLB or block-fetch buffers to minimize
>>
>> translation
>>>
>>> +latency
>>> +
>>> +Each System MMU is included in the H/W block of a peripheral device.
>>
>> Thus, it is
>>>
>>> +important to specify that a System MMU is dedicated to which
>>
>> peripheral device
>>>
>>> +before using System MMU. System initialization must specify the
>>
>> relationships
>>>
>>> +between a System MMU and a peripheral device that owns the System MMU.
>>> +
>>> +Some device drivers may control several peripheral devices with a
>>
>> single device
>>>
>>> +descriptor like MFC. Since handling a System MMU with IOMMU API
>>
>> requires a
>>>
>>> +device descriptor that needs the System MMU, it is best to combine
>>
>> the System
>>>
>>> +MMUs of the peripheral devices and control them with a single System
>>
>> MMU device
>>>
>>> +descriptor. If it is unable to combine them into a single device
>>
>> descriptor,
>>>
>>> +they can be linked with each other by the means of device.parent
>>
>> relationship.
>>>
>>> +
>>> +Required properties:
>>> +- compatible: Should be "samsung,exynos-sysmmu".
>>> +- reg: Tuples of base address and size of System MMU registers. The
>>
>> number of
>>>
>>> + tuples can be more than one if two or more System MMUs are
>>
>> controlled
>>>
>>> + by a single device descriptor.
>>> +- interrupt-parent: The phandle of the interrupt controller of System
>>> MMU
>>> +- interrupts: Tuples of numbers that indicates the interrupt source.
>>> The
>>> + number of elements in the tuple is dependent upon
>>> + 'interrupt-parent' property. The number of tuples in this property
>>> + must be the same with 'reg' property.
>>> +
>>> +Optional properties:
>>> +- mmuname: Strings of the name of System MMU for debugging purpose.
>>
>> The number
>>>
>>> + of strings must be the same with the number of tuples in
>>> 'reg'
>>> + property.
>>>
>>> As commented on previous patch, this isn't something that belongs here.
>>> But for debugging you could probably retrieve this from the node name ?
>>
>>
>> Thank you for good idea. However mmuname is an array of strings,
>> actually. Anyway I agree with your opinion that 'mmuname' is not proper
>> property of a device node. I will remove it and substitute it with base
>> register address of a System MMU.
>
>
> Ok.
>
>
>>> +- mmu-master: phandle to the device node that owns System MMU. Only
>>
>> the device
>>>
>>> + that is specified whith this property can control System
>>
>> MMU with
>>>
>>> + IOMMU API.
>>> +
>>> +Examples:
>>> +
>>> +MFC has 2 System MMUs for each port that MFC is attached. Thus it
>>
>> seems natural
>>>
>>> +to define 2 System MMUs for each port of the MFC:
>
>
> "The video codec (MFC) device has a System MMUs for each port (AXI master).
> Thus it seems natural to define a System MMU device node for each port of
>
> the MFC:"
Thanks. I think your expression is easier to understand.
I am also not a good English writer :)
>>> +
>>> + sysmmu-mfc-l {
>>> + mmuname = "mfc_l";
>>> + reg = <0x11210000 0x1000>;
>>> + compatible = "samsung,exynos-sysmmu";
>>> + interrupt-parent = <&combiner>;
>>> + interrupts = <8 5>;
>>> + mmu-master = <&mfc>;
>>> + };
>>> +
>>> + sysmmu-mfc-r {
>>> + mmuname = "mfc_r";
>>> + reg = <0x11200000 0x1000>;
>>> + compatible = "samsung,exynos-sysmmu";
>>> + interrupt-parent = <&combiner>;
>>> + interrupts = <6 2>;
>>> + mmu-master = <&mfc>;
>>> + };
>>> +
>>> +Actually, MFC device driver requires sub-devices that represents each
>>
>> port and
>>>
>>> +above 'mmu-master' properties of sysmmu-mfc-l and sysmmu-mfc-r have
>>
>> the phandles
>>>
>>> +to those sub-devices.
>>>
>>> I find this sentence really difficult to parse. This documentation
>>
>> should talk
>>>
>>> about how the device is designed and represented, rather than about
>>
>> its driver.
>>>
>>>
>> OK. I will trying to find another expression easy to understand. Do you
>> have any suggestion?
>
>
> I'm not a native English speaker, but maybe something like this makes sense:
>
> "The sysmmu-mfc-l, sysmmy-mfc-r nodes represent parts of the MFC device
> which
> indicate their 'mmu-master' phandles pointing to the mfc node."
I understand what you have intended.
Thank you for the suggestion. I will consider to make it easy to understand.
>
> ?
>
>>> +However, it is also a good idea that treats the above System MMUs as
>
>
> treats -> treat
>
Thanks.
>
>> one System
>>>
>>> +MMU because those System MMUs are actually required by the MFC device:
>>> +
>>> + sysmmu-mfc {
>>> + mmuname = "mfc_l", "mfc_r";
>>> + reg = <0x11210000 0x1000
>>> + 0x11200000 0x1000>;
>>> + compatible = "samsung,exynos-sysmmu";
>>> + interrupt-parent = <&combiner>;
>>> + interrupts = <8 5
>>> + 6 2>;
>
>
> interrupts = <8 5>, <6 2>; ?
>
Please see my reply below.
>
>>> + mmu-master = <&mfc>;
>>> + };
>>> +
>>> +If System MMU of MFC is defined like the above, the number of
>>
>> elements and the
>>>
>>> +order of list in 'mmuname', 'reg' and 'interrupts' must be the same.
>
> ...
>
>>> diff --git a/arch/arm/boot/dts/exynos5250.dtsi
>>
>> b/arch/arm/boot/dts/exynos5250.dtsi
>>>
>>> index 2e3b6ef..2ff6d78 100644
>>> --- a/arch/arm/boot/dts/exynos5250.dtsi
>>> +++ b/arch/arm/boot/dts/exynos5250.dtsi
>>> @@ -75,7 +75,7 @@
>>> interrupts = <0 42 0>;
>>> };
>>>
> ...
>
>>> + sysmmu-is0 {
>>> + mmuname = "isp", "drc", "scalerc", "scalerp", "fd",
>>> "mcu";
>>> + reg = < 0x13260000 0x1000
>>> + 0x13270000 0x1000
>>> + 0x13280000 0x1000
>>> + 0x13290000 0x1000
>>> + 0x132A0000 0x1000
>>> + 0x132B0000 0x1000 >;
>>> + compatible = "samsung,exynos-sysmmu";
>>> + interrupt-parent = <&combiner>;
>>> + interrupts = < 10 6
>>> + 11 6
>>> + 5 2
>>> + 3 6
>>> + 5 0
>>> + 5 4 >;
>>>
>>> I believe this should be
>>>
>>> interrupts = <10 6>, <11 6>, <5 2>,
>>> <3 6>, <5 0>, <5 4>;
>>>
>> I found the syntax of array of resources in the specifications of device
>> tree. I found that it works correctly.
>
>
> OK, it seems both conventions are valid. I just found it unusual, since
> all interrupt specifiers I've seen for Samsung SoCs use the syntax, where
> each interrupt is enclosed in triangular brackets. Maybe it's better to
> keep it consistent across all files ?
Let me check the other dts/dti and change my expression to follow the
convention:)
Sorry for late reply. I have just little time to spend after work in
these days. :(
Thank you for kind review.
KyongHo
^ permalink raw reply
* [PATCH v5 06/14] ARM: EXYNOS: add System MMU definition to DT
From: Hiroshi Doyu @ 2013-01-16 16:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130116115114.GB16543@mudshark.cambridge.arm.com>
Will Deacon <will.deacon@arm.com> wrote @ Wed, 16 Jan 2013 12:51:14 +0100:
> On Tue, Dec 11, 2012 at 11:09:47AM +0000, Cho KyongHo wrote:
> > This commit adds System MMU nodes to DT of Exynos SoCs.
>
> [Adding devicetree-discuss and some other IOMMU/DT people to CC]
>
> > Signed-off-by: KyongHo Cho <pullip.cho@samsung.com>
> > ---
> > .../devicetree/bindings/arm/exynos/system-mmu.txt | 86 ++++++++++++
> > arch/arm/boot/dts/exynos4210.dtsi | 96 ++++++++++++++
> > arch/arm/boot/dts/exynos4x12.dtsi | 124 +++++++++++++++++
> > arch/arm/boot/dts/exynos5250.dtsi | 147 ++++++++++++++++++++-
> > 4 files changed, 451 insertions(+), 2 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
nit, we have this doc in Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt.
Probably under Documentation/devicetree/bindings/iommu, it's easier to
find the similarity among SoC IOMMUs.
> > diff --git a/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
> > b/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
> > new file mode 100644
> > index 0000000..9c30a36
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
> > @@ -0,0 +1,86 @@
> > +* Samsung Exynos System MMU
> > +
> > +Samsung's Exynos architecture includes System MMU that enables scattered
> > +physical chunks to be visible as a contiguous region to DMA-capabile peripheral
> > +devices like MFC, FIMC, FIMD, GScaler, FIMC-IS and so forth.
> > +
> > +System MMU is a sort of IOMMU and support identical translation table format to
> > +ARMv7 translation tables with minimum set of page properties including access
> > +permissions, shareability and security protection. In addition System MMU has
> > +another capabilities like L2 TLB or block-fetch buffers to minimize translation
> > +latency
>
> ARMv7 has two translation table formats -- please specify which ones you
> support. Stage-2 descriptors also have a few differences, so you should
> describe what you actually support.
>
> > +Each System MMU is included in the H/W block of a peripheral device. Thus, it is
> > +important to specify that a System MMU is dedicated to which peripheral device
> > +before using System MMU. System initialization must specify the relationships
> > +between a System MMU and a peripheral device that owns the System MMU.
> > +
> > +Some device drivers may control several peripheral devices with a single device
> > +descriptor like MFC. Since handling a System MMU with IOMMU API requires a
> > +device descriptor that needs the System MMU, it is best to combine the System
> > +MMUs of the peripheral devices and control them with a single System MMU device
> > +descriptor. If it is unable to combine them into a single device descriptor,
> > +they can be linked with each other by the means of device.parent relationship.
>
> I agree with the sentiment here, but I don't think your solution really
> caters for the generic case (outside of exynos). For example, I've recently
> started looking at writing an IOMMU driver for ARM's System MMU
> Architecture, where a likely use-case is for an SoC where there are a bunch
> of MMIO devices, with subsets of these devices assigned to different IOMMUs.
> This is similar to your scenario, except that the System MMU is not
> necessarily tied to a specific hardware block:
>
>
> Bus
> =========================================
> || ||
> +----------+ +----------+
> | IOMMU0 | | IOMMU1 |
> +----------+ +----------+
> | | | |
> | | | |
> Device0 Device1 Device2 Device3
>
>
> From Linux's perspective, all of these devices sit on the platform bus
> and are probed using device tree. That is where the fun starts: because
> the platform bus has only one set of iommu_ops associated with it, the
> driver needs to handle each IOMMU instance explicitly, choosing the
> appropriate one for the device when setting up or tearing down an I/O
> mapping. To complicate this further, each device has a unique StreamID
> assigned statically in the hardware which is required when programming
> the IOMMU in order to describe translations for a particular bus master.
>
> In this case, your mmu-master property doesn't work because there are a
> multiple devices sharing an IOMMU. Furthermore, the StreamIDs for each
> client device need to encoded somewhere as well.
>
> Given that this information is not discoverable, it needs to be encoded
> in the device tree, but where? I can see two approaches:
>
> 1. For each IOMMU node, list phandles to the devices connected to it
> and have a corresponding list of StreamIDs.
>
> or
>
> 2. For each device wishing to use an IOMMU, have a phandle to the
> IOMMU node and a separate StreamID property. The IOMMU would then
> parse this information when the device is added to the bus.
>
> Although I prefer the second approach, it has the downside of affecting
> all device bindings that wish to use an IOMMU, so I'm open to any other
> ideas.
Actually the above summarize tegra SMMU situation well too. For
example, each IOMMU'able device has IOVA constraint that some of the
address area isn't available because of its MMIO. This info needs to
be described in DT. If <IOMMU phandle> + some parametes are embedded
in a device node, that info could be dealt at a bus notifier(*1).
*1: http://lists.linuxfoundation.org/pipermail/iommu/2012-November/004934.html
> > +Required properties:
> > +- compatible: Should be "samsung,exynos-sysmmu".
> > +- reg: Tuples of base address and size of System MMU registers. The number of
> > + tuples can be more than one if two or more System MMUs are controlled
> > + by a single device descriptor.
> > +- interrupt-parent: The phandle of the interrupt controller of System MMU
> > +- interrupts: Tuples of numbers that indicates the interrupt source. The
> > + number of elements in the tuple is dependent upon
> > + 'interrupt-parent' property. The number of tuples in this property
> > + must be the same with 'reg' property.
> > +
> > +Optional properties:
> > +- mmuname: Strings of the name of System MMU for debugging purpose. The number
> > + of strings must be the same with the number of tuples in 'reg'
> > + property.
> > +- mmu-master: phandle to the device node that owns System MMU. Only the device
> > + that is specified whith this property can control System MMU with
> > + IOMMU API.
> > +
> > +Examples:
> > +
> > +MFC has 2 System MMUs for each port that MFC is attached. Thus it seems natural
> > +to define 2 System MMUs for each port of the MFC:
> > +
> > + sysmmu-mfc-l {
> > + mmuname = "mfc_l";
> > + reg = <0x11210000 0x1000>;
> > + compatible = "samsung,exynos-sysmmu";
> > + interrupt-parent = <&combiner>;
> > + interrupts = <8 5>;
> > + mmu-master = <&mfc>;
> > + };
> > +
> > + sysmmu-mfc-r {
> > + mmuname = "mfc_r";
> > + reg = <0x11200000 0x1000>;
> > + compatible = "samsung,exynos-sysmmu";
> > + interrupt-parent = <&combiner>;
> > + interrupts = <6 2>;
> > + mmu-master = <&mfc>;
> > + };
> > +
> > +Actually, MFC device driver requires sub-devices that represents each port and
> > +above 'mmu-master' properties of sysmmu-mfc-l and sysmmu-mfc-r have the phandles
> > +to those sub-devices.
> > +
> > +However, it is also a good idea that treats the above System MMUs as one System
> > +MMU because those System MMUs are actually required by the MFC device:
> > +
> > + sysmmu-mfc {
> > + mmuname = "mfc_l", "mfc_r";
> > + reg = <0x11210000 0x1000
> > + 0x11200000 0x1000>;
> > + compatible = "samsung,exynos-sysmmu";
> > + interrupt-parent = <&combiner>;
> > + interrupts = <8 5
> > + 6 2>;
> > + mmu-master = <&mfc>;
> > + };
>
> Merging the nodes like this has strong requirements for uniform smmu
> devices, which I think are unreasonable. I would not be surprised to see
> some system MMUs have more interrupts than others, for example. Furthermore,
> you may chain stage-1 System MMUs with a stage-2 System MMU and these would
> need to be described as separate nodes (this actually complicates my two
> suggestions earlier on...).
>
> > +If System MMU of MFC is defined like the above, the number of elements and the
> > +order of list in 'mmuname', 'reg' and 'interrupts' must be the same.
>
> That's a really nasty restriction (the interrupts could even be ORd
> together).
>
> I appreciate that this is a samsung/exynos-specific binding but if we can
> generalise at least some parts of it then they can be re-used by other
> SoCs with multiple IOMMUs too.
>
> Will
^ permalink raw reply
* [PATCH 1/5] W1: Add device tree support to MXC onewire master.
From: Mark Rutland @ 2013-01-16 16:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130116094823.9660.2116.stgit@localhost>
Hi,
This looks nice and simple, I just have a couple of comment.
On Wed, Jan 16, 2013 at 09:48:23AM +0000, Martin Fuzzey wrote:
> Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com>
> ---
> drivers/w1/masters/mxc_w1.c | 9 ++++++++-
> 1 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
> index 708a25f..949e566 100644
> --- a/drivers/w1/masters/mxc_w1.c
> +++ b/drivers/w1/masters/mxc_w1.c
> @@ -186,9 +186,16 @@ static int mxc_w1_remove(struct platform_device *pdev)
> return 0;
> }
>
> +static struct of_device_id mxc_w1_dt_ids[] = {
> + { .compatible = "fsl,imx21-owire" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mxc_w1_dt_ids);
> +
> static struct platform_driver mxc_w1_driver = {
> .driver = {
> - .name = "mxc_w1",
> + .name = "mxc_w1",
> + .of_match_table = mxc_w1_dt_ids,
> },
> .probe = mxc_w1_probe,
> .remove = mxc_w1_remove,
>
I see there's already a binding for gpio-based w1 -- "w1-gpio". Given this is
already using the "w1" naming convention in a binding, I think it'd be worth
using the compatible string "fsl,imx21-w1", for consistency (both with the
other binding and the driver name).
It's also be worth documenting (in
Documentation/devicetree/bindings/w1/fsl-imx21-w1, presumably).
When adding bindings, it's also good to Cc devicetree-discuss.
Thanks,
Mark.
^ permalink raw reply
* linux-next: manual merge of the tegra tree with the arm-soc tree
From: Olof Johansson @ 2013-01-16 16:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358311923.537.3.camel@gitbox>
Hi,
On Tue, Jan 15, 2013 at 8:52 PM, Tony Prisk <linux@prisktech.co.nz> wrote:
> On Tue, 2013-01-15 at 21:32 -0700, Stephen Warren wrote:
>> On 01/15/2013 08:49 PM, Tony Prisk wrote:
>> > On Wed, 2013-01-16 at 14:14 +1100, Stephen Rothwell wrote:
>> >> Hi all,
>> >>
>> >> Today's linux-next merge of the tegra tree got a conflict in
>> >> drivers/clocksource/Makefile between commit ff7ec345f0ec ("timer: vt8500:
>> >> Move timer code to drivers/clocksource") from the arm-soc tree and commit
>> >> ac0fd9eca3ba ("ARM: tegra: move timer.c to drivers/clocksource/") from
>> >> the tegra tree.
>> >>
>> >> I fixed it up (see below) and can carry the fix as necessary (no action
>> >> is required).
>> >>
>> >
>> > I don't know about everyone else, but I feel the preference should be to
>> > keep things alphabetized where possible to help avoid with merge
>> > conflicts later on. This is always a problem when we start tacking
>> > things on the end of lists.
>> >
>> > I realise this Kconfig is not alphabetized anyway, but it's never too
>> > early to start on the 'right' path.
>>
>> Sounds like a good idea, but the issue is: When to do the initial sort
>> so it doesn't conflict with all the adds in a kernel cycle... Post and
>> immediately commit a new patch near the end of the merge window?
>
> Given that the maintainer can quite safely do the patch (sorry
> maintainers), I don't see any reason why it couldn't be done at the
> point where they stop accepting patches for the merge-window. Once the
> patches are stopped, sort the list in one last patch.
>
> It makes sense to get it done in this window if possible as the Kconfig
> will only get bigger as time goes on, making sorting it more time
> consuming.
Actually, Russell wen through and reordered these not long ago, if I
remember correctly. The current ordering is the same as in the
structure definition, and should be kept that way.
-Olof
^ permalink raw reply
* [PATCH v5 07/14] KVM: ARM: World-switch implementation
From: Gleb Natapov @ 2013-01-16 16:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANM98qLtf0i1LA3KT3xT0ivS3U9ioA_HkKQHwe6ZzXHNuYOONw@mail.gmail.com>
On Wed, Jan 16, 2013 at 11:17:06AM -0500, Christoffer Dall wrote:
> On Wed, Jan 16, 2013 at 10:52 AM, Gleb Natapov <gleb@redhat.com> wrote:
> > On Wed, Jan 16, 2013 at 10:42:02AM -0500, Christoffer Dall wrote:
> >> [...]
> >>
> >> >
> >> >> read side RCU protects against is the memslots data structure as far
> >> >> as I can see, so the second patch pasted below fixes this for the code
> >> >> that actually accesses this data structure.
> >> > Many memory related functions that you call access memslots under the
> >> > hood and assume that locking is done by the caller. From the quick look
> >> > I found those that you've missed:
> >> > kvm_is_visible_gfn()
> >> > kvm_read_guest()
> >> > gfn_to_hva()
> >> > gfn_to_pfn_prot()
> >> > kvm_memslots()
> >> >
> >> > May be there are more. Can you enable RCU debugging in your kernel config
> >> > and check? This does not guaranty that it will catch all of the places,
> >> > but better than nothing.
> >> >
> >>
> >> yeah, I missed the call to is_visible_gfn and friends, this fixes it:
> >>
> > Thank you. One more kvm_read_guest() in emulate.c.
> >
>
> this one is going out for now (see the i/o discussion).
>
I thought there wasn't resolution yet. Guess I missed something. If
kvm_read_guest() is removed from emulator then the patch looks good to me.
--
Gleb.
^ permalink raw reply
* [PATCH v5 07/14] KVM: ARM: World-switch implementation
From: Gleb Natapov @ 2013-01-16 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANM98qJ7O8RT_t0OinGDukdR5PNrObmU0rj6uFGEbT2hCvCjmA@mail.gmail.com>
On Wed, Jan 16, 2013 at 10:40:37AM -0500, Christoffer Dall wrote:
> [...]
>
> >>
> >
> > Agree. Lets merge it and change later. The vcpu run loop is simple
> > enough at this point. The question of using vcpu->requests is not
> > the question of "real benefit" though, of course you can introduce your
> > own mechanism to pass requests to vcpus instead of using whatever kvm
> > provides you. But from maintenance and code share point of view this
> > is wrong thing to do. Looks at this code for instance:
> >
> > /* Kick out any which are still running. */
> > kvm_for_each_vcpu(i, v, vcpu->kvm) {
> > /* Guest could exit now, making cpu wrong. That's OK. */
> > if (kvm_vcpu_exiting_guest_mode(v) == IN_GUEST_MODE) {
> > force_vm_exit(get_cpu_mask(v->cpu));
> > }
> > }
> >
> > Why not make_all_cpus_request(vcpu->kvm, KVM_REQ_PAUSE)?
>
> well for one, make_all_cpus_request is a static function in kvm_main.c
> and the semantics of that one is really tricky with respect to locking
> and requires (imho) a much clearer explanation with commenting (see
> separate e-mail to kvm list). And now is not the time to do this.
>
All current users add exported function that calls
make_all_cpus_request(). But this is very valid question why just not
export it directly. Patch is welcome :)
> >
> > And I am not sure KVM_REQ_UNHALT is so useless to you in the first
> > place. kvm_vcpu_block() can return even when vcpu is not runnable (if
> > signal is pending). KVM_REQ_UNHALT is the way to check for that. Hmm
> > this is actually looks like a BUG in the current code.
> >
> there's no guarantee that you won't be woken up from a WFI instruction
> for spurious interrupts on ARM, so we don't care about this, we simply
> return to the guest, and it must go back to sleep if that's what it
> wants to do.
>
If guest can handle it then we can ignore it (at least for now), but still
it's strange that signal unhalts vcpu.
--
Gleb.
^ permalink raw reply
* [kvmarm] [PATCH v5 07/12] ARM: KVM: VGIC virtual CPU interface management
From: Marc Zyngier @ 2013-01-16 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANM98qL1Ln2GYhC-prLR3VHgb=b1YR608dW6o7CS4s3L6Xy84Q@mail.gmail.com>
On Wed, 16 Jan 2013 11:13:08 -0500, Christoffer Dall
<c.dall@virtualopensystems.com> wrote:
> On Wed, Jan 16, 2013 at 11:09 AM, Marc Zyngier <marc.zyngier@arm.com>
> wrote:
>> On 16/01/13 15:29, Christoffer Dall wrote:
>>> [...]
>>>
>>>>> diff --git a/arch/arm/include/asm/kvm_vgic.h
>>>>> b/arch/arm/include/asm/kvm_vgic.h
>>>>> index 1ace491..f9d1977 100644
>>>>> --- a/arch/arm/include/asm/kvm_vgic.h
>>>>> +++ b/arch/arm/include/asm/kvm_vgic.h
>>>>> @@ -33,6 +33,7 @@
>>>>> #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS)
>>>>> #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS)
>>>>> #define VGIC_MAX_CPUS KVM_MAX_VCPUS
>>>>> +#define VGIC_MAX_LRS 64
>>>>
>>>> Consider this instead (for the reason below)
>>>> #define VGIC_MAX_LRS (1 << 7)
>>>>
>>>
>>> so here you mean (1 << 6), right?
>>
>> No. We have a 6 bit field that contains (NR_LRS - 1). So the maximum
>> value is (0b111111 + 1), which is (1 << 7).
>>
>
> eh, (1 << 7) is 128, and we have a maximum value of 63 (which plus the
> one is 64). You can verify this by thinking about having four bits, is
> a halfword, which we use hex numbers to deal with, so the number of
> values you can decode there is 16, then you have two more bits, which
> each doubles the number of values, so this becomes 64 values total,
> ie. from 0 through 63. :)
>
Blah. Ignore me, I'm being stupid.
>
>
>>>
>>>>> /* Sanity checks... */
>>>>> #if (VGIC_MAX_CPUS > 8)
>>>>> @@ -120,7 +121,7 @@ struct vgic_cpu {
>>>>> DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS);
>>>>>
>>>>> /* Bitmap of used/free list registers */
>>>>> - DECLARE_BITMAP( lr_used, 64);
>>>>> + DECLARE_BITMAP( lr_used, VGIC_MAX_LRS);
>>>>>
>>>>> /* Number of list registers on this CPU */
>>>>> int nr_lr;
>>>>> @@ -132,7 +133,7 @@ struct vgic_cpu {
>>>>> u32 vgic_eisr[2]; /* Saved only */
>>>>> u32 vgic_elrsr[2]; /* Saved only */
>>>>> u32 vgic_apr;
>>>>> - u32 vgic_lr[64]; /* A15 has only 4... */
>>>>> + u32 vgic_lr[VGIC_MAX_LRS];
>>>>> #endif
>>>>> };
>>>>>
>>>>> diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
>>>>> index a0d283c..90a99fd 100644
>>>>> --- a/arch/arm/kvm/vgic.c
>>>>> +++ b/arch/arm/kvm/vgic.c
>>>>> @@ -1345,6 +1345,8 @@ int kvm_vgic_hyp_init(void)
>>>>>
>>>>> vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR);
>>>>> vgic_nr_lr = (vgic_nr_lr & 0x1f) + 1;
>>>>
>>>> There is a bug here. It should be:
>>>> vgic_nr_lr = (vgic_nr_lr & 0x2f) + 1;
>>>>
>>>
>>> and here you mean (vgic_nr_lr & 0x3f) + 1
>>> right?
>>
>> Neither. 0x2f is the right value. See the GIC spec, 5.3.2, GICH_VTR
>> register.
>>
> I'm looking at it, and I don't understand why you don't want to
> consider bit[4] ?
Because it's not a prime number? ;-)
I think I should stay away from patches these days, I'm clearly not
thinking straight. Thanks for coping with my lack of brain.
M.
--
Fast, cheap, reliable. Pick two.
^ permalink raw reply
* [PATCH 10/14] PCI: tegra: Move PCIe driver to drivers/pci/host
From: Andrew Murray @ 2013-01-16 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201301161400.26587.arnd@arndb.de>
On Wed, Jan 16, 2013 at 02:00:26PM +0000, Arnd Bergmann wrote:
> On Tuesday 15 January 2013, Thierry Reding wrote:
> > Is there actually hardware that supports this? I assumed that the MSI
> > controller would have to be tightly coupled to the PCI host bridge in
> > order to raise an interrupt when an MSI is received via PCI.
>
> No, as long as it's guaranteed that the MSI notification won't arrive
> at the CPU before any inbound DMA data before it, the MSI controller
> can be anywhere. Typically, the MSI controller is actually closer to
> the CPU core than to the PCI bridge. On X86, I believe the MSI address
> is on normally on the the "local APIC" on each CPU.
MSIs are indistinguishable from other memory-write transactions originating
from the RC other than the address they target. Anything that can capture
that write in the address space (even a page fault) could be an MSI controller
and call interrupt handlers. And so the RC / MSI controllers don't need to
be aware of each other.
Andrew Murray
^ permalink raw reply
* [PATCH v5 07/14] KVM: ARM: World-switch implementation
From: Christoffer Dall @ 2013-01-16 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130116155212.GX11529@redhat.com>
On Wed, Jan 16, 2013 at 10:52 AM, Gleb Natapov <gleb@redhat.com> wrote:
> On Wed, Jan 16, 2013 at 10:42:02AM -0500, Christoffer Dall wrote:
>> [...]
>>
>> >
>> >> read side RCU protects against is the memslots data structure as far
>> >> as I can see, so the second patch pasted below fixes this for the code
>> >> that actually accesses this data structure.
>> > Many memory related functions that you call access memslots under the
>> > hood and assume that locking is done by the caller. From the quick look
>> > I found those that you've missed:
>> > kvm_is_visible_gfn()
>> > kvm_read_guest()
>> > gfn_to_hva()
>> > gfn_to_pfn_prot()
>> > kvm_memslots()
>> >
>> > May be there are more. Can you enable RCU debugging in your kernel config
>> > and check? This does not guaranty that it will catch all of the places,
>> > but better than nothing.
>> >
>>
>> yeah, I missed the call to is_visible_gfn and friends, this fixes it:
>>
> Thank you. One more kvm_read_guest() in emulate.c.
>
this one is going out for now (see the i/o discussion).
>> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
>> index c806080..f30e131 100644
>> --- a/arch/arm/kvm/mmu.c
>> +++ b/arch/arm/kvm/mmu.c
>> @@ -591,7 +591,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
>> struct kvm_run *run)
>> struct kvm_memory_slot *memslot;
>> bool is_iabt;
>> gfn_t gfn;
>> - int ret;
>> + int ret, idx;
>>
>> hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
>> is_iabt = (hsr_ec == HSR_EC_IABT);
>> @@ -608,33 +608,43 @@ int kvm_handle_guest_abort(struct kvm_vcpu
>> *vcpu, struct kvm_run *run)
>> return -EFAULT;
>> }
>>
>> + idx = srcu_read_lock(&vcpu->kvm->srcu);
>> +
>> gfn = fault_ipa >> PAGE_SHIFT;
>> if (!kvm_is_visible_gfn(vcpu->kvm, gfn)) {
>> if (is_iabt) {
>> /* Prefetch Abort on I/O address */
>> kvm_inject_pabt(vcpu, vcpu->arch.hxfar);
>> - return 1;
>> + ret = 1;
>> + goto out_unlock;
>> }
>>
>> if (fault_status != FSC_FAULT) {
>> kvm_err("Unsupported fault status on io memory: %#lx\n",
>> fault_status);
>> - return -EFAULT;
>> + ret = -EFAULT;
>> + goto out_unlock;
>> }
>>
>> /* Adjust page offset */
>> fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK;
>> - return io_mem_abort(vcpu, run, fault_ipa);
>> + ret = io_mem_abort(vcpu, run, fault_ipa);
>> + goto out_unlock;
>> }
>>
>> memslot = gfn_to_memslot(vcpu->kvm, gfn);
>> if (!memslot->user_alloc) {
>> kvm_err("non user-alloc memslots not supported\n");
>> - return -EINVAL;
>> + ret = -EINVAL;
>> + goto out_unlock;
>> }
>>
>> ret = user_mem_abort(vcpu, fault_ipa, gfn, memslot, fault_status);
>> - return ret ? ret : 1;
>> + if (ret == 0)
>> + ret = 1;
>> +out_unlock:
>> + srcu_read_unlock(&vcpu->kvm->srcu, idx);
>> + return ret;
>> }
>>
>> static void handle_hva_to_gpa(struct kvm *kvm,
>> --
>>
>> Thanks,
>> -Christoffer
>
> --
> Gleb.
^ permalink raw reply
* [PATCH v5 07/12] ARM: KVM: VGIC virtual CPU interface management
From: Christoffer Dall @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F6D0A0.5010707@arm.com>
On Wed, Jan 16, 2013 at 11:09 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On 16/01/13 15:29, Christoffer Dall wrote:
>> [...]
>>
>>>> diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h
>>>> index 1ace491..f9d1977 100644
>>>> --- a/arch/arm/include/asm/kvm_vgic.h
>>>> +++ b/arch/arm/include/asm/kvm_vgic.h
>>>> @@ -33,6 +33,7 @@
>>>> #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS)
>>>> #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS)
>>>> #define VGIC_MAX_CPUS KVM_MAX_VCPUS
>>>> +#define VGIC_MAX_LRS 64
>>>
>>> Consider this instead (for the reason below)
>>> #define VGIC_MAX_LRS (1 << 7)
>>>
>>
>> so here you mean (1 << 6), right?
>
> No. We have a 6 bit field that contains (NR_LRS - 1). So the maximum
> value is (0b111111 + 1), which is (1 << 7).
>
eh, (1 << 7) is 128, and we have a maximum value of 63 (which plus the
one is 64). You can verify this by thinking about having four bits, is
a halfword, which we use hex numbers to deal with, so the number of
values you can decode there is 16, then you have two more bits, which
each doubles the number of values, so this becomes 64 values total,
ie. from 0 through 63. :)
>>
>>>> /* Sanity checks... */
>>>> #if (VGIC_MAX_CPUS > 8)
>>>> @@ -120,7 +121,7 @@ struct vgic_cpu {
>>>> DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS);
>>>>
>>>> /* Bitmap of used/free list registers */
>>>> - DECLARE_BITMAP( lr_used, 64);
>>>> + DECLARE_BITMAP( lr_used, VGIC_MAX_LRS);
>>>>
>>>> /* Number of list registers on this CPU */
>>>> int nr_lr;
>>>> @@ -132,7 +133,7 @@ struct vgic_cpu {
>>>> u32 vgic_eisr[2]; /* Saved only */
>>>> u32 vgic_elrsr[2]; /* Saved only */
>>>> u32 vgic_apr;
>>>> - u32 vgic_lr[64]; /* A15 has only 4... */
>>>> + u32 vgic_lr[VGIC_MAX_LRS];
>>>> #endif
>>>> };
>>>>
>>>> diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
>>>> index a0d283c..90a99fd 100644
>>>> --- a/arch/arm/kvm/vgic.c
>>>> +++ b/arch/arm/kvm/vgic.c
>>>> @@ -1345,6 +1345,8 @@ int kvm_vgic_hyp_init(void)
>>>>
>>>> vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR);
>>>> vgic_nr_lr = (vgic_nr_lr & 0x1f) + 1;
>>>
>>> There is a bug here. It should be:
>>> vgic_nr_lr = (vgic_nr_lr & 0x2f) + 1;
>>>
>>
>> and here you mean (vgic_nr_lr & 0x3f) + 1
>> right?
>
> Neither. 0x2f is the right value. See the GIC spec, 5.3.2, GICH_VTR
> register.
>
I'm looking at it, and I don't understand why you don't want to
consider bit[4] ?
-Christoffer
^ permalink raw reply
* [PATCH 7/7] ARM i.MX5: Add system reset controller (SRC) to i.MX51 and i.MX53 device tree
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
Also, link SRC to IPU via phandle.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
arch/arm/boot/dts/imx51.dtsi | 7 +++++++
arch/arm/boot/dts/imx53.dtsi | 7 +++++++
2 files changed, 14 insertions(+)
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 1f5d45e..1ff0adf 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -67,6 +67,7 @@
compatible = "fsl,imx51-ipu";
reg = <0x40000000 0x20000000>;
interrupts = <11 10>;
+ resets = <&src 2>;
};
aips at 70000000 { /* AIPS1 */
@@ -448,6 +449,12 @@
status = "disabled";
};
+ src: src at 73fd0000 {
+ compatible = "fsl,imx5-src";
+ reg = <0x73fd0000 0x4000>;
+ #reset-cells = <1>;
+ };
+
clks: ccm at 73fd4000{
compatible = "fsl,imx51-ccm";
reg = <0x73fd4000 0x4000>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index edc3f1e..088dc49 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -72,6 +72,7 @@
compatible = "fsl,imx53-ipu";
reg = <0x18000000 0x080000000>;
interrupts = <11 10>;
+ resets = <&src 2>;
};
aips at 50000000 { /* AIPS1 */
@@ -497,6 +498,12 @@
status = "disabled";
};
+ src: src at 53fd0000 {
+ compatible = "fsl,imx5-src";
+ reg = <0x53fd0000 0x4000>;
+ #reset-cells = <1>;
+ };
+
clks: ccm at 53fd4000{
compatible = "fsl,imx53-ccm";
reg = <0x53fd4000 0x4000>;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 6/7] ARM i.MX5: Add System Reset Controller (SRC) support for i.MX51 and i.MX53
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
The SRC in i.MX51 and i.MX53 is similar to the one in i.MX6q minus
the IPU2 reset line and multi core CPU reset/enable bits.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
arch/arm/mach-imx/Kconfig | 1 +
arch/arm/mach-imx/common.h | 3 ++-
arch/arm/mach-imx/mach-imx6q.c | 2 +-
arch/arm/mach-imx/mm-imx5.c | 2 ++
arch/arm/mach-imx/src.c | 14 +++++++++++++-
5 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3e628fd..d7924e5 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -829,6 +829,7 @@ config SOC_IMX53
select ARCH_MX53
select HAVE_CAN_FLEXCAN if CAN
select IMX_HAVE_PLATFORM_IMX2_WDT
+ select HAVE_IMX_SRC
select PINCTRL
select PINCTRL_IMX53
select SOC_IMX5
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 7191ab4..f36be3c 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -133,7 +133,8 @@ static inline void imx_smp_prepare(void) {}
#endif
extern void imx_enable_cpu(int cpu, bool enable);
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
-extern void imx_src_init(void);
+extern void imx5_src_init(void);
+extern void imx6q_src_init(void);
extern void imx_src_prepare_restart(void);
extern void imx_gpc_init(void);
extern void imx_gpc_pre_suspend(void);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index cd277a0..b1e076c 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -229,7 +229,7 @@ static const struct of_device_id imx6q_irq_match[] __initconst = {
static void __init imx6q_init_irq(void)
{
l2x0_of_init(0, ~0UL);
- imx_src_init();
+ imx6q_src_init();
imx_gpc_init();
of_irq_init(imx6q_irq_match);
}
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index 79d71cf..53f87be 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -106,6 +106,7 @@ void __init imx51_init_early(void)
mxc_set_cpu_type(MXC_CPU_MX51);
mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
+ imx5_src_init();
}
void __init imx53_init_early(void)
@@ -113,6 +114,7 @@ void __init imx53_init_early(void)
mxc_set_cpu_type(MXC_CPU_MX53);
mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
+ imx5_src_init();
}
void __init mx50_init_irq(void)
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 41687c6..e350250 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -125,7 +125,19 @@ void imx_src_prepare_restart(void)
writel_relaxed(0, src_base + SRC_GPR1);
}
-void __init imx_src_init(void)
+void __init imx5_src_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx5-src");
+ src_base = of_iomap(np, 0);
+ WARN_ON(!src_base);
+
+ imx_reset_controller.of_node = np;
+ reset_controller_register(&imx_reset_controller);
+}
+
+void __init imx6q_src_init(void)
{
struct device_node *np;
u32 val;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/7] staging: drm/imx: Use SRC to reset IPU
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
Request the System Reset Controller to reset the IPU if
specified via device tree phandle.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
.../devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt | 3 +++
drivers/staging/imx-drm/ipu-v3/ipu-common.c | 12 +++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
index 07654f0..f769857 100644
--- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
+++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
@@ -8,6 +8,8 @@ Required properties:
- interrupts: Should contain sync interrupt and error interrupt,
in this order.
- #crtc-cells: 1, See below
+- resets: phandle pointing to the system reset controller and
+ reset line index, see reset/fsl,imx-src.txt for details
example:
@@ -16,6 +18,7 @@ ipu: ipu at 18000000 {
compatible = "fsl,imx53-ipu";
reg = <0x18000000 0x080000000>;
interrupts = <11 10>;
+ resets = <&src 2>;
};
Parallel display support
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
index f7059cd..6a6211d 100644
--- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c
+++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
@@ -16,6 +16,7 @@
#include <linux/export.h>
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/reset.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/spinlock.h>
@@ -660,7 +661,7 @@ int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
}
EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
-static int ipu_reset(struct ipu_soc *ipu)
+static int ipu_memory_reset(struct ipu_soc *ipu)
{
unsigned long timeout;
@@ -1104,7 +1105,12 @@ static int ipu_probe(struct platform_device *pdev)
if (ret)
goto out_failed_irq;
- ret = ipu_reset(ipu);
+ ret = device_reset(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to reset: %d\n", ret);
+ goto out_failed_reset;
+ }
+ ret = ipu_memory_reset(ipu);
if (ret)
goto out_failed_reset;
@@ -1130,8 +1136,8 @@ static int ipu_probe(struct platform_device *pdev)
failed_add_clients:
ipu_submodules_exit(ipu);
failed_submodules_init:
- ipu_irq_exit(ipu);
out_failed_reset:
+ ipu_irq_exit(ipu);
out_failed_irq:
clk_disable_unprepare(ipu->clk);
failed_clk_get:
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/7] ARM i.MX6q: Link system reset controller (SRC) to IPU in DT
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
arch/arm/boot/dts/imx6q.dtsi | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index d6265ca..c445959 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -555,6 +555,7 @@
compatible = "fsl,imx6q-src";
reg = <0x020d8000 0x4000>;
interrupts = <0 91 0x04 0 96 0x04>;
+ #reset-cells = <1>;
};
gpc: gpc at 020dc000 {
@@ -1046,6 +1047,7 @@
interrupts = <0 6 0x4 0 5 0x4>;
clocks = <&clks 130>, <&clks 131>, <&clks 132>;
clock-names = "bus", "di0", "di1";
+ resets = <&src 2>;
};
ipu2: ipu at 02800000 {
@@ -1055,6 +1057,7 @@
interrupts = <0 8 0x4 0 7 0x4>;
clocks = <&clks 133>, <&clks 134>, <&clks 137>;
clock-names = "bus", "di0", "di1";
+ reset = <&src 4>;
};
};
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/7] ARM i.MX6q: Add GPU, VPU, IPU, and OpenVG resets to System Reset Controller (SRC)
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
The SRC has auto-deasserting reset bits that control reset lines to
the GPU, VPU, IPU, and OpenVG IP modules. This patch adds a reset
controller that can be controlled by those devices using the
reset controller API.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
.../devicetree/bindings/reset/fsl,imx-src.txt | 49 +++++++++++++
arch/arm/mach-imx/src.c | 72 ++++++++++++++++++++
include/linux/imx-src.h | 6 ++
3 files changed, 127 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx-src.txt
create mode 100644 include/linux/imx-src.h
diff --git a/Documentation/devicetree/bindings/reset/fsl,imx-src.txt b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
new file mode 100644
index 0000000..1330177
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
@@ -0,0 +1,49 @@
+Freescale i.MX System Reset Controller
+======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "fsl,<chip>-src"
+- reg: should be register base and length as documented in the
+ datasheet
+- interrupts: Should contain SRC interrupt and CPU WDOG interrupt,
+ in this order.
+- #reset-cells: 1, see below
+
+example:
+
+src: src at 020d8000 {
+ compatible = "fsl,imx6q-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <0 91 0x04 0 96 0x04>;
+ #reset-cells = <1>;
+};
+
+Specifying reset lines connected to IP modules
+==============================================
+
+The system reset controller can be used to reset the GPU, VPU,
+IPU, and OpenVG IP modules on i.MX5 and i.MX6 ICs. Those device
+nodes should specify the reset line on the SRC in their resets
+property, containing a phandle to the SRC device node and a
+RESET_INDEX specifying which module to reset, as described in
+reset.txt
+
+example:
+
+ ipu1: ipu at 02400000 {
+ resets = <&src 2>;
+ };
+ ipu2: ipu at 02800000 {
+ resets = <&src 4>;
+ };
+
+The following RESET_INDEX values are valid for i.MX5:
+GPU_RESET 0
+VPU_RESET 1
+IPU1_RESET 2
+OPEN_VG_RESET 3
+The following additional RESET_INDEX value is valid for i.MX6:
+IPU2_RESET 4
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index e15f155..41687c6 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -15,16 +15,85 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/smp.h>
+#include <linux/reset-controller.h>
#include <asm/smp_plat.h>
#define SRC_SCR 0x000
#define SRC_GPR1 0x020
#define BP_SRC_SCR_WARM_RESET_ENABLE 0
+#define BP_SRC_SCR_SW_GPU_RST 1
+#define BP_SRC_SCR_SW_VPU_RST 2
+#define BP_SRC_SCR_SW_IPU1_RST 3
+#define BP_SRC_SCR_SW_OPEN_VG_RST 4
+#define BP_SRC_SCR_SW_IPU2_RST 12
#define BP_SRC_SCR_CORE1_RST 14
#define BP_SRC_SCR_CORE1_ENABLE 22
static void __iomem *src_base;
+static int sw_reset_bits[5] = {
+ BP_SRC_SCR_SW_GPU_RST,
+ BP_SRC_SCR_SW_VPU_RST,
+ BP_SRC_SCR_SW_IPU1_RST,
+ BP_SRC_SCR_SW_OPEN_VG_RST,
+ BP_SRC_SCR_SW_IPU2_RST
+};
+
+static int imx_src_reset(unsigned long sw_reset_idx)
+{
+ unsigned long timeout;
+ int bit;
+ u32 val;
+
+ if (!src_base)
+ return -ENODEV;
+
+ if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
+ return -EINVAL;
+
+ bit = 1 << sw_reset_bits[sw_reset_idx];
+
+ val = readl_relaxed(src_base + SRC_SCR);
+ val |= bit;
+ writel_relaxed(val, src_base + SRC_SCR);
+
+ timeout = jiffies + msecs_to_jiffies(1000);
+ while (readl(src_base + SRC_SCR) & bit) {
+ if (time_after(jiffies, timeout))
+ return -ETIME;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+static int imx_src_is_asserted(unsigned long sw_reset_idx)
+{
+ int bit;
+ u32 val;
+
+ if (!src_base)
+ return -ENODEV;
+
+ if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
+ return -EINVAL;
+
+ bit = 1 << sw_reset_bits[sw_reset_idx];
+
+ val = readl_relaxed(src_base + SRC_SCR);
+
+ return (val & bit) ? 1 : 0;
+}
+
+static struct reset_control_ops imx_src_ops = {
+ .reset = imx_src_reset,
+ .is_asserted = imx_src_is_asserted,
+};
+
+static struct reset_controller_dev imx_reset_controller = {
+ .ops = &imx_src_ops,
+};
+
void imx_enable_cpu(int cpu, bool enable)
{
u32 mask, val;
@@ -65,6 +134,9 @@ void __init imx_src_init(void)
src_base = of_iomap(np, 0);
WARN_ON(!src_base);
+ imx_reset_controller.of_node = np;
+ reset_controller_register(&imx_reset_controller);
+
/*
* force warm reset sources to generate cold reset
* for a more reliable restart
diff --git a/include/linux/imx-src.h b/include/linux/imx-src.h
new file mode 100644
index 0000000..b93ed96
--- /dev/null
+++ b/include/linux/imx-src.h
@@ -0,0 +1,6 @@
+#ifndef __IMX_SRC_H__
+#define __IMX_SRC_H__
+
+extern int imx_src_reset(int sw_reset_idx);
+
+#endif /* __IMX_SRC_H__ */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/7] reset: Add reset controller API
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
This adds a simple API for devices to request being reset
by separate reset controller hardware and implements the
reset signal device tree binding.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
drivers/Kconfig | 2 +
drivers/Makefile | 2 +
drivers/reset/Kconfig | 10 ++
drivers/reset/Makefile | 2 +
drivers/reset/core.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 257 insertions(+)
create mode 100644 drivers/reset/Kconfig
create mode 100644 drivers/reset/Makefile
create mode 100644 drivers/reset/core.c
diff --git a/drivers/Kconfig b/drivers/Kconfig
index f5fb072..51f73ae 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -158,4 +158,6 @@ source "drivers/irqchip/Kconfig"
source "drivers/ipack/Kconfig"
+source "drivers/reset/Kconfig"
+
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 346ecc5..870bf7e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -42,6 +42,8 @@ ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
obj-y += clocksource/
endif
+obj-$(CONFIG_RESET_CONTROLLER) += reset/
+
# tty/ comes before char/ so that the VT console is the boot-time
# default.
obj-y += tty/
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
new file mode 100644
index 0000000..82dc89e
--- /dev/null
+++ b/drivers/reset/Kconfig
@@ -0,0 +1,10 @@
+menuconfig RESET_CONTROLLER
+ bool "Reset Controller Support"
+ help
+ Generic Reset Controller support.
+
+ This framework is designed to abstract reset handling of devices
+ via GPIOs or SoC-internal reset controller modules.
+
+ If unsure, say no.
+
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
new file mode 100644
index 0000000..9a7b6df
--- /dev/null
+++ b/drivers/reset/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_RESET_CONTROLLER) += core.o
+
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
new file mode 100644
index 0000000..f0ed61b
--- /dev/null
+++ b/drivers/reset/core.c
@@ -0,0 +1,241 @@
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/reset.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+static DEFINE_MUTEX(reset_controller_list_mutex);
+static LIST_HEAD(reset_controller_list);
+
+/**
+ * struct reset_control - a reset control
+ *
+ * @id: ID of the reset controller in the reset
+ * controller device
+ */
+struct reset_control {
+ struct reset_controller_dev *rcdev;
+ unsigned int id;
+};
+
+/**
+ * reset_controller_register - register a reset controller
+ *
+ * @ops: a pointer to struct reset_controller_ops callbacks
+ *
+ * Returns a struct reset_controller_dev or IS_ERR() condition
+ * containing errno.
+ */
+int reset_controller_register(struct reset_controller_dev *rcdev)
+{
+ mutex_lock(&reset_controller_list_mutex);
+ list_add(&rcdev->list, &reset_controller_list);
+ mutex_unlock(&reset_controller_list_mutex);
+
+ return 0;
+}
+
+/**
+ * reset_control_reset - reset the controlled device
+ * @rstc: reset controller
+ */
+int reset_control_reset(struct reset_control *rstc)
+{
+ if (rstc->rcdev->ops->reset)
+ return rstc->rcdev->ops->reset(rstc->id);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_control_reset);
+
+/**
+ * reset_control_assert - asserts the reset line
+ * @rstc: reset controller
+ */
+int reset_control_assert(struct reset_control *rstc)
+{
+ if (rstc->rcdev->ops->assert)
+ return rstc->rcdev->ops->assert(rstc->id);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_control_assert);
+
+/**
+ * reset_control_deassert - deasserts the reset line
+ * @rstc: reset controller
+ */
+int reset_control_deassert(struct reset_control *rstc)
+{
+ if (rstc->rcdev->ops->deassert)
+ return rstc->rcdev->ops->deassert(rstc->id);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_control_deassert);
+
+/**
+ * reset_control_is_asserted - deasserts the reset line
+ * @rstc: reset controller
+ */
+int reset_control_is_asserted(struct reset_control *rstc)
+{
+ if (rstc->rcdev->ops->is_asserted)
+ return rstc->rcdev->ops->is_asserted(rstc->id);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_control_is_asserted);
+
+/**
+ * reset_control_get - Lookup and obtain a reference to a reset controller.
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Returns a struct reset_control or IS_ERR() condition containing errno.
+ *
+ * Use of id names is optional.
+ */
+struct reset_control *reset_control_get(struct device *dev, const char *id)
+{
+ struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER);
+ struct reset_controller_dev *r, *rcdev;
+ struct device_node *rcdev_node;
+ struct of_phandle_args args;
+ int rcdev_index;
+ int ret;
+ int i;
+
+ if (!dev)
+ return ERR_PTR(-EINVAL);
+
+ rcdev_node = NULL;
+ for (i = 0; rcdev_node == NULL; i++) {
+ ret = of_parse_phandle_with_args(dev->of_node, "resets",
+ "#reset-cells", i, &args);
+ if (ret)
+ return ERR_PTR(ret);
+ of_node_put(args.np);
+ if (args.args_count <= 0)
+ return ERR_PTR(-EINVAL);
+
+ if (id) {
+ const char *reset_name;
+ ret = of_property_read_string_index(dev->of_node,
+ "reset-names", i,
+ &reset_name);
+ if (ret)
+ return ERR_PTR(ret);
+ if (strcmp(id, reset_name) != 0)
+ continue;
+ }
+
+ rcdev_node = args.np;
+ rcdev_index = args.args[0];
+ }
+
+ mutex_lock(&reset_controller_list_mutex);
+ rcdev = NULL;
+ list_for_each_entry(r, &reset_controller_list, list) {
+ if (rcdev_node == r->of_node) {
+ rcdev = r;
+ break;
+ }
+ }
+ mutex_unlock(&reset_controller_list_mutex);
+
+ if (!rcdev)
+ return ERR_PTR(-ENODEV);
+
+ try_module_get(rcdev->owner);
+
+ rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
+ if (!rstc)
+ return ERR_PTR(-ENOMEM);
+
+ rstc->rcdev = rcdev;
+ rstc->id = rcdev_index;
+
+ return rstc;
+}
+EXPORT_SYMBOL_GPL(reset_control_get);
+
+/**
+ * reset_control_put - free the reset controller
+ * @reset: reset controller
+ */
+
+void reset_control_put(struct reset_control *rstc)
+{
+ if (rstc == NULL || IS_ERR(rstc))
+ return;
+
+ kfree(rstc);
+ module_put(rstc->rcdev->owner);
+}
+EXPORT_SYMBOL_GPL(reset_control_put);
+
+static void devm_reset_control_release(struct device *dev, void *res)
+{
+ reset_control_put(*(struct reset_control **)res);
+}
+
+/**
+ * devm_reset_control_get - resource managed reset_control_get()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get(). For reset controllers returned from this
+ * function, reset_control_put() is called automatically on driver detach.
+ * See reset_control_get() for more information.
+ */
+struct reset_control *devm_reset_control_get(struct device *dev, const char *id)
+{
+ struct reset_control **ptr, *rstc;
+
+ ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ rstc = reset_control_get(dev, id);
+ if (!IS_ERR(rstc)) {
+ *ptr = rstc;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return rstc;
+}
+EXPORT_SYMBOL_GPL(devm_reset_control_get);
+
+/**
+ * device_reset - find reset controller associated with the device
+ * and perform reset
+ * @dev: device to be reset by the controller
+ *
+ * Convenience wrapper for reset_control_get() and reset_control_reset().
+ * This is useful for the common case of devices with single, dedicated reset
+ * lines.
+ */
+int device_reset(struct device *dev)
+{
+ struct reset_control *rstc;
+ int ret;
+
+ rstc = reset_control_get(dev, NULL);
+ if (IS_ERR(rstc))
+ return PTR_ERR(rstc);
+
+ ret = reset_control_reset(rstc);
+
+ kfree(rstc);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(device_reset);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/7] dt: describe base reset signal binding
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358352787-15441-1-git-send-email-p.zabel@pengutronix.de>
From: Stephen Warren <swarren@nvidia.com>
This binding is intended to represent the hardware reset signals present
internally in most IC (SoC, FPGA, ...) designs.
Such a binding would allow the creation of a "reset subsystem", which
could replace APIs such as the following Tegra-specific API:
void tegra_periph_reset_deassert(struct clk *c);
void tegra_periph_reset_assert(struct clk *c);
(Note that at present, Tegra couples reset assertion with the clock for
the affected peripheral module. However, reset and clocking are two
separate, yet admittedly related, concepts).
Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
Documentation/devicetree/bindings/reset/reset.txt | 75 +++++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/reset.txt
diff --git a/Documentation/devicetree/bindings/reset/reset.txt b/Documentation/devicetree/bindings/reset/reset.txt
new file mode 100644
index 0000000..31db6ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/reset.txt
@@ -0,0 +1,75 @@
+= Reset Signal Device Tree Bindings =
+
+This binding is intended to represent the hardware reset signals present
+internally in most IC (SoC, FPGA, ...) designs. Reset signals for whole
+standalone chips are most likely better represented as GPIOs, although there
+are likely to be exceptions to this rule.
+
+Hardware blocks typically receive a reset signal. This signal is generated by
+a reset provider (e.g. power management or clock module) and received by a
+reset consumer (the module being reset, or a module managing when a sub-
+ordinate module is reset). This binding exists to represent the provider and
+consumer, and provide a way to couple the two together.
+
+A reset signal is represented by the phandle of the provider, plus a reset
+specifier - a list of DT cells that represents the reset signal within the
+provider. The length (number of cells) and semantics of the reset specifier
+are dictated by the binding of the reset provider, although common schemes
+are described below.
+
+A word on where to place reset signal consumers in device tree: It is possible
+in hardware for a reset signal to affect multiple logically separate HW blocks
+at once. In this case, it would be unwise to represent this reset signal in
+the DT node of each affected HW block, since if activated, an unrelated block
+may be reset. Instead, reset signals should be represented in the DT node
+where it makes most sense to control it; this may be a bus node if all
+children of the bus are affected by the reset signal, or an individual HW
+block node for dedicated reset signals. The intent of this binding is to give
+appropriate software access to the reset signals in order to manage the HW,
+rather than to slavishly enumerate the reset signal that affects each HW
+block.
+
+= Reset providers =
+
+Required properties:
+#reset-cells: Number of cells in a reset specifier; Typically 0 for nodes
+ with a single reset output and 1 for nodes with multiple
+ reset outputs.
+
+For example:
+
+ rst: reset-controller {
+ #reset-cells = <1>;
+ };
+
+= Reset consumers =
+
+Required properties:
+resets: List of phandle and reset specifier pairs, one pair
+ for each reset signal that affects the device, or that the
+ device manages. Note: if the reset provider specifies '0' for
+ #reset-cells, then only the phandle portion of the pair will
+ appear.
+
+Optional properties:
+reset-names: List of reset signal name strings sorted in the same order as
+ the resets property. Consumers drivers will use reset-names to
+ match reset signal names with reset specifiers.
+
+For example:
+
+ device {
+ resets = <&rst 20>;
+ reset-names = "reset";
+ };
+
+This represents a device with a single reset signal named "reset".
+
+ bus {
+ resets = <&rst 10> <&rst 11> <&rst 12> <&rst 11>;
+ reset-names = "i2s1", "i2s2", "dma", "mixer";
+ };
+
+This represents a bus that controls the reset signal of each of four sub-
+ordinate devices. Consider for example a bus that fails to operate unless no
+child device has reset asserted.
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 0/5] Reset controller API to reset IP modules on i.MX5 and i.MX6
From: Philipp Zabel @ 2013-01-16 16:13 UTC (permalink / raw)
To: linux-arm-kernel
The system reset controller (SRC) on i.MX51, i.MX53, and i.MX6q controls
reset lines to the GPU, VPU, IPU, and OpenVG IP modules.
The following patches add a simple API for devices to request being reset
by separate reset controller hardware. They implement the reset signal
device tree binding proposed by Stephen Warren. Contrary to Tegra hardware,
the i.MX SRC has self-deasserting reset bits, so I've included both
ops to manually assert/deassert a reset line, as well as a reset
operation that is supposed to assert the reset line and wait for it to
deassert.
The i.MX SRC is enhanced to provide a reset controller and the IPU driver
is made to request being reset by calling the device_reset(&pdev->dev)
convenience wrapper during probing.
regards
Philipp
---
.../devicetree/bindings/reset/fsl,imx-src.txt | 49 ++++
Documentation/devicetree/bindings/reset/reset.txt | 75 ++++++
.../bindings/staging/imx-drm/fsl-imx-drm.txt | 3 +
arch/arm/boot/dts/imx51.dtsi | 7 +
arch/arm/boot/dts/imx53.dtsi | 7 +
arch/arm/boot/dts/imx6q.dtsi | 3 +
arch/arm/mach-imx/Kconfig | 1 +
arch/arm/mach-imx/common.h | 3 +-
arch/arm/mach-imx/mach-imx6q.c | 2 +-
arch/arm/mach-imx/mm-imx5.c | 2 +
arch/arm/mach-imx/src.c | 86 ++++++-
drivers/Kconfig | 2 +
drivers/Makefile | 2 +
drivers/reset/Kconfig | 10 +
drivers/reset/Makefile | 2 +
drivers/reset/core.c | 241 ++++++++++++++++++++
drivers/staging/imx-drm/ipu-v3/ipu-common.c | 12 +-
include/linux/imx-src.h | 6 +
18 files changed, 507 insertions(+), 6 deletions(-)
^ permalink raw reply
* [PATCH v5 07/12] ARM: KVM: VGIC virtual CPU interface management
From: Marc Zyngier @ 2013-01-16 16:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANM98qJ0YRNA5R+qnRF9i0a7BRoL817Mq9D1SFPcxsSWgd2x0w@mail.gmail.com>
On 16/01/13 15:29, Christoffer Dall wrote:
> [...]
>
>>> diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h
>>> index 1ace491..f9d1977 100644
>>> --- a/arch/arm/include/asm/kvm_vgic.h
>>> +++ b/arch/arm/include/asm/kvm_vgic.h
>>> @@ -33,6 +33,7 @@
>>> #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS)
>>> #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS)
>>> #define VGIC_MAX_CPUS KVM_MAX_VCPUS
>>> +#define VGIC_MAX_LRS 64
>>
>> Consider this instead (for the reason below)
>> #define VGIC_MAX_LRS (1 << 7)
>>
>
> so here you mean (1 << 6), right?
No. We have a 6 bit field that contains (NR_LRS - 1). So the maximum
value is (0b111111 + 1), which is (1 << 7).
>
>>> /* Sanity checks... */
>>> #if (VGIC_MAX_CPUS > 8)
>>> @@ -120,7 +121,7 @@ struct vgic_cpu {
>>> DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS);
>>>
>>> /* Bitmap of used/free list registers */
>>> - DECLARE_BITMAP( lr_used, 64);
>>> + DECLARE_BITMAP( lr_used, VGIC_MAX_LRS);
>>>
>>> /* Number of list registers on this CPU */
>>> int nr_lr;
>>> @@ -132,7 +133,7 @@ struct vgic_cpu {
>>> u32 vgic_eisr[2]; /* Saved only */
>>> u32 vgic_elrsr[2]; /* Saved only */
>>> u32 vgic_apr;
>>> - u32 vgic_lr[64]; /* A15 has only 4... */
>>> + u32 vgic_lr[VGIC_MAX_LRS];
>>> #endif
>>> };
>>>
>>> diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
>>> index a0d283c..90a99fd 100644
>>> --- a/arch/arm/kvm/vgic.c
>>> +++ b/arch/arm/kvm/vgic.c
>>> @@ -1345,6 +1345,8 @@ int kvm_vgic_hyp_init(void)
>>>
>>> vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR);
>>> vgic_nr_lr = (vgic_nr_lr & 0x1f) + 1;
>>
>> There is a bug here. It should be:
>> vgic_nr_lr = (vgic_nr_lr & 0x2f) + 1;
>>
>
> and here you mean (vgic_nr_lr & 0x3f) + 1
> right?
Neither. 0x2f is the right value. See the GIC spec, 5.3.2, GICH_VTR
register.
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH 07/16] ARM: bL_platsmp.c: close the kernel entry gate before hot-unplugging a CPU
From: Catalin Marinas @ 2013-01-16 16:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130115184037.GE1983@linaro.org>
On Tue, Jan 15, 2013 at 06:40:37PM +0000, Dave Martin wrote:
> On Mon, Jan 14, 2013 at 06:26:04PM +0000, Russell King - ARM Linux wrote:
> > On Mon, Jan 14, 2013 at 12:15:07PM -0500, Nicolas Pitre wrote:
> > > The same could be said about the outer cache ops. If a DSB is needed
> > > for their intent to be valid, then why isn't this DSB always implied by
> > > the corresponding cache op calls?
> >
> > Hmm, just been thinking about this.
> >
> > The L2x0 calls do contain a DSB but it's not obvious. They hold a
> > raw spinlock, and when that spinlock is dropped, we issue a dsb and
> > sev instruction.
> >
> > Whether the other L2 implementations do this or not I'm not sure -
> > but the above is a requirement of the spinlock implementation, and
> > it just happens to provide the right behaviour for L2x0.
> >
> > But... we _probably_ don't want to impose that down at the L2 cache
> > level of things - at least not for DMA ops, particular for the sanity
> > of the scatter-list operating operations. We really want to avoid
> > doing one DSB per scatterlist entry, doing one DSB per scatterlist
> > operation instead.
> >
> > That does affect how the L2 cache API gets used - maybe we want to
> > separate out the DMA stuff from the other users so that we can have
> > dsbs in that path for non-DMA users.
> >
> > Thoughts?
>
> Perhaps the existing functions could be renamed to things like:
>
> outer_XXX_flush_range()
> outer_XXX_sync()
>
> Where XXX is something like "batch" or "background". Optionally these
> could be declared somewhere separate to discourage non-DMA code from
> using them. Other code could still want to do batches of outer cache
> operations efficiently, but I guess DMA is the main user.
There can be some confusion with using 'background' name because both
PL310 and L2X0 have background operations (the former only for the
set/way ops). But in software you need to ensure the completion of such
operations otherwise the L2 controller behaviour can be unpredictable.
So you just want to drop the barriers (outer_sync and dsb), maybe could
use the 'relaxed' suffix which matches the I/O accessors.
--
Catalin
^ permalink raw reply
* [PATCH 00/16] big.LITTLE low-level CPU and cluster power management
From: Catalin Marinas @ 2013-01-16 16:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301151140550.6300@xanadu.home>
On Tue, Jan 15, 2013 at 04:44:23PM +0000, Nicolas Pitre wrote:
> On Tue, 15 Jan 2013, Joseph Lo wrote:
> > So do you have a plan to make it become a generic framework in this
> > series or later work?
>
> It is already generic, except for the name. In other words, you could
> start using this code already.
>
> I'm still debating a good substitute for the bL_ prefix in this series
> to give it the appearance of generic code.
mc_?
--
Catalin
^ permalink raw reply
* [PATCH v5 07/14] KVM: ARM: World-switch implementation
From: Gleb Natapov @ 2013-01-16 15:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANM98q+jpzVWfg8drE+azcbDF1Q1suphZyJrij04b+OB4ZX4Dw@mail.gmail.com>
On Wed, Jan 16, 2013 at 10:42:02AM -0500, Christoffer Dall wrote:
> [...]
>
> >
> >> read side RCU protects against is the memslots data structure as far
> >> as I can see, so the second patch pasted below fixes this for the code
> >> that actually accesses this data structure.
> > Many memory related functions that you call access memslots under the
> > hood and assume that locking is done by the caller. From the quick look
> > I found those that you've missed:
> > kvm_is_visible_gfn()
> > kvm_read_guest()
> > gfn_to_hva()
> > gfn_to_pfn_prot()
> > kvm_memslots()
> >
> > May be there are more. Can you enable RCU debugging in your kernel config
> > and check? This does not guaranty that it will catch all of the places,
> > but better than nothing.
> >
>
> yeah, I missed the call to is_visible_gfn and friends, this fixes it:
>
Thank you. One more kvm_read_guest() in emulate.c.
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index c806080..f30e131 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -591,7 +591,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
> struct kvm_run *run)
> struct kvm_memory_slot *memslot;
> bool is_iabt;
> gfn_t gfn;
> - int ret;
> + int ret, idx;
>
> hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
> is_iabt = (hsr_ec == HSR_EC_IABT);
> @@ -608,33 +608,43 @@ int kvm_handle_guest_abort(struct kvm_vcpu
> *vcpu, struct kvm_run *run)
> return -EFAULT;
> }
>
> + idx = srcu_read_lock(&vcpu->kvm->srcu);
> +
> gfn = fault_ipa >> PAGE_SHIFT;
> if (!kvm_is_visible_gfn(vcpu->kvm, gfn)) {
> if (is_iabt) {
> /* Prefetch Abort on I/O address */
> kvm_inject_pabt(vcpu, vcpu->arch.hxfar);
> - return 1;
> + ret = 1;
> + goto out_unlock;
> }
>
> if (fault_status != FSC_FAULT) {
> kvm_err("Unsupported fault status on io memory: %#lx\n",
> fault_status);
> - return -EFAULT;
> + ret = -EFAULT;
> + goto out_unlock;
> }
>
> /* Adjust page offset */
> fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK;
> - return io_mem_abort(vcpu, run, fault_ipa);
> + ret = io_mem_abort(vcpu, run, fault_ipa);
> + goto out_unlock;
> }
>
> memslot = gfn_to_memslot(vcpu->kvm, gfn);
> if (!memslot->user_alloc) {
> kvm_err("non user-alloc memslots not supported\n");
> - return -EINVAL;
> + ret = -EINVAL;
> + goto out_unlock;
> }
>
> ret = user_mem_abort(vcpu, fault_ipa, gfn, memslot, fault_status);
> - return ret ? ret : 1;
> + if (ret == 0)
> + ret = 1;
> +out_unlock:
> + srcu_read_unlock(&vcpu->kvm->srcu, idx);
> + return ret;
> }
>
> static void handle_hva_to_gpa(struct kvm *kvm,
> --
>
> Thanks,
> -Christoffer
--
Gleb.
^ permalink raw reply
* [PATCH] ata: sata_mv: fix sg_tbl_pool alignment
From: Jason Cooper @ 2013-01-16 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50F66B1B.40301@web.de>
On Wed, Jan 16, 2013 at 09:55:55AM +0100, Soeren Moch wrote:
> On 16.01.2013 04:24, Soeren Moch wrote:
> >On 16.01.2013 03:40, Jason Cooper wrote:
> >>On Wed, Jan 16, 2013 at 01:17:59AM +0100, Soeren Moch wrote:
> >>>On 15.01.2013 22:56, Jason Cooper wrote:
> >>>>On Tue, Jan 15, 2013 at 03:16:17PM -0500, Jason Cooper wrote:
> OK, I could trigger the error
> ERROR: 1024 KiB atomic DMA coherent pool is too small!
> Please increase it with coherent_pool= kernel parameter!
> only with em28xx sticks and sata, dib0700 sticks removed.
Did you test the reverse scenario? ie dib0700 with sata_mv and no
em28xx.
What kind of throughput are you pushing to the sata disk?
> >>What would be most helpful is if you could do a git bisect between
> >>v3.5.x (working) and the oldest version where you know it started
> >>failing (v3.7.1 or earlier if you know it).
> >>
> >I did not bisect it, but Marek mentioned earlier that commit
> >e9da6e9905e639b0f842a244bc770b48ad0523e9 in Linux v3.6-rc1 introduced
> >new code for dma allocations. This is probably the root cause for the
> >new (mis-)behavior (due to my tests 3.6.0 is not working anymore).
>
> I don't want to say that Mareks patch is wrong, probably it triggers a
> bug somewhere else! (in em28xx?)
Of the four drivers you listed, none are using dma. sata_mv is the only
one.
If one is to believe the comments in sata_mv.c:~151, then the alignment
is wrong for the sg_tbl_pool.
Could you please try the following patch?
thx,
Jason.
---8<----------
>From 566c7e30285e4c31d76724ea4811b016b753f24f Mon Sep 17 00:00:00 2001
From: Jason Cooper <jason@lakedaemon.net>
Date: Wed, 16 Jan 2013 15:43:37 +0000
Subject: [PATCH] ata: sata_mv: fix sg_tbl_pool alignment
If the comment is to be believed, the alignment should be 16B, and the
size 4K. The current code sets both to 4K. On some arm boards
(kirkwood), this causes:
ERROR: 1024 KiB atomic DMA coherent pool is too small!
Please increase it with coherent_pool= kernel parameter!
Set alignment to 16B to prevent exhausting the atomic_pool.
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
drivers/ata/sata_mv.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 68f4fb5..e2e5a8a 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -148,6 +148,9 @@ enum {
* CRPB needs alignment on a 256B boundary. Size == 256B
* ePRD (SG) entries need alignment on a 16B boundary. Size == 16B
*/
+ MV_CRQB_Q_ALIGN = 1024,
+ MV_CRPB_Q_ALIGN = 256,
+ MV_SG_TBL_ALIGN = 16,
MV_CRQB_Q_SZ = (32 * MV_MAX_Q_DEPTH),
MV_CRPB_Q_SZ = (8 * MV_MAX_Q_DEPTH),
MV_MAX_SG_CT = 256,
@@ -3975,17 +3978,17 @@ done:
static int mv_create_dma_pools(struct mv_host_priv *hpriv, struct device *dev)
{
hpriv->crqb_pool = dmam_pool_create("crqb_q", dev, MV_CRQB_Q_SZ,
- MV_CRQB_Q_SZ, 0);
+ MV_CRQB_Q_ALIGN, 0);
if (!hpriv->crqb_pool)
return -ENOMEM;
hpriv->crpb_pool = dmam_pool_create("crpb_q", dev, MV_CRPB_Q_SZ,
- MV_CRPB_Q_SZ, 0);
+ MV_CRPB_Q_ALIGN, 0);
if (!hpriv->crpb_pool)
return -ENOMEM;
hpriv->sg_tbl_pool = dmam_pool_create("sg_tbl", dev, MV_SG_TBL_SZ,
- MV_SG_TBL_SZ, 0);
+ MV_SG_TBL_ALIGN, 0);
if (!hpriv->sg_tbl_pool)
return -ENOMEM;
--
1.8.1.1
^ permalink raw reply related
* ARM DMA: Fix in dma_cache_maint_page
From: James Bottomley @ 2013-01-16 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130116130838.GS23505@n2100.arm.linux.org.uk>
On Wed, 2013-01-16 at 13:08 +0000, Russell King - ARM Linux wrote:
> On Wed, Jan 16, 2013 at 12:51:55PM +0000, James Bottomley wrote:
> > On Wed, 2013-01-16 at 18:17 +0530, Subhash Jadavani wrote:
> > > Is it possible to pick up James patch below? Thread here:
> > > http://comments.gmane.org/gmane.linux.kernel.mmc/18670, have the details
> > > on the motivation behind this fix.
> >
> > Someone should also audit the arm kernel code for more of these linear
> > page array assumptions. I'm guessing that when sparsemem was added to
> > arm over a year ago, whoever did it either didn't audit or missed a few.
>
> No, that's a bad assumption. We've had discontigmem for years - maybe
> something like 12 years.
Discontigmem doesn't suffer from this particular problem: The breaks in
the page arrays in a discontigmem environment represent real breaks in
the physical memory map, so there can never arise a situation where
page++ wouldn't get you the next valid page, provided there's still a
real contiguous page of physical memory present in the system, of
course.
Sparsemem tried to be cleverer and it broke that assumption. I'm
starting to wonder if there are other places in the kernel which make it
and get broken by sparsemem.
I have patches for parisc to switch it over to sparsemem from
discontigmem ... I haven't pushed them yet, fortunately, and I certainly
didn't check our underlying assumptions for this problem.
> I switched everything over to sparsemem, and
> sparsemem has been used on ARM for years too:
>
> commit 05944d74bc28fffbcce159cb915d0acff82f30a1
> Author: Russell King <rmk@dyn-67.arm.linux.org.uk>
> Date: Thu Nov 30 20:43:51 2006 +0000
>
> [ARM] Add initial sparsemem support
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>
> However, there's a big problem with this: very few of the lead people
> have machines which suffer from this disability, so there's very little
> testing of it - and there's very little testing of new code with it.
Anyone can test this just by enabling sparsemem with an artificially
small SECTION_SIZE_BITS (that makes it much more likely you'll hit a
boundary).
> The patch which originally introduced this code which your patch
> touches was part of adding highmem support to ARM:
>
> commit 43377453af83b8ff8c1c731da1508bd6b84ebfea
> Author: Nicolas Pitre <nico@cam.org>
> Date: Thu Mar 12 22:52:09 2009 -0400
>
> [ARM] introduce dma_cache_maint_page()
>
> This is a helper to be used by the DMA mapping API to handle cache
> maintenance for memory identified by a page structure instead of a
> virtual address. Those pages may or may not be highmem pages, and
> when they're highmem pages, they may or may not be virtually mapped.
> When they're not mapped then there is no L1 cache to worry about. But
> even in that case the L2 cache must be processed since unmapped highmem
> pages can still be L2 cached.
>
> Signed-off-by: Nicolas Pitre <nico@marvell.com>
>
> some three years later, and has been through a number of revisions since.
>
> I'd really like to get rid of sparsemem so it's one less failure case, but
> alas there's a relatively small bunch of folk who rely upon it. That
> means it's always going to be more buggy.
Heh, I'd like to do that too on parisc; the problem is that the memory
holes in our platform are just to big to use a linear array on. And now
that the slub people want DISCONTIGMEM deprecated, there's not much
choice.
James
^ permalink raw reply
* [PATCH v5 07/14] KVM: ARM: World-switch implementation
From: Christoffer Dall @ 2013-01-16 15:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130116121238.GS11529@redhat.com>
[...]
>
>> read side RCU protects against is the memslots data structure as far
>> as I can see, so the second patch pasted below fixes this for the code
>> that actually accesses this data structure.
> Many memory related functions that you call access memslots under the
> hood and assume that locking is done by the caller. From the quick look
> I found those that you've missed:
> kvm_is_visible_gfn()
> kvm_read_guest()
> gfn_to_hva()
> gfn_to_pfn_prot()
> kvm_memslots()
>
> May be there are more. Can you enable RCU debugging in your kernel config
> and check? This does not guaranty that it will catch all of the places,
> but better than nothing.
>
yeah, I missed the call to is_visible_gfn and friends, this fixes it:
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index c806080..f30e131 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -591,7 +591,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
struct kvm_run *run)
struct kvm_memory_slot *memslot;
bool is_iabt;
gfn_t gfn;
- int ret;
+ int ret, idx;
hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
is_iabt = (hsr_ec == HSR_EC_IABT);
@@ -608,33 +608,43 @@ int kvm_handle_guest_abort(struct kvm_vcpu
*vcpu, struct kvm_run *run)
return -EFAULT;
}
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+
gfn = fault_ipa >> PAGE_SHIFT;
if (!kvm_is_visible_gfn(vcpu->kvm, gfn)) {
if (is_iabt) {
/* Prefetch Abort on I/O address */
kvm_inject_pabt(vcpu, vcpu->arch.hxfar);
- return 1;
+ ret = 1;
+ goto out_unlock;
}
if (fault_status != FSC_FAULT) {
kvm_err("Unsupported fault status on io memory: %#lx\n",
fault_status);
- return -EFAULT;
+ ret = -EFAULT;
+ goto out_unlock;
}
/* Adjust page offset */
fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK;
- return io_mem_abort(vcpu, run, fault_ipa);
+ ret = io_mem_abort(vcpu, run, fault_ipa);
+ goto out_unlock;
}
memslot = gfn_to_memslot(vcpu->kvm, gfn);
if (!memslot->user_alloc) {
kvm_err("non user-alloc memslots not supported\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_unlock;
}
ret = user_mem_abort(vcpu, fault_ipa, gfn, memslot, fault_status);
- return ret ? ret : 1;
+ if (ret == 0)
+ ret = 1;
+out_unlock:
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
+ return ret;
}
static void handle_hva_to_gpa(struct kvm *kvm,
--
Thanks,
-Christoffer
^ permalink raw reply related
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