Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL 2/2] arm64 dts: exynos: Last round for v4.12
From: Krzysztof Kozlowski @ 2017-04-27 19:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a1HA6cio=hboc7=BYwJn-i6RzCP1uzcCVvcQwt4wtB3Tw@mail.gmail.com>

On Thu, Apr 27, 2017 at 09:46:03PM +0200, Arnd Bergmann wrote:
> On Fri, Apr 21, 2017 at 6:40 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> > The following changes since commit e3c07546747cdec07ff15c984bc6cebc9c9f788c:
> >
> >   arm64: dts: exynos: Add the burst and esc clock frequency properties to DSI node (2017-03-08 08:55:39 +0200)
> >
> > are available in the git repository at:
> >
> >   git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-4.12-2
> >
> > for you to fetch changes up to 5dccc9873c4af60f4478b3ef54267353f25cc301:
> >
> >   arm64: dts: exynos: Use - instead of @ for DT OPP entries (2017-04-20 18:10:05 +0200)
> >
> > ----------------------------------------------------------------
> > Second update of  Samsung DeviceTree ARM64 for v4.12:
> >  - Fix DTC warnings in Exynos ARM64 Device Tree sources.
> >  - Add panel node to TM2E board.
> >
> > ----------------------------------------------------------------
> > Hoegeun Kwon (1):
> >       arm64: dts: exynos: Add support for s6e3hf2 panel device on TM2e board
> >
> > Viresh Kumar (1):
> >       arm64: dts: exynos: Use - instead of @ for DT OPP entries
> >
> >  arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi | 48 ++++++++++++-------------
> >  arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 11 ++++++
> >  arch/arm64/boot/dts/exynos/exynos5433.dtsi     | 50 +++++++++++++-------------
> >  3 files changed, 60 insertions(+), 49 deletions(-)
> 
> I pulled the updated version into next/dt64, thanks,

Thanks! Do not forget also about next/dt (this wasn't updated so just
tags/samsung-dt-4.12-2).

Best regards,
Krzysztof

^ permalink raw reply

* [PATCH] Mangled urls fixed (was... Re: linux-next: manual merge of the pm tree with the arm-soc tree)
From: Arnd Bergmann @ 2017-04-27 19:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <664dcaaf-3eee-3292-9489-912baf5c393d@oracle.com>

On Mon, Apr 24, 2017 at 11:28 PM, santosh.shilimkar at oracle.com
<santosh.shilimkar@oracle.com> wrote:
> On 4/21/17 2:44 PM, Arnd Bergmann wrote:
>>
>> On Fri, Apr 21, 2017 at 11:02 PM, santosh.shilimkar at oracle.com
>
>
> [...]
>
>> Ok, good, thanks for checking! They are however the commits that
>> contain the silly https://urldefense.proofpoint.com URLs. Can you
>> send a follow-up patch to fix these and use the regular
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__www.ti.org&d=DwIBaQ&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY&m=vFHOEb7p2FxbH00YRQq4WnRiu2BKHADn0gl6e6DoNFQ&s=7mfiIp2Ywy9_ppWKjEGlrswiKRndv8_I7zGVF9uyT0w&e=
>> URL that is in linux-next?
>>
> If not late can you please apply the top patch from below head
> which fixes the mangled urls. Let me know if you want me to
> create tag for the same.
>
> git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
> for_4.12/soc-pmdomain-p2

I pulled the fix into next/drivers. The timing is not a problem, but I would
have preferred a signed tag. Not a big issue here since it's a very obvious
fix and there is reason to doubt its authenticity.

     Arnd

^ permalink raw reply

* [GIT PULL 1/2] ARM: dts: exynos: Last round for v4.12
From: Arnd Bergmann @ 2017-04-27 19:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421164050.7404-1-krzk@kernel.org>

On Fri, Apr 21, 2017 at 6:40 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> Hi,
>
> I know it is late so just one fix for v4.12.
> On top of previous pull request.

Pulled into next/dt, thanks

      Arnd

[I had actually pulled it already, but forgot to send out the mail reply and now
saw your reminder, thanks for paying attention!]

^ permalink raw reply

* [PATCH V5 1/4] arm64: dts: Add basic DT to support Spreadtrum's SP9860G
From: Arnd Bergmann @ 2017-04-27 19:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492746440-11071-1-git-send-email-chunyan.zhang@spreadtrum.com>

On Fri, Apr 21, 2017 at 5:47 AM, Chunyan Zhang
<chunyan.zhang@spreadtrum.com> wrote:
> From: Orson Zhai <orson.zhai@spreadtrum.com>
>
> SC9860G is a 8 cores of A53 SoC with 4G LTE support SoC from Spreadtrum.
>
> According to regular hierarchy of sprd dts, whale2.dtsi contains SoC
> peripherals IP nodes, sc9860.dtsi contains stuff related to ARM core stuff
> and sp9860g dts is for the board level.
>
> Signed-off-by: Orson Zhai <orson.zhai@spreadtrum.com>
> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

Applied to next/dt64 now, thanks!

       Arnd

^ permalink raw reply

* [PATCH] IMX: Rearm watchdog after loading value for restart
From: Baruch Siach @ 2017-04-27 19:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170427131434.17085-1-Frederik.juul@3shape.com>

Hi Frederik,

On Thu, Apr 27, 2017 at 03:14:34PM +0200, frederikj at gmail.com wrote:
> When calling the restart function the watchdog is activated and the WDOG
> timeout field is set to 0. This gives a reset time of 500 ms, which is
> consistent with the following delay. However this new time is not loaded
> into the WDOG until the WDOG service routine is run (see IMX6SXRM section
> 70.5.1.1 "Servicing WDOG to reload the counter").
> 
> Not reloading the counter could result in a random delay up to 128 seconds
> before the system restarts, depending on the previous value of the WDOG
> timeout field and when it has last been serviced. That bug is fixed with
> this patch.

Which platform are you using? This code seems to only be used on legacy 
platforms that were not converted to DT. For DT based systems, including all 
i.MX6, the equivalent version is at 
drivers/watchdog/imx2_wdt.c:imx2_wdt_restart().

baruch

> Signed-off-by: Frederik Juul <Frederik.juul@3shape.com>
> 
> --- linux/arch/arm/mach-imx/system.c.orig	2017-04-20 10:41:33.207558297 +0200
> +++ linux/arch/arm/mach-imx/system.c	2017-04-27 14:27:19.225474885 +0200
> @@ -32,6 +32,8 @@
>  #include "common.h"
>  #include "hardware.h"
>  
> +#define IMX_WATCHDOG_SERVICE_REGISTER 2
> +
>  static void __iomem *wdog_base;
>  static struct clk *wdog_clk;
>  static int wcr_enable = (1 << 2);
> @@ -59,6 +61,10 @@ void mxc_restart(enum reboot_mode mode,
>  	imx_writew(wcr_enable, wdog_base);
>  	imx_writew(wcr_enable, wdog_base);
>  
> +	/* Rearm WDOG to load 500ms value */
> +	imx_writew(0x5555, wdog_base+IMX_WATCHDOG_SERVICE_REGISTER);
> +	imx_writew(0xaaaa, wdog_base+IMX_WATCHDOG_SERVICE_REGISTER);
> +
>  	/* wait for reset to assert... */
>  	mdelay(500);

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -

^ permalink raw reply

* [PATCH] arm64: sunxi: always enable reset controller
From: Arnd Bergmann @ 2017-04-27 19:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170420080241.4445eir3nsmrq6fw@lukather>

On Thu, Apr 20, 2017 at 10:02 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Wed, Apr 19, 2017 at 07:35:36PM +0200, Arnd Bergmann wrote:
>> The sunxi clk driver causes a link error when the reset controller
>> subsystem is disabled:
>>
>> drivers/clk/built-in.o: In function `sun4i_ve_clk_setup':
>> :(.init.text+0xd040): undefined reference to `reset_controller_register'
>> drivers/clk/built-in.o: In function `sun4i_a10_display_init':
>> :(.init.text+0xe5e0): undefined reference to `reset_controller_register'
>> drivers/clk/built-in.o: In function `sunxi_usb_clk_setup':
>> :(.init.text+0x10074): undefined reference to `reset_controller_register'
>>
>> We already force it to be enabled on arm32 and some other arm64 platforms,
>> but not on arm64/sunxi. This adds the respective Kconfig statements to
>> also select it here.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> ---
>>  arch/arm64/Kconfig.platforms | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> I'd suggest we can pick this up in arm-soc as a non-urgent bugfix for 4.12
>
> That works for me, you can add my Acked-by.
>

Applied now.

        Arnd

^ permalink raw reply

* [RFC/RFT PATCH 00/18] PCI: ARM/ARM64: remove pci_fixup_irqs() usage
From: Thierry Reding @ 2017-04-27 20:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170426111809.19922-1-lorenzo.pieralisi@arm.com>

On Wed, Apr 26, 2017 at 12:17:51PM +0100, Lorenzo Pieralisi wrote:
> Current pci_fixup_irqs() usage on ARM/ARM64 host controller drivers is
> flawed in that pci_fixup_irqs() allocates IRQs for all PCI devices present
> in a system; those PCI devices possibly belong to different PCI bus trees
> (and possibly rooted at different host bridges) and may well be enabled
> (ie probed and bound to a driver) by the time pci_fixup_irqs() is called
> when probing a given host bridge driver.
> 
> Furthermore, current kernel code relying on pci_fixup_irqs() to
> assign legacy PCI IRQs to devices does not work at all for
> hotplugged devices in that the code carrying out the IRQ fixup
> is called at host bridge driver probe time, which just cannot take
> into account devices hotplugged after system has booted.
> 
> By leveraging Matthew Minter's patch series (and its purpose):
> 
> http://lkml.kernel.org/r/1445576642-29624-2-git-send-email-matt at masarand.com
> 
> this series[1] adds IRQs mapping and swizzling primitives to
> the struct pci_host_bridge which allows IRQs to be allocated for
> for a device at probe time with host bridge specific functions,
> fixing the aforementioned limitations.
> 
> Current series remove pci_fixup_irqs() usage on ARM/ARM64; removal
> can be extended to other architectures provided the IRQs map/swizzle
> functions are set-up properly in the respective host bridges
> set-up/probe paths.
> 
> Tested on kvmtool with PCI host generic.

I've tested this on Jetson TX1 (though I need a small patch specific to
Tegra on top to fix a preexisting issue) and things seem to be working
normally.

