Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/3] arm: dts: imx7-colibri: Use pwm polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Configure PWM polarity control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 arch/arm/boot/dts/imx7-colibri.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index a9cc657..2af5e3e 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -43,7 +43,7 @@
 / {
 	bl: backlight {
 		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 5000000>;
+		pwms = <&pwm1 0 5000000 0>;
 	};
 
 	reg_module_3v3: regulator-module-3v3 {
-- 
2.9.2

^ permalink raw reply related

* [PATCH 1/3] arm: dts: imx7: Update #pwm-cells for PWM polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Update #pwm-cells to 3 in order to support PWM signal polarity control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +++---
 arch/arm/boot/dts/imx7s.dtsi                      | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
index e00c2e9..c61bdf8 100644
--- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -6,8 +6,8 @@ Required properties:
   - "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1
   - "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27
 - reg: physical base address and length of the controller's registers
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
-  the cells format.
+- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt
+  in this directory for a description of the cells format.
 - clocks : Clock specifiers for both ipg and per clocks.
 - clock-names : Clock names should include both "ipg" and "per"
 See the clock consumer binding,
@@ -17,7 +17,7 @@ See the clock consumer binding,
 Example:
 
 pwm1: pwm at 53fb4000 {
-	#pwm-cells = <2>;
+	#pwm-cells = <3>;
 	compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
 	reg = <0x53fb4000 0x4000>;
 	clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 0d7d5ac..8d1d471 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -601,7 +601,7 @@
 				clocks = <&clks IMX7D_PWM1_ROOT_CLK>,
 					 <&clks IMX7D_PWM1_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -612,7 +612,7 @@
 				clocks = <&clks IMX7D_PWM2_ROOT_CLK>,
 					 <&clks IMX7D_PWM2_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -623,7 +623,7 @@
 				clocks = <&clks IMX7D_PWM3_ROOT_CLK>,
 					 <&clks IMX7D_PWM3_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -634,7 +634,7 @@
 				clocks = <&clks IMX7D_PWM4_ROOT_CLK>,
 					 <&clks IMX7D_PWM4_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
-- 
2.9.2

^ permalink raw reply related

* [PATCH 0/3] iMX7 PWM polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset depends on this patchset[1] and this patch[2] which adds support
for polarity control in imx-pwm driver.

- Use pwm polarity control on iMX7 based modules.
- Enable polarity control on Toradex Colibri iMX7D/S module.
- Add BL_ON GPIO control for Toradex Colibri iMX7D/S module.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/294027.html
[2] https://www.spinics.net/lists/arm-kernel/msg530818.html

Bhuvanchandra DV (3):
  arm: dts: imx7: Update #pwm-cells for PWM polarity control
  arm: dts: imx7-colibri: Use pwm polarity control
  arm: dts: imx7-colibri: Use enable-gpios for BL_ON

 Documentation/devicetree/bindings/pwm/imx-pwm.txt |  6 +++---
 arch/arm/boot/dts/imx7-colibri.dtsi               | 12 ++++++++++--
 arch/arm/boot/dts/imx7s.dtsi                      |  8 ++++----
 3 files changed, 17 insertions(+), 9 deletions(-)

-- 
2.9.2

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Will Deacon @ 2016-09-19 14:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <99ee0946-c7ff-e6e4-08c1-ff686ea1a8a5@arm.com>

On Mon, Sep 19, 2016 at 01:41:47PM +0100, Robin Murphy wrote:
> On 19/09/16 13:24, Will Deacon wrote:
> > On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
> >> On 16/09/2016 18:18, Robin Murphy wrote:
> >>> What I probably will do, though, since we have the functionality in
> >>> place for the sake of the old binding, and I think there are other folks
> >>> who want PCI iommu-map support but would prefer not to bother with DMA
> >>> ops on the host, is add a command-line option to disable DMA domains
> >>> even for the generic bindings.
> >>
> >> Yes this would be a good thing I think. This series has an important
> >> impact on platforms which do not have smmu v3, where contexts are scarce
> >> HW resources.
> > 
> > Rather than disabling DMA domains entirely, we could specify a number
> > of contexts to reserve for other use (e.g. VFIO). It's a pity that these
> > options are global for the system, as opposed to per SMMU instance,
> > but I can't see a good way around that.
> 
> The problem with that approach is that due to bus traversal order you'd
> typically end up with the even-more-limited number of non-reserved
> contexts getting consumed by bridges that are unlikely to ever actually
> use their DMA ops, so you end up barely any better off than just not
> doing DMA ops at all, which we already have the code for.

For Seattle, perhaps, but that's quite a big generalisation. If we're
going to add an option, I'd much rather add something with some flexibility,
rather than end up supporting both "disable_dma_domains" and
"reserved_s2_contexts" in the long run.

> And yeah, if you had, say, "arm-smmu.reserved_s2_contexts=4", for the
> benefit of your PCI SMMU, what do the SMMUs in front of your other
> platform devices with only 2 contexts (and which only want DMA ops) do?

There's two things in this example:

  (1) If other SMMUs only have 2 contexts, then they reserve both and warn
  (2) If some SMMUs want DMA ops and others don't, then you have an issue
      with *any* sort of cmdline option to control this

Will

^ permalink raw reply

* [RFC] Arm64 boot fail with numa enable in BIOS
From: Mark Rutland @ 2016-09-19 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7618d76d-bfa8-d8aa-59aa-06f9d90c1a98@huawei.com>

[adding LAKML, arm64 maintainers]

On Mon, Sep 19, 2016 at 09:05:26PM +0800, Yisheng Xie wrote:
> hi all,

Hi,

In future, please make sure to Cc LAKML along with relevant parties when
sending arm64 patches/queries.

For everyone newly Cc'd, the original message (with attachments) can be
found at:

http://lkml.kernel.org/r/7618d76d-bfa8-d8aa-59aa-06f9d90c1a98 at huawei.com

> When I enable NUMA in BIOS for arm64, it failed to boot on v4.8-rc4-162-g071e31e.

That commit ID doesn't seem to be in mainline (I can't find it in my
local tree). Which tree are you using? Do you have local patches
applied?

I take it that by "enable NUMA in BIOS", you mean exposing SRAT to the
OS?

> For the crash log, it seems caused by error number of cpumask.
> Any ideas about it?

Much earlier in your log, there was a (non-fatal) warning, as below. Do
you see this without NUMA/SRAT enabled in your FW? I don't see how the
SRAT should affect the secondaries we try to bring online.

Given your MPIDRs have Aff2 bits set, I wonder if we've conflated a
logical ID with a physical ID somewhere, and it just so happens that the
NUMA code is more likely to poke something based on that.

Can you modify the warning in cpumask.h to dump the bad CPU number? That
would make it fairly clear if that's the case.

Thanks,
Mark.

> [    0.297337] Detected PIPT I-cache on CPU1
> [    0.297347] GICv3: CPU1: found redistributor 10001 region 1:0x000000004d140000
> [    0.297356] CPU1: Booted secondary processor [410fd082]
> [    0.297375] ------------[ cut here ]------------
> [    0.320390] WARNING: CPU: 1 PID: 0 at ./include/linux/cpumask.h:121 gic_raise_softirq+0x128/0x17c
> [    0.329356] Modules linked in:
> [    0.332434] 
> [    0.333932] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-rc4-00163-g803ea3a #21
> [    0.341581] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> [    0.347735] task: ffff8013e9dd0000 task.stack: ffff8013e9dcc000
> [    0.353714] PC is at gic_raise_softirq+0x128/0x17c
> [    0.358550] LR is at gic_raise_softirq+0xa0/0x17c
> [    0.363298] pc : [<ffff00000838c124>] lr : [<ffff00000838c09c>] pstate: 200001c5
> [    0.370770] sp : ffff8013e9dcfde0
> [    0.374112] x29: ffff8013e9dcfde0 x28: 0000000000000000 
> [    0.379476] x27: 000000000083207c x26: ffff000008ca5d70 
> [    0.384841] x25: 0000000100000001 x24: ffff000008d63ff3 
> [    0.390205] x23: 0000000000000000 x22: ffff000008cb0000 
> [    0.395569] x21: ffff00000884edb0 x20: 0000000000000001 
> [    0.400933] x19: 0000000100000000 x18: 0000000000000000 
> [    0.406298] x17: 0000000000000000 x16: 0000000003010066 
> [    0.411661] x15: ffff000008ca8000 x14: 0000000000000013 
> [    0.417025] x13: 0000000000000000 x12: 0000000000000013 
> [    0.422389] x11: 0000000000000013 x10: 0000000002e92aa7 
> [    0.427754] x9 : 0000000000000000 x8 : ffff8413eb6ca668 
> [    0.433118] x7 : ffff8413eb6ca690 x6 : 0000000000000000 
> [    0.438482] x5 : fffffffffffffffe x4 : 0000000000000000 
> [    0.443845] x3 : 0000000000000040 x2 : 0000000000000041 
> [    0.449209] x1 : 0000000000000000 x0 : 0000000000000001 
> [    0.454573] 
> [    0.456069] ---[ end trace b58e70f3295a8cd7 ]---
> [    0.460730] Call trace:
> [    0.463193] Exception stack(0xffff8013e9dcfc10 to 0xffff8013e9dcfd40)
> [    0.469699] fc00:                                   0000000100000000 0001000000000000
> [    0.477611] fc20: ffff8013e9dcfde0 ffff00000838c124 ffff000008d72228 ffff8013e9dcff70
> [    0.485524] fc40: ffff000008d72608 ffff000008ab02a4 0000000000000000 0000000000000000
> [    0.493436] fc60: 0000000000000000 3464313430303030 0000000000000000 0000000000000000
> [    0.501348] fc80: ffff8013e9dcfc90 ffff00000836e678 ffff8013e9dcfca0 ffff00000836e910
> [    0.509259] fca0: ffff8013e9dcfd30 ffff00000836ec10 0000000000000001 0000000000000000
> [    0.517171] fcc0: 0000000000000041 0000000000000040 0000000000000000 fffffffffffffffe
> [    0.525083] fce0: 0000000000000000 ffff8413eb6ca690 ffff8413eb6ca668 0000000000000000
> [    0.532995] fd00: 0000000002e92aa7 0000000000000013 0000000000000013 0000000000000000
> [    0.540907] fd20: 0000000000000013 ffff000008ca8000 0000000003010066 0000000000000000
> [    0.548819] [<ffff00000838c124>] gic_raise_softirq+0x128/0x17c
> [    0.554713] [<ffff00000808e1f4>] smp_send_reschedule+0x34/0x3c
> [    0.560605] [<ffff0000080ddf18>] resched_curr+0x40/0x5c
> [    0.565881] [<ffff0000080de650>] check_preempt_curr+0x58/0xa0
> [    0.571685] [<ffff0000080de6b0>] ttwu_do_wakeup+0x18/0x80
> [    0.577136] [<ffff0000080de790>] ttwu_do_activate+0x78/0x88
> [    0.582763] [<ffff0000080df5cc>] try_to_wake_up+0x1f8/0x300
> [    0.588390] [<ffff0000080df79c>] default_wake_function+0x10/0x18
> [    0.594458] [<ffff0000080f3210>] __wake_up_common+0x5c/0x9c
> [    0.600085] [<ffff0000080f3264>] __wake_up_locked+0x14/0x1c
> [    0.605712] [<ffff0000080f3e10>] complete+0x40/0x5c
> [    0.610635] [<ffff00000808dba8>] secondary_start_kernel+0x148/0x1a8
> [    0.616965] [<00000000000831a8>] 0x831a8

^ permalink raw reply

* [PATCH v2 1/3] ipmi: add an Aspeed BT IPMI BMC driver
From: Corey Minyard @ 2016-09-19 14:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9ce54c4c-e8ae-7ac2-de9c-71402dfa4c39@kaod.org>

On 09/19/2016 03:00 AM, C?dric Le Goater wrote:
> On 09/16/2016 09:41 PM, Corey Minyard wrote:
>> On 09/16/2016 05:39 AM, C?dric Le Goater wrote:
>>> From: Alistair Popple <alistair@popple.id.au>
>>>
>>> This patch adds a simple device driver to expose the iBT interface on
>>> Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
>>> commonly used as BMCs (BaseBoard Management Controllers) and this
>>> driver implements the BMC side of the BT interface.
>>>
>>> The BT (Block Transfer) interface is used to perform in-band IPMI
>>> communication between a host and its BMC. Entire messages are buffered
>>> before sending a notification to the other end, host or BMC, that
>>> there is data to be read. Usually, the host emits requests and the BMC
>>> responses but the specification provides a mean for the BMC to send
>>> SMS Attention (BMC-to-Host attention or System Management Software
>>> attention) messages.
>>>
>>> For this purpose, the driver introduces a specific ioctl on the
>>> device: 'BT_BMC_IOCTL_SMS_ATN' that can be used by the system running
>>> on the BMC to signal the host of such an event.
>>>
>>> The device name defaults to '/dev/ipmi-bt-host'
>> Others have reviewed this for style and such, and I have looked
>> at it from a protocol point of view.  it looks to be sound for the
>> most part.  I have some higher level concerns:
>>
>> There appears to be no handling for multiple simultaneous users.
>> This interface can only be used by one task at a time, so you should
>> probably only allow one opener.  Well, I guess the BMC could be split
>> into a reader and a writer task, so I'm not really sure about that, but
>> I would think in most situations having more than one opener is a
>> bug.  You do call clr_b_busy() on open, for instance, which might be
>> an issue for multiple openers.  Maybe a module parameter for
>> maximum number of openers? Just want to make sure this was
>> thought about, at least.
> yes but not implemented ... The open_count in the bt_bmc structure
> is unused. In v3, I will replace it with a global atomic_t tracked
> in the open and release operations.
>
>> There is also no mutex protecting reading or writing.  If multiple
>> threads call read or write at the same time, it probably wouldn't
>> work correctly.  I think you need a read and a write mutex on the
>> interface to protect against this.
> yes. I will add a mutex also in v3.
>
>> The spec says:
>>
>>     The BMC must not return a given response once the corresponding
>>     Request-to-Response interval has passed. The BMC can ensure this
>>     by maintaining its own internal list of outstanding requests through
>>     the interface. The BMC could age and expire the entries in the list
>>     by expiring the entries at an interval that is somewhat shorter than
>>     the specified Request-to-Response interval....
> This is clearly not handled in the driver.
>
> For this purpose, we could maintain a request expiry list using the seq
> field of the BT message. Update the list in the read and write operations
> and arm a timer to garbage collect any left overs. As for the errno in
> the write when a response had timeout'ed, may be ETIMEDOUT ?

I think that would work, though I don't think you really need an
error response in this case.

I was thinking more just a timeout in the write function.  Ideally
the timeout would be calculated at receive time and then be
passed in on every write, to preserve the request-to-response
time for slow messages.  I like the simplicity of the driver the
way it is.

The trouble is that there is no easy way to pass in a timeout
in a write operation.  You could pass in a structure where the
first part is a 32-bit timeout, or something like that.  Or
maybe just a fixed timeout and assume every message is
handled in a short enough time that it meets the spec
requirement.  But that doesn't handle slowness on the
host side.  You can send the message via an ioctl,  which
again isn't terribly ideal.

It would be nice if there was a write function which was
able to pass metadata, but AFAIK that's only available on
sockets.

> For configuration of the maximum response time, a sysfs file would do
> I think.
>
> Do you want that in v3 also ? I have some experimental patches for it,
> that I can send as follow ups.

I'm fine either way.

Thanks,

-corey

>
> Thanks,
>
> C.
>
>> On the write side, though, there doesn't seem to be a way to handle a
>> situation where the host side doesn't respond for a while and the
>> pending message would need to be discarded.
>>
>> The spec doesn't mention much about error recovery on this interface,
>> but the way this is written should be fine, I think.
>>
>> I'm copying Rocky Craig, who wrote the host side driver for Linux, in
>> case he wants to comment on this.
>>
>> This is easy to read and understand, so I think v3 should be good.
>>
>> Thanks,
>>
>> -corey
>>
>>> Signed-off-by: Alistair Popple <alistair@popple.id.au>
>>> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
>>> Signed-off-by: Joel Stanley <joel@jms.id.au>
>>> [clg: - checkpatch fixes
>>>         - added a devicetree binding documentation
>>>         - replace 'bt_host' by 'bt_bmc' to reflect that the driver is
>>>           the BMC side of the IPMI BT interface
>>>         - renamed the device to 'ipmi-bt-host'
>>>         - introduced a temporary buffer to copy_{to,from}_user
>>>         - used platform_get_irq()
>>>         - moved the driver under drivers/char/ipmi/ but kept it as a misc
>>>           device
>>>         - changed the compatible cell to "aspeed,ast2400-bt-bmc"
>>> ]
>>> Signed-off-by: C?dric Le Goater <clg@kaod.org>
>>> ---
>>>
>>>    Changes since v1:
>>>
>>>    - replace 'bt_host' by 'bt_bmc' to reflect that the driver is
>>>      the BMC side of the IPMI BT interface
>>>    - renamed the device to 'ipmi-bt-host'
>>>    - introduced a temporary buffer to copy_{to,from}_user
>>>    - used platform_get_irq()
>>>    - moved the driver under drivers/char/ipmi/ but kept it as a misc
>>>      device
>>>    - changed the compatible cell to "aspeed,ast2400-bt-bmc"
>>>
>>>    .../bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt   |  23 +
>>>    drivers/Makefile                                   |   2 +-
>>>    drivers/char/ipmi/Kconfig                          |   7 +
>>>    drivers/char/ipmi/Makefile                         |   1 +
>>>    drivers/char/ipmi/bt-bmc.c                         | 486 +++++++++++++++++++++
>>>    include/uapi/linux/Kbuild                          |   1 +
>>>    include/uapi/linux/bt-bmc.h                        |  18 +
>>>    7 files changed, 537 insertions(+), 1 deletion(-)
>>>    create mode 100644 Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>>    create mode 100644 drivers/char/ipmi/bt-bmc.c
>>>    create mode 100644 include/uapi/linux/bt-bmc.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt b/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>> new file mode 100644
>>> index 000000000000..fbbacd958240
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>> @@ -0,0 +1,23 @@
>>> +* Aspeed BT (Block Transfer) IPMI interface
>>> +
>>> +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs
>>> +(BaseBoard Management Controllers) and the BT interface can be used to
>>> +perform in-band IPMI communication with their host.
>>> +
>>> +Required properties:
>>> +
>>> +- compatible : should be "aspeed,ast2400-bt-bmc"
>>> +- reg: physical address and size of the registers
>>> +
>>> +Optional properties:
>>> +
>>> +- interrupts: interrupt generated by the BT interface. without an
>>> +  interrupt, the driver will operate in poll mode.
>>> +
>>> +Example:
>>> +
>>> +    ibt at 1e789140 {
>>> +        compatible = "aspeed,ast2400-bt-bmc";
>>> +        reg = <0x1e789140 0x18>;
>>> +        interrupts = <8>;
>>> +    };
>>> diff --git a/drivers/Makefile b/drivers/Makefile
>>> index 53abb4a5f736..5a9e7b6b7928 100644
>>> --- a/drivers/Makefile
>>> +++ b/drivers/Makefile
>>> @@ -21,7 +21,7 @@ obj-y                += video/
>>>    obj-y                += idle/
>>>      # IPMI must come before ACPI in order to provide IPMI opregion support
>>> -obj-$(CONFIG_IPMI_HANDLER)    += char/ipmi/
>>> +obj-y                += char/ipmi/
>>>      obj-$(CONFIG_ACPI)        += acpi/
>>>    obj-$(CONFIG_SFI)        += sfi/
>>> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
>>> index 5a9350b1069a..2c234e3e7513 100644
>>> --- a/drivers/char/ipmi/Kconfig
>>> +++ b/drivers/char/ipmi/Kconfig
>>> @@ -76,3 +76,10 @@ config IPMI_POWEROFF
>>>         the IPMI management controller is capable of this.
>>>      endif # IPMI_HANDLER
>>> +
>>> +config ASPEED_BT_IPMI_BMC
>>> +    tristate "BT IPMI bmc driver"
>>> +    help
>>> +      Provides a driver for the BT (Block Transfer) IPMI interface
>>> +      found on Aspeed SOCs (AST2400 and AST2500). The driver
>>> +      implements the BMC side of the BT interface.
>>> diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
>>> index f3ffde1f5f1f..0d98cd91def1 100644
>>> --- a/drivers/char/ipmi/Makefile
>>> +++ b/drivers/char/ipmi/Makefile
>>> @@ -11,3 +11,4 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o
>>>    obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
>>>    obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
>>>    obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
>>> +obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
>>> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
>>> new file mode 100644
>>> index 000000000000..b96cb421e1c2
>>> --- /dev/null
>>> +++ b/drivers/char/ipmi/bt-bmc.c
>>> @@ -0,0 +1,486 @@
>>> +/*
>>> + * Copyright (c) 2015-2016, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version
>>> + * 2 of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +#include <linux/module.h>
>>> +#include <linux/moduleparam.h>
>>> +#include <linux/errno.h>
>>> +#include <linux/poll.h>
>>> +#include <linux/sched.h>
>>> +#include <linux/spinlock.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/init.h>
>>> +#include <linux/device.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_irq.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/io.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/delay.h>
>>> +#include <linux/miscdevice.h>
>>> +#include <linux/timer.h>
>>> +#include <linux/jiffies.h>
>>> +#include <linux/bt-bmc.h>
>>> +
>>> +/*
>>> + * This is a BMC device used to communicate to the host
>>> + */
>>> +#define DEVICE_NAME    "ipmi-bt-host"
>>> +
>>> +#define BT_IO_BASE    0xe4
>>> +#define BT_IRQ        10
>>> +
>>> +#define BT_CR0        0x0
>>> +#define   BT_CR0_IO_BASE        16
>>> +#define   BT_CR0_IRQ            12
>>> +#define   BT_CR0_EN_CLR_SLV_RDP        0x8
>>> +#define   BT_CR0_EN_CLR_SLV_WRP        0x4
>>> +#define   BT_CR0_ENABLE_IBT        0x1
>>> +#define BT_CR1        0x4
>>> +#define   BT_CR1_IRQ_H2B    0x01
>>> +#define   BT_CR1_IRQ_HBUSY    0x40
>>> +#define BT_CR2        0x8
>>> +#define   BT_CR2_IRQ_H2B    0x01
>>> +#define   BT_CR2_IRQ_HBUSY    0x40
>>> +#define BT_CR3        0xc
>>> +#define BT_CTRL        0x10
>>> +#define   BT_CTRL_B_BUSY        0x80
>>> +#define   BT_CTRL_H_BUSY        0x40
>>> +#define   BT_CTRL_OEM0            0x20
>>> +#define   BT_CTRL_SMS_ATN        0x10
>>> +#define   BT_CTRL_B2H_ATN        0x08
>>> +#define   BT_CTRL_H2B_ATN        0x04
>>> +#define   BT_CTRL_CLR_RD_PTR        0x02
>>> +#define   BT_CTRL_CLR_WR_PTR        0x01
>>> +#define BT_BMC2HOST    0x14
>>> +#define BT_INTMASK    0x18
>>> +#define   BT_INTMASK_B2H_IRQEN        0x01
>>> +#define   BT_INTMASK_B2H_IRQ        0x02
>>> +#define   BT_INTMASK_BMC_HWRST        0x80
>>> +
>>> +struct bt_bmc {
>>> +    struct device        dev;
>>> +    struct miscdevice    miscdev;
>>> +    void __iomem        *base;
>>> +    int            open_count;
>>> +    int            irq;
>>> +    wait_queue_head_t    queue;
>>> +    struct timer_list    poll_timer;
>>> +};
>>> +
>>> +static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
>>> +{
>>> +    return ioread8(bt_bmc->base + reg);
>>> +}
>>> +
>>> +static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
>>> +{
>>> +    iowrite8(data, bt_bmc->base + reg);
>>> +}
>>> +
>>> +static void clr_rd_ptr(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_CLR_RD_PTR, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_wr_ptr(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_CLR_WR_PTR, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_h2b_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_H2B_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static void set_b_busy(struct bt_bmc *bt_bmc)
>>> +{
>>> +    if (!(bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_B_BUSY))
>>> +        bt_outb(bt_bmc, BT_CTRL_B_BUSY, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_b_busy(struct bt_bmc *bt_bmc)
>>> +{
>>> +    if (bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_B_BUSY)
>>> +        bt_outb(bt_bmc, BT_CTRL_B_BUSY, BT_CTRL);
>>> +}
>>> +
>>> +static void set_b2h_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_B2H_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static u8 bt_read(struct bt_bmc *bt_bmc)
>>> +{
>>> +    return bt_inb(bt_bmc, BT_BMC2HOST);
>>> +}
>>> +
>>> +static ssize_t bt_readn(struct bt_bmc *bt_bmc, u8 *buf, size_t n)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n; i++)
>>> +        buf[i] = bt_read(bt_bmc);
>>> +    return n;
>>> +}
>>> +
>>> +static void bt_write(struct bt_bmc *bt_bmc, u8 c)
>>> +{
>>> +    bt_outb(bt_bmc, c, BT_BMC2HOST);
>>> +}
>>> +
>>> +static ssize_t bt_writen(struct bt_bmc *bt_bmc, u8 *buf, size_t n)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n; i++)
>>> +        bt_write(bt_bmc, buf[i]);
>>> +    return n;
>>> +}
>>> +
>>> +static void set_sms_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_SMS_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static struct bt_bmc *file_bt_bmc(struct file *file)
>>> +{
>>> +    return container_of(file->private_data, struct bt_bmc, miscdev);
>>> +}
>>> +
>>> +static int bt_bmc_open(struct inode *inode, struct file *file)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +#define BT_BMC_BUFFER_SIZE 256
>>> +
>>> +/*
>>> + * The BT (Block Transfer) interface means that entire messages are
>>> + * buffered by the host before a notification is sent to the BMC that
>>> + * there is data to be read. The first byte is the length and the
>>> + * message data follows. The read operation just tries to capture the
>>> + * whole before returning it to userspace.
>>> + */
>>> +static ssize_t bt_bmc_read(struct file *file, char __user *buf,
>>> +                size_t count, loff_t *ppos)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    u8 len;
>>> +    int len_byte = 1;
>>> +    u8 kbuffer[BT_BMC_BUFFER_SIZE];
>>> +    ssize_t ret = 0;
>>> +    ssize_t nread;
>>> +
>>> +    if (!access_ok(VERIFY_WRITE, buf, count))
>>> +        return -EFAULT;
>>> +
>>> +    WARN_ON(*ppos);
>>> +
>>> +    if (wait_event_interruptible(bt_bmc->queue,
>>> +                bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_H2B_ATN))
>>> +        return -ERESTARTSYS;
>>> +
>>> +    set_b_busy(bt_bmc);
>>> +    clr_h2b_atn(bt_bmc);
>>> +    clr_rd_ptr(bt_bmc);
>>> +
>>> +    /*
>>> +     * The BT frames start with the message length, which does not
>>> +     * include the length byte.
>>> +     */
>>> +    kbuffer[0] = bt_read(bt_bmc);
>>> +    len = kbuffer[0];
>>> +
>>> +    /* We pass the length back to userspace as well */
>>> +    if (len + 1 > count)
>>> +        len = count - 1;
>>> +
>>> +    while (len) {
>>> +        nread = min_t(ssize_t, len, sizeof(kbuffer) - len_byte);
>>> +
>>> +        bt_readn(bt_bmc, kbuffer + len_byte, nread);
>>> +
>>> +        if (copy_to_user(buf, kbuffer, nread + len_byte)) {
>>> +            ret = -EFAULT;
>>> +            break;
>>> +        }
>>> +        len -= nread;
>>> +        buf += nread + len_byte;
>>> +        ret += nread + len_byte;
>>> +        len_byte = 0;
>>> +    }
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static ssize_t bt_bmc_write(struct file *file, const char __user *buf,
>>> +                size_t count, loff_t *ppos)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    u8 kbuffer[BT_BMC_BUFFER_SIZE];
>>> +    ssize_t ret = 0;
>>> +    ssize_t nwritten;
>>> +
>>> +    if (!access_ok(VERIFY_READ, buf, count))
>>> +        return -EFAULT;
>>> +
>>> +    WARN_ON(*ppos);
>>> +
>>> +    /* There's no interrupt for clearing bmc busy so we have to
>>> +     * poll
>>> +     */
>>> +    if (wait_event_interruptible(bt_bmc->queue,
>>> +                !(bt_inb(bt_bmc, BT_CTRL) &
>>> +                    (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN))))
>>> +        return -ERESTARTSYS;
>>> +
>>> +    clr_wr_ptr(bt_bmc);
>>> +
>>> +    while (count) {
>>> +        nwritten = min_t(ssize_t, count, sizeof(kbuffer));
>>> +        if (copy_from_user(&kbuffer, buf, nwritten)) {
>>> +            ret = -EFAULT;
>>> +            break;
>>> +        }
>>> +
>>> +        bt_writen(bt_bmc, kbuffer, nwritten);
>>> +
>>> +        count -= nwritten;
>>> +        buf += nwritten;
>>> +        ret += nwritten;
>>> +    }
>>> +
>>> +    set_b2h_atn(bt_bmc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static long bt_bmc_ioctl(struct file *file, unsigned int cmd,
>>> +        unsigned long param)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    switch (cmd) {
>>> +    case BT_BMC_IOCTL_SMS_ATN:
>>> +        set_sms_atn(bt_bmc);
>>> +        return 0;
>>> +    }
>>> +    return -EINVAL;
>>> +}
>>> +
>>> +static int bt_bmc_release(struct inode *inode, struct file *file)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    set_b_busy(bt_bmc);
>>> +    return 0;
>>> +}
>>> +
>>> +static unsigned int bt_bmc_poll(struct file *file, poll_table *wait)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    unsigned int mask = 0;
>>> +    uint8_t ctrl;
>>> +
>>> +    poll_wait(file, &bt_bmc->queue, wait);
>>> +
>>> +    ctrl = bt_inb(bt_bmc, BT_CTRL);
>>> +
>>> +    if (ctrl & BT_CTRL_H2B_ATN)
>>> +        mask |= POLLIN;
>>> +
>>> +    if (!(ctrl & (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN)))
>>> +        mask |= POLLOUT;
>>> +
>>> +    return mask;
>>> +}
>>> +
>>> +static const struct file_operations bt_bmc_fops = {
>>> +    .owner        = THIS_MODULE,
>>> +    .open        = bt_bmc_open,
>>> +    .read        = bt_bmc_read,
>>> +    .write        = bt_bmc_write,
>>> +    .release    = bt_bmc_release,
>>> +    .poll        = bt_bmc_poll,
>>> +    .unlocked_ioctl    = bt_bmc_ioctl,
>>> +};
>>> +
>>> +static void poll_timer(unsigned long data)
>>> +{
>>> +    struct bt_bmc *bt_bmc = (void *)data;
>>> +
>>> +    bt_bmc->poll_timer.expires += msecs_to_jiffies(500);
>>> +    wake_up(&bt_bmc->queue);
>>> +    add_timer(&bt_bmc->poll_timer);
>>> +}
>>> +
>>> +static irqreturn_t bt_bmc_irq(int irq, void *arg)
>>> +{
>>> +    struct bt_bmc *bt_bmc = arg;
>>> +    uint32_t reg;
>>> +
>>> +    reg = ioread32(bt_bmc->base + BT_CR2);
>>> +    reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
>>> +    if (!reg)
>>> +        return IRQ_NONE;
>>> +
>>> +    /* ack pending IRQs */
>>> +    iowrite32(reg, bt_bmc->base + BT_CR2);
>>> +
>>> +    wake_up(&bt_bmc->queue);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>>> +        struct platform_device *pdev)
>>> +{
>>> +    struct device *dev = &pdev->dev;
>>> +    uint32_t reg;
>>> +    int rc;
>>> +
>>> +    bt_bmc->irq = platform_get_irq(pdev, 0);
>>> +    if (!bt_bmc->irq)
>>> +        return -ENODEV;
>>> +
>>> +    rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
>>> +            DEVICE_NAME, bt_bmc);
>>> +    if (rc < 0) {
>>> +        dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
>>> +        bt_bmc->irq = 0;
>>> +        return rc;
>>> +    }
>>> +
>>> +    /* Configure IRQs on the bmc clearing the H2B and HBUSY bits;
>>> +     * H2B will be asserted when the bmc has data for us; HBUSY
>>> +     * will be cleared (along with B2H) when we can write the next
>>> +     * message to the BT buffer
>>> +     */
>>> +    reg = ioread32(bt_bmc->base + BT_CR1);
>>> +    reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
>>> +    iowrite32(reg, bt_bmc->base + BT_CR1);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int bt_bmc_probe(struct platform_device *pdev)
>>> +{
>>> +    struct bt_bmc *bt_bmc;
>>> +    struct device *dev;
>>> +    struct resource *res;
>>> +    int rc;
>>> +
>>> +    if (!pdev || !pdev->dev.of_node)
>>> +        return -ENODEV;
>>> +
>>> +    dev = &pdev->dev;
>>> +    dev_info(dev, "Found bt bmc device\n");
>>> +
>>> +    bt_bmc = devm_kzalloc(dev, sizeof(*bt_bmc), GFP_KERNEL);
>>> +    if (!bt_bmc)
>>> +        return -ENOMEM;
>>> +
>>> +    dev_set_drvdata(&pdev->dev, bt_bmc);
>>> +
>>> +    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +    if (!res) {
>>> +        dev_err(dev, "Unable to find resources\n");
>>> +        rc = -ENXIO;
>>> +        goto out_free;
>>> +    }
>>> +
>>> +    bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
>>> +    if (!bt_bmc->base) {
>>> +        rc = -ENOMEM;
>>> +        goto out_free;
>>> +    }
>>> +
>>> +    init_waitqueue_head(&bt_bmc->queue);
>>> +
>>> +    bt_bmc->miscdev.minor    = MISC_DYNAMIC_MINOR,
>>> +    bt_bmc->miscdev.name    = DEVICE_NAME,
>>> +    bt_bmc->miscdev.fops    = &bt_bmc_fops,
>>> +    bt_bmc->miscdev.parent = dev;
>>> +    rc = misc_register(&bt_bmc->miscdev);
>>> +    if (rc) {
>>> +        dev_err(dev, "Unable to register device\n");
>>> +        goto out_unmap;
>>> +    }
>>> +
>>> +    bt_bmc_config_irq(bt_bmc, pdev);
>>> +
>>> +    if (bt_bmc->irq) {
>>> +        dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
>>> +    } else {
>>> +        dev_info(dev, "No IRQ; using timer\n");
>>> +        setup_timer(&bt_bmc->poll_timer, poll_timer,
>>> +                (unsigned long)bt_bmc);
>>> +        bt_bmc->poll_timer.expires = jiffies + msecs_to_jiffies(10);
>>> +        add_timer(&bt_bmc->poll_timer);
>>> +    }
>>> +
>>> +    iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
>>> +          (BT_IRQ << BT_CR0_IRQ) |
>>> +          BT_CR0_EN_CLR_SLV_RDP |
>>> +          BT_CR0_EN_CLR_SLV_WRP |
>>> +          BT_CR0_ENABLE_IBT,
>>> +          bt_bmc->base + BT_CR0);
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return 0;
>>> +
>>> +out_unmap:
>>> +    devm_iounmap(&pdev->dev, bt_bmc->base);
>>> +
>>> +out_free:
>>> +    devm_kfree(dev, bt_bmc);
>>> +    return rc;
>>> +
>>> +}
>>> +
>>> +static int bt_bmc_remove(struct platform_device *pdev)
>>> +{
>>> +    struct bt_bmc *bt_bmc = dev_get_drvdata(&pdev->dev);
>>> +
>>> +    misc_deregister(&bt_bmc->miscdev);
>>> +    if (!bt_bmc->irq)
>>> +        del_timer_sync(&bt_bmc->poll_timer);
>>> +    devm_iounmap(&pdev->dev, bt_bmc->base);
>>> +    devm_kfree(&pdev->dev, bt_bmc);
>>> +    bt_bmc = NULL;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static const struct of_device_id bt_bmc_match[] = {
>>> +    { .compatible = "aspeed,ast2400-bt-bmc" },
>>> +    { },
>>> +};
>>> +
>>> +static struct platform_driver bt_bmc_driver = {
>>> +    .driver = {
>>> +        .name        = DEVICE_NAME,
>>> +        .of_match_table = bt_bmc_match,
>>> +    },
>>> +    .probe = bt_bmc_probe,
>>> +    .remove = bt_bmc_remove,
>>> +};
>>> +
>>> +module_platform_driver(bt_bmc_driver);
>>> +
>>> +MODULE_DEVICE_TABLE(of, bt_bmc_match);
>>> +MODULE_LICENSE("GPL");
>>> +MODULE_AUTHOR("Alistair Popple <alistair@popple.id.au>");
>>> +MODULE_DESCRIPTION("Linux device interface to the BT interface");
>>> diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
>>> index 185f8ea2702f..17b12942c67d 100644
>>> --- a/include/uapi/linux/Kbuild
>>> +++ b/include/uapi/linux/Kbuild
>>> @@ -74,6 +74,7 @@ header-y += bpf_common.h
>>>    header-y += bpf.h
>>>    header-y += bpqether.h
>>>    header-y += bsg.h
>>> +header-y += bt-bmc.h
>>>    header-y += btrfs.h
>>>    header-y += can.h
>>>    header-y += capability.h
>>> diff --git a/include/uapi/linux/bt-bmc.h b/include/uapi/linux/bt-bmc.h
>>> new file mode 100644
>>> index 000000000000..d9ec766a63d0
>>> --- /dev/null
>>> +++ b/include/uapi/linux/bt-bmc.h
>>> @@ -0,0 +1,18 @@
>>> +/*
>>> + * Copyright (c) 2015-2016, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version
>>> + * 2 of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +#ifndef _UAPI_LINUX_BT_BMC_H
>>> +#define _UAPI_LINUX_BT_BMC_H
>>> +
>>> +#include <linux/ioctl.h>
>>> +
>>> +#define __BT_BMC_IOCTL_MAGIC    0xb1
>>> +#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)
>>> +
>>> +#endif /* _UAPI_LINUX_BT_BMC_H */
>>

^ permalink raw reply

* [PATCH] ARM: mvebu: Select corediv clk for all mvebu v7 SoC
From: Uwe Kleine-König @ 2016-09-19 13:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919115207.19334-1-gregory.clement@free-electrons.com>

On Mon, Sep 19, 2016 at 01:52:07PM +0200, Gregory CLEMENT wrote:
> Since the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
> Armada XP"), the corediv clk is no more selected for Armada XP, however
> this clock is used for Armada XP using the compatible
> armada-370-corediv-clock.
> 
> More over even if with the commit 1594d568c6e3 ("clk: mvebu: Move corediv
> config to mvebu config"), it was selected for Armada 38x and Armada 375,
> it was still not selected for Armada 39x.

Instead of the above paragraph I'd write:

	While since commit 1594d568c6e3 ("clk: mvebu: Move corediv
	config to mvebu config") Armada 38x and Armada 375 got corediv
	support again, not only Armada XP was missed but also Armada
	39x.

> Actually all the SoC selecting MVEBU_V7 config need this clock:
> git grep "\-corediv-clock" arch/arm/boot/dts
> arch/arm/boot/dts/armada-370-xp.dtsi: compatible = "marvell,armada-370-corediv-clock";
> arch/arm/boot/dts/armada-375.dtsi:    compatible = "marvell,armada-375-corediv-clock";
> arch/arm/boot/dts/armada-38x.dtsi:    compatible = "marvell,armada-380-corediv-clock";
> arch/arm/boot/dts/armada-39x.dtsi:    compatible = "marvell,armada-390-corediv-clock"
> 
> This commit now fixes this behavior.

... by letting MVEBU_V7 select MVEBU_CLK_COREDIV.

> Fixes: bd3677ff31a3 ("clk: mvebu: Remove corediv clock from Armada XP")
> Cc: stable at vger.kernel.org
> Reported-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

BTW, I considered doing this, too, but failed to see that 39x is
missing, too, and so thought this to be wrong.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [RESEND PATCH v4] thermal: tango: add resume support
From: Marc Gonzalez @ 2016-09-19 13:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474163885.3425.0.camel@intel.com>

On 18/09/2016 03:58, Zhang Rui wrote:

> On 2016-09-14 at 17:35 +0200, Marc Gonzalez wrote:
>
>> Hello Rui, Eduardo,
>>
>> The present patch has been reviewed by both Kevin Hilman and Arnd Bergmann,
>> two arm-soc maintainers. Can you pick it up in time for inclusion in v4.9?
> 
> It has already been in thermal -release branch for a while, and queued
> for 4.9.

Sorry, I was expecting an ACK on the list. It never occurred to me
to check your tree. Thanks for taking the patch.

https://git.kernel.org/cgit/linux/kernel/git/rzhang/linux.git/commit/?h=release&id=186e2aa3954c3201583e5ec3149faa6caa67d2b9

Regards.

^ permalink raw reply

* [PATCH] arm64: Add BCM2835 (Raspberry Pi 3) support to the defconfig
From: Eric Anholt @ 2016-09-19 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Most of the drivers are included as modules, except for serial (needed
for early console), WDT (required for reboot), and the dependency
chain of RASPBERRYPI_POWER (which is currently not buildable as a
module, but should be changed).

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm64/configs/defconfig | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fb8d84516e92..9748c4735a60 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -34,6 +34,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
+CONFIG_ARCH_BCM2835=y
 CONFIG_ARCH_BCM_IPROC=y
 CONFIG_ARCH_BERLIN=y
 CONFIG_ARCH_EXYNOS=y
@@ -193,6 +194,7 @@ CONFIG_USB_NET_SMSC75XX=m
 CONFIG_USB_NET_SMSC95XX=m
 CONFIG_USB_NET_PLUSB=m
 CONFIG_USB_NET_MCS7830=m
+CONFIG_BRCMFMAC=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
 CONFIG_INPUT_EVDEV=y
@@ -205,6 +207,9 @@ CONFIG_SERIO_AMBAKMI=y
 CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_8250_UNIPHIER=y
@@ -228,6 +233,7 @@ CONFIG_VIRTIO_CONSOLE=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_BCM2835=m
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_IMX=y
 CONFIG_I2C_MESON=y
@@ -238,6 +244,8 @@ CONFIG_I2C_UNIPHIER_F=y
 CONFIG_I2C_RCAR=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SPI=y
+CONFIG_SPI_BCM2835=m
+CONFIG_SPI_BCM2835AUX=m
 CONFIG_SPI_MESON_SPIFC=m
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
@@ -272,6 +280,7 @@ CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_BCM2835_WDT=y
 CONFIG_RENESAS_WDT=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_MESON_GXBB_WATCHDOG=m
@@ -294,6 +303,7 @@ CONFIG_REGULATOR_S2MPS11=y
 CONFIG_DRM=m
 CONFIG_DRM_NOUVEAU=m
 CONFIG_DRM_TEGRA=m
+CONFIG_DRM_VC4=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_HISI_KIRIN=m
@@ -308,6 +318,7 @@ CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
+CONFIG_SND_BCM2835_SOC_I2S=m
 CONFIG_SND_SOC_RCAR=y
 CONFIG_SND_SOC_SAMSUNG=y
 CONFIG_SND_SOC_AK4613=y
@@ -372,6 +383,7 @@ CONFIG_RTC_DRV_XGENE=y
 CONFIG_RTC_DRV_S3C=y
 CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
+CONFIG_DMA_BCM2835=m
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_QCOM_HIDMA_MGMT=y
@@ -394,8 +406,10 @@ CONFIG_MSM_MMCC_8996=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_MAILBOX=y
 CONFIG_ARM_MHU=y
+CONFIG_BCM2835_MBOX=y
 CONFIG_HI6220_MBOX=y
 CONFIG_ARM_SMMU=y
+CONFIG_RASPBERRYPI_POWER=y
 CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
@@ -403,6 +417,7 @@ CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_PWM=y
+CONFIG_PWM_BCM2835=m
 CONFIG_PWM_TEGRA=m
 CONFIG_COMMON_RESET_HI6220=y
 CONFIG_PHY_RCAR_GEN3_USB2=y
@@ -414,6 +429,7 @@ CONFIG_ACPI=y
 CONFIG_IIO=y
 CONFIG_EXYNOS_ADC=y
 CONFIG_PWM_SAMSUNG=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 0/3] Armada 7k/8k CP110 system controller fixes
From: Marcin Wojtas @ 2016-09-19 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473183117-11889-1-git-send-email-mw@semihalf.com>

Hi Stephen,

Did you have any chance to take a look at v2? Do you have any remarks?

Best regards.
Marcin

2016-09-06 19:31 GMT+02:00 Marcin Wojtas <mw@semihalf.com>:
> Hi,
>
> Here is the second version of the patchset adding fixes to CP110
> system controller clock driver. As requested during review,
> an additional patch is submitted, which covers migration of the
> driver to clk_hw registration and API.
>
> Any feedback would be very welcome.
>
> Best regards,
> Marcin
>
> Changelog:
> v1 -> v2
> * replace setting CLK_IS_BASIC flag with clearing init structure fields
>   with memset
> * minor improvements of allocation and error checking
> * add migration to clk_hw
>
> Marcin Wojtas (3):
>   clk: mvebu: fix setting unwanted flags in CP110 gate clock
>   clk: mvebu: dynamically allocate resources in Armada CP110 system
>     controller
>   clk: mvebu: migrate CP110 system controller to clk_hw API and
>     registration
>
>  drivers/clk/mvebu/cp110-system-controller.c | 155 +++++++++++++++-------------
>  1 file changed, 81 insertions(+), 74 deletions(-)
>
> --
> 1.8.3.1
>

^ permalink raw reply

* [PATCH 1/1 v6] ARM: imx: Added perf functionality to mmdc driver
From: Mark Rutland @ 2016-09-19 12:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473864500-24256-1-git-send-email-Frank.Li@nxp.com>

Hi,

This is generally looking good now. There are just a few issues
remaining which I've noted below.

On Wed, Sep 14, 2016 at 09:48:20AM -0500, Frank Li wrote:
> From: Zhengyu Shen <zhengyu.shen@nxp.com>

> +static bool mmdc_pmu_group_is_valid(struct perf_event *event)

As a general note, you prefix other functions with mmdc_ rather than
mmdc_pmu. For consistency, it would be better for all the perf-specific
functions to be called mmdc_pmu_*. Likewise for attr_groups.

> +{
> +	struct pmu *pmu = event->pmu;
> +	struct perf_event *leader = event->group_leader;
> +	struct perf_event *sibling;
> +
> +	int cfg = leader->attr.config;
> +	int counter_mask = 0;
> +
> +	if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
> +		return false;

For any event managed by this PMU, this is checked in event_init, so
this check is unnecessary.

> +
> +	if (leader->pmu == pmu)
> +		counter_mask |= 1 << cfg;
> +	else if (!is_software_event(leader))
> +		return false;
> +
> +	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
> +		if (sibling->pmu == pmu) {
> +			cfg = sibling->attr.config;
> +			if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
> +				return false;

Likewise.

> +			counter_mask |= 1 << cfg;
> +		} else if (!is_software_event(sibling)) {
> +			return false;
> +		}
> +	}
> +
> +	if (event == leader)
> +		return true;
> +
> +	cfg = event->attr.config;
> +	if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
> +		return false;
> +
> +	return !(counter_mask & (1 << cfg));
> +}

I think this would be far clearer if written something like the below:

bool mmdc_pmu_group_event_is_valid(struct perf_event *event,
				   struct pmu *pmu,
				   unsigned long *used_counters)
{
	int counter = event->attr.config;

	if (is_software_event(event))
		return true;
	if (event->pmu != pmu)
		return false;
	return !test_and_set_bit(counter, &used_counters);
}

/*
 * Each event has a single fixed-purpose counter, so we can only have a
 * single active event for each at any point in time. Here we just check
 * for duplicates, and rely on mmdc_pmu_event_init to verify that the HW
 * event numbers are valid.
 */
bool mmdc_pmu_group_is_valid(struct perf_event *event)
{
	struct pmu *pmu = event->pmu;
	struct perf_event *leader = event->group_leader;
	struct perf_event *sibling;
	unigned long used_counters = 0;

	set_bit(counter(event), &used_counters);

	if (event != leader) {
		if (!mmdc_pmu_event_is_valid(event, pmu, &counter_mask))
			return false;
	}

	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
		if (!mmdc_pmu_group_event_is_valid(event, pmu, &used_counters))
			return false;
	}

	return true;
}

