Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/13] pinctrl: mvebu: restructure resource allocation
From: Thomas Petazzoni @ 2014-02-13 16:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220776-30851-1-git-send-email-sebastian.hesselbarth@gmail.com>

Dear Sebastian Hesselbarth,

Thanks again for working on this! I have boot tested this successfully
on an Armada XP platform, and it seems to behave normally, the debugfs
pinctrl contents make sense.

I have a few comments below, though.

On Wed, 12 Feb 2014 16:59:23 +0100, Sebastian Hesselbarth wrote:

> Also, in the meantime, pinctrl driver stubs for new Armada 375/28x have
> been posted [3]. Before any of this patches move to a stable branch, I
> plan to send an updated version comprising the required patches for the
> new SoCs. As the new driver stubs are very much like what we already have
> for Armada 370/XP, let's only discuss the general approach now and add
> the branch dependency and patches later.

I am not sure what you mean here in terms of the ordering for the
patches. I'm attaching several patches, and the first three patches
adapt your patch series to also cover 375 and 38x, assuming the pinctrl
support for 375 and 38x is merged before your patch series.

With these patches, I have 


> Patches 1-3 first deal with the way we handle unnamed "generic" mpp
> controls. Patch 1 consolidates the per-control allocation of name buffers
> to counting unnamed controls first and then allocate a global name buffer
> for all those controls. Patch 2 then removes the now obsolete per-control
> allocation of name buffers. Patch 3 then makes the common driver to
> identify "generic" mpp controls by an empty name and adds some valuable
> comments about that special treatment.

I must say I dislike quite a bit this unnamed mpp controls mechanism.
Why isn't the name statically defined in the source code by the
MPP_MODE macro, which already takes as first argument the pin number?

All the calculation of the buffer size, generating the names and so on,
looks like a lot of unnecessary code to me. But well, this unnamed
thing was already here, so I'm not saying your patch series should do
anything about it.

> Patch 4 removes passing struct mvebu_mpp_ctrl to the special callback
> as the only relevant information in that struct for the callback is the
> pin number which is passed directly instead.
> 
> Patches 5-9 then add some global defines and provide SoC specific
> callbacks even for the "generic" mpp controls. This allows Patch 10 to
> move resource allocation to SoC specific drivers and remove the common
> generic callbacks in Patch 11.

This is definitely good, but I'm wondering why the core cannot provide
helper functions for the generic case where we have 4 bits per pin in
contiguous registers. This would avoid duplicating the helper function
six times (you have four in your patch series, and we'll need two more
for A375 and A38x).

I've also attached other patches:

 * One patch that fixes your Armada XP handling, which missed the
   mv78230 and mv78260 cases (PATCH 4)

 * One patch that removes MPP_REG_CTRL (PATCH 5)

 * One patch that adjusts a comment in the code that was no longer true
   (PATCH 6)

Feel free to squash these patches into the appropriate patches.

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-pinctrl-mvebu-armada-375-provide-generic-mpp-callbac.patch
Type: text/x-patch
Size: 1659 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140213/9f210261/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-pinctrl-mvebu-armada-38x-provide-generic-mpp-callbac.patch
Type: text/x-patch
Size: 1604 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140213/9f210261/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-fixup-pinctrl-mvebu-move-resource-allocation-to-SoC-.patch
Type: text/x-patch
Size: 2639 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140213/9f210261/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0004-fixup-pinctrl-mvebu-move-resource-allocation-to-SoC-.patch
Type: text/x-patch
Size: 1255 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140213/9f210261/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-pinctrl-mvebu-remove-MPP_REG_CTRL-macro.patch
Type: text/x-patch
Size: 1299 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140213/9f210261/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0006-pinctrl-mvebu-update-comment-about-mvebu_mpp_ctrl.patch
Type: text/x-patch
Size: 1293 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140213/9f210261/attachment-0005.bin>

^ permalink raw reply

* [PATCH v2 3/3] PCI: ARM: add support for generic PCI host controller
From: Arnd Bergmann @ 2014-02-13 16:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <BA5E6077-77F8-4BE8-80E5-BAB9FE111387@codeaurora.org>

On Thursday 13 February 2014 10:22:25 Kumar Gala wrote:
> On Feb 13, 2014, at 5:07 AM, Will Deacon <will.deacon@arm.com> wrote:
> > Happy to change it, but I'm also struggling for names. Maybe "linux,?"?
>
> I was thinking that as well, I?d say go with ?linux,?.

I see nothing linux specific in there. I would only use that namespace
for things we don't expect to work with another OS.

> >>> +- ranges         : As described in IEEE Std 1275-1994, but must provide
> >>> +                   at least a definition of one or both of IO and Memory
> >>> +                   Space.
> >>> +
> >>> +- #address-cells : Must be 3
> >>> +
> >>> +- #size-cells    : Must be 2
> >>> +
> >>> +- reg            : The Configuration Space base address, as accessed by the
> >>> +                   parent bus.
> >> 
> >> Isn?t the size fixed here for cam or ecam?
> > 
> > Yes, which is why reg just specifies the base address.
> 
> Huh?  The reg property clearly has the size in it (as shown in the example below).
> I guess I was just asking for the description here to say what the size was for
> the 2 compatibles since its fixed and known.

It's still an open question whether the config space in the reg property should
cover all 256 buses or just the ones in the bus-range. In the latter case,
it would be variable (but predictable) size.

> You could clean it up a bit to be human readable even if its kvmtool that?s creating it.
> 
> 	pci {
> 		compatible = "arm,pci-cam-generic?;
> 		#address-cells = <3>;
> 		#size-cells = <2>;
> 		#interrupt-cells = <1>
> 		reg = <0x0 0x40000000>;
> 		ranges = <
> 			0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000
> 			0x2000000 0x0 0x41000000 0x0 0x41000000 0x0 0x3f000000
> 			>;

Make it 

 		ranges = <0x1000000 0x0 0x00000000 0x0 0x00000000 0x0 0x00010000>,
 			 <0x2000000 0x0 0x41000000 0x0 0x41000000 0x0 0x3f000000>;

and it will be perfect ;-)

	Arnd

^ permalink raw reply

* [PATCH] Fix uses of dma_max_pfn() when converting to a limiting address
From: Santosh Shilimkar @ 2014-02-13 16:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1WDH7v-00038J-2k@rmk-PC.arm.linux.org.uk>

On Tuesday 11 February 2014 12:28 PM, Russell King wrote:
> We must use a 64-bit for this, otherwise overflowed bits get lost, and
> that can result in a lower than intended value set.
> 
> Fixes: 8e0cb8a1f6ac ("ARM: 7797/1: mmc: Use dma_max_pfn(dev) helper for bounce_limit calculations")
> Fixes: 7d35496dd982 ("ARM: 7796/1: scsi: Use dma_max_pfn(dev) helper for bounce_limit calculations")
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> While poking about with the Cubox-i4 and investigating why my UHS-1
> SD card wasn't achieving its full potential, I came across a slight
> problem... the SDHCI host sets a mask of 0xffffffff, but with the
> start of memory at pfn 0x10000, the blk code sees this when setting
> the bounce limit:
> 
> 	max addr 0x0ffff000 bounce limit 0xffff dma 1
> 
> and this results in the bounce functions appearing in the profile:
> 
> 00000000c00f8b70 copy_to_high_bio_irq                  1139 2.5886
> 00000000c00f8d28 bounce_end_io                           12 0.0714
> 00000000c00f8dd0 bounce_end_io_read_isa                   8 0.1053
> 
> which, compared to the cost of copying the data to userland and
> request handling, this is quite significant:
> 
> 00000000c04b1794 sdhci_request                          268 0.5447
> 00000000c02d0740 __copy_to_user_std                     398 0.4252
> 
> With this calculation fixed, we avoid the bouncing code entirely.
> 
> 	max addr 0x10ffff000 bounce limit 0x10ffff dma 0
>
You are right. We were seeing an issue with SCSI HDD over PCI and
the patch fixes that issue as well.

I think we should send this patch to stable as well. At least 3.13
should get this patch.

Thanks RMK for the bug fix. Feel free to add, in case the patch is
not committed already

Tested-Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
 
>  drivers/mmc/card/queue.c | 2 +-
>  drivers/scsi/scsi_lib.c  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
> index 357bbc54fe4b..3e049c13429c 100644
> --- a/drivers/mmc/card/queue.c
> +++ b/drivers/mmc/card/queue.c
> @@ -197,7 +197,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
>  	struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
>  
>  	if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
> -		limit = dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
> +		limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
>  
>  	mq->card = card;
>  	mq->queue = blk_init_queue(mmc_request_fn, lock);
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 7bd7f0d5f050..62ec84b42e31 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -1684,7 +1684,7 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
>  
>  	host_dev = scsi_get_device(shost);
>  	if (host_dev && host_dev->dma_mask)
> -		bounce_limit = dma_max_pfn(host_dev) << PAGE_SHIFT;
> +		bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
>  
>  	return bounce_limit;
>  }
> 

^ permalink raw reply

* [PATCH] ARM: tegra: don't timeout if CPU is powergated
From: Stephen Warren @ 2014-02-13 16:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213084907.GA11795@ulmo.nvidia.com>

On 02/13/2014 01:49 AM, Thierry Reding wrote:
> On Thu, Feb 13, 2014 at 09:28:52AM +0100, Marc Dietrich wrote:
>> Am Mittwoch, 12. Februar 2014, 12:20:29 schrieb Stephen Warren:
>>> On 02/10/2014 05:44 PM, Stefan Agner wrote:
>>>> When booting secondary CPU(s) which are not yet powergated, a wrong
>>>> check lead to a timeout after 100 jiffies. With this patch, we only
>>>> delay powergating if CPUs are still not powered yet.
>>>
>>> I've applied this to Tegra's for-3.15/soc branch.
>>
>> also for 3.14 and maybe lower versioned kernels? Since this seems to fix a bug 
>> where some core doesn't come up.
> 
> Yeah, this bug has been there for pretty much forever it seems. Commit
> 86e51a2ee471 "ARM: tegra: support for secondary cores on Tegra30" added
> tegra30_boot_secondary() (named tegra30_power_up_cpu() back then, which
> was renamed to tegra30_boot_secondary() in commit 0d1f79b033bb "ARM:
> tegra: refactor tegra{20,30}_boot_secondary". The latter was introduced
> in v3.10, so I guess backporting it to stable releases all the way back
> to v3.10 would be good.
> 
> Backporting to earlier versions (86e51a2ee471 went into v3.4) will be a
> lot more difficult since some of the APIs were renamed since then.

I'm actually uninclined to backport this; I've never once seen an issue
because of this problem, and nobody has reported it in older kernels.

^ permalink raw reply

* [PATCH v2 4/6] ARM: firmware: add prepare_idle() operation
From: Stephen Warren @ 2014-02-13 16:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FCA5FC.80504@samsung.com>

On 02/13/2014 04:01 AM, Tomasz Figa wrote:
> Hi Alexandre,
> 
> On 07.02.2014 05:35, Alexandre Courbot wrote:
>> Some firmwares do not put the CPU into idle mode themselves, but still
>> need to be informed that the CPU is about to enter idle mode before this
>> happens. Add a prepare_idle() operation to the firmware_ops structure to
>> handle such cases.
>>
>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>> ---
>>   arch/arm/include/asm/firmware.h | 4 ++++
>>   1 file changed, 4 insertions(+)
> 
> I wonder if .do_idle() couldn't simply return an appropriate error code
> to let the upper layer know that it should proceed with normal CPU idle
> activation, while still letting the firmware know that the CPU is going
> to idle.

That seems to disagree with the naming of the operation, and the
semantics I assume it has, though. It seems clearer to add an explicit
separate op for this.

^ permalink raw reply

* [PATCH] mfd: vexpress-sysreg: initialize "site" variable
From: Semen Protsenko @ 2014-02-13 16:39 UTC (permalink / raw)
  To: linux-arm-kernel

"site" variable should be initialized with 0 so that
when "site" property doesn't exist in DTB it can be handled correctly.

"0" value means board site number is motherboard (see
Documentation/devicetree/bindings/arm/vexpress.txt for details).

Signed-off-by: Semen Protsenko <semen.protsenko@linaro.org>
---
 drivers/mfd/vexpress-sysreg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index 981bef4..35281e8 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -168,7 +168,7 @@ static void *vexpress_sysreg_config_func_get(struct device *dev,
 		struct device_node *node)
 {
 	struct vexpress_sysreg_config_func *config_func;
-	u32 site;
+	u32 site = 0;
 	u32 position = 0;
 	u32 dcc = 0;
 	u32 func_device[2];
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v3 00/13] pinctrl: mvebu: restructure resource allocation
From: Sebastian Hesselbarth @ 2014-02-13 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213172620.76e760ba@skate>

On 02/13/14 17:26, Thomas Petazzoni wrote:
> Thanks again for working on this! I have boot tested this successfully
> on an Armada XP platform, and it seems to behave normally, the debugfs
> pinctrl contents make sense.

I guess this is a Tested-by ?

> I have a few comments below, though.
>
> On Wed, 12 Feb 2014 16:59:23 +0100, Sebastian Hesselbarth wrote:
>
>> Also, in the meantime, pinctrl driver stubs for new Armada 375/28x have
>> been posted [3]. Before any of this patches move to a stable branch, I
>> plan to send an updated version comprising the required patches for the
>> new SoCs. As the new driver stubs are very much like what we already have
>> for Armada 370/XP, let's only discuss the general approach now and add
>> the branch dependency and patches later.
>
> I am not sure what you mean here in terms of the ordering for the
> patches. I'm attaching several patches, and the first three patches
> adapt your patch series to also cover 375 and 38x, assuming the pinctrl
> support for 375 and 38x is merged before your patch series.

Right. If 375/38x pinctrl goes in first (what I expect), I'd have to add
corresponding patches. You already sent them, I'll pick them up.

> With these patches, I have
>
>> Patches 1-3 first deal with the way we handle unnamed "generic" mpp
>> controls. Patch 1 consolidates the per-control allocation of name buffers
>> to counting unnamed controls first and then allocate a global name buffer
>> for all those controls. Patch 2 then removes the now obsolete per-control
>> allocation of name buffers. Patch 3 then makes the common driver to
>> identify "generic" mpp controls by an empty name and adds some valuable
>> comments about that special treatment.
>
> I must say I dislike quite a bit this unnamed mpp controls mechanism.
> Why isn't the name statically defined in the source code by the
> MPP_MODE macro, which already takes as first argument the pin number?

Honestly, the unnamed mpp control thing is a bit odd. But if you tell
me how to create ~60 statically defined one pin groups out of a
single-line macro, we can change that easily.

Back when that unnamed mpp control thing was invented, I must have been
to lazy to write e.g.

MPP_FUNC_CTRL(0, 0, "mpp0", armada_xp_mpp_ctrl),
MPP_FUNC_CTRL(1, 1, "mpp1", armada_xp_mpp_ctrl),
MPP_FUNC_CTRL(2, 2, "mpp2", armada_xp_mpp_ctrl),
...
MPP_FUNC_CTRL(66, 66, "mpp66", armada_xp_mpp_ctrl),

instead of

MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),

and generate the 66 names dynamically.

> All the calculation of the buffer size, generating the names and so on,
> looks like a lot of unnecessary code to me. But well, this unnamed
> thing was already here, so I'm not saying your patch series should do
> anything about it.

If you come up with a cool idea, we can shove it in now.

>> Patch 4 removes passing struct mvebu_mpp_ctrl to the special callback
>> as the only relevant information in that struct for the callback is the
>> pin number which is passed directly instead.
>>
>> Patches 5-9 then add some global defines and provide SoC specific
>> callbacks even for the "generic" mpp controls. This allows Patch 10 to
>> move resource allocation to SoC specific drivers and remove the common
>> generic callbacks in Patch 11.
>
> This is definitely good, but I'm wondering why the core cannot provide
> helper functions for the generic case where we have 4 bits per pin in
> contiguous registers. This would avoid duplicating the helper function
> six times (you have four in your patch series, and we'll need two more
> for A375 and A38x).

I thought about it too, but we would need a soc specific callback
anyway as you'll have to pass the base address somehow (and that is now
known by soc specific stub only). My quick rule of thumb was that the
amount of code replication would be almost the same.

> I've also attached other patches:
>
>   * One patch that fixes your Armada XP handling, which missed the
>     mv78230 and mv78260 cases (PATCH 4)
>
>   * One patch that removes MPP_REG_CTRL (PATCH 5)
>
>   * One patch that adjusts a comment in the code that was no longer true
>     (PATCH 6)
>
> Feel free to squash these patches into the appropriate patches.

Yep, thanks for these! I'll squash them in and send an updated v4 as
soon as the discussion here stalls.

Sebastian

^ permalink raw reply

* [PATCH v2 2/7] ARM: imx6: gpc: Add PU power domain for GPU/VPU
From: Philipp Zabel @ 2014-02-13 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392302350-11729-3-git-send-email-p.zabel@pengutronix.de>

Am Donnerstag, den 13.02.2014, 15:39 +0100 schrieb Philipp Zabel:
> When generic pm domain support is enabled, the PGC can be used
> to completely gate power to the PU power domain containing GPU3D,
> GPU2D, and VPU cores.
> This code triggers the PGC powerdown sequence to disable the GPU/VPU
> isolation cells and gate power and then disables the PU regulator.
> To reenable, the reverse powerup sequence is triggered after the PU
> regulaotor is enabled again.
> 
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> Changes since v1:
>  - Removed superfluous comment
>  - Link PU domain with its DT node, check for PU domain in bus notifier
>  - Turn off the PU power domain on boot
> ---
>  arch/arm/mach-imx/Kconfig |   2 +
>  arch/arm/mach-imx/gpc.c   | 170 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 172 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 33567aa..3c58f2e 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -808,6 +808,7 @@ config SOC_IMX6Q
>  	select PL310_ERRATA_727915 if CACHE_PL310
>  	select PL310_ERRATA_769419 if CACHE_PL310
>  	select PM_OPP if PM
> +	select PM_GENERIC_DOMAINS if PM
>  
>  	help
>  	  This enables support for Freescale i.MX6 Quad processor.
> @@ -827,6 +828,7 @@ config SOC_IMX6SL
>  	select PL310_ERRATA_588369 if CACHE_PL310
>  	select PL310_ERRATA_727915 if CACHE_PL310
>  	select PL310_ERRATA_769419 if CACHE_PL310
> +	select PM_GENERIC_DOMAINS if PM
>  
>  	help
>  	  This enables support for Freescale i.MX6 SoloLite processor.
> diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
> index 586e017..1dc4301 100644
> --- a/arch/arm/mach-imx/gpc.c
> +++ b/arch/arm/mach-imx/gpc.c
> @@ -10,19 +10,32 @@
>   * http://www.gnu.org/copyleft/gpl.html
>   */
>  
> +#include <linux/clk.h>
> +#include <linux/delay.h>
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/regulator/consumer.h>
>  #include <linux/irqchip/arm-gic.h>
>  #include "common.h"
> +#include "hardware.h"
>  
> +#define GPC_CNTR		0x000
>  #define GPC_IMR1		0x008
> +#define GPC_PGC_GPU_PDN		0x260
> +#define GPC_PGC_GPU_PUPSCR	0x264
> +#define GPC_PGC_GPU_PDNSCR	0x268
>  #define GPC_PGC_CPU_PDN		0x2a0
>  
>  #define IMR_NUM			4
>  
> +#define GPU_VPU_PUP_REQ		BIT(1)
> +#define GPU_VPU_PDN_REQ		BIT(0)
> +
>  static void __iomem *gpc_base;
>  static u32 gpc_wake_irqs[IMR_NUM];
>  static u32 gpc_saved_imrs[IMR_NUM];
> @@ -138,3 +151,160 @@ void __init imx_gpc_init(void)
>  	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
>  	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
>  }
> +
> +static struct regulator *pu_reg;
> +
> +static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
> +{
> +	u32 val;
> +	int iso, iso2sw;
> +
> +	/* Read ISO and ISO2SW power down delays */
> +	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR);
> +	iso = val & 0x3f;
> +	iso2sw = (val >> 8) & 0x3f;
> +
> +	/* Gate off PU domain when GPU/VPU when powered down */
> +	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
> +
> +	/* Request GPC to power down GPU/VPU */
> +	val = readl_relaxed(gpc_base + GPC_CNTR);
> +	val |= GPU_VPU_PDN_REQ;
> +	writel_relaxed(val, gpc_base + GPC_CNTR);
> +
> +	/* Wait ISO + ISO2SW IPG clock cycles */
> +	ndelay((iso + iso2sw) * 1000 / 66);
> +
> +	regulator_disable(pu_reg);
> +
> +	return 0;
> +}
> +
> +static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
> +{
> +	int ret;
> +	u32 val;
> +	int sw, sw2iso;
> +
> +	ret = regulator_enable(pu_reg);
> +	if (ret) {
> +		pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	/* Gate off PU domain when GPU/VPU when powered down */
> +	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
> +
> +	/* Read ISO and ISO2SW power down delays */
> +	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR);
> +	sw = val & 0x3f;
> +	sw2iso = (val >> 8) & 0x3f;
> +
> +	/* Request GPC to power up GPU/VPU */
> +	val = readl_relaxed(gpc_base + GPC_CNTR);
> +	val |= GPU_VPU_PUP_REQ;
> +	writel_relaxed(val, gpc_base + GPC_CNTR);
> +
> +	/* Wait ISO + ISO2SW IPG clock cycles */
> +	ndelay((sw + sw2iso) * 1000 / 66);
> +
> +	return 0;
> +}
> +
> +static struct generic_pm_domain imx6q_pu_domain = {
> +	.name = "PU",
> +	.power_off = imx6q_pm_pu_power_off,
> +	.power_on = imx6q_pm_pu_power_on,
> +};
> +
> +static int imx6q_pm_notifier_call(struct notifier_block *nb,
> +				  unsigned long event, void *data)
> +{
> +	struct generic_pm_domain *genpd;
> +	struct device *dev = data;
> +	struct device_node *np;
> +	int ret;
> +
> +	switch (event) {
> +	case BUS_NOTIFY_BIND_DRIVER:
> +		np = of_parse_phandle(dev->of_node, "power-domain", 0);
> +		if (!np || np != imx6q_pu_domain.of_node)
> +			return NOTIFY_DONE;
> +
> +		ret = pm_genpd_of_add_device(np, dev);
> +		if (ret)
> +			dev_err(dev, "failed to add to power domain: %d\n",
> +				ret);
> +		break;
> +	case BUS_NOTIFY_UNBOUND_DRIVER:
> +		genpd = dev_to_genpd(dev);
> +		if (IS_ERR(genpd) || genpd != &imx6q_pu_domain)
> +			return NOTIFY_DONE;
> +
> +		ret = pm_genpd_remove_device(genpd, dev);
> +		if (ret)
> +			dev_err(dev, "failed to remove from power domain: %d\n",
> +				ret);
> +		break;
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block imx6q_platform_nb = {
> +	.notifier_call = imx6q_pm_notifier_call,
> +};
> +
> +static int imx_gpc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np;
> +	int ret;
> +
> +	np = of_get_child_by_name(pdev->dev.of_node, "pu-power-domain");
> +	if (!np) {
> +		dev_err(&pdev->dev, "missing pu-power-domain node\n");
> +		return -EINVAL;
> +	}
> +	imx6q_pu_domain.of_node = np;
> +
> +	pu_reg = devm_regulator_get(&pdev->dev, "pu");
> +	if (IS_ERR(pu_reg)) {
> +		ret = PTR_ERR(pu_reg);
> +		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* The regulator is initially enabled */
> +	ret = regulator_enable(pu_reg);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
> +		return ret;
> +	}
> +
> +	imx6q_pu_domain.of_node = np;
> +	imx6q_pm_pu_power_off(&imx6q_pu_domain);
> +	pm_genpd_init(&imx6q_pu_domain, NULL, true);

Turning off the PU power domain and supply voltage on boot isn't a good
idea if the kernel doesn't have runtime PM support compiled in. In that
case it should be left enabled:

--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -366,8 +366,12 @@ static int imx_gpc_probe(struct platform_device *pdev)
        regulator_allow_bypass(pu_reg, true);
 
        imx6q_pu_domain.of_node = np;
+#ifdef CONFIG_PM_RUNTIME
        imx6q_pm_pu_power_off(&imx6q_pu_domain);
        pm_genpd_init(&imx6q_pu_domain, NULL, true);
+#else
+       pm_genpd_init(&imx6q_pu_domain, NULL, false);
+#endif
        bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
 
        return 0;

> +	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
> +
> +	return 0;
> +}
> +
> +static struct of_device_id imx_gpc_dt_ids[] = {
> +	{ .compatible = "fsl,imx6q-gpc" },
> +	{ }
> +};
> +
> +static struct platform_driver imx_gpc_driver = {
> +	.driver = {
> +		.name = "imx-gpc",
> +		.owner = THIS_MODULE,
> +		.of_match_table = imx_gpc_dt_ids,
> +	},
> +	.probe = imx_gpc_probe,
> +};
> +
> +static int __init imx_pgc_init(void)
> +{
> +	return platform_driver_register(&imx_gpc_driver);
> +}
> +subsys_initcall(imx_pgc_init);

regards
Philipp

^ permalink raw reply

* [PATCH 5/5] iommu/arm-smmu: fix compilation issue when !CONFIG_ARM_AMBA
From: Timur Tabi @ 2014-02-13 16:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391710173-4343-6-git-send-email-will.deacon@arm.com>

On Thu, Feb 6, 2014 at 12:09 PM, Will Deacon <will.deacon@arm.com> wrote:

> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 0ae4dd39197f..6fe7922ecc1d 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -2004,8 +2004,10 @@ static int __init arm_smmu_init(void)
>         if (!iommu_present(&platform_bus_type))
>                 bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
>
> +#ifdef CONFIG_ARM_AMBA
>         if (!iommu_present(&amba_bustype))
>                 bus_set_iommu(&amba_bustype, &arm_smmu_ops);
> +#endif

So I admit I don't know much about the ARM kernel (yet), but doesn't
this break multi-arch?  That is, we can't support one binary that runs
on a processor with AMBA and one without?

^ permalink raw reply

* [PATCH] Fix uses of dma_max_pfn() when converting to a limiting address
From: James Bottomley @ 2014-02-13 16:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1WDH7v-00038J-2k@rmk-PC.arm.linux.org.uk>

On Tue, 2014-02-11 at 17:28 +0000, Russell King wrote:
> We must use a 64-bit for this, otherwise overflowed bits get lost, and
> that can result in a lower than intended value set.
> 
> Fixes: 8e0cb8a1f6ac ("ARM: 7797/1: mmc: Use dma_max_pfn(dev) helper for bounce_limit calculations")
> Fixes: 7d35496dd982 ("ARM: 7796/1: scsi: Use dma_max_pfn(dev) helper for bounce_limit calculations")
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> While poking about with the Cubox-i4 and investigating why my UHS-1
> SD card wasn't achieving its full potential, I came across a slight
> problem... the SDHCI host sets a mask of 0xffffffff, but with the
> start of memory at pfn 0x10000, the blk code sees this when setting
> the bounce limit:
> 
> 	max addr 0x0ffff000 bounce limit 0xffff dma 1
> 
> and this results in the bounce functions appearing in the profile:
> 
> 00000000c00f8b70 copy_to_high_bio_irq                  1139 2.5886
> 00000000c00f8d28 bounce_end_io                           12 0.0714
> 00000000c00f8dd0 bounce_end_io_read_isa                   8 0.1053
> 
> which, compared to the cost of copying the data to userland and
> request handling, this is quite significant:
> 
> 00000000c04b1794 sdhci_request                          268 0.5447
> 00000000c02d0740 __copy_to_user_std                     398 0.4252
> 
> With this calculation fixed, we avoid the bouncing code entirely.
> 
> 	max addr 0x10ffff000 bounce limit 0x10ffff dma 0
> 
>  drivers/mmc/card/queue.c | 2 +-
>  drivers/scsi/scsi_lib.c  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
> index 357bbc54fe4b..3e049c13429c 100644
> --- a/drivers/mmc/card/queue.c
> +++ b/drivers/mmc/card/queue.c
> @@ -197,7 +197,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
>  	struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
>  
>  	if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
> -		limit = dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
> +		limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
>  
>  	mq->card = card;
>  	mq->queue = blk_init_queue(mmc_request_fn, lock);
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 7bd7f0d5f050..62ec84b42e31 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -1684,7 +1684,7 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
>  
>  	host_dev = scsi_get_device(shost);
>  	if (host_dev && host_dev->dma_mask)
> -		bounce_limit = dma_max_pfn(host_dev) << PAGE_SHIFT;
> +		bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;

This doesn't really look like the right fix.  You replaced dev->dma_mask
with a calculation on dev_max_pfn().  Since dev->dma_mask is always u64
and dev_max_pfn is supposed to be returning the pfn of the dma_mask, it
should unconditionally be 64 bits as well.  Either that or it should
return dma_addr_t.

James

^ permalink raw reply

* [PATCH v3 00/13] pinctrl: mvebu: restructure resource allocation
From: Thomas Petazzoni @ 2014-02-13 16:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FCF59E.3090100@gmail.com>

Dear Sebastian Hesselbarth,

On Thu, 13 Feb 2014 17:41:02 +0100, Sebastian Hesselbarth wrote:

> > Thanks again for working on this! I have boot tested this successfully
> > on an Armada XP platform, and it seems to behave normally, the debugfs
> > pinctrl contents make sense.
> 
> I guess this is a Tested-by ?

Yes. My tests were admittedly fairly light, but I believe good enough :)

> > I am not sure what you mean here in terms of the ordering for the
> > patches. I'm attaching several patches, and the first three patches
> > adapt your patch series to also cover 375 and 38x, assuming the pinctrl
> > support for 375 and 38x is merged before your patch series.
> 
> Right. If 375/38x pinctrl goes in first (what I expect), I'd have to add
> corresponding patches. You already sent them, I'll pick them up.

Ok, cool. Hopefully we can sort out the merging of those two patch
series for 3.15 with Linus Walleij.

> > I must say I dislike quite a bit this unnamed mpp controls mechanism.
> > Why isn't the name statically defined in the source code by the
> > MPP_MODE macro, which already takes as first argument the pin number?
> 
> Honestly, the unnamed mpp control thing is a bit odd. But if you tell
> me how to create ~60 statically defined one pin groups out of a
> single-line macro, we can change that easily.
> 
> Back when that unnamed mpp control thing was invented, I must have been
> to lazy to write e.g.
> 
> MPP_FUNC_CTRL(0, 0, "mpp0", armada_xp_mpp_ctrl),
> MPP_FUNC_CTRL(1, 1, "mpp1", armada_xp_mpp_ctrl),
> MPP_FUNC_CTRL(2, 2, "mpp2", armada_xp_mpp_ctrl),
> ...
> MPP_FUNC_CTRL(66, 66, "mpp66", armada_xp_mpp_ctrl),
> 
> instead of
> 
> MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
> 
> and generate the 66 names dynamically.

Right. But what I meant is that we already have a place where we have
one macro call for each pin: when defining the MPP modes. So I was
thinking of simplifying the whole stuff by "merging" the notion of MPP
control with the notion of MPP mode. This way, when you do:

	MPP_MODE(0,
		   MPP_FUNCTION(...),
		   MPP_FUNCTION(...)),
	MPP_MODE(1,
		   MPP_FUNCTION(...),
		   MPP_FUNCTION(...)),
	MPP_MODE(2,
		   MPP_FUNCTION(...),
		   MPP_FUNCTION(...)),
[...]
	MPP_MODE(65,
		   MPP_FUNCTION(...),
		   MPP_FUNCTION(...)),

You can take this opportunity to generate:

	{ "mpp0", ... },
	{ "mpp1", ... },
	{ "mpp2", ... },
	...
	{ "mpp65", ... },