The output of "lspci -v" is identical before and after applying the
series (on top of next-20170427):

-sh-4.4# lspci -v
00:01.0 PCI bridge: NVIDIA Corporation Device 0fae (rev a1) (prog-if 00 [Normal decode])
        Flags: bus master, fast devsel, latency 0, IRQ 348
        Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
        I/O behind bridge: 00001000-00001fff [size=4K]
        Memory behind bridge: 13000000-130fffff [size=1M]
        Prefetchable memory behind bridge: 0000000020000000-00000000200fffff [size=1M]
        Capabilities: [40] Subsystem: NVIDIA Corporation Device 0000
        Capabilities: [48] Power Management version 3
        Capabilities: [50] MSI: Enable+ Count=1/2 Maskable- 64bit+
        Capabilities: [60] HyperTransport: MSI Mapping Enable- Fixed-
        Capabilities: [80] Express Root Port (Slot+), MSI 00
        Capabilities: [100] #00
        Capabilities: [140] L1 PM Substates
        Kernel driver in use: pcieport

01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 02)
        Subsystem: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
        Flags: bus master, fast devsel, latency 0, IRQ 349
        I/O ports at 1000 [size=256]
        Memory at 13000000 (64-bit, non-prefetchable) [size=4K]
        Memory at 20000000 (64-bit, prefetchable) [size=64K]
        Capabilities: [40] Power Management version 3
        Capabilities: [50] MSI: Enable+ Count=1/1 Maskable- 64bit+
        Capabilities: [70] Express Endpoint, MSI 01
        Capabilities: [b0] MSI-X: Enable- Count=2 Masked-
        Capabilities: [d0] Vital Product Data
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [140] Virtual Channel
        Capabilities: [160] Device Serial Number 8d-08-00-00-68-4c-e0-00
        Kernel driver in use: r8169

Note that the Realtek card is initialized by the r8169 driver and the
network card is used to boot over NFS.

My understanding is that this is what's expected, so:

Tested-by: Thierry Reding <treding@nvidia.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170427/a7d62976/attachment.sig>

^ permalink raw reply

* [PATCH] Mangled urls fixed (was... Re: linux-next: manual merge of the pm tree with the arm-soc tree)
From: Santosh Shilimkar @ 2017-04-27 20:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a3O1zJt87prKyh691u854Pb1ef0TQS22fh0CS9KU69veg@mail.gmail.com>

On 4/27/2017 12:50 PM, Arnd Bergmann wrote:
> On Mon, Apr 24, 2017 at 11:28 PM, santosh.shilimkar at oracle.com
> <santosh.shilimkar@oracle.com> wrote:
>> On 4/21/17 2:44 PM, Arnd Bergmann wrote:
>>>
>>> On Fri, Apr 21, 2017 at 11:02 PM, santosh.shilimkar at oracle.com
>>
>>
>> [...]
>>
>>> Ok, good, thanks for checking! They are however the commits that
>>> contain the silly https://urldefense.proofpoint.com URLs. Can you
>>> send a follow-up patch to fix these and use the regular
>>> https://urldefense.proofpoint.com/v2/url?u=http-3A__www.ti.org&d=DwIBaQ&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY&m=vFHOEb7p2FxbH00YRQq4WnRiu2BKHADn0gl6e6DoNFQ&s=7mfiIp2Ywy9_ppWKjEGlrswiKRndv8_I7zGVF9uyT0w&e=
>>> URL that is in linux-next?
>>>
>> If not late can you please apply the top patch from below head
>> which fixes the mangled urls. Let me know if you want me to
>> create tag for the same.
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
>> for_4.12/soc-pmdomain-p2
>
> I pulled the fix into next/drivers. The timing is not a problem, but I would
> have preferred a signed tag. Not a big issue here since it's a very obvious
> fix and there is reason to doubt its authenticity.
>
Thanks Arnd !!

Regards,
Santosh

^ permalink raw reply

* [PATCH net-next 1/4] ixgbe: sparc: rename the ARCH_WANT_RELAX_ORDER to IXGBE_ALLOW_RELAXED_ORDER
From: Casey Leedom @ 2017-04-27 20:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170427171938.GA10705@bhelgaas-glaptop.roam.corp.google.com>

| From: Bjorn Helgaas <helgaas@kernel.org>
| Sent: Thursday, April 27, 2017 10:19 AM
|
| Are you hinting that the PCI core or arch code could actually *enable*
| Relaxed Ordering without the driver doing anything?  Is it safe to do that?
| Is there such a thing as a device that is capable of using RO, but where the
| driver must be aware of it being enabled, so it programs the device
| appropriately?

  I forgot to reply to this portion of Bjorn's email.

  The PCI Configuration Space PCI Capability Device Control[Enable Relaxed
Ordering] bit governs enabling the _ability_ for the PCIe Device to send
TLPs with the Relaxed Ordering Attribute set.  It does not _cause_ RO to be
set on TLPs.  Doing that would almost certainly cause Data Corruption Bugs
since you only want a subset of TLPs to have RO set.

  For instance, we typically use RO for Ingress Packet Data delivery but
non-RO for messages notifying the Host that an Ingress Packet has been
delivered.  This ensures that the "Ingress Packet Delivered" non-RO TLP is
processed _after_ any preceding RO TLPs delivering the actual Ingress Packet
Data.

  In the above scenario, if one were to turn off Enable Relaxed Ordering via
the PCIe Capability, then the on-chip PCIe engine would simply never send a
TLP with the Relaxed Ordering Attribute set, regardless of any other chip
programming.

  And finally, just to be absolutely clear, using Relaxed Ordering isn't and
"Architecture Thing".  It's a PCIe Fabric End Point Thing.  Many End Points
simply ignore the Relaxed Ordering Attribute (except to reflect it back in
Response TLPs).  In this sense, Relaxed Ordering simply provides
potentially useful optimization information to the PCIe End Point.

Casey

^ permalink raw reply

* [PATCH] arm64: prefetch: Change assembly to be compatible with gcc and clang
From: Matthias Kaehlcke @ 2017-04-27 20:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170424133447.GA12323@arm.com>

Hi,

Thanks for your comments!

El Mon, Apr 24, 2017 at 02:34:47PM +0100 Will Deacon ha dit:

> On Thu, Apr 20, 2017 at 09:42:07AM +0100, Mark Rutland wrote:
> > On Wed, Apr 19, 2017 at 02:22:11PM -0700, Matthias Kaehlcke wrote:
> > > clang fails to build with the current code:
> > > 
> > > arch/arm64/include/asm/processor.h:172:15: error: invalid operand in
> > > inline asm: 'prfm pldl1keep, ${0:a}'
> > > 
> > > Apparently clang does not support the 'a' modifier. Change the
> > > constraint from 'p' ('An operand that is a valid memory address is
> > > allowed') to 'Q' ('A memory address which uses a single base register
> > > with no offset'), which works for both gcc and clang.
> > 
> > It looks like the current %a0 template and p constraint were inherited
> > from arch/arm, as they've been there from day one on arm64.
> > 
> > Looking at the arch/arm history, the "a" operand modifier and "p"
> > constraint were introduced in commit:
> > 
> >   16f719de62809e22 ("[ARM] 5196/1: fix inline asm constraints for preload")
> > 
> > ... so as to avoid GCC assuming prefetch of a pointer implied it was not
> > NULL. Until that point, we'd used no operand modifier and "o"
> > constraint.
> > 
> > It's not clear to me whether "o", "p", and "Q" constraints differ in
> > this regard on AArch64, or if the issue regarding NULL is still
> > relevant. The GCC docs say the "p" constraint is used for "a valid
> > memory address", which does sound like it shouldn't be NULL.
> > 
> > Otherwise, this does look consistent with what we do elsewhere.
> 
> I really don't like using 'Q' here, for two reasons:
> 
> 1. It means we likely allocate a register where we don't need to, because
>    we're going to need to use [Xn] as the addressing mode, which means
>    adding any immediate offsets.
> 
> 2. As you mention, 16f719de62809e22 says that GCC will use this as an
>    indication that the address is non-NULL.
> 
> We also can't just remove the 'a', because that will result in assembly
> failures. I haven't dug into exactly why, but I suspect it's because "p"
> can generate a label, which then won't assemble if surrounded by '[]'.

I was suggested to use the intrinsic __pldx() from ACLE, however it
isn't supported by gcc and there seem to be no other uses of ACLE in
the kernel. For clang it should be possible to use its
__builtin_arm_prefetch(), however I suspect that the compiler
dependency wouldn't be well received.

I guess another option is to get clang to support the 'a' modifier,
though it seems to be another modifier that is undocumented (I only
saw it mentioned in some ancient gcc documentation).

Cheers

Matthias

^ permalink raw reply

* [PATCH v2 0/3] thermal: broadcom: Add NSP Thermal Support
From: Jon Mason @ 2017-04-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel

Changes in v2:
* Split SoC enablement into a separate patch (per Eduardo Valentin)
* Added Eduardo Valentin's Acked-by to the DTS patch


This adds support for NSP to the existing Northstar thermal driver.
This code is based on patches currently in the Linux SoC Thermal git
tree.  Specfically,
https://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git/commit/?h=linus&id=a94cb7eeecc4104a6874339f90c5d0647359c102

Jon Mason (3):
  ARM: BCM: Enable thermal support for iProc SoCs
  thermal: broadcom: ns-thermal: default on iProc SoCs
  ARM: dts: NSP: Add Thermal Support

 arch/arm/boot/dts/bcm-nsp.dtsi   | 26 ++++++++++++++++++++++++++
 arch/arm/mach-bcm/Kconfig        |  2 ++
 drivers/thermal/broadcom/Kconfig |  9 +++++----
 3 files changed, 33 insertions(+), 4 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH v2 1/3] ARM: BCM: Enable thermal support for iProc SoCs
From: Jon Mason @ 2017-04-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1493328194-1766-1-git-send-email-jon.mason@broadcom.com>

Change the iProc Kconfig to select THERMAL and THERMAL_OF, which allows
the ns-thermal driver to be selected via menuconfig.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 arch/arm/mach-bcm/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index a0e66d8..da2bfeb 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -19,6 +19,8 @@ config ARCH_BCM_IPROC
 	select GPIOLIB
 	select ARM_AMBA
 	select PINCTRL
+	select THERMAL
+	select THERMAL_OF
 	help
 	  This enables support for systems based on Broadcom IPROC architected SoCs.
 	  The IPROC complex contains one or more ARM CPUs along with common
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/3] thermal: broadcom: ns-thermal: default on iProc SoCs
From: Jon Mason @ 2017-04-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1493328194-1766-1-git-send-email-jon.mason@broadcom.com>

Tweak the Kconfig description to mention support for NSP and make the
default on for iProc based platforms.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 drivers/thermal/broadcom/Kconfig | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/broadcom/Kconfig b/drivers/thermal/broadcom/Kconfig
index f0dea8a..26d706c 100644
--- a/drivers/thermal/broadcom/Kconfig
+++ b/drivers/thermal/broadcom/Kconfig
@@ -1,8 +1,9 @@
 config BCM_NS_THERMAL
 	tristate "Northstar thermal driver"
 	depends on ARCH_BCM_IPROC || COMPILE_TEST
+	default ARCH_BCM_IPROC
 	help
-	  Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
-	  BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
-	  with a thermal sensor that allows checking CPU temperature. This
-	  driver provides support for it.
+	  Support for the Northstar and Northstar Plus family of SoCs (e.g.
+	  BCM4708, BCM4709, BCM5301x, BCM95852X, etc). It contains DMU (Device
+	  Management Unit) block with a thermal sensor that allows checking CPU
+	  temperature.
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/3] ARM: dts: NSP: Add Thermal Support
From: Jon Mason @ 2017-04-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1493328194-1766-1-git-send-email-jon.mason@broadcom.com>

Add thermal support via the ns-thermal driver and create a single
thermal zone for the entire SoC.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Acked-by: Eduardo Valentin <edubezval@gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 832795b..be6fcfb 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -383,6 +383,12 @@
 			      <0x3f408 0x04>;
 		};
 
+		thermal: thermal at 3f2c0 {
+			compatible = "brcm,ns-thermal";
+			reg = <0x3f2c0 0x10>;
+			#thermal-sensor-cells = <0>;
+		};
+
 		sata_phy: sata_phy at 40100 {
 			compatible = "brcm,iproc-nsp-sata-phy";
 			reg = <0x40100 0x340>;
@@ -533,4 +539,24 @@
 			brcm,pcie-msi-inten;
 		};
 	};
+
+	thermal-zones {
+		cpu-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			coefficients = <(-556) 418000>;
+			thermal-sensors = <&thermal>;
+
+			trips {
+				cpu-crit {
+					temperature     = <125000>;
+					hysteresis      = <0>;
+					type            = "critical";
+				};
+			};
+
+			cooling-maps {
+			};
+		};
+	};
 };
-- 
2.7.4

^ permalink raw reply related

* [PATCH] drm/rockchip: Set line flag config register in vop_crtc_enable
From: Kristian H. Kristensen @ 2017-04-27 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1493276057-4516-1-git-send-email-jeffy.chen@rock-chips.com>

Jeffy Chen <jeffy.chen@rock-chips.com> writes:

> We need to set vop config done after update line flag config, it's a
> new requirement for chips newer than rk3368.
>
> Since we would only use line flag irq for vact_end, let's move it to
> vop_crtc_enable.
>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
>
> ---
>
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  4 ++--
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.h     |  3 +--
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c     | 20 +++++++++-----------
>  3 files changed, 12 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index d8fa7a9..9bfdbc6 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -115,8 +115,8 @@ static void analogix_dp_psr_work(struct work_struct *work)
>  
>  	vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay;

We don't need vact_end anymore here.

Kristian

> -	ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,
> -					  PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
> +	ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
> +					 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
>  	if (ret) {
>  		dev_err(dp->dev, "line flag interrupt did not arrive\n");
>  		return;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> index a48fcce..47905fa 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> @@ -62,8 +62,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
>  				   struct device *dev);
>  void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
>  				    struct device *dev);
> -int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
> -				unsigned int mstimeout);
> +int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
>  
>  extern struct platform_driver cdn_dp_driver;
>  extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 3f7a82d..40a5e6e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop)
>  	return !!line_flag_irq;
>  }
>  
> -static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
> +static void vop_line_flag_irq_enable(struct vop *vop)
>  {
>  	unsigned long flags;
>  
> @@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
>  
>  	spin_lock_irqsave(&vop->irq_lock, flags);
>  
> -	VOP_CTRL_SET(vop, line_flag_num[0], line_num);
>  	VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
>  	VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
>  
> @@ -981,6 +980,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
>  	VOP_CTRL_SET(vop, vact_st_end, val);
>  	VOP_CTRL_SET(vop, vpost_st_end, val);
>  
> +	VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
> +
>  	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
>  
>  	VOP_CTRL_SET(vop, standby, 0);
> @@ -1507,19 +1508,16 @@ static void vop_win_init(struct vop *vop)
>  }
>  
>  /**
> - * rockchip_drm_wait_line_flag - acqiure the give line flag event
> + * rockchip_drm_wait_vact_end
>   * @crtc: CRTC to enable line flag
> - * @line_num: interested line number
>   * @mstimeout: millisecond for timeout
>   *
> - * Driver would hold here until the interested line flag interrupt have
> - * happened or timeout to wait.
> + * Wait for vact_end line flag irq or timeout.
>   *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
> -int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
> -				unsigned int mstimeout)
> +int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
>  {
>  	struct vop *vop = to_vop(crtc);
>  	unsigned long jiffies_left;
> @@ -1527,14 +1525,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
>  	if (!crtc || !vop->is_enabled)
>  		return -ENODEV;
>  
> -	if (line_num > crtc->mode.vtotal || mstimeout <= 0)
> +	if (mstimeout <= 0)
>  		return -EINVAL;
>  
>  	if (vop_line_flag_irq_is_enabled(vop))
>  		return -EBUSY;
>  
>  	reinit_completion(&vop->line_flag_completion);
> -	vop_line_flag_irq_enable(vop, line_num);
> +	vop_line_flag_irq_enable(vop);
>  
>  	jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
>  						   msecs_to_jiffies(mstimeout));
> @@ -1547,7 +1545,7 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
>  
>  	return 0;
>  }
> -EXPORT_SYMBOL(rockchip_drm_wait_line_flag);
> +EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
>  
>  static int vop_bind(struct device *dev, struct device *master, void *data)
>  {
> -- 
> 2.1.4
>
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* [PATCH 1/2] dt/bindings: Add bindings for Broadcom STB DRAM Sensors
From: Rob Herring @ 2017-04-27 21:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGt4E5uu1Ty0ReaiBZ0kcR_-jnqJQL8vgU4Y9mL64FP7f+=T7Q@mail.gmail.com>

On Thu, Apr 27, 2017 at 11:28:37AM -0700, Markus Mayer wrote:
> On 25 April 2017 at 12:29, Markus Mayer <markus.mayer@broadcom.com> wrote:
> > Hi Rob,
> >
> > On 18 April 2017 at 13:17, Markus Mayer <code@mmayer.net> wrote:
> >> From: Markus Mayer <mmayer@broadcom.com>
> >>
> >> Provide bindings for the Broadcom STB DDR PHY Front End (DPFE).
> >
> > Would you be able to have a look at this binding? The driver won't be
> > upstreamed as hwmon driver (as per Guenter's comments). I am currently
> > converting the driver to a "soc" driver instead, but the proposed
> > binding remains unchanged.
> >
> > If you have comments or suggestions, I would like to incorporate them
> > with the new series I will be sending out.
> 
> To explain a bit more what we are looking for: we had a internal
> discussions how to structure this binding and are looking for some
> guidance.
> 
> Should we create three different nodes for the three different memory
> areas (dpfe-cpu at ..., dpfe-dmem at ..., dpfe-imem at ...), each with a single
> "reg" property (which is the proposal below) or should this be one
> single property with 3 "reg" cells, i.e. something like this:

Either way could be okay. It is conceptually 1 thing or 3?

> 
> dpfe-cpu at f1132000 {
>     ...
>     reg = <0xf1132000 0x180     /* register space */
>            0xf1134000 0x1000    /* data memory */
>            0xf1138000 0x4000>;  /* instruction memory */
>     ...
> };
> 
> Regards,
> -Markus
> 
> >> Signed-off-by: Markus Mayer <mmayer@broadcom.com>
> >> ---
> >>  .../devicetree/bindings/hwmon/brcmstb-dpfe.txt     | 68 ++++++++++++++++++++++
> >>  1 file changed, 68 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/hwmon/brcmstb-dpfe.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/hwmon/brcmstb-dpfe.txt b/Documentation/devicetree/bindings/hwmon/brcmstb-dpfe.txt
> >> new file mode 100644
> >> index 0000000..3519197
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/hwmon/brcmstb-dpfe.txt
> >> @@ -0,0 +1,68 @@
> >> +DDR PHY Front End (DPFE) for Broadcom STB
> >> +=========================================
> >> +
> >> +DPFE and the DPFE firmware provide an interface for the host CPU to
> >> +communicate with the DCPU, which resides inside the DDR PHY.
> >> +
> >> +There are three memory regions for interacting with the DCPU.
> >> +
> >> +The DCPU Register Space
> >> +-----------------------
> >> +
> >> +Required properties:
> >> +  - compatible: must be one of brcm,bcm7271-dpfe-cpu, brcm,dpfe-cpu-v12.0.0.0
> >> +    or brcm,dpfe-cpu

3 compatibles is a bit excessive. You can always use 
brcm,bcm7271-dpfe-cpu as a fallback for other chips. I wouldn't expect a 
DDR phy to be around a long time without changes given process and DDR 
technology changes.

> >> +  - reg: must reference the start address and length of the DCPU register
> >> +    space
> >> +
> >> +Optional properties:
> >> +  - cell-index: the index of the DPFE instance; will default to 0 if not set

Don't use cell-index. It's not a valid property for FDT (only real 
OpenFirmware).

Rob

^ permalink raw reply

* [PATCH] pwm: sun4i: switch to atomic PWM
From: Alexandre Belloni @ 2017-04-27 22:00 UTC (permalink / raw)
  To: linux-arm-kernel

Switch the driver to atomic PWM. This makes it easier to wait a proper
amount of time when changing the duty cycle before disabling the channel
(main use case is switching the duty cycle to 0 before disabling).

Also, the hardware read out is now greatly improved as it was formerly only
handling PWM polarity.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/pwm/pwm-sun4i.c | 272 ++++++++++++++++++++++++++----------------------
 1 file changed, 150 insertions(+), 122 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index b0803f6c64d9..de300779c811 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -27,7 +28,6 @@
 
 #define PWMCH_OFFSET		15
 #define PWM_PRESCAL_MASK	GENMASK(3, 0)
-#define PWM_PRESCAL_OFF		0
 #define PWM_EN			BIT(4)
 #define PWM_ACT_STATE		BIT(5)
 #define PWM_CLK_GATING		BIT(6)
@@ -44,6 +44,11 @@
 
 #define PWM_DTY_MASK		GENMASK(15, 0)
 
+#define PWM_MAX_PRD_US		198000000
+#define PWM_REG_PRD(reg)	(((reg >> 16) & PWM_PRD_MASK) + 1)
+#define PWM_REG_DTY(reg)	(reg & PWM_DTY_MASK)
+#define PWM_REG_PRESCAL(reg, chan)	((reg >> ((chan) * PWMCH_OFFSET)) & PWM_PRESCAL_MASK)
+
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
 static const u32 prescaler_table[] = {
@@ -96,26 +101,65 @@ static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
 	writel(val, chip->base + offset);
 }
 
-static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-			    int duty_ns, int period_ns)
+static void sun4i_pwm_get_state(struct pwm_chip *chip,
+				struct pwm_device *pwm,
+				struct pwm_state *state)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
-	u32 prd, dty, val, clk_gate;
+	u64 clk_rate, tmp;
+	u32 val;
+	unsigned int prescaler;
+
+	clk_rate = clk_get_rate(sun4i_pwm->clk);
+
+	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+
+	if ((val == PWM_PRESCAL_MASK) && sun4i_pwm->data->has_prescaler_bypass)
+		prescaler = 1;
+	else
+		prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm->hwpwm)];
+
+	if (prescaler == 0)
+		return;
+
+	if (val & BIT_CH(PWM_ACT_STATE, pwm->hwpwm))
+		state->polarity = PWM_POLARITY_NORMAL;
+	else
+		state->polarity = PWM_POLARITY_INVERSED;
+
+	if (val & BIT_CH(PWM_CLK_GATING | PWM_EN, pwm->hwpwm))
+		state->enabled = true;
+	else
+		state->enabled = false;
+
+	val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm));
+
+	tmp = prescaler * NSEC_PER_SEC * PWM_REG_DTY(val);
+	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+
+	tmp = prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
+	state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+}
+
+static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
+			       struct pwm_state *state,
+			       u32 *dty, u32 *prd, unsigned int *prsclr)
+{
 	u64 clk_rate, div = 0;
-	unsigned int prescaler = 0;
-	int err;
+	unsigned int pval, prescaler = 0;
 
 	clk_rate = clk_get_rate(sun4i_pwm->clk);
 
 	if (sun4i_pwm->data->has_prescaler_bypass) {
 		/* First, test without any prescaler when available */
 		prescaler = PWM_PRESCAL_MASK;
+		pval = 1;
 		/*
 		 * When not using any prescaler, the clock period in nanoseconds
 		 * is not an integer so round it half up instead of
 		 * truncating to get less surprising values.
 		 */
-		div = clk_rate * period_ns + NSEC_PER_SEC / 2;
+		div = clk_rate * state->period + NSEC_PER_SEC / 2;
 		do_div(div, NSEC_PER_SEC);
 		if (div - 1 > PWM_PRD_MASK)
 			prescaler = 0;
@@ -126,137 +170,139 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		for (prescaler = 0; prescaler < PWM_PRESCAL_MASK; prescaler++) {
 			if (!prescaler_table[prescaler])
 				continue;
+			pval = prescaler_table[prescaler];
 			div = clk_rate;
-			do_div(div, prescaler_table[prescaler]);
-			div = div * period_ns;
+			do_div(div, pval);
+			div = div * state->period;
 			do_div(div, NSEC_PER_SEC);
 			if (div - 1 <= PWM_PRD_MASK)
 				break;
 		}
 
-		if (div - 1 > PWM_PRD_MASK) {
-			dev_err(chip->dev, "period exceeds the maximum value\n");
+		if (div - 1 > PWM_PRD_MASK)
 			return -EINVAL;
-		}
-	}
-
-	prd = div;
-	div *= duty_ns;
-	do_div(div, period_ns);
-	dty = div;
-
-	err = clk_prepare_enable(sun4i_pwm->clk);
-	if (err) {
-		dev_err(chip->dev, "failed to enable PWM clock\n");
-		return err;
-	}
-
-	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-
-	if (sun4i_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) {
-		spin_unlock(&sun4i_pwm->ctrl_lock);
-		clk_disable_unprepare(sun4i_pwm->clk);
-		return -EBUSY;
-	}
-
-	clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	if (clk_gate) {
-		val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
 	}
 
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
-	val |= BIT_CH(prescaler, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
-
-	val = (dty & PWM_DTY_MASK) | PWM_PRD(prd);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+	*prd = div;
+	div *= state->duty_cycle;
+	do_div(div, state->period);
+	*dty = div;
+	*prsclr = prescaler;
 
-	if (clk_gate) {
-		val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-		val |= clk_gate;
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
-	}
+	div = (u64)pval * NSEC_PER_SEC * *prd;
+	state->period = DIV_ROUND_CLOSEST_ULL(div, clk_rate);
 
-	spin_unlock(&sun4i_pwm->ctrl_lock);
-	clk_disable_unprepare(sun4i_pwm->clk);
+	div = (u64)pval * NSEC_PER_SEC * *dty;
+	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(div, clk_rate);
 
 	return 0;
 }
 
-static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
-				  enum pwm_polarity polarity)
+static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			   struct pwm_state *state)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
-	u32 val;
-	int ret;
-
-	ret = clk_prepare_enable(sun4i_pwm->clk);
-	if (ret) {
-		dev_err(chip->dev, "failed to enable PWM clock\n");
-		return ret;
+	struct pwm_state cstate;
+	u32 ctrl;
+	int delay_us, ret;
+	bool needs_delay = false, prescaler_changed = false;
+
+	pwm_get_state(pwm, &cstate);
+
+	if (!cstate.enabled) {
+		ret = clk_prepare_enable(sun4i_pwm->clk);
+		if (ret) {
+			dev_err(chip->dev, "failed to enable PWM clock\n");
+			return ret;
+		}
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 
-	if (polarity != PWM_POLARITY_NORMAL)
-		val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
-	else
-		val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+	if ((cstate.period != state->period) ||
+	    (cstate.duty_cycle != state->duty_cycle)) {
+		u32 period, duty, val;
+		unsigned int prescaler;
 
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		needs_delay = true;
 
-	spin_unlock(&sun4i_pwm->ctrl_lock);
-	clk_disable_unprepare(sun4i_pwm->clk);
+		ret = sun4i_pwm_calculate(sun4i_pwm, state,
+					  &duty, &period, &prescaler);
+		if (ret) {
+			dev_err(chip->dev, "period exceeds the maximum value\n");
+			spin_unlock(&sun4i_pwm->ctrl_lock);
+			if (!cstate.enabled)
+				clk_disable_unprepare(sun4i_pwm->clk);
+			return ret;
+		}
 
-	return 0;
-}
+		if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
+			prescaler_changed = true;
+			/* Prescaler changed, the clock has to be gated */
+			ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+			sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
 
-static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
-	u32 val;
-	int ret;
+			ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
+			ctrl |= BIT_CH(prescaler, pwm->hwpwm);
+		}
 
-	ret = clk_prepare_enable(sun4i_pwm->clk);
-	if (ret) {
-		dev_err(chip->dev, "failed to enable PWM clock\n");
-		return ret;
+		val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
+		sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
 	}
 
-	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val |= BIT_CH(PWM_EN, pwm->hwpwm);
-	val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
-	spin_unlock(&sun4i_pwm->ctrl_lock);
-
-	return 0;
-}
+	if (state->polarity != PWM_POLARITY_NORMAL)
+		ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+	else
+		ctrl |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+
+	ctrl |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+	if (state->enabled) {
+		ctrl |= BIT_CH(PWM_EN, pwm->hwpwm);
+	} else if (!needs_delay) {
+		ctrl &= ~BIT_CH(PWM_EN, pwm->hwpwm);
+		ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+	}
 