> +static int mmdc_event_add(struct perf_event *event, int flags)
> +{
> +	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	int cfg = event->attr.config;
> +
> +	if (WARN_ONCE((cfg < 0 || cfg >= MMDC_NUM_COUNTERS),
> +				"invalid configuration %d for mmdc", cfg))
> +		return -1;

This should never happen, as you checked this at event_init time.

If you must check this here, please use a real error code mnemonic
rather than -1 (which happens to be -EPERM).

> +
> +	if (flags & PERF_EF_START)
> +		mmdc_event_start(event, flags);
> +
> +	pmu_mmdc->mmdc_events[cfg] = event;
> +	pmu_mmdc->active_events++;
> +
> +	local64_set(&hwc->prev_count, mmdc_read_counter(pmu_mmdc, cfg));
> +
> +	return 0;
> +}

You must verify at pmu::add() time that the counter isn't in use
already, as you can have separate events (i.e. that aren't in the same
group) trying to reuse the same counter.

If you don't check that, then stopping/starting/resetting the counter
will not work as expected, and you will get erroneous results.

I think that here all you need to do is to check that check
pmu_mmdc->mmdc_events[cfg] is NULL before you assign to it. If it has a
non-NULL value, return -EAGAIN.

> +
> +static void mmdc_event_stop(struct perf_event *event, int flags)
> +{
> +	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
> +	void __iomem *mmdc_base, *reg;
> +	int cfg = (int)event->attr.config;
> +
> +	mmdc_base = pmu_mmdc->mmdc_base;
> +	reg = mmdc_base + MMDC_MADPCR0;
> +
> +	if (WARN_ONCE((cfg < 0 || cfg >= MMDC_NUM_COUNTERS),
> +				"invalid configuration %d for mmdc counter", cfg))
> +		return;

You checked this at event_init time. Is it really necessary to check
again?

> +static void mmdc_event_del(struct perf_event *event, int flags)
> +{
> +	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
> +	int cfg = event->attr.config;
> +
> +	pmu_mmdc->mmdc_events[cfg] = NULL;
> +	pmu_mmdc->active_events--;
> +
> +	if (pmu_mmdc->active_events <= 0)
> +		hrtimer_cancel(&pmu_mmdc->hrtimer);

You should only have to check that this is equal to zero. If
active_events is negative, you have a bigger problem.

Thanks,
Mark.

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Robin Murphy @ 2016-09-19 12:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919122435.GD9005@arm.com>

On 19/09/16 13:24, Will Deacon wrote:
> On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
>> On 16/09/2016 18:18, Robin Murphy wrote:
>>> What I probably will do, though, since we have the functionality in
>>> place for the sake of the old binding, and I think there are other folks
>>> who want PCI iommu-map support but would prefer not to bother with DMA
>>> ops on the host, is add a command-line option to disable DMA domains
>>> even for the generic bindings.
>>
>> Yes this would be a good thing I think. This series has an important
>> impact on platforms which do not have smmu v3, where contexts are scarce
>> HW resources.
> 
> Rather than disabling DMA domains entirely, we could specify a number
> of contexts to reserve for other use (e.g. VFIO). It's a pity that these
> options are global for the system, as opposed to per SMMU instance,
> but I can't see a good way around that.

The problem with that approach is that due to bus traversal order you'd
typically end up with the even-more-limited number of non-reserved
contexts getting consumed by bridges that are unlikely to ever actually
use their DMA ops, so you end up barely any better off than just not
doing DMA ops at all, which we already have the code for.

And yeah, if you had, say, "arm-smmu.reserved_s2_contexts=4", for the
benefit of your PCI SMMU, what do the SMMUs in front of your other
platform devices with only 2 contexts (and which only want DMA ops) do?

Robin.

> 
> Will
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
> 

^ permalink raw reply

* [PATCH] arm64/efi: efi_init error handling fix
From: Yisheng Xie @ 2016-09-19 12:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160913111804.GG3872@codeblueprint.co.uk>



On 2016/9/13 19:18, Matt Fleming wrote:
> On Wed, 07 Sep, at 07:15:48PM, Yisheng Xie wrote:
>>
>>
>> On 2016/9/5 21:57, Matt Fleming wrote:
>>> On Fri, 02 Sep, at 11:26:18AM, Will Deacon wrote:
>>>> On Fri, Sep 02, 2016 at 06:18:39PM +0800, Xie Yisheng wrote:
>>>>> From: Yisheng Xie <xieyisheng1@huawei.com>
>>>>>
>>>
>>> This should be a call to efi_memmap_unmap() because the EFI_MEMMAP
>>> flag also needs clearing.
>>>
>> Hi Matt,
>> Thanks for your reply.
>> You mean call the function efi_unmap_memmap() like x86?
>>
>> however, it seems no need to clear EFI_MEMMAP here. For arm*, the flag
>> EFI_MEMMAP is set in function reserve_regions(), which is called
>> only when uefi_init() return 0:
>>
>> efi_init()
>>    -> reserve_regions()
>>        -> set_bit(EFI_MEMMAP, &efi.flags);
> 
> This patch should be against the 'next' branch here,
> 
>   https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/log/?h=next
> 
> My comments were made with that branch in mind.
> 
Hi Matt,
Sorry for my misunderstanding, I will try to rebase to next branch.

Thanks.
Yisheng Xie.

> .
> 

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Will Deacon @ 2016-09-19 12:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <48f3bc10-3966-7d50-d070-7ec7f0946c92@redhat.com>

On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
> On 16/09/2016 18:18, Robin Murphy wrote:
> > What I probably will do, though, since we have the functionality in
> > place for the sake of the old binding, and I think there are other folks
> > who want PCI iommu-map support but would prefer not to bother with DMA
> > ops on the host, is add a command-line option to disable DMA domains
> > even for the generic bindings.
> 
> Yes this would be a good thing I think. This series has an important
> impact on platforms which do not have smmu v3, where contexts are scarce
> HW resources.

Rather than disabling DMA domains entirely, we could specify a number
of contexts to reserve for other use (e.g. VFIO). It's a pity that these
options are global for the system, as opposed to per SMMU instance,
but I can't see a good way around that.

Will

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Auger Eric @ 2016-09-19 12:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f16db032-1905-9804-0607-fe007af72b0e@arm.com>

Hi Robin,

On 16/09/2016 18:18, Robin Murphy wrote:
> Hi Eric,
> 
> On 15/09/16 17:46, Auger Eric wrote:
> [...]
>> Hum OK; thanks for the explanation. With that implementation however,
>> don't we face back the issue we encountered in early stage of default
>> domain implementation:
>>
>> With this sample config (AMD overdrive + I350-T2 + 2VFs per PF) I fill
>> the 8 context banks. Whereas practically we didn't need them before?
>>
>> 00:00.0 0600: 1022:1a00
>> 	Subsystem: 1022:1a00
>> 00:02.0 0600: 1022:1a01
>> 00:02.2 0604: 1022:1a02
>> 	Kernel driver in use: pcieport
>> 01:00.0 0200: 8086:1521 (rev 01)
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igb
>> 01:00.1 0200: 8086:1521 (rev 01)
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igb
>> 01:10.0 0200: 8086:1520 (rev 01) -> context 5
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: vfio-pci
>> 01:10.1 0200: 8086:1520 (rev 01) -> context 7
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igbvf
>> 01:10.4 0200: 8086:1520 (rev 01) -> context 6
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igbvf
>> 01:10.5 0200: 8086:1520 (rev 01) -> shortage
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igbvf
>>
>> So I can't even do passthrough anymore with that config. Is there
>> anything wrong in my setup/understanding?
> 
> It's kind of hard to avoid, really - people want DMA ops support (try
> plugging a card which can only do 32-bit DMA into that Seattle, for
> instance); DMA ops need default domains; default domains are allocated
> per group; each domain requires a context bank to back it; thus if you
> have 9 groups and 8 context banks you're in a corner. It would relieve
> the pressure to have a single default domain per SMMU, but we've no way
> to do that due to the way the iommu_domain_alloc() API is intended to work.
> 
> Ultimately, it's a hardware limitation of that platform - plug in a card
> with 16 VFs with ACS, and either way you're stuck. There are a number of
> bodges I can think of that would make your specific situation work, but
> none of them are really sufficiently general to consider upstreaming.
> The most logical thing to do right now, if you were happy without DMA
> ops using the old binding before, is to keep using the old binding (just
> fixing your DT with #stream-id-cells=0 on the host controller so as not
> to create the fake aliasing problem). Hopefully future platforms will be
> in a position to couple their PCI host controllers to an IOMMU which is
> actually designed to support a PCI host controller.
> 
> What I probably will do, though, since we have the functionality in
> place for the sake of the old binding, and I think there are other folks
> who want PCI iommu-map support but would prefer not to bother with DMA
> ops on the host, is add a command-line option to disable DMA domains
> even for the generic bindings.

Yes this would be a good thing I think. This series has an important
impact on platforms which do not have smmu v3, where contexts are scarce
HW resources.

Thanks

Eric

> 
> Robin.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [PATCH] ARM: mvebu: Select corediv clk for all mvebu v7 SoC
From: Gregory CLEMENT @ 2016-09-19 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

Since the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
Armada XP"), the corediv clk is no more selected for Armada XP, however
this clock is used for Armada XP using the compatible
armada-370-corediv-clock.

More over even if with the commit 1594d568c6e3 ("clk: mvebu: Move corediv
config to mvebu config"), it was selected for Armada 38x and Armada 375,
it was still not selected for Armada 39x.

Actually all the SoC selecting MVEBU_V7 config need this clock:
git grep "\-corediv-clock" arch/arm/boot/dts
arch/arm/boot/dts/armada-370-xp.dtsi: compatible = "marvell,armada-370-corediv-clock";
arch/arm/boot/dts/armada-375.dtsi:    compatible = "marvell,armada-375-corediv-clock";
arch/arm/boot/dts/armada-38x.dtsi:    compatible = "marvell,armada-380-corediv-clock";
arch/arm/boot/dts/armada-39x.dtsi:    compatible = "marvell,armada-390-corediv-clock"

This commit now fixes this behavior.

Fixes: bd3677ff31a3 ("clk: mvebu: Remove corediv clock from Armada XP")
Cc: stable at vger.kernel.org
Reported-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/Kconfig | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index f9b6bd306cfe..541647f57192 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -23,6 +23,7 @@ config MACH_MVEBU_V7
 	select CACHE_L2X0
 	select ARM_CPU_SUSPEND
 	select MACH_MVEBU_ANY
+	select MVEBU_CLK_COREDIV
 
 config MACH_ARMADA_370
 	bool "Marvell Armada 370 boards"
@@ -32,7 +33,6 @@ config MACH_ARMADA_370
 	select CPU_PJ4B
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_370
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 370 SoC with device tree.
@@ -50,7 +50,6 @@ config MACH_ARMADA_375
 	select HAVE_SMP
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_375
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 375 SoC with device tree.
@@ -68,7 +67,6 @@ config MACH_ARMADA_38X
 	select HAVE_SMP
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_38X
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 380/385 SoC with device tree.
-- 
2.9.3

^ permalink raw reply related

* [PATCH] ARM: mvebu: let Armada XP also select corediv clk
From: Gregory CLEMENT @ 2016-09-19 11:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474276961-4645-1-git-send-email-u.kleine-koenig@pengutronix.de>

Hi Uwe,
 
 On lun., sept. 19 2016, Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de> wrote:

> An Armada XP there is also a marvell,armada-370-corediv-clock
> compatible device that is needed to make the nand device work.

Indeed when I acked the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
Armada XP") I missed that the armada-370-corediv-clock compatible sting
was for Armada 370 and Armada XP. We didn't see it until now because I
used the mvebu_v7_defconfig (or the multi_v7_defconfig) where all the
mvebu SoC are enabled.

But the Armada 39x also need it and actually all the SoC selecting
MVEBU_V7 config need this clock.

So I am sending a patch to fix it and it will part of the pull request
to arm-soc for the fix this week.

Thanks,

Gregory

>
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
> ---
>  arch/arm/mach-mvebu/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
> index f9b6bd306cfe..2979a9c454f6 100644
> --- a/arch/arm/mach-mvebu/Kconfig
> +++ b/arch/arm/mach-mvebu/Kconfig
> @@ -97,6 +97,7 @@ config MACH_ARMADA_XP
>  	select CPU_PJ4B
>  	select MACH_MVEBU_V7
>  	select PINCTRL_ARMADA_XP
> +	select MVEBU_CLK_COREDIV
>  	help
>  	  Say 'Y' here if you want your kernel to support boards based
>  	  on the Marvell Armada XP SoC with device tree.
> -- 
> 2.8.1
>

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH v3 0/2] KVM: ARM: Enable vtimers with user space gic
From: Alexander Graf @ 2016-09-19 11:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919075217.nlxdmoicjhmc2hy6@kamzik.localdomain>



On 19.09.16 09:52, Andrew Jones wrote:
> On Fri, Sep 16, 2016 at 09:36:42PM +0200, Alexander Graf wrote:
>>
>>
>>> Am 16.09.2016 um 15:46 schrieb Andrew Jones <drjones@redhat.com>:
>>>
>>>> On Fri, Sep 16, 2016 at 03:30:27PM +0200, Christoffer Dall wrote:
>>>>> On Fri, Sep 16, 2016 at 02:31:42PM +0200, Paolo Bonzini wrote:
>>>>>
>>>>>
>>>>> On 16/09/2016 14:30, Christoffer Dall wrote:
>>>>>>>>> This patch set allows user space to receive vtimer events as well as mask
>>>>>>>>> them, so that we can handle all vtimer related interrupt injection from user
>>>>>>>>> space, enabling us to use architected timer with user space gic emulation.
>>>>>>>>
>>>>>>>> I have already voiced my concerns in the past, including face to face,
>>>>>>>> and I'm going to repeat it: I not keen at all on adding a new userspace
>>>>>>>> interface that is going to bitrot extremely quickly.
>>>>>>>
>>>>>>> You don't have automated tests set up?  It's not going to bitrot if you
>>>>>>> test it, either with kvm-unit-tests or just by smoke-testing Linux.
>>>>>>> It's _for_ the raspi, but it's not limited to it.
>>>>>>
>>>>>> Our automated testing situation is not great, no.  Something we're
>>>>>> looking at, but have resource problems with.
>>>>>
>>>>> But it's not a good reason to hold back a feature...
>>>>
>>>> I didn't say that exactly, but choosing not to merge something we cannot
>>>> maintain and which we're not paid to look after and where there's a
>>>> minimal interest, is not entirely unreasonable.
>>>>
>>>> That being said, I'm not categorically against these patches, but I
>>>> share Marc's view that we've already seen that non-vgic support had been
>>>> broken for multiple versions without anyone complaining, and without
>>>> automated testing or substantial interest in the work, the patches
>>>> really are likely to bit-rot.
>>>>
>>>> But I haven't even looked at the patches in detail, I was just replying
>>>> to the comment about testing.
>>>
>>> This may be a great time to start encouraging feature writers to submit
>>> kvm-unit-tests patches at the same time as the feature (Hi Alex :-)
>>
>> I actually started off implementing this with the help of kvm-unit-tests. It's awesome!
>>
>> I'm lacking actual irq support to make the test reasonable though and wanted to get the kernel bits out first :). But I'll sit down on that again soon I hope.
> 
> I'm glad it looks like a good base for you. I need to get this series
> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/gic refreshed and
> merged, and also it's time to start looking into adding interrupt
> injection to chr-testdev. With those in place I hope it'll be an even
> better base for you.

Awesome. Let me know when you're further ahead with the gic work then so
that we can actually trigger interrupts and measure irq latencies :).

