* [PATCH v2 1/4] arm64: export memblock_reserve()d regions via /proc/iomem
From: James Morse @ 2018-06-19 15:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <72307608-90e0-4842-edc1-d3b284782940@oracle.com>
Hi Dave,
On 19/06/18 14:37, Dave Kleikamp wrote:
> On 06/19/2018 01:44 AM, AKASHI Takahiro wrote:
>> +static int __init reserve_memblock_reserved_regions(void)
>> +{
>> + phys_addr_t start, end, roundup_end = 0;
>> + struct resource *mem, *res;
>> + u64 i;
>> +
>> + for_each_reserved_mem_region(i, &start, &end) {
>> + if (end <= roundup_end)
>> + continue; /* done already */
>> +
>> + start = __pfn_to_phys(PFN_DOWN(start));
>> + end = __pfn_to_phys(PFN_UP(end)) - 1;
>> + roundup_end = end;
>> +
>> + res = kzalloc(sizeof(*res), GFP_ATOMIC);
>> + if (WARN_ON(!res))
>> + return -ENOMEM;
>> + res->start = start;
>> + res->end = end;
>> + res->name = "reserved";
>> + res->flags = IORESOURCE_MEM;
>> +
>> + mem = request_resource_conflict(&iomem_resource, res);
>> + /*
>> + * We expected memblock_reserve() regions to conflict with
>> + * memory created by request_standard_resources().
>> + */
>> + if (WARN_ON_ONCE(!mem))
>> + continue;
>> + kfree(res);
>
> Why is kfree() after the conditional continue? This is a memory leak.
request_resource_conflict() inserts res into the iomem_resource tree, or returns
the conflict if there is already something at this address.
We expect something at this address: a 'System RAM' section added by
request_resource(). This code wants the conflicting 'System RAM' entry so that
reserve_region_with_split() can fill in the gaps below it with 'reserved'. See
the commit-message for an example.
If there was no conflict, it means the memory map doesn't look like we expect,
we can't pass NULL to reserve_region_with_split(), and we just inserted the
'reserved' at the top level. Freeing res at this point would be a use-after-free
hanging from /proc/iomem.
This code generates a WARN_ON_ONCE() and leaves the 'reserved' description where
it is.
Trying to cleanup here is pointless, we can remove the resource entry and free
it ... but we still want to report it as reserved, which is what just happened,
just not quite how we we wanted it.
If you ever see this warning, it means some RAM stopped being nomap between
request_resources() and reserve_memblock_reserved_regions(). I can't find any
case where that ever happens.
If all that makes sense: how can I improve the comment above the WARN_ON_ONCE()
to make it clearer?
Thanks,
James
>> +
>> + reserve_region_with_split(mem, start, end, "reserved");
>> + }
>> +
>> + return 0;
>> +}
>> +arch_initcall(reserve_memblock_reserved_regions);
>> +
>> u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
>>
>> void __init setup_arch(char **cmdline_p)
>>
^ permalink raw reply
* [PATCHv3 08/19] arm64: convert raw syscall invocation to C
From: Mark Rutland @ 2018-06-19 14:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619145541.xi3yybejmbfenrum@armageddon.cambridge.arm.com>
On Tue, Jun 19, 2018 at 03:55:42PM +0100, Catalin Marinas wrote:
> On Tue, Jun 19, 2018 at 03:48:45PM +0100, Mark Rutland wrote:
> > On Tue, Jun 19, 2018 at 03:21:25PM +0100, Catalin Marinas wrote:
> > > On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> > > > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > > > new file mode 100644
> > > > index 000000000000..b463b962d597
> > > > --- /dev/null
> > > > +++ b/arch/arm64/kernel/syscall.c
> > > > @@ -0,0 +1,30 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +
> > > > +#include <linux/nospec.h>
> > > > +#include <linux/ptrace.h>
> > > > +
> > > > +long do_ni_syscall(struct pt_regs *regs);
> > > > +
> > > > +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> > > > + unsigned long, unsigned long,
> > > > + unsigned long, unsigned long);
> > > > +
> > > > +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> > > > +{
> > > > + regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> > > > + regs->regs[2], regs->regs[3],
> > > > + regs->regs[4], regs->regs[5]);
> > > > +}
> > > > +
> > > > +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> > > > + unsigned int sc_nr,
> > > > + syscall_fn_t syscall_table[])
> > > > +{
> > > > + if (scno < sc_nr) {
> > > > + syscall_fn_t syscall_fn;
> > > > + syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > > > + __invoke_syscall(regs, syscall_fn);
> > > > + } else {
> > > > + regs->regs[0] = do_ni_syscall(regs);
> > > > + }
> > > > +}
> > >
> > > While reviewing the subsequent patch, it crossed my mind that we no
> > > longer have any callers to do_ni_syscall() outside this file. Can we not
> > > more it here and have a similar implementation to __invoke_syscall() for
> > > consistency, i.e. set regs->regs[0].
> >
> > I think so, though it complicates the logic in do_ni_syscall(), since
> > there are two places we may return a value.
> >
> > Would you be happy if instead I made __invoke_syscall() return the
> > result, and have invoke_syscall() place the result in regs->regs[0] in
> > either case, e.g. as below?
>
> It looks fine. Feel free to keep the original reviewed-by tag.
Will do; cheers!
Mark.
^ permalink raw reply
* next/master boot: 138 boots: 8 failed, 112 passed with 18 offline (next-20180619)
From: Heiko Stübner @ 2018-06-19 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619144143.GE11230@sirena.org.uk>
> > On Tue, Jun 19, 2018 at 07:00:13AM -0700, kernelci.org bot wrote:
> >
> > Today and yesterday's -next is failing to boot on rk3399-firefly in two
> >
> > configs:
> >> defconfig:
> >> rk3399-firefly:
> >> lab-baylibre-seattle: failing since 1 day (last pass:
> >> next-20180615 - first fail: next-20180618)>>
> >> defconfig+CONFIG_RANDOMIZE_BASE=y:
> >> rk3399-firefly:
> >> lab-baylibre-seattle: failing since 1 day (last pass:
> >> next-20180615 - first fail: next-20180618)>
> > The log ends with:
> >
> > [ 2.629278] SWITCH_REG2: supplied by vcc3v3_sys
> > [ 2.633030] fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1]
> > Detected! [ 2.633723] fan53555-reg: supplied by vcc_sys
> > [ 2.6353|] Internal error: undefined instruction: 0 [#1] PREEMPT SMP
> >
> > which is rather entertaining.
> Am Dienstag, 19. Juni 2018, 16:41:43 CEST schrieb Mark Brown:
> On Tue, Jun 19, 2018 at 03:22:47PM +0100, Sudeep Holla wrote:
> > Based on the logs from successful boots, I see it's CPUFreq that gets
> > probed after fan53555-reg. I also see that it warns about unlisted OPPs
> > in the successful boots. I guess, the undefined instruction could occur
> > if there's issue with CPU DVFS(under voltage or frequency that's not
> > supported). I don't have much knowledge on the platform, I am just
> > guessing on the possible cause here.
>
> Yeah, that was my guess - either an out of spec voltage/frequency was
> selected or the regulator isn't able to keep up with the voltage
> transition or a load spike and the power browns out.
I guess this is related to
arm64: dts: rockchip: correct voltage selector Firefly-RK3399 [0]
which is in so far interesting as the patch seems to fix a similar issue
to the above with the opposite "fcs,suspend-voltage-selector" value.
And also claims to be in line with the vendor kernel.
>From looking at the schematics, we might have a discrepancy between the
fcs,suspend-voltage-selector and vsel input-pin leading to a gpio
[likely depending on what the bootloader set this pin up for].
I'll drop the patch for now and get in contact with the patch submitter.
Heiko
[0] https://patchwork.kernel.org/patch/10447075/
^ permalink raw reply
* [PATCH 15/20] dts: arm: imx7{d,s}: Update coresight binding for hardware ports
From: Mathieu Poirier @ 2018-06-19 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619021218.GV16091@dragon>
On Mon, 18 Jun 2018 at 20:13, Shawn Guo <shawnguo@kernel.org> wrote:
>
> Hi Stefan,
>
> Can you take a look at the patch? Thanks.
>
These bindings are still being discussed and patches related to them
shouldn't be merged. The next iteration of this patchset will not
included individual modifications to device tree files, that will be
left for a later time when bindings have been agreed upon.
Thanks,
Mathieu
> Shawn
>
> On Tue, Jun 05, 2018 at 10:43:26PM +0100, Suzuki K Poulose wrote:
> > Switch to the updated coresight bindings.
> >
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Cc: Sascha Hauer <s.hauer@pengutronix.de>
> > Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> > Cc: Fabio Estevam <fabio.estevam@nxp.com>
> > Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > ---
> > arch/arm/boot/dts/imx7d.dtsi | 5 ++++-
> > arch/arm/boot/dts/imx7s.dtsi | 41 ++++++++++++++++++++++++++++++-----------
> > 2 files changed, 34 insertions(+), 12 deletions(-)
> >
> > diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
> > index 200714e..5faff17 100644
> > --- a/arch/arm/boot/dts/imx7d.dtsi
> > +++ b/arch/arm/boot/dts/imx7d.dtsi
> > @@ -87,7 +87,9 @@
> >
> > port {
> > etm1_out_port: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&ca_funnel_in_port1>;
> > + coresight,hwid = <0>;
> > };
> > };
> > };
> > @@ -174,8 +176,9 @@
> > port at 1 {
> > reg = <1>;
> > ca_funnel_in_port1: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&etm1_out_port>;
> > + coresight,hwid = <1>;
> > };
> > };
> > };
> > diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
> > index 4d42335..8e90915 100644
> > --- a/arch/arm/boot/dts/imx7s.dtsi
> > +++ b/arch/arm/boot/dts/imx7s.dtsi
> > @@ -151,23 +151,28 @@
> > port at 0 {
> > reg = <0>;
> > replicator_out_port0: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&tpiu_in_port>;
> > + coresight,hwid = <0>;
> > };
> > };
> >
> > port at 1 {
> > reg = <1>;
> > replicator_out_port1: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&etr_in_port>;
> > + coresight,hwid = <1>;
> > };
> > };
> >
> > /* replicator input port */
> > port at 2 {
> > - reg = <0>;
> > + reg = <2>;
> > replicator_in_port0: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&etf_out_port>;
> > + coresight,hwid = <0>;
> > };
> > };
> > };
> > @@ -203,16 +208,19 @@
> > port at 0 {
> > reg = <0>;
> > ca_funnel_in_port0: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&etm0_out_port>;
> > + coresight,hwid = <0>;
> > };
> > };
> >
> > /* funnel output port */
> > port at 2 {
> > - reg = <0>;
> > + reg = <2>;
> > ca_funnel_out_port0: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&hugo_funnel_in_port0>;
> > + coresight,hwid = <0>;
> > };
> > };
> >
> > @@ -229,7 +237,9 @@
> >
> > port {
> > etm0_out_port: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&ca_funnel_in_port0>;
> > + coresight,hwid = <0>;
> > };
> > };
> > };
> > @@ -248,22 +258,26 @@
> > port at 0 {
> > reg = <0>;
> > hugo_funnel_in_port0: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&ca_funnel_out_port0>;
> > + coresight,hwid = <0>;
> > };
> > };
> >
> > port at 1 {
> > reg = <1>;
> > hugo_funnel_in_port1: endpoint {
> > - slave-mode; /* M4 input */
> > + direction = <0>; /* M4 input */
> > + coresight,hwid = <1>;
> > };
> > };
> >
> > port at 2 {
> > - reg = <0>;
> > + reg = <2>;
> > hugo_funnel_out_port0: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&etf_in_port>;
> > + coresight,hwid = <0>;
> > };
> > };
> >
> > @@ -284,15 +298,18 @@
> > port at 0 {
> > reg = <0>;
> > etf_in_port: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&hugo_funnel_out_port0>;
> > + coresight,hwid = <0>;
> > };
> > };
> >
> > port at 1 {
> > - reg = <0>;
> > + reg = <1>;
> > etf_out_port: endpoint {
> > + direction = <1>;
> > remote-endpoint = <&replicator_in_port0>;
> > + coresight,hwid = <0>;
> > };
> > };
> > };
> > @@ -306,8 +323,9 @@
> >
> > port {
> > etr_in_port: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&replicator_out_port1>;
> > + coresight,hwid = <0>;
> > };
> > };
> > };
> > @@ -320,8 +338,9 @@
> >
> > port {
> > tpiu_in_port: endpoint {
> > - slave-mode;
> > + direction = <0>;
> > remote-endpoint = <&replicator_out_port1>;
> > + coresight,hwid = <0>;
> > };
> > };
> > };
> > --
> > 2.7.4
> >
^ permalink raw reply
* [PATCHv3 08/19] arm64: convert raw syscall invocation to C
From: Catalin Marinas @ 2018-06-19 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619144845.22mgd4req5cnp5tv@lakrids.cambridge.arm.com>
On Tue, Jun 19, 2018 at 03:48:45PM +0100, Mark Rutland wrote:
> On Tue, Jun 19, 2018 at 03:21:25PM +0100, Catalin Marinas wrote:
> > On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> > > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > > new file mode 100644
> > > index 000000000000..b463b962d597
> > > --- /dev/null
> > > +++ b/arch/arm64/kernel/syscall.c
> > > @@ -0,0 +1,30 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +
> > > +#include <linux/nospec.h>
> > > +#include <linux/ptrace.h>
> > > +
> > > +long do_ni_syscall(struct pt_regs *regs);
> > > +
> > > +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> > > + unsigned long, unsigned long,
> > > + unsigned long, unsigned long);
> > > +
> > > +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> > > +{
> > > + regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> > > + regs->regs[2], regs->regs[3],
> > > + regs->regs[4], regs->regs[5]);
> > > +}
> > > +
> > > +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> > > + unsigned int sc_nr,
> > > + syscall_fn_t syscall_table[])
> > > +{
> > > + if (scno < sc_nr) {
> > > + syscall_fn_t syscall_fn;
> > > + syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > > + __invoke_syscall(regs, syscall_fn);
> > > + } else {
> > > + regs->regs[0] = do_ni_syscall(regs);
> > > + }
> > > +}
> >
> > While reviewing the subsequent patch, it crossed my mind that we no
> > longer have any callers to do_ni_syscall() outside this file. Can we not
> > more it here and have a similar implementation to __invoke_syscall() for
> > consistency, i.e. set regs->regs[0].
>
> I think so, though it complicates the logic in do_ni_syscall(), since
> there are two places we may return a value.
>
> Would you be happy if instead I made __invoke_syscall() return the
> result, and have invoke_syscall() place the result in regs->regs[0] in
> either case, e.g. as below?
It looks fine. Feel free to keep the original reviewed-by tag.
--
Catalin
^ permalink raw reply
* [PATCH 5/5] RFC: ARM64: dts: Add Low-Speed Connector to ZCU100
From: Rob Herring @ 2018-06-19 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618074556.6944-6-linus.walleij@linaro.org>
+David G
On Mon, Jun 18, 2018 at 1:45 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
> This adds the low-speed connector to the ZCU100 rev C device
> tree (also known as the Ultra96 board).
>
> This is a proof-of-concept only, showing how it is possible
> to populate a Secure96 board using the other patches in the
> series.
>
> If you comment out or delete the board {} node, you can
> populate/depopulate the board from sysfs instead.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> .../boot/dts/xilinx/zynqmp-zcu100-revC.dts | 27 +++++++++++++++++--
> 1 file changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> index d62276e0e0a9..fc30497f248d 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> @@ -110,6 +110,28 @@
> compatible = "mmc-pwrseq-simple";
> reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */
> };
> +
> + lscon: connector {
> + compatible = "96boards,low-speed-connector";
> + i2c0 = <&i2csw_0>;
> + i2c1 = <&i2csw_1>;
> + spi = <&spi0>;
David had suggested having an aliases node here for mapping things
like SPI and I2C. That actually seems like a good use for aliases
compared to the usual abuse to make Linux provide fixed numbering.
> + gpios = <&gpio 36 GPIO_ACTIVE_HIGH>, /* GPIO-A */
Why aren't you using gpio-map? This is what it was defined for.
> + <&gpio 37 GPIO_ACTIVE_HIGH>, /* GPIO-B */
> + <&gpio 39 GPIO_ACTIVE_HIGH>, /* GPIO-C */
> + <&gpio 40 GPIO_ACTIVE_HIGH>, /* GPIO-D */
> + <&gpio 44 GPIO_ACTIVE_HIGH>, /* GPIO-E */
> + <&gpio 45 GPIO_ACTIVE_HIGH>, /* GPIO-F */
> + <&gpio 78 GPIO_ACTIVE_HIGH>, /* GPIO-G */
> + <&gpio 79 GPIO_ACTIVE_HIGH>, /* GPIO-H */
> + <&gpio 80 GPIO_ACTIVE_HIGH>, /* GPIO-I */
> + <&gpio 81 GPIO_ACTIVE_HIGH>, /* GPIO-J */
> + <&gpio 82 GPIO_ACTIVE_HIGH>, /* GPIO-K */
> + <&gpio 83 GPIO_ACTIVE_HIGH>; /* GPIO-L */
> + board {
> + compatible = "96boards,secure96";
I'm all for putting things in the kernel/drivers for things we can't
nail down bindings for, but it really seems like you are punting all
the problems. Plus if we fully define how to handle the different
bindings, we'll likely end up with something different and
incompatible with what you have here.
Rob
^ permalink raw reply
* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Punit Agrawal @ 2018-06-19 14:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619140818.GA16927@e107981-ln.cambridge.arm.com>
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> writes:
> On Tue, Jun 19, 2018 at 01:52:16PM +0100, Punit Agrawal wrote:
>> Michal Hocko <mhocko@kernel.org> writes:
>>
>> > On Tue 19-06-18 20:03:07, Xie XiuQi wrote:
>> > [...]
>> >> I tested on a arm board with 128 cores 4 numa nodes, but I set CONFIG_NR_CPUS=72.
>> >> Then node 3 is not be created, because node 3 has no memory, and no cpu.
>> >> But some pci device may related to node 3, which be set in ACPI table.
>> >
>> > Could you double check that zonelists for node 3 are generated
>> > correctly?
>>
>> The cpus in node 3 aren't onlined and there's no memory attached - I
>> suspect that no zonelists are built for this node.
>>
>> We skip creating a node, if the number of SRAT entries parsed exceeds
>> NR_CPUS[0]. This in turn prevents onlining the numa node and so no
>> zonelists will be created for it.
>>
>> I think the problem will go away if the cpus are restricted via the
>> kernel command line by setting nr_cpus.
>>
>> Xie, can you try the below patch on top of the one enabling memoryless
>> nodes? I'm not sure this is the right solution but at least it'll
>> confirm the problem.
>
> This issue looks familiar (or at least related):
>
> git log d3bd058826aa
Indeed. Thanks for digging into this.
>
> The reason why the NR_CPUS guard is there is to avoid overflowing
> the early_node_cpu_hwid array.
Ah right... I missed that. The below patch is definitely not what we
want.
> IA64 does something different in
> that respect compared to x86, we have to have a look into this.
>
> Regardless, AFAICS the proximity domains to nodes mappings should not
> depend on CONFIG_NR_CPUS, it seems that there is something wrong in that
> in ARM64 ACPI SRAT parsing.
Not only SRAT parsing but it looks like there is a similar restriction
while parsing the ACPI MADT in acpi_map_gic_cpu_interface().
The incomplete parsing introduces a dependency on the ordering of
entries being aligned between SRAT and MADT when NR_CPUS is
restricted. We want to parse the entire table in both cases so that the
code is robust to reordering of entries.
In terms of $SUBJECT, I wonder if it's worth taking the original patch
as a temporary fix (it'll also be easier to backport) while we work on
fixing these other issues and enabling memoryless nodes.
^ permalink raw reply
* [PATCHv3 08/19] arm64: convert raw syscall invocation to C
From: Mark Rutland @ 2018-06-19 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619142125.esqcbknxd2pqeotb@localhost>
On Tue, Jun 19, 2018 at 03:21:25PM +0100, Catalin Marinas wrote:
> On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > new file mode 100644
> > index 000000000000..b463b962d597
> > --- /dev/null
> > +++ b/arch/arm64/kernel/syscall.c
> > @@ -0,0 +1,30 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/nospec.h>
> > +#include <linux/ptrace.h>
> > +
> > +long do_ni_syscall(struct pt_regs *regs);
> > +
> > +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> > + unsigned long, unsigned long,
> > + unsigned long, unsigned long);
> > +
> > +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> > +{
> > + regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> > + regs->regs[2], regs->regs[3],
> > + regs->regs[4], regs->regs[5]);
> > +}
> > +
> > +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> > + unsigned int sc_nr,
> > + syscall_fn_t syscall_table[])
> > +{
> > + if (scno < sc_nr) {
> > + syscall_fn_t syscall_fn;
> > + syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> > + __invoke_syscall(regs, syscall_fn);
> > + } else {
> > + regs->regs[0] = do_ni_syscall(regs);
> > + }
> > +}
>
> While reviewing the subsequent patch, it crossed my mind that we no
> longer have any callers to do_ni_syscall() outside this file. Can we not
> more it here and have a similar implementation to __invoke_syscall() for
> consistency, i.e. set regs->regs[0].
I think so, though it complicates the logic in do_ni_syscall(), since
there are two places we may return a value.
Would you be happy if instead I made __invoke_syscall() return the
result, and have invoke_syscall() place the result in regs->regs[0] in
either case, e.g. as below?
Thanks,
Mark.
---->8----
// SPDX-License-Identifier: GPL-2.0
#include <linux/errno.h>
#include <linux/nospec.h>
#include <linux/ptrace.h>
#include <linux/syscalls.h>
#include <asm/compat.h>
long compat_arm_syscall(struct pt_regs *regs);
static long do_ni_syscall(struct pt_regs *regs)
{
#ifdef CONFIG_COMPAT
long ret;
if (is_compat_task()) {
ret = compat_arm_syscall(regs);
if (ret != -ENOSYS)
return ret;
}
#endif
return sys_ni_syscall();
}
typedef long (*syscall_fn_t)(unsigned long, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
{
return syscall_fn(regs->regs[0], regs->regs[1], regs->regs[2],
regs->regs[3], regs->regs[4], regs->regs[5]);
}
asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
unsigned int sc_nr,
syscall_fn_t syscall_table[])
{
long ret;
if (scno < sc_nr) {
syscall_fn_t syscall_fn;
syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
ret = __invoke_syscall(regs, syscall_fn);
} else {
ret = do_ni_syscall(regs);
}
regs->regs[0] = ret;
}
^ permalink raw reply
* [PATCH v3] irqchip/gic-v3: Ensure GICR_CTLR.EnableLPI=0 is observed before enabling
From: Marc Zyngier @ 2018-06-19 14:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8898674D84E3B24BA3A2D289B872026A69F37935@G01JPEXMBKW03>
Hi Lei,
On Tue, 19 Jun 2018 15:14:27 +0100,
"Zhang, Lei" <zhang.lei@jp.fujitsu.com> wrote:
>
> Hi shankerd, Marc
>
> I have one question.
>
> Does it means after GICR_CTLR.EnableLPI has been written to 1,
> if the bit GICR_CTLR.EnableLPI becomes RES1, we can't use LPIs?
> Because its_cpu_init_lpis and its_cpu_init_collections will not be called.
There are two issues:
- If EnableLPI is already set to 1, your redistributors are already
potentially corrupting the memory by writing to the pending
tables. Your system is now potentially unstable (single bit
corruption, depending on what the ITS outputs).
- If EnableLPI has become RES1, you cannot even turn it off to
reprogram things so that the property and pending tables are under
your control.
At that stage, your system is in a very bad shape, and LPIs are the
least of your problems.
Thanks,
M.
--
Jazz is not dead, it just smell funny.
^ permalink raw reply
* next/master boot: 138 boots: 8 failed, 112 passed with 18 offline (next-20180619)
From: Mark Brown @ 2018-06-19 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <69c0adb9-b784-4f73-fcc9-ff1a01ce27c5@arm.com>
On Tue, Jun 19, 2018 at 03:22:47PM +0100, Sudeep Holla wrote:
> Based on the logs from successful boots, I see it's CPUFreq that gets
> probed after fan53555-reg. I also see that it warns about unlisted OPPs
> in the successful boots. I guess, the undefined instruction could occur
> if there's issue with CPU DVFS(under voltage or frequency that's not
> supported). I don't have much knowledge on the platform, I am just
> guessing on the possible cause here.
Yeah, that was my guess - either an out of spec voltage/frequency was
selected or the regulator isn't able to keep up with the voltage
transition or a load spike and the power browns out.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180619/cd40b399/attachment.sig>
^ permalink raw reply
* [PATCHv3 09/19] arm64: convert syscall trace logic to C
From: Catalin Marinas @ 2018-06-19 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618120310.39527-10-mark.rutland@arm.com>
On Mon, Jun 18, 2018 at 01:03:00PM +0100, Mark Rutland wrote:
> +asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> + syscall_fn_t syscall_table[])
> +{
> + unsigned long flags = current_thread_info()->flags;
> +
> + regs->orig_x0 = regs->regs[0];
> + regs->syscallno = scno;
> +
> + local_daif_restore(DAIF_PROCCTX);
> + user_exit();
> +
> + if (has_syscall_work(flags)) {
> + /* set default errno for user-issued syscall(-1) */
> + if (scno == NO_SYSCALL)
> + regs->regs[0] = -ENOSYS;
> + scno = syscall_trace_enter(regs);
> + if (scno == NO_SYSCALL)
> + goto trace_exit;
> + }
> +
> + invoke_syscall(regs, scno, sc_nr, syscall_table);
> +
> + /*
> + * The tracing status may have changed under our feet, so we have to
> + * check again. However, if we were tracing entry, then we always trace
> + * exit regardless, as the old entry assembly did.
> + */
> + if (!has_syscall_work(flags)) {
> + local_daif_mask();
> + flags = current_thread_info()->flags;
> + if (!has_syscall_work(flags))
> + return;
> + local_daif_restore(DAIF_PROCCTX);
> + }
IIUC the above 'if' block replaces ret_fast_syscall in entry.S with the
work_pending handled via ret_to_user (we used to check _TIF_WORK_MASK in
two places).
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [linux-sunxi] [PATCH v3 4/4] arm64: dts: allwinner: a64: add SRAM controller device tree node
From: Icenowy Zheng @ 2018-06-19 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMty3ZCsPXh7Fhmhtd7UjTmJ9id+NeaZDVqkix1iQz7-fDqoUw@mail.gmail.com>
? 2018?6?19? GMT+08:00 ??3:36:19, Jagan Teki <jagan@amarulasolutions.com> ??:
>On Fri, Jun 15, 2018 at 4:39 AM, Icenowy Zheng <icenowy@aosc.io> wrote:
>>
>>
>> ? 2018?6?15? GMT+08:00 ??1:27:21, "Jernej ?krabec"
><jernej.skrabec@gmail.com> ??:
>>>Dne ?etrtek, 14. junij 2018 ob 19:09:56 CEST je Jagan Teki
>napisal(a):
>>>> On Thu, Jun 14, 2018 at 9:05 PM, Chen-Yu Tsai <wens@csie.org>
>wrote:
>>>> > From: Icenowy Zheng <icenowy@aosc.io>
>>>> >
>>>> > Allwinner A64 has a SRAM controller, and in the device tree
>>>currently
>>>> > we have a syscon node to enable EMAC driver to access the EMAC
>>>clock
>>>> > register. As SRAM controller driver can now export regmap for
>this
>>>> > register, replace the syscon node to the SRAM controller device
>>>node,
>>>> > and let EMAC driver to acquire its EMAC clock regmap.
>>>> >
>>>> > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>>>> > [wens at csie.org: Updated compatible string]
>>>> > Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>>>> > ---
>>>> >
>>>> > arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 19
>>>+++++++++++++++++--
>>>> > 1 file changed, 17 insertions(+), 2 deletions(-)
>>>> >
>>>> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>>>> > b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index
>>>> > 1b2ef28c42bd..87968dafe1dc 100644
>>>> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>>>> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>>>> > @@ -169,9 +169,24 @@
>>>> >
>>>> > ranges;
>>>> >
>>>> > syscon: syscon at 1c00000 {
>>>> >
>>>> > - compatible =
>>>> > "allwinner,sun50i-a64-system-controller", -
>>>
>>>> > "syscon";
>>>> > + compatible =
>>>> > "allwinner,sun50i-a64-system-control";
>>>> >
>>>> > reg = <0x01c00000 0x1000>;
>>>> >
>>>> > + #address-cells = <1>;
>>>> > + #size-cells = <1>;
>>>> > + ranges;
>>>> > +
>>>> > + sram_c: sram at 18000 {
>>>> > + compatible = "mmio-sram";
>>>> > + reg = <0x00018000 0x28000>;
>>>> > + #address-cells = <1>;
>>>> > + #size-cells = <1>;
>>>> > + ranges = <0 0x00018000 0x28000>;
>>>> > +
>>>> > + de2_sram: sram-section at 0 {
>>>>
>>>> So, this can attach to display-engine node through allwinner,sram
>and
>>>> add support to claim the sram on sun4i/sun4i_drv.c, correct?
>>>
>>>Actually, it has to be added to display_clocks node and claimed in
>>>drivers/
>>>clk/sunxi-ng/ccu-sun8i-de2.c
>>
>> Sorry it's old practice.
>>
>> My new way is to add a bus driver which claims the SRAM.
>
>Are you pointing this driver[1] ? if yes do we have recent version
>patches for these changes so-that I can import.
I'll resend it when this patchset is ready.
>
>[1] https://patchwork.kernel.org/patch/10290399/
^ permalink raw reply
* next/master boot: 138 boots: 8 failed, 112 passed with 18 offline (next-20180619)
From: Sudeep Holla @ 2018-06-19 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619141324.GD11230@sirena.org.uk>
On 19/06/18 15:13, Mark Brown wrote:
> On Tue, Jun 19, 2018 at 07:00:13AM -0700, kernelci.org bot wrote:
>
> Today and yesterday's -next is failing to boot on rk3399-firefly in two
> configs:
>
>> defconfig:
>> rk3399-firefly:
>> lab-baylibre-seattle: failing since 1 day (last pass: next-20180615 - first fail: next-20180618)
>
>> defconfig+CONFIG_RANDOMIZE_BASE=y:
>> rk3399-firefly:
>> lab-baylibre-seattle: failing since 1 day (last pass: next-20180615 - first fail: next-20180618)
>
> The log ends with:
>
> [ 2.629278] SWITCH_REG2: supplied by vcc3v3_sys
> [ 2.633030] fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected!
> [ 2.633723] fan53555-reg: supplied by vcc_sys
> [ 2.6353|] Internal error: undefined instruction: 0 [#1] PREEMPT SMP
>
> which is rather entertaining.
>
Based on the logs from successful boots, I see it's CPUFreq that gets
probed after fan53555-reg. I also see that it warns about unlisted OPPs
in the successful boots. I guess, the undefined instruction could occur
if there's issue with CPU DVFS(under voltage or frequency that's not
supported). I don't have much knowledge on the platform, I am just
guessing on the possible cause here.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCHv3 08/19] arm64: convert raw syscall invocation to C
From: Catalin Marinas @ 2018-06-19 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618120310.39527-9-mark.rutland@arm.com>
On Mon, Jun 18, 2018 at 01:02:59PM +0100, Mark Rutland wrote:
> diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> new file mode 100644
> index 000000000000..b463b962d597
> --- /dev/null
> +++ b/arch/arm64/kernel/syscall.c
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/nospec.h>
> +#include <linux/ptrace.h>
> +
> +long do_ni_syscall(struct pt_regs *regs);
> +
> +typedef long (*syscall_fn_t)(unsigned long, unsigned long,
> + unsigned long, unsigned long,
> + unsigned long, unsigned long);
> +
> +static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
> +{
> + regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
> + regs->regs[2], regs->regs[3],
> + regs->regs[4], regs->regs[5]);
> +}
> +
> +asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
> + unsigned int sc_nr,
> + syscall_fn_t syscall_table[])
> +{
> + if (scno < sc_nr) {
> + syscall_fn_t syscall_fn;
> + syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
> + __invoke_syscall(regs, syscall_fn);
> + } else {
> + regs->regs[0] = do_ni_syscall(regs);
> + }
> +}
While reviewing the subsequent patch, it crossed my mind that we no
longer have any callers to do_ni_syscall() outside this file. Can we not
more it here and have a similar implementation to __invoke_syscall() for
consistency, i.e. set regs->regs[0].
--
Catalin
^ permalink raw reply
* [PATCH v3] irqchip/gic-v3: Ensure GICR_CTLR.EnableLPI=0 is observed before enabling
From: Zhang, Lei @ 2018-06-19 14:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <86o9jf174o.wl-marc.zyngier@arm.com>
Hi shankerd, Marc
I have one question.
Does it means after GICR_CTLR.EnableLPI has been written to 1,
if the bit GICR_CTLR.EnableLPI becomes RES1, we can't use LPIs?
Because its_cpu_init_lpis and its_cpu_init_collections will not be called.
> whether
> + * the bit GICR_CTLR.EnableLPI becomes RES1 or can be cleared to
> 0.
> + * Bail out the driver probe() on systems where it's RES1.
> + *
> + /**
> + * After it has been written to 1, it is IMPLEMENTATION DEFINED
> whether
> + * the bit GICR_CTLR.EnableLPI becomes RES1 or can be cleared to
> 0.
> + * Bail out the driver probe() on systems where it's RES1.
> + */
> + if (readl_relaxed(rbase + GICR_CTLR) & GICR_CTLR_ENABLE_LPIS) {
> + pr_err("CPU%d: Failed to disable LPIs\n",
> smp_processor_id());
> + return -EBUSY;
> + }
Best Regards,
Lei Zhang
zhang.lei at jp.fujitsu.com
^ permalink raw reply
* next/master boot: 138 boots: 8 failed, 112 passed with 18 offline (next-20180619)
From: Mark Brown @ 2018-06-19 14:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5b290c6d.1c69fb81.fc936.98ee@mx.google.com>
On Tue, Jun 19, 2018 at 07:00:13AM -0700, kernelci.org bot wrote:
Today and yesterday's -next is failing to boot on rk3399-firefly in two
configs:
> defconfig:
> rk3399-firefly:
> lab-baylibre-seattle: failing since 1 day (last pass: next-20180615 - first fail: next-20180618)
> defconfig+CONFIG_RANDOMIZE_BASE=y:
> rk3399-firefly:
> lab-baylibre-seattle: failing since 1 day (last pass: next-20180615 - first fail: next-20180618)
The log ends with:
[ 2.629278] SWITCH_REG2: supplied by vcc3v3_sys
[ 2.633030] fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected!
[ 2.633723] fan53555-reg: supplied by vcc_sys
[ 2.6353|] Internal error: undefined instruction: 0 [#1] PREEMPT SMP
which is rather entertaining.
The pending fixes -next branch is fine. More diagnostics can be seen
at:
https://kernelci.org/boot/id/5b28eadb59b514636d79a877/
(that's the defconfig.) Other boards don't seem to be affected, there's
some other boards that are failing but don't seem to be related.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180619/0dbabfd4/attachment.sig>
^ permalink raw reply
* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Lorenzo Pieralisi @ 2018-06-19 14:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <874lhz3pmn.fsf@e105922-lin.cambridge.arm.com>
On Tue, Jun 19, 2018 at 01:52:16PM +0100, Punit Agrawal wrote:
> Michal Hocko <mhocko@kernel.org> writes:
>
> > On Tue 19-06-18 20:03:07, Xie XiuQi wrote:
> > [...]
> >> I tested on a arm board with 128 cores 4 numa nodes, but I set CONFIG_NR_CPUS=72.
> >> Then node 3 is not be created, because node 3 has no memory, and no cpu.
> >> But some pci device may related to node 3, which be set in ACPI table.
> >
> > Could you double check that zonelists for node 3 are generated
> > correctly?
>
> The cpus in node 3 aren't onlined and there's no memory attached - I
> suspect that no zonelists are built for this node.
>
> We skip creating a node, if the number of SRAT entries parsed exceeds
> NR_CPUS[0]. This in turn prevents onlining the numa node and so no
> zonelists will be created for it.
>
> I think the problem will go away if the cpus are restricted via the
> kernel command line by setting nr_cpus.
>
> Xie, can you try the below patch on top of the one enabling memoryless
> nodes? I'm not sure this is the right solution but at least it'll
> confirm the problem.
This issue looks familiar (or at least related):
git log d3bd058826aa
The reason why the NR_CPUS guard is there is to avoid overflowing
the early_node_cpu_hwid array. IA64 does something different in
that respect compared to x86, we have to have a look into this.
Regardless, AFAICS the proximity domains to nodes mappings should not
depend on CONFIG_NR_CPUS, it seems that there is something wrong in that
in ARM64 ACPI SRAT parsing.
Lorenzo
>
> Thanks,
> Punit
>
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/acpi_numa.c?h=v4.18-rc1#n73
>
> -- >8 --
> diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
> index d190a7b231bf..fea0f7164f1a 100644
> --- a/arch/arm64/kernel/acpi_numa.c
> +++ b/arch/arm64/kernel/acpi_numa.c
> @@ -70,11 +70,9 @@ void __init acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa)
> if (!(pa->flags & ACPI_SRAT_GICC_ENABLED))
> return;
>
> - if (cpus_in_srat >= NR_CPUS) {
> + if (cpus_in_srat >= NR_CPUS)
> pr_warn_once("SRAT: cpu_to_node_map[%d] is too small, may not be able to use all cpus\n",
> NR_CPUS);
> - return;
> - }
>
> pxm = pa->proximity_domain;
> node = acpi_map_pxm_to_node(pxm);
^ permalink raw reply
* [PATCH 3/3] arm64: IPI each CPU after invalidating the I-cache for kernel mappings
From: Mark Rutland @ 2018-06-19 13:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619135528.4rxgluvroybxgxem@lakrids.cambridge.arm.com>
On Tue, Jun 19, 2018 at 02:55:28PM +0100, Mark Rutland wrote:
> On Tue, Jun 19, 2018 at 01:48:15PM +0100, Will Deacon wrote:
> > When invalidating the instruction cache for a kernel mapping via
> > flush_icache_range(), it is also necessary to flush the pipeline for
> > other CPUs so that instructions fetched into the pipeline before the
> > I-cache invalidation are discarded. For example, if module 'foo' is
> > unloaded and then module 'bar' is loaded into the same area of memory,
> > a CPU could end up executing instructions from 'foo' when branching into
> > 'bar' if these instructions were fetched into the pipeline before 'foo'
> > was unloaded.
> >
> > Whilst this is highly unlikely to occur in practice, particularly as
> > any exception acts as a context-synchronizing operation, following the
> > letter of the architecture requires us to execute an ISB on each CPU
> > in order for the new instruction stream to be visible.
> >
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> > ---
> > arch/arm64/include/asm/cacheflush.h | 13 ++++++++++++-
> > arch/arm64/kernel/alternative.c | 1 -
> > arch/arm64/kernel/cpu_errata.c | 2 +-
> > arch/arm64/kernel/insn.c | 15 ++-------------
> > arch/arm64/mm/cache.S | 4 ++--
> > 5 files changed, 17 insertions(+), 18 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> > index d264a7274811..a0ec27066e6f 100644
> > --- a/arch/arm64/include/asm/cacheflush.h
> > +++ b/arch/arm64/include/asm/cacheflush.h
> > @@ -71,7 +71,7 @@
> > * - kaddr - page address
> > * - size - region size
> > */
> > -extern void flush_icache_range(unsigned long start, unsigned long end);
> > +extern void __flush_icache_range(unsigned long start, unsigned long end);
> > extern int invalidate_icache_range(unsigned long start, unsigned long end);
> > extern void __flush_dcache_area(void *addr, size_t len);
> > extern void __inval_dcache_area(void *addr, size_t len);
> > @@ -81,6 +81,17 @@ extern void __clean_dcache_area_pou(void *addr, size_t len);
> > extern long __flush_cache_user_range(unsigned long start, unsigned long end);
> > extern void sync_icache_aliases(void *kaddr, unsigned long len);
> >
> > +static inline void flush_icache_range(unsigned long start, unsigned long end)
> > +{
> > + __flush_icache_range(start, end);
> > +
> > + /*
> > + * IPI all online CPUs so that they undergo a context synchronization
> > + * event and are forced to refetch the new instructions.
> > + */
> > + kick_all_cpus_sync();
> > +}
> > +
> > static inline void flush_cache_mm(struct mm_struct *mm)
> > {
> > }
> > diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
> > index 4f3dcc15a5b2..0ac06560c166 100644
> > --- a/arch/arm64/kernel/alternative.c
> > +++ b/arch/arm64/kernel/alternative.c
> > @@ -205,7 +205,6 @@ static int __apply_alternatives_multi_stop(void *unused)
> > if (smp_processor_id()) {
> > while (!READ_ONCE(alternatives_applied))
> > cpu_relax();
> > - isb();
> > } else {
> > BUG_ON(alternatives_applied);
> > __apply_alternatives(®ion, false);
> > diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> > index 1d2b6d768efe..0a338a1cd2d7 100644
> > --- a/arch/arm64/kernel/cpu_errata.c
> > +++ b/arch/arm64/kernel/cpu_errata.c
> > @@ -101,7 +101,7 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
> > for (i = 0; i < SZ_2K; i += 0x80)
> > memcpy(dst + i, hyp_vecs_start, hyp_vecs_end - hyp_vecs_start);
> >
> > - flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
> > + __flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
> > }
> >
> > static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
> > diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
> > index 816d03c4c913..4cc41864f277 100644
> > --- a/arch/arm64/kernel/insn.c
> > +++ b/arch/arm64/kernel/insn.c
> > @@ -249,7 +249,6 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg)
> > } else {
> > while (atomic_read(&pp->cpu_count) <= num_online_cpus())
> > cpu_relax();
> > - isb();
> > }
>
> Something seems amiss here.
>
> We call __apply_alternatives_multi_stop() via stop_machine(), and I
> thought that ensured that all CPUs had IRQs masked.
Whoops; that should say aarch64_insn_patch_text_cb(), not
__apply_alternatives_multi_stop()
> If so, the IPI from flush_icache_range() will deadlock.
>
> If not, we can take IRQs, and execute potentially patched code.
>
> I think there's also an existing problem here. Even if with have IRQs
> masked, we could take SDEI events (or GICv3 psudeo-NMIs, once we have
> those). I don't know how we can manage those.
Mark.
^ permalink raw reply
* [PATCH v2 0/5] crypto: ccree: cleanup, fixes and R-Car enabling
From: Gilad Ben-Yossef @ 2018-06-19 13:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdVXrppnFEBmR3xhwNu3i0N3mVE1+FJRjEcWBYpHHbsAsw@mail.gmail.com>
On Tue, Jun 19, 2018 at 3:58 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> Hi Gilad,
>
> On Thu, May 24, 2018 at 4:19 PM Gilad Ben-Yossef <gilad@benyossef.com> wrote:
>> The patch set enables the use of CryptoCell found in some Renesas R-Car
>> Salvator-X boards and fixes some driver issues uncovered that prevented
>> to work properly.
>
> With DEBUG enabled on R-Car H3, I see lots of
>
> ccree e6601000.crypto: IRR includes unknown cause bits (0x00000098)
> ccree e6601000.crypto: IRR includes unknown cause bits (0x000000C0)
> ccree e6601000.crypto: IRR includes unknown cause bits (0x000000D0)
> ccree e6601000.crypto: IRR includes unknown cause bits (0x000000D8)
> ccree e6601000.crypto: IRR includes unknown cause bits (0x000000E0)
> ccree e6601000.crypto: IRR includes unknown cause bits (0x000000F0)
> ccree e6601000.crypto: IRR includes unknown cause bits (0x000000F8)
>
> during boot. Is that expected?
Yes. The condition itself it is reporting is not necessarily bad. It
means that driver
did not act on certain HW notification during interrupts and that's
OK, we don't act on all of them
depending on configuration - e.g. if you have CONFIG_FIPS enabled and
an active TEE module or not.
I can rate_limit the message if it bothers you but other than that it
is a harmless debug print.
Thanks,
Gilad
--
Gilad Ben-Yossef
Chief Coffee Drinker
values of ? will give rise to dom!
^ permalink raw reply
* [PATCH v10 13/14] cpufreq: Add module to register cpufreq on Krait CPUs
From: Sudeep Holla @ 2018-06-19 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529415925-28915-14-git-send-email-sricharan@codeaurora.org>
On 19/06/18 14:45, Sricharan R wrote:
> From: Stephen Boyd <sboyd@codeaurora.org>
>
> Register a cpufreq-generic device whenever we detect that a
> "qcom,krait" compatible CPU is present in DT.
>
Just curious to know how different is this from qcom kryo driver
that was added recently. IIRC even that gets the speedbin from nvmem.
Can they be merged ? I don't see need to have different driver for Krait
and Kryo CPUs when the code is not even remotely related to CPU type.
Sorry if I have missed anything from previous versions, I just happen
to open and looked at this series first time today.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH 3/3] arm64: IPI each CPU after invalidating the I-cache for kernel mappings
From: Mark Rutland @ 2018-06-19 13:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529412495-17525-4-git-send-email-will.deacon@arm.com>
On Tue, Jun 19, 2018 at 01:48:15PM +0100, Will Deacon wrote:
> When invalidating the instruction cache for a kernel mapping via
> flush_icache_range(), it is also necessary to flush the pipeline for
> other CPUs so that instructions fetched into the pipeline before the
> I-cache invalidation are discarded. For example, if module 'foo' is
> unloaded and then module 'bar' is loaded into the same area of memory,
> a CPU could end up executing instructions from 'foo' when branching into
> 'bar' if these instructions were fetched into the pipeline before 'foo'
> was unloaded.
>
> Whilst this is highly unlikely to occur in practice, particularly as
> any exception acts as a context-synchronizing operation, following the
> letter of the architecture requires us to execute an ISB on each CPU
> in order for the new instruction stream to be visible.
>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
> arch/arm64/include/asm/cacheflush.h | 13 ++++++++++++-
> arch/arm64/kernel/alternative.c | 1 -
> arch/arm64/kernel/cpu_errata.c | 2 +-
> arch/arm64/kernel/insn.c | 15 ++-------------
> arch/arm64/mm/cache.S | 4 ++--
> 5 files changed, 17 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> index d264a7274811..a0ec27066e6f 100644
> --- a/arch/arm64/include/asm/cacheflush.h
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -71,7 +71,7 @@
> * - kaddr - page address
> * - size - region size
> */
> -extern void flush_icache_range(unsigned long start, unsigned long end);
> +extern void __flush_icache_range(unsigned long start, unsigned long end);
> extern int invalidate_icache_range(unsigned long start, unsigned long end);
> extern void __flush_dcache_area(void *addr, size_t len);
> extern void __inval_dcache_area(void *addr, size_t len);
> @@ -81,6 +81,17 @@ extern void __clean_dcache_area_pou(void *addr, size_t len);
> extern long __flush_cache_user_range(unsigned long start, unsigned long end);
> extern void sync_icache_aliases(void *kaddr, unsigned long len);
>
> +static inline void flush_icache_range(unsigned long start, unsigned long end)
> +{
> + __flush_icache_range(start, end);
> +
> + /*
> + * IPI all online CPUs so that they undergo a context synchronization
> + * event and are forced to refetch the new instructions.
> + */
> + kick_all_cpus_sync();
> +}
> +
> static inline void flush_cache_mm(struct mm_struct *mm)
> {
> }
> diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
> index 4f3dcc15a5b2..0ac06560c166 100644
> --- a/arch/arm64/kernel/alternative.c
> +++ b/arch/arm64/kernel/alternative.c
> @@ -205,7 +205,6 @@ static int __apply_alternatives_multi_stop(void *unused)
> if (smp_processor_id()) {
> while (!READ_ONCE(alternatives_applied))
> cpu_relax();
> - isb();
> } else {
> BUG_ON(alternatives_applied);
> __apply_alternatives(®ion, false);
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 1d2b6d768efe..0a338a1cd2d7 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -101,7 +101,7 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
> for (i = 0; i < SZ_2K; i += 0x80)
> memcpy(dst + i, hyp_vecs_start, hyp_vecs_end - hyp_vecs_start);
>
> - flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
> + __flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
> }
>
> static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
> diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
> index 816d03c4c913..4cc41864f277 100644
> --- a/arch/arm64/kernel/insn.c
> +++ b/arch/arm64/kernel/insn.c
> @@ -249,7 +249,6 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg)
> } else {
> while (atomic_read(&pp->cpu_count) <= num_online_cpus())
> cpu_relax();
> - isb();
> }
Something seems amiss here.
We call __apply_alternatives_multi_stop() via stop_machine(), and I
thought that ensured that all CPUs had IRQs masked.
If so, the IPI from flush_icache_range() will deadlock.
If not, we can take IRQs, and execute potentially patched code.
I think there's also an existing problem here. Even if with have IRQs
masked, we could take SDEI events (or GICv3 psudeo-NMIs, once we have
those). I don't know how we can manage those.
Thanks,
Mark.
^ permalink raw reply
* [PATCH v10 14/14] dt-bindings: cpufreq: Document operating-points-v2-krait-cpu
From: Sricharan R @ 2018-06-19 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529415925-28915-1-git-send-email-sricharan@codeaurora.org>
In Certain QCOM SoCs like ipq8064, apq8064, msm8960, msm8974
that has KRAIT processors the voltage/current value of each OPP
varies based on the silicon variant in use.
operating-points-v2-krait-cpu specifies the phandle to nvmem efuse cells
and the operating-points-v2 table for each opp. The qcom-cpufreq driver
reads the efuse value from the SoC to provide the required information
that is used to determine the voltage and current value for each OPP of
operating-points-v2 table when it is parsed by the OPP framework.
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
.../devicetree/bindings/cpufreq/krait-cpufreq.txt | 363 +++++++++++++++++++++
1 file changed, 363 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cpufreq/krait-cpufreq.txt
diff --git a/Documentation/devicetree/bindings/cpufreq/krait-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/krait-cpufreq.txt
new file mode 100644
index 0000000..7b083c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/krait-cpufreq.txt
@@ -0,0 +1,363 @@
+QCOM KRAIT CPUFreq and OPP bindings
+===================================
+
+In Certain QCOM SoCs like ipq8064, apq8064, msm8960, msm8974
+that has KRAIT processors the voltage value of each OPP varies
+based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
+defines the voltage and current value based on the speed/pvs/version
+combination blown in the efuse. The qcom-cpufreq driver reads the efuse
+value from the SoC to provide the OPP framework with required information.
+This is used to determine the voltage and current value for each OPP of
+operating-points-v2 table when it is parsed by the OPP framework.
+
+Required properties:
+--------------------
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+ - 'operating-points-v2-krait-cpu' for ipq8064, apq8064, msm8960,
+ msm8974.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+ efuse registers that has information about the
+ speedbin/pvs/version that is used to select the right
+ voltage/current value pair. Note that the length field of the
+ nvmem-cell is used to differentiate between format 'A' or 'B'
+ efuse settings. len of '4' bytes is for format 'A' and '8'
+ bytes for format 'B'. Please refer the for nvmem-cells
+ bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+ and also examples below for both the cases.
+Example 1:
+---------
+
+/* For arch/arm/boot/dts/apq8064.dtsi --> format 'A' */
+cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ CPU0: cpu at 0 {
+ compatible = "qcom,krait";
+ enable-method = "qcom,kpss-acc-v1";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ cpu-idle-states = <&CPU_SPC>;
+ operating-points-v2 = <&cpu_opp_table>;
+ };
+};
+
+qfprom: qfprom at 700000 {
+ compatible = "qcom,qfprom";
+ reg = <0x00700000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ pvs_efuse: pvs {
+ reg = <0xc0 0x4>;
+ };
+};
+
+cpu_opp_table: opp-table {
+ compatible = "operating-points-v2-krait-cpu";
+ nvmem-cells = <&pvs_efuse>;
+
+ /*
+ * Missing opp-shared property means CPUs switch DVFS states
+ * independently.
+ */
+
+ opp-918000000 {
+ opp-hz = /bits/ 64 <918000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1100000>;
+ opp-microvolt-speed0-pvs1-v0 = <1050000>;
+ opp-microvolt-speed0-pvs3-v0 = <1000000>;
+ opp-microvolt-speed0-pvs4-v0 = <975000>;
+ opp-microvolt-speed1-pvs0-v0 = <1025000>;
+ opp-microvolt-speed1-pvs1-v0 = <1000000>;
+ opp-microvolt-speed1-pvs2-v0 = <950000>;
+ opp-microvolt-speed1-pvs3-v0 = <925000>;
+ opp-microvolt-speed1-pvs4-v0 = <900000>;
+ opp-microvolt-speed1-pvs5-v0 = <900000>;
+ opp-microvolt-speed1-pvs6-v0 = <900000>;
+ opp-microvolt-speed2-pvs0-v0 = <975000>;
+ opp-microvolt-speed2-pvs1-v0 = <950000>;
+ opp-microvolt-speed2-pvs2-v0 = <925000>;
+ opp-microvolt-speed2-pvs3-v0 = <912500>;
+ opp-microvolt-speed2-pvs4-v0 = <900000>;
+ opp-microvolt-speed2-pvs5-v0 = <900000>;
+ opp-microvolt-speed2-pvs6-v0 = <900000>;
+ opp-microvolt-speed14-pvs0-v0 = <1025000>;
+ opp-microvolt-speed14-pvs1-v0 = <1000000>;
+ opp-microvolt-speed14-pvs2-v0 = <950000>;
+ opp-microvolt-speed14-pvs3-v0 = <925000>;
+ opp-microvolt-speed14-pvs4-v0 = <900000>;
+ opp-microvolt-speed14-pvs5-v0 = <900000>;
+ opp-microvolt-speed14-pvs6-v0 = <900000>;
+ };
+
+ opp-810000000 {
+ opp-hz = /bits/ 64 <810000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1075000>;
+ opp-microvolt-speed0-pvs1-v0 = <1025000>;
+ opp-microvolt-speed0-pvs3-v0 = <975000>;
+ opp-microvolt-speed0-pvs3-v0 = <962500>;
+ opp-microvolt-speed1-pvs0-v0 = <1000000>;
+ opp-microvolt-speed1-pvs1-v0 = <975000>;
+ opp-microvolt-speed1-pvs2-v0 = <937500>;
+ opp-microvolt-speed1-pvs3-v0 = <900000>;
+ opp-microvolt-speed1-pvs4-v0 = <887500>;
+ opp-microvolt-speed1-pvs5-v0 = <887500>;
+ opp-microvolt-speed1-pvs6-v0 = <887500>;
+ opp-microvolt-speed2-pvs0-v0 = <962500>;
+ opp-microvolt-speed2-pvs1-v0 = <937500>;
+ opp-microvolt-speed2-pvs2-v0 = <912500>;
+ opp-microvolt-speed2-pvs3-v0 = <900000>;
+ opp-microvolt-speed2-pvs4-v0 = <887500>;
+ opp-microvolt-speed2-pvs5-v0 = <887500>;
+ opp-microvolt-speed2-pvs6-v0 = <887500>;
+ opp-microvolt-speed14-pvs0-v0 = <1000000>;
+ opp-microvolt-speed14-pvs1-v0 = <975000>;
+ opp-microvolt-speed14-pvs2-v0 = <937500>;
+ opp-microvolt-speed14-pvs3-v0 = <900000>;
+ opp-microvolt-speed14-pvs4-v0 = <887500>;
+ opp-microvolt-speed14-pvs5-v0 = <887500>;
+ opp-microvolt-speed14-pvs6-v0 = <887500>;
+ };
+
+ opp-702000000 {
+ opp-hz = /bits/ 64 <702000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1025000>;
+ opp-microvolt-speed0-pvs1-v0 = <975000>;
+ opp-microvolt-speed0-pvs3-v0 = <925000>;
+ opp-microvolt-speed0-pvs3-v0 = <925000>;
+ opp-microvolt-speed1-pvs0-v0 = <962500>;
+ opp-microvolt-speed1-pvs1-v0 = <962500>;
+ opp-microvolt-speed1-pvs2-v0 = <925000>;
+ opp-microvolt-speed1-pvs3-v0 = <900000>;
+ opp-microvolt-speed1-pvs4-v0 = <875000>;
+ opp-microvolt-speed1-pvs5-v0 = <875000>;
+ opp-microvolt-speed1-pvs6-v0 = <875000>;
+ opp-microvolt-speed2-pvs0-v0 = <950000>;
+ opp-microvolt-speed2-pvs1-v0 = <925000>;
+ opp-microvolt-speed2-pvs2-v0 = <900000>;
+ opp-microvolt-speed2-pvs3-v0 = 900000>;
+ opp-microvolt-speed2-pvs4-v0 = <875000>;
+ opp-microvolt-speed2-pvs5-v0 = <875000>;
+ opp-microvolt-speed2-pvs6-v0 = <875000>;
+ opp-microvolt-speed14-pvs0-v0 = <962500>;
+ opp-microvolt-speed14-pvs1-v0 = <962500>;
+ opp-microvolt-speed14-pvs2-v0 = <925000>;
+ opp-microvolt-speed14-pvs3-v0 = <900000>;
+ opp-microvolt-speed14-pvs4-v0 = <875000>;
+ opp-microvolt-speed14-pvs5-v0 = <875000>;
+ opp-microvolt-speed14-pvs6-v0 = <875000>;
+ };
+
+ opp-594000000 {
+ opp-hz = /bits/ 64 <594000000>;
+ opp-microvolt-speed0-pvs0-v0 = <1000000>;
+ opp-microvolt-speed0-pvs1-v0 = <950000>;
+ opp-microvolt-speed0-pvs3-v0 = <900000>;
+ opp-microvolt-speed0-pvs3-v0 = <900000>;
+ opp-microvolt-speed1-pvs0-v0 = <950000>;
+ opp-microvolt-speed1-pvs1-v0 = <950000>;
+ opp-microvolt-speed1-pvs2-v0 = <925000>;
+ opp-microvolt-speed1-pvs3-v0 = <900000>;
+ opp-microvolt-speed1-pvs4-v0 = <875000>;
+ opp-microvolt-speed1-pvs5-v0 = <875000>;
+ opp-microvolt-speed1-pvs6-v0 = <875000>;
+ opp-microvolt-speed2-pvs0-v0 = <950000>;
+ opp-microvolt-speed2-pvs1-v0 = <925000>;
+ opp-microvolt-speed2-pvs2-v0 = <900000>;
+ opp-microvolt-speed2-pvs3-v0 = <900000>;
+ opp-microvolt-speed2-pvs4-v0 = <875000>;
+ opp-microvolt-speed2-pvs5-v0 = <875000>;
+ opp-microvolt-speed2-pvs6-v0 = <875000>;
+ opp-microvolt-speed14-pvs0-v0 = <950000>;
+ opp-microvolt-speed14-pvs1-v0 = <950000>;
+ opp-microvolt-speed14-pvs2-v0 = <925000>;
+ opp-microvolt-speed14-pvs3-v0 = <900000>;
+ opp-microvolt-speed14-pvs4-v0 = <875000>;
+ opp-microvolt-speed14-pvs5-v0 = <875000>;
+ opp-microvolt-speed14-pvs6-v0 = <875000>;
+ };
+
+ opp-486000000 {
+ opp-hz = /bits/ 64 <486000000>;
+ opp-microvolt-speed0-pvs0-v0 = <975000>;
+ opp-microvolt-speed0-pvs1-v0 = <925000>;
+ opp-microvolt-speed0-pvs3-v0 = <875000>;
+ opp-microvolt-speed0-pvs3-v0 = <875000>;
+ opp-microvolt-speed1-pvs0-v0 = <950000>;
+ opp-microvolt-speed1-pvs1-v0 = <950000>;
+ opp-microvolt-speed1-pvs2-v0 = <925000>;
+ opp-microvolt-speed1-pvs3-v0 = <900000>;
+ opp-microvolt-speed1-pvs4-v0 = <875000>;
+ opp-microvolt-speed1-pvs5-v0 = <875000>;
+ opp-microvolt-speed1-pvs6-v0 = <875000>;
+ opp-microvolt-speed2-pvs0-v0 = <950000>;
+ opp-microvolt-speed2-pvs1-v0 = <925000>;
+ opp-microvolt-speed2-pvs2-v0 = <900000>;
+ opp-microvolt-speed2-pvs3-v0 = <900000>;
+ opp-microvolt-speed2-pvs4-v0 = <875000>;
+ opp-microvolt-speed2-pvs5-v0 = <875000>;
+ opp-microvolt-speed2-pvs6-v0 = <875000>;
+ opp-microvolt-speed14-pvs0-v0 = <950000>;
+ opp-microvolt-speed14-pvs1-v0 = <950000>;
+ opp-microvolt-speed14-pvs2-v0 = <925000>;
+ opp-microvolt-speed14-pvs3-v0 = <900000>;
+ opp-microvolt-speed14-pvs4-v0 = <875000>;
+ opp-microvolt-speed14-pvs5-v0 = <875000>;
+ opp-microvolt-speed14-pvs6-v0 = <875000>;
+ };
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ opp-microvolt-speed0-pvs0-v0 = <950000>;
+ opp-microvolt-speed0-pvs1-v0 = <900000>;
+ opp-microvolt-speed0-pvs3-v0 = <850000>;
+ opp-microvolt-speed0-pvs3-v0 = <850000>;
+ opp-microvolt-speed1-pvs0-v0 = <950000>;
+ opp-microvolt-speed1-pvs1-v0 = <950000>;
+ opp-microvolt-speed1-pvs2-v0 = <925000>;
+ opp-microvolt-speed1-pvs3-v0 = <900000>;
+ opp-microvolt-speed1-pvs4-v0 = <875000>;
+ opp-microvolt-speed1-pvs5-v0 = <875000>;
+ opp-microvolt-speed1-pvs6-v0 = <875000>;
+ opp-microvolt-speed2-pvs0-v0 = <950000>;
+ opp-microvolt-speed2-pvs1-v0 = <925000>;
+ opp-microvolt-speed2-pvs2-v0 = <900000>;
+ opp-microvolt-speed2-pvs3-v0 = <900000>;
+ opp-microvolt-speed2-pvs4-v0 = <875000>;
+ opp-microvolt-speed2-pvs5-v0 = <875000>;
+ opp-microvolt-speed2-pvs6-v0 = <875000>;
+ opp-microvolt-speed14-pvs0-v0 = <950000>;
+ opp-microvolt-speed14-pvs1-v0 = <950000>;
+ opp-microvolt-speed14-pvs2-v0 = <925000>;
+ opp-microvolt-speed14-pvs3-v0 = <900000>;
+ opp-microvolt-speed14-pvs4-v0 = <875000>;
+ opp-microvolt-speed14-pvs5-v0 = <875000>;
+ opp-microvolt-speed14-pvs6-v0 = <875000>;
+ };
+};
+
+EXAMPLE 2:
+---------
+/* For arch/arm/boot/dts/qcom-msm8974.dtsi--> format 'B' */
+
+qfprom: qfprom at 700000 {
+ compatible = "qcom,qfprom";
+ reg = <0x00700000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ pvs_efuse: pvs {
+ reg = <0xc0 0x8>;
+ };
+};
+
+cpu_opp_table: opp-table {
+ compatible = "operating-points-v2-krait-cpu";
+ nvmem-cells = <&pvs_efuse>;
+
+ /*
+ * Missing opp-shared property means CPUs switch DVFS states
+ * independently.
+ */
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ opp-microvolt-speed0-pvs0-v0 = <915000>;
+ opp-microvolt-speed0-pvs1-v0 = <895000>;
+ opp-microvolt-speed0-pvs2-v0 = <875000>;
+ opp-microvolt-speed0-pvs3-v0 = <860000>;
+ opp-microvolt-speed0-pvs4-v0 = <850000>;
+ opp-microvolt-speed0-pvs5-v0 = <840000>;
+ opp-microvolt-speed0-pvs6-v0 = <830000>;
+ opp-microvolt-speed2-pvs0-v0 = <875000>;
+ opp-microvolt-speed2-pvs1-v0 = <860000>;
+ opp-microvolt-speed2-pvs2-v0 = <845000>;
+ opp-microvolt-speed2-pvs3-v0 = <830000>;
+ opp-microvolt-speed2-pvs4-v0 = <820000>;
+ opp-microvolt-speed2-pvs5-v0 = <810000>;
+ opp-microvolt-speed2-pvs6-v0 = <800000>;
+ opp-microvolt-speed1-pvs0-v0 = <840000>;
+ opp-microvolt-speed1-pvs1-v0 = <825000>;
+ opp-microvolt-speed1-pvs2-v0 = <810000>;
+ opp-microvolt-speed1-pvs3-v0 = <795000>;
+ opp-microvolt-speed1-pvs4-v0 = <785000>;
+ opp-microvolt-speed1-pvs5-v0 = <775000>;
+ opp-microvolt-speed1-pvs6-v0 = <765000>;
+
+ opp-microamp-speed0-pvs0-v0 = <252>;
+ opp-microamp-speed0-pvs1-v0 = <252>;
+ opp-microamp-speed0-pvs2-v0 = <252>;
+ opp-microamp-speed0-pvs3-v0 = <252>;
+ opp-microamp-speed0-pvs4-v0 = <252>;
+ opp-microamp-speed0-pvs5-v0 = <252>;
+ opp-microamp-speed0-pvs6-v0 = <252>;
+ opp-microamp-speed2-pvs0-v0 = <245>;
+ opp-microamp-speed2-pvs1-v0 = <245>;
+ opp-microamp-speed2-pvs2-v0 = <245>;
+ opp-microamp-speed2-pvs3-v0 = <245>;
+ opp-microamp-speed2-pvs4-v0 = <245>;
+ opp-microamp-speed2-pvs5-v0 = <245>;
+ opp-microamp-speed2-pvs6-v0 = <245>;
+ opp-microamp-speed1-pvs0-v0 = <242>;
+ opp-microamp-speed1-pvs1-v0 = <242>;
+ opp-microamp-speed1-pvs2-v0 = <242>;
+ opp-microamp-speed1-pvs3-v0 = <242>;
+ opp-microamp-speed1-pvs4-v0 = <242>;
+ opp-microamp-speed1-pvs5-v0 = <242>;
+ opp-microamp-speed1-pvs6-v0 = <242>;
+ };
+
+ opp-883200000 {
+ opp-hz = /bits/ 64 <883200000>;
+ opp-microvolt-speed0-pvs0-v0 = <900000>;
+ opp-microvolt-speed0-pvs1-v0 = <885000>;
+ opp-microvolt-speed0-pvs2-v0 = <865000>;
+ opp-microvolt-speed0-pvs3-v0 = <850000>;
+ opp-microvolt-speed0-pvs4-v0 = <840000>;
+ opp-microvolt-speed0-pvs5-v0 = <830000>;
+ opp-microvolt-speed0-pvs6-v0 = <820000>;
+ opp-microvolt-speed2-pvs0-v0 = <865000>;
+ opp-microvolt-speed2-pvs1-v0 = <850000>;
+ opp-microvolt-speed2-pvs2-v0 = <835000>;
+ opp-microvolt-speed2-pvs3-v0 = <820000>;
+ opp-microvolt-speed2-pvs4-v0 = <810000>;
+ opp-microvolt-speed2-pvs5-v0 = <800000>;
+ opp-microvolt-speed2-pvs6-v0 = <790000>;
+ opp-microvolt-speed1-pvs0-v0 = <830000>;
+ opp-microvolt-speed1-pvs1-v0 = <815000>;
+ opp-microvolt-speed1-pvs2-v0 = <800000>;
+ opp-microvolt-speed1-pvs3-v0 = <785000>;
+ opp-microvolt-speed1-pvs4-v0 = <775000>;
+ opp-microvolt-speed1-pvs5-v0 = <765000>;
+ opp-microvolt-speed1-pvs6-v0 = <755000>;
+
+ opp-microamp-speed0-pvs0-v0 = <229>;
+ opp-microamp-speed0-pvs1-v0 = <229>;
+ opp-microamp-speed0-pvs2-v0 = <229>;
+ opp-microamp-speed0-pvs3-v0 = <229>;
+ opp-microamp-speed0-pvs4-v0 = <229>;
+ opp-microamp-speed0-pvs5-v0 = <229>;
+ opp-microamp-speed0-pvs6-v0 = <229>;
+ opp-microamp-speed2-pvs0-v0 = <223>;
+ opp-microamp-speed2-pvs1-v0 = <223>;
+ opp-microamp-speed2-pvs2-v0 = <223>;
+ opp-microamp-speed2-pvs3-v0 = <223>;
+ opp-microamp-speed2-pvs4-v0 = <223>;
+ opp-microamp-speed2-pvs5-v0 = <223>;
+ opp-microamp-speed2-pvs6-v0 = <223>;
+ opp-microamp-speed1-pvs0-v0 = <221>;
+ opp-microamp-speed1-pvs1-v0 = <221>;
+ opp-microamp-speed1-pvs2-v0 = <221>;
+ opp-microamp-speed1-pvs3-v0 = <221>;
+ opp-microamp-speed1-pvs4-v0 = <221>;
+ opp-microamp-speed1-pvs5-v0 = <221>;
+ opp-microamp-speed1-pvs6-v0 = <221>;
+ };
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v10 13/14] cpufreq: Add module to register cpufreq on Krait CPUs
From: Sricharan R @ 2018-06-19 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529415925-28915-1-git-send-email-sricharan@codeaurora.org>
From: Stephen Boyd <sboyd@codeaurora.org>
Register a cpufreq-generic device whenever we detect that a
"qcom,krait" compatible CPU is present in DT.
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
[Sricharan: updated to use dev_pm_opp_set_prop_name and
nvmem apis]
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
[Thierry Escande: update to add support for opp-supported-hw]
Signed-off-by: Thierry Escande <thierry.escande@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
[v10] updated to add support for opp-supported-hw given by
Thierry Escande <thierry.escande@linaro.org>
drivers/cpufreq/Kconfig.arm | 10 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/cpufreq-dt-platdev.c | 5 +
drivers/cpufreq/qcom-cpufreq.c | 201 +++++++++++++++++++++++++++++++++++
4 files changed, 217 insertions(+)
create mode 100644 drivers/cpufreq/qcom-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 7f56fe5..87e5d8d 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -134,6 +134,16 @@ config ARM_OMAP2PLUS_CPUFREQ
depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
+config ARM_QCOM_CPUFREQ
+ bool "CPUfreq driver for the QCOM SoCs with KRAIT processors"
+ depends on ARCH_QCOM
+ select PM_OPP
+ help
+ This enables the CPUFreq driver for Qualcomm SoCs with
+ KRAIT processors.
+
+ If in doubt, say N.
+
config ARM_S3C_CPUFREQ
bool
help
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 8d24ade..c591e1e 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
+obj-$(CONFIG_ARM_QCOM_CPUFREQ) += qcom-cpufreq.o
obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 3b585e4..e2e9a99 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -127,6 +127,11 @@
{ .compatible = "ti,am43", },
{ .compatible = "ti,dra7", },
+ { .compatible = "qcom,ipq8064", },
+ { .compatible = "qcom,apq8064", },
+ { .compatible = "qcom,msm8974", },
+ { .compatible = "qcom,msm8960", },
+
{ }
};
diff --git a/drivers/cpufreq/qcom-cpufreq.c b/drivers/cpufreq/qcom-cpufreq.c
new file mode 100644
index 0000000..1d4ab54
--- /dev/null
+++ b/drivers/cpufreq/qcom-cpufreq.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+
+static void __init get_krait_bin_format_a(int *speed, int *pvs, int *pvs_ver,
+ struct nvmem_cell *pvs_nvmem, u8 *buf)
+{
+ u32 pte_efuse;
+
+ pte_efuse = *((u32 *)buf);
+
+ *speed = pte_efuse & 0xf;
+ if (*speed == 0xf)
+ *speed = (pte_efuse >> 4) & 0xf;
+
+ if (*speed == 0xf) {
+ *speed = 0;
+ pr_warn("Speed bin: Defaulting to %d\n", *speed);
+ } else {
+ pr_info("Speed bin: %d\n", *speed);
+ }
+
+ *pvs = (pte_efuse >> 10) & 0x7;
+ if (*pvs == 0x7)
+ *pvs = (pte_efuse >> 13) & 0x7;
+
+ if (*pvs == 0x7) {
+ *pvs = 0;
+ pr_warn("PVS bin: Defaulting to %d\n", *pvs);
+ } else {
+ pr_info("PVS bin: %d\n", *pvs);
+ }
+
+ kfree(buf);
+}
+
+static void __init get_krait_bin_format_b(int *speed, int *pvs, int *pvs_ver,
+ struct nvmem_cell *pvs_nvmem, u8 *buf)
+{
+ u32 pte_efuse, redundant_sel;
+
+ pte_efuse = *((u32 *)buf);
+ redundant_sel = (pte_efuse >> 24) & 0x7;
+ *speed = pte_efuse & 0x7;
+
+ /* 4 bits of PVS are in efuse register bits 31, 8-6. */
+ *pvs = ((pte_efuse >> 28) & 0x8) | ((pte_efuse >> 6) & 0x7);
+ *pvs_ver = (pte_efuse >> 4) & 0x3;
+
+ switch (redundant_sel) {
+ case 1:
+ *speed = (pte_efuse >> 27) & 0xf;
+ break;
+ case 2:
+ *pvs = (pte_efuse >> 27) & 0xf;
+ break;
+ }
+
+ /* Check SPEED_BIN_BLOW_STATUS */
+ if (pte_efuse & BIT(3)) {
+ pr_info("Speed bin: %d\n", *speed);
+ } else {
+ pr_warn("Speed bin not set. Defaulting to 0!\n");
+ *speed = 0;
+ }
+
+ /* Check PVS_BLOW_STATUS */
+ pte_efuse = *(((u32 *)buf) + 4);
+ if (pte_efuse) {
+ pr_info("PVS bin: %d\n", *pvs);
+ } else {
+ pr_warn("PVS bin not set. Defaulting to 0!\n");
+ *pvs = 0;
+ }
+
+ pr_info("PVS version: %d\n", *pvs_ver);
+ kfree(buf);
+}
+
+static int __init qcom_cpufreq_populate_opps(struct nvmem_cell *pvs_nvmem,
+ struct opp_table **tbl1,
+ struct opp_table **tbl2)
+{
+ int speed = 0, pvs = 0, pvs_ver = 0, cpu, ret;
+ struct device *cpu_dev;
+ u8 *buf;
+ size_t len;
+ char pvs_name[] = "speedXX-pvsXX-vXX";
+ u32 hw_version;
+
+ buf = nvmem_cell_read(pvs_nvmem, &len);
+ if (len == 4)
+ get_krait_bin_format_a(&speed, &pvs, &pvs_ver, pvs_nvmem, buf);
+ else if (len == 8)
+ get_krait_bin_format_b(&speed, &pvs, &pvs_ver, pvs_nvmem, buf);
+ else
+ pr_warn("Unable to read nvmem data. Defaulting to 0!\n");
+
+ snprintf(pvs_name, sizeof(pvs_name), "speed%d-pvs%d-v%d",
+ speed, pvs, pvs_ver);
+
+ hw_version = (1 << speed);
+
+ for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+ cpu_dev = get_cpu_device(cpu);
+ if (!cpu_dev)
+ return -ENODEV;
+
+ tbl1[cpu] = dev_pm_opp_set_prop_name(cpu_dev, pvs_name);
+ if (IS_ERR(tbl1[cpu])) {
+ ret = PTR_ERR(tbl1[cpu]);
+ tbl1[cpu] = 0;
+ pr_warn("failed to add OPP name %s\n", pvs_name);
+ return ret;
+ }
+
+ tbl2[cpu] = dev_pm_opp_set_supported_hw(cpu_dev, &hw_version,
+ 1);
+ if (IS_ERR(tbl2[cpu])) {
+ ret = PTR_ERR(tbl2[cpu]);
+ tbl2[cpu] = 0;
+ pr_warn("failed to set supported hw version\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int __init qcom_cpufreq_driver_init(void)
+{
+ struct platform_device *pdev;
+ struct device *cpu_dev;
+ struct device_node *np;
+ struct nvmem_cell *pvs_nvmem;
+ struct opp_table *tbl1[NR_CPUS] = { NULL }, *tbl2[NR_CPUS] = { NULL };
+ int ret, cpu = 0;
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev)
+ return -ENODEV;
+
+ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+ if (!np)
+ return -ENOENT;
+
+ if (!of_device_is_compatible(np, "operating-points-v2-krait-cpu")) {
+ ret = -ENOENT;
+ goto free_np;
+ }
+
+ pvs_nvmem = of_nvmem_cell_get(np, NULL);
+ if (IS_ERR(pvs_nvmem)) {
+ dev_err(cpu_dev, "Could not get nvmem cell\n");
+ ret = PTR_ERR(pvs_nvmem);
+ goto free_np;
+ }
+
+ ret = qcom_cpufreq_populate_opps(pvs_nvmem, tbl1, tbl2);
+ if (ret)
+ goto free_opp_name;
+
+ pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto free_opp_name;
+ }
+
+ of_node_put(np);
+
+ return 0;
+
+free_opp_name:
+ while (tbl1[cpu]) {
+ dev_pm_opp_put_prop_name(tbl1[cpu]);
+ cpu++;
+ }
+
+ cpu = 0;
+ while (tbl2[cpu]) {
+ dev_pm_opp_put_supported_hw(tbl2[cpu]);
+ cpu++;
+ }
+
+free_np:
+ of_node_put(np);
+
+ return ret;
+}
+late_initcall(qcom_cpufreq_driver_init);
+
+MODULE_DESCRIPTION("Qualcomm CPUfreq driver");
+MODULE_AUTHOR("Stephen Boyd <sboyd@codeaurora.org>");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v10 12/14] clk: qcom: Add safe switch hook for krait mux clocks
From: Sricharan R @ 2018-06-19 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529415925-28915-1-git-send-email-sricharan@codeaurora.org>
When the Hfplls are reprogrammed during the rate change,
the primary muxes which are sourced from the same hfpll
for higher frequencies, needs to be switched to the 'safe
secondary mux' as the parent for that small window. This
is done by registering a clk notifier for the muxes and
switching to the safe parent in the PRE_RATE_CHANGE notifier
and back to the original parent in the POST_RATE_CHANGE notifier.
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
drivers/clk/qcom/clk-krait.c | 2 ++
drivers/clk/qcom/clk-krait.h | 3 +++
drivers/clk/qcom/krait-cc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
index a651710..ee1076c 100644
--- a/drivers/clk/qcom/clk-krait.c
+++ b/drivers/clk/qcom/clk-krait.c
@@ -50,6 +50,8 @@ static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
if (__clk_is_enabled(hw->clk))
__krait_mux_set_sel(mux, sel);
+ mux->reparent = true;
+
return 0;
}
diff --git a/drivers/clk/qcom/clk-krait.h b/drivers/clk/qcom/clk-krait.h
index 441ba1e..9120bd2 100644
--- a/drivers/clk/qcom/clk-krait.h
+++ b/drivers/clk/qcom/clk-krait.h
@@ -12,6 +12,9 @@ struct krait_mux_clk {
u32 shift;
u32 en_mask;
bool lpl;
+ u8 safe_sel;
+ u8 old_index;
+ bool reparent;
struct clk_hw hw;
struct notifier_block clk_nb;
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index 7c9dfb0..4d4b657 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -26,6 +26,49 @@
0,
};
+/*
+ * Notifier function for switching the muxes to safe parent
+ * while the hfpll is getting reprogrammed.
+ */
+static int krait_notifier_cb(struct notifier_block *nb,
+ unsigned long event,
+ void *data)
+{
+ int ret = 0;
+ struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk,
+ clk_nb);
+ /* Switch to safe parent */
+ if (event == PRE_RATE_CHANGE) {
+ mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw);
+ ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel);
+ mux->reparent = false;
+ /*
+ * By the time POST_RATE_CHANGE notifier is called,
+ * clk framework itself would have changed the parent for the new rate.
+ * Only otherwise, put back to the old parent.
+ */
+ } else if (event == POST_RATE_CHANGE) {
+ if (!mux->reparent)
+ ret = krait_mux_clk_ops.set_parent(&mux->hw,
+ mux->old_index);
+ }
+
+ return notifier_from_errno(ret);
+}
+
+static int krait_notifier_register(struct device *dev, struct clk *clk,
+ struct krait_mux_clk *mux)
+{
+ int ret = 0;
+
+ mux->clk_nb.notifier_call = krait_notifier_cb;
+ ret = clk_notifier_register(clk, &mux->clk_nb);
+ if (ret)
+ dev_err(dev, "failed to register clock notifier: %d\n", ret);
+
+ return ret;
+}
+
static int
krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
{
@@ -70,6 +113,7 @@
krait_add_sec_mux(struct device *dev, int id, const char *s,
unsigned int offset, bool unique_aux)
{
+ int ret;
struct krait_mux_clk *mux;
static const char *sec_mux_list[] = {
"acpu_aux",
@@ -93,6 +137,7 @@
mux->shift = 2;
mux->parent_map = sec_mux_map;
mux->hw.init = &init;
+ mux->safe_sel = 0;
init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
if (!init.name)
@@ -108,6 +153,11 @@
clk = devm_clk_register(dev, &mux->hw);
+ ret = krait_notifier_register(dev, clk, mux);
+ if (ret)
+ goto unique_aux;
+
+unique_aux:
if (unique_aux)
kfree(sec_mux_list[0]);
err_aux:
@@ -119,6 +169,7 @@
krait_add_pri_mux(struct device *dev, int id, const char *s,
unsigned int offset)
{
+ int ret;
struct krait_mux_clk *mux;
const char *p_names[3];
struct clk_init_data init = {
@@ -139,6 +190,7 @@
mux->lpl = id >= 0;
mux->parent_map = pri_mux_map;
mux->hw.init = &init;
+ mux->safe_sel = 2;
init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
if (!init.name)
@@ -164,6 +216,10 @@
clk = devm_clk_register(dev, &mux->hw);
+ ret = krait_notifier_register(dev, clk, mux);
+ if (ret)
+ goto err_p3;
+err_p3:
kfree(p_names[2]);
err_p2:
kfree(p_names[1]);
--
1.9.1
^ permalink raw reply related
* [PATCH v10 11/14] dt-bindings: clock: Document qcom,krait-cc
From: Sricharan R @ 2018-06-19 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529415925-28915-1-git-send-email-sricharan@codeaurora.org>
From: Stephen Boyd <sboyd@codeaurora.org>
The Krait clock controller controls the krait CPU and the L2 clocks
consisting a primary mux and secondary mux. Add document for that.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
[v10] updated to include clocks and clock-names property newly
.../devicetree/bindings/clock/qcom,krait-cc.txt | 34 ++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
diff --git a/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
new file mode 100644
index 0000000..030ba60
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
@@ -0,0 +1,34 @@
+Krait Clock Controller
+
+PROPERTIES
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be one of:
+ "qcom,krait-cc-v1"
+ "qcom,krait-cc-v2"
+
+- #clock-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 1
+
+- clocks:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: reference to the clock parents of hfpll, secondary muxes.
+
+- clock-names:
+ Usage: required
+ Value type: <stringlist>
+ Definition: must be "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb".
+
+Example:
+
+ kraitcc: clock-controller {
+ compatible = "qcom,krait-cc-v1";
+ clocks = <&hfpll0>, <&hfpll1>, <&acpu0_aux>, <&acpu1_aux>, <qsb>;
+ clock-names = "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb";
+ #clock-cells = <1>;
+ };
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox