Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 1/4] ARM: Add Krait L2 register accessor functions
From: Stephen Boyd @ 2014-01-14 21:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389735034-21430-1-git-send-email-sboyd@codeaurora.org>

Krait CPUs have a handful of L2 cache controller registers that
live behind a cp15 based indirection register. First you program
the indirection register (l2cpselr) to point the L2 'window'
register (l2cpdr) at what you want to read/write.  Then you
read/write the 'window' register to do what you want. The
l2cpselr register is not banked per-cpu so we must lock around
accesses to it to prevent other CPUs from re-pointing l2cpdr
underneath us.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Courtney Cavin <courtney.cavin@sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 arch/arm/common/Kconfig                   |  3 ++
 arch/arm/common/Makefile                  |  1 +
 arch/arm/common/krait-l2-accessors.c      | 58 +++++++++++++++++++++++++++++++
 arch/arm/include/asm/krait-l2-accessors.h | 20 +++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 arch/arm/common/krait-l2-accessors.c
 create mode 100644 arch/arm/include/asm/krait-l2-accessors.h

diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index c3a4e9ceba34..9da52dc6260b 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -9,6 +9,9 @@ config DMABOUNCE
 	bool
 	select ZONE_DMA
 
+config KRAIT_L2_ACCESSORS
+	bool
+
 config SHARP_LOCOMO
 	bool
 
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 4bdc41622c36..2836f992ee5d 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -7,6 +7,7 @@ obj-y				+= firmware.o
 obj-$(CONFIG_ICST)		+= icst.o
 obj-$(CONFIG_SA1111)		+= sa1111.o
 obj-$(CONFIG_DMABOUNCE)		+= dmabounce.o
+obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o
 obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
diff --git a/arch/arm/common/krait-l2-accessors.c b/arch/arm/common/krait-l2-accessors.c
new file mode 100644
index 000000000000..5d514bbc88a6
--- /dev/null
+++ b/arch/arm/common/krait-l2-accessors.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/export.h>
+
+#include <asm/barrier.h>
+#include <asm/krait-l2-accessors.h>
+
+static DEFINE_RAW_SPINLOCK(krait_l2_lock);
+
+void krait_set_l2_indirect_reg(u32 addr, u32 val)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&krait_l2_lock, flags);
+	/*
+	 * Select the L2 window by poking l2cpselr, then write to the window
+	 * via l2cpdr.
+	 */
+	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
+	isb();
+	asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
+	isb();
+
+	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
+}
+EXPORT_SYMBOL(krait_set_l2_indirect_reg);
+
+u32 krait_get_l2_indirect_reg(u32 addr)
+{
+	u32 val;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&krait_l2_lock, flags);
+	/*
+	 * Select the L2 window by poking l2cpselr, then read from the window
+	 * via l2cpdr.
+	 */
+	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
+	isb();
+	asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
+
+	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
+
+	return val;
+}
+EXPORT_SYMBOL(krait_get_l2_indirect_reg);
diff --git a/arch/arm/include/asm/krait-l2-accessors.h b/arch/arm/include/asm/krait-l2-accessors.h
new file mode 100644
index 000000000000..48fe5527bc01
--- /dev/null
+++ b/arch/arm/include/asm/krait-l2-accessors.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H
+#define __ASMARM_KRAIT_L2_ACCESSORS_H
+
+extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
+extern u32 krait_get_l2_indirect_reg(u32 addr);
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [PATCH v5 0/4] Krait L1/L2 EDAC driver
From: Stephen Boyd @ 2014-01-14 21:30 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds support for the Krait L1/L2 cache error detection
hardware. The first patch adds the Krait l2 indirection
register code. This patch is in need of an ACK from ARM folks.
The next two patches add the driver and the binding and 
the final patch hooks it all up by adding the device tree node.

I think Boris will pick up the first and third patches since they depend
on each other. The final dts change could go through arm-soc via davidb's tree
and the Documentation patch could go through the devicetree tree. Or patches 1
through 3 can go through Boris' tree.

Changes since v4:
 * Prefixed l2 accessors functions with krait_
 * Dropped first two patches as Boris says he picked them up

Changes since v3:
 * Fixed l1_irq handler to properly dereference dev_id

Changes since v2:
 * Picked up acks
 * s/an/a/ in DT binding

Stephen Boyd (4):
  ARM: Add Krait L2 register accessor functions
  devicetree: bindings: Document Krait CPU/L1 EDAC
  edac: Add support for Krait CPU cache error detection
  ARM: dts: msm: Add Krait CPU/L2 nodes

 Documentation/devicetree/bindings/arm/cpus.txt |  52 ++++
 arch/arm/boot/dts/qcom-msm8974.dtsi            |  41 +++
 arch/arm/common/Kconfig                        |   3 +
 arch/arm/common/Makefile                       |   1 +
 arch/arm/common/krait-l2-accessors.c           |  58 +++++
 arch/arm/include/asm/krait-l2-accessors.h      |  20 ++
 drivers/edac/Kconfig                           |   8 +
 drivers/edac/Makefile                          |   2 +
 drivers/edac/krait_edac.c                      | 346 +++++++++++++++++++++++++
 9 files changed, 531 insertions(+)
 create mode 100644 arch/arm/common/krait-l2-accessors.c
 create mode 100644 arch/arm/include/asm/krait-l2-accessors.h
 create mode 100644 drivers/edac/krait_edac.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [PATCH] ACPI: introduce CONFIG_ACPI_REDUCED_HARDWARE_ONLY to enforce this ACPI mode
From: Arnd Bergmann @ 2014-01-14 21:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389731822-21336-1-git-send-email-al.stone@linaro.org>

On Tuesday 14 January 2014 13:37:02 al.stone at linaro.org wrote:
> +config ACPI_REDUCED_HARDWARE_ONLY
> +       bool "Hardware-reduced ACPI support only"
> +       def_bool n
> +       depends on ACPI && EXPERT

I think this will cause a Kconfig warning if you try to select this
on ARM64 without turning on EXPERT as well. 

It should be ok if you express it as

config ACPI_REDUCED_HARDWARE_ONLY
       bool "Hardware-reduced ACPI support only" if EXPERT
       def_bool n
       depends on ACPI


	Arnd

^ permalink raw reply

* [PATCH v2] ARM: OMAP4460: cpuidle: Extend PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD on cpuidle
From: Kevin Hilman @ 2014-01-14 21:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5286480B.3060801@ti.com>

On Fri, Nov 15, 2013 at 8:12 AM, Santosh Shilimkar
<santosh.shilimkar@ti.com> wrote:
> On Friday 15 November 2013 11:11 AM, Tony Lindgren wrote:
>> * Taras Kondratiuk <taras.kondratiuk@linaro.org> [131115 08:03]:
>>> On 11/15/2013 05:36 PM, Tony Lindgren wrote:
>>>> * Tony Lindgren <tony@atomide.com> [131114 10:36]:
>>>>> * Grygorii Strashko <grygorii.strashko@ti.com> [131022 12:09]:
>>>>>> The same workaround as ff999b8a0983ee15668394ed49e38d3568fc6859
>>>>>> "ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX GIC ..."
>>>>>> need to be applied not only when system is booting, but when MPUSS hits
>>>>>> OSWR state through CPUIdle too. Without this WA the same issue is
>>>>>> reproduced now on boards PandaES and Tablet/Blaze with SOM OMAP4460
>>>>>> when CONFIG_CPU_IDLE is enabled.
>>>>>> After MPUSS has enterred OSWR and waken up:
>>>>>> - GIC distributor became disabled forever
>>>>>> - scheduling is not performed any more
>>>>>>
>>>>>> Cc: Kevin Hilman <khilman@linaro.org>
>>>>>> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>>> Reported-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
>>>>>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>>>>>
>>>>> Applying into omap-for-v3.13/fixes thanks.
>>>>
>>>> Hmm looks like this breaks the build with randconfigs at least
>>>> with the attached .config, so dropping for now.
>>>
>>> Hi Tony
>>> Have you forgot to attach .config?
>>
>> Oops, sorry looks like I removed it already as I rebuilt the tree
>> and started a new set of randconfig build tests.
>>
>>>> arch/arm/mach-omap2/built-in.o: In function `omap_enter_idle_coupled':
>>>> :(.text+0xb48c): undefined reference to `pm44xx_errata'
>>>
>>> I assume that .config doesn't have CONFIG_SMP enabled while
>>> pm44xx_errata is defined in omap-smp.c.
>>> I think it should be a separate patch to move pm44xx_errata somewhere
>>> else, so this patch will remain the same.
>>
>> Yes something like that probably. Sounds like that should be then
>> patches before this fix.
>>
>>> Btw, do we need omap_enter_idle_coupled() in UP?
>>
>> That should be checked, am43xx may need it.
>>
> Nope. omap_enter_idle_coupled() is needed only for SMP
> systems. UP don't need couple idle functionality as
> such.

So what's the status of this fix and dependencies?

Both linux-next[1] and arm-soc/for-next[2] are failing boot tests on
omap4460/panda-es because multi_v7_defconfig now has CPUidle enabled
by default.

Kevin

[1] http://lists.linaro.org/pipermail/kernel-build-reports/2014-January/001891.html
[2] http://lists.linaro.org/pipermail/kernel-build-reports/2014-January/001898.html

^ permalink raw reply

* [PATCH] ARM: OMAP4: sleep: byteswap data for big-endian
From: Nishanth Menon @ 2014-01-14 21:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52D5A60C.7080800@ti.com>

On Tue, Jan 14, 2014 at 3:03 PM, Santosh Shilimkar
<santosh.shilimkar@ti.com> wrote:
>
>> ok.. some sort of Linaro thing about which I have no background about
>> - but dont really care in this context.
>>
> Nothing related Linaro. Its just that platforms are supporting ARM BE
> mode and Linaro folks had working patches for Panda. So I suggested
> to get them on the lists.

I tend to think -> is this with OFF mode and CPUidle completely
working? All context save and restore works with this? on HS and GP
devices with BE mode builds? works on SDP4430,60 variations,
considered reuse with AM43xx which could use parts of that logic?

I mean to indicate that terms like "works on panda" tends always to be relative.

It is nice to see it as a proof of concept, but I'd hate to see some
dead code lying around in kernel and folks blindly following suit and
introducing macros for new assembly for a feature that in practice
just one group of folks care about and creates additional burden for
rest of folks trying to keep that functionality going as we jump from
one "device tree" style churn to another "framework"? Not to mean that
good features should be kept away.. but personally, I could not find
convincing arguments in this case..

Regards,
Nishanth Menon

^ permalink raw reply

* Add .determine_rate to composite clk
From: Mike Turquette @ 2014-01-14 21:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJiWf8Wvcu0pWBNd7xSm9ES7ApTNp27CXTHWBxbr4msfNd9xCA@mail.gmail.com>

Quoting Lemon Dai (2014-01-14 06:08:44)
> Hi Maxime,
> 
> The commit 107f3198 in Mike's clk-next branch shows that:
> (about line 72 in drivers/clk/clk-composite.c)
> 
>         } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
>                 mux_hw->clk = hw->clk;
>                 return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
>                                                best_parent_p);
> 
> 
>  It should be fixed as follows, at least for reason that  NULL rate_hw
> may be used in the old code,
> 
>         } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
>                 mux_hw->clk = hw->clk;
>  -              return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
>  +             return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
>                                                best_parent_p);

Hi Lemon Dai,

I have applied this fix to clk-next. The patch is below:



>From ca01f3f60aa864d7ee8124ca597d4010378926b5 Mon Sep 17 00:00:00 2001
From: Mike Turquette <mturquette@linaro.org>
Date: Tue, 14 Jan 2014 12:56:01 -0800
Subject: [PATCH] clk: composite: pass mux_hw into determine_rate

The composite clock's .determine_rate implementation can call the
underyling .determine_rate callback corresponding to rate_hw or the
underlying .determine_rate callback corresponding to mux_hw. In both
cases we pass in rate_hw, which is wrong. Fixed by passing mux_hw into
the correct callback.

Reported-by: Lemon Dai <dailemon.gl@gmail.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
---
 drivers/clk/clk-composite.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 753d0b7..57a078e 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -71,7 +71,7 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 						best_parent_p);
 	} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
 		mux_hw->clk = hw->clk;
-		return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
+		return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
 					       best_parent_p);
 	} else {
 		pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH] ARM: OMAP4: sleep: byteswap data for big-endian
From: Santosh Shilimkar @ 2014-01-14 21:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGo_u6p7ErrKOMy4Ljg3nehVpd=DOg3XDn6gZ1nrFE_OuOjsWg@mail.gmail.com>

On Tuesday 14 January 2014 03:56 PM, Nishanth Menon wrote:
> On Tue, Jan 14, 2014 at 2:20 PM, Victor Kamensky
> <victor.kamensky@linaro.org> wrote:
>> On 14 January 2014 09:56, Nishanth Menon <nm@ti.com> wrote:
>>> On Tue, Jan 14, 2014 at 11:35 AM, Victor Kamensky
>>> <victor.kamensky@linaro.org> wrote:
>>>>
>>>> When BE kernel is built Makefile does take of compiling code in BE
>>>> mode. I.e all proper flags like -mbig-endian and -Wl,--be8 will be set.
>>>
>>> Agreed, and I assume you cannot instead switch to LE mode when
>>> entering assembly assuming LE?
>>
>> Yes. Note that this asm interacts with other data in kernel that would
>> be in BE form. And after all linker will not allow to put together files
>> that were compiled in different endianity.
>>
>>> The reason I ask this is - most of our development is NOT in BE mode.
>>> we will continue to manipulate and add assembly - AM335x, DRA7/OMAP5
>>> etc.. and obviously not every code change will indulge in ensuring
>>> right markers will be in place.
>>>
>>> by ensuring readl_relaxed handles the variations, you have ensured
>>> that I dont need to care about drivers other than to ensure they use
>>> _relaxed variants. in the case of assembly, this does not seem long
>>> term manageable.
>>
>> Yes, I agree if it is outside of main use case it will get broken if not
>> attended to. Definitely universe entropy increases :) - if left without
>> attention things will decay. Note we admit that even with ARM CPU
>> core BE changes similar decay can happen eventually ...that is
>> what LNG BE group trying to prevent. I think
>> the deal here is that next user of it can/need to fix things if they
>> decayed.
>>
> 
> Personally, I have no idea what "LNG BE" stands for.. I see the
> approach we are attempting here is to do any interaction external to
> ARM boundary to go through the ARM_BE8 macro.
> 
> If we want to make this something we can live with, then the platforms
> will have to ensure memory operations external to ARM must be operated
> upon by these macros. Instead, an approach that may be used is to
> introduce accessors macros that will provide right instruction based
> on BE/LE build and BE/LE SoC peripheral behavior.
> 
>>>>
>>>>> is the idea of BE build meant to deal with having a single BE kernel
>>>>> build work for all platforms (including LE ones)?
>>>>
>>>> Sort of. The idea here to run BE image on OMAP4 chip, with
>>>> kernel that would deals with LE periphery correctly, but ARM
>>>> core run in BE with special kernel that compiled for BE case (i.e
>>>> CONFIG_CPU_BIG_ENDIAN is set).
>>>
>>> I still dont get the usecase - other than "hey, we do this coz we can
>>> do it!".. I mean, yep, it sounds great and all.. but 4 years down the
>>> line, is this still going to work? is this going to be interesting
>>> careabout? or we are just maintaining additional code for a passing
>>> fancy or proof-of-concept?
>>
>> Valid concern. From LNG BE group point of view it is not "we can do
>> it". It is more like we've done it. We have Pandaboard ES running BE
>> kernel for a while. It is in LNG BE tree. We used it as development
>> and testing vehicle for BE work for a while. We are very grateful to
>> the platform for that - it is affordable and easily available! Given,
>> beyond ongoing BE testing on Pandaboard in LNG there may not be valid
>> use case for further things on OMAP4 BE. We had discussion
>> with Santosh Shilimkar from TI during last Linaro connect what to
>> do with LNG BE Pandaboard series. Santosh suggested and we
>> agreed that we would try to contribute them back to community. And
>> that is what Taras is doing. IMHO even though there may not be real
> 
> ok.. some sort of Linaro thing about which I have no background about
> - but dont really care in this context.
> 
Nothing related Linaro. Its just that platforms are supporting ARM BE
mode and Linaro folks had working patches for Panda. So I suggested
to get them on the lists.

Regards,
Santosh

^ permalink raw reply

* [PATCH 2/7] ARM: perf_event: Support percpu irqs for the CPU PMU
From: Stephen Boyd @ 2014-01-14 20:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140113115213.GE1189@mudshark.cambridge.arm.com>

On 01/13/14 03:52, Will Deacon wrote:
> On Fri, Jan 10, 2014 at 07:36:57PM +0000, Stephen Boyd wrote:
>>
>> Passing the hw_events as the pcpu token here is kind of hacky.
>> The reason is because the token is dereferenced into cpu_pmu in
>> armv7pmu_handle_irq() like so:
>>
>> 	struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
>>
>> It would be great if we could pass cpu_pmu directly to the
>> request call like so:
>>
>> 	request_percpu_irq(irq, cpu_pmu->handle_irq, "arm-pmu", &cpu_pmu);
>>
>> but no. request_percpu_irq() wants a percpu pointer so this won't
>> work. If cpu_pmu was declared as DEFINE_PER_CPU, this would work
>> out just fine.
> That feels really broken though, since we rely on the cpu_pmu being a
> container for the struct pmu that was registered with perf core.
>
>> Should the cpu_pmu become a per-cpu variable? That sounds rather
>> invasive.
> I also don't think that's the right solution, based on the above. It's
> actually pretty hard to work out what's the right thing to do here...

Yes it doesn't seem like the right solution.

>
> We *could* have a per-cpu pointer to the cpu_pmu_pointer, but then we'd
> need to update the IRQ handlers, including things like the CCI PMU which
> really doesn't care about per-cpu stuff. So after all this, the shim we have
> around the IRQ handler for the U8500 SPI workarounds might be the right
> thing after all -- it allows us to consolidate the conversion of a pcpu
> pointer into the relevant instance (actually any instance, since they'd all
> point at the same thing) for the current CPU.
>
> What do you think to having that shim throw away the second level pcpu
> pointer in the case of a PPI? (probably means we need to revisit that
> renaming again).

Ok I think I understand what you're getting at. We pass a per-cpu
pointer to the cpu_pmu pointer as the dev_id argument to the PPI irq
handler, and then we check to see if the irq is per-cpu inside the
armpmu_dispatch_irq() function and throw away the second level of
pointer, i.e.

static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
{
        struct arm_pmu *armpmu;
        struct platform_device *plat_device;
        struct arm_pmu_platdata *plat;

        if (irq_is_percpu(irq))
                dev = *(struct arm_pmu_cpu **)dev;
        armpmu = dev;
        plat_device = armpmu->plat_device;
        plat = dev_get_platdata(&plat_device->dev);

        if (plat && plat->handle_irq)
                return plat->handle_irq(irq, dev, armpmu->handle_irq);
        else
                return armpmu->handle_irq(irq, dev);
}


We still need to make a per-cpu variable to hold the pointer, and assign
it during cpu_pmu_init like this patch does. Hopefully that is ok.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [PATCH] ARM: OMAP4: sleep: byteswap data for big-endian
From: Nishanth Menon @ 2014-01-14 20:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAA3XUr1_cNuPmMU6Fs6c7Si2So0VFGcLyGJe+tS_R47BVKRXnw@mail.gmail.com>

On Tue, Jan 14, 2014 at 2:20 PM, Victor Kamensky
<victor.kamensky@linaro.org> wrote:
> On 14 January 2014 09:56, Nishanth Menon <nm@ti.com> wrote:
>> On Tue, Jan 14, 2014 at 11:35 AM, Victor Kamensky
>> <victor.kamensky@linaro.org> wrote:
>>>
>>> When BE kernel is built Makefile does take of compiling code in BE
>>> mode. I.e all proper flags like -mbig-endian and -Wl,--be8 will be set.
>>
>> Agreed, and I assume you cannot instead switch to LE mode when
>> entering assembly assuming LE?
>
> Yes. Note that this asm interacts with other data in kernel that would
> be in BE form. And after all linker will not allow to put together files
> that were compiled in different endianity.
>
>> The reason I ask this is - most of our development is NOT in BE mode.
>> we will continue to manipulate and add assembly - AM335x, DRA7/OMAP5
>> etc.. and obviously not every code change will indulge in ensuring
>> right markers will be in place.
>>
>> by ensuring readl_relaxed handles the variations, you have ensured
>> that I dont need to care about drivers other than to ensure they use
>> _relaxed variants. in the case of assembly, this does not seem long
>> term manageable.
>
> Yes, I agree if it is outside of main use case it will get broken if not
> attended to. Definitely universe entropy increases :) - if left without
> attention things will decay. Note we admit that even with ARM CPU
> core BE changes similar decay can happen eventually ...that is
> what LNG BE group trying to prevent. I think
> the deal here is that next user of it can/need to fix things if they
> decayed.
>

Personally, I have no idea what "LNG BE" stands for.. I see the
approach we are attempting here is to do any interaction external to
ARM boundary to go through the ARM_BE8 macro.

If we want to make this something we can live with, then the platforms
will have to ensure memory operations external to ARM must be operated
upon by these macros. Instead, an approach that may be used is to
introduce accessors macros that will provide right instruction based
on BE/LE build and BE/LE SoC peripheral behavior.

>>>
>>>> is the idea of BE build meant to deal with having a single BE kernel
>>>> build work for all platforms (including LE ones)?
>>>
>>> Sort of. The idea here to run BE image on OMAP4 chip, with
>>> kernel that would deals with LE periphery correctly, but ARM
>>> core run in BE with special kernel that compiled for BE case (i.e
>>> CONFIG_CPU_BIG_ENDIAN is set).
>>
>> I still dont get the usecase - other than "hey, we do this coz we can
>> do it!".. I mean, yep, it sounds great and all.. but 4 years down the
>> line, is this still going to work? is this going to be interesting
>> careabout? or we are just maintaining additional code for a passing
>> fancy or proof-of-concept?
>
> Valid concern. From LNG BE group point of view it is not "we can do
> it". It is more like we've done it. We have Pandaboard ES running BE
> kernel for a while. It is in LNG BE tree. We used it as development
> and testing vehicle for BE work for a while. We are very grateful to
> the platform for that - it is affordable and easily available! Given,
> beyond ongoing BE testing on Pandaboard in LNG there may not be valid
> use case for further things on OMAP4 BE. We had discussion
> with Santosh Shilimkar from TI during last Linaro connect what to
> do with LNG BE Pandaboard series. Santosh suggested and we
> agreed that we would try to contribute them back to community. And
> that is what Taras is doing. IMHO even though there may not be real

ok.. some sort of Linaro thing about which I have no background about
- but dont really care in this context.

> product use case for BE OMAP4, it could serve in kernel source as good
> example that shows how to work with LE periphery from BE kernel. After
> all, these changes are noop for LE case and they don't introduce
> a lot of clutter: all BE asm rev and rev16 instructions wrapped around
> with ARM_BE8 macro.
>

So, why are we not doing this for *all* OMAP platforms? we try very
hard not to regress on features introduced and wish to ensure all
platforms are equivalent in terms of usage. it makes code sharing a
little harder if we have to ensure that ARM_BE8 is supported in a mix
of reusable codebases.

Personally, here is what I might expect to see:
a) if we are going to force usage of BE and LE build options - then we
*must* be able to reuse code across platforms without having to worry
about breaking platform x etc..
b) this seems like - "take this code in" if something breaks, the guy
who needs it later will come and fix - Shrug, I personally dont buy
that. if something benefits many folks, lets all use it in upstream,
if there is just an exception usage for a short duration which may
impact code scalability and hard to maintain, keep it forked.
c) considering this is non standard usage, some sort of regular test
procedure and owner to ensure this feature is kept sane

With out the above, we are just adding dead code IMHO.

Regards,
Nishanth Menon

^ permalink raw reply

* [PATCH v2 02/10] genirq: Add devm_request_any_context_irq()
From: Stephen Boyd @ 2014-01-14 20:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52CB2D29.3050107@codeaurora.org>

On 01/06/14 14:24, Stephen Boyd wrote:
> On 01/02/14 16:37, Stephen Boyd wrote:
>> Some drivers use request_any_context_irq() but there isn't a
>> devm_* function for it. Add one so that these drivers don't need
>> to explicitly free the irq on driver detach.
>>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> Thomas, can you please review this patch?

ping?

>> ---
>>  include/linux/interrupt.h |  5 +++++
>>  kernel/irq/devres.c       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 50 insertions(+)
>>
>> diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
>> index 0053adde0ed9..a2678d35b5a2 100644
>> --- a/include/linux/interrupt.h
>> +++ b/include/linux/interrupt.h
>> @@ -158,6 +158,11 @@ devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
>>  					 devname, dev_id);
>>  }
>>  
>> +extern int __must_check
>> +devm_request_any_context_irq(struct device *dev, unsigned int irq,
>> +		 irq_handler_t handler, unsigned long irqflags,
>> +		 const char *devname, void *dev_id);
>> +
>>  extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
>>  
>>  /*
>> diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
>> index bd8e788d71e0..1ef0606797c9 100644
>> --- a/kernel/irq/devres.c
>> +++ b/kernel/irq/devres.c
>> @@ -73,6 +73,51 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>>  EXPORT_SYMBOL(devm_request_threaded_irq);
>>  
>>  /**
>> + *	devm_request_any_context_irq - allocate an interrupt line for a managed device
>> + *	@dev: device to request interrupt for
>> + *	@irq: Interrupt line to allocate
>> + *	@handler: Function to be called when the IRQ occurs
>> + *	@thread_fn: function to be called in a threaded interrupt context. NULL
>> + *		    for devices which handle everything in @handler
>> + *	@irqflags: Interrupt type flags
>> + *	@devname: An ascii name for the claiming device
>> + *	@dev_id: A cookie passed back to the handler function
>> + *
>> + *	Except for the extra @dev argument, this function takes the
>> + *	same arguments and performs the same function as
>> + *	request_any_context_irq().  IRQs requested with this function will be
>> + *	automatically freed on driver detach.
>> + *
>> + *	If an IRQ allocated with this function needs to be freed
>> + *	separately, devm_free_irq() must be used.
>> + */
>> +int devm_request_any_context_irq(struct device *dev, unsigned int irq,
>> +			      irq_handler_t handler, unsigned long irqflags,
>> +			      const char *devname, void *dev_id)
>> +{
>> +	struct irq_devres *dr;
>> +	int rc;
>> +
>> +	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
>> +			  GFP_KERNEL);
>> +	if (!dr)
>> +		return -ENOMEM;
>> +
>> +	rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
>> +	if (rc) {
>> +		devres_free(dr);
>> +		return rc;
>> +	}
>> +
>> +	dr->irq = irq;
>> +	dr->dev_id = dev_id;
>> +	devres_add(dev, dr);
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(devm_request_any_context_irq);
>> +
>> +/**
>>   *	devm_free_irq - free an interrupt
>>   *	@dev: device to free interrupt for
>>   *	@irq: Interrupt line to free


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [RFC PATCH] clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent
From: Mike Turquette @ 2014-01-14 20:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389114233-11162-1-git-send-email-b.brezillon@overkiz.com>

Quoting Boris BREZILLON (2014-01-07 09:03:52)
> In case the rate_hw does not implement determine_rate, but only round_rate
> we fallback to best_parent selection if mux_hw is present and support
> reparenting.
> 
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>

Hi Boris,

Since this change affects users of the composite clock type I will hold
off reviewing/applying this patch until after the merge window.

Thanks,
Mike

> ---
>  drivers/clk/clk-composite.c |   49 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
> index 753d0b7..d3cf49a 100644
> --- a/drivers/clk/clk-composite.c
> +++ b/drivers/clk/clk-composite.c
> @@ -64,11 +64,57 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
>         const struct clk_ops *mux_ops = composite->mux_ops;
>         struct clk_hw *rate_hw = composite->rate_hw;
>         struct clk_hw *mux_hw = composite->mux_hw;
> +       struct clk *parent;
> +       unsigned long parent_rate;
> +       long tmp_rate;
> +       unsigned long rate_diff;
> +       unsigned long best_rate_diff = ULONG_MAX;
> +       int i;
>  
>         if (rate_hw && rate_ops && rate_ops->determine_rate) {
>                 rate_hw->clk = hw->clk;
>                 return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
>                                                 best_parent_p);
> +       } else if (rate_hw && rate_ops && rate_ops->round_rate &&
> +                  mux_hw && mux_ops && mux_ops->set_parent) {
> +               *best_parent_p = NULL;
> +
> +               if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
> +                       *best_parent_p = clk_get_parent(mux_hw->clk);
> +                       *best_parent_rate = __clk_get_rate(*best_parent_p);
> +
> +                       return rate_ops->round_rate(rate_hw, rate,
> +                                                   best_parent_rate);
> +               }
> +
> +               for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
> +                       parent = clk_get_parent_by_index(mux_hw->clk, i);
> +                       if (!parent)
> +                               continue;
> +
> +                       parent_rate = __clk_get_rate(parent);
> +
> +                       tmp_rate = rate_ops->round_rate(rate_hw, rate,
> +                                                       &parent_rate);
> +                       if (tmp_rate < 0)
> +                               continue;
> +
> +                       if (tmp_rate < rate)
> +                               rate_diff = rate - tmp_rate;
> +                       else
> +                               rate_diff = tmp_rate - rate;
> +
> +                       if (!rate_diff || !*best_parent_p || best_rate_diff > rate_diff) {
> +                               *best_parent_p = parent;
> +                               *best_parent_rate = parent_rate;
> +                               best_rate_diff = rate_diff;
> +                       }
> +
> +                       if (!rate_diff)
> +                               return rate;
> +               }
> +
> +               return best_rate_diff;
>         } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
>                 mux_hw->clk = hw->clk;
>                 return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
> @@ -196,7 +242,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
>                 composite->rate_hw = rate_hw;
>                 composite->rate_ops = rate_ops;
>                 clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
> -               if (rate_ops->determine_rate)
> +               if (rate_ops->determine_rate ||
> +                   (rate_ops->round_rate && clk_composite_ops->set_parent))
>                         clk_composite_ops->determine_rate = clk_composite_determine_rate;
>         }
>  
> -- 
> 1.7.9.5
> 

^ permalink raw reply

* [PATCH] ACPI: introduce CONFIG_ACPI_REDUCED_HARDWARE_ONLY to enforce this ACPI mode
From: al.stone at linaro.org @ 2014-01-14 20:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Al Stone <al.stone@linaro.org>

Hardware reduced mode, despite the name, exists primarily to allow
newer platforms to use a much simpler form of ACPI that does not
require supporting the legacy of previous versions of the specification.
This mode was first introduced in the ACPI 5.0 specification, but because
it is so much simpler and reduces the size of the object code needed to
support ACPI, it is likely to be used more often in the near future.

To enable the hardware reduced mode of ACPI on some platforms (such as
ARM), we need to modify the kernel code and set ACPI_REDUCED_HARDWARE
to TRUE in the ACPICA source.  For ARM/ARM64, hardware reduced ACPI
should be the only mode used; legacy mode would require modifications
to SoCs in order to provide several x86-specific hardware features (e.g.,
an NMI and SMI support).

We set ACPI_REDUCED_HARDWARE to TRUE in the ACPICA source by introducing
a kernel config item to enable/disable ACPI_REDUCED_HARDWARE.  We can then
change the kernel config instead of having to modify the kernel source
directly to enable the reduced hardware mode of ACPI.

Lv Zheng suggested that this configuration item does not belong in ACPICA,
the upstream source for much of the ACPI internals, but rather to the
Linux kernel itself.  Hence, we introduce this flag so that we can make
ACPI_REDUCED_HARDWARE configurable.  For the details of the discussion,
please refer to: http://www.spinics.net/lists/linux-acpi/msg46369.html

Even though support for X86 in hardware reduced mode is possible, it
is NOT enabled.  Extensive effort has gone into the Linux kernel so that
there is a single kernel image than can run on all x86 hardware; the kernel
changes run-time behavior to adapt to the hardware being used.  This is not
currently possible with the existing ACPICA infrastructure but only presents
a problem on achitectures supporting both hardware-reduced and legacy modes
of ACPI -- i.e., on x86 only.

The problem with the current ACPICA code base is that if one builds legacy
ACPI (a proper superset of hardware-reduced), the kernel can run in hardware-
reduced with the proper ACPI tables, but there is still ACPICA code that could
be executed even though it is not allowed by the specification.  If one builds
a hardware-reduced only ACPI, the kernel cannot run with ACPI tables that are
for legacy mode.  To ensure compliance with ACPI, one must therefore build
two separate kernels.  Once this problem has been properly fixed, we can then
enable x86 hardware-reduced mode and use a single kernel.

This patch used to be part of a set to implement stricter conformance with
hardware reduced ACPI.  The code changes from that set are being re-thought
in order to handle some non-compliant hardware, but this patch did not depend
on those changes.  In the meantime, this patch is needed in order to enable
ACPI core functionality for ARMv8 servers and hence is being submitted
separately in order to aid that effort.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
---
 drivers/acpi/Kconfig            | 13 +++++++++++++
 include/acpi/platform/aclinux.h |  6 ++++++
 2 files changed, 19 insertions(+)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 4770de5..961ea9e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -343,6 +343,19 @@ config ACPI_BGRT
 	  data from the firmware boot splash. It will appear under
 	  /sys/firmware/acpi/bgrt/ .
 
+config ACPI_REDUCED_HARDWARE_ONLY
+	bool "Hardware-reduced ACPI support only"
+	def_bool n
+	depends on ACPI && EXPERT
+	help
+	This config item changes the way the ACPI code is built.  When this
+	option is selected, the kernel will use a specialized version of
+	ACPICA that ONLY supports the ACPI "reduced hardware" mode.  The
+	resulting kernel will be smaller but it will also be restricted to
+	running in ACPI reduced hardware mode ONLY.
+
+	If you are unsure what to do, do not enable this option.
+
 source "drivers/acpi/apei/Kconfig"
 
 config ACPI_EXTLOG
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 28f4f4d..7d71f08 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -52,6 +52,12 @@
 
 #ifdef __KERNEL__
 
+/* Compile for reduced hardware mode only with this kernel config */
+
+#ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY
+#define ACPI_REDUCED_HARDWARE 1
+#endif
+
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
-- 
1.8.4.2

^ permalink raw reply related

* [PATCH 2/3] ASoC: atmel_wm8904: make it available to choose clock
From: Mark Brown @ 2014-01-14 20:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389669956-2304-3-git-send-email-voice.shen@atmel.com>

On Tue, Jan 14, 2014 at 11:25:55AM +0800, Bo Shen wrote:
> Make it available to choose the clock from TK pin or RK pin. This
> is hardware design decided.

> --- a/sound/soc/atmel/atmel_wm8904.c
> +++ b/sound/soc/atmel/atmel_wm8904.c
> @@ -108,6 +108,7 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
>  	struct device_node *codec_np, *cpu_np;
>  	struct snd_soc_card *card = &atmel_asoc_wm8904_card;
>  	struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
> +	struct atmel_ssc_info *ssc_info;
>  	int ret;
>  
>  	if (!np) {
> @@ -115,6 +116,15 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> +	ssc_info = devm_kzalloc(&pdev->dev, sizeof(*ssc_info), GFP_KERNEL);
> +	if (!ssc_info)
> +		return -ENOMEM;
> +
> +	ssc_info->clk_from_rk_pin =
> +		of_property_read_bool(np, "clk_from_rk_pin");
> +
> +	card->drvdata = (void *)ssc_info;

Shouldn't this code be in the DAI driver?  Otherwise this series looks
fine to me, though the DT folks might have something to say I guess.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140114/0e9ccb1a/attachment.sig>

^ permalink raw reply

* [PATCHv13 00/40] ARM: TI SoC clock DT conversion
From: Felipe Balbi @ 2014-01-14 20:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52D53084.1070105@ti.com>

On Tue, Jan 14, 2014 at 02:41:40PM +0200, Tero Kristo wrote:
> On 01/10/2014 08:51 PM, Tony Lindgren wrote:
> >* Tero Kristo <t-kristo@ti.com> [140110 08:32]:
> >>On 01/10/2014 06:13 PM, Felipe Balbi wrote:
> >>>On Fri, Jan 10, 2014 at 11:52:49AM +0200, Tero Kristo wrote:
> >>>>On 01/10/2014 01:15 AM, Felipe Balbi wrote:
> >>>>>On Thu, Jan 09, 2014 at 03:22:03PM -0600, Nishanth Menon wrote:
> >>>>>>
> >>>>>>conflicts with be changes on Tony's be branch.
> >>>>>>commit 80f304dd2360cf5d50953c4eb4e902536f6a1263
> >>>>>>     ARM: OMAP2+: raw read and write endian fix
> >>>>>>
> >>>>>>Conflict:
> >>>>>>arch/arm/mach-omap2/clkt_clksel.c
> >>>>>>arch/arm/mach-omap2/clkt_dpll.c
> >>>>>>arch/arm/mach-omap2/clkt_iclk.c
> >>>>>>arch/arm/mach-omap2/clock.c
> >>>>>>arch/arm/mach-omap2/clock36xx.c
> >>>>>>arch/arm/mach-omap2/dpll3xxx.c
> >>>>>>arch/arm/mach-omap2/dpll44xx.c
> >>>>>>
> >>>>>>Both change raw_readls -> should now be just clk api instead which
> >>>>>>already does readl_relaxed etc.. If Tony feels like, then we should
> >>>>>>probably post a branch based on 'be' branch for easy merge.
> >
> >This should be a trivial merge conflict to handle, so let's not base
> >things on the BE changes.
> >
> >>>>I think all of these fails are caused by the initially bugged
> >>>>Makefile + Kconfig under mach-omap2. Seems like they can be fixed by
> >>>>the patches I inlined at the end (will also post them as proper
> >>>>patches to l-o list after this.) The question is, should Mike go
> >>>>ahead and merge these along with the base clk patches or how should
> >>>>we handle them? Patch 1 must be merged, patch 2 is a nice to have one
> >>>>which allows DRA7 only builds (doing DRA7 only build currently seems
> >>>>not possible.)
> >>>
> >>>If it's OK with Tony, I would suggest having a branch with both patches
> >>>below which both Tony and Mike merge before merging CCF series. That way
> >>>we avoid bisection problems.
> >
> >I can queue those two separately as fixes.
> >
> >>That reminds me, I think the baseline branch for the mach-omap2
> >>patches is still somewhat unclear to me, what should be used for
> >>this? And which patches should be put there (the mach-omap2 patches
> >>depend on the drivers/clk/ti part basically, so I need to put at
> >>least those there also.)
> >
> >I would keep the clock patches against some mainline -rc commit if
> >possible, and if there are non trivial merge conflicts, the omap
> >to use as the base is commit adfe9361b236154215d4b0fc8b6d79995394b15c.
> >
> >In any case, it's probably best that Mike merges this all via his
> >clock tree unless there non-trivial merge conflicts.
> >
> 
> I just pushed a branch against rc7 with makefile fixes in place to
> fix omap1 and omap2 only builds for this stuff. Inlined the delta
> here at the end. Do you want me to repost the series as v14 for this
> or is the attached delta ok for review purposes? All the changes have
> been squashed to existing patches (except the 2 patches I posted
> separately for DRA7xx / AM43xx only builds.)
> 
> The test branch itself can be found here:
> 
> tree: https://github.com/t-kristo/linux-pm.git
> branch: 3.13-rc7-dt-clks-v13-build-fixes
> 
> Felipe, care to run your randconfig magic for this?

This branch builds just fine so far, I still have omap5 multiplaform and
uniplatform builds, but since that was working before i'm assuming it
won't break.

cheers

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140114/144666a9/attachment-0001.sig>

^ permalink raw reply

* [PATCH] msm_serial: Add support for poll_{get,put}_char()
From: Stephen Boyd @ 2014-01-14 20:34 UTC (permalink / raw)
  To: linux-arm-kernel

Implement the polling functionality for the MSM serial driver.
This allows us to use KGDB on this hardware.

Cc: David Brown <davidb@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/tty/serial/msm_serial.c | 140 +++++++++++++++++++++++++++++++++++++++-
 drivers/tty/serial/msm_serial.h |   9 +++
 2 files changed, 146 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index b5d779cd3c2b..053b98eb46c8 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -39,6 +39,13 @@
 
 #include "msm_serial.h"
 
+enum {
+	UARTDM_1P1 = 1,
+	UARTDM_1P2,
+	UARTDM_1P3,
+	UARTDM_1P4,
+};
+
 struct msm_port {
 	struct uart_port	uart;
 	char			name[16];
@@ -309,6 +316,8 @@ static unsigned int msm_get_mctrl(struct uart_port *port)
 
 static void msm_reset(struct uart_port *port)
 {
+	struct msm_port *msm_port = UART_TO_MSM(port);
+
 	/* reset everything */
 	msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
 	msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
@@ -316,6 +325,10 @@ static void msm_reset(struct uart_port *port)
 	msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
 	msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
 	msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
+
+	/* Disable DM modes */
+	if (msm_port->is_uartdm)
+		msm_write(port, 0, UARTDM_DMEN);
 }
 
 static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
@@ -711,6 +724,117 @@ static void msm_power(struct uart_port *port, unsigned int state,
 	}
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int msm_poll_init(struct uart_port *port)
+{
+	struct msm_port *msm_port = UART_TO_MSM(port);
+
+	/* Enable single character mode on RX FIFO */
+	if (msm_port->is_uartdm >= UARTDM_1P4)
+		msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN);
+
+	return 0;
+}
+
+static int msm_poll_get_char_single(struct uart_port *port)
+{
+	struct msm_port *msm_port = UART_TO_MSM(port);
+	unsigned int rf_reg = msm_port->is_uartdm ? UARTDM_RF : UART_RF;
+
+	if (!(msm_read(port, UART_SR) & UART_SR_RX_READY))
+		return NO_POLL_CHAR;
+	else
+		return msm_read(port, rf_reg) & 0xff;
+}
+
+static int msm_poll_get_char_dm_1p3(struct uart_port *port)
+{
+	int c;
+	static u32 slop;
+	static int count;
+	unsigned char *sp = (unsigned char *)&slop;
+
+	/* Check if a previous read had more than one char */
+	if (count) {
+		c = sp[sizeof(slop) - count];
+		count--;
+	/* Or if FIFO is empty */
+	} else if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) {
+		/*
+		 * If RX packing buffer has less than a word, force stale to
+		 * push contents into RX FIFO
+		 */
+		count = msm_read(port, UARTDM_RXFS);
+		count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
+		if (count) {
+			msm_write(port, UART_CR_CMD_FORCE_STALE, UART_CR);
+			slop = msm_read(port, UARTDM_RF);
+			c = sp[0];
+			count--;
+		} else {
+			c = NO_POLL_CHAR;
+		}
+	/* FIFO has a word */
+	} else {
+		slop = msm_read(port, UARTDM_RF);
+		c = sp[0];
+		count = sizeof(slop) - 1;
+	}
+
+	return c;
+}
+
+static int msm_poll_get_char(struct uart_port *port)
+{
+	u32 imr;
+	int c;
+	struct msm_port *msm_port = UART_TO_MSM(port);
+
+	/* Disable all interrupts */
+	imr = msm_read(port, UART_IMR);
+	msm_write(port, 0, UART_IMR);
+
+	if (msm_port->is_uartdm == UARTDM_1P3)
+		c = msm_poll_get_char_dm_1p3(port);
+	else
+		c = msm_poll_get_char_single(port);
+
+	/* Enable interrupts */
+	msm_write(port, imr, UART_IMR);
+
+	return c;
+}
+
+static void msm_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	u32 imr;
+	struct msm_port *msm_port = UART_TO_MSM(port);
+
+	/* Disable all interrupts */
+	imr = msm_read(port, UART_IMR);
+	msm_write(port, 0, UART_IMR);
+
+	if (msm_port->is_uartdm)
+		reset_dm_count(port, 1);
+
+	/* Wait until FIFO is empty */
+	while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
+		cpu_relax();
+
+	/* Write a character */
+	msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
+
+	/* Wait until FIFO is empty */
+	while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
+		cpu_relax();
+
+	/* Enable interrupts */
+	msm_write(port, imr, UART_IMR);
+
+	return;
+}
+#endif
+
 static struct uart_ops msm_uart_pops = {
 	.tx_empty = msm_tx_empty,
 	.set_mctrl = msm_set_mctrl,
@@ -729,6 +853,11 @@ static struct uart_ops msm_uart_pops = {
 	.config_port = msm_config_port,
 	.verify_port = msm_verify_port,
 	.pm = msm_power,
+#ifdef CONFIG_CONSOLE_POLL
+	.poll_init = msm_poll_init,
+	.poll_get_char	= msm_poll_get_char,
+	.poll_put_char	= msm_poll_put_char,
+#endif
 };
 
 static struct msm_port msm_uart_ports[] = {
@@ -900,7 +1029,10 @@ static struct uart_driver msm_uart_driver = {
 static atomic_t msm_uart_next_id = ATOMIC_INIT(0);
 
 static const struct of_device_id msm_uartdm_table[] = {
-	{ .compatible = "qcom,msm-uartdm" },
+	{ .compatible = "qcom,msm-uartdm-v1.1", .data = (void *)UARTDM_1P1 },
+	{ .compatible = "qcom,msm-uartdm-v1.2", .data = (void *)UARTDM_1P2 },
+	{ .compatible = "qcom,msm-uartdm-v1.3", .data = (void *)UARTDM_1P3 },
+	{ .compatible = "qcom,msm-uartdm-v1.4", .data = (void *)UARTDM_1P4 },
 	{ }
 };
 
@@ -909,6 +1041,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
 	struct msm_port *msm_port;
 	struct resource *resource;
 	struct uart_port *port;
+	const struct of_device_id *id;
 	int irq;
 
 	if (pdev->id == -1)
@@ -923,8 +1056,9 @@ static int __init msm_serial_probe(struct platform_device *pdev)
 	port->dev = &pdev->dev;
 	msm_port = UART_TO_MSM(port);
 
-	if (of_match_device(msm_uartdm_table, &pdev->dev))
-		msm_port->is_uartdm = 1;
+	id = of_match_device(msm_uartdm_table, &pdev->dev);
+	if (id)
+		msm_port->is_uartdm = (unsigned long)id->data;
 	else
 		msm_port->is_uartdm = 0;
 
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 469fda50ac63..1e9b68b6f9eb 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -59,6 +59,7 @@
 #define UART_CR_CMD_RESET_RFR		(14 << 4)
 #define UART_CR_CMD_PROTECTION_EN	(16 << 4)
 #define UART_CR_CMD_STALE_EVENT_ENABLE	(80 << 4)
+#define UART_CR_CMD_FORCE_STALE		(4 << 8)
 #define UART_CR_CMD_RESET_TX_READY	(3 << 8)
 #define UART_CR_TX_DISABLE		(1 << 3)
 #define UART_CR_TX_ENABLE		(1 << 2)
@@ -113,6 +114,14 @@
 #define GSBI_PROTOCOL_UART	0x40
 #define GSBI_PROTOCOL_IDLE	0x0
 
+#define UARTDM_RXFS		0x50
+#define UARTDM_RXFS_BUF_SHIFT	0x7
+#define UARTDM_RXFS_BUF_MASK	0x7
+
+#define UARTDM_DMEN		0x3C
+#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
+#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
+
 #define UARTDM_DMRX		0x34
 #define UARTDM_NCF_TX		0x40
 #define UARTDM_RX_TOTAL_SNAP	0x38
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [PATCH] ARM: OMAP4: sleep: byteswap data for big-endian
From: Victor Kamensky @ 2014-01-14 20:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGo_u6oKpRFnPAWaqr9NTNAJB+m56jiDgBUgvsiZpaQ-3SF2kw@mail.gmail.com>

On 14 January 2014 09:56, Nishanth Menon <nm@ti.com> wrote:
> On Tue, Jan 14, 2014 at 11:35 AM, Victor Kamensky
> <victor.kamensky@linaro.org> wrote:
>>
>> When BE kernel is built Makefile does take of compiling code in BE
>> mode. I.e all proper flags like -mbig-endian and -Wl,--be8 will be set.
>
> Agreed, and I assume you cannot instead switch to LE mode when
> entering assembly assuming LE?

Yes. Note that this asm interacts with other data in kernel that would
be in BE form. And after all linker will not allow to put together files
that were compiled in different endianity.

> The reason I ask this is - most of our development is NOT in BE mode.
> we will continue to manipulate and add assembly - AM335x, DRA7/OMAP5
> etc.. and obviously not every code change will indulge in ensuring
> right markers will be in place.
>
> by ensuring readl_relaxed handles the variations, you have ensured
> that I dont need to care about drivers other than to ensure they use
> _relaxed variants. in the case of assembly, this does not seem long
> term manageable.

Yes, I agree if it is outside of main use case it will get broken if not
attended to. Definitely universe entropy increases :) - if left without
attention things will decay. Note we admit that even with ARM CPU
core BE changes similar decay can happen eventually ...that is
what LNG BE group trying to prevent. I think
the deal here is that next user of it can/need to fix things if they
decayed.

>>
>>> is the idea of BE build meant to deal with having a single BE kernel
>>> build work for all platforms (including LE ones)?
>>
>> Sort of. The idea here to run BE image on OMAP4 chip, with
>> kernel that would deals with LE periphery correctly, but ARM
>> core run in BE with special kernel that compiled for BE case (i.e
>> CONFIG_CPU_BIG_ENDIAN is set).
>
> I still dont get the usecase - other than "hey, we do this coz we can
> do it!".. I mean, yep, it sounds great and all.. but 4 years down the
> line, is this still going to work? is this going to be interesting
> careabout? or we are just maintaining additional code for a passing
> fancy or proof-of-concept?

Valid concern. From LNG BE group point of view it is not "we can do
it". It is more like we've done it. We have Pandaboard ES running BE
kernel for a while. It is in LNG BE tree. We used it as development
and testing vehicle for BE work for a while. We are very grateful to
the platform for that - it is affordable and easily available! Given,
beyond ongoing BE testing on Pandaboard in LNG there may not be valid
use case for further things on OMAP4 BE. We had discussion
with Santosh Shilimkar from TI during last Linaro connect what to
do with LNG BE Pandaboard series. Santosh suggested and we
agreed that we would try to contribute them back to community. And
that is what Taras is doing. IMHO even though there may not be real
product use case for BE OMAP4, it could serve in kernel source as good
example that shows how to work with LE periphery from BE kernel. After
all, these changes are noop for LE case and they don't introduce
a lot of clutter: all BE asm rev and rev16 instructions wrapped around
with ARM_BE8 macro.

Thanks,
Victor

> Regards,
> Nishanth Menon

^ permalink raw reply

* [PATCH 1/2] clk: hisilicon: add hi3620_mmc_clks
From: Mike Turquette @ 2014-01-14 20:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389604469-8064-2-git-send-email-zhangfei.gao@linaro.org>

Quoting Zhangfei Gao (2014-01-13 01:14:28)
> Suggest by Arnd: abstract mmc tuning as clock behavior,
> also because different soc have different tuning method and registers.
> hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.
> 
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Jaehoon Chung <jh80.chung@samsung.com>

Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the
clk-next branch. Is there a stable branch I can pull in as a dependency?

Thanks,
Mike

> ---
>  .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
>  .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
>  drivers/clk/hisilicon/clk-hi3620.c                 |  267 ++++++++++++++++++++
>  include/dt-bindings/clock/hi3620-clock.h           |    5 +
>  4 files changed, 287 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
> index 8c7a4653508d..df0a452b8526 100644
> --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
> @@ -30,3 +30,17 @@ Example:
>                 resume-offset = <0x308>;
>                 reboot-offset = <0x4>;
>         };
> +
> +PCTRL: Peripheral misc control register
> +
> +Required Properties:
> +- compatible: "hisilicon,pctrl"
> +- reg: Address and size of pctrl.
> +
> +Example:
> +
> +       /* for Hi3620 */
> +       pctrl: pctrl at fca09000 {
> +               compatible = "hisilicon,pctrl";
> +               reg = <0xfca09000 0x1000>;
> +       };
> diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt
> index 4b71ab41be53..dad6269f52c5 100644
> --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt
> +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt
> @@ -7,6 +7,7 @@ Required Properties:
>  
>  - compatible: should be one of the following.
>    - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
> +  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
>  
>  - reg: physical base address of the controller and length of memory mapped
>    region.
> diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c
> index f24ad6a3a797..54cc3475ec36 100644
> --- a/drivers/clk/hisilicon/clk-hi3620.c
> +++ b/drivers/clk/hisilicon/clk-hi3620.c
> @@ -240,3 +240,270 @@ static void __init hi3620_clk_init(struct device_node *np)
>                                    base);
>  }
>  CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
> +
> +struct hisi_mmc_clock {
> +       unsigned int            id;
> +       const char              *name;
> +       const char              *parent_name;
> +       unsigned long           flags;
> +       u32                     clken_reg;
> +       u32                     clken_bit;
> +       u32                     div_reg;
> +       u32                     div_off;
> +       u32                     div_bits;
> +       u32                     drv_reg;
> +       u32                     drv_off;
> +       u32                     drv_bits;
> +       u32                     sam_reg;
> +       u32                     sam_off;
> +       u32                     sam_bits;
> +};
> +
> +struct clk_mmc {
> +       struct clk_hw   hw;
> +       u32             id;
> +       void __iomem    *clken_reg;
> +       u32             clken_bit;
> +       void __iomem    *div_reg;
> +       u32             div_off;
> +       u32             div_bits;
> +       void __iomem    *drv_reg;
> +       u32             drv_off;
> +       u32             drv_bits;
> +       void __iomem    *sam_reg;
> +       u32             sam_off;
> +       u32             sam_bits;
> +};
> +
> +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
> +
> +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
> +       { HI3620_SD_CIUCLK,     "sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4},
> +       { HI3620_MMC_CIUCLK1,   "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4},
> +       { HI3620_MMC_CIUCLK2,   "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4},
> +       { HI3620_MMC_CIUCLK3,   "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4},
> +};
> +
> +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
> +                      unsigned long parent_rate)
> +{
> +       switch (parent_rate) {
> +       case 26000000:
> +               return 13000000;
> +       case 180000000:
> +               return 25000000;
> +       case 360000000:
> +               return 50000000;
> +       case 720000000:
> +               return 100000000;
> +       default:
> +               return parent_rate;
> +       }
> +}
> +
> +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
> +                             unsigned long *best_parent_rate,
> +                             struct clk **best_parent_p)
> +{
> +       struct clk_mmc *mclk = to_mmc(hw);
> +       unsigned long best = 0;
> +
> +       if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {
> +               rate = 13000000;
> +               best = 26000000;
> +       } else if (rate <= 26000000) {
> +               rate = 25000000;
> +               best = 180000000;
> +       } else if (rate <= 52000000) {
> +               rate = 50000000;
> +               best = 360000000;
> +       } else if (rate <= 100000000) {
> +               rate = 100000000;
> +               best = 720000000;
> +       } else {
> +               /* max is 180M */
> +               rate = 180000000;
> +               best = 1440000000;
> +       }
> +       *best_parent_rate = best;
> +       return rate;
> +}
> +
> +static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
> +{
> +       u32 i;
> +
> +       if (para >= 0) {
> +               for (i = 0; i < len; i++) {
> +                       if (para % 2)
> +                               val |= 1 << (off + i);
> +                       else
> +                               val &= ~(1 << (off + i));
> +                       para = para >> 1;
> +               }
> +       }
> +       return val;
> +}
> +
> +static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
> +{
> +       struct clk_mmc *mclk = to_mmc(hw);
> +       unsigned long flags;
> +       u32 sam, drv, div, val;
> +       static DEFINE_SPINLOCK(mmc_clk_lock);
> +
> +       switch (rate) {
> +       case 13000000:
> +               sam = 3;
> +               drv = 1;
> +               div = 1;
> +               break;
> +       case 25000000:
> +               sam = 13;
> +               drv = 6;
> +               div = 6;
> +               break;
> +       case 50000000:
> +               sam = 3;
> +               drv = 6;
> +               div = 6;
> +               break;
> +       case 100000000:
> +               sam = 6;
> +               drv = 4;
> +               div = 6;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       spin_lock_irqsave(&mmc_clk_lock, flags);
> +
> +       val = readl_relaxed(mclk->clken_reg);
> +       val &= ~(1 << mclk->clken_bit);
> +       writel_relaxed(val, mclk->clken_reg);
> +
> +       val = readl_relaxed(mclk->sam_reg);
> +       val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
> +       writel_relaxed(val, mclk->sam_reg);
> +
> +       val = readl_relaxed(mclk->drv_reg);
> +       val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
> +       writel_relaxed(val, mclk->drv_reg);
> +
> +       val = readl_relaxed(mclk->div_reg);
> +       val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
> +       writel_relaxed(val, mclk->div_reg);
> +
> +       val = readl_relaxed(mclk->clken_reg);
> +       val |= 1 << mclk->clken_bit;
> +       writel_relaxed(val, mclk->clken_reg);
> +
> +       spin_unlock_irqrestore(&mmc_clk_lock, flags);
> +
> +       return 0;
> +}
> +
> +static int mmc_clk_prepare(struct clk_hw *hw)
> +{
> +       struct clk_mmc *mclk = to_mmc(hw);
> +       unsigned long rate;
> +
> +       if (mclk->id == HI3620_MMC_CIUCLK1)
> +               rate = 13000000;
> +       else
> +               rate = 25000000;
> +
> +       return mmc_clk_set_timing(hw, rate);
> +}
> +
> +static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> +                            unsigned long parent_rate)
> +{
> +       return mmc_clk_set_timing(hw, rate);
> +}
> +
> +static struct clk_ops clk_mmc_ops = {
> +       .prepare = mmc_clk_prepare,
> +       .determine_rate = mmc_clk_determine_rate,
> +       .set_rate = mmc_clk_set_rate,
> +       .recalc_rate = mmc_clk_recalc_rate,
> +};
> +
> +static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
> +                       void __iomem *base, struct device_node *np)
> +{
> +       struct clk_mmc *mclk;
> +       struct clk *clk;
> +       struct clk_init_data init;
> +
> +       mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
> +       if (!mclk) {
> +               pr_err("%s: fail to allocate mmc clk\n", __func__);
> +               return ERR_PTR(-ENOMEM);
> +       }
> +
> +       init.name = mmc_clk->name;
> +       init.ops = &clk_mmc_ops;
> +       init.flags = mmc_clk->flags | CLK_IS_BASIC;
> +       init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
> +       init.num_parents = (mmc_clk->parent_name ? 1 : 0);
> +       mclk->hw.init = &init;
> +
> +       mclk->id = mmc_clk->id;
> +       mclk->clken_reg = base + mmc_clk->clken_reg;
> +       mclk->clken_bit = mmc_clk->clken_bit;
> +       mclk->div_reg = base + mmc_clk->div_reg;
> +       mclk->div_off = mmc_clk->div_off;
> +       mclk->div_bits = mmc_clk->div_bits;
> +       mclk->drv_reg = base + mmc_clk->drv_reg;
> +       mclk->drv_off = mmc_clk->drv_off;
> +       mclk->drv_bits = mmc_clk->drv_bits;
> +       mclk->sam_reg = base + mmc_clk->sam_reg;
> +       mclk->sam_off = mmc_clk->sam_off;
> +       mclk->sam_bits = mmc_clk->sam_bits;
> +
> +       clk = clk_register(NULL, &mclk->hw);
> +       if (WARN_ON(IS_ERR(clk)))
> +               kfree(mclk);
> +       return clk;
> +}
> +
> +static void __init hi3620_mmc_clk_init(struct device_node *node)
> +{
> +       void __iomem *base;
> +       int i, num = ARRAY_SIZE(hi3620_mmc_clks);
> +       struct clk_onecell_data *clk_data;
> +
> +       if (!node) {
> +               pr_err("failed to find pctrl node in DTS\n");
> +               return;
> +       }
> +
> +       base = of_iomap(node, 0);
> +       if (!base) {
> +               pr_err("failed to map pctrl\n");
> +               return;
> +       }
> +
> +       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
> +       if (WARN_ON(!clk_data))
> +               return;
> +
> +       clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
> +       if (!clk_data->clks) {
> +               pr_err("%s: fail to allocate mmc clk\n", __func__);
> +               return;
> +       }
> +
> +       for (i = 0; i < num; i++) {
> +               struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
> +               clk_data->clks[mmc_clk->id] =
> +                       hisi_register_clk_mmc(mmc_clk, base, node);
> +       }
> +
> +       clk_data->clk_num = num;
> +       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +}
> +
> +CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
> diff --git a/include/dt-bindings/clock/hi3620-clock.h b/include/dt-bindings/clock/hi3620-clock.h
> index 6eaa6a45e110..21b9d0e2eb0c 100644
> --- a/include/dt-bindings/clock/hi3620-clock.h
> +++ b/include/dt-bindings/clock/hi3620-clock.h
> @@ -147,6 +147,11 @@
>  #define HI3620_MMC_CLK3                217
>  #define HI3620_MCU_CLK         218
>  
> +#define HI3620_SD_CIUCLK       0
> +#define HI3620_MMC_CIUCLK1     1
> +#define HI3620_MMC_CIUCLK2     2
> +#define HI3620_MMC_CIUCLK3     3
> +
>  #define HI3620_NR_CLKS         219
>  
>  #endif /* __DTS_HI3620_CLOCK_H */
> -- 
> 1.7.9.5
> 

^ permalink raw reply

* [PATCH v2 1/2] dmaengine: add Qualcomm BAM dma driver
From: Stephen Boyd @ 2014-01-14 19:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389380874-22753-2-git-send-email-agross@codeaurora.org>

(Mostly nitpicks)

On 01/10, Andy Gross wrote:
> Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
> found in the MSM 8x74 platforms.
> 
> Each BAM DMA device is associated with a specific on-chip peripheral.  Each
> channel provides a uni-directional data transfer engine that is capable of
> transferring data between the peripheral and system memory (System mode), or
> between two peripherals (BAM2BAM).
> 
> The initial release of this driver only supports slave transfers between
> peripherals and system memory.
> 
> Signed-off-by: Andy Gross <agross@codeaurora.org>
> ---
>  drivers/dma/Kconfig        |   9 +
>  drivers/dma/Makefile       |   1 +
>  drivers/dma/qcom_bam_dma.c | 843 +++++++++++++++++++++++++++++++++++++++++++++
>  drivers/dma/qcom_bam_dma.h | 268 ++++++++++++++
>  4 files changed, 1121 insertions(+)
>  create mode 100644 drivers/dma/qcom_bam_dma.c
>  create mode 100644 drivers/dma/qcom_bam_dma.h
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index c823daa..e58e6d2 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -384,4 +384,13 @@ config DMATEST
>  config DMA_ENGINE_RAID
>  	bool
>  
> +config QCOM_BAM_DMA
> +	tristate "QCOM BAM DMA support"
> +	depends on ARCH_MSM || COMPILE_TEST

I don't think writel_relaxed() is available on every arch, so
it's possible this will break some random arch that doesn't have
that function.

> +	select DMA_ENGINE
> +	select DMA_VIRTUAL_CHANNELS
> +	---help---
> +	  Enable support for the QCOM BAM DMA controller.  This controller
> +	  provides DMA capabilities for a variety of on-chip devices.
> +
>  endif
> diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
> new file mode 100644
> index 0000000..7a84b02
> --- /dev/null
> +++ b/drivers/dma/qcom_bam_dma.c
[...]
> +static int bam_alloc_chan(struct dma_chan *chan)
[...]
> +
> +	/* Go ahead and initialize the pipe/channel hardware here
> +	   - Reset the channel to clear internal state of the FIFO
> +	   - Program in the FIFO address
> +	   - Configure the irq based on the EE passed in from the DT entry
> +	   - Set mode, direction and enable channel
> +
> +	   We do this here because the channel can only be enabled once and
> +	   can only be disabled via a reset.  If done here, we don't have to
> +	   manage additional state to figure out when to do this
> +	*/

Multi-line comments are of the form:

	/*
	 * comment
	 */

> +
> +	bam_reset_channel(bdev, bchan->id);
> +
> +	/* write out 8 byte aligned address.  We have enough space for this
> +	   because we allocated 1 more descriptor (8 bytes) than we can use */
> +	writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
> +			bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id));
> +	writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs +
> +			BAM_P_FIFO_SIZES(bchan->id));
[...]
> +
> +/**
> + * bam_dma_terminate_all - terminate all transactions
> + * @chan: dma channel
> + *
> + * Idles channel and dequeues and frees all transactions
> + * No callbacks are done
> + *
> +*/

Weird '*' starting the line here and on the next function.

> +static void bam_dma_terminate_all(struct dma_chan *chan)
> +{
> +	struct bam_chan *bchan = to_bam_chan(chan);
> +	struct bam_device *bdev = bchan->bdev;
> +
> +	bam_reset_channel(bdev, bchan->id);
> +
> +	vchan_free_chan_resources(&bchan->vc);
> +}
> +
> +/**
> + * bam_control - DMA device control
> + * @chan: dma channel
> + * @cmd: control cmd
> + * @arg: cmd argument
> + *
> + * Perform DMA control command
> + *
> +*/
> +static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
> +	unsigned long arg)
> +{
> +	struct bam_chan *bchan = to_bam_chan(chan);
> +	struct bam_device *bdev = bchan->bdev;
> +	int ret = 0;
> +	unsigned long flag;
> +
[...]
> +/**
> + * bam_dma_irq - irq handler for bam controller
> + * @irq: IRQ of interrupt
> + * @data: callback data
> + *
> + * IRQ handler for the bam controller
> + */
> +static irqreturn_t bam_dma_irq(int irq, void *data)
> +{
> +	struct bam_device *bdev = (struct bam_device *)data;

Unnecessary cast from void.

> +static int bam_dma_probe(struct platform_device *pdev)
> +{
[...]
> +
> +	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +	if (!irq_res) {
> +		dev_err(bdev->dev, "irq resource is missing\n");
> +		return -EINVAL;
> +	}

Please use platform_get_irq() instead.

> diff --git a/drivers/dma/qcom_bam_dma.h b/drivers/dma/qcom_bam_dma.h
> new file mode 100644
> index 0000000..2cb3b5f
> --- /dev/null
> +++ b/drivers/dma/qcom_bam_dma.h
[...]
> +#define BAM_CNFG_BITS_DEFAULT	(BAM_PIPE_CNFG |	\
> +			BAM_NO_EXT_P_RST |		\
> +			BAM_IBC_DISABLE |		\
> +			BAM_SB_CLK_REQ |		\
> +			BAM_PSM_CSW_REQ |		\
> +			BAM_PSM_P_RES |			\
> +			BAM_AU_P_RES |			\
> +			BAM_SI_P_RES |			\
> +			BAM_WB_P_RES |			\
> +			BAM_WB_BLK_CSW |		\
> +			BAM_WB_CSW_ACK_IDL |		\
> +			BAM_WB_RETR_SVPNT |		\
> +			BAM_WB_DSC_AVL_P_RST |		\
> +			BAM_REG_P_EN |			\
> +			BAM_PSM_P_HD_DATA |		\
> +			BAM_AU_ACCUMED |		\
> +			BAM_CMD_ENABLE)
> +
> +/* PIPE CTRL */
> +#define	P_EN			BIT(1)

Nit: Weird formatting here?

> +#define P_DIRECTION		BIT(3)
[...]
> +
> +
> +struct bam_device {
> +	void __iomem *regs;
> +	struct device *dev;
> +	struct dma_device common;
> +	struct device_dma_parameters dma_parms;
> +	struct bam_chan *channels;

Maybe this should be a flexible array. It looks like probe might
need to be rewritten to detect the number of channels from the
hardware before assigning anything, but it should be possible.
But it probably doesn't matter.

> +	u32 num_channels;
> +	u32 num_ees;
> +	unsigned long enabled_ees;
> +	int irq;

Is irq used?

> +	struct clk *bamclk;
> +
> +	/* dma start transaction tasklet */
> +	struct tasklet_struct task;
> +};

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [PATCH V6 3/8] Add helper function to get and convert EFI command line
From: Roy Franz @ 2014-01-14 19:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140113150406.GE3256@console-pimps.org>

On Mon, Jan 13, 2014 at 7:04 AM, Matt Fleming <matt@console-pimps.org> wrote:
> On Fri, 10 Jan, at 08:30:12AM, Roy Franz wrote:
>> Add an EFI stub helper function to retrieve the EFI command line using
>> the LOADED_IMAGE_PROTOCOL, and convert it to ASCII.  This function will
>> be shared by the various EFI stub implementations.
>>
>> Signed-off-by: Roy Franz <roy.franz@linaro.org>
>> ---
>>  drivers/firmware/efi/efi-stub-helper.c |   30 ++++++++++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
>> index eb5d2eb..f657456 100644
>> --- a/drivers/firmware/efi/efi-stub-helper.c
>> +++ b/drivers/firmware/efi/efi-stub-helper.c
>> @@ -637,3 +637,33 @@ static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
>>       *cmd_line_len = options_size;
>>       return (char *)cmdline_addr;
>>  }
>> +
>> +/*
>> + * get the command line from EFI, using the LOADED_IMAGE
>> + * protocol, and convert to ASCII.
>> + *
>> + */
>> +static void efi_get_cmdline(efi_system_table_t *sys_table,
>> +                           efi_loaded_image_t **image,
>> +                           void *handle, char **cmdline_ptr)
>> +{
>
> Wouldn't this prototype make more sense?
>
> static char *efi_get_cmdline(efi_system_table_t *sys_table,
>                              efi_loaded_image_t **image,
>                              void *handle);
>
> Is this function really worth implementing at all? Certainly on x86, we
> lookup the loaded image protocol for reasons other than parsing the
> command line, and so would need to do it in the caller anyway.
>
> --
> Matt Fleming, Intel Open Source Technology Center

Yeah, this should just go away.  This was the result of some
over-zealous moving code from arm/arm64 to shared code.

Roy

^ permalink raw reply

* [PATCH V6 0/8] Add ARM EFI stub
From: Roy Franz @ 2014-01-14 19:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140113150735.GF3256@console-pimps.org>

On Mon, Jan 13, 2014 at 7:07 AM, Matt Fleming <matt@console-pimps.org> wrote:
> On Fri, 10 Jan, at 08:30:09AM, Roy Franz wrote:
>> This patch series adds EFI stub support for the ARM architecture.  The
>> stub for ARM is implemented in a similar manner to x86 in that it is a
>> shim layer between EFI and the normal zImage/bzImage boot process, and
>> that an image with the stub configured is bootable as both a zImage and
>> EFI application.  This patchset adds common code that is shared with
>> the ARM64 EFI stub.
>>
>> This patch depends on Leif Lindholm's ARM v7 runtime services patchset, which
>> in turn depends on Mark Salter's early_io_remap() patchset.  This EFI stub
>> patchset can be tested without those by simply modifying the Kconfig for
>> EFI_STUB to not depend on EFI.  The kernel will boot using the stub,
>> however no EFI support will be available in the kernel.
>>
>> I have addressed all the feedback I have recieved to date, and I am hoping
>> that this patchset is acceptable for merging into 3.14.  It has been
>> functionally stable for some time, and provides useful functionality.
>> Further consolidation of the ARM/ARM64 stubs planned as part of the
>> ongoing development of the stubs and supporting tools for both
>> architectures (getting the FDT from a UEFI configuration table, using UEFI
>> memory map instead of FDT for memory description.)
>
> Is this going to Linus via one of the ARM maintainer trees?
>
> --
> Matt Fleming, Intel Open Source Technology Center

Hi Matt,

    Yes, this is planned to go through one of the ARM trees.  Given
that this relies on the early_io_remap
patchsets that have not been accepted yet, I don't see this being
accepted for 3.14.

Roy

^ permalink raw reply

* [PATCH 1/3] crypto: Fix the pointer voodoo in unaligned ahash
From: Tom Lendacky @ 2014-01-14 19:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389720829-5963-2-git-send-email-marex@denx.de>


On Tuesday, January 14, 2014 06:33:47 PM Marek Vasut wrote:
> Add documentation for the pointer voodoo that is happening in crypto/ahash.c
> in ahash_op_unaligned(). This code is quite confusing, so add a beefy chunk
> of documentation.
> 
> Moreover, make sure the mangled request is completely restored after finishing
> this unaligned operation. This means restoring all of .result, .priv, .base.data
> and .base.complete .
> 
> Also, remove the crypto_completion_t complete = ... line present in the
> ahash_op_unaligned_done() function. This type actually declares a function
> pointer, which is very confusing.
> 
> Finally, yet very important nonetheless, make sure the req->priv is free()'d
> only after the original request is restored in ahash_op_unaligned_done().
> The req->priv data must not be free()'d before that in ahash_op_unaligned_finish(),
> since we would be accessing previously free()'d data in ahash_op_unaligned_done()
> and cause corruption.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Cc: Shawn Guo <shawn.guo@linaro.org>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>  crypto/ahash.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 54 insertions(+), 11 deletions(-)
> 
> diff --git a/crypto/ahash.c b/crypto/ahash.c
> index a92dc38..5ca8ede 100644
> --- a/crypto/ahash.c
> +++ b/crypto/ahash.c
> @@ -29,6 +29,7 @@
>  struct ahash_request_priv {
>  	crypto_completion_t complete;
>  	void *data;
> +	void *priv;
>  	u8 *result;
>  	void *ubuf[] CRYPTO_MINALIGN_ATTR;
>  };
> @@ -200,23 +201,38 @@ static void ahash_op_unaligned_finish(struct ahash_request *req, int err)
>  	if (!err)
>  		memcpy(priv->result, req->result,
>  		       crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
> -
> -	kzfree(priv);

You can't move/remove this kzfree since a synchronous operation will not take
the ahash_op_unaligned_done path.  A synchronous operation will never return
-EINPROGRESS and the effect will be to never free the priv structure.

>  }
>  
> -static void ahash_op_unaligned_done(struct crypto_async_request *req, int err)
> +static void ahash_op_unaligned_done(struct crypto_async_request *areq, int err)
>  {
> -	struct ahash_request *areq = req->data;
> -	struct ahash_request_priv *priv = areq->priv;
> -	crypto_completion_t complete = priv->complete;
> -	void *data = priv->data;
> +	struct ahash_request *req = areq->data;
> +	struct ahash_request_priv *priv = req->priv;
> +	struct crypto_async_request *data;
> +
> +	/*
> +	 * Restore the original request, see ahash_op_unaligned() for what
> +	 * goes where.
> +	 *
> +	 * The "struct ahash_request *req" here is in fact the "req.base"
> +	 * from the ADJUSTED request from ahash_op_unaligned(), thus as it
> +	 * is a pointer to self, it is also the ADJUSTED "req" .
> +	 */
> +
> +	/* First copy req->result into req->priv.result */
> +	ahash_op_unaligned_finish(req, err);

Given the above comment on the kzfree, you'll need to save all the priv
values as was done previously.

Thanks,
Tom

>  
> -	ahash_op_unaligned_finish(areq, err);
> +	/* Restore the original crypto request. */
> +	req->result = priv->result;
> +	req->base.complete = priv->complete;
> +	req->base.data = priv->data;
> +	req->priv = priv->priv;
>  
> -	areq->base.complete = complete;
> -	areq->base.data = data;
> +	/* Free the req->priv.priv from the ADJUSTED request. */
> +	kzfree(priv);
>  
> -	complete(&areq->base, err);
> +	/* Complete the ORIGINAL request. */
> +	data = req->base.data;
> +	req->base.complete(data, err);
>  }
>  
>  static int ahash_op_unaligned(struct ahash_request *req,
> @@ -234,9 +250,36 @@ static int ahash_op_unaligned(struct ahash_request *req,
>  	if (!priv)
>  		return -ENOMEM;
>  
> +	/*
> +	 * WARNING: Voodoo programming below!
> +	 *
> +	 * The code below is obscure and hard to understand, thus explanation
> +	 * is necessary. See include/crypto/hash.h and include/linux/crypto.h
> +	 * to understand the layout of structures used here!
> +	 *
> +	 * The code here will replace portions of the ORIGINAL request with
> +	 * pointers to new code and buffers so the hashing operation can store
> +	 * the result in aligned buffer. We will call the modified request
> +	 * an ADJUSTED request.
> +	 *
> +	 * The newly mangled request will look as such:
> +	 *
> +	 * req {
> +	 *   .result        = ADJUSTED[new aligned buffer]
> +	 *   .base.complete = ADJUSTED[pointer to completion function]
> +	 *   .base.data     = ADJUSTED[*req (pointer to self)]
> +	 *   .priv          = ADJUSTED[new priv] {
> +	 *           .result   = ORIGINAL(result)
> +	 *           .complete = ORIGINAL(base.complete)
> +	 *           .data     = ORIGINAL(base.data)
> +	 *           .priv     = ORIGINAL(priv)
> +	 *   }
> +	 */
> +
>  	priv->result = req->result;
>  	priv->complete = req->base.complete;
>  	priv->data = req->base.data;
> +	priv->priv = req->priv;
>  
>  	req->result = PTR_ALIGN((u8 *)priv->ubuf, alignmask + 1);
>  	req->base.complete = ahash_op_unaligned_done;
> -- 
> 1.8.5.2
> 
> 

^ permalink raw reply

* [PATCH V6 6/8] Add EFI stub for ARM
From: Roy Franz @ 2014-01-14 19:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_JsqLDVBfYomiNpFRacku4pJ3TrFy4rKJKedGp+LPGQt4m0w@mail.gmail.com>

On Tue, Jan 14, 2014 at 11:29 AM, Rob Herring <robherring2@gmail.com> wrote:
> On Fri, Jan 10, 2014 at 10:30 AM, Roy Franz <roy.franz@linaro.org> wrote:
>> This patch adds EFI stub support for the ARM Linux kernel.  The EFI stub
>> operates similarly to the x86 stub: it is a shim between the EFI firmware
>> and the normal zImage entry point, and sets up the environment that the
>> zImage is expecting.  This includes loading the initrd (optionaly) and
>> device tree from the system partition based on the kernel command line.
>> The stub updates the device tree as necessary, adding entries for EFI
>> runtime services. The PE/COFF "MZ" header at offset 0 results in the
>> first instruction being an add that corrupts r5, which is not used by
>> the zImage interface.
>>
>> Signed-off-by: Roy Franz <roy.franz@linaro.org>
>> Acked-by: Grant Likely <grant.likely@linaro.org>
>> ---
>
> [snip]
>
>> +       /* Look up the base of DRAM from the device tree. */
>> +       fdt = (void *)fdt_addr;
>> +       node = fdt_subnode_offset(fdt, 0, "memory");
>> +       region = fdt_getprop(fdt, node, "reg", NULL);
>> +       if (region) {
>> +               dram_base = fdt64_to_cpu(region->base);
>
> This will not work if the address is 32-bit size.
>
>> +       } else {
>> +               /* There is no way to get amount or addresses of physical
>> +                * memory installed using EFI calls.  If the device tree
>> +                * we read from disk doesn't have this, there is no way
>> +                * for us to construct this informaion.
>> +                */
>> +               pr_efi_err(sys_table, "No 'memory' node in device tree.\n");
>> +               goto fail_free_fdt;
>
> The current pc can't be used to determine the DRAM base like AUTO_ZRELADDR?
>
> Rob

Hi Rob,

   UEFI may load the stub based kernel anywhere, so we don't get any
useful information from where we were loaded.
I am currently working on getting the base address from the EFI memory
map, so all of the above code will go away, the only FDT
operations that the stub will perform is to add the EFI related fields.

Roy

^ permalink raw reply

* [PATCH V6 6/8] Add EFI stub for ARM
From: Rob Herring @ 2014-01-14 19:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389371417-379-7-git-send-email-roy.franz@linaro.org>

On Fri, Jan 10, 2014 at 10:30 AM, Roy Franz <roy.franz@linaro.org> wrote:
> This patch adds EFI stub support for the ARM Linux kernel.  The EFI stub
> operates similarly to the x86 stub: it is a shim between the EFI firmware
> and the normal zImage entry point, and sets up the environment that the
> zImage is expecting.  This includes loading the initrd (optionaly) and
> device tree from the system partition based on the kernel command line.
> The stub updates the device tree as necessary, adding entries for EFI
> runtime services. The PE/COFF "MZ" header at offset 0 results in the
> first instruction being an add that corrupts r5, which is not used by
> the zImage interface.
>
> Signed-off-by: Roy Franz <roy.franz@linaro.org>
> Acked-by: Grant Likely <grant.likely@linaro.org>
> ---

[snip]

> +       /* Look up the base of DRAM from the device tree. */
> +       fdt = (void *)fdt_addr;
> +       node = fdt_subnode_offset(fdt, 0, "memory");
> +       region = fdt_getprop(fdt, node, "reg", NULL);
> +       if (region) {
> +               dram_base = fdt64_to_cpu(region->base);

This will not work if the address is 32-bit size.

> +       } else {
> +               /* There is no way to get amount or addresses of physical
> +                * memory installed using EFI calls.  If the device tree
> +                * we read from disk doesn't have this, there is no way
> +                * for us to construct this informaion.
> +                */
> +               pr_efi_err(sys_table, "No 'memory' node in device tree.\n");
> +               goto fail_free_fdt;

The current pc can't be used to determine the DRAM base like AUTO_ZRELADDR?

Rob

^ permalink raw reply

* [PATCH 4/6] arm64: add EFI stub
From: Roy Franz @ 2014-01-14 19:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389710640.26822.10.camel@deneb.redhat.com>

On Tue, Jan 14, 2014 at 6:44 AM, Mark Salter <msalter@redhat.com> wrote:
> On Mon, 2014-01-13 at 19:49 +0100, Arnd Bergmann wrote:
>> On Friday 10 January 2014, Mark Salter wrote:
>> > This patch adds PE/COFF header fields to the start of the Image
>> > so that it appears as an EFI application to EFI firmware. An EFI
>> > stub is included to allow direct booting of the kernel Image. Due
>> > to EFI firmware limitations, only little endian kernels with 4K
>> > page sizes are supported at this time. Support in the COFF header
>> > for signed images was provided by Ard Biesheuvel.
>> >
>> > Signed-off-by: Mark Salter <msalter@redhat.com>
>> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>
>> You got the ordering of the S-o-b lines wrong. Since you send the
>> patch, your name should come last.
>
> Yes.
>
>>
>> > +config EFI_STUB
>> > +     bool "EFI stub support"
>> > +     depends on !ARM64_64K_PAGES && OF
>> > +     select LIBFDT
>> > +     default y
>> > +     help
>> > +       This kernel feature allows an Image to be loaded directly
>> > +       by EFI firmware without the use of a bootloader.
>> > +       See Documentation/efi-stub.txt for more information.
>> > +
>> >  endmenu
>>
>> Why not ARM64_64K_PAGES? I thought that it was going to be the
>> default for a lot of distros that would need to run on UEFI systems.
>
> The UEFI spec currently mandates 4k page size. We may be able to work
> around that or get the spec changed, but for now it is just 4k pages.
>
>>
>> >  menu "Userspace binary formats"
>> > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> > index 5ba2fd4..1c52b84 100644
>> > --- a/arch/arm64/kernel/Makefile
>> > +++ b/arch/arm64/kernel/Makefile
>> > @@ -4,6 +4,8 @@
>> >
>> >  CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
>> >  AFLAGS_head.o                := -DTEXT_OFFSET=$(TEXT_OFFSET)
>> > +CFLAGS_efi-stub.o    := -DTEXT_OFFSET=$(TEXT_OFFSET) \
>> > +                        -I$(src)/../../../scripts/dtc/libfdt
>>
>> Hmm, this is pretty ugly. I notice the same has been done on MIPS
>> as well, but I'd hope we can find a proper way to do it.
>
> Yes, I just copied that from mips. I can look into some more.
>
>>
>> > diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
>> > new file mode 100644
>> > index 0000000..10d02bf
>> > --- /dev/null
>> > +++ b/arch/arm64/kernel/efi-stub.c
>> > +
>> > +/* Include shared EFI stub code */
>> > +#include "../../../drivers/firmware/efi/efi-stub-helper.c"
>> > +#include "../../../drivers/firmware/efi/fdt.c"
>>
>> It gets worse here.
>
> Well, I'm open to suggestions here. The shared code has to work with
> stubs which are built into kernel (arm64) and which are part of the
> compressed image wrapper.
>

The decompression algorithms are shared among the compressed image
wrappers using #include of C code, so this is
following that convention.  The only other mechanism that I saw for
sharing code with the compressed image wrappers was
copying of files, as is done with the FDT files for the ARM compressed
wrapper.  I agree that neither of these is elegant, but
whatever we do needs to work for compiling into the decompression
wrapper (arm) and the kernel proper (arm64).

Roy

^ permalink raw reply

* [PATCH] ARM: OMAP4: sleep: byteswap data for big-endian
From: Ben Dooks @ 2014-01-14 19:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGo_u6oKpRFnPAWaqr9NTNAJB+m56jiDgBUgvsiZpaQ-3SF2kw@mail.gmail.com>

On 14/01/14 17:56, Nishanth Menon wrote:
> On Tue, Jan 14, 2014 at 11:35 AM, Victor Kamensky
> <victor.kamensky@linaro.org> wrote:
>>
>> When BE kernel is built Makefile does take of compiling code in BE
>> mode. I.e all proper flags like -mbig-endian and -Wl,--be8 will be set.
>
> Agreed, and I assume you cannot instead switch to LE mode when
> entering assembly assuming LE?

You could make it so that individual pieces of code could swap
back to big-endian, however that would introduce the possibility
of bugs if the code used a pointer to memory passed in, or refers
to a piece of data in another part of the code which is built in
big endian.


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ 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