Until then, I sent the simplistic version that I used for bringup to the
list.


Alex

^ permalink raw reply

* [PATCH] ARM: dts: sun8i: Add accelerometer to polaroid-mid2407pxe03
From: Maxime Ripard @ 2016-09-19 11:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919103925.25149-1-hdegoede@redhat.com>

On Mon, Sep 19, 2016 at 12:39:25PM +0200, Hans de Goede wrote:
> Add a dt node describing the mma7660 accelerometer on the
> polaroid-mid2407pxe03 tablet.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Applied, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160919/3a0aef41/attachment.sig>

^ permalink raw reply

* [PATCH v3 0/2] KVM: ARM: Enable vtimers with user space gic
From: Christoffer Dall @ 2016-09-19 11:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <43020f1f-6367-6f11-2534-b26ced13b540@suse.de>

On Mon, Sep 19, 2016 at 12:51:46PM +0200, Alexander Graf wrote:
> 
> 
> On 16.09.16 15:30, Christoffer Dall wrote:

[...]

> > 
> > That being said, I'm not categorically against these patches, but I
> > share Marc's view that we've already seen that non-vgic support had been
> > broken for multiple versions without anyone complaining, and without
> > automated testing or substantial interest in the work, the patches
> > really are likely to bit-rot.
> 
> I know that it's very hard to grasp from an upstream maintainer
> perspective, 

pfff

> but keep in mind where the bulk of execution of kernel code
> lies. The average life cycle of a "stable" Linux distribution's kernel
> is a few years.
> 
> So far all regressions in the user space gic code have been found within
> less than 1y of the respective code release. I'd say that counts for
> quite a well used feature.
> 

The only report I can think of about this was Pavel using an upstream
kernel for in-house Samsung development on non-public hardware.

But, again, I didn't look at the patches in detail yet, I'm not
categorically against them, I will take a careful look at them like I do
with all patches on the kvmarm list.  There's a risk they'll break in
mainline unless we sort out our testing story, and it may just be
something we'll have to live with.

> > But I haven't even looked at the patches in detail, I was just replying
> > to the comment about testing.
> 
> Also keep in mind that without the architected timer support (and/or
> without qemu patches than enable user space timers) the user space gic
> support is pretty unusable to most people, so you obviously get less
> reports.
>

I don't disagree with this.  I don't know what this has to do with the
part of my mail you're replying to, but I completely agree that the
current userspace irqchip support has limited value.

-Christoffer

^ permalink raw reply

* next-20160914 build: 2 failures 3 warnings (next-20160914)
From: Arnd Bergmann @ 2016-09-19 11:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919105429.GK10189@sirena.org.uk>

On Monday, September 19, 2016 11:54:29 AM CEST Mark Brown wrote:
> On Mon, Sep 19, 2016 at 12:31:04PM +0200, Arnd Bergmann wrote:
> 
> > My guess is that this is indeed the correct fix, but I don't understand
> > at all what the function does, and Marcin Niestroj said the same thing,
> > he just copied the code from a driver that is always built-in.
> 
> Yes, most of the code is copied from regmap-irq.  Setting the parent is
> needed for edge triggered interrupts that don't latch state when
> disabled but isn't needed in the general case.

I found this in the tps65217 data sheet:

 9.3.7 Interrupt Pin (nINT)
 The interrupt pin is used to signal any event or fault
 condition to the host processor. Whenever a fault or event
 occurs in the IC the corresponding interrupt bit is set in
 the INT register, and the open-drain output is pulled low.
 The nINT pin is released (returns to Hi-Z state) and fault
 bits are cleared when the INT register is read by the
 host. However, if a failure persists, the corresponding
 INT bit remains set and the nINT pin is pulled low again
 after a maximum of 32 ?s.

 Interrupt events include pushbutton pressed/released, USB
 and AC voltage status change.
 The MASK bits in the INT register are used to mask events
 from generating interrupts. The MASK settings affect the
 nINT pin only and have no impact on protection and
 monitor circuits themselves. Note that persisting event
 conditions such as ISINK enabled shutdown can cause the
 nINT pin to be pulled low for an extended period of
 time which can keep the host in a loop trying to resolve
 the interrupt. If this behavior is not desired, set the
 corresponding mask bit after receiving the interrupt and
 keep polling the INT register to see when the event
 condition has disappeared. Then unmask the interrupt bit
 again.

Does this tell us if it's needed or not?

	Arnd

^ permalink raw reply

* [PATCH v4 2/2] KVM: arm/arm64: Route vtimer events to user space
From: Alexander Graf @ 2016-09-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474283695-212421-1-git-send-email-agraf@suse.de>

