* [PATCH] pinctrl: Rename Broadcom Capri pinctrl driver
From: Matt Porter @ 2014-01-22 1:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMj7wXJ+DfXzk0U1pusKqZShq+KJdPY8hh=Ffj7KDti4_Q@mail.gmail.com>
On Tue, Jan 21, 2014 at 04:59:35PM -0800, Olof Johansson wrote:
> Hi,
>
>
> On Tue, Jan 21, 2014 at 2:38 PM, Sherman Yin <syin@broadcom.com> wrote:
> > To be consistent with other Broadcom drivers, the Broadcom Capri pinctrl
> > driver and its related CONFIG option are renamed to bcm281xx.
> >
> > Devicetree compatible string and binding documentation use
> > "brcm,bcm11351-pinctrl" to match the machine binding here:
> > Documentation/devicetree/bindings/arm/bcm/bcm11351.txt
> >
> > This driver supports pinctrl on BCM11130, BCM11140, BCM11351, BCM28145
> > and BCM28155 SoCs.
> >
> > Signed-off-by: Sherman Yin <syin@broadcom.com>
> > Reviewed-by: Matt Porter <mporter@linaro.org>
> > ---
> > ...capri-pinctrl.txt => brcm,bcm11351-pinctrl.txt} | 8 +-
> > arch/arm/boot/dts/bcm11351.dtsi | 2 +-
> > arch/arm/configs/bcm_defconfig | 2 +-
> > drivers/pinctrl/Kconfig | 8 +-
> > drivers/pinctrl/Makefile | 2 +-
> > .../{pinctrl-capri.c => pinctrl-bcm281xx.c} | 1521 ++++++++++----------
> > 6 files changed, 775 insertions(+), 768 deletions(-)
> > rename Documentation/devicetree/bindings/pinctrl/{brcm,capri-pinctrl.txt => brcm,bcm11351-pinctrl.txt} (98%)
> > rename drivers/pinctrl/{pinctrl-capri.c => pinctrl-bcm281xx.c} (25%)
> >
> > diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
> > similarity index 98%
> > rename from Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt
> > rename to Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
> > index 9e9e9ef..c119deb 100644
> > --- a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt
> > +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
> > @@ -1,4 +1,4 @@
> > -Broadcom Capri Pin Controller
> > +Broadcom BCM281xx Pin Controller
> >
> > This is a pin controller for the Broadcom BCM281xx SoC family, which includes
> > BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs.
> > @@ -7,14 +7,14 @@ BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs.
> >
> > Required Properties:
> >
> > -- compatible: Must be "brcm,capri-pinctrl".
> > +- compatible: Must be "brcm,bcm11351-pinctrl"
>
> Since the original binding is queued for 3.14 (I believe?), if this
> rename isn't merged for 3.14 then you will still need to accept the
> old compatible string (binding). You can document it as deprecated,
> but the driver needs to still probe with it.
Linus had mentioned that he could take a rename in 3.14-rc for this
driver which is really what we had in mind here. Since the binding
doesn't become stable until 3.14 is actually released I was under the
impression that this is ok without keeping a deprecated compatible
string. I notice that Tomasz had comments about this type of situation
in http://www.spinics.net/lists/devicetree/msg18010.html
-Matt
^ permalink raw reply
* [GIT PULL]ARM: sirf: machine update for 3.14
From: Barry Song @ 2014-01-22 1:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGsJ_4z2NRZxqUAyKSX+ksDbkO4j3=ggzMHH2=GDyG2fphGjww@mail.gmail.com>
Hi Olof/Kevin,
this series was missed?
-barry
2014/1/15 Barry Song <21cnbao@gmail.com>:
> Hi Kevin/Olof,
>
> The following changes since commit 374b105797c3d4f29c685f3be535c35f5689b30e:
>
> Linux 3.13-rc3 (2013-12-06 09:34:04 -0800)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git
> tags/sirf-soc-for-3.14
>
> for you to fetch changes up to dbd1b42baa6ec8082bce6eec37de5e1b46aff19c:
>
> ARM: prima2: make sirfsoc_init_late function static (2014-01-15
> 10:42:26 +0800)
>
> ----------------------------------------------------------------
> ARM: sirf: machine update for 3.14
>
> Among them:
> - ARM: prima2: move to generic reset controller driver framework
> - MAINTAINERS: ARM: SiRF: use regex patterns to involve all SiRF drivers
> - ARM: prima2: make sirfsoc_init_late function static
>
> ----------------------------------------------------------------
> Barry Song (3):
> ARM: prima2: move to generic reset controller driver framework
> MAINTAINERS: ARM: SiRF: use regex patterns to involve all SiRF drivers
> ARM: prima2: make sirfsoc_init_late function static
>
> .../devicetree/bindings/reset/sirf,rstc.txt | 42 +++++++++
> MAINTAINERS | 9 +-
> arch/arm/boot/dts/atlas6.dtsi | 3 +-
> arch/arm/boot/dts/marco.dtsi | 3 +-
> arch/arm/boot/dts/prima2.dtsi | 3 +-
> arch/arm/mach-prima2/Kconfig | 1 +
> arch/arm/mach-prima2/common.c | 2 +-
> arch/arm/mach-prima2/rstc.c | 93 +++++++++++++-------
> 8 files changed, 110 insertions(+), 46 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/reset/sirf,rstc.txt
>
> -barry
^ permalink raw reply
* [PATCH] clk: export __clk_get_hw for re-use in others
From: SeongJae Park @ 2014-01-22 3:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAEjAshoh5ucPJA6pG1sx+7HGCYjHzCKtbzmH+GYJwpefDYLwJg@mail.gmail.com>
Dear Greg, Mike,
May I ask your answer or other opinion, please?
On Mon, Jan 20, 2014 at 5:07 PM, SeongJae Park <sj38.park@gmail.com> wrote:
> On Mon, Jan 20, 2014 at 4:47 PM, Mike Turquette <mturquette@linaro.org> wrote:
>> On Sun, Jan 19, 2014 at 9:37 AM, Greg KH <gregkh@linuxfoundation.org> wrote:
>>> On Sun, Jan 19, 2014 at 02:55:07PM +0900, SeongJae Park wrote:
>>>> Following build comes while modprobe process:
>>>> > ERROR: "__clk_get_hw" [drivers/clk/clk-max77686.ko] undefined!
>>>> > make[2]: *** [__modpost] Error 1
>>>> > make[1]: *** [modules] Error 2
>>>>
>>>> Export the symbol to fix it and for other part's usecase.
>>>>
>>>> Signed-off-by: SeongJae Park <sj38.park@gmail.com>
>>>> ---
>>>> drivers/clk/clk.c | 1 +
>>>> 1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
>>>> index 2b38dc9..3883fba 100644
>>>> --- a/drivers/clk/clk.c
>>>> +++ b/drivers/clk/clk.c
>>>> @@ -575,6 +575,7 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
>>>> {
>>>> return !clk ? NULL : clk->hw;
>>>> }
>>>> +EXPORT_SYMBOL_GPL(__clk_get_hw);
>>>
>>> __ functions should usually only be for "internal" use, why does this
>>> get exported to modules? Why not just put it in a .h file?
>>
>> It was originally used only within the clock core but it is sensible
>> for hardware-specific clock drivers to use this as well. I plan to
>> audit all of the double-underscore functions in
>> include/linux/clk-provider.h for 3.15.
>>
>> Regards,
>> Mike
>>
> Thank you very much for answering about it, Mike.
>
> I agree Greg's indication and think Mike's explanation is reasonable.
>
> So, I think it would be better to just export the symbol now
> because it would be easier for future functions renaming and
> similar issues were solved in this way in past:
> https://lkml.org/lkml/2013/4/15/50
>
> Or, maybe I can change the client code of __clk_get_hw to not use the function.
>
> What do you think would be better to fix this build error? Or, do you
> have better idea?
> I will respect your opinion.
>
> Thanks and Regards.
> SeongJae Park.
>
>>>
>>> greg k-h
^ permalink raw reply
* [PATCH v5 0/8] ARM: brcmstb: Add Broadcom STB SoC support
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
This patchset contains the board support package for the
Broadcom BCM7445 ARM-based SoC [1]. These changes contain a
minimal set of code needed for a BCM7445-based board to boot
the Linux kernel.
These changes heavily leverage the OF/devicetree framework.
v5:
- rebased to v3.13 tag
- make UART DT node a child of 'rdb' node
- fix ordering of debug UART entries
v4:
- make a reboot driver and put it in the drivers folder
- rework DT bindings to leverage 'syscon'
- rework BSP code to use 'syscon' for all register mappings
- misc. tweaks per suggestions from v3
v3:
- rebased to v3.13-rc8
- switched to using 'multi_v7_defconfig'
- eliminated dependence on compile-time peripheral register access
- moved DT node iomap out from 'init_early'
- misc. minor cleanups from mailing-list discussion for v2
v2:
- rebased to v3.13-rc1
- moved implementation to 'mach-bcm' folder
- added CPU init for B15
v1:
- initial submission
[1] http://www.broadcom.com/products/Cable/Cable-Set-Top-Box-Solutions/BCM7445
Marc Carino (8):
ARM: brcmstb: add infrastructure for ARM-based Broadcom STB SoCs
power: reset: Add reboot driver for brcmstb
ARM: brcmstb: add debug UART for earlyprintk support
ARM: do CPU-specific init for Broadcom Brahma15 cores
ARM: brcmstb: add CPU binding for Broadcom Brahma15
ARM: brcmstb: add misc. DT bindings for brcmstb
ARM: brcmstb: gic: add compatible string for Broadcom Brahma15
ARM: brcmstb: dts: add a reference DTS for Broadcom 7445
.../devicetree/bindings/arm/brcm-brcmstb.txt | 95 ++++++
Documentation/devicetree/bindings/arm/cpus.txt | 1 +
Documentation/devicetree/bindings/arm/gic.txt | 1 +
arch/arm/Kconfig.debug | 16 +-
arch/arm/boot/dts/bcm7445.dts | 111 +++++++
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm/mach-bcm/Kconfig | 14 +
arch/arm/mach-bcm/Makefile | 4 +
arch/arm/mach-bcm/brcmstb.c | 110 +++++++
arch/arm/mach-bcm/brcmstb.h | 38 +++
arch/arm/mach-bcm/headsmp-brcmstb.S | 34 ++
arch/arm/mach-bcm/hotplug-brcmstb.c | 334 ++++++++++++++++++++
arch/arm/mm/proc-v7.S | 11 +
drivers/power/reset/Kconfig | 10 +
drivers/power/reset/Makefile | 1 +
drivers/power/reset/brcmstb-reboot.c | 120 +++++++
16 files changed, 900 insertions(+), 1 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/brcm-brcmstb.txt
create mode 100644 arch/arm/boot/dts/bcm7445.dts
create mode 100644 arch/arm/mach-bcm/brcmstb.c
create mode 100644 arch/arm/mach-bcm/brcmstb.h
create mode 100644 arch/arm/mach-bcm/headsmp-brcmstb.S
create mode 100644 arch/arm/mach-bcm/hotplug-brcmstb.c
create mode 100644 drivers/power/reset/brcmstb-reboot.c
^ permalink raw reply
* [PATCH v5 1/8] ARM: brcmstb: add infrastructure for ARM-based Broadcom STB SoCs
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
The BCM7xxx series of Broadcom SoCs are used primarily in set-top boxes.
This patch adds machine support for the ARM-based Broadcom SoCs.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm/mach-bcm/Kconfig | 14 ++
arch/arm/mach-bcm/Makefile | 4 +
arch/arm/mach-bcm/brcmstb.c | 110 ++++++++++++
arch/arm/mach-bcm/brcmstb.h | 38 ++++
arch/arm/mach-bcm/headsmp-brcmstb.S | 34 ++++
arch/arm/mach-bcm/hotplug-brcmstb.c | 334 +++++++++++++++++++++++++++++++++++
7 files changed, 535 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-bcm/brcmstb.c
create mode 100644 arch/arm/mach-bcm/brcmstb.h
create mode 100644 arch/arm/mach-bcm/headsmp-brcmstb.S
create mode 100644 arch/arm/mach-bcm/hotplug-brcmstb.c
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index c1df4e9..7028d11 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -7,6 +7,7 @@ CONFIG_MACH_ARMADA_370=y
CONFIG_MACH_ARMADA_XP=y
CONFIG_ARCH_BCM=y
CONFIG_ARCH_BCM_MOBILE=y
+CONFIG_ARCH_BRCMSTB=y
CONFIG_GPIO_PCA953X=y
CONFIG_ARCH_HIGHBANK=y
CONFIG_ARCH_KEYSTONE=y
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 9fe6d88..2c1ae83 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -31,6 +31,20 @@ config ARCH_BCM_MOBILE
BCM11130, BCM11140, BCM11351, BCM28145 and
BCM28155 variants.
+config ARCH_BRCMSTB
+ bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
+ depends on MMU
+ select ARM_GIC
+ select MIGHT_HAVE_PCI
+ select HAVE_SMP
+ select HAVE_ARM_ARCH_TIMER
+ help
+ Say Y if you intend to run the kernel on a Broadcom ARM-based STB
+ chipset.
+
+ This enables support for Broadcom ARM-based set-top box chipsets,
+ including the 7445 family of chips.
+
endmenu
endif
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index c2ccd5a..b744a12 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -13,3 +13,7 @@
obj-$(CONFIG_ARCH_BCM_MOBILE) := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec)
+
+obj-$(CONFIG_ARCH_BRCMSTB) := brcmstb.o
+obj-$(CONFIG_SMP) += headsmp-brcmstb.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug-brcmstb.o
diff --git a/arch/arm/mach-bcm/brcmstb.c b/arch/arm/mach-bcm/brcmstb.c
new file mode 100644
index 0000000..7a6093d
--- /dev/null
+++ b/arch/arm/mach-bcm/brcmstb.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/console.h>
+#include <linux/clocksource.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "brcmstb.h"
+
+/***********************************************************************
+ * STB CPU (main application processor)
+ ***********************************************************************/
+
+static const char *brcmstb_match[] __initconst = {
+ "brcm,bcm7445",
+ "brcm,brcmstb",
+ NULL
+};
+
+static void __init brcmstb_init_early(void)
+{
+ add_preferred_console("ttyS", 0, "115200");
+}
+
+/***********************************************************************
+ * SMP boot
+ ***********************************************************************/
+
+#ifdef CONFIG_SMP
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __cpuinit brcmstb_secondary_init(unsigned int cpu)
+{
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+static int __cpuinit brcmstb_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /* Bring up power to the core if necessary */
+ if (brcmstb_cpu_get_power_state(cpu) == 0)
+ brcmstb_cpu_power_on(cpu);
+
+ brcmstb_cpu_boot(cpu);
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+struct smp_operations brcmstb_smp_ops __initdata = {
+ .smp_prepare_cpus = brcmstb_cpu_ctrl_setup,
+ .smp_secondary_init = brcmstb_secondary_init,
+ .smp_boot_secondary = brcmstb_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = brcmstb_cpu_kill,
+ .cpu_die = brcmstb_cpu_die,
+#endif
+};
+#endif
+
+DT_MACHINE_START(BRCMSTB, "Broadcom STB (Flattened Device Tree)")
+ .dt_compat = brcmstb_match,
+#ifdef CONFIG_SMP
+ .smp = smp_ops(brcmstb_smp_ops),
+#endif
+ .init_early = brcmstb_init_early,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/brcmstb.h b/arch/arm/mach-bcm/brcmstb.h
new file mode 100644
index 0000000..e49bde6
--- /dev/null
+++ b/arch/arm/mach-bcm/brcmstb.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __BRCMSTB_H__
+#define __BRCMSTB_H__
+
+#if !defined(__ASSEMBLY__)
+#include <linux/smp.h>
+#endif
+
+#if !defined(__ASSEMBLY__)
+extern void brcmstb_secondary_startup(void);
+extern void brcmstb_cpu_boot(unsigned int cpu);
+extern void brcmstb_cpu_power_on(unsigned int cpu);
+extern int brcmstb_cpu_get_power_state(unsigned int cpu);
+extern struct smp_operations brcmstb_smp_ops;
+#if defined(CONFIG_HOTPLUG_CPU)
+extern void brcmstb_cpu_die(unsigned int cpu);
+extern int brcmstb_cpu_kill(unsigned int cpu);
+void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus);
+#else
+static inline void brcmstb_cpu_die(unsigned int cpu) {}
+static inline int brcmstb_cpu_kill(unsigned int cpu) {}
+static inline void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus) {}
+#endif
+#endif
+
+#endif /* __BRCMSTB_H__ */
diff --git a/arch/arm/mach-bcm/headsmp-brcmstb.S b/arch/arm/mach-bcm/headsmp-brcmstb.S
new file mode 100644
index 0000000..57ec438
--- /dev/null
+++ b/arch/arm/mach-bcm/headsmp-brcmstb.S
@@ -0,0 +1,34 @@
+/*
+ * SMP boot code for secondary CPUs
+ * Based on arch/arm/mach-tegra/headsmp.S
+ *
+ * Copyright (C) 2010 NVIDIA, Inc.
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/assembler.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ .section ".text.head", "ax"
+ __CPUINIT
+
+ENTRY(brcmstb_secondary_startup)
+ /*
+ * Ensure CPU is in a sane state by disabling all IRQs and switching
+ * into SVC mode.
+ */
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0
+
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(brcmstb_secondary_startup)
diff --git a/arch/arm/mach-bcm/hotplug-brcmstb.c b/arch/arm/mach-bcm/hotplug-brcmstb.c
new file mode 100644
index 0000000..ff4a732
--- /dev/null
+++ b/arch/arm/mach-bcm/hotplug-brcmstb.c
@@ -0,0 +1,334 @@
+/*
+ * Broadcom STB CPU hotplug support for ARM
+ *
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/printk.h>
+#include <linux/regmap.h>
+#include <linux/smp.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+
+#include "brcmstb.h"
+
+enum {
+ ZONE_MAN_CLKEN_MASK = BIT(0),
+ ZONE_MAN_RESET_CNTL_MASK = BIT(1),
+ ZONE_MAN_MEM_PWR_MASK = BIT(4),
+ ZONE_RESERVED_1_MASK = BIT(5),
+ ZONE_MAN_ISO_CNTL_MASK = BIT(6),
+ ZONE_MANUAL_CONTROL_MASK = BIT(7),
+ ZONE_PWR_DN_REQ_MASK = BIT(9),
+ ZONE_PWR_UP_REQ_MASK = BIT(10),
+ ZONE_BLK_RST_ASSERT_MASK = BIT(10),
+ ZONE_PWR_OFF_STATE_MASK = BIT(26),
+ ZONE_PWR_ON_STATE_MASK = BIT(26),
+ ZONE_DPG_PWR_STATE_MASK = BIT(28),
+ ZONE_MEM_PWR_STATE_MASK = BIT(29),
+ ZONE_RESET_STATE_MASK = BIT(31),
+};
+
+static void __iomem *cpubiuctrl_block;
+static void __iomem *hif_cont_block;
+static u32 cpu0_pwr_zone_ctrl_reg;
+static u32 cpu_rst_cfg_reg;
+static u32 hif_cont_reg;
+DEFINE_PER_CPU(int, per_cpu_sw_state);
+
+static void __iomem *pwr_ctrl_get_base(unsigned int cpu)
+{
+ void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg;
+ base += (cpu * 4);
+ return base;
+}
+
+static u32 pwr_ctrl_rd(unsigned int cpu)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ return readl_relaxed(base);
+}
+
+static void pwr_ctrl_wr(unsigned int cpu, u32 val)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ writel(val, base);
+}
+
+static void cpu_rst_cfg_set(int cpu, int set)
+{
+ u32 val;
+ val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg);
+ if (set)
+ val |= BIT(cpu);
+ else
+ val &= ~BIT(cpu);
+ writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg);
+}
+
+static void cpu_set_boot_addr(int cpu, unsigned long boot_addr)
+{
+ const int reg_ofs = cpu * 8;
+ writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs);
+ writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs);
+}
+
+void brcmstb_cpu_boot(unsigned int cpu)
+{
+ pr_info("SMP: Booting CPU%d...\n", cpu);
+
+ /*
+ * set the reset vector to point to the secondary_startup
+ * routine
+ */
+ cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup));
+
+ flush_cache_all();
+
+ /* unhalt the cpu */
+ cpu_rst_cfg_set(cpu, 0);
+}
+
+void brcmstb_cpu_power_on(unsigned int cpu)
+{
+ /*
+ * The secondary cores power was cut, so we must go through
+ * power-on initialization.
+ */
+ u32 tmp;
+
+ pr_info("SMP: Powering up CPU%d...\n", cpu);
+
+ /* Request zone power up */
+ pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK);
+
+ /* Wait for the power up FSM to complete */
+ do {
+ tmp = pwr_ctrl_rd(cpu);
+ } while (!(tmp & ZONE_PWR_ON_STATE_MASK));
+
+ per_cpu(per_cpu_sw_state, cpu) = 1;
+}
+
+int brcmstb_cpu_get_power_state(unsigned int cpu)
+{
+ int tmp = pwr_ctrl_rd(cpu);
+ return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1;
+}
+
+void __ref brcmstb_cpu_die(unsigned int cpu)
+{
+ /* Derived from misc_bpcm_arm.c */
+
+ /* Clear SCTLR.C bit */
+ __asm__(
+ "mrc p15, 0, r0, c1, c0, 0\n"
+ "bic r0, r0, #(1 << 2)\n"
+ "mcr p15, 0, r0, c1, c0, 0\n"
+ : /* no output */
+ : /* no input */
+ : "r0" /* clobber r0 */
+ );
+
+ /*
+ * Instruction barrier to ensure cache is really disabled before
+ * cleaning/invalidating the caches
+ */
+ isb();
+
+ flush_cache_all();
+
+ /* Invalidate all instruction caches to PoU (ICIALLU) */
+ /* Data sync. barrier to ensure caches have emptied out */
+ __asm__("mcr p15, 0, r0, c7, c5, 0\n" : : : "r0");
+ dsb();
+
+ /*
+ * Clear ACTLR.SMP bit to prevent broadcast TLB messages from reaching
+ * this core
+ */
+ __asm__(
+ "mrc p15, 0, r0, c1, c0, 1\n"
+ "bic r0, r0, #(1 << 6)\n"
+ "mcr p15, 0, r0, c1, c0, 1\n"
+ : /* no output */
+ : /* no input */
+ : "r0" /* clobber r0 */
+ );
+
+ /* Disable all IRQs for this CPU */
+ arch_local_irq_disable();
+
+ per_cpu(per_cpu_sw_state, cpu) = 0;
+
+ /*
+ * Final full barrier to ensure everything before this instruction has
+ * quiesced.
+ */
+ isb();
+ dsb();
+
+ /* Sit and wait to die */
+ wfi();
+
+ /* We should never get here... */
+ nop();
+ panic("Spurious interrupt on CPU %d received!\n", cpu);
+}
+
+int brcmstb_cpu_kill(unsigned int cpu)
+{
+ u32 tmp;
+
+ pr_info("SMP: Powering down CPU%d...\n", cpu);
+
+ while (per_cpu(per_cpu_sw_state, cpu))
+ ;
+
+ /* Program zone reset */
+ pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK |
+ ZONE_PWR_DN_REQ_MASK);
+
+ /* Verify zone reset */
+ tmp = pwr_ctrl_rd(cpu);
+ if (!(tmp & ZONE_RESET_STATE_MASK))
+ pr_err("%s: Zone reset bit for CPU %d not asserted!\n",
+ __func__, cpu);
+
+ /* Wait for power down */
+ do {
+ tmp = pwr_ctrl_rd(cpu);
+ } while (!(tmp & ZONE_PWR_OFF_STATE_MASK));
+
+ /* Settle-time from Broadcom-internal DVT reference code */
+ udelay(7);
+
+ /* Assert reset on the CPU */
+ cpu_rst_cfg_set(cpu, 1);
+
+ return 1;
+}
+
+static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
+{
+ int rc = 0;
+ char *name;
+ int index;
+ struct device_node *syscon_np = NULL;
+
+ name = "syscon-cpu";
+
+ syscon_np = of_parse_phandle(np, name, 0);
+ if (!syscon_np) {
+ pr_err("can't find phandle %s\n", name);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ cpubiuctrl_block = of_iomap(syscon_np, 0);
+ if (!cpubiuctrl_block) {
+ pr_err("iomap failed for cpubiuctrl_block\n");
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ index = 1;
+ rc = of_property_read_u32_index(np, name, index,
+ &cpu0_pwr_zone_ctrl_reg);
+ if (rc) {
+ pr_err("failed to read %d from %s property (%d)\n", index, name,
+ rc);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ index = 2;
+ rc = of_property_read_u32_index(np, name, index, &cpu_rst_cfg_reg);
+ if (rc) {
+ pr_err("failed to read %d from %s property (%d)\n", index, name,
+ rc);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+cleanup:
+ if (syscon_np)
+ of_node_put(syscon_np);
+
+ return rc;
+}
+
+static int __init setup_hifcont_regs(struct device_node *np)
+{
+ int rc = 0;
+ char *name;
+ struct device_node *syscon_np = NULL;
+
+ name = "syscon-cont";
+
+ syscon_np = of_parse_phandle(np, name, 0);
+ if (!syscon_np) {
+ pr_err("can't find phandle %s\n", name);
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ hif_cont_block = of_iomap(syscon_np, 0);
+ if (!hif_cont_block) {
+ pr_err("iomap failed for hif_cont_block\n");
+ rc = -EINVAL;
+ goto cleanup;
+ }
+
+ /* offset is@top of hif_cont_block */
+ hif_cont_reg = 0;
+
+cleanup:
+ if (syscon_np)
+ of_node_put(syscon_np);
+
+ return rc;
+}
+
+void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus)
+{
+ int rc;
+ struct device_node *np;
+ char *name;
+
+ name = "brcm,brcmstb-smpboot";
+ np = of_find_compatible_node(NULL, NULL, name);
+ if (!np) {
+ pr_err("can't find compatible node %s\n", name);
+ return;
+ }
+
+ rc = setup_hifcpubiuctrl_regs(np);
+ if (rc)
+ return;
+
+ rc = setup_hifcont_regs(np);
+ if (rc)
+ return;
+}
+
--
1.7.1
^ permalink raw reply related
* [PATCH v5 2/8] power: reset: Add reboot driver for brcmstb
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Add support for reboot functionality on boards with ARM-based
Broadcom STB chipsets.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
---
drivers/power/reset/Kconfig | 10 +++
drivers/power/reset/Makefile | 1 +
drivers/power/reset/brcmstb-reboot.c | 120 ++++++++++++++++++++++++++++++++++
3 files changed, 131 insertions(+), 0 deletions(-)
create mode 100644 drivers/power/reset/brcmstb-reboot.c
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 9b3ea53..31b468b 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -6,6 +6,16 @@ menuconfig POWER_RESET
Say Y here to enable board reset and power off
+config POWER_RESET_BRCMSTB
+ bool "Broadcom STB reset driver"
+ depends on POWER_RESET && ARCH_BRCMSTB
+ help
+ This driver provides restart support for ARM-based Broadcom STB
+ boards.
+
+ Say Y here if you have an ARM-based Broadcom STB board and you wish
+ to have restart support.
+
config POWER_RESET_GPIO
bool "GPIO power-off driver"
depends on OF_GPIO && POWER_RESET
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 3e6ed88..806d056 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
+obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c
new file mode 100644
index 0000000..3f23692
--- /dev/null
+++ b/drivers/power/reset/brcmstb-reboot.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+#include <linux/smp.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/system_misc.h>
+
+#define RESET_SOURCE_ENABLE_REG 1
+#define SW_MASTER_RESET_REG 2
+
+static struct regmap *regmap;
+static u32 rst_src_en;
+static u32 sw_mstr_rst;
+
+static void brcmstb_reboot(enum reboot_mode mode, const char *cmd)
+{
+ int rc;
+ u32 tmp;
+
+ rc = regmap_write(regmap, rst_src_en, 1);
+ if (rc) {
+ pr_err("failed to write rst_src_en (%d)\n", rc);
+ return;
+ }
+
+ rc = regmap_read(regmap, rst_src_en, &tmp);
+ if (rc) {
+ pr_err("failed to read rst_src_en (%d)\n", rc);
+ return;
+ }
+
+ rc = regmap_write(regmap, sw_mstr_rst, 1);
+ if (rc) {
+ pr_err("failed to write sw_mstr_rst (%d)\n", rc);
+ return;
+ }
+
+ rc = regmap_read(regmap, sw_mstr_rst, &tmp);
+ if (rc) {
+ pr_err("failed to read sw_mstr_rst (%d)\n", rc);
+ return;
+ }
+
+ while (1)
+ ;
+}
+
+static int brcmstb_reboot_probe(struct platform_device *pdev)
+{
+ int rc;
+ struct device_node *np = pdev->dev.of_node;
+
+ regmap = syscon_regmap_lookup_by_phandle(np, "syscon");
+ if (IS_ERR(regmap)) {
+ pr_err("failed to get syscon phandle\n");
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_index(np, "syscon", RESET_SOURCE_ENABLE_REG,
+ &rst_src_en);
+ if (rc) {
+ pr_err("can't get rst_src_en offset (%d)\n", rc);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_index(np, "syscon", SW_MASTER_RESET_REG,
+ &sw_mstr_rst);
+ if (rc) {
+ pr_err("can't get sw_mstr_rst offset (%d)\n", rc);
+ return -EINVAL;
+ }
+
+ arm_pm_restart = brcmstb_reboot;
+
+ return 0;
+}
+
+static const struct of_device_id of_match[] = {
+ { .compatible = "brcm,brcmstb-reboot", },
+ {},
+};
+
+static struct platform_driver brcmstb_reboot_driver = {
+ .probe = brcmstb_reboot_probe,
+ .driver = {
+ .name = "brcmstb-reboot",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match,
+ },
+};
+
+static int __init brcmstb_reboot_init(void)
+{
+ return platform_driver_probe(&brcmstb_reboot_driver,
+ brcmstb_reboot_probe);
+}
+subsys_initcall(brcmstb_reboot_init);
--
1.7.1
^ permalink raw reply related
* [PATCH v5 3/8] ARM: brcmstb: add debug UART for earlyprintk support
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Add the UART definitions needed to support earlyprintk on brcmstb machines.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/Kconfig.debug | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5765abf..666afd7 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -94,6 +94,17 @@ choice
depends on ARCH_BCM2835
select DEBUG_UART_PL01X
+ config DEBUG_BRCMSTB_UART
+ bool "Use BRCMSTB UART for low-level debug"
+ depends on ARCH_BRCMSTB
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the first serial port on these devices.
+
+ If you have a Broadcom STB chip and would like early print
+ messages to appear over the UART, select this option.
+
config DEBUG_CLPS711X_UART1
bool "Kernel low-level debugging messages via UART1"
depends on ARCH_CLPS711X
@@ -1008,6 +1019,7 @@ config DEBUG_UART_PHYS
default 0xd4018000 if DEBUG_MMP_UART3
default 0xe0000000 if ARCH_SPEAR13XX
default 0xf0000be0 if ARCH_EBSA110
+ default 0xf0406b00 if DEBUG_BRCMSTB_UART
default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \
ARCH_ORION5X
@@ -1040,6 +1052,7 @@ config DEBUG_UART_VIRT
default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1
default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
+ default 0xfc406b00 if DEBUG_BRCMSTB_UART
default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
default 0xfd000000 if ARCH_SPEAR13XX
default 0xfd012000 if ARCH_MV78XX0
@@ -1091,7 +1104,8 @@ config DEBUG_UART_8250_WORD
default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \
ARCH_KEYSTONE || \
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
- DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1
+ DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 || \
+ DEBUG_BRCMSTB_UART
config DEBUG_UART_8250_FLOW_CONTROL
bool "Enable flow control for 8250 UART"
--
1.7.1
^ permalink raw reply related
* [PATCH v5 4/8] ARM: do CPU-specific init for Broadcom Brahma15 cores
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Perform any CPU-specific initialization required on the
Broadcom Brahma-15 core.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/mm/proc-v7.S | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index bd17819..98ea423 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -193,6 +193,7 @@ __v7_cr7mp_setup:
b 1f
__v7_ca7mp_setup:
__v7_ca15mp_setup:
+__v7_b15mp_setup:
mov r10, #0
1:
#ifdef CONFIG_SMP
@@ -494,6 +495,16 @@ __v7_ca15mp_proc_info:
.size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
/*
+ * Broadcom Corporation Brahma-B15 processor.
+ */
+ .type __v7_b15mp_proc_info, #object
+__v7_b15mp_proc_info:
+ .long 0x420f00f0
+ .long 0xff0ffff0
+ __v7_proc __v7_b15mp_setup, hwcaps = HWCAP_IDIV
+ .size __v7_b15mp_proc_info, . - __v7_b15mp_proc_info
+
+ /*
* Qualcomm Inc. Krait processors.
*/
.type __krait_proc_info, #object
--
1.7.1
^ permalink raw reply related
* [PATCH v5 5/8] ARM: brcmstb: add CPU binding for Broadcom Brahma15
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Add the Broadcom Brahma B15 CPU to the DT CPU binding list.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
Documentation/devicetree/bindings/arm/cpus.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 9130435..0cd1e25 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -163,6 +163,7 @@ nodes to be present and contain the properties described below.
"arm,cortex-r4"
"arm,cortex-r5"
"arm,cortex-r7"
+ "brcm,brahma-b15"
"faraday,fa526"
"intel,sa110"
"intel,sa1100"
--
1.7.1
^ permalink raw reply related
* [PATCH v5 6/8] ARM: brcmstb: add misc. DT bindings for brcmstb
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Document the bindings that the Broadcom STB platform needs
for proper bootup.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../devicetree/bindings/arm/brcm-brcmstb.txt | 95 ++++++++++++++++++++
1 files changed, 95 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/brcm-brcmstb.txt
diff --git a/Documentation/devicetree/bindings/arm/brcm-brcmstb.txt b/Documentation/devicetree/bindings/arm/brcm-brcmstb.txt
new file mode 100644
index 0000000..3c436cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/brcm-brcmstb.txt
@@ -0,0 +1,95 @@
+ARM Broadcom STB platforms Device Tree Bindings
+-----------------------------------------------
+Boards with Broadcom Brahma15 ARM-based BCMxxxx (generally BCM7xxx variants)
+SoC shall have the following DT organization:
+
+Required root node properties:
+ - compatible: "brcm,bcm<chip_id>", "brcm,brcmstb"
+
+example:
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "Broadcom STB (bcm7445)";
+ compatible = "brcm,bcm7445", "brcm,brcmstb";
+
+Further, syscon nodes that map platform-specific registers used for general
+system control is required:
+
+ - compatible: "brcm,bcm<chip_id>-sun-top-ctrl", "syscon"
+ - compatible: "brcm,bcm<chip_id>-hif-cpubiuctrl", "syscon"
+ - compatible: "brcm,bcm<chip_id>-hif-continuation", "syscon"
+
+example:
+ rdb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0x00 0xf0000000 0x1000000>;
+
+ sun_top_ctrl: syscon at 404000 {
+ compatible = "brcm,bcm7445-sun-top-ctrl", "syscon";
+ reg = <0x404000 0x51c>;
+ };
+
+ hif_cpubiuctrl: syscon at 3e2400 {
+ compatible = "brcm,bcm7445-hif-cpubiuctrl", "syscon";
+ reg = <0x3e2400 0x5b4>;
+ };
+
+ hif_continuation: syscon at 452000 {
+ compatible = "brcm,bcm7445-hif-continuation", "syscon";
+ reg = <0x452000 0x100>;
+ };
+ };
+
+Lastly, nodes that allow for support of SMP initialization and reboot are
+required:
+
+smpboot
+-------
+Required properties:
+
+ - compatible
+ The string "brcm,brcmstb-smpboot".
+
+ - syscon-cpu
+ A phandle / integer array property which lets the BSP know the location
+ of certain CPU power-on registers.
+
+ The layout of the property is as follows:
+ o a phandle to the "hif_cpubiuctrl" syscon node
+ o offset to the base CPU power zone register
+ o offset to the base CPU reset register
+
+ - syscon-cont
+ A phandle pointing to the syscon node which describes the CPU boot
+ continuation registers.
+ o a phandle to the "hif_continuation" syscon node
+
+example:
+ smpboot {
+ compatible = "brcm,brcmstb-smpboot";
+ syscon-cpu = <&hif_cpubiuctrl 0x88 0x178>;
+ syscon-cont = <&hif_continuation>;
+ };
+
+reboot
+-------
+Required properties
+
+ - compatible
+ The string property "brcm,brcmstb-reboot".
+
+ - syscon
+ A phandle / integer array that points to the syscon node which describes
+ the general system reset registers.
+ o a phandle to "sun_top_ctrl"
+ o offset to the "reset source enable" register
+ o offset to the "software master reset" register
+
+example:
+ reboot {
+ compatible = "brcm,brcmstb-reboot";
+ syscon = <&sun_top_ctrl 0x304 0x308>;
+ };
--
1.7.1
^ permalink raw reply related
* [PATCH v5 7/8] ARM: brcmstb: gic: add compatible string for Broadcom Brahma15
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Document the Broadcom Brahma B15 GIC implementation as compatible
with the ARM GIC standard.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
Documentation/devicetree/bindings/arm/gic.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
index 3dfb0c0..d7409fd 100644
--- a/Documentation/devicetree/bindings/arm/gic.txt
+++ b/Documentation/devicetree/bindings/arm/gic.txt
@@ -15,6 +15,7 @@ Main node required properties:
"arm,cortex-a9-gic"
"arm,cortex-a7-gic"
"arm,arm11mp-gic"
+ "brcm,brahma-b15-gic"
- interrupt-controller : Identifies the node as an interrupt controller
- #interrupt-cells : Specifies the number of cells needed to encode an
interrupt source. The type shall be a <u32> and the value shall be 3.
--
1.7.1
^ permalink raw reply related
* [PATCH v5 8/8] ARM: brcmstb: dts: add a reference DTS for Broadcom 7445
From: Marc Carino @ 2014-01-22 3:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390361452-3124-1-git-send-email-marc.ceeeee@gmail.com>
Add a sample DTS which will allow bootup of a board populated
with the BCM7445 chip.
Signed-off-by: Marc Carino <marc.ceeeee@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/boot/dts/bcm7445.dts | 111 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 111 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/boot/dts/bcm7445.dts
diff --git a/arch/arm/boot/dts/bcm7445.dts b/arch/arm/boot/dts/bcm7445.dts
new file mode 100644
index 0000000..ffa3305
--- /dev/null
+++ b/arch/arm/boot/dts/bcm7445.dts
@@ -0,0 +1,111 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "Broadcom STB (bcm7445)";
+ compatible = "brcm,bcm7445", "brcm,brcmstb";
+ interrupt-parent = <&gic>;
+
+ chosen {};
+
+ memory {
+ device_type = "memory";
+ reg = <0x00 0x00000000 0x00 0x40000000>,
+ <0x00 0x40000000 0x00 0x40000000>,
+ <0x00 0x80000000 0x00 0x40000000>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu at 0 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu at 1 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu at 2 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu at 3 {
+ compatible = "brcm,brahma-b15";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ gic: interrupt-controller at ffd00000 {
+ compatible = "brcm,brahma-b15-gic", "arm,cortex-a15-gic";
+ reg = <0x00 0xffd01000 0x00 0x1000>,
+ <0x00 0xffd02000 0x00 0x2000>,
+ <0x00 0xffd04000 0x00 0x2000>,
+ <0x00 0xffd06000 0x00 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ rdb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0x00 0xf0000000 0x1000000>;
+
+ serial at 406b00 {
+ compatible = "ns16550a";
+ reg = <0x406b00 0x20>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ interrupts = <0 75 0x4>;
+ clock-frequency = <0x4d3f640>;
+ };
+
+ sun_top_ctrl: syscon at 404000 {
+ compatible = "brcm,bcm7445-sun-top-ctrl",
+ "syscon";
+ reg = <0x404000 0x51c>;
+ };
+
+ hif_cpubiuctrl: syscon at 3e2400 {
+ compatible = "brcm,bcm7445-hif-cpubiuctrl",
+ "syscon";
+ reg = <0x3e2400 0x5b4>;
+ };
+
+ hif_continuation: syscon at 452000 {
+ compatible = "brcm,bcm7445-hif-continuation",
+ "syscon";
+ reg = <0x452000 0x100>;
+ };
+ };
+
+ smpboot {
+ compatible = "brcm,brcmstb-smpboot";
+ syscon-cpu = <&hif_cpubiuctrl 0x88 0x178>;
+ syscon-cont = <&hif_continuation>;
+ };
+
+ reboot {
+ compatible = "brcm,brcmstb-reboot";
+ syscon = <&sun_top_ctrl 0x304 0x308>;
+ };
+};
--
1.7.1
^ permalink raw reply related
* [PATCH v3 2/2] serial: fsl_lpuart: add DMA support
From: Yao Yuan @ 2014-01-22 3:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b55917fd1b664ebeaeb135330ff806bd@DM2PR03MB349.namprd03.prod.outlook.com>
Hi, Mark
Think twice.
Yes, you are right. "of_get_property" is not necessary here.
Thanks for your suggestion.
> -----Original Message-----
> From: linux-serial-owner at vger.kernel.org [mailto:linux-serial-
> owner at vger.kernel.org] On Behalf Of Yao Yuan
> Sent: Thursday, January 16, 2014 2:54 PM
> To: Mark Rutland
> Cc: gregkh at linuxfoundation.org; shawn.guo at linaro.org;
> linux at arm.linux.org.uk; linux-arm-kernel at lists.infradead.org;
> arnd at arndb.de; linux-serial at vger.kernel.org
> Subject: RE: [PATCH v3 2/2] serial: fsl_lpuart: add DMA support
>
> Hi, mark
>
> > -----Original Message-----
> > > +#ifdef CONFIG_SERIAL_FSL_LPUART_DMA
> > > + struct platform_device *pdev = to_platform_device(port->dev);
> > > + struct device_node *np = pdev->dev.of_node;
> > > +
> > > + if (of_get_property(np, "dmas", NULL)) {
> > > + sport->lpuart_dma_use = true;
> > > + lpuart_dma_tx_request(port);
> > > + lpuart_dma_rx_request(port);
> > > + temp = readb(port->membase + UARTCR5);
> > > + writeb(temp | UARTCR5_TDMAS, port->membase +
> > > + UARTCR5);
> >
> > Rather than reading the raw dt to find out if you have dmas, can you
> > not just attempt to request the dmas and if either fail give up on
> using them?
>
> Yes, the dma request function can also confirm it. But maybe it's better
> that add the judge as a dma entrance first?
> I think if the dmas is be written it means dma want be support. At this
> time, rather than silently change to no dma model, we may throw the error
> when some errors happened.
> But dma request failed may have many other reasons. Also the judge will
> just run only once, it will not waste of performance.
> If the dmas is not be written, we don't need to do anything about dma.
> \x13 ?
& ~ & \x18 +- ?\x17 w ? m b lz ) w*jg
?j/ z ? 2 ?
> & )? a \x7f
G h \x0f j:+v w ?
^ permalink raw reply
* [PATCH v4 0/3] serial: fsl_lpuart: add DMA support
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
Changed in v4:
- Move dma properties from dtsi to dts.
- Cancle the macro(SERIAL_FSL_LPUART_DMA) .
- Separate the document for clocks which undocumented before into a single patch.
- Change some explanations in document(clocks, clock-names, dmas, dma-names).
- Change "lpuart-tx" and "lpuart-rx" to "tx" and "rx".
Changed in v3:
- Use the streaming DMA API for receive.
- Add the macro(SERIAL_FSL_LPUART_DMA) and dts node propertie for whether using the dma.
- Adjust some coding style.
Changed in v2:
- Add eDMA support for lpuart receive.
- Use dma_mapping_error test dma_map_single.
- Change some names of variable.
- Fix some bugs.
Added in v1:
- Add device tree bindings for lupart eDMA support.
- Add eDMA support for lpuart send.
^ permalink raw reply
* [PATCH v4 1/3] ARM: dts: vf610: lpuart: Add eDMA support
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390363773-24108-1-git-send-email-yao.yuan@freescale.com>
Add lpuart dts node properties for eDMA support, them depend on the eDMA driver.
Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
arch/arm/boot/dts/vf610-twr.dts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 80db14e..4149ed6 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -101,5 +101,8 @@
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
+ dmas = <&edma0 0 4>,
+ <&edma0 0 5>;
+ dma-names = "rx","tx";
status = "okay";
};
--
1.8.4
^ permalink raw reply related
* [PATCH v4 2/3] serial: fsl_lpuart: add DMA support
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390363773-24108-1-git-send-email-yao.yuan@freescale.com>
Add dma support for lpuart. This function depend on DMA driver.
You can turn on it by write both the dmas and dma-name properties in dts node.
Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
.../devicetree/bindings/serial/fsl-lpuart.txt | 19 +-
drivers/tty/serial/fsl_lpuart.c | 430 ++++++++++++++++++++-
2 files changed, 433 insertions(+), 16 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index 6fd1dd1..6e1cbbf 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -5,10 +5,21 @@ Required properties:
- reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt
+Optional properties:
+- dmas: Generic dma devicetree binding as described
+ in Documentation/devicetree/bindings/dma/dma.txt.
+- dma-names: Two dmas have to be defined, "rx" and "tx".
+ An ordered list of channel names affiliated to the above.
+
+Note: Optional properties for DMA support. Write them both or both not.
+
Example:
uart0: serial at 40027000 {
- compatible = "fsl,vf610-lpuart";
- reg = <0x40027000 0x1000>;
- interrupts = <0 61 0x00>;
- };
+ compatible = "fsl,vf610-lpuart";
+ reg = <0x40027000 0x1000>;
+ interrupts = <0 61 0x00>;
+ dmas = <&edma0 0 2>,
+ <&edma0 0 3>;
+ dma-names = "rx","tx";
+ };
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 8978dc9..c5eb897 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -13,14 +13,19 @@
#define SUPPORT_SYSRQ
#endif
-#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
#include <linux/io.h>
#include <linux/irq.h>
-#include <linux/clk.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/console.h>
+#include <linux/of_dma.h>
#include <linux/serial_core.h>
+#include <linux/slab.h>
#include <linux/tty_flip.h>
/* All registers are 8-bit width */
@@ -112,6 +117,10 @@
#define UARTSFIFO_TXOF 0x02
#define UARTSFIFO_RXUF 0x01
+#define DMA_MAXBURST 16
+#define DMA_MAXBURST_MASK (DMA_MAXBURST - 1)
+#define FSL_UART_RX_DMA_BUFFER_SIZE 64
+
#define DRIVER_NAME "fsl-lpuart"
#define DEV_NAME "ttyLP"
#define UART_NR 6
@@ -121,6 +130,24 @@ struct lpuart_port {
struct clk *clk;
unsigned int txfifo_size;
unsigned int rxfifo_size;
+
+ bool lpuart_dma_use;
+ struct dma_chan *dma_tx_chan;
+ struct dma_chan *dma_rx_chan;
+ struct dma_async_tx_descriptor *dma_tx_desc;
+ struct dma_async_tx_descriptor *dma_rx_desc;
+ dma_addr_t dma_tx_buf_bus;
+ dma_addr_t dma_rx_buf_bus;
+ dma_cookie_t dma_tx_cookie;
+ dma_cookie_t dma_rx_cookie;
+ unsigned char *dma_tx_buf_virt;
+ unsigned char *dma_rx_buf_virt;
+ unsigned int dma_tx_bytes;
+ unsigned int dma_rx_bytes;
+ int dma_tx_in_progress;
+ int dma_rx_in_progress;
+ unsigned int dma_rx_timeout;
+ struct timer_list lpuart_timer;
};
static struct of_device_id lpuart_dt_ids[] = {
@@ -131,6 +158,10 @@ static struct of_device_id lpuart_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
+/* Forward declare this for the dma callbacks*/
+static void lpuart_dma_tx_complete(void *arg);
+static void lpuart_dma_rx_complete(void *arg);
+
static void lpuart_stop_tx(struct uart_port *port)
{
unsigned char temp;
@@ -152,6 +183,210 @@ static void lpuart_enable_ms(struct uart_port *port)
{
}
+static void lpuart_copy_rx_to_tty(struct lpuart_port *sport,
+ struct tty_port *tty, int count)
+{
+ int copied;
+
+ sport->port.icount.rx += count;
+
+ if (!tty) {
+ dev_err(sport->port.dev, "No tty port\n");
+ return;
+ }
+
+ dma_sync_single_for_cpu(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+ copied = tty_insert_flip_string(tty,
+ ((unsigned char *)(sport->dma_rx_buf_virt)), count);
+
+ if (copied != count) {
+ WARN_ON(1);
+ dev_err(sport->port.dev, "RxData copy to tty layer failed\n");
+ }
+
+ dma_sync_single_for_device(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE);
+}
+
+static void lpuart_pio_tx(struct lpuart_port *sport)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ while (!uart_circ_empty(xmit) &&
+ readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size) {
+ writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ sport->port.icount.tx++;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&sport->port);
+
+ if (uart_circ_empty(xmit))
+ writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_TDMAS,
+ sport->port.membase + UARTCR5);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static int lpuart_dma_tx(struct lpuart_port *sport, unsigned long count)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ dma_addr_t tx_bus_addr;
+
+ dma_sync_single_for_device(sport->port.dev, sport->dma_tx_buf_bus,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ sport->dma_tx_bytes = count & ~(DMA_MAXBURST_MASK);
+ tx_bus_addr = sport->dma_tx_buf_bus + xmit->tail;
+ sport->dma_tx_desc = dmaengine_prep_slave_single(sport->dma_tx_chan,
+ tx_bus_addr, sport->dma_tx_bytes,
+ DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
+
+ if (!sport->dma_tx_desc) {
+ dev_err(sport->port.dev, "Not able to get desc for tx\n");
+ return -EIO;
+ }
+
+ sport->dma_tx_desc->callback = lpuart_dma_tx_complete;
+ sport->dma_tx_desc->callback_param = sport;
+ sport->dma_tx_in_progress = 1;
+ sport->dma_tx_cookie = dmaengine_submit(sport->dma_tx_desc);
+ dma_async_issue_pending(sport->dma_tx_chan);
+
+ return 0;
+}
+
+static void lpuart_prepare_tx(struct lpuart_port *sport)
+{
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ unsigned long count = CIRC_CNT_TO_END(xmit->head,
+ xmit->tail, UART_XMIT_SIZE);
+
+ if (!count)
+ return;
+
+ if (count < DMA_MAXBURST)
+ writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_TDMAS,
+ sport->port.membase + UARTCR5);
+ else {
+ writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_TDMAS,
+ sport->port.membase + UARTCR5);
+ lpuart_dma_tx(sport, count);
+ }
+}
+
+static void lpuart_dma_tx_complete(void *arg)
+{
+ struct lpuart_port *sport = arg;
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ unsigned long flags;
+
+ async_tx_ack(sport->dma_tx_desc);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ xmit->tail = (xmit->tail + sport->dma_tx_bytes) & (UART_XMIT_SIZE - 1);
+ sport->dma_tx_in_progress = 0;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&sport->port);
+
+ lpuart_prepare_tx(sport);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static int lpuart_dma_rx(struct lpuart_port *sport)
+{
+ dma_sync_single_for_device(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE);
+ sport->dma_rx_desc = dmaengine_prep_slave_single(sport->dma_rx_chan,
+ sport->dma_rx_buf_bus, FSL_UART_RX_DMA_BUFFER_SIZE,
+ DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+
+ if (!sport->dma_rx_desc) {
+ dev_err(sport->port.dev, "Not able to get desc for rx\n");
+ return -EIO;
+ }
+
+ sport->dma_rx_desc->callback = lpuart_dma_rx_complete;
+ sport->dma_rx_desc->callback_param = sport;
+ sport->dma_rx_in_progress = 1;
+ sport->dma_rx_cookie = dmaengine_submit(sport->dma_rx_desc);
+ dma_async_issue_pending(sport->dma_rx_chan);
+
+ return 0;
+}
+
+static void lpuart_dma_rx_complete(void *arg)
+{
+ struct lpuart_port *sport = arg;
+ struct tty_port *port = &sport->port.state->port;
+ unsigned long flags;
+
+ async_tx_ack(sport->dma_rx_desc);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ sport->dma_rx_in_progress = 0;
+ lpuart_copy_rx_to_tty(sport, port, FSL_UART_RX_DMA_BUFFER_SIZE);
+ tty_flip_buffer_push(port);
+ lpuart_dma_rx(sport);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static void lpuart_timer_func(unsigned long data)
+{
+ struct lpuart_port *sport = (struct lpuart_port *)data;
+ struct tty_port *port = &sport->port.state->port;
+ struct dma_tx_state state;
+ unsigned long flags;
+ unsigned char temp;
+ int count;
+
+ del_timer(&sport->lpuart_timer);
+ dmaengine_pause(sport->dma_rx_chan);
+ dmaengine_tx_status(sport->dma_rx_chan, sport->dma_rx_cookie, &state);
+ dmaengine_terminate_all(sport->dma_rx_chan);
+ count = FSL_UART_RX_DMA_BUFFER_SIZE - state.residue;
+ async_tx_ack(sport->dma_rx_desc);
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ sport->dma_rx_in_progress = 0;
+ lpuart_copy_rx_to_tty(sport, port, count);
+ tty_flip_buffer_push(port);
+ temp = readb(sport->port.membase + UARTCR5);
+ writeb(temp & ~UARTCR5_RDMAS, sport->port.membase + UARTCR5);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static inline void lpuart_prepare_rx(struct lpuart_port *sport)
+{
+ unsigned long flags;
+ unsigned char temp;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ init_timer(&sport->lpuart_timer);
+ sport->lpuart_timer.function = lpuart_timer_func;
+ sport->lpuart_timer.data = (unsigned long)sport;
+ sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout;
+ add_timer(&sport->lpuart_timer);
+
+ lpuart_dma_rx(sport);
+ temp = readb(sport->port.membase + UARTCR5);
+ writeb(temp | UARTCR5_RDMAS, sport->port.membase + UARTCR5);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
{
struct circ_buf *xmit = &sport->port.state->xmit;
@@ -172,14 +407,21 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
static void lpuart_start_tx(struct uart_port *port)
{
- struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct circ_buf *xmit = &sport->port.state->xmit;
unsigned char temp;
temp = readb(port->membase + UARTCR2);
writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
- if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
- lpuart_transmit_buffer(sport);
+ if (sport->lpuart_dma_use) {
+ if (!uart_circ_empty(xmit) && !sport->dma_tx_in_progress)
+ lpuart_prepare_tx(sport);
+ } else {
+ if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
+ lpuart_transmit_buffer(sport);
+ }
}
static irqreturn_t lpuart_txint(int irq, void *dev_id)
@@ -279,12 +521,19 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
sts = readb(sport->port.membase + UARTSR1);
- if (sts & UARTSR1_RDRF)
- lpuart_rxint(irq, dev_id);
-
+ if (sts & UARTSR1_RDRF) {
+ if (sport->lpuart_dma_use)
+ lpuart_prepare_rx(sport);
+ else
+ lpuart_rxint(irq, dev_id);
+ }
if (sts & UARTSR1_TDRE &&
- !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS))
- lpuart_txint(irq, dev_id);
+ !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS)) {
+ if (sport->lpuart_dma_use)
+ lpuart_pio_tx(sport);
+ else
+ lpuart_txint(irq, dev_id);
+ }
return IRQ_HANDLED;
}
@@ -366,13 +615,156 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
sport->port.membase + UARTCFIFO);
- writeb(2, sport->port.membase + UARTTWFIFO);
+ writeb(0, sport->port.membase + UARTTWFIFO);
writeb(1, sport->port.membase + UARTRWFIFO);
/* Restore cr2 */
writeb(cr2_saved, sport->port.membase + UARTCR2);
}
+static int lpuart_dma_tx_request(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *tx_chan;
+ struct dma_slave_config dma_tx_sconfig;
+ dma_addr_t dma_bus;
+ unsigned char *dma_buf;
+ int ret;
+
+ tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
+
+ if (!tx_chan) {
+ dev_err(sport->port.dev, "Dma tx channel request failed!\n");
+ return -ENODEV;
+ }
+
+ dma_bus = dma_map_single(tx_chan->device->dev,
+ sport->port.state->xmit.buf,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+
+ if (dma_mapping_error(tx_chan->device->dev, dma_bus)) {
+ dev_err(sport->port.dev, "dma_map_single tx failed\n");
+ dma_release_channel(tx_chan);
+ return -ENOMEM;
+ }
+
+ dma_buf = sport->port.state->xmit.buf;
+ dma_tx_sconfig.dst_addr = sport->port.mapbase + UARTDR;
+ dma_tx_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_tx_sconfig.dst_maxburst = DMA_MAXBURST;
+ dma_tx_sconfig.direction = DMA_MEM_TO_DEV;
+ ret = dmaengine_slave_config(tx_chan, &dma_tx_sconfig);
+
+ if (ret < 0) {
+ dev_err(sport->port.dev,
+ "Dma slave config failed, err = %d\n", ret);
+ dma_release_channel(tx_chan);
+ return ret;
+ }
+
+ sport->dma_tx_chan = tx_chan;
+ sport->dma_tx_buf_virt = dma_buf;
+ sport->dma_tx_buf_bus = dma_bus;
+ sport->dma_tx_in_progress = 0;
+
+ return 0;
+}
+
+static int lpuart_dma_rx_request(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *rx_chan;
+ struct dma_slave_config dma_rx_sconfig;
+ dma_addr_t dma_bus;
+ unsigned char *dma_buf;
+ int ret;
+
+ rx_chan = dma_request_slave_channel(sport->port.dev, "rx");
+
+ if (!rx_chan) {
+ dev_err(sport->port.dev, "Dma rx channel request failed!\n");
+ return -ENODEV;
+ }
+
+ dma_buf = devm_kzalloc(sport->port.dev,
+ FSL_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL);
+
+ if (!dma_buf) {
+ dev_err(sport->port.dev, "Dma rx alloc failed\n");
+ dma_release_channel(rx_chan);
+ return -ENOMEM;
+ }
+
+ dma_bus = dma_map_single(rx_chan->device->dev, dma_buf,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(rx_chan->device->dev, dma_bus)) {
+ dev_err(sport->port.dev, "dma_map_single rx failed\n");
+ dma_release_channel(rx_chan);
+ return -ENOMEM;
+ }
+
+ dma_rx_sconfig.src_addr = sport->port.mapbase + UARTDR;
+ dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_rx_sconfig.src_maxburst = 1;
+ dma_rx_sconfig.direction = DMA_DEV_TO_MEM;
+ ret = dmaengine_slave_config(rx_chan, &dma_rx_sconfig);
+
+ if (ret < 0) {
+ dev_err(sport->port.dev,
+ "Dma slave config failed, err = %d\n", ret);
+ dma_release_channel(rx_chan);
+ return ret;
+ }
+
+ sport->dma_rx_chan = rx_chan;
+ sport->dma_rx_buf_virt = dma_buf;
+ sport->dma_rx_buf_bus = dma_bus;
+ sport->dma_rx_in_progress = 0;
+
+ sport->dma_rx_timeout = (sport->port.timeout - HZ / 50) *
+ FSL_UART_RX_DMA_BUFFER_SIZE * 3 /
+ sport->rxfifo_size / 2;
+
+ if (sport->dma_rx_timeout < msecs_to_jiffies(20))
+ sport->dma_rx_timeout = msecs_to_jiffies(20);
+
+ return 0;
+}
+
+static void lpuart_dma_tx_free(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *dma_chan;
+
+ dma_unmap_single(sport->port.dev, sport->dma_tx_buf_bus,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ dma_chan = sport->dma_tx_chan;
+ sport->dma_tx_chan = NULL;
+ sport->dma_tx_buf_bus = 0;
+ sport->dma_tx_buf_virt = NULL;
+ dma_release_channel(dma_chan);
+}
+
+static void lpuart_dma_rx_free(struct uart_port *port)
+{
+ struct lpuart_port *sport = container_of(port,
+ struct lpuart_port, port);
+ struct dma_chan *dma_chan;
+
+ dma_unmap_single(sport->port.dev, sport->dma_rx_buf_bus,
+ FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+ dma_chan = sport->dma_rx_chan;
+ sport->dma_rx_chan = NULL;
+ sport->dma_rx_buf_bus = 0;
+ sport->dma_rx_buf_virt = NULL;
+ dma_release_channel(dma_chan);
+}
+
static int lpuart_startup(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
@@ -380,6 +772,15 @@ static int lpuart_startup(struct uart_port *port)
unsigned long flags;
unsigned char temp;
+ /*whether use dma support by dma request results*/
+ if (lpuart_dma_tx_request(port) || lpuart_dma_rx_request(port)) {
+ sport->lpuart_dma_use = false;
+ } else {
+ sport->lpuart_dma_use = true;
+ temp = readb(port->membase + UARTCR5);
+ writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
+ }
+
ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0,
DRIVER_NAME, sport);
if (ret)
@@ -414,6 +815,11 @@ static void lpuart_shutdown(struct uart_port *port)
spin_unlock_irqrestore(&port->lock, flags);
devm_free_irq(port->dev, port->irq, sport);
+
+ if (sport->lpuart_dma_use) {
+ lpuart_dma_tx_free(port);
+ lpuart_dma_rx_free(port);
+ }
}
static void
--
1.8.4
^ permalink raw reply related
* [PATCH v4 3/3] serial: fsl_lpuart: documented the clock requirement.
From: Yuan Yao @ 2014-01-22 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390363773-24108-1-git-send-email-yao.yuan@freescale.com>
It was previously required but not documented.
Add the text to the binding along with the new "dmas" addition.
Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
Documentation/devicetree/bindings/serial/fsl-lpuart.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index 6e1cbbf..9666f97 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -4,6 +4,8 @@ Required properties:
- compatible : Should be "fsl,<soc>-lpuart"
- reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt
+- clocks : phandle + clock specifier pairs, one for each entry in clock-names
+- clock-names : should contain: "ipg" - the uart clock
Optional properties:
- dmas: Generic dma devicetree binding as described
@@ -19,6 +21,8 @@ uart0: serial at 40027000 {
compatible = "fsl,vf610-lpuart";
reg = <0x40027000 0x1000>;
interrupts = <0 61 0x00>;
+ clocks = <&clks VF610_CLK_UART0>;
+ clock-names = "ipg";
dmas = <&edma0 0 2>,
<&edma0 0 3>;
dma-names = "rx","tx";
--
1.8.4
^ permalink raw reply related
* [PATCH v6 0/3] AArch64: KGDB support
From: Vijay Kilari @ 2014-01-22 4:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140121183604.GQ30706@mudshark.cambridge.arm.com>
On Wed, Jan 22, 2014 at 12:06 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jan 21, 2014 at 02:10:14PM +0000, Vijay Kilari wrote:
>> Hi Will,
>
> Hello Vijay,
>
>> On Mon, Jan 20, 2014 at 3:53 PM, Will Deacon <will.deacon@arm.com> wrote:
>> > Well, the warnings are one thing but the 100 miles of backtrace output that
>> > appear on every boot (and I think end in an oops) are probably more
>> > important to fix. Please enable CONFIG_KGDB_TESTS and
>> > CONFIG_KGDB_TESTS_ON_BOOT and take a look.
>> >
>>
>> I could manage to run KGDB boot tests if I run from sysfs after complete boot
>>
>> echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
>>
>> Here the value of PSTATE is 80000145, which means PSTATE.D is unmasked
>> hence it works fine.
>>
>> If I run during boot by enabling CONFIG_KGDB_TESTS_ON_BOOT,
>> the step debug test fail because value of PSTATE is 80000345.
>> If I force PSTATE.D to 0, it works fine
>>
>> In debug_monitors.c file, only PSTATE.SS & MDSCR.KDE/MDE is managed
>> but not PSTATE.D
>>
>> Can you please let me know if where PSTATE.D is managed in arm64?
>
> That's a good point: I think we wait until our first exception before they
> are unmasked. Perhaps we should:
>
> (1) Move local_dbg_{save,restore} from debug-monitors.h into irqflags.h
> (2) Add local_dbg_enable/local_dbg_disable macros
> (3) Add a call to local_dbg_enable in the clear_os_lock function after the
> isb().
>
> Does that work for you?
Yes, only after first exception occurs the PSTATE.D is unmasked.
I have patched (temp) as below and now KGDB boot tests pass
diff --git a/arch/arm64/include/asm/debug-monitors.h
b/arch/arm64/include/asm/debug-monitors.h
index aff3a76..ea2bc46 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -64,6 +111,24 @@ struct task_struct;
#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
+#define local_dbg_enable()
\
+ do {
\
+ asm volatile(
\
+ "msr daifclr, #9 //
arch_local_irq_disable" \
+ :
\
+ :
\
+ : "memory");
\
+ } while (0)
+
+#define local_dbg_disable()
\
+ do {
\
+ asm volatile(
\
+ "msr daifset, #9 //
arch_local_irq_disable" \
+ :
\
+ :
\
+ : "memory");
\
+ } while (0)
+
struct step_hook {
struct list_head node;
int (*fn)(struct pt_regs *regs, unsigned int insn, unsigned long addr);
diff --git a/arch/arm64/kernel/debug-monitors.c
b/arch/arm64/kernel/debug-monitors.c
index f8b90c0..d0e55f7 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -139,6 +142,7 @@ static void clear_os_lock(void *unused)
{
asm volatile("msr oslar_el1, %0" : : "r" (0));
isb();
+ local_dbg_enable();
}
boot test:
[32927.161317] msgmni has been set to 1870
[32927.212747] alg: No test for stdrng (krng)
[32927.213953] Key type asymmetric registered
[32927.214899] Asymmetric key parser 'x509' registered
[32927.220029] Block layer SCSI generic (bsg) driver version 0.4
loaded (major 253)
[32927.225824] io scheduler noop registered
[32927.226764] io scheduler deadline registered
[32927.230714] io scheduler cfq registered (default)
[32927.237895] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[32927.266066] kgdb: Registered I/O driver kgdbts.
[32927.266419] kgdb: Waiting for connection from remote gdb...
[32927.268598] kgdbts:RUN plant and detach test
[32927.270683] kgdbts:RUN sw breakpoint test
[32927.287659] kgdbts:RUN bad memory access test
[32927.290322] kgdbts:RUN singlestep test 1000 iterations
[32927.330342] kgdbts:RUN singlestep [0/1000]
[32931.286356] kgdbts:RUN singlestep [100/1000]
[32935.242536] kgdbts:RUN singlestep [200/1000]
[32939.205392] kgdbts:RUN singlestep [300/1000]
[32943.169522] kgdbts:RUN singlestep [400/1000]
[32947.231868] kgdbts:RUN singlestep [500/1000]
[32951.188008] kgdbts:RUN singlestep [600/1000]
[32955.332243] kgdbts:RUN singlestep [700/1000]
[32959.467109] kgdbts:RUN singlestep [800/1000]
[32963.430888] kgdbts:RUN singlestep [900/1000]
[32967.346992] kgdbts:RUN do_fork for 100 breakpoints
kgdb test using sysfs:
~ # echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
[33231.554237] kgdb: Registered I/O driver kgdbts.
[33231.554677] kgdbts:RUN plant and detach test
[33231.557072] kgdbts:RUN sw breakpoint test
[33231.576980] kgdbts:RUN bad memory access test
[33231.580022] kgdbts:RUN singlestep test 1000 iterations
[33231.627056] kgdbts:RUN singlestep [0/1000]
[33235.954027] kgdbts:RUN singlestep [100/1000]
[33240.429086] kgdbts:RUN singlestep [200/1000]
[33244.687118] kgdbts:RUN singlestep [300/1000]
[33248.945191] kgdbts:RUN singlestep [400/1000]
[33253.203751] kgdbts:RUN singlestep [500/1000]
[33257.462019] kgdbts:RUN singlestep [600/1000]
[33261.817809] kgdbts:RUN singlestep [700/1000]
[33266.081268] kgdbts:RUN singlestep [800/1000]
[33270.339813] kgdbts:RUN singlestep [900/1000]
[33274.712404] kgdbts:RUN do_fork for 1000 breakpoints
~ #
This works for me. Should I patch it or will you send a patch for this?
PS: cc to mailing list missed
>
> Will
^ permalink raw reply related
* [PATCH] pinctrl: Rename Broadcom Capri pinctrl driver
From: Olof Johansson @ 2014-01-22 4:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140122013512.GT31176@beef>
On Tue, Jan 21, 2014 at 5:35 PM, Matt Porter <mporter@linaro.org> wrote:
> On Tue, Jan 21, 2014 at 04:59:35PM -0800, Olof Johansson wrote:
>> Hi,
>>
>>
>> On Tue, Jan 21, 2014 at 2:38 PM, Sherman Yin <syin@broadcom.com> wrote:
>> > To be consistent with other Broadcom drivers, the Broadcom Capri pinctrl
>> > driver and its related CONFIG option are renamed to bcm281xx.
>> >
>> > Devicetree compatible string and binding documentation use
>> > "brcm,bcm11351-pinctrl" to match the machine binding here:
>> > Documentation/devicetree/bindings/arm/bcm/bcm11351.txt
>> >
>> > This driver supports pinctrl on BCM11130, BCM11140, BCM11351, BCM28145
>> > and BCM28155 SoCs.
>> >
>> > Signed-off-by: Sherman Yin <syin@broadcom.com>
>> > Reviewed-by: Matt Porter <mporter@linaro.org>
>> > ---
>> > ...capri-pinctrl.txt => brcm,bcm11351-pinctrl.txt} | 8 +-
>> > arch/arm/boot/dts/bcm11351.dtsi | 2 +-
>> > arch/arm/configs/bcm_defconfig | 2 +-
>> > drivers/pinctrl/Kconfig | 8 +-
>> > drivers/pinctrl/Makefile | 2 +-
>> > .../{pinctrl-capri.c => pinctrl-bcm281xx.c} | 1521 ++++++++++----------
>> > 6 files changed, 775 insertions(+), 768 deletions(-)
>> > rename Documentation/devicetree/bindings/pinctrl/{brcm,capri-pinctrl.txt => brcm,bcm11351-pinctrl.txt} (98%)
>> > rename drivers/pinctrl/{pinctrl-capri.c => pinctrl-bcm281xx.c} (25%)
>> >
>> > diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
>> > similarity index 98%
>> > rename from Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt
>> > rename to Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
>> > index 9e9e9ef..c119deb 100644
>> > --- a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt
>> > +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
>> > @@ -1,4 +1,4 @@
>> > -Broadcom Capri Pin Controller
>> > +Broadcom BCM281xx Pin Controller
>> >
>> > This is a pin controller for the Broadcom BCM281xx SoC family, which includes
>> > BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs.
>> > @@ -7,14 +7,14 @@ BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs.
>> >
>> > Required Properties:
>> >
>> > -- compatible: Must be "brcm,capri-pinctrl".
>> > +- compatible: Must be "brcm,bcm11351-pinctrl"
>>
>> Since the original binding is queued for 3.14 (I believe?), if this
>> rename isn't merged for 3.14 then you will still need to accept the
>> old compatible string (binding). You can document it as deprecated,
>> but the driver needs to still probe with it.
>
> Linus had mentioned that he could take a rename in 3.14-rc for this
> driver which is really what we had in mind here. Since the binding
> doesn't become stable until 3.14 is actually released I was under the
> impression that this is ok without keeping a deprecated compatible
> string. I notice that Tomasz had comments about this type of situation
> in http://www.spinics.net/lists/devicetree/msg18010.html
Yes, if the rename goes in before the binding has been in one stable
release then we can make noncompatible changes. Which is why I said if
this isn't merged for 3.14, etc.
-Olof
^ permalink raw reply
* [PATCH] clk: export __clk_get_hw for re-use in others
From: Greg KH @ 2014-01-22 4:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAEjAshozB4S0ZGqEn41ROfZwGTV+_GZRRTZ8cssi0VdH8Uhr_w@mail.gmail.com>
On Wed, Jan 22, 2014 at 12:05:57PM +0900, SeongJae Park wrote:
> Dear Greg, Mike,
>
> May I ask your answer or other opinion, please?
It's the middle of the merge window, it's not time for new development,
or much time for free-time for me, sorry. Feel free to fix it the best
way you know how.
greg k-h
^ permalink raw reply
* [PATCH] clk: export __clk_get_hw for re-use in others
From: SeongJae Park @ 2014-01-22 5:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140122045937.GB23869@kroah.com>
On Wed, Jan 22, 2014 at 1:59 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Wed, Jan 22, 2014 at 12:05:57PM +0900, SeongJae Park wrote:
>> Dear Greg, Mike,
>>
>> May I ask your answer or other opinion, please?
>
> It's the middle of the merge window, it's not time for new development,
> or much time for free-time for me, sorry. Feel free to fix it the best
> way you know how.
Oops, I've forgot about the merge window. Thank you very much for your
kind answer.
Sorry if I bothered you while you're in busy time.
Because the build problem is not a big deal because it exists only in
-next tree,
I will wait until merge window be closed and then fix it again if it
still exist.
SeongJae Park.
>
> greg k-h
^ permalink raw reply
* mutual exculsion between clk_prepare_enable /clk_disable_unprepare and clk_set_parent
From: Xiaoguang Chen @ 2014-01-22 6:02 UTC (permalink / raw)
To: linux-arm-kernel
Hi, Mike
We met a issue between clk_prepare_enable /clk_disable_unprepare and
clk_set_parent.
As we know, clk preprare/unprare will grab preprare lock, and clk
enable/disable will grab enable lock. clk_set_parent will grab prepare
lock
but there is no lock protection in clk_prepare_enable /clk_disable_unprepare,
for example, in clk_disable_unprepare, it is expended as clk_disable +
clk_unprepare,
and if below condition occurs, there will be problem
thread1 thread 2
call clk_disable_unprepare
1) clk_disable
get enable lock
...............
release enable lock
call clk_set_parent
get prepare lock
set clock's
parent to another parent
release prepare lock
2) clk_unprepare
get prepare lock
unprepare parent clock <<--------------
release prepare lock
In above sequence, After thread 1 call clock disable, thread 2 change
clk's parent to another clock, then in thread1 step2, it will
unprepare clk's new parent, but not old parent, this will cause old
parent is not unprepared, but new parent is unprepared even when it is
not prepared yet.
So How can we use this API: clk_prepare_enable and clk_disable_unprepare ?
Should we add lock to protect this API, if we get a prepare lock
inside this API, like
clk_disable_unprepare ()
{
get_prepare_lock();
clk_disable();
clk_unprepare();
clk_prepare_unlock();
}
is above sequence ok? if so, I can provide a patch for this.
Thanks
Xiaoguang
^ permalink raw reply
* [PATCH v4 2/2] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
From: Vivek Gautam @ 2014-01-22 6:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52DE7D75.4040302@ti.com>
Hi,
On Tue, Jan 21, 2014 at 7:30 PM, Roger Quadros <rogerq@ti.com> wrote:
> Hi Kishon,
>
> On 01/21/2014 12:11 PM, Kishon Vijay Abraham I wrote:
>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>> phy_power_on() and phy_power_off().
>>
>> However using the old USB phy library wont be removed till the PHYs of all
>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v3:
>> * avoided using quirks
>>
>> Documentation/devicetree/bindings/usb/dwc3.txt | 6 ++-
>> drivers/usb/dwc3/core.c | 60 ++++++++++++++++++++++++
>> drivers/usb/dwc3/core.h | 7 +++
>> 3 files changed, 71 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>> index e807635..471366d 100644
>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>> @@ -6,11 +6,13 @@ Required properties:
>> - compatible: must be "snps,dwc3"
>> - reg : Address and length of the register set for the device
>> - interrupts: Interrupts used by the dwc3 controller.
>> +
>> +Optional properties:
>> - usb-phy : array of phandle for the PHY device. The first element
>> in the array is expected to be a handle to the USB2/HS PHY and
>> the second element is expected to be a handle to the USB3/SS PHY
>> -
>> -Optional properties:
>> + - phys: from the *Generic PHY* bindings
>> + - phy-names: from the *Generic PHY* bindings
>> - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>
>> This is usually a subnode to DWC3 glue to which it is connected.
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index e009d4e..036d589 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -82,6 +82,11 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>
>> usb_phy_init(dwc->usb2_phy);
>> usb_phy_init(dwc->usb3_phy);
>> + if (dwc->usb2_generic_phy)
>> + phy_init(dwc->usb2_generic_phy);
>
> What if phy_init() fails? You need to report and fail. Same applies for all PHY apis in this patch.
>
>> + if (dwc->usb3_generic_phy)
>> + phy_init(dwc->usb3_generic_phy);
>> +
>> mdelay(100);
>>
>> /* Clear USB3 PHY reset */
>> @@ -343,6 +348,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>> {
>> usb_phy_shutdown(dwc->usb2_phy);
>> usb_phy_shutdown(dwc->usb3_phy);
>> + if (dwc->usb2_generic_phy)
>> + phy_exit(dwc->usb2_generic_phy);
>> + if (dwc->usb3_generic_phy)
>> + phy_exit(dwc->usb3_generic_phy);
>> +
>> }
>>
>> #define DWC3_ALIGN_MASK (16 - 1)
>> @@ -433,6 +443,32 @@ static int dwc3_probe(struct platform_device *pdev)
>> }
>> }
>>
>> + dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>> + if (IS_ERR(dwc->usb2_generic_phy)) {
>> + ret = PTR_ERR(dwc->usb2_generic_phy);
>> + if (ret == -ENOSYS || ret == -ENODEV) {
>> + dwc->usb2_generic_phy = NULL;
>> + } else if (ret == -EPROBE_DEFER) {
>> + return ret;
>> + } else {
>> + dev_err(dev, "no usb2 phy configured\n");
>> + return ret;
>> + }
>> + }
>> +
>> + dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>> + if (IS_ERR(dwc->usb3_generic_phy)) {
>> + ret = PTR_ERR(dwc->usb3_generic_phy);
>> + if (ret == -ENOSYS || ret == -ENODEV) {
>> + dwc->usb3_generic_phy = NULL;
>> + } else if (ret == -EPROBE_DEFER) {
>> + return ret;
>> + } else {
>> + dev_err(dev, "no usb3 phy configured\n");
>> + return ret;
>> + }
>> + }
>> +
>> dwc->xhci_resources[0].start = res->start;
>> dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
>> DWC3_XHCI_REGS_END;
>> @@ -482,6 +518,11 @@ static int dwc3_probe(struct platform_device *pdev)
>> usb_phy_set_suspend(dwc->usb2_phy, 0);
>> usb_phy_set_suspend(dwc->usb3_phy, 0);
>>
>> + if (dwc->usb2_generic_phy)
>> + phy_power_on(dwc->usb2_generic_phy);
>> + if (dwc->usb3_generic_phy)
>> + phy_power_on(dwc->usb3_generic_phy);
>> +
>
> Is it OK to power on the phy before phy_init()?
Isn't phy_init() being done before phy_power_on() in the
core_soft_reset() in this patch ?
Isn't that what you want here ?
>
> I suggest to move phy_init() from core_soft_reset() to here, just before phy_power_on().
core_soft_reset() is called before phy_power_on() itself from
dwc3_core_init(), right ?
will moving the phy_inti() here make nay difference ?
>
>> ret = dwc3_event_buffers_setup(dwc);
>> if (ret) {
>> dev_err(dwc->dev, "failed to setup event buffers\n");
[...]
snip
--
Best Regards
Vivek Gautam
Samsung R&D Institute, Bangalore
India
^ permalink raw reply
* [PATCH REPOST 1/5] ARM: kvm: replace push and pop with stdmb and ldmia instrs to enable assembler.h inclusion
From: Victor Kamensky @ 2014-01-22 6:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52DE44C4.20503@arm.com>
Russell, Dave, Will, could you please check below
inline, looking for your opinion.
Marc, response is inline.
On 21 January 2014 01:58, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On 21/01/14 01:18, Christoffer Dall wrote:
>> On Fri, Dec 20, 2013 at 08:48:41AM -0800, Victor Kamensky wrote:
>>> Before fix kvm interrupt.S and interrupt_head.S used push and pop assembler
>>> instruction. It causes problem if <asm/assembler.h> file should be include. In
>>> assembler.h "push" is defined as macro so it causes compilation errors like
>>> this:
>>
>> "Before fix kvm..." doesn't read very pleasently, consider using
>> something like "Prior to this commit...."
>>
>> "causes a problem" or "causes problems"
>>
>> change "if <asm/assembler.h> file should be include..." to "if
>> <asm/assembler.h> is included, because assember.h defines 'push' as a
>> macro..."
>>
>>
>>
>>>
>>> arch/arm/kvm/interrupts.S: Assembler messages:
>>> arch/arm/kvm/interrupts.S:51: Error: ARM register expected -- `lsr {r2,r3}'
>>>
>>> Solution implemented by this patch replaces all 'push {...}' with
>>> 'stdmb sp!, {...}' instruction; and all 'pop {...}' with 'ldmia sp!, {...}'.
>>>
>>> Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
>>> ---
>>> arch/arm/kvm/interrupts.S | 38 +++++++++++++++++++-------------------
>>> arch/arm/kvm/interrupts_head.S | 34 +++++++++++++++++-----------------
>>> 2 files changed, 36 insertions(+), 36 deletions(-)
>>>
>>> diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
>>> index ddc1553..df19133 100644
>>> --- a/arch/arm/kvm/interrupts.S
>>> +++ b/arch/arm/kvm/interrupts.S
>>> @@ -47,7 +47,7 @@ __kvm_hyp_code_start:
>>> * instead, ignoring the ipa value.
>>> */
>>> ENTRY(__kvm_tlb_flush_vmid_ipa)
>>> - push {r2, r3}
>>> + stmdb sp!, {r2, r3}
>>>
>>> dsb ishst
>>> add r0, r0, #KVM_VTTBR
>>> @@ -62,7 +62,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa)
>>> mcrr p15, 6, r2, r3, c2 @ Back to VMID #0
>>> isb @ Not necessary if followed by eret
>>>
>>> - pop {r2, r3}
>>> + ldmia sp!, {r2, r3}
>>> bx lr
>>> ENDPROC(__kvm_tlb_flush_vmid_ipa)
>>>
>>> @@ -110,7 +110,7 @@ ENTRY(__kvm_vcpu_run)
>>> #ifdef CONFIG_VFPv3
>>> @ Set FPEXC_EN so the guest doesn't trap floating point instructions
>>> VFPFMRX r2, FPEXC @ VMRS
>>> - push {r2}
>>> + stmdb sp!, {r2}
>>> orr r2, r2, #FPEXC_EN
>>> VFPFMXR FPEXC, r2 @ VMSR
>>> #endif
>>> @@ -175,7 +175,7 @@ __kvm_vcpu_return:
>>>
>>> after_vfp_restore:
>>> @ Restore FPEXC_EN which we clobbered on entry
>>> - pop {r2}
>>> + ldmia sp!, {r2}
>>> VFPFMXR FPEXC, r2
>>> #endif
>>>
>>> @@ -260,7 +260,7 @@ ENTRY(kvm_call_hyp)
>>>
>>> /* Handle undef, svc, pabt, or dabt by crashing with a user notice */
>>> .macro bad_exception exception_code, panic_str
>>> - push {r0-r2}
>>> + stmdb sp!, {r0-r2}
>>> mrrc p15, 6, r0, r1, c2 @ Read VTTBR
>>> lsr r1, r1, #16
>>> ands r1, r1, #0xff
>>> @@ -338,7 +338,7 @@ hyp_hvc:
>>> * Getting here is either becuase of a trap from a guest or from calling
>>> * HVC from the host kernel, which means "switch to Hyp mode".
>>> */
>>> - push {r0, r1, r2}
>>> + stmdb sp!, {r0, r1, r2}
>>>
>>> @ Check syndrome register
>>> mrc p15, 4, r1, c5, c2, 0 @ HSR
>>> @@ -361,11 +361,11 @@ hyp_hvc:
>>> bne guest_trap @ Guest called HVC
>>>
>>> host_switch_to_hyp:
>>> - pop {r0, r1, r2}
>>> + ldmia sp!, {r0, r1, r2}
>>>
>>> - push {lr}
>>> + stmdb sp!, {lr}
>>> mrs lr, SPSR
>>> - push {lr}
>>> + stmdb sp!, {lr}
>>>
>>> mov lr, r0
>>> mov r0, r1
>>> @@ -375,9 +375,9 @@ host_switch_to_hyp:
>>> THUMB( orr lr, #1)
>>> blx lr @ Call the HYP function
>>>
>>> - pop {lr}
>>> + ldmia sp!, {lr}
>>> msr SPSR_csxf, lr
>>> - pop {lr}
>>> + ldmia sp!, {lr}
>>> eret
>>>
>>> guest_trap:
>>> @@ -418,7 +418,7 @@ guest_trap:
>>>
>>> /* Preserve PAR */
>>> mrrc p15, 0, r0, r1, c7 @ PAR
>>> - push {r0, r1}
>>> + stmdb sp!, {r0, r1}
>>>
>>> /* Resolve IPA using the xFAR */
>>> mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR
>>> @@ -431,7 +431,7 @@ guest_trap:
>>> orr r2, r2, r1, lsl #24
>>>
>>> /* Restore PAR */
>>> - pop {r0, r1}
>>> + ldmia sp!, {r0, r1}
>>> mcrr p15, 0, r0, r1, c7 @ PAR
>>>
>>> 3: load_vcpu @ Load VCPU pointer to r0
>>> @@ -440,10 +440,10 @@ guest_trap:
>>> 1: mov r1, #ARM_EXCEPTION_HVC
>>> b __kvm_vcpu_return
>>>
>>> -4: pop {r0, r1} @ Failed translation, return to guest
>>> +4: ldmia sp!, {r0, r1} @ Failed translation, return to guest
>>> mcrr p15, 0, r0, r1, c7 @ PAR
>>> clrex
>>> - pop {r0, r1, r2}
>>> + ldmia sp!, {r0, r1, r2}
>>> eret
>>>
>>> /*
>>> @@ -455,7 +455,7 @@ guest_trap:
>>> #ifdef CONFIG_VFPv3
>>> switch_to_guest_vfp:
>>> load_vcpu @ Load VCPU pointer to r0
>>> - push {r3-r7}
>>> + stmdb sp!, {r3-r7}
>>>
>>> @ NEON/VFP used. Turn on VFP access.
>>> set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11))
>>> @@ -467,15 +467,15 @@ switch_to_guest_vfp:
>>> add r7, r0, #VCPU_VFP_GUEST
>>> restore_vfp_state r7
>>>
>>> - pop {r3-r7}
>>> - pop {r0-r2}
>>> + ldmia sp!, {r3-r7}
>>> + ldmia sp!, {r0-r2}
>>> clrex
>>> eret
>>> #endif
>>>
>>> .align
>>> hyp_irq:
>>> - push {r0, r1, r2}
>>> + stmdb sp!, {r0, r1, r2}
>>> mov r1, #ARM_EXCEPTION_IRQ
>>> load_vcpu @ Load VCPU pointer to r0
>>> b __kvm_vcpu_return
>>> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
>>> index 6f18695..c371db7 100644
>>> --- a/arch/arm/kvm/interrupts_head.S
>>> +++ b/arch/arm/kvm/interrupts_head.S
>>> @@ -63,7 +63,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrs r2, SP_\mode
>>> mrs r3, LR_\mode
>>> mrs r4, SPSR_\mode
>>> - push {r2, r3, r4}
>>> + stmdb sp!, {r2, r3, r4}
>>> .endm
>>>
>>> /*
>>> @@ -73,13 +73,13 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> .macro save_host_regs
>>> /* Hyp regs. Only ELR_hyp (SPSR_hyp already saved) */
>>> mrs r2, ELR_hyp
>>> - push {r2}
>>> + stmdb sp!, {r2}
>>>
>>> /* usr regs */
>>> - push {r4-r12} @ r0-r3 are always clobbered
>>> + stmdb sp!, {r4-r12} @ r0-r3 are always clobbered
>>> mrs r2, SP_usr
>>> mov r3, lr
>>> - push {r2, r3}
>>> + stmdb sp!, {r2, r3}
>>>
>>> push_host_regs_mode svc
>>> push_host_regs_mode abt
>>> @@ -95,11 +95,11 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrs r7, SP_fiq
>>> mrs r8, LR_fiq
>>> mrs r9, SPSR_fiq
>>> - push {r2-r9}
>>> + stmdb sp!, {r2-r9}
>>> .endm
>>>
>>> .macro pop_host_regs_mode mode
>>> - pop {r2, r3, r4}
>>> + ldmia sp!, {r2, r3, r4}
>>> msr SP_\mode, r2
>>> msr LR_\mode, r3
>>> msr SPSR_\mode, r4
>>> @@ -110,7 +110,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> * Clobbers all registers, in all modes, except r0 and r1.
>>> */
>>> .macro restore_host_regs
>>> - pop {r2-r9}
>>> + ldmia sp!, {r2-r9}
>>> msr r8_fiq, r2
>>> msr r9_fiq, r3
>>> msr r10_fiq, r4
>>> @@ -125,12 +125,12 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> pop_host_regs_mode abt
>>> pop_host_regs_mode svc
>>>
>>> - pop {r2, r3}
>>> + ldmia sp!, {r2, r3}
>>> msr SP_usr, r2
>>> mov lr, r3
>>> - pop {r4-r12}
>>> + ldmia sp!, {r4-r12}
>>>
>>> - pop {r2}
>>> + ldmia sp!, {r2}
>>> msr ELR_hyp, r2
>>> .endm
>>>
>>> @@ -218,7 +218,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> add r2, vcpu, #VCPU_USR_REG(3)
>>> stm r2, {r3-r12}
>>> add r2, vcpu, #VCPU_USR_REG(0)
>>> - pop {r3, r4, r5} @ r0, r1, r2
>>> + ldmia sp!, {r3, r4, r5} @ r0, r1, r2
>>> stm r2, {r3, r4, r5}
>>> mrs r2, SP_usr
>>> mov r3, lr
>>> @@ -258,7 +258,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrc p15, 2, r12, c0, c0, 0 @ CSSELR
>>>
>>> .if \store_to_vcpu == 0
>>> - push {r2-r12} @ Push CP15 registers
>>> + stmdb sp!, {r2-r12} @ Push CP15 registers
>>> .else
>>> str r2, [vcpu, #CP15_OFFSET(c1_SCTLR)]
>>> str r3, [vcpu, #CP15_OFFSET(c1_CPACR)]
>>> @@ -286,7 +286,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrc p15, 0, r12, c12, c0, 0 @ VBAR
>>>
>>> .if \store_to_vcpu == 0
>>> - push {r2-r12} @ Push CP15 registers
>>> + stmdb sp!, {r2-r12} @ Push CP15 registers
>>> .else
>>> str r2, [vcpu, #CP15_OFFSET(c13_CID)]
>>> str r3, [vcpu, #CP15_OFFSET(c13_TID_URW)]
>>> @@ -305,7 +305,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mrrc p15, 0, r4, r5, c7 @ PAR
>>>
>>> .if \store_to_vcpu == 0
>>> - push {r2,r4-r5}
>>> + stmdb sp!, {r2,r4-r5}
>>> .else
>>> str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
>>> add r12, vcpu, #CP15_OFFSET(c7_PAR)
>>> @@ -322,7 +322,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> */
>>> .macro write_cp15_state read_from_vcpu
>>> .if \read_from_vcpu == 0
>>> - pop {r2,r4-r5}
>>> + ldmia sp!, {r2,r4-r5}
>>> .else
>>> ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
>>> add r12, vcpu, #CP15_OFFSET(c7_PAR)
>>> @@ -333,7 +333,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mcrr p15, 0, r4, r5, c7 @ PAR
>>>
>>> .if \read_from_vcpu == 0
>>> - pop {r2-r12}
>>> + ldmia sp!, {r2-r12}
>>> .else
>>> ldr r2, [vcpu, #CP15_OFFSET(c13_CID)]
>>> ldr r3, [vcpu, #CP15_OFFSET(c13_TID_URW)]
>>> @@ -361,7 +361,7 @@ vcpu .req r0 @ vcpu pointer always in r0
>>> mcr p15, 0, r12, c12, c0, 0 @ VBAR
>>>
>>> .if \read_from_vcpu == 0
>>> - pop {r2-r12}
>>> + ldmia sp!, {r2-r12}
>>> .else
>>> ldr r2, [vcpu, #CP15_OFFSET(c1_SCTLR)]
>>> ldr r3, [vcpu, #CP15_OFFSET(c1_CPACR)]
>>> --
>>> 1.8.1.4
>>>
>>
>> If you fix to address Dave's comments, then the code change otherwise
>> looks good.
>
> How about trying this alternative approach:
>
> It looks like all the users of the push/pop macros are located in
> arch/arm/lib (mostly checksumming code). Can't we move these macros to a
> separate include file and leave the code that uses push/pop (as defined
> by the assembler) alone?
Marc, personally I am OK with such proposal. I was considering something
along these lines as one of the options. It works for me both ways. If
others agree I am happy to recode it as your suggested. I choose
proposed above patch because kvm arm code came after push and pop
defines were introduced in asm/assembler.h and used in other places.
I am OK either way. I agree that use of push and pop as define names
seems a bit unfortunate, but I don't have any historic visibility here
Russell, Dave, Will, do you have any opinion on Marc's proposal to
fix this issue?
Thanks,
Victor
> Thanks,
>
> M.
> --
> Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH V2] ARM: imx: correct usecount of IPG, ARM and MMDC clk on i.mx6sl
From: Sascha Hauer @ 2014-01-22 6:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390301452-10143-1-git-send-email-b20788@freescale.com>
On Tue, Jan 21, 2014 at 06:50:52PM +0800, Anson Huang wrote:
> IPG, ARM and MMDC's clock should be enabled during kernel boot up,
> so we need to maintain their use count, otherwise, they may be
> disabled unexpectedly if their children's clock are turned off,
> which is not allowed.
>
> Signed-off-by: Anson Huang <b20788@freescale.com>
> ---
> arch/arm/mach-imx/clk-imx6sl.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
> index 78f3bd6..047f4ff 100644
> --- a/arch/arm/mach-imx/clk-imx6sl.c
> +++ b/arch/arm/mach-imx/clk-imx6sl.c
> @@ -291,6 +291,22 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
> pr_warn("%s: failed to set AHB clock rate %d!\n",
> __func__, ret);
>
> + /*
> + * Make sure those always on clocks are enabled to maintain the correct
> + * usecount and enabling/disabling of parent PLLs.
> + */
> + ret = clk_prepare_enable(clks[IMX6SL_CLK_IPG]);
> + if (ret)
> + pr_warn("%s: failed to enable IPG clock %d\n", __func__, ret);
> +
> + ret = clk_prepare_enable(clks[IMX6SL_CLK_ARM]);
> + if (ret)
> + pr_warn("%s: failed to enable ARM clock %d\n", __func__, ret);
> +
> + ret = clk_prepare_enable(clks[IMX6SL_CLK_MMDC_ROOT]);
> + if (ret)
> + pr_warn("%s: failed to enable MMDC clock %d\n", __func__, ret);
> +
Consider using a clk_init_on array like we have in clk-imx6q.c
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
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