> > This is definitely good, but I'm wondering why the core cannot provide
> > helper functions for the generic case where we have 4 bits per pin in
> > contiguous registers. This would avoid duplicating the helper function
> > six times (you have four in your patch series, and we'll need two more
> > for A375 and A38x).
> 
> I thought about it too, but we would need a soc specific callback
> anyway as you'll have to pass the base address somehow (and that is now
> known by soc specific stub only). My quick rule of thumb was that the
> amount of code replication would be almost the same.

In pinctrl-mvebu.h, we could have:

static inline int default_mpp_ctrl_get(void __iomem *base, unsigned int pid, unsigned long *config)
{
        unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
        unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;

        *config = (readl(base + off) >> shift) & MVEBU_MPP_MASK;

        return 0;
}

static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid, unsigned long config)
{
        unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
        unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
        unsigned long reg;

        reg = readl(base + off) & ~(MVEBU_MPP_MASK << shift);
        writel(reg | (config << shift), base + off);

        return 0;
}

which would slightly reduce the per-SoC code to:

static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
	return default_mpp_ctrl_get(mpp_base, pid, config);
}

static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config)
{
	return default_mpp_ctrl_set(mpp_base, pid, config);
}

but we admittedly cannot completely remove the per-SoC function, since
the mpp_base is now only known to each per-SoC driver.

> > Feel free to squash these patches into the appropriate patches.
> 
> Yep, thanks for these! I'll squash them in and send an updated v4 as
> soon as the discussion here stalls.

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH] perf: ARM64: wire up perf_regs and unwind support
From: Jean Pihet @ 2014-02-13 17:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212130938.GA7624@krava.brq.redhat.com>

Hi Jiri,


On 12 February 2014 14:09, Jiri Olsa <jolsa@redhat.com> wrote:
> On Mon, Feb 03, 2014 at 07:17:07PM +0100, Jean Pihet wrote:
>> This patch hooks in the perf_regs and libunwind code for ARM64.
>> The tools/perf/arch/arm64 is created; it contains the arch specific
>> code for DWARF unwinding.
>>
>> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
>> Acked-by: Will Deacon <will.deacon@arm.com>
>
> SNIP
>
>> + */
>> +const char *get_arch_regstr(unsigned int n)
>> +{
>> +     const struct pt_regs_dwarfnum *roff;
>> +     for (roff = regdwarfnum_table; roff->name != NULL; roff++)
>> +             if (roff->dwarfnum == n)
>> +                     return roff->name;
>> +     return NULL;
>> +}
>> diff --git a/tools/perf/arch/arm64/util/unwind.c b/tools/perf/arch/arm64/util/unwind.c
>> new file mode 100644
>> index 0000000..8d37a4c
>> --- /dev/null
>> +++ b/tools/perf/arch/arm64/util/unwind.c
>> @@ -0,0 +1,82 @@
>> +
>> +#include <errno.h>
>> +#include <libunwind.h>
>> +#include "perf_regs.h"
>> +#include "../../util/unwind.h"
>> +
>> +int unwind__arch_reg_id(int regnum)
>
>
> I think this ^^^ wouldn't compile over acme/perf/core, bacause of
> the recent code changes for the libdw unwind:
>
> 1d86598 perf callchain: Rename unwind__arch_reg_id into libunwind__arch_reg_id
That is correct, the patch is for mainline.
Re-sending a rebased version on acme/perf/core in a bit.

> jirka

Thanks,
Jean

^ permalink raw reply

* [PATCH 5/5] iommu/arm-smmu: fix compilation issue when !CONFIG_ARM_AMBA
From: Will Deacon @ 2014-02-13 17:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOZdJXW6tY=MjHGMa1EQtJayY=ToqiJOWsggCsEjfPzirUeUxg@mail.gmail.com>

On Thu, Feb 13, 2014 at 04:55:25PM +0000, Timur Tabi wrote:
> On Thu, Feb 6, 2014 at 12:09 PM, Will Deacon <will.deacon@arm.com> wrote:
> 
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > index 0ae4dd39197f..6fe7922ecc1d 100644
> > --- a/drivers/iommu/arm-smmu.c
> > +++ b/drivers/iommu/arm-smmu.c
> > @@ -2004,8 +2004,10 @@ static int __init arm_smmu_init(void)
> >         if (!iommu_present(&platform_bus_type))
> >                 bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
> >
> > +#ifdef CONFIG_ARM_AMBA
> >         if (!iommu_present(&amba_bustype))
> >                 bus_set_iommu(&amba_bustype, &arm_smmu_ops);
> > +#endif
> 
> So I admit I don't know much about the ARM kernel (yet), but doesn't
> this break multi-arch?  That is, we can't support one binary that runs
> on a processor with AMBA and one without?

Huh?

It's harmless to enable CONFIG_ARM_AMBA, even if you don't have any AMBA
devices in your SoC, it just makes your binary a bit bigger because you're
compiling in code that you don't need. Instead, you might elect to set
CONFIG_ARM_AMBA=n, at which point the arm-smmu driver will fail to build
without this patch.

Will

^ permalink raw reply

* [PATCH] perf: ARM64: wire up perf_regs and unwind support
From: Jean Pihet @ 2014-02-13 17:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch hooks in the perf_regs and libunwind code for ARM64.
The tools/perf/arch/arm64 is created; it contains the arch specific
code for DWARF unwinding.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
---
 tools/perf/arch/arm64/Makefile                |  7 +++
 tools/perf/arch/arm64/include/perf_regs.h     | 88 +++++++++++++++++++++++++++
 tools/perf/arch/arm64/util/dwarf-regs.c       | 80 ++++++++++++++++++++++++
 tools/perf/arch/arm64/util/unwind-libunwind.c | 82 +++++++++++++++++++++++++
 tools/perf/config/Makefile                    |  8 ++-
 5 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/arch/arm64/Makefile
 create mode 100644 tools/perf/arch/arm64/include/perf_regs.h
 create mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c
 create mode 100644 tools/perf/arch/arm64/util/unwind-libunwind.c

diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
new file mode 100644
index 0000000..67e9b3d
--- /dev/null
+++ b/tools/perf/arch/arm64/Makefile
@@ -0,0 +1,7 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
+ifndef NO_LIBUNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o
+endif
diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h
new file mode 100644
index 0000000..2359546
--- /dev/null
+++ b/tools/perf/arch/arm64/include/perf_regs.h
@@ -0,0 +1,88 @@
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include "../../util/types.h"
+#include <asm/perf_regs.h>
+
+#define PERF_REGS_MASK	((1ULL << PERF_REG_ARM64_MAX) - 1)
+#define PERF_REG_IP	PERF_REG_ARM64_PC
+#define PERF_REG_SP	PERF_REG_ARM64_SP
+
+static inline const char *perf_reg_name(int id)
+{
+	switch (id) {
+	case PERF_REG_ARM64_X0:
+		return "x0";
+	case PERF_REG_ARM64_X1:
+		return "x1";
+	case PERF_REG_ARM64_X2:
+		return "x2";
+	case PERF_REG_ARM64_X3:
+		return "x3";
+	case PERF_REG_ARM64_X4:
+		return "x4";
+	case PERF_REG_ARM64_X5:
+		return "x5";
+	case PERF_REG_ARM64_X6:
+		return "x6";
+	case PERF_REG_ARM64_X7:
+		return "x7";
+	case PERF_REG_ARM64_X8:
+		return "x8";
+	case PERF_REG_ARM64_X9:
+		return "x9";
+	case PERF_REG_ARM64_X10:
+		return "x10";
+	case PERF_REG_ARM64_X11:
+		return "x11";
+	case PERF_REG_ARM64_X12:
+		return "x12";
+	case PERF_REG_ARM64_X13:
+		return "x13";
+	case PERF_REG_ARM64_X14:
+		return "x14";
+	case PERF_REG_ARM64_X15:
+		return "x15";
+	case PERF_REG_ARM64_X16:
+		return "x16";
+	case PERF_REG_ARM64_X17:
+		return "x17";
+	case PERF_REG_ARM64_X18:
+		return "x18";
+	case PERF_REG_ARM64_X19:
+		return "x19";
+	case PERF_REG_ARM64_X20:
+		return "x20";
+	case PERF_REG_ARM64_X21:
+		return "x21";
+	case PERF_REG_ARM64_X22:
+		return "x22";
+	case PERF_REG_ARM64_X23:
+		return "x23";
+	case PERF_REG_ARM64_X24:
+		return "x24";
+	case PERF_REG_ARM64_X25:
+		return "x25";
+	case PERF_REG_ARM64_X26:
+		return "x26";
+	case PERF_REG_ARM64_X27:
+		return "x27";
+	case PERF_REG_ARM64_X28:
+		return "x28";
+	case PERF_REG_ARM64_X29:
+		return "x29";
+	case PERF_REG_ARM64_SP:
+		return "sp";
+	case PERF_REG_ARM64_LR:
+		return "lr";
+	case PERF_REG_ARM64_PC:
+		return "pc";
+	default:
+		return NULL;
+	}
+
+	return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
new file mode 100644
index 0000000..d49efeb
--- /dev/null
+++ b/tools/perf/arch/arm64/util/dwarf-regs.c
@@ -0,0 +1,80 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Will Deacon, ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stddef.h>
+#include <dwarf-regs.h>
+
+struct pt_regs_dwarfnum {
+	const char *name;
+	unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+	{.name = STR(%x##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+	GPR_DWARFNUM_NAME(0),
+	GPR_DWARFNUM_NAME(1),
+	GPR_DWARFNUM_NAME(2),
+	GPR_DWARFNUM_NAME(3),
+	GPR_DWARFNUM_NAME(4),
+	GPR_DWARFNUM_NAME(5),
+	GPR_DWARFNUM_NAME(6),
+	GPR_DWARFNUM_NAME(7),
+	GPR_DWARFNUM_NAME(8),
+	GPR_DWARFNUM_NAME(9),
+	GPR_DWARFNUM_NAME(10),
+	GPR_DWARFNUM_NAME(11),
+	GPR_DWARFNUM_NAME(12),
+	GPR_DWARFNUM_NAME(13),
+	GPR_DWARFNUM_NAME(14),
+	GPR_DWARFNUM_NAME(15),
+	GPR_DWARFNUM_NAME(16),
+	GPR_DWARFNUM_NAME(17),
+	GPR_DWARFNUM_NAME(18),
+	GPR_DWARFNUM_NAME(19),
+	GPR_DWARFNUM_NAME(20),
+	GPR_DWARFNUM_NAME(21),
+	GPR_DWARFNUM_NAME(22),
+	GPR_DWARFNUM_NAME(23),
+	GPR_DWARFNUM_NAME(24),
+	GPR_DWARFNUM_NAME(25),
+	GPR_DWARFNUM_NAME(26),
+	GPR_DWARFNUM_NAME(27),
+	GPR_DWARFNUM_NAME(28),
+	GPR_DWARFNUM_NAME(29),
+	REG_DWARFNUM_NAME("%lr", 30),
+	REG_DWARFNUM_NAME("%sp", 31),
+	REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n:	the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+	const struct pt_regs_dwarfnum *roff;
+	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+		if (roff->dwarfnum == n)
+			return roff->name;
+	return NULL;
+}
diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c
new file mode 100644
index 0000000..436ee43
--- /dev/null
+++ b/tools/perf/arch/arm64/util/unwind-libunwind.c
@@ -0,0 +1,82 @@
+
+#include <errno.h>
+#include <libunwind.h>
+#include "perf_regs.h"
+#include "../../util/unwind.h"
+
+int libunwind__arch_reg_id(int regnum)
+{
+	switch (regnum) {
+	case UNW_AARCH64_X0:
+		return PERF_REG_ARM64_X0;
+	case UNW_AARCH64_X1:
+		return PERF_REG_ARM64_X1;
+	case UNW_AARCH64_X2:
+		return PERF_REG_ARM64_X2;
+	case UNW_AARCH64_X3:
+		return PERF_REG_ARM64_X3;
+	case UNW_AARCH64_X4:
+		return PERF_REG_ARM64_X4;
+	case UNW_AARCH64_X5:
+		return PERF_REG_ARM64_X5;
+	case UNW_AARCH64_X6:
+		return PERF_REG_ARM64_X6;
+	case UNW_AARCH64_X7:
+		return PERF_REG_ARM64_X7;
+	case UNW_AARCH64_X8:
+		return PERF_REG_ARM64_X8;
+	case UNW_AARCH64_X9:
+		return PERF_REG_ARM64_X9;
+	case UNW_AARCH64_X10:
+		return PERF_REG_ARM64_X10;
+	case UNW_AARCH64_X11:
+		return PERF_REG_ARM64_X11;
+	case UNW_AARCH64_X12:
+		return PERF_REG_ARM64_X12;
+	case UNW_AARCH64_X13:
+		return PERF_REG_ARM64_X13;
+	case UNW_AARCH64_X14:
+		return PERF_REG_ARM64_X14;
+	case UNW_AARCH64_X15:
+		return PERF_REG_ARM64_X15;
+	case UNW_AARCH64_X16:
+		return PERF_REG_ARM64_X16;
+	case UNW_AARCH64_X17:
+		return PERF_REG_ARM64_X17;
+	case UNW_AARCH64_X18:
+		return PERF_REG_ARM64_X18;
+	case UNW_AARCH64_X19:
+		return PERF_REG_ARM64_X19;
+	case UNW_AARCH64_X20:
+		return PERF_REG_ARM64_X20;
+	case UNW_AARCH64_X21:
+		return PERF_REG_ARM64_X21;
+	case UNW_AARCH64_X22:
+		return PERF_REG_ARM64_X22;
+	case UNW_AARCH64_X23:
+		return PERF_REG_ARM64_X23;
+	case UNW_AARCH64_X24:
+		return PERF_REG_ARM64_X24;
+	case UNW_AARCH64_X25:
+		return PERF_REG_ARM64_X25;
+	case UNW_AARCH64_X26:
+		return PERF_REG_ARM64_X26;
+	case UNW_AARCH64_X27:
+		return PERF_REG_ARM64_X27;
+	case UNW_AARCH64_X28:
+		return PERF_REG_ARM64_X28;
+	case UNW_AARCH64_X29:
+		return PERF_REG_ARM64_X29;
+	case UNW_AARCH64_X30:
+		return PERF_REG_ARM64_LR;
+	case UNW_AARCH64_SP:
+		return PERF_REG_ARM64_SP;
+	case UNW_AARCH64_PC:
+		return PERF_REG_ARM64_PC;
+	default:
+		pr_err("unwind: invalid reg id %d\n", regnum);
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 1686583..2e3a19e 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -29,11 +29,17 @@ ifeq ($(ARCH),x86)
   endif
   NO_PERF_REGS := 0
 endif
+
 ifeq ($(ARCH),arm)
   NO_PERF_REGS := 0
   LIBUNWIND_LIBS = -lunwind -lunwind-arm
 endif
 
+ifeq ($(ARCH),arm64)
+  NO_PERF_REGS := 0
+  LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
+endif
+
 ifeq ($(LIBUNWIND_LIBS),)
   NO_LIBUNWIND := 1
 else
@@ -327,7 +333,7 @@ ifndef NO_LIBUNWIND
     msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
     NO_LIBUNWIND := 1
   else
-    ifeq ($(ARCH),arm)
+    ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
       $(call feature_check,libunwind-debug-frame)
       ifneq ($(feature-libunwind-debug-frame), 1)
         msg := $(warning No debug_frame support found in libunwind);
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v3 00/13] pinctrl: mvebu: restructure resource allocation
From: Sebastian Hesselbarth @ 2014-02-13 17:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213175914.205803a6@skate>

On 02/13/14 17:59, Thomas Petazzoni wrote:
> On Thu, 13 Feb 2014 17:41:02 +0100, Sebastian Hesselbarth wrote:
>>> Thanks again for working on this! I have boot tested this successfully
>>> on an Armada XP platform, and it seems to behave normally, the debugfs
>>> pinctrl contents make sense.
>>
>> I guess this is a Tested-by ?
>
> Yes. My tests were admittedly fairly light, but I believe good enough :)

Ok.

>>> I am not sure what you mean here in terms of the ordering for the
>>> patches. I'm attaching several patches, and the first three patches
>>> adapt your patch series to also cover 375 and 38x, assuming the pinctrl
>>> support for 375 and 38x is merged before your patch series.
>>
>> Right. If 375/38x pinctrl goes in first (what I expect), I'd have to add
>> corresponding patches. You already sent them, I'll pick them up.
>
> Ok, cool. Hopefully we can sort out the merging of those two patch
> series for 3.15 with Linus Walleij.

That is the plan - or rather get his Acked-by as we are lucky to have
pinctrl/mvebu and touching nothing else.

>>> I must say I dislike quite a bit this unnamed mpp controls mechanism.
>>> Why isn't the name statically defined in the source code by the
>>> MPP_MODE macro, which already takes as first argument the pin number?
>>
>> Honestly, the unnamed mpp control thing is a bit odd. But if you tell
>> me how to create ~60 statically defined one pin groups out of a
>> single-line macro, we can change that easily.
>>
>> Back when that unnamed mpp control thing was invented, I must have been
>> to lazy to write e.g.
>>
>> MPP_FUNC_CTRL(0, 0, "mpp0", armada_xp_mpp_ctrl),
>> MPP_FUNC_CTRL(1, 1, "mpp1", armada_xp_mpp_ctrl),
>> MPP_FUNC_CTRL(2, 2, "mpp2", armada_xp_mpp_ctrl),
>> ...
>> MPP_FUNC_CTRL(66, 66, "mpp66", armada_xp_mpp_ctrl),
>>
>> instead of
>>
>> MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
>>
>> and generate the 66 names dynamically.
>
> Right. But what I meant is that we already have a place where we have
> one macro call for each pin: when defining the MPP modes. So I was
> thinking of simplifying the whole stuff by "merging" the notion of MPP
> control with the notion of MPP mode. This way, when you do:
>
> 	MPP_MODE(0,
> 		   MPP_FUNCTION(...),
> 		   MPP_FUNCTION(...)),
> 	MPP_MODE(1,
> 		   MPP_FUNCTION(...),
> 		   MPP_FUNCTION(...)),
> 	MPP_MODE(2,
> 		   MPP_FUNCTION(...),
> 		   MPP_FUNCTION(...)),
> [...]
> 	MPP_MODE(65,
> 		   MPP_FUNCTION(...),
> 		   MPP_FUNCTION(...)),
>
> You can take this opportunity to generate:
>
> 	{ "mpp0", ... },
> 	{ "mpp1", ... },
> 	{ "mpp2", ... },
> 	...
> 	{ "mpp65", ... },

Ah, ok, I see. Yes that should be doable. We should definitely consider
this for later, i.e. leave it now as is and rework later.

>>> This is definitely good, but I'm wondering why the core cannot provide
>>> helper functions for the generic case where we have 4 bits per pin in
>>> contiguous registers. This would avoid duplicating the helper function
>>> six times (you have four in your patch series, and we'll need two more
>>> for A375 and A38x).
>>
>> I thought about it too, but we would need a soc specific callback
>> anyway as you'll have to pass the base address somehow (and that is now
>> known by soc specific stub only). My quick rule of thumb was that the
>> amount of code replication would be almost the same.
>
> In pinctrl-mvebu.h, we could have:
>
> static inline int default_mpp_ctrl_get(void __iomem *base, unsigned int pid, unsigned long *config)
> {
>          unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
>          unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
>
>          *config = (readl(base + off) >> shift) & MVEBU_MPP_MASK;
>
>          return 0;
> }
>
> static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid, unsigned long config)
> {
>          unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
>          unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
>          unsigned long reg;
>
>          reg = readl(base + off) & ~(MVEBU_MPP_MASK << shift);
>          writel(reg | (config << shift), base + off);
>
>          return 0;
> }
>
> which would slightly reduce the per-SoC code to:
>
> static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config)
> {
> 	return default_mpp_ctrl_get(mpp_base, pid, config);
> }
>
> static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config)
> {
> 	return default_mpp_ctrl_set(mpp_base, pid, config);
> }
>
> but we admittedly cannot completely remove the per-SoC function, since
> the mpp_base is now only known to each per-SoC driver.

I guess I'll squash the above in for v4.. doesn't look that bad.

Sebastian

^ permalink raw reply

* [PATCH] Fix uses of dma_max_pfn() when converting to a limiting address
From: Russell King - ARM Linux @ 2014-02-13 17:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392310690.2175.13.camel@dabdike.int.hansenpartnership.com>

On Thu, Feb 13, 2014 at 08:58:10AM -0800, James Bottomley wrote:
> This doesn't really look like the right fix.  You replaced dev->dma_mask
> with a calculation on dev_max_pfn().  Since dev->dma_mask is always u64
> and dev_max_pfn is supposed to be returning the pfn of the dma_mask, it
> should unconditionally be 64 bits as well.  Either that or it should
> return dma_addr_t.

My reasoning is that PFNs in the system are always of type "unsigned long"
and therefore a function returning a pfn should have that type.  If we
overflow a PFN fitting in an unsigned long, we have lots of places which
need fixing.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH 5/5] iommu/arm-smmu: fix compilation issue when !CONFIG_ARM_AMBA
From: Timur Tabi @ 2014-02-13 17:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213170408.GM13576@mudshark.cambridge.arm.com>

On 02/13/2014 11:04 AM, Will Deacon wrote:

> It's harmless to enable CONFIG_ARM_AMBA, even if you don't have any AMBA
> devices in your SoC,

Ah, ok.  It's seems obvious now, but somehow that didn't click.

> it just makes your binary a bit bigger because you're
> compiling in code that you don't need. Instead, you might elect to set
> CONFIG_ARM_AMBA=n, at which point the arm-smmu driver will fail to build
> without this patch.

Ok, thanks.  We discovered the same problem internally, and had the same 
solution, but during code reviews some concerns were raised.

^ permalink raw reply

* [PATCH v2] ARM: mm: report both sections from PMD
From: Catalin Marinas @ 2014-02-13 17:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212224638.GA4558@www.outflux.net>

On Wed, Feb 12, 2014 at 10:46:38PM +0000, Kees Cook wrote:
> diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
> index 03243f7eeddf..fb3de59ee811 100644
> --- a/arch/arm/include/asm/pgtable-3level.h
> +++ b/arch/arm/include/asm/pgtable-3level.h
> @@ -138,10 +138,6 @@
>  #define pud_none(pud)		(!pud_val(pud))
>  #define pud_bad(pud)		(!(pud_val(pud) & 2))
>  #define pud_present(pud)	(pud_val(pud))
> -#define pmd_table(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
> -						 PMD_TYPE_TABLE)
> -#define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
> -						 PMD_TYPE_SECT)
>  #define pmd_large(pmd)		pmd_sect(pmd)
>  
>  #define pud_clear(pudp)			\
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index 7d59b524f2af..934aa5b60c7c 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -183,6 +183,10 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
>  
>  #define pmd_none(pmd)		(!pmd_val(pmd))
>  #define pmd_present(pmd)	(pmd_val(pmd))
> +#define pmd_table(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
> +						 PMD_TYPE_TABLE)
> +#define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
> +						 PMD_TYPE_SECT)

Do you still need to move these two if you only use pmd_large()? AFAICT,
it is equivalent to pmd_sect().

>  static inline pte_t *pmd_page_vaddr(pmd_t pmd)
>  {
> diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
> index 2b342177f5de..32635b474832 100644
> --- a/arch/arm/mm/dump.c
> +++ b/arch/arm/mm/dump.c
> @@ -260,8 +260,14 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
>  
>  	for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
>  		addr = start + i * PMD_SIZE;
> -		if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
> +		if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd)) {
>  			note_page(st, addr, 3, pmd_val(*pmd));
> +			if (SECTION_SIZE < PMD_SIZE &&
> +			    pmd_sect(*pmd) && pmd_sect(pmd[1])) {

I think the first patch was better with pmd[0] and pmd[1] treated
independently if SECTION_SIZE < PMD_SIZE, only that it should have
checked for pmd_sect(pmd[1]). I don't see anything in
__map_init_section() that would prevent populating only the second pmd
leaving the first one empty.

-- 
Catalin

^ permalink raw reply

* [PATCH 00/26] OMAP dma engine rework
From: Tony Lindgren @ 2014-02-13 17:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210155531.GB26684@n2100.arm.linux.org.uk>

* Russell King - ARM Linux <linux@arm.linux.org.uk> [140210 07:58]:
> This is the current set of patches for the OMAP DMA engine rework,
> which should now work correctly on OMAP1 platforms thanks to Tony's
> testing.
> 
> It would be good to get this validated by others across a range of
> OMAP platforms, and queued up for the next merge window, so it can
> be built upon.
> 
> Acks appreciated, and once sufficient have been added, I'll send a
> pull request for this to Vinod.

Looks good to me and should not conflict with other patches
that I'm aware of. Please feel free to add:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply

* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Olof Johansson @ 2014-02-13 17:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1626419.Ta3A7zgHIt@wuerfel>

On Thu, Feb 13, 2014 at 05:13:14PM +0100, Arnd Bergmann wrote:
> On Thursday 13 February 2014 14:41:06 Russell King - ARM Linux wrote:
> > On Thu, Feb 13, 2014 at 01:48:55PM +0100, Arnd Bergmann wrote:
> > > On Thursday 13 February 2014 10:42:48 Russell King - ARM Linux wrote:
> > > > 
> > > > What if we have a platform where things subtly change, like for instance,
> > > > the wiring on the SD slot to fix a problem with UHS-1 cards, which means
> > > > you don't have UHS-1 support for some platforms but do for others.
> > > > 
> > > > What if you have a platform which uses a brcm4329 chip for Wifi, but then
> > > > later in the production run switch to using a different Wifi chipset?
> > > 
> > > As far as I can tell, the power sequencing is normally really
> > > dependent on the device. If someone has an on-board brcm4329
> > > that requires a specific set of clocks, resets, voltages etc
> > > to be routed to the chip and enabled in the correct order to
> > > allow probing, it seems unlikely that changing the wifi chipset
> > > to something else would keep the exact same requirements.
> > 
> > That's your assertion - however, do we /know/ whether there's a situation
> > where Olof's solution doesn't work because the sequencing is wrong?
> > 
> > I see nothing unreasonable about the sequence:
> > 
> > 1. hold reset at low level
> > 2. apply power
> > 3. turn clock on
> > 4. apply reset
> > 5. release reset
> 
> I was thinking of cases where you may need a more complex sequence:
> - wait for a device specific time between some of the steps
>   (the cw1200 driver seems to need that, but we could probably
>    get away with waiting long enough for everyone)
> - have more than one of each, and turn them on in the right order.
>   cw1200 seems to need two voltages, two gpio resets ("reset"
>   and "powerup").

Those two gpio resets are extremely common, but on snow (the chromebook) the
powerup gpio is hard-wired. So it's not all that unusual. As I mention in the
patch, a positive-sense powerup and a negative-sense reset aren't all that
different in practice.

>   Again, we could specify a larger number of clocks that can be
>   provided to the host, but if we make it a device specific
>   property, we already know how many we need.
> 
> I can't think of anything that would require significant changes
> to the procedure though, just refinements as we run into problems.

The main pain will be if there's a requirement to do
gpio-requlator-gpio-regulator. We could mandate that regulators are turned on
in order. (Also, see below).

> 
> > The points being:
> > * never set a signal to a high level before power is applied, otherwise
> >   we can end up supplying power through that signal (which may cause
> >   damage.)  That goes for the reset and clock.
> > * devices normally want clocks running to complete their reset sequencing.
> > 
> > This is actually the sequence which MMC/SD cards do (except without the
> > reset) anyway - it's spec'd that on the MMC/SD bus, power will be applied
> > and will be stable before the clock signal is applied, and then the clock
> > signal runs for a certain number of cycles before you even start talking
> > to the card.
> 
> It may be dangerous to refer to the spec, since we are talking
> specifically about devices that require something beyond what the
> spec says ;-) For instance in SD/MMC cards I'd assume the device clock
> to be derived from the bus clock. However we can expect that clock
> to work already (any working mmc host driver would provide that),
> but we may need to drive the device clock. It still sounds reasonable
> to assume that the sequencing is the same as for the bus clock.
> 
> > That all said, we do have the problem that once we decide, we need to
> > support it because it becomes part of DT - this is one of the things I
> > hate about DT, it requires over-design.
> 
> Yes, I agree. It is a problem that we have to face all the time.
> We have in the past defined bindings of both types, overdesigned
> and not thought through enough.
> 
> >  Your point is "Olof's solution
> > may break if we have a device which requires a different sequence" which
> > is a valid point which has to be considered from the DT perspective and
> > addressed whether or not we actually have a device which meets that
> > criteria.  I don't see an easy solution to this.
> 
> I think either one will work. With Olof's suggestion that may mean we
> have to keep adding support for increasingly complex cases when we
> run into them, or it may all be easy. With my suggestion, we give
> more room for function drivers to mess things up, but at least we
> can keep the complexity in the places that need them and only need
> to change the core once.

I always anticipated the binding needing amendment over time -- for example if
a device needs longer delays between clock enable and reset release. But most
of those can be handled through bindings amendments as needed (with default
behavior for non-amended bindings the same as today).

Chances are that if we do a per-device binding, we'll likely end up having
shared helpers to parse the settings anyway, so in the end we end up with
similar code, and similar bind maybe subtly different bindings. I suspect
sharing one common binding and common code will be easier long-term but it's
not a black and white choice.

> Aside from the power-on problem, my suggestion would at the same
> time solve the second problem of having a place to stick arbitrary
> DT properties for the sdio function. Again looking at the cw1200
> example, they may require passing an IRQ descriptor, a MAC address,
> the device clock rate, and two flags for things that are not
> detectable by looking at the device ID (whether a 5GHz antenna is
> connected and something about odd block size transfers).
> This is probably the main difference between the two approaches.

So, we do have the option of making the mmc binding take a device subnode
that gets passed in as the of_node when binding the device, and we can
move the power/reset/clock data there even if we don't leave it up to
the card driver to handle and act upon it. It would give us a place to
locate per-device properties like these, but it wouldn't greatly affect
how the rest of the solution looks.


-Olof

^ permalink raw reply

* [PATCH v4 00/13] CPU idle for Armada XP
From: Gregory CLEMENT @ 2014-02-13 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch set adds the CPU idle support for Armada XP and prepares
the support for Armada 370. This was based on the work of Nadav
Haklai.

There were many changes done, see the changelog for the details. I
should have managed to comply with all the reviewer wishes.

Most of the patches modify the mvebu code in order to prepare the
support for CPU idle, hence the patches 2 to 6 and from 8 to 11 should
go to mvebu subsystem (and then arm-soc).

The first patch should go through ARM subsystem and should be taken by
Russell King. As I didn't receive any comment against this patch, I
planed to submit to Russell's patch system.

The 7th patch should also go to mvebu subsystem (and then arm-soc) but
it would be nice to have an Acked-by from on of the device tree
maintainer.

The 12th patch 'cpuidle: mvebu: Add initial cpu idle support for
Armada 370/XP SoC' is the only one who should go to the cpuidle
subsystem. But of course I would like that Daniel Lezcano or Rafael
J. Wysocki have a look on the whole series.

The 13th patch should go to mvebu subsystem.

The whole series is also available in the branch CPU-idle-ArmadaXP-v4
at https://github.com/MISL-EBU-System-SW/mainline-public.git

Thanks,

Changelog:
v3 -> v4:

* factorized the code in coherency_ll.S and make it autodetect as mush
  as possible

* reordered the introduction of the device tree binding

* removed all the EXPORT_SYMBOL_GPL as the driver can only be built
  into the kernel and never be built as a module.

* moved the armada_370_xp_pmsu_enable_l2_powerdown_onidle function in
  armada_370_cp.c file during the initialization of the platform.

* fixed various coding style issue and typos pointed by Thomas

* fixed all the coding issue style, made the comments more coherent
  and add more comment in the suspend-armada-370-xp.S file.

* moved all the device tree related check from
  armada_370_xp_cpuidle_probe to armada_370_xp_dt_init.

* used cpu_pm_enter() instead of directly calling platform code in
  Armada_370_xp_enter_idle.

* convert the sequence to disable the coherency to the one used in
  TC2.

* Rebased on v3.14-rc1

v2 -> v3:

* Converted the driver to use module_platform_driver. This lead to the
  introduction of a new patch (PATCH 11). Pointed by Daniel Lezcano.

* Used PUIDLE_DRIVER_FLAGS_MASK to store the deep idle information,
  suggested by Daniel Lezcano.

* Removed cpu_init call from armada_370_xp_enter_idle
  function. Pointed by Lorenzo Pieralisi.

* Rebased on v3.12-rc5


v1 -> v2:

* Removed the pm_level kernel parameter. As Kevin Hilman pointed, its
  usage can be replaced by using
  /sys/devices/system/cpu/cpu*/cpuidle/state*/disable or the kernel
  parameter cpuidle.off.

* Used BIT() macro (reported by Ezequiel)

* Made the function more readable the
  armada_370_xp_pmsu_idle_prepare() function (reported by Thomas)

* Moved the config entry in Kconfig.arm, and rename the config symbol
  according the pattern used by other arm cpu: ARM_"soc name"_CPUIDLE

* Moved the build rule under the new ARM SoC section in the Makefile

* Rebased on Linus Torvalds master branch of Thursday September 12

Gregory CLEMENT (13):
  ARM: PJ4B: Add cpu_suspend/cpu_resume hooks for PJ4B
  ARM: mvebu: remove the address parameter for ll_set_cpu_coherent
  ARM: mvebu: ll_set_cpu_coherent always uses the current CPU
  ARM: mvebu: Remove the unused argument of set_cpu_coherent()
  ARM: mvebu: Low level function to disable HW coherency support
  ARM: mvebu: Add a new set of registers for pmsu
  ARM: dts: mvebu: Add a new set of registers to the PMSU node
  ARM: mvebu: Allow to power down L2 cache controller in idle mode
  ARM: mvebu: Add the PMSU related part of the cpu idle functions
  ARM: mvebu: Set the start address of a CPU in a separate function
  ARM: mvebu: Register notifier callback for the cpuidle transition
  cpuidle: mvebu: Add initial CPU idle support for Armada 370/XP SoC
  ARM: mvebu: register the cpuidle driver for the Armada XP SoCs

 .../devicetree/bindings/arm/armada-370-xp-pmsu.txt |  12 +-
 arch/arm/boot/dts/armada-xp.dtsi                   |   2 +-
 arch/arm/mach-mvebu/armada-370-xp.c                |  12 ++
 arch/arm/mach-mvebu/coherency.c                    |  12 +-
 arch/arm/mach-mvebu/coherency.h                    |   2 +-
 arch/arm/mach-mvebu/coherency_ll.S                 |  86 +++++++++---
 arch/arm/mach-mvebu/headsmp.S                      |  15 +--
 arch/arm/mach-mvebu/platsmp.c                      |   2 +-
 arch/arm/mach-mvebu/pmsu.c                         | 147 ++++++++++++++++++++-
 arch/arm/mach-mvebu/pmsu.h                         |   2 +
 arch/arm/mm/proc-v7.S                              |  64 ++++++++-
 drivers/cpuidle/Kconfig.arm                        |   5 +
 drivers/cpuidle/Makefile                           |   1 +
 drivers/cpuidle/cpuidle-armada-370-xp.c            | 120 +++++++++++++++++
 14 files changed, 427 insertions(+), 55 deletions(-)
 create mode 100644 drivers/cpuidle/cpuidle-armada-370-xp.c

-- 
1.8.1.2

^ permalink raw reply

* [PATCH v4 01/13] ARM: PJ4B: Add cpu_suspend/cpu_resume hooks for PJ4B
From: Gregory CLEMENT @ 2014-02-13 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392312816-17657-1-git-send-email-gregory.clement@free-electrons.com>

PJ4B needs extra instructions for suspend and resume, so instead of
using the armv7 version, this commit introduces specific versions for
PJ4B.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mm/proc-v7.S | 64 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 61 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index bd1781979a39..11117423a9b4 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -169,9 +169,67 @@ ENDPROC(cpu_pj4b_do_idle)
 	globl_equ	cpu_pj4b_do_idle,  	cpu_v7_do_idle
 #endif
 	globl_equ	cpu_pj4b_dcache_clean_area,	cpu_v7_dcache_clean_area
-	globl_equ	cpu_pj4b_do_suspend,	cpu_v7_do_suspend
-	globl_equ	cpu_pj4b_do_resume,	cpu_v7_do_resume
-	globl_equ	cpu_pj4b_suspend_size,	cpu_v7_suspend_size
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_pj4b_do_suspend)
+	stmfd	sp!, {r4 - r10, lr}
+	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
+	mrc	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
+	stmia	r0!, {r4 - r5}
+	mrc	p15, 1, r6, c15, c1, 0  @ save CP15 - extra features
+	mrc	p15, 1, r7, c15, c2, 0	@ save CP15 - Aux Func Modes Ctrl 0
+	mrc	p15, 1, r8, c15, c1, 2	@ save CP15 - Aux Debug Modes Ctrl 2
+	mrc	p15, 1, r9, c15, c1, 1  @ save CP15 - Aux Debug Modes Ctrl 1
+	mrc	p15, 0, r10, c9, c14, 0  @ save CP15 - PMC
+	stmia	r0!, {r6 - r10}
+	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
+	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1
+	mrc	p15, 0, r11, c2, c0, 2	@ TTB control register
+	mrc	p15, 0, r8, c1, c0, 0	@ Control register
+	mrc	p15, 0, r9, c1, c0, 1	@ Auxiliary control register
+	mrc	p15, 0, r10, c1, c0, 2	@ Co-processor access control
+	stmia	r0, {r6 - r11}
+	ldmfd	sp!, {r4 - r10, pc}
+ENDPROC(cpu_pj4b_do_suspend)
+
+ENTRY(cpu_pj4b_do_resume)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
+	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
+	ldmia	r0!, {r4 - r5}
+	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
+	mcr	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
+	ldmia	r0!, {r6 - r10}
+	mcr	p15, 1, r6, c15, c1, 0  @ save CP15 - extra features
+	mcr	p15, 1, r7, c15, c2, 0	@ save CP15 - Aux Func Modes Ctrl 0
+	mcr	p15, 1, r8, c15, c1, 2	@ save CP15 - Aux Debug Modes Ctrl 2
+	mcr	p15, 1, r9, c15, c1, 1  @ save CP15 - Aux Debug Modes Ctrl 1
+	mcr	p15, 0, r10, c9, c14, 0  @ save CP15 - PMC
+	ldmia	r0, {r6 - r11}
+	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs
+	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
+#ifndef CONFIG_ARM_LPAE
+	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
+#endif
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB 0
+	mcr	p15, 0, r7, c2, c0, 1	@ TTB 1
+	mcr	p15, 0, r11, c2, c0, 2	@ TTB control register
+	ldr	r4, =PRRR		@ PRRR
+	ldr	r5, =NMRR		@ NMRR
+	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR
+	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR
+	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
+	teq	r4, r9			@ Is it already set?
+	mcrne	p15, 0, r9, c1, c0, 1	@ No, so write it
+	mcr	p15, 0, r10, c1, c0, 2	@ Co-processor access control
+	isb
+	dsb
+	mov	r0, r8			@ control register
+	b	cpu_resume_mmu
+ENDPROC(cpu_pj4b_do_resume)
+#endif
+.globl	cpu_pj4b_suspend_size
+.equ	cpu_pj4b_suspend_size, 4 * 13
 
 #endif
 
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v4 02/13] ARM: mvebu: remove the address parameter for ll_set_cpu_coherent
From: Gregory CLEMENT @ 2014-02-13 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392312816-17657-1-git-send-email-gregory.clement@free-electrons.com>

Until now the calling functions of ll_set_cpu_coherent() have to know
the base address of the coherency registers. This commit doesn't
expose anymore this address. This was needed to be able to use either
a virtual or a physical address. This patch add a check of the MMU bit
to choose the accurate address, then the calling function do have pass
this information.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/coherency.c    |  6 +++---
 arch/arm/mach-mvebu/coherency_ll.S | 22 ++++++++++++++++++++--
 arch/arm/mach-mvebu/headsmp.S      |  9 ---------
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 4e9d58148ca7..88dd507221fc 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -30,7 +30,7 @@
 #include "coherency.h"
 
 unsigned long coherency_phys_base;
-static void __iomem *coherency_base;
+void __iomem *coherency_base;
 static void __iomem *coherency_cpu_base;
 
 /* Coherency fabric registers */
@@ -44,7 +44,7 @@ static struct of_device_id of_coherency_table[] = {
 };
 
 /* Function defined in coherency_ll.S */
-int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);
+int ll_set_cpu_coherent(unsigned int hw_cpu_id);
 
 int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
 {
@@ -54,7 +54,7 @@ int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
 		return 1;
 	}
 
-	return ll_set_cpu_coherent(coherency_base, hw_cpu_id);
+	return ll_set_cpu_coherent(hw_cpu_id);
 }
 
 static inline void mvebu_hwcc_sync_io_barrier(void)
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index ee7598fe75db..1f2bcd4b5424 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -21,13 +21,27 @@
 #define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
 
 #include <asm/assembler.h>
+#include <asm/cp15.h>
 
 	.text
 /*
- * r0: Coherency fabric base register address
- * r1: HW CPU id
+ * r0: HW CPU id
  */
 ENTRY(ll_set_cpu_coherent)
+	mrc	p15, 0, r1, c1, c0, 0
+	tst	r1, #CR_M @ Check MMU bit enabled
+	bne	1f
+
+	/* use physical address of the coherency register*/
+	adr	r0, 3f
+	ldr	r3, [r0]
+	ldr	r0, [r0, r3]
+	b	2f
+1:
+	/* use virtual address of the coherency register*/
+	ldr	r0, =coherency_base
+	ldr	r0, [r0]
+2:
 	/* Create bit by cpu index */
 	mov	r3, #(1 << 24)
 	lsl	r1, r3, r1
@@ -56,3 +70,7 @@ ARM_BE8(rev	r1, r1)
 	mov	r0, #0
 	mov	pc, lr
 ENDPROC(ll_set_cpu_coherent)
+
+	.align 2
+3:
+	.long	coherency_phys_base - .
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
index 3dd80df428f7..f30bc8d78871 100644
--- a/arch/arm/mach-mvebu/headsmp.S
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -31,11 +31,6 @@
 ENTRY(armada_xp_secondary_startup)
  ARM_BE8(setend	be )			@ go BE8 if entered LE
 
-	/* Get coherency fabric base physical address */
-	adr	r0, 1f
-	ldr	r1, [r0]
-	ldr	r0, [r0, r1]
-
 	/* Read CPU id */
 	mrc     p15, 0, r1, c0, c0, 5
 	and     r1, r1, #0xF
@@ -45,7 +40,3 @@ ENTRY(armada_xp_secondary_startup)
 	b	secondary_startup
 
 ENDPROC(armada_xp_secondary_startup)
-
-	.align 2
-1:
-	.long	coherency_phys_base - .
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v4 03/13] ARM: mvebu: ll_set_cpu_coherent always uses the current CPU
From: Gregory CLEMENT @ 2014-02-13 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392312816-17657-1-git-send-email-gregory.clement@free-electrons.com>

ll_set_cpu_coherent is always used on the current CPU, so instead of
passing the CPU id as argument, ll_set_cpu_coherent() can find it by
itself.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/coherency.c    | 10 +++++-----
 arch/arm/mach-mvebu/coherency.h    |  2 +-
 arch/arm/mach-mvebu/coherency_ll.S | 12 ++++++------
 arch/arm/mach-mvebu/headsmp.S      |  4 ----
 arch/arm/mach-mvebu/platsmp.c      |  2 +-
 5 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 88dd507221fc..51010dbbf7e4 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -44,17 +44,17 @@ static struct of_device_id of_coherency_table[] = {
 };
 
 /* Function defined in coherency_ll.S */
-int ll_set_cpu_coherent(unsigned int hw_cpu_id);
+int ll_set_cpu_coherent(void);
 
-int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
+int set_cpu_coherent(int smp_group_id)
 {
 	if (!coherency_base) {
-		pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id);
+		pr_warn("Can't make current CPU cache coherent.\n");
 		pr_warn("Coherency fabric is not initialized\n");
 		return 1;
 	}
 
-	return ll_set_cpu_coherent(hw_cpu_id);
+	return ll_set_cpu_coherent();
 }
 
 static inline void mvebu_hwcc_sync_io_barrier(void)
@@ -140,7 +140,7 @@ int __init coherency_init(void)
 		sync_cache_w(&coherency_phys_base);
 		coherency_base = of_iomap(np, 0);
 		coherency_cpu_base = of_iomap(np, 1);
-		set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
+		set_cpu_coherent(0);
 		of_node_put(np);
 	}
 
diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h
index 760226c41353..c7e5df368d98 100644
--- a/arch/arm/mach-mvebu/coherency.h
+++ b/arch/arm/mach-mvebu/coherency.h
@@ -16,7 +16,7 @@
 
 extern unsigned long coherency_phys_base;
 
-int set_cpu_coherent(unsigned int cpu_id, int smp_group_id);
+int set_cpu_coherent(int smp_group_id);
 int coherency_init(void);
 
 #endif	/* __MACH_370_XP_COHERENCY_H */
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index 1f2bcd4b5424..6cb26b919787 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -24,9 +24,7 @@
 #include <asm/cp15.h>
 
 	.text
-/*
- * r0: HW CPU id
- */
+
 ENTRY(ll_set_cpu_coherent)
 	mrc	p15, 0, r1, c1, c0, 0
 	tst	r1, #CR_M @ Check MMU bit enabled
@@ -43,9 +41,11 @@ ENTRY(ll_set_cpu_coherent)
 	ldr	r0, [r0]
 2:
 	/* Create bit by cpu index */
-	mov	r3, #(1 << 24)
-	lsl	r1, r3, r1
-ARM_BE8(rev	r1, r1)
+	mrc	15, 0, r1, cr0, cr0, 5
+	and	r1, r1, #15
+	mov	r2, #(1 << 24)
+	lsl	r1, r2, r1
+	ARM_BE8(rev	r1, r1)
 
 	/* Add CPU to SMP group - Atomic */
 	add	r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
index f30bc8d78871..cf7abe6554f7 100644
--- a/arch/arm/mach-mvebu/headsmp.S
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -31,10 +31,6 @@
 ENTRY(armada_xp_secondary_startup)
  ARM_BE8(setend	be )			@ go BE8 if entered LE
 
-	/* Read CPU id */
-	mrc     p15, 0, r1, c0, c0, 5
-	and     r1, r1, #0xF
-
 	/* Add CPU to coherency fabric */
 	bl	ll_set_cpu_coherent
 	b	secondary_startup
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index a6da03f5b24e..a99d71a747f0 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -102,7 +102,7 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
 
 	set_secondary_cpus_clock();
 	flush_cache_all();
-	set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
+	set_cpu_coherent(0);
 
 	/*
 	 * In order to boot the secondary CPUs we need to ensure
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v4 04/13] ARM: mvebu: Remove the unused argument of set_cpu_coherent()
From: Gregory CLEMENT @ 2014-02-13 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392312816-17657-1-git-send-email-gregory.clement@free-electrons.com>

set_cpu_coherent() took the SMP group ID as parameter. But this
parameter was never used, and the CPU always use the SMP group 0. So
we can remove this parameter.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/coherency.c    |  8 ++---
 arch/arm/mach-mvebu/coherency.h    |  2 +-
 arch/arm/mach-mvebu/coherency_ll.S | 61 ++++++++++++++++++++++++--------------
 arch/arm/mach-mvebu/headsmp.S      |  4 +--
 arch/arm/mach-mvebu/platsmp.c      |  2 +-
 5 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 51010dbbf7e4..931c62be2bce 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -44,9 +44,9 @@ static struct of_device_id of_coherency_table[] = {
 };
 
 /* Function defined in coherency_ll.S */
-int ll_set_cpu_coherent(void);
+int ll_set_cpu_coherent_and_smp(void);
 
-int set_cpu_coherent(int smp_group_id)
+int set_cpu_coherent(void)
 {
 	if (!coherency_base) {
 		pr_warn("Can't make current CPU cache coherent.\n");
@@ -54,7 +54,7 @@ int set_cpu_coherent(int smp_group_id)
 		return 1;
 	}
 
-	return ll_set_cpu_coherent();
+	return ll_set_cpu_coherent_and_smp();
 }
 
 static inline void mvebu_hwcc_sync_io_barrier(void)
@@ -140,7 +140,7 @@ int __init coherency_init(void)
 		sync_cache_w(&coherency_phys_base);
 		coherency_base = of_iomap(np, 0);
 		coherency_cpu_base = of_iomap(np, 1);
-		set_cpu_coherent(0);
+		set_cpu_coherent();
 		of_node_put(np);
 	}
 
diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h
index c7e5df368d98..dff16612dd93 100644
--- a/arch/arm/mach-mvebu/coherency.h
+++ b/arch/arm/mach-mvebu/coherency.h
@@ -15,8 +15,8 @@
 #define __MACH_370_XP_COHERENCY_H
 
 extern unsigned long coherency_phys_base;
+int set_cpu_coherent(void);
 
-int set_cpu_coherent(int smp_group_id);
 int coherency_init(void);
 
 #endif	/* __MACH_370_XP_COHERENCY_H */
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index 6cb26b919787..7b42b4b08a80 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -25,52 +25,67 @@
 
 	.text
 
-ENTRY(ll_set_cpu_coherent)
+	.macro modify_coherent_reg join_smp
 	mrc	p15, 0, r1, c1, c0, 0
 	tst	r1, #CR_M @ Check MMU bit enabled
 	bne	1f
 
-	/* use physical address of the coherency register*/
-	adr	r0, 3f
-	ldr	r3, [r0]
-	ldr	r0, [r0, r3]
+	/* use physical address of the coherency register */
+	adr	r1, 3f
+	ldr	r3, [r1]
+	ldr	r1, [r1, r3]
 	b	2f
 1:
-	/* use virtual address of the coherency register*/
-	ldr	r0, =coherency_base
-	ldr	r0, [r0]
+	/* use virtual address of the coherency register */
+	ldr	r1, =coherency_base
+	ldr	r1, [r1]
 2:
 	/* Create bit by cpu index */
-	mrc	15, 0, r1, cr0, cr0, 5
-	and	r1, r1, #15
+	mrc	15, 0, r3, cr0, cr0, 5
+	and	r3, r3, #15
 	mov	r2, #(1 << 24)
-	lsl	r1, r2, r1
-	ARM_BE8(rev	r1, r1)
+	lsl	r3, r2, r3
+	ARM_BE8(rev	r3, r3)
 
-	/* Add CPU to SMP group - Atomic */
-	add	r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
+	.if \join_smp == 1
+	/* Add CPU to SMP group - Atomic (only if the flag is set) */
+	add	r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
 1:
-	ldrex	r2, [r3]
-	orr	r2, r2, r1
-	strex 	r0, r2, [r3]
-	cmp	r0, #0
+	ldrex	r2, [r0]
+	orr	r2, r2, r3
+	strex 	r1, r2, [r0]
+	cmp	r1, #0
 	bne 1b
 
+	/* get back to the base register */
+	sub	r1, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET
+	.endif
+
 	/* Enable coherency on CPU - Atomic */
-	add	r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET
+	add	r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
 1:
-	ldrex	r2, [r3]
-	orr	r2, r2, r1
-	strex	r0, r2, [r3]
-	cmp	r0, #0
+	ldrex	r2, [r0]
+	orr	r2, r2, r3
+	strex	r1, r2, [r0]
+	cmp	r1, #0
 	bne 1b
 
 	dsb
 
 	mov	r0, #0
 	mov	pc, lr
+	.endm
+
+/*  Enable coherency on CPU */
+ENTRY(ll_set_cpu_coherent)
+	modify_coherent_reg join_smp = 0
 ENDPROC(ll_set_cpu_coherent)
 
+/* Add CPU to SMP group */
+ENTRY(ll_set_cpu_coherent_and_smp)
+	modify_coherent_reg join_smp = 1
+ENDPROC(ll_set_cpu_coherent_and_smp)
+
 	.align 2
 3:
 	.long	coherency_phys_base - .
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
index cf7abe6554f7..924fb96775c5 100644
--- a/arch/arm/mach-mvebu/headsmp.S
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -31,8 +31,8 @@
 ENTRY(armada_xp_secondary_startup)
  ARM_BE8(setend	be )			@ go BE8 if entered LE
 
-	/* Add CPU to coherency fabric */
-	bl	ll_set_cpu_coherent
+	bl	ll_set_cpu_coherent_and_smp
+
 	b	secondary_startup
 
 ENDPROC(armada_xp_secondary_startup)
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index a99d71a747f0..f2f1830063c8 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -102,7 +102,7 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
 
 	set_secondary_cpus_clock();
 	flush_cache_all();
-	set_cpu_coherent(0);
+	set_cpu_coherent();
 
 	/*
 	 * In order to boot the secondary CPUs we need to ensure
-- 
1.8.1.2

^ permalink raw reply related


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