We have 2 modes for dealing with interrupts in the ARM world. We can either
handle them all using hardware acceleration through the vgic or we can emulate
a gic in user space and only drive CPU IRQ pins from there.

Unfortunately, when driving IRQs from user space, we never tell user space
about timer events that may result in interrupt line state changes, so we
lose out on timer events if we run with user space gic emulation.

This patch fixes that by routing vtimer expiration events to user space.
With this patch I can successfully run edk2 and Linux with user space gic
emulation.

Signed-off-by: Alexander Graf <agraf@suse.de>

---

v1 -> v2:

  - Add back curly brace that got lost

v2 -> v3:

  - Split into patch set

v3 -> v4:

  - Improve documentation
---
 Documentation/virtual/kvm/api.txt |  30 ++++++++-
 arch/arm/include/asm/kvm_host.h   |   3 +
 arch/arm/kvm/arm.c                |  22 ++++---
 arch/arm64/include/asm/kvm_host.h |   3 +
 include/uapi/linux/kvm.h          |  14 +++++
 virt/kvm/arm/arch_timer.c         | 125 +++++++++++++++++++++++++++-----------
 6 files changed, 155 insertions(+), 42 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 23937e0..1c0bd86 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3202,9 +3202,14 @@ struct kvm_run {
 	/* in */
 	__u8 request_interrupt_window;
 
-Request that KVM_RUN return when it becomes possible to inject external
+[x86] Request that KVM_RUN return when it becomes possible to inject external
 interrupts into the guest.  Useful in conjunction with KVM_INTERRUPT.
 
+[arm*] Bits set to 1 in here mask IRQ lines that would otherwise potentially
+trigger forever. These lines are available:
+
+    KVM_IRQWINDOW_VTIMER  -  Masks hw virtual timer irq while in guest
+
 	__u8 padding1[7];
 
 	/* out */
@@ -3519,6 +3524,18 @@ Hyper-V SynIC state change. Notification is used to remap SynIC
 event/message pages and to enable/disable SynIC messages/events processing
 in userspace.
 
+		/* KVM_EXIT_ARM_TIMER */
+		struct {
+			__u8 timesource;
+		} arm_timer;
+
+Indicates that a timer triggered that user space needs to handle and
+potentially mask with vcpu->run->request_interrupt_window to allow the
+guest to proceed. This only happens for timers that got enabled through
+KVM_CAP_ARM_TIMER. The following time sources are available:
+
+    KVM_ARM_TIMER_VTIMER  - virtual cpu timer
+
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -3739,6 +3756,17 @@ Once this is done the KVM_REG_MIPS_VEC_* and KVM_REG_MIPS_MSA_* registers can be
 accessed, and the Config5.MSAEn bit is accessible via the KVM API and also from
 the guest.
 
+6.11 KVM_CAP_ARM_TIMER
+
+Architectures: arm, arm64
+Target: vcpu
+Parameters: args[0] contains a bitmap of timers to select (see 5.)
+
+This capability allows to route per-core timers into user space. When it's
+enabled and no in-kernel interrupt controller is in use, the timers selected
+by args[0] trigger KVM_EXIT_ARM_TIMER guest exits when they are pending,
+unless masked by vcpu->run->request_interrupt_window (see 5.).
+
 7. Capabilities that can be enabled on VMs
 ------------------------------------------
 
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index de338d9..77d1f73 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -180,6 +180,9 @@ struct kvm_vcpu_arch {
 
 	/* Detect first run of a vcpu */
 	bool has_run_once;
+
+	/* User space wants timer notifications */
+	bool user_space_arm_timers;
 };
 
 struct kvm_vm_stat {
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index c84b6ad..57bdb71 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -187,6 +187,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_PSCI_0_2:
 	case KVM_CAP_READONLY_MEM:
 	case KVM_CAP_MP_STATE:
+	case KVM_CAP_ARM_TIMER:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -474,13 +475,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 			return ret;
 	}
 
-	/*
-	 * Enable the arch timers only if we have an in-kernel VGIC
-	 * and it has been properly initialized, since we cannot handle
-	 * interrupts from the virtual timer with a userspace gic.
-	 */
-	if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
-		ret = kvm_timer_enable(vcpu);
+	ret = kvm_timer_enable(vcpu);
 
 	return ret;
 }