-static void sun4i_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
-	u32 val;
+	sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
 
-	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val &= ~BIT_CH(PWM_EN, pwm->hwpwm);
-	val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
-	clk_disable_unprepare(sun4i_pwm->clk);
+	if (!needs_delay)
+		return 0;
+
+	/* We need a full (previous) period to elapse before disabling the
+	 * channel. If a ready bit is available, wait for it instead of waiting
+	 * for a full period.
+	 *
+	 * If the new period is greater than the previous one, the prescaler may
+	 * have changed and the previous period may go slower.
+	 *
+	 */
+	delay_us = max(state->period / 1000 + 1, cstate.period / 1000 + 1);
+	if ((cstate.enabled && !state->enabled) || !sun4i_pwm->data->has_rdy)
+		usleep_range(delay_us, delay_us * 2);
+	else
+		readl_poll_timeout(sun4i_pwm->base + PWM_CTRL_REG, ctrl,
+				   !(ctrl & PWM_RDY(pwm->hwpwm)),
+				   delay_us / 4, PWM_MAX_PRD_US);
+
+	if (!state->enabled) {
+		spin_lock(&sun4i_pwm->ctrl_lock);
+		ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+		ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+		sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
+		spin_unlock(&sun4i_pwm->ctrl_lock);
+
+		clk_disable_unprepare(sun4i_pwm->clk);
+	}
+
+	return 0;
 }
 
 static const struct pwm_ops sun4i_pwm_ops = {
-	.config = sun4i_pwm_config,
-	.set_polarity = sun4i_pwm_set_polarity,
-	.enable = sun4i_pwm_enable,
-	.disable = sun4i_pwm_disable,
+	.apply = sun4i_pwm_apply,
+	.get_state = sun4i_pwm_get_state,
 	.owner = THIS_MODULE,
 };
 
@@ -316,8 +362,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 {
 	struct sun4i_pwm_chip *pwm;
 	struct resource *res;
-	u32 val;
-	int i, ret;
+	int ret;
 	const struct of_device_id *match;
 
 	match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
@@ -354,24 +399,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, pwm);
 
-	ret = clk_prepare_enable(pwm->clk);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to enable PWM clock\n");
-		goto clk_error;
-	}
-
-	val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
-	for (i = 0; i < pwm->chip.npwm; i++)
-		if (!(val & BIT_CH(PWM_ACT_STATE, i)))
-			pwm_set_polarity(&pwm->chip.pwms[i],
-					 PWM_POLARITY_INVERSED);
-	clk_disable_unprepare(pwm->clk);
-
 	return 0;
-
-clk_error:
-	pwmchip_remove(&pwm->chip);
-	return ret;
 }
 
 static int sun4i_pwm_remove(struct platform_device *pdev)
-- 
2.11.0

^ permalink raw reply related

* [PATCH 1/2] dt/bindings: Add bindings for Broadcom STB DRAM Sensors
From: Florian Fainelli @ 2017-04-27 22:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170427215737.dmnj4u2e4tfc6vfv@rob-hp-laptop>

On 04/27/2017 02:57 PM, Rob Herring wrote:
>>>> +  - reg: must reference the start address and length of the DCPU register
>>>> +    space
>>>> +
>>>> +Optional properties:
>>>> +  - cell-index: the index of the DPFE instance; will default to 0 if not set
> 
> Don't use cell-index. It's not a valid property for FDT (only real 
> OpenFirmware).

My bad, I was advising Markus to use this property since it was largely
used throughout Documentation/devicetree/bindings/. What would be a more
appropriate way to have the same information? Aliases?
-- 
Florian

^ permalink raw reply

* [PATCH v2] arm64: Add ASM modifier for xN register operands
From: Matthias Kaehlcke @ 2017-04-27 22:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170427110256.GC31337@leverpostej>

Hi Mark,

Thanks for your comments.

El Thu, Apr 27, 2017 at 12:02:56PM +0100 Mark Rutland ha dit:

> Hi,
> 
> On Wed, Apr 26, 2017 at 02:46:16PM -0700, Matthias Kaehlcke wrote:
> > Many inline assembly statements don't include the 'x' modifier when
> > using xN registers as operands. This is perfectly valid, however it
> > causes clang to raise warnings like this:
> > 
> > warning: value size does not match register size specified by the
> >   constraint and modifier [-Wasm-operand-widths]
> > ...
> > arch/arm64/include/asm/barrier.h:62:23: note: expanded from macro
> >   '__smp_store_release'
> >     asm volatile ("stlr %1, %0"
> > 
> > Add the modifiers to keep clang happy.
> 
> If we're going to make this consistent, it would make sense to similarly
> annotate 'w' regs. That will make it easier going forward to enforce a
> policy that registers are suitably annotated.

Ok

> Also, there's a risk that we silently mask a bug here, for which clang's
> warning is legitimate, so we need to review this very carefully...
>
> > Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> > ---
> > Changes in v2:
> > - also add modifiers to multiline ASM statements in include/asm/
> >   {atomic_ll_sc.h,irqflags.h,pgtable.h,uaccess.h,word-at-a-time.h}
> >   that were missed on v1
> > 
> >  arch/arm64/include/asm/arch_gicv3.h     |  2 +-
> >  arch/arm64/include/asm/atomic_ll_sc.h   | 36 ++++++++++++++++-----------------
> >  arch/arm64/include/asm/barrier.h        |  4 ++--
> >  arch/arm64/include/asm/io.h             | 24 +++++++++++-----------
> >  arch/arm64/include/asm/irqflags.h       | 10 ++++-----
> >  arch/arm64/include/asm/kvm_hyp.h        | 10 ++++-----
> >  arch/arm64/include/asm/kvm_mmu.h        | 12 +++++------
> >  arch/arm64/include/asm/percpu.h         |  4 ++--
> >  arch/arm64/include/asm/pgtable.h        | 20 +++++++++---------
> >  arch/arm64/include/asm/sysreg.h         |  4 ++--
> >  arch/arm64/include/asm/uaccess.h        | 14 ++++++-------
> >  arch/arm64/include/asm/word-at-a-time.h | 14 ++++++-------
> >  arch/arm64/kernel/armv8_deprecated.c    |  4 ++--
> >  arch/arm64/kernel/probes/kprobes.c      |  2 +-
> >  arch/arm64/kvm/hyp/switch.c             |  4 ++--
> >  15 files changed, 82 insertions(+), 82 deletions(-)
> 
> ... to that end, could you split these into a few patches?
> 
> That way, knowledgeable people can focus their review on the code they
> understand.
> 
> That doesn't need to be a patch per file; all the KVM bits can be
> collated in one patch, for example. However, the atomics, kvm, and
> uaccess+word-at-a-time bits should certainly be separate patches given
> their (existing) complexity.

I agree the patch is too large, I considered to split it up but wasn't
sure where to draw the line(s). Will try to find halfway reasonable
batches :)

> Otherwise, I have a couple of comments below.
> 
> > diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
> > index f37e3a21f6e7..ba54e5bee885 100644
> > --- a/arch/arm64/include/asm/arch_gicv3.h
> > +++ b/arch/arm64/include/asm/arch_gicv3.h
> > @@ -166,7 +166,7 @@ static inline void gic_write_sre(u32 val)
> >  
> >  static inline void gic_write_bpr1(u32 val)
> >  {
> > -	asm volatile("msr_s " __stringify(ICC_BPR1_EL1) ", %0" : : "r" (val));
> > +	asm volatile("msr_s " __stringify(ICC_BPR1_EL1) ", %x0" : : "r" (val));
> >  }
> 
> Please make this use write_sysreg_s() instead, i.e.
> 
> static inline void gic_write_bpr1(u32 val)
> {
> 	write_sysreg_s(var, ICC_BPR1_EL1);
> }
> 
> ... that uses the 'x' modifier internally, and it's what we do for the
> other GIC sysreg accesors.
> 
> This accessor was missed by commit:
> 
>   d44ffa5ae70a15a1 ("irqchip/gic-v3: Convert arm64 GIC accessors to {read,write}_sysreg_s")
> 
> ... because it was added concurrently by commitL
> 
>   91ef84428a86b75a ("irqchip/gic-v3: Reset BPR during initialization")
> 
> ... i.e. it was not deliberately omitted.

Will do

> [...]
> 
> > -	asm volatile("strb %w0, [%1]" : : "rZ" (val), "r" (addr));
> > +	asm volatile("strb %w0, [%x1]" : : "rZ" (val), "r" (addr));
> 
> In general, the '[%xN]' pattern looks *very* suspicious to me. Any
> address must be 64-bit, so this would mask a legitimate warning.
> 
> Given the prototype of this function the code if fine either way, but
> were we to refactor things (e.g. making this a macro), that might not be
> true.
> 
> ... so I'm not sure it make sense to alter instances used for addresses.

Good point, I'll leave instances dealing with addresses untouched for now.

Cheers

Matthias

^ permalink raw reply

* [PATCH v2 1/3] ARM: BCM: Enable thermal support for iProc SoCs
From: Scott Branden @ 2017-04-27 23:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1493328194-1766-2-git-send-email-jon.mason@broadcom.com>



On 17-04-27 02:23 PM, Jon Mason wrote:
> Change the iProc Kconfig to select THERMAL and THERMAL_OF, which allows
> the ns-thermal driver to be selected via menuconfig.
>
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> ---
>  arch/arm/mach-bcm/Kconfig | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
> index a0e66d8..da2bfeb 100644
> --- a/arch/arm/mach-bcm/Kconfig
> +++ b/arch/arm/mach-bcm/Kconfig
> @@ -19,6 +19,8 @@ config ARCH_BCM_IPROC
>  	select GPIOLIB
>  	select ARM_AMBA
>  	select PINCTRL
> +	select THERMAL
> +	select THERMAL_OF
This is NSP specific at this point.  Also, If it increases code size in 
any way it shouldn't be selected for all IPROC SoCS.  I'd rather this 
was just selected via defconfig
>  	help
>  	  This enables support for systems based on Broadcom IPROC architected SoCs.
>  	  The IPROC complex contains one or more ARM CPUs along with common
>

^ permalink raw reply

* [PATCH v2 pci] PCI/MSI: pci-xgene-msi: Enable MSI support in ACPI boot for X-Gene v1
From: Khuong Dinh @ 2017-04-28  0:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Khuong Dinh <kdinh@apm.com>

This patch makes pci-xgene-msi driver ACPI-aware and provides
MSI capability for X-Gene v1 PCIe controllers in ACPI boot mode.

Signed-off-by: Khuong Dinh <kdinh@apm.com>
Signed-off-by: Duc Dang <dhdang@apm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
v2:
 - Verify with BIOS version 3.06.25 and 3.07.09
v1:
 - Initial version
---
 drivers/pci/host/pci-xgene-msi.c |   35 ++++++++++++++++++++++++++++++++---
 1 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c
index f1b633b..00aaa3d 100644
--- a/drivers/pci/host/pci-xgene-msi.c
+++ b/drivers/pci/host/pci-xgene-msi.c
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/of_pci.h>
+#include <linux/acpi.h>
 
 #define MSI_IR0			0x000000
 #define MSI_INT0		0x800000
@@ -39,7 +40,7 @@ struct xgene_msi_group {
 };
 
 struct xgene_msi {
-	struct device_node	*node;
+	struct fwnode_handle	*fwnode;
 	struct irq_domain	*inner_domain;
 	struct irq_domain	*msi_domain;
 	u64			msi_addr;
@@ -249,6 +250,13 @@ static void xgene_irq_domain_free(struct irq_domain *domain,
 	.free   = xgene_irq_domain_free,
 };
 
+#ifdef CONFIG_ACPI
+static struct fwnode_handle *xgene_msi_get_fwnode(struct device *dev)
+{
+	return xgene_msi_ctrl.fwnode;
+}
+#endif
+
 static int xgene_allocate_domains(struct xgene_msi *msi)
 {
 	msi->inner_domain = irq_domain_add_linear(NULL, NR_MSI_VEC,
@@ -256,7 +264,7 @@ static int xgene_allocate_domains(struct xgene_msi *msi)
 	if (!msi->inner_domain)
 		return -ENOMEM;
 
-	msi->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(msi->node),
+	msi->msi_domain = pci_msi_create_irq_domain(msi->fwnode,
 						    &xgene_msi_domain_info,
 						    msi->inner_domain);
 
@@ -265,6 +273,9 @@ static int xgene_allocate_domains(struct xgene_msi *msi)
 		return -ENOMEM;
 	}
 
+#ifdef CONFIG_ACPI
+	pci_msi_register_fwnode_provider(&xgene_msi_get_fwnode);
+#endif
 	return 0;
 }
 
@@ -449,6 +460,13 @@ static int xgene_msi_hwirq_free(unsigned int cpu)
 	{},
 };
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id xgene_msi_acpi_ids[] = {
+	{"APMC0D0E", 0},
+	{ },
+};
+#endif
+
 static int xgene_msi_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -469,7 +487,17 @@ static int xgene_msi_probe(struct platform_device *pdev)
 		goto error;
 	}
 	xgene_msi->msi_addr = res->start;
-	xgene_msi->node = pdev->dev.of_node;
+
+	xgene_msi->fwnode = of_node_to_fwnode(pdev->dev.of_node);
+	if (!xgene_msi->fwnode) {
+		xgene_msi->fwnode = irq_domain_alloc_fwnode(NULL);
+		if (!xgene_msi->fwnode) {
+			dev_err(&pdev->dev, "Failed to create fwnode\n");
+			rc = ENOMEM;
+			goto error;
+		}
+	}
+
 	xgene_msi->num_cpus = num_possible_cpus();
 
 	rc = xgene_msi_init_allocator(xgene_msi);
@@ -540,6 +568,7 @@ static int xgene_msi_probe(struct platform_device *pdev)
 	.driver = {
 		.name = "xgene-msi",
 		.of_match_table = xgene_msi_match_table,
+		.acpi_match_table = ACPI_PTR(xgene_msi_acpi_ids),
 	},
 	.probe = xgene_msi_probe,
 	.remove = xgene_msi_remove,
-- 
1.7.1

^ permalink raw reply related

* [PATCH] watchdog: bcm281xx: Fix use of uninitialized spinlock.
From: Eric Anholt @ 2017-04-28  1:02 UTC (permalink / raw)
  To: linux-arm-kernel

The bcm_kona_wdt_set_resolution_reg() call takes the spinlock, so
initialize it earlier.  Fixes a warning at boot with lock debugging
enabled.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/watchdog/bcm_kona_wdt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 6fce17d5b9f1..a5775dfd8d5f 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -304,6 +304,8 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
 	if (!wdt)
 		return -ENOMEM;
 
+	spin_lock_init(&wdt->lock);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	wdt->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(wdt->base))
@@ -316,7 +318,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	spin_lock_init(&wdt->lock);
 	platform_set_drvdata(pdev, wdt);
 	watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
 	bcm_kona_wdt_wdd.parent = &pdev->dev;
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2] clk: sunxi-ng: Fix dependency on SUNXI_CCU_GATE
From: Stephen Boyd @ 2017-04-28  1:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170427081249.GA25781@Red>

On 04/27, Corentin Labbe wrote:
> On Thu, Apr 27, 2017 at 09:04:36AM +0200, Maxime Ripard wrote:
> > On Wed, Apr 26, 2017 at 01:53:19PM +0200, Corentin Labbe wrote:
> > > When CONFIG_SUNXI_CCU is set but no other SUNXI_CCU is selected i got
> > > the following build error:
> > > drivers/built-in.o: In function `ccu_pll_notifier_cb':
> > > drivers/clk/sunxi-ng/ccu_common.c:71: undefined reference to `ccu_gate_helper_disable'
> > > drivers/clk/sunxi-ng/ccu_common.c:73: undefined reference to `ccu_gate_helper_enable'
> > > 
> > > The problem is the function ccu_pll_notifier_cb in ccu_common.c need
> > > some function from ccu_gate.c which is not compiled since SUNXI_CCU_GATE
> > > is not selected.
> > > 
> > > This patch remove SUNXI_CCU_GATE and compile ccu_gate.c unconditionnaly
> > > since all other combination of options select SUNXI_CCU_GATE finally.
> > > 
> > > Fixes: 02ae2bc6febd ("clk: sunxi-ng: Add clk notifier to gate then ungate PLL clocks")
> > > Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > 
> > I think Chen-Yu had some comments that you didn't address.
> > 
> 
> I have changed subject as requested

There were more comments than just fixing the subject. And now
Arnd has sent a patch. This is a problem in mainline, and the
release is days away. I'm inclined to go with Arnd's patch unless
someone sends something else and forward it directly to Linus.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH 1/3] ARM: at91: pm: Add sama5d2 backup mode
From: Yang, Wenyou @ 2017-04-28  1:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170426160419.22401-1-alexandre.belloni@free-electrons.com>



On 2017/4/27 0:04, Alexandre Belloni wrote:
> The sama5d2 has a mode were it is possible to cut power to the SoC while
> keeping the RAM in self refresh.
> Resuming from that mode needs support in the firmware/bootloader.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>
> ---
>   arch/arm/mach-at91/Makefile          |   4 ++
>   arch/arm/mach-at91/generic.h         |   2 +
>   arch/arm/mach-at91/pm.c              | 103 ++++++++++++++++++++++++++++++++++-
>   arch/arm/mach-at91/pm.h              |   4 ++
>   arch/arm/mach-at91/pm_data-offsets.c |   3 +
>   arch/arm/mach-at91/pm_suspend.S      |  86 ++++++++++++++++++++++-------
>   arch/arm/mach-at91/sama5.c           |  19 ++++++-
>   7 files changed, 198 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
> index cfd8f60a9268..87fe17dbdb56 100644
> --- a/arch/arm/mach-at91/Makefile
> +++ b/arch/arm/mach-at91/Makefile
> @@ -14,6 +14,10 @@ obj-$(CONFIG_PM)		+= pm_suspend.o
>   ifeq ($(CONFIG_CPU_V7),y)
>   AFLAGS_pm_suspend.o := -march=armv7-a
>   endif
> +# Backup mode will not compile for ARMv5 because of movt
> +ifeq ($(CONFIG_SOC_SAMA5D2),y)
> +AFLAGS_pm_suspend.o += -DBACKUP_MODE
> +endif
>   ifeq ($(CONFIG_PM_DEBUG),y)
>   CFLAGS_pm.o += -DDEBUG
>   endif
> diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
> index f1ead0f13c19..e2bd17237964 100644
> --- a/arch/arm/mach-at91/generic.h
> +++ b/arch/arm/mach-at91/generic.h
> @@ -15,10 +15,12 @@
>   extern void __init at91rm9200_pm_init(void);
>   extern void __init at91sam9_pm_init(void);
>   extern void __init sama5_pm_init(void);
> +extern void __init sama5d2_pm_init(void);
>   #else
>   static inline void __init at91rm9200_pm_init(void) { }
>   static inline void __init at91sam9_pm_init(void) { }
>   static inline void __init sama5_pm_init(void) { }
> +static inline void __init sama5d2_pm_init(void) { }
>   #endif
>   
>   #endif /* _AT91_GENERIC_H */
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
> index 2cd27c830ab6..1e03f1277f14 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -22,6 +22,7 @@
>   #include <asm/cacheflush.h>
>   #include <asm/fncpy.h>
>   #include <asm/system_misc.h>
> +#include <asm/suspend.h>
>   
>   #include "generic.h"
>   #include "pm.h"
> @@ -58,6 +59,14 @@ static int at91_pm_valid_state(suspend_state_t state)
>   	}
>   }
>   
> +static int canary = 0xA5A5A5A5;
> +
> +static struct at91_pm_bu {
> +	int suspended;
> +	unsigned long reserved;
> +	phys_addr_t canary;
> +	phys_addr_t resume;
> +} *pm_bu;
>   
>   static suspend_state_t target_state;
>   
> @@ -123,15 +132,39 @@ static void (*at91_suspend_sram_fn)(struct at91_pm_data *);
>   extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
>   extern u32 at91_pm_suspend_in_sram_sz;
>   
> -static void at91_pm_suspend(suspend_state_t state)
> +static int at91_suspend_finish(unsigned long val)
>   {
> -	pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
> -
>   	flush_cache_all();
>   	outer_disable();
>   
>   	at91_suspend_sram_fn(&pm_data);
>   
> +	return 0;
> +}
> +
> +static void at91_pm_suspend(suspend_state_t state)
> +{
> +	if (pm_data.deepest_state == AT91_PM_BACKUP)
> +		if (state == PM_SUSPEND_MEM)
> +			pm_data.mode = AT91_PM_BACKUP;
> +		else
> +			pm_data.mode = AT91_PM_SLOW_CLOCK;
> +	else
> +		pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
> +
> +	if (pm_data.mode == AT91_PM_BACKUP) {
> +		pm_bu->suspended = 1;
> +
> +		cpu_suspend(0, at91_suspend_finish);
> +
> +		/* The SRAM is lost between suspend cycles */
> +		at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
> +					     &at91_pm_suspend_in_sram,
> +					     at91_pm_suspend_in_sram_sz);
> +	} else {
> +		at91_suspend_finish(0);
> +	}
> +
>   	outer_resume();
>   }
>   
> @@ -375,6 +408,25 @@ static __init void at91_dt_ramc(void)
>   	at91_cpuidle_device.dev.platform_data = standby;
>   }
>   
> +static __init void at91_dt_shdwc(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc");
> +	if (!np)
> +		return;
> +
> +	pm_data.shdwc = of_iomap(np, 0);
> +	of_node_put(np);
> +
> +	np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
> +	if (!np)
> +		return;
> +
> +	pm_data.sfrbu = of_iomap(np, 0);
> +	of_node_put(np);
> +}
> +
>   static void at91rm9200_idle(void)
>   {
>   	/*
> @@ -436,6 +488,44 @@ static void __init at91_pm_sram_init(void)
>   			&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
>   }
>   
> +static void __init at91_pm_bu_sram_init(void)
> +{
> +	struct gen_pool *sram_pool;
> +	struct device_node *node;
> +	struct platform_device *pdev = NULL;
> +
> +	pm_bu = NULL;
> +
> +	for_each_compatible_node(node, NULL, "atmel,sama5d2-securam") {
> +		pdev = of_find_device_by_node(node);
> +		if (pdev) {
> +			of_node_put(node);
> +			break;
> +		}
> +	}
> +
> +	if (!pdev) {
> +		pr_warn("%s: failed to find securam device!\n", __func__);
> +		return;
> +	}
> +
> +	sram_pool = gen_pool_get(&pdev->dev, NULL);
> +	if (!sram_pool) {
> +		pr_warn("%s: securam pool unavailable!\n", __func__);
> +		return;
> +	}
> +
> +	pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu));
> +	if (!pm_bu) {
> +		pr_warn("%s: unable to alloc securam!\n", __func__);
> +		return;
> +	}
> +
> +	pm_bu->suspended = 0;
> +	pm_bu->canary = virt_to_phys(&canary);
> +	pm_bu->resume = virt_to_phys(cpu_resume);
> +}
> +
>   struct pmc_info {
>   	unsigned long uhp_udp_mask;
>   };
> @@ -510,3 +600,10 @@ void __init sama5_pm_init(void)
>   	at91_dt_ramc();
>   	at91_pm_init(NULL);
>   }
> +
> +void __init sama5d2_pm_init(void)
> +{
> +	at91_dt_shdwc();
> +	at91_pm_bu_sram_init();
> +	sama5_pm_init();
> +}
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
> index fc0f7d048187..d9c6612ef62f 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -22,6 +22,7 @@
>   #define AT91_MEMCTRL_DDRSDR	2
>   
>   #define	AT91_PM_SLOW_CLOCK	0x01
> +#define	AT91_PM_BACKUP		0x02
>   
>   #ifndef __ASSEMBLY__
>   struct at91_pm_data {
> @@ -30,6 +31,9 @@ struct at91_pm_data {
>   	unsigned long uhp_udp_mask;
>   	unsigned int memctrl;
>   	unsigned int mode;
> +	void __iomem *shdwc;
> +	void __iomem *sfrbu;
> +	unsigned int deepest_state;
>   };
>   #endif
>   
> diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
> index 30302cb16df0..c0a73e62b725 100644
> --- a/arch/arm/mach-at91/pm_data-offsets.c
> +++ b/arch/arm/mach-at91/pm_data-offsets.c
> @@ -9,5 +9,8 @@ int main(void)
>   	DEFINE(PM_DATA_RAMC1,		offsetof(struct at91_pm_data, ramc[1]));
>   	DEFINE(PM_DATA_MEMCTRL,	offsetof(struct at91_pm_data, memctrl));
>   	DEFINE(PM_DATA_MODE,		offsetof(struct at91_pm_data, mode));
> +	DEFINE(PM_DATA_SHDWC,		offsetof(struct at91_pm_data, shdwc));
> +	DEFINE(PM_DATA_SFRBU,		offsetof(struct at91_pm_data, sfrbu));
> +
>   	return 0;
>   }
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
> index 96781daa671a..b5ffa8e1f203 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -97,15 +97,74 @@ ENTRY(at91_pm_suspend_in_sram)
>   	str	tmp1, .memtype
>   	ldr	tmp1, [r0, #PM_DATA_MODE]
>   	str	tmp1, .pm_mode
> +	ldr	tmp1, [r0, #PM_DATA_SHDWC]
> +#if defined(BACKUP_MODE)
> +	str	tmp1, .shdwc
> +	cmp	tmp1, #0
> +	ldrne	tmp2, [tmp1, #0]
> +	ldr	tmp1, [r0, #PM_DATA_SFRBU]
> +	str	tmp1, .sfr
> +	cmp	tmp1, #0
> +	ldrne	tmp2, [tmp1, #0x10]
> +#endif
>   
>   	/* Active the self-refresh mode */
>   	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
>   	bl	at91_sramc_self_refresh
>   
>   	ldr	r0, .pm_mode
> -	tst	r0, #AT91_PM_SLOW_CLOCK
> -	beq	skip_disable_main_clock
> +	cmp	r0, #AT91_PM_SLOW_CLOCK
> +	beq	slow_clock
> +#if defined(BACKUP_MODE)
> +	cmp	r0, #AT91_PM_BACKUP
> +	beq	backup_mode
> +#endif
>   
> +	/* Wait for interrupt */
> +	ldr	pmc, .pmc_base
> +	at91_cpu_idle
> +	b	exit_suspend
> +
> +slow_clock:
> +	bl	at91_slowck_mode
> +	b	exit_suspend
> +#if defined(BACKUP_MODE)
> +backup_mode:
> +	bl	at91_backup_mode
> +	b	exit_suspend
> +#endif
> +
> +exit_suspend:
> +	/* Exit the self-refresh mode */
> +	mov	r0, #SRAMC_SELF_FRESH_EXIT
> +	bl	at91_sramc_self_refresh
> +
> +	/* Restore registers, and return */
> +	ldmfd	sp!, {r4 - r12, pc}
> +ENDPROC(at91_pm_suspend_in_sram)
> +
> +#if defined(BACKUP_MODE)
> +ENTRY(at91_backup_mode)
> +	#if 0
> +	/* Read LPR */
> +	ldr	r2, .sramc_base
> +	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
> +	#endif
> +
> +	/*BUMEN*/
> +	ldr	r0, .sfr
> +	mov	tmp1, #(0x1)
> +	str	tmp1, [r0, #0x10]
> +
> +	/* Shutdown */
> +	ldr	r0, .shdwc
> +	movw    tmp1, #0x1
> +	movt    tmp1, #0xA500
> +	str	tmp1, [r0, #0]
> +ENDPROC(at91_backup_mode)
> +#endif
> +
> +ENTRY(at91_slowck_mode)
>   	ldr	pmc, .pmc_base
>   
>   	/* Save Master clock setting */
> @@ -134,18 +193,9 @@ ENTRY(at91_pm_suspend_in_sram)
>   	orr	tmp1, tmp1, #AT91_PMC_KEY
>   	str	tmp1, [pmc, #AT91_CKGR_MOR]
>   
> -skip_disable_main_clock:
> -	ldr	pmc, .pmc_base
> -
>   	/* Wait for interrupt */
>   	at91_cpu_idle
>   
> -	ldr	r0, .pm_mode
> -	tst	r0, #AT91_PM_SLOW_CLOCK
> -	beq	skip_enable_main_clock
> -
> -	ldr	pmc, .pmc_base
> -
>   	/* Turn on the main oscillator */
>   	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
>   	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
> @@ -174,14 +224,8 @@ skip_disable_main_clock:
>   
>   	wait_mckrdy
>   
> -skip_enable_main_clock:
> -	/* Exit the self-refresh mode */
> -	mov	r0, #SRAMC_SELF_FRESH_EXIT
> -	bl	at91_sramc_self_refresh
> -
> -	/* Restore registers, and return */
> -	ldmfd	sp!, {r4 - r12, pc}
> -ENDPROC(at91_pm_suspend_in_sram)
> +	mov	pc, lr
> +ENDPROC(at91_slowck_mode)
>   
>   /*
>    * void at91_sramc_self_refresh(unsigned int is_active)
> @@ -314,6 +358,10 @@ ENDPROC(at91_sramc_self_refresh)
>   	.word 0
>   .sramc1_base:
>   	.word 0
> +.shdwc:
> +	.word 0
> +.sfr:
> +	.word 0
>   .memtype:
>   	.word 0
>   .pm_mode:
> diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c
> index 6d157d0ead8e..3d0bf95a56ae 100644
> --- a/arch/arm/mach-at91/sama5.c
> +++ b/arch/arm/mach-at91/sama5.c
> @@ -34,7 +34,6 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
>   MACHINE_END
>   
>   static const char *const sama5_alt_dt_board_compat[] __initconst = {
> -	"atmel,sama5d2",
>   	"atmel,sama5d4",
>   	NULL
>   };
> @@ -45,3 +44,21 @@ DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5")
>   	.dt_compat	= sama5_alt_dt_board_compat,
>   	.l2c_aux_mask	= ~0UL,
>   MACHINE_END
> +
> +static void __init sama5d2_init(void)
> +{
> +	of_platform_default_populate(NULL, NULL, NULL);
> +	sama5d2_pm_init();
> +}
> +
> +static const char *const sama5d2_compat[] __initconst = {
> +	"atmel,sama5d2",
> +	NULL
> +};
> +
> +DT_MACHINE_START(sama5d2, "Atmel SAMA5")
> +	/* Maintainer: Atmel */
> +	.init_machine	= sama5d2_init,
> +	.dt_compat	= sama5d2_compat,
> +	.l2c_aux_mask	= ~0UL,
> +MACHINE_END

^ permalink raw reply

* [PATCH v5 1/4] printk/nmi: generic solution for safe printk in NMI
From: Sergey Senozhatsky @ 2017-04-28  1:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170420131154.GL3452@pathway.suse.cz>


On (04/20/17 15:11), Petr Mladek wrote:
[..]
>  void printk_nmi_enter(void)
>  {
> -	this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK);
> +	/*
> +	 * The size of the extra per-CPU buffer is limited. Use it
> +	 * only when really needed.
> +	 */
> +	if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK ||
> +	    raw_spin_is_locked(&logbuf_lock)) {

can we please have && here?


[..]
> diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c
> index 4e8a30d1c22f..0bc0a3535a8a 100644
> --- a/lib/nmi_backtrace.c
> +++ b/lib/nmi_backtrace.c
> @@ -86,9 +86,11 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
>  
>  bool nmi_cpu_backtrace(struct pt_regs *regs)
>  {
> +	static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED;
>  	int cpu = smp_processor_id();
>  
>  	if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
> +		arch_spin_lock(&lock);
>  		if (regs && cpu_in_idle(instruction_pointer(regs))) {
>  			pr_warn("NMI backtrace for cpu %d skipped: idling at pc %#lx\n",
>  				cpu, instruction_pointer(regs));
> @@ -99,6 +101,7 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
>  			else
>  				dump_stack();
>  		}
> +		arch_spin_unlock(&lock);
>  		cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
>  		return true;
>  	}

can the nmi_backtrace part be a patch on its own?

	-ss

^ 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