@@ -601,6 +596,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 			run->exit_reason = KVM_EXIT_INTR;
 		}
 
+		if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu)) {
+			/* Tell user space about the pending vtimer */
+			ret = 0;
+			run->exit_reason = KVM_EXIT_ARM_TIMER;
+			run->arm_timer.timesource = KVM_ARM_TIMER_VTIMER;
+		}
+
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
 			vcpu->arch.power_off || vcpu->arch.pause) {
 			local_irq_enable();
@@ -887,6 +889,12 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 		return -EINVAL;
 
 	switch (cap->cap) {
+	case KVM_CAP_ARM_TIMER:
+		r = 0;
+		if (cap->args[0] != KVM_ARM_TIMER_VTIMER)
+			return -EINVAL;
+		vcpu->arch.user_space_arm_timers = true;
+		break;
 	default:
 		r = -EINVAL;
 		break;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3eda975..3d01481 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -270,6 +270,9 @@ struct kvm_vcpu_arch {
 
 	/* Detect first run of a vcpu */
 	bool has_run_once;
+
+	/* User space wants timer notifications */
+	bool user_space_arm_timers;
 };
 
 #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 300ef25..00f4948 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -205,6 +205,7 @@ struct kvm_hyperv_exit {
 #define KVM_EXIT_S390_STSI        25
 #define KVM_EXIT_IOAPIC_EOI       26
 #define KVM_EXIT_HYPERV           27
+#define KVM_EXIT_ARM_TIMER        28
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -361,6 +362,10 @@ struct kvm_run {
 		} eoi;
 		/* KVM_EXIT_HYPERV */
 		struct kvm_hyperv_exit hyperv;
+		/* KVM_EXIT_ARM_TIMER */
+		struct {
+			__u8 timesource;
+		} arm_timer;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -870,6 +875,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_S390_USER_INSTR0 130
 #define KVM_CAP_MSI_DEVID 131
 #define KVM_CAP_PPC_HTM 132
+#define KVM_CAP_ARM_TIMER 133
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1327,4 +1333,12 @@ struct kvm_assigned_msix_entry {
 #define KVM_X2APIC_API_USE_32BIT_IDS            (1ULL << 0)
 #define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK  (1ULL << 1)
 
+/* Available with KVM_CAP_ARM_TIMER */
+
+/* Bits for run->request_interrupt_window */
+#define KVM_IRQWINDOW_VTIMER		(1 << 0)
+
+/* Bits for run->arm_timer.timesource */
+#define KVM_ARM_TIMER_VTIMER		(1 << 0)
+
 #endif /* __LINUX_KVM_H */
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 4309b60..cbbb50dd 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -170,16 +170,45 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
 {
 	int ret;
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+	struct kvm_run *run = vcpu->run;
 
-	BUG_ON(!vgic_initialized(vcpu->kvm));
+	BUG_ON(irqchip_in_kernel(vcpu->kvm) && !vgic_initialized(vcpu->kvm));
 
 	timer->active_cleared_last = false;
 	timer->irq.level = new_level;
-	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->irq.irq,
+	trace_kvm_timer_update_irq(vcpu->vcpu_id, host_vtimer_irq,
 				   timer->irq.level);
-	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
-					 timer->irq.irq,
-					 timer->irq.level);
+
+	if (irqchip_in_kernel(vcpu->kvm) && vgic_initialized(vcpu->kvm)) {
+		/* Fire the timer in the VGIC */
+
+		ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
+						 timer->irq.irq,
+						 timer->irq.level);
+	} else if (!vcpu->arch.user_space_arm_timers) {
+		/* User space has not activated timer use */
+		ret = 0;
+	} else {
+		/*
+		 * Set PENDING_TIMER so that user space can handle the event if
+		 *
+		 *   1) Level is high
+		 *   2) The vtimer is not suppressed by user space
+		 *   3) We are not in the timer trigger exit path
+		 */
+		if (new_level &&
+		    !(run->request_interrupt_window & KVM_IRQWINDOW_VTIMER) &&
+		    (run->exit_reason != KVM_EXIT_ARM_TIMER)) {
+			/* KVM_REQ_PENDING_TIMER means vtimer triggered */
+			kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
+		}
+
+		/* Force a new level high check on next entry */
+		timer->irq.level = 0;
+
+		ret = 0;
+	}
+
 	WARN_ON(ret);
 }
 
@@ -197,7 +226,8 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
 	 * because the guest would never see the interrupt.  Instead wait
 	 * until we call this function from kvm_timer_flush_hwstate.
 	 */
-	if (!vgic_initialized(vcpu->kvm) || !timer->enabled)
+	if ((irqchip_in_kernel(vcpu->kvm) && !vgic_initialized(vcpu->kvm)) ||
+	    !timer->enabled)
 		return -ENODEV;
 
 	if (kvm_timer_should_fire(vcpu) != timer->irq.level)
@@ -275,35 +305,57 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
 	* to ensure that hardware interrupts from the timer triggers a guest
 	* exit.
 	*/
-	phys_active = timer->irq.level ||
-			kvm_vgic_map_is_active(vcpu, timer->irq.irq);
-
-	/*
-	 * We want to avoid hitting the (re)distributor as much as
-	 * possible, as this is a potentially expensive MMIO access
-	 * (not to mention locks in the irq layer), and a solution for
-	 * this is to cache the "active" state in memory.
-	 *
-	 * Things to consider: we cannot cache an "active set" state,
-	 * because the HW can change this behind our back (it becomes
-	 * "clear" in the HW). We must then restrict the caching to
-	 * the "clear" state.
-	 *
-	 * The cache is invalidated on:
-	 * - vcpu put, indicating that the HW cannot be trusted to be
-	 *   in a sane state on the next vcpu load,
-	 * - any change in the interrupt state
-	 *
-	 * Usage conditions:
-	 * - cached value is "active clear"
-	 * - value to be programmed is "active clear"
-	 */
-	if (timer->active_cleared_last && !phys_active)
-		return;
+	if (irqchip_in_kernel(vcpu->kvm) && vgic_initialized(vcpu->kvm)) {
+		phys_active = timer->irq.level ||
+				kvm_vgic_map_is_active(vcpu, timer->irq.irq);
+
+		/*
+		 * We want to avoid hitting the (re)distributor as much as
+		 * possible, as this is a potentially expensive MMIO access
+		 * (not to mention locks in the irq layer), and a solution for
+		 * this is to cache the "active" state in memory.
+		 *
+		 * Things to consider: we cannot cache an "active set" state,
+		 * because the HW can change this behind our back (it becomes
+		 * "clear" in the HW). We must then restrict the caching to
+		 * the "clear" state.
+		 *
+		 * The cache is invalidated on:
+		 * - vcpu put, indicating that the HW cannot be trusted to be
+		 *   in a sane state on the next vcpu load,
+		 * - any change in the interrupt state
+		 *
+		 * Usage conditions:
+		 * - cached value is "active clear"
+		 * - value to be programmed is "active clear"
+		 */
+		if (timer->active_cleared_last && !phys_active)
+			return;
+
+		ret = irq_set_irqchip_state(host_vtimer_irq,
+					    IRQCHIP_STATE_ACTIVE,
+					    phys_active);
+	} else {
+		/* User space tells us whether the timer is in active mode */
+		phys_active = vcpu->run->request_interrupt_window &
+			      KVM_IRQWINDOW_VTIMER;
+
+		/* However if the line is high, we exit anyway, so we want
+		 * to keep the IRQ masked */
+		phys_active = phys_active || timer->irq.level;
+
+		/*
+		 * So we can just explicitly mask or unmask the IRQ, gaining
+		 * more compatibility with oddball irq controllers.
+		 */
+		if (phys_active)
+			disable_percpu_irq(host_vtimer_irq);
+		else
+			enable_percpu_irq(host_vtimer_irq, 0);
+
+		ret = 0;
+	}
 
-	ret = irq_set_irqchip_state(host_vtimer_irq,
-				    IRQCHIP_STATE_ACTIVE,
-				    phys_active);
 	WARN_ON(ret);
 
 	timer->active_cleared_last = !phys_active;
@@ -479,6 +531,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
 	if (timer->enabled)
 		return 0;
 
+	/* No need to route physical IRQs when we don't use the vgic */
+	if (!irqchip_in_kernel(vcpu->kvm))
+		goto no_vgic;
+
 	/*
 	 * Find the physical IRQ number corresponding to the host_vtimer_irq
 	 */
@@ -502,6 +558,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
 	if (ret)
 		return ret;
 
+no_vgic:
 
 	/*
 	 * There is a potential race here between VCPUs starting for the first
-- 
1.8.5.6

^ permalink raw reply related

* [PATCH v4 1/2] KVM: arm/arm64: Add vcpu ENABLE_CAP functionality
From: Alexander Graf @ 2016-09-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474283695-212421-1-git-send-email-agraf@suse.de>

In a follow-up patch we will need to enable capabilities on demand for
backwards compatibility. This patch adds the generic framework to handle
vcpu cap enablement to the arm code base.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Documentation/virtual/kvm/api.txt |  4 +++-
 arch/arm/kvm/arm.c                | 25 +++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 739db9a..23937e0 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -997,7 +997,9 @@ documentation when it pops into existence).
 
 Capability: KVM_CAP_ENABLE_CAP, KVM_CAP_ENABLE_CAP_VM
 Architectures: x86 (only KVM_CAP_ENABLE_CAP_VM),
-	       mips (only KVM_CAP_ENABLE_CAP), ppc, s390
+	       mips (only KVM_CAP_ENABLE_CAP), ppc, s390,
+	       arm (only KVM_CAP_ENABLE_CAP),
+	       arm64 (only KVM_CAP_ENABLE_CAP)
 Type: vcpu ioctl, vm ioctl (with KVM_CAP_ENABLE_CAP_VM)
 Parameters: struct kvm_enable_cap (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 75f130e..c84b6ad 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -878,6 +878,23 @@ static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu,
 	return ret;
 }
 
+static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
+				     struct kvm_enable_cap *cap)
+{
+	int r;
+
+	if (cap->flags)
+		return -EINVAL;
+
+	switch (cap->cap) {
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg)
 {
@@ -941,6 +958,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 			return -EFAULT;
 		return kvm_arm_vcpu_has_attr(vcpu, &attr);
 	}
+	case KVM_ENABLE_CAP:
+	{
+		struct kvm_enable_cap cap;
+
+		if (copy_from_user(&cap, argp, sizeof(cap)))
+			return -EFAULT;
+		return kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
+	}
 	default:
 		return -EINVAL;
 	}
-- 
1.8.5.6

^ permalink raw reply related

* [PATCH v4 0/2] KVM: ARM: Enable vtimers with user space gic
From: Alexander Graf @ 2016-09-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel

Some systems out there (well, one type in particular - the Raspberry Pi series)
do have virtualization capabilities in the core, but no ARM GIC interrupt
controller.

To run on these systems, the cleanest route is to just handle all
interrupt delivery in user space and only deal with IRQ pins in the core
side in KVM.

This works pretty well already, but breaks when the guest starts to use
architected timers, as these are handled straight inside kernel space today.

This patch set allows user space to receive vtimer events as well as mask
them, so that we can handle all vtimer related interrupt injection from user
space, enabling us to use architected timer with user space gic emulation.

I have successfully run edk2 as well as Linux using these patches on a
Raspberry Pi 3 system with acceptable speed.

A branch with WIP QEMU code can be found here:

  https://github.com/agraf/qemu.git no-kvm-irqchip

To use the user space irqchip, just run it with

  $ qemu-system-aarch64 -M virt ...

if you're on a non-vgic host system. Or -M virt,kernel-irqchip=off if your
host system has vgic support.

v1 -> v2:

  - Add back curly brace that got lost

v2 -> v3:

  - Fix "only only" in documentation
  - Split patches
  - Remove kvm_emulate.h include

v3 -> v4:

  - Improve documentation

Alexander Graf (2):
  KVM: arm/arm64: Add vcpu ENABLE_CAP functionality
  KVM: arm/arm64: Route vtimer events to user space

 Documentation/virtual/kvm/api.txt |  34 ++++++++++-
 arch/arm/include/asm/kvm_host.h   |   3 +
 arch/arm/kvm/arm.c                |  47 +++++++++++---
 arch/arm64/include/asm/kvm_host.h |   3 +
 include/uapi/linux/kvm.h          |  14 +++++
 virt/kvm/arm/arch_timer.c         | 125 +++++++++++++++++++++++++++-----------
 6 files changed, 183 insertions(+), 43 deletions(-)

-- 
1.8.5.6

^ permalink raw reply

* [PATCH v7 0/8] CPUs capacity information for heterogeneous systems
From: Juri Lelli @ 2016-09-19 11:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160912072424.GL10409@e106622-lin>

Hi,

On 12/09/16 08:24, Juri Lelli wrote:
> Hi,
> 
> this is a ping for people interested in this series. Patches 2,4,7-8
> still needs ACKs.
> 

Weekly ping. :-)

Best,

- Juri

> I know it's only been a week since I posted v7, but this series would
> pair nicely with asym cpu capacity support bits already sitting in
> tip/sched/core. I also know that it might be already late for 4.9 merge
> window; nevertheless, still hoping we can make it.
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox