* [PATCH] ARM: mvebu: fix compilation warning on Armada 370 (i.e. non-SMP)
From: Arnaud Ebalard @ 2014-01-20 20:14 UTC (permalink / raw)
To: linux-arm-kernel
The following appears during compilation for an Armada 370 target
because 'irq_controller_lock' is used only when CONFIG_SMP is enabled:
drivers/irqchip/irq-armada-370-xp.c:62:8: warning: 'irq_controller_lock' defined but not used [-Wunused-variable]
Fix that warning by protecting declaration via an #ifdef.
Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
---
drivers/irqchip/irq-armada-370-xp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 433cc8568dec..499c5070f841 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -59,7 +59,9 @@
#define PCI_MSI_DOORBELL_END (32)
#define PCI_MSI_DOORBELL_MASK 0xFFFF0000
+#ifdef CONFIG_SMP
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+#endif
static void __iomem *per_cpu_int_base;
static void __iomem *main_int_base;
--
1.8.5.2
^ permalink raw reply related
* [PATCH] ARM: mvebu: Fix kernel hang in mvebu_soc_id_init() when of_iomap failed
From: Jason Cooper @ 2014-01-20 20:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390229990-26450-1-git-send-email-gregory.clement@free-electrons.com>
On Mon, Jan 20, 2014 at 03:59:50PM +0100, Gregory CLEMENT wrote:
> When pci_base is accessed whereas it has not been properly mapped by
> of_iomap() the kernel hang. The check of this pointer made an improper
> use of IS_ERR() instead of comparing to NULL. This patch fix this
> issue.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> Reported-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> ---
> Jason,
>
> As this is a fix on a fix which should be ported to the stable branch, I
> don't know how to handle the cc:stable flag
No problem, I added it.
> arch/arm/mach-mvebu/mvebu-soc-id.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to mvebu/fixes.
thx,
Jason.
^ permalink raw reply
* [PATCH] ARM: mvebu: fix compilation warning on Armada 370 (i.e. non-SMP)
From: Arnd Bergmann @ 2014-01-20 20:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87r48276ne.fsf@natisbad.org>
On Monday 20 January 2014 21:14:13 Arnaud Ebalard wrote:
> diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
> index 433cc8568dec..499c5070f841 100644
> --- a/drivers/irqchip/irq-armada-370-xp.c
> +++ b/drivers/irqchip/irq-armada-370-xp.c
> @@ -59,7 +59,9 @@
> #define PCI_MSI_DOORBELL_END (32)
> #define PCI_MSI_DOORBELL_MASK 0xFFFF0000
>
> +#ifdef CONFIG_SMP
> static DEFINE_RAW_SPINLOCK(irq_controller_lock);
> +#endif
>
> static void __iomem *per_cpu_
How about moving it inside of the existing #ifdef?
That also brings it closer to the one place it's used.
Arnd
^ permalink raw reply
* [PATCH] ARM: dts: omap3-gta04: Add EOC irq gpio line handling.
From: Belisko Marek @ 2014-01-20 20:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1387638743-12278-1-git-send-email-marek@goldelico.com>
Ping? Benoit can you please merge this trivial update. Thanks.
On Sat, Dec 21, 2013 at 4:12 PM, Marek Belisko <marek@goldelico.com> wrote:
> BMP085 EOC (End Of Conversion) irq line is connected to
> gpio113 on gta04. Set irq properties to have driver using irq
> instead polling for EOC.
>
> Signed-off-by: Marek Belisko <marek@goldelico.com>
> ---
> arch/arm/boot/dts/omap3-gta04.dts | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts
> index b9b55c9..7a8e37d 100644
> --- a/arch/arm/boot/dts/omap3-gta04.dts
> +++ b/arch/arm/boot/dts/omap3-gta04.dts
> @@ -92,6 +92,8 @@
> bmp085 at 77 {
> compatible = "bosch,bmp085";
> reg = <0x77>;
> + interrupt-parent = <&gpio4>;
> + interrupts = <17 IRQ_TYPE_EDGE_RISING>;
> };
>
> /* leds */
> --
> 1.8.4.2
>
BR,
marek
--
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer
Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
twitter: #opennandra
web: http://open-nandra.com
^ permalink raw reply
* [PATCH 0/2] DT updates for Hummingboard and new Cubox-i
From: Olof Johansson @ 2014-01-20 20:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140120095532.GW15937@n2100.arm.linux.org.uk>
On Mon, Jan 20, 2014 at 1:55 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Sun, Jan 19, 2014 at 07:34:22PM -0800, Olof Johansson wrote:
>> I'm guessing this is going to mess up Shawn's cleanup patches, but
>> time has ran out for 3.14 for those so they will need to be respun
>> anyway, most likely.
>>
>> We can apply them to arm-soc's dt branch. I think it's better if we
>> merge them since dts files tend to be one of the conflict-ridden areas
>> (even if this particular instance isn't). Send the series our way if
>> you want, or send a branch pull request, your choice.
>
> There's no conflict, and they build fine according to my autobuilder
> which includes arm-soc for-next.
Great, I didn't see any patches sent from you though. Should I
cherry-pick them from -next instead?
-Olof
^ permalink raw reply
* [PATCH] ARM: dts: imx6qdl-sabreauto: Add PFUZE100 support
From: Fabio Estevam @ 2014-01-20 20:47 UTC (permalink / raw)
To: linux-arm-kernel
From: Fabio Estevam <fabio.estevam@freescale.com>
mx6 sabreauto boards have Freescale PFUZE100 regulator, so add support for it.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi | 110 +++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index 47c5a3f..e44ff49 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -63,6 +63,112 @@
status = "okay";
};
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100 at 08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3b_reg: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ };
+
+ snvs_reg: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vref_reg: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
@@ -90,6 +196,10 @@
fsl,pins = <MX6QDL_ENET_PINGRP2_GPIO6>;
};
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <MX6QDL_I2C2_PINGRP3>;
+ };
+
pinctrl_gpmi_nand: gpminandgrp {
fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1>;
};
--
1.8.1.2
^ permalink raw reply related
* [PATCH 1/5] ARM: integrator: define clocks in the device trees
From: Linus Walleij @ 2014-01-20 20:54 UTC (permalink / raw)
To: linux-arm-kernel
This adds the clock definitions to the Integrator/CP
and Integrator/AP device trees.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/integratorap.dts | 35 +++++++++++++
arch/arm/boot/dts/integratorcp.dts | 102 ++++++++++++++++++++++++++++++++++++-
2 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts
index e6be9315ff0a..b10e6351da53 100644
--- a/arch/arm/boot/dts/integratorap.dts
+++ b/arch/arm/boot/dts/integratorap.dts
@@ -18,6 +18,28 @@
bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";
};
+ /* 24 MHz chrystal on the core module */
+ xtal24mhz: xtal24mhz at 24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ pclk: pclk at 0 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The UART clock is 14.74 MHz divided by an ICS525 */
+ uartclk: uartclk at 14.74M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <14745600>;
+ };
+
syscon {
compatible = "arm,integrator-ap-syscon";
reg = <0x11000000 0x100>;
@@ -28,14 +50,17 @@
timer0: timer at 13000000 {
compatible = "arm,integrator-timer";
+ clocks = <&xtal24mhz>;
};
timer1: timer at 13000100 {
compatible = "arm,integrator-timer";
+ clocks = <&xtal24mhz>;
};
timer2: timer at 13000200 {
compatible = "arm,integrator-timer";
+ clocks = <&xtal24mhz>;
};
pic: pic at 14000000 {
@@ -92,26 +117,36 @@
rtc: rtc at 15000000 {
compatible = "arm,pl030", "arm,primecell";
arm,primecell-periphid = <0x00041030>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
uart0: uart at 16000000 {
compatible = "arm,pl010", "arm,primecell";
arm,primecell-periphid = <0x00041010>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
};
uart1: uart at 17000000 {
compatible = "arm,pl010", "arm,primecell";
arm,primecell-periphid = <0x00041010>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
};
kmi0: kmi at 18000000 {
compatible = "arm,pl050", "arm,primecell";
arm,primecell-periphid = <0x00041050>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
};
kmi1: kmi at 19000000 {
compatible = "arm,pl050", "arm,primecell";
arm,primecell-periphid = <0x00041050>;
+ clocks = <&xtal24mhz>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
};
};
};
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
index a21c17de9a5e..d43f15b4f79a 100644
--- a/arch/arm/boot/dts/integratorcp.dts
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -13,25 +13,107 @@
bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
};
+ /*
+ * The Integrator/CP overall clocking architecture can be found in
+ * ARM DUI 0184B page 7-28 "Integrator/CP922T system clocks" which
+ * appear to illustrate the layout used in most configurations.
+ */
+
+ /* The codec chrystal operates at 24.576 MHz */
+ xtal_codec: xtal24.576 at 24.576M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24576000>;
+ };
+
+ /* The chrystal is divided by 2 by the codec for the AACI bit clock */
+ aaci_bitclk: aaci_bitclk at 12.288M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&xtal_codec>;
+ };
+
+ /* This is a 25MHz chrystal on the base board */
+ xtal25mhz: xtal25mhz at 25M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ /* The UART clock is 14.74 MHz divided from 25MHz by an ICS525 */
+ uartclk: uartclk at 14.74M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <14745600>;
+ };
+
+ /* Actually sysclk I think */
+ pclk: pclk at 0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ core-module at 10000000 {
+ /* 24 MHz chrystal on the core module */
+ xtal24mhz: xtal24mhz at 24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ /*
+ * External oscillator on the core module, usually used
+ * to drive video circuitry. Driven from the 24MHz clock.
+ */
+ auxosc: cm_aux_osc at 25M {
+ #clock-cells = <0>;
+ compatible = "arm,integrator-cm-auxosc";
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The KMI clock is the 24 MHz oscillator divided to 8MHz */
+ kmiclk: kmiclk at 1M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <3>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+
+ /* The timer clock is the 24 MHz oscillator divided to 1MHz */
+ timclk: timclk at 1M {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <24>;
+ clock-mult = <1>;
+ clocks = <&xtal24mhz>;
+ };
+ };
+
syscon {
compatible = "arm,integrator-cp-syscon";
reg = <0xcb000000 0x100>;
};
timer0: timer at 13000000 {
- /* TIMER0 runs @ 25MHz */
+ /* TIMER0 runs directly on the 25MHz chrystal */
compatible = "arm,integrator-cp-timer";
- status = "disabled";
+ clocks = <&xtal25mhz>;
};
timer1: timer at 13000100 {
/* TIMER1 runs @ 1MHz */
compatible = "arm,integrator-cp-timer";
+ clocks = <&timclk>;
};
timer2: timer at 13000200 {
/* TIMER2 runs @ 1MHz */
compatible = "arm,integrator-cp-timer";
+ clocks = <&timclk>;
};
pic: pic at 14000000 {
@@ -74,22 +156,32 @@
*/
rtc at 15000000 {
compatible = "arm,pl031", "arm,primecell";
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
uart at 16000000 {
compatible = "arm,pl011", "arm,primecell";
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
};
uart at 17000000 {
compatible = "arm,pl011", "arm,primecell";
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
};
kmi at 18000000 {
compatible = "arm,pl050", "arm,primecell";
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
};
kmi at 19000000 {
compatible = "arm,pl050", "arm,primecell";
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
};
/*
@@ -100,18 +192,24 @@
reg = <0x1c000000 0x1000>;
interrupts = <23 24>;
max-frequency = <515633>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "mclk", "apb_pclk";
};
aaci at 1d000000 {
compatible = "arm,pl041", "arm,primecell";
reg = <0x1d000000 0x1000>;
interrupts = <25>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
clcd at c0000000 {
compatible = "arm,pl110", "arm,primecell";
reg = <0xC0000000 0x1000>;
interrupts = <22>;
+ clocks = <&auxosc>, <&pclk>;
+ clock-names = "clcd", "apb_pclk";
};
};
};
--
1.8.4.2
^ permalink raw reply related
* [PATCH 2/5] ARM: SP804: make Integrator/CP timer pick clock from DT
From: Linus Walleij @ 2014-01-20 20:55 UTC (permalink / raw)
To: linux-arm-kernel
This modifies the SP804 driver so that the clock will be taken
from the device tree node for the timer.
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Rob Herring <rob.herring@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/common/timer-sp.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index ce922d0ea7aa..a0648d296055 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -271,10 +271,14 @@ static void __init integrator_cp_of_init(struct device_node *np)
void __iomem *base;
int irq;
const char *name = of_get_property(np, "compatible", NULL);
+ struct clk *clk;
base = of_iomap(np, 0);
if (WARN_ON(!base))
return;
+ clk = of_clk_get(np, 0);
+ if (WARN_ON(IS_ERR(clk)))
+ return;
/* Ensure timer is disabled */
writel(0, base + TIMER_CTRL);
@@ -283,13 +287,13 @@ static void __init integrator_cp_of_init(struct device_node *np)
goto err;
if (!init_count)
- sp804_clocksource_init(base, name);
+ __sp804_clocksource_and_sched_clock_init(base, name, clk, 0);
else {
irq = irq_of_parse_and_map(np, 0);
if (irq <= 0)
goto err;
- sp804_clockevents_init(base, irq, name);
+ __sp804_clockevents_init(base, irq, clk, name);
}
init_count++;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 3/5] ARM: integrator: switch to fetch clocks from device tree
From: Linus Walleij @ 2014-01-20 20:55 UTC (permalink / raw)
To: linux-arm-kernel
This atomic commit changes the Integrator clock implementation
and the machines to register clocks from the device tree and
use these instead of the previous hard-coded clocks.
In the clock implementation all hard-coded clocks and the
special initialization function call goes away, and is
replaced by two compatible strings for the two clocks
available on the core module.
Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Hi Mike, looking for an ACK to reform this clock handling.
---
.../devicetree/bindings/clock/arm-integrator.txt | 34 +++++++++
arch/arm/mach-integrator/integrator_ap.c | 19 +++--
arch/arm/mach-integrator/integrator_cp.c | 6 --
drivers/clk/versatile/clk-integrator.c | 80 +++++++++-------------
include/linux/platform_data/clk-integrator.h | 1 -
5 files changed, 80 insertions(+), 60 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/arm-integrator.txt
diff --git a/Documentation/devicetree/bindings/clock/arm-integrator.txt b/Documentation/devicetree/bindings/clock/arm-integrator.txt
new file mode 100644
index 000000000000..652914b17b95
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/arm-integrator.txt
@@ -0,0 +1,34 @@
+Clock bindings for ARM Integrator Core Module clocks
+
+Auxilary Oscillator Clock
+
+This is a configurable clock fed from a 24 MHz chrystal,
+used for generating e.g. video clocks. It is located on the
+core module and there is only one of these.
+
+This clock node *must* be a subnode of the core module, since
+it obtains the base address for it's address range from its
+parent node.
+
+
+Required properties:
+- compatible: must be "arm,integrator-cm-auxosc"
+- #clock-cells: must be <0>
+
+Optional properties:
+- clocks: parent clock(s)
+
+Example:
+
+core-module at 10000000 {
+ xtal24mhz: xtal24mhz at 24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ auxosc: cm_aux_osc at 25M {
+ #clock-cells = <0>;
+ compatible = "arm,integrator-cm-auxosc";
+ clocks = <&xtal24mhz>;
+ };
+};
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index d50dc2dbfd89..1b80a83fe58d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -42,6 +42,7 @@
#include <linux/sys_soc.h>
#include <linux/termios.h>
#include <linux/sched_clock.h>
+#include <linux/clk-provider.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@@ -412,10 +413,7 @@ static void __init ap_of_timer_init(void)
struct clk *clk;
unsigned long rate;
- clk = clk_get_sys("ap_timer", NULL);
- BUG_ON(IS_ERR(clk));
- clk_prepare_enable(clk);
- rate = clk_get_rate(clk);
+ of_clk_init(NULL);
err = of_property_read_string(of_aliases,
"arm,timer-primary", &path);
@@ -425,6 +423,12 @@ static void __init ap_of_timer_init(void)
base = of_iomap(node, 0);
if (WARN_ON(!base))
return;
+
+ clk = of_clk_get(node, 0);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
writel(0, base + TIMER_CTRL);
integrator_clocksource_init(rate, base);
@@ -437,6 +441,12 @@ static void __init ap_of_timer_init(void)
if (WARN_ON(!base))
return;
irq = irq_of_parse_and_map(node, 0);
+
+ clk = of_clk_get(node, 0);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
writel(0, base + TIMER_CTRL);
integrator_clockevent_init(rate, base, irq);
}
@@ -450,7 +460,6 @@ static void __init ap_init_irq_of(void)
{
cm_init();
of_irq_init(fpga_irq_of_match);
- integrator_clk_init(false);
}
/* For the Device Tree, add in the UART callbacks as AUXDATA */
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 4fc0a195de01..cf02c91f7c8c 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -23,7 +23,6 @@
#include <linux/irqchip/versatile-fpga.h>
#include <linux/gfp.h>
#include <linux/mtd/physmap.h>
-#include <linux/platform_data/clk-integrator.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -33,8 +32,6 @@
#include <mach/platform.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst.h>
#include <mach/lm.h>
@@ -43,8 +40,6 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <asm/hardware/timer-sp.h>
-
#include <plat/clcd.h>
#include <plat/sched_clock.h>
@@ -258,7 +253,6 @@ static void __init intcp_init_irq_of(void)
{
cm_init();
of_irq_init(fpga_irq_of_match);
- integrator_clk_init(true);
}
/*
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index bda8967e09c2..19864b5690e9 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -10,20 +10,17 @@
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/err.h>
-#include <linux/platform_data/clk-integrator.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include "clk-icst.h"
-/*
- * Implementation of the ARM Integrator/AP and Integrator/CP clock tree.
- * Inspired by portions of:
- * plat-versatile/clock.c and plat-versatile/include/plat/clock.h
- */
+#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
-static const struct icst_params cp_auxvco_params = {
+/* Base offset for the core module */
+static void __iomem *cm_base;
+
+static const struct icst_params cp_auxosc_params = {
.ref = 24000000,
.vco_max = ICST525_VCO_MAX_5V,
.vco_min = ICST525_VCO_MIN,
@@ -35,50 +32,37 @@ static const struct icst_params cp_auxvco_params = {
.idx2s = icst525_idx2s,
};
-static const struct clk_icst_desc __initdata cp_icst_desc = {
- .params = &cp_auxvco_params,
+static const struct clk_icst_desc __initdata cm_auxosc_desc = {
+ .params = &cp_auxosc_params,
.vco_offset = 0x1c,
.lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
};
-/*
- * integrator_clk_init() - set up the integrator clock tree
- * @is_cp: pass true if it's the Integrator/CP else AP is assumed
- */
-void __init integrator_clk_init(bool is_cp)
+static void __init of_integrator_cm_osc_setup(struct device_node *np)
{
- struct clk *clk;
-
- /* APB clock dummy */
- clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
- clk_register_clkdev(clk, "apb_pclk", NULL);
-
- /* UART reference clock */
- clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT,
- 14745600);
- clk_register_clkdev(clk, NULL, "uart0");
- clk_register_clkdev(clk, NULL, "uart1");
- if (is_cp)
- clk_register_clkdev(clk, NULL, "mmci");
-
- /* 24 MHz clock */
- clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT,
- 24000000);
- clk_register_clkdev(clk, NULL, "kmi0");
- clk_register_clkdev(clk, NULL, "kmi1");
- if (!is_cp)
- clk_register_clkdev(clk, NULL, "ap_timer");
+ struct clk *clk = ERR_PTR(-EINVAL);
+ const char *clk_name = np->name;
+ const struct clk_icst_desc *desc = &cm_auxosc_desc;
- if (!is_cp)
- return;
+ if (!cm_base) {
+ /* Remap the core module base if not done yet */
+ struct device_node *parent;
- /* 1 MHz clock */
- clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT,
- 1000000);
- clk_register_clkdev(clk, NULL, "sp804");
+ parent = of_get_parent(np);
+ if (!np) {
+ pr_err("no parent on core module clock\n");
+ return;
+ }
+ cm_base = of_iomap(parent, 0);
+ if (!cm_base) {
+ pr_err("could not remap core module base\n");
+ return;
+ }
+ }
- /* ICST VCO clock used on the Integrator/CP CLCD */
- clk = icst_clk_register(NULL, &cp_icst_desc, "icst",
- __io_address(INTEGRATOR_HDR_BASE));
- clk_register_clkdev(clk, NULL, "clcd");
+ clk = icst_clk_register(NULL, desc, clk_name, cm_base);
+ if (!IS_ERR(clk))
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
+CLK_OF_DECLARE(integrator_cm_auxosc_clk,
+ "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);
diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h
index 280edac9d0a5..addd48cac625 100644
--- a/include/linux/platform_data/clk-integrator.h
+++ b/include/linux/platform_data/clk-integrator.h
@@ -1,3 +1,2 @@
-void integrator_clk_init(bool is_cp);
void integrator_impd1_clk_init(void __iomem *base, unsigned int id);
void integrator_impd1_clk_exit(unsigned int id);
--
1.8.4.2
^ permalink raw reply related
* [PATCH 4/5] clk: versatile: pass a parent to the ICST clock
From: Linus Walleij @ 2014-01-20 20:55 UTC (permalink / raw)
To: linux-arm-kernel
As we want to actually define the parent frequency in the device
tree for the ICST clocks, modify the clock registration function
to take a parent argument.
Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Hi Mike, looking for an ACK to take this through the Integrator
and ARM SOC tree.
---
drivers/clk/versatile/clk-icst.c | 1 +
drivers/clk/versatile/clk-icst.h | 1 +
drivers/clk/versatile/clk-impd1.c | 6 ++++--
drivers/clk/versatile/clk-integrator.c | 4 +++-
drivers/clk/versatile/clk-realview.c | 4 ++--
5 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index 8cbfcf88fae3..c98adbe62733 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -120,6 +120,7 @@ static const struct clk_ops icst_ops = {
struct clk *icst_clk_register(struct device *dev,
const struct clk_icst_desc *desc,
const char *name,
+ const char *parent_name,
void __iomem *base)
{
struct clk *clk;
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h
index be99dd0da785..04e6f0aef588 100644
--- a/drivers/clk/versatile/clk-icst.h
+++ b/drivers/clk/versatile/clk-icst.h
@@ -16,4 +16,5 @@ struct clk_icst_desc {
struct clk *icst_clk_register(struct device *dev,
const struct clk_icst_desc *desc,
const char *name,
+ const char *parent_name,
void __iomem *base);
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c
index 844f8d711a12..6d8b8e1a080a 100644
--- a/drivers/clk/versatile/clk-impd1.c
+++ b/drivers/clk/versatile/clk-impd1.c
@@ -93,13 +93,15 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
imc = &impd1_clks[id];
imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id);
- clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base);
+ clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL,
+ base);
imc->vco1clk = clk;
imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
/* VCO2 is also called "CLK2" */
imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id);
- clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base);
+ clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, NULL,
+ base);
imc->vco2clk = clk;
/* MMCI uses CLK2 right off */
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index 19864b5690e9..5d36a719fefb 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -43,6 +43,7 @@ static void __init of_integrator_cm_osc_setup(struct device_node *np)
struct clk *clk = ERR_PTR(-EINVAL);
const char *clk_name = np->name;
const struct clk_icst_desc *desc = &cm_auxosc_desc;
+ const char *parent_name;
if (!cm_base) {
/* Remap the core module base if not done yet */
@@ -60,7 +61,8 @@ static void __init of_integrator_cm_osc_setup(struct device_node *np)
}
}
- clk = icst_clk_register(NULL, desc, clk_name, cm_base);
+ parent_name = of_clk_get_parent_name(np, 0);
+ clk = icst_clk_register(NULL, desc, clk_name, parent_name, cm_base);
if (!IS_ERR(clk))
of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
index 747e7b31117c..c8b523117fb7 100644
--- a/drivers/clk/versatile/clk-realview.c
+++ b/drivers/clk/versatile/clk-realview.c
@@ -85,10 +85,10 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
/* ICST VCO clock */
if (is_pb1176)
clk = icst_clk_register(NULL, &realview_osc0_desc,
- "osc0", sysbase);
+ "osc0", NULL, sysbase);
else
clk = icst_clk_register(NULL, &realview_osc4_desc,
- "osc4", sysbase);
+ "osc4", NULL, sysbase);
clk_register_clkdev(clk, NULL, "dev:clcd");
clk_register_clkdev(clk, NULL, "issp:clcd");
--
1.8.4.2
^ permalink raw reply related
* [PATCH 5/5] clk: versatile: respect parent rate in ICST clock
From: Linus Walleij @ 2014-01-20 20:55 UTC (permalink / raw)
To: linux-arm-kernel
If the ICST clock has a parent, respect the rate of the parent
when calculating the clock frequency. Alter const arguments
as this involves modifying the ICST parameter struct, and do
not define the reference clock on the Integrator as we have
the reference clock from the device tree. Keep it everywhere
else.
Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Hi Mike, looking for an ACK for this one as well.
---
drivers/clk/versatile/clk-icst.c | 10 +++++++---
drivers/clk/versatile/clk-icst.h | 2 +-
drivers/clk/versatile/clk-impd1.c | 4 ++--
drivers/clk/versatile/clk-integrator.c | 3 +--
drivers/clk/versatile/clk-realview.c | 2 +-
5 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index c98adbe62733..4bbfbf49b009 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -33,7 +33,7 @@ struct clk_icst {
struct clk_hw hw;
void __iomem *vcoreg;
void __iomem *lockreg;
- const struct icst_params *params;
+ struct icst_params *params;
unsigned long rate;
};
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
struct clk_icst *icst = to_icst(hw);
struct icst_vco vco;
+ if (parent_rate)
+ icst->params->ref = parent_rate;
vco = vco_get(icst->vcoreg);
icst->rate = icst_hz(icst->params, vco);
return icst->rate;
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk_icst *icst = to_icst(hw);
struct icst_vco vco;
+ if (parent_rate)
+ icst->params->ref = parent_rate;
vco = icst_hz_to_vco(icst->params, rate);
icst->rate = icst_hz(icst->params, vco);
vco_set(icst->lockreg, icst->vcoreg, vco);
@@ -135,8 +139,8 @@ struct clk *icst_clk_register(struct device *dev,
init.name = name;
init.ops = &icst_ops;
init.flags = CLK_IS_ROOT;
- init.parent_names = NULL;
- init.num_parents = 0;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
icst->hw.init = &init;
icst->params = desc->params;
icst->vcoreg = base + desc->vco_offset;
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h
index 04e6f0aef588..e72b1c15d084 100644
--- a/drivers/clk/versatile/clk-icst.h
+++ b/drivers/clk/versatile/clk-icst.h
@@ -8,7 +8,7 @@
* memory base
*/
struct clk_icst_desc {
- const struct icst_params *params;
+ struct icst_params *params;
u32 vco_offset;
u32 lock_offset;
};
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c
index 6d8b8e1a080a..a3edc0463517 100644
--- a/drivers/clk/versatile/clk-impd1.c
+++ b/drivers/clk/versatile/clk-impd1.c
@@ -39,7 +39,7 @@ static struct impd1_clk impd1_clks[4];
* There are two VCO's on the IM-PD1
*/
-static const struct icst_params impd1_vco1_params = {
+static struct icst_params impd1_vco1_params = {
.ref = 24000000, /* 24 MHz */
.vco_max = ICST525_VCO_MAX_3V,
.vco_min = ICST525_VCO_MIN,
@@ -57,7 +57,7 @@ static const struct clk_icst_desc impd1_icst1_desc = {
.lock_offset = IMPD1_LOCK,
};
-static const struct icst_params impd1_vco2_params = {
+static struct icst_params impd1_vco2_params = {
.ref = 24000000, /* 24 MHz */
.vco_max = ICST525_VCO_MAX_3V,
.vco_min = ICST525_VCO_MIN,
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index 5d36a719fefb..b1f46d5154ea 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -20,8 +20,7 @@
/* Base offset for the core module */
static void __iomem *cm_base;
-static const struct icst_params cp_auxosc_params = {
- .ref = 24000000,
+static struct icst_params cp_auxosc_params = {
.vco_max = ICST525_VCO_MAX_5V,
.vco_min = ICST525_VCO_MIN,
.vd_min = 8,
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
index c8b523117fb7..a1491590e028 100644
--- a/drivers/clk/versatile/clk-realview.c
+++ b/drivers/clk/versatile/clk-realview.c
@@ -21,7 +21,7 @@
* Implementation of the ARM RealView clock trees.
*/
-static const struct icst_params realview_oscvco_params = {
+static struct icst_params realview_oscvco_params = {
.ref = 24000000,
.vco_max = ICST307_VCO_MAX,
.vco_min = ICST307_VCO_MIN,
--
1.8.4.2
^ permalink raw reply related
* [PATCH 0/2] DT updates for Hummingboard and new Cubox-i
From: Russell King - ARM Linux @ 2014-01-20 21:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMjBCbMZrpbKjBBUeFhWEkLHS5rERtajRDk0ew_5FYvQEA@mail.gmail.com>
On Mon, Jan 20, 2014 at 12:47:07PM -0800, Olof Johansson wrote:
> On Mon, Jan 20, 2014 at 1:55 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Sun, Jan 19, 2014 at 07:34:22PM -0800, Olof Johansson wrote:
> >> I'm guessing this is going to mess up Shawn's cleanup patches, but
> >> time has ran out for 3.14 for those so they will need to be respun
> >> anyway, most likely.
> >>
> >> We can apply them to arm-soc's dt branch. I think it's better if we
> >> merge them since dts files tend to be one of the conflict-ridden areas
> >> (even if this particular instance isn't). Send the series our way if
> >> you want, or send a branch pull request, your choice.
> >
> > There's no conflict, and they build fine according to my autobuilder
> > which includes arm-soc for-next.
>
> Great, I didn't see any patches sent from you though. Should I
> cherry-pick them from -next instead?
If there's no conflicts, and if there other imx DT changes aren't going
to be submitted, then why is there any need to cherry-pick them into
arm-soc?
Are you suggesting that DT changes happen spontaneously all the time?
If that's true, why couldn't the new board support be put in during
-rc kernels?
What you're saying doesn't really make _that_ much sense to me at the
moment.
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply
* [PATCH 5/5] clk: versatile: respect parent rate in ICST clock
From: Russell King - ARM Linux @ 2014-01-20 21:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390251332-6411-1-git-send-email-linus.walleij@linaro.org>
On Mon, Jan 20, 2014 at 09:55:32PM +0100, Linus Walleij wrote:
> If the ICST clock has a parent, respect the rate of the parent
> when calculating the clock frequency. Alter const arguments
> as this involves modifying the ICST parameter struct, and do
> not define the reference clock on the Integrator as we have
> the reference clock from the device tree. Keep it everywhere
> else.
This is not what I'd call a good idea.
> @@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
> struct clk_icst *icst = to_icst(hw);
> struct icst_vco vco;
>
> + if (parent_rate)
> + icst->params->ref = parent_rate;
...
> diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c
> index 6d8b8e1a080a..a3edc0463517 100644
> --- a/drivers/clk/versatile/clk-impd1.c
> +++ b/drivers/clk/versatile/clk-impd1.c
> @@ -39,7 +39,7 @@ static struct impd1_clk impd1_clks[4];
> * There are two VCO's on the IM-PD1
> */
>
> -static const struct icst_params impd1_vco1_params = {
> +static struct icst_params impd1_vco1_params = {
> .ref = 24000000, /* 24 MHz */
> .vco_max = ICST525_VCO_MAX_3V,
> .vco_min = ICST525_VCO_MIN,
> @@ -57,7 +57,7 @@ static const struct clk_icst_desc impd1_icst1_desc = {
> .lock_offset = IMPD1_LOCK,
> };
>
> -static const struct icst_params impd1_vco2_params = {
> +static struct icst_params impd1_vco2_params = {
> .ref = 24000000, /* 24 MHz */
> .vco_max = ICST525_VCO_MAX_3V,
> .vco_min = ICST525_VCO_MIN,
Right, so we end up writing directly into these _shared_ _statically_
_allocated_ structures.
> diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
> index c8b523117fb7..a1491590e028 100644
> --- a/drivers/clk/versatile/clk-realview.c
> +++ b/drivers/clk/versatile/clk-realview.c
> @@ -21,7 +21,7 @@
> * Implementation of the ARM RealView clock trees.
> */
>
> -static const struct icst_params realview_oscvco_params = {
> +static struct icst_params realview_oscvco_params = {
> .ref = 24000000,
And this one is shared by two different VCOs. Thankfully, the only
reason this isn't a problem is because they're both sourced from a
24MHz clock.
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply
* [PATCH 5/5] clk: versatile: respect parent rate in ICST clock
From: Linus Walleij @ 2014-01-20 21:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140120211207.GI15937@n2100.arm.linux.org.uk>
On Mon, Jan 20, 2014 at 10:12 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>> -static const struct icst_params impd1_vco2_params = {
>> +static struct icst_params impd1_vco2_params = {
>> .ref = 24000000, /* 24 MHz */
>> .vco_max = ICST525_VCO_MAX_3V,
>> .vco_min = ICST525_VCO_MIN,
>
> Right, so we end up writing directly into these _shared_ _statically_
> _allocated_ structures.
Argh yeah that's right.
I'll think of something better, like allocating the params on-the-fly
for DT instead.
Yours,
Linus Walleij
^ permalink raw reply
* [RFC PATCH 0/3] Add support for dwarf compat mode unwinding
From: Jean Pihet @ 2014-01-20 21:21 UTC (permalink / raw)
To: linux-arm-kernel
In the case of unwinding the debug info from a binary that has a different
address size than the current native platform, it is needed to record
it in the address space struct, in order to correctly parse the debug
info later. This mode is known as compat mode.
This is the case when e.g. profiling an ARMv7 binary that runs on an
ARMv8 (aka AARCH64) platform.
Depending on the target binary address size, loading and parsing of the
dwarf debug info and unwinding of the recorded stack frame must be
performed accordingly.
Tested dwarf local unwinding on ARMv8 (aka AARCH64) with ARMv7 and
ARMv8 binaries; and natively on X86_64.
Note:
- this series is an RFC, although tested OK on ARMv7, ARMv8 and x86_64,
- only local unwinding has been tested,
- retrieval of the next ip and frame pointer is performed using a
native read followed by a cast to the desired target address size.
Jean Pihet (3):
Add support for different binary target address sizes
Dwarf: load and parse the debug info of different target address
sizes
Dwarf: unwind the recorded stack frame of different target address
sizes
include/libunwind_i.h | 7 ++
include/tdep-aarch64/libunwind_i.h | 1 +
include/tdep-arm/libunwind_i.h | 1 +
include/tdep-hppa/libunwind_i.h | 1 +
include/tdep-ia64/libunwind_i.h | 1 +
include/tdep-mips/libunwind_i.h | 1 +
include/tdep-ppc32/libunwind_i.h | 1 +
include/tdep-ppc64/libunwind_i.h | 1 +
include/tdep-sh/libunwind_i.h | 1 +
include/tdep-x86/libunwind_i.h | 1 +
include/tdep-x86_64/libunwind_i.h | 1 +
src/dwarf/Gfde.c | 25 +++--
src/dwarf/Gfind_proc_info-lsb.c | 194 +++++++++++++++++++++++++++++--------
src/dwarf/Gparser.c | 27 ++++++
14 files changed, 214 insertions(+), 49 deletions(-)
--
1.7.11.7
^ permalink raw reply
* [PATCH 1/3] Add support for different binary target address sizes
From: Jean Pihet @ 2014-01-20 21:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390252922-25889-1-git-send-email-jean.pihet@linaro.org>
In the case of unwinding the debug info from a binary that has a different
address size than the current native platform, it is needed to record
it in the address space struct, in order to correctly parse the debug
info later. This mode is known as compat mode.
This is the case on e.g. profiling an ARMv7 binary that runs on an
ARMv8 (aka AARCH64) platform.
Add the target_addr_size field in the unw_addr_space struct and provide
the 32 and 64 bit macros for use in the code.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
include/libunwind_i.h | 7 +++++++
include/tdep-aarch64/libunwind_i.h | 1 +
include/tdep-arm/libunwind_i.h | 1 +
include/tdep-hppa/libunwind_i.h | 1 +
include/tdep-ia64/libunwind_i.h | 1 +
include/tdep-mips/libunwind_i.h | 1 +
include/tdep-ppc32/libunwind_i.h | 1 +
include/tdep-ppc64/libunwind_i.h | 1 +
include/tdep-sh/libunwind_i.h | 1 +
include/tdep-x86/libunwind_i.h | 1 +
include/tdep-x86_64/libunwind_i.h | 1 +
11 files changed, 17 insertions(+)
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 0be551f..859ae03 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -345,6 +345,13 @@ static inline void invalidate_edi (struct elf_dyn_info *edi)
# define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */
#endif /* !PT_ARM_EXIDX */
+/* Define binary target address size */
+enum {
+ TARGET_ADDR_SIZE_DEFAULT,
+ TARGET_ADDR_SIZE_32,
+ TARGET_ADDR_SIZE_64
+};
+
#include "tdep/libunwind_i.h"
#ifndef tdep_get_func_addr
diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h
index b162271..5341118 100644
--- a/include/tdep-aarch64/libunwind_i.h
+++ b/include/tdep-aarch64/libunwind_i.h
@@ -61,6 +61,7 @@ struct unw_addr_space
{
struct unw_accessors acc;
int big_endian;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h
index 291b101..7353f82 100644
--- a/include/tdep-arm/libunwind_i.h
+++ b/include/tdep-arm/libunwind_i.h
@@ -46,6 +46,7 @@ struct unw_addr_space
{
struct unw_accessors acc;
int big_endian;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-hppa/libunwind_i.h b/include/tdep-hppa/libunwind_i.h
index b5bbcec..7e2ebd7 100644
--- a/include/tdep-hppa/libunwind_i.h
+++ b/include/tdep-hppa/libunwind_i.h
@@ -45,6 +45,7 @@ unw_tdep_frame_t;
struct unw_addr_space
{
struct unw_accessors acc;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-ia64/libunwind_i.h b/include/tdep-ia64/libunwind_i.h
index 2bea830..20dd999 100644
--- a/include/tdep-ia64/libunwind_i.h
+++ b/include/tdep-ia64/libunwind_i.h
@@ -96,6 +96,7 @@ struct unw_addr_space
struct unw_accessors acc;
int big_endian;
int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-mips/libunwind_i.h b/include/tdep-mips/libunwind_i.h
index 3ef1cef..c7a0c16 100644
--- a/include/tdep-mips/libunwind_i.h
+++ b/include/tdep-mips/libunwind_i.h
@@ -52,6 +52,7 @@ struct unw_addr_space
int big_endian;
mips_abi_t abi;
unsigned int addr_size;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
diff --git a/include/tdep-ppc32/libunwind_i.h b/include/tdep-ppc32/libunwind_i.h
index 06c0023..3c67454 100644
--- a/include/tdep-ppc32/libunwind_i.h
+++ b/include/tdep-ppc32/libunwind_i.h
@@ -51,6 +51,7 @@ unw_tdep_frame_t;
struct unw_addr_space
{
struct unw_accessors acc;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-ppc64/libunwind_i.h b/include/tdep-ppc64/libunwind_i.h
index 6024455..faf6483 100644
--- a/include/tdep-ppc64/libunwind_i.h
+++ b/include/tdep-ppc64/libunwind_i.h
@@ -53,6 +53,7 @@ struct unw_addr_space
struct unw_accessors acc;
int big_endian;
ppc64_abi_t abi;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-sh/libunwind_i.h b/include/tdep-sh/libunwind_i.h
index 51234d1..c731001 100644
--- a/include/tdep-sh/libunwind_i.h
+++ b/include/tdep-sh/libunwind_i.h
@@ -46,6 +46,7 @@ struct unw_addr_space
{
struct unw_accessors acc;
int big_endian;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-x86/libunwind_i.h b/include/tdep-x86/libunwind_i.h
index f59a3cf..7f5be18 100644
--- a/include/tdep-x86/libunwind_i.h
+++ b/include/tdep-x86/libunwind_i.h
@@ -45,6 +45,7 @@ unw_tdep_frame_t;
struct unw_addr_space
{
struct unw_accessors acc;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
diff --git a/include/tdep-x86_64/libunwind_i.h b/include/tdep-x86_64/libunwind_i.h
index 8c9cd05..623416b 100644
--- a/include/tdep-x86_64/libunwind_i.h
+++ b/include/tdep-x86_64/libunwind_i.h
@@ -62,6 +62,7 @@ unw_tdep_frame_t;
struct unw_addr_space
{
struct unw_accessors acc;
+ int target_addr_size; /* target binary: 32/64 bit */
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
--
1.7.11.7
^ permalink raw reply related
* [PATCH 2/3] Dwarf: load and parse the debug info of different target address sizes
From: Jean Pihet @ 2014-01-20 21:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390252922-25889-1-git-send-email-jean.pihet@linaro.org>
When in compat mode, load and parse the dwarf debug info accordingly.
Tested dwarf local unwinding on ARMv8 (aka AARCH64) with ARMv7 and
ARMv8 binaries.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
src/dwarf/Gfde.c | 25 ++++--
src/dwarf/Gfind_proc_info-lsb.c | 194 +++++++++++++++++++++++++++++++---------
2 files changed, 170 insertions(+), 49 deletions(-)
diff --git a/src/dwarf/Gfde.c b/src/dwarf/Gfde.c
index 8659624..81959d1 100644
--- a/src/dwarf/Gfde.c
+++ b/src/dwarf/Gfde.c
@@ -59,14 +59,23 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
/* Pick appropriate default for FDE-encoding. DWARF spec says
start-IP (initial_location) and the code-size (address_range) are
"address-unit sized constants". The `R' augmentation can be used
- to override this, but by default, we pick an address-sized unit
- for fde_encoding. */
- switch (dwarf_addr_size (as))
- {
- case 4: fde_encoding = DW_EH_PE_udata4; break;
- case 8: fde_encoding = DW_EH_PE_udata8; break;
- default: fde_encoding = DW_EH_PE_omit; break;
- }
+ to override this, but by default, we pick the target binary address
+ size unit for fde_encoding. */
+ switch (as->target_addr_size)
+ {
+ /* If defined at binary load time (e.g. from the ELF format) */
+ case TARGET_ADDR_SIZE_32: fde_encoding = DW_EH_PE_udata4; break;
+ case TARGET_ADDR_SIZE_64: fde_encoding = DW_EH_PE_udata8; break;
+ /* If not defined, use the current address size unit */
+ case TARGET_ADDR_SIZE_DEFAULT:
+ default:
+ switch (dwarf_addr_size (as))
+ {
+ case 4: fde_encoding = DW_EH_PE_udata4; break;
+ case 8: fde_encoding = DW_EH_PE_udata8; break;
+ default: fde_encoding = DW_EH_PE_omit; break;
+ }
+ }
dci->lsda_encoding = DW_EH_PE_omit;
dci->handler = 0;
diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c
index f75bda2..8c35e58 100644
--- a/src/dwarf/Gfind_proc_info-lsb.c
+++ b/src/dwarf/Gfind_proc_info-lsb.c
@@ -81,36 +81,89 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
#endif /* !UNW_REMOTE_ONLY */
#ifdef CONFIG_DEBUG_FRAME
-/* Load .debug_frame section from FILE. Allocates and returns space
- in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the
- local process, in which case we can search the system debug file
- directory; 0 for other address spaces, in which case we do not; or
- -1 for recursive calls following .gnu_debuglink. Returns 0 on
- success, 1 on error. Succeeds even if the file contains no
- .debug_frame. */
-/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */
-
-static int
-load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
+static int load_debug_frame_Elf32(const char *file, FILE *f, char *linkbuf,
+ size_t *linksize, char **buf, size_t *bufsize)
{
- FILE *f;
- Elf_W (Ehdr) ehdr;
- Elf_W (Half) shstrndx;
- Elf_W (Shdr) *sec_hdrs = NULL;
+ Elf32_Ehdr ehdr;
+ Elf32_Shdr *sec_hdrs = NULL;
+ Elf32_Half shstrndx;
char *stringtab = NULL;
unsigned int i;
- size_t linksize = 0;
- char *linkbuf = NULL;
+
+ if (fseek(f, 0L, SEEK_SET))
+ goto file_error;
+ if (fread (&ehdr, sizeof(Elf32_Ehdr), 1, f) != 1)
+ goto file_error;
- *buf = NULL;
- *bufsize = 0;
+ shstrndx = ehdr.e_shstrndx;
- f = fopen (file, "r");
+ Debug (4, "opened file '%s'. Section header at offset %d\n",
+ file, (int) ehdr.e_shoff);
+
+ fseek (f, ehdr.e_shoff, SEEK_SET);
+ sec_hdrs = calloc (ehdr.e_shnum, sizeof(Elf32_Shdr));
+ if (fread (sec_hdrs, sizeof(Elf32_Shdr), ehdr.e_shnum, f) != ehdr.e_shnum)
+ goto file_error;
- if (!f)
- return 1;
+ Debug (4, "loading string table of size %zd\n",
+ sec_hdrs[shstrndx].sh_size);
+ stringtab = malloc (sec_hdrs[shstrndx].sh_size);
+ fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET);
+ if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size)
+ goto file_error;
- if (fread (&ehdr, sizeof (Elf_W (Ehdr)), 1, f) != 1)
+ for (i = 1; i < ehdr.e_shnum && *buf == NULL; i++)
+ {
+ char *secname = &stringtab[sec_hdrs[i].sh_name];
+
+ if (strcmp (secname, ".debug_frame") == 0)
+ {
+ *bufsize = sec_hdrs[i].sh_size;
+ *buf = malloc (*bufsize);
+
+ fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
+ if (fread (*buf, 1, *bufsize, f) != *bufsize)
+ goto file_error;
+
+ Debug (4, "read %zd bytes of .debug_frame from offset %d\n",
+ *bufsize, sec_hdrs[i].sh_offset);
+ }
+ else if (strcmp (secname, ".gnu_debuglink") == 0)
+ {
+ *linksize = sec_hdrs[i].sh_size;
+ linkbuf = malloc(*linksize);
+
+ fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
+ if (fread (linkbuf, 1, *linksize, f) != *linksize)
+ goto file_error;
+
+ Debug (4, "read %d bytes of .gnu_debuglink from offset %d\n",
+ (int) *linksize, sec_hdrs[i].sh_offset);
+ }
+ }
+
+ free(sec_hdrs);
+ free(stringtab);
+ return 0;
+
+file_error:
+ free(sec_hdrs);
+ free(stringtab);
+ return -1;
+}
+
+static int load_debug_frame_Elf64(const char *file, FILE *f, char *linkbuf,
+ size_t *linksize, char **buf, size_t *bufsize)
+{
+ Elf64_Ehdr ehdr;
+ Elf64_Shdr *sec_hdrs = NULL;
+ Elf64_Half shstrndx;
+ char *stringtab = NULL;
+ unsigned int i;
+
+ if (fseek(f, 0L, SEEK_SET))
+ goto file_error;
+ if (fread (&ehdr, sizeof(Elf64_Ehdr), 1, f) != 1)
goto file_error;
shstrndx = ehdr.e_shstrndx;
@@ -119,8 +172,8 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
file, (int) ehdr.e_shoff);
fseek (f, ehdr.e_shoff, SEEK_SET);
- sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr)));
- if (fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum)
+ sec_hdrs = calloc (ehdr.e_shnum, sizeof(Elf64_Shdr));
+ if (fread (sec_hdrs, sizeof(Elf64_Shdr), ehdr.e_shnum, f) != ehdr.e_shnum)
goto file_error;
Debug (4, "loading string table of size %zd\n",
@@ -131,7 +184,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
goto file_error;
for (i = 1; i < ehdr.e_shnum && *buf == NULL; i++)
- {
+ {
char *secname = &stringtab[sec_hdrs[i].sh_name];
if (strcmp (secname, ".debug_frame") == 0)
@@ -148,20 +201,71 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
}
else if (strcmp (secname, ".gnu_debuglink") == 0)
{
- linksize = sec_hdrs[i].sh_size;
- linkbuf = malloc (linksize);
+ *linksize = sec_hdrs[i].sh_size;
+ linkbuf = malloc(*linksize);
fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
- if (fread (linkbuf, 1, linksize, f) != linksize)
+ if (fread (linkbuf, 1, *linksize, f) != *linksize)
goto file_error;
- Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n",
- linksize, sec_hdrs[i].sh_offset);
+ Debug (4, "read %d bytes of .gnu_debuglink from offset %zd\n",
+ (int) *linksize, sec_hdrs[i].sh_offset);
}
- }
+ }
+
+ free(sec_hdrs);
+ free(stringtab);
+ return 0;
+
+file_error:
+ free(sec_hdrs);
+ free(stringtab);
+ return -1;
+}
+
+/* Load .debug_frame section from FILE. Allocates and returns space
+ in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the
+ local process, in which case we can search the system debug file
+ directory; 0 for other address spaces, in which case we do not; or
+ -1 for recursive calls following .gnu_debuglink. Returns 0 on
+ success, 1 on error. Succeeds even if the file contains no
+ .debug_frame. */
+/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */
- free (stringtab);
- free (sec_hdrs);
+static int
+load_debug_frame (const char *file, char **buf, size_t *bufsize,
+ unw_addr_space_t as, int is_local)
+{
+ FILE *f;
+ unsigned char e_ident[sizeof(((Elf32_Ehdr *)0)->e_ident)];
+ size_t linksize = 0;
+ char *linkbuf = NULL;
+
+ *buf = NULL;
+ *bufsize = 0;
+
+ f = fopen (file, "r");
+
+ if (!f)
+ return 1;
+
+ if (fread (&e_ident, sizeof(e_ident), 1, f) != 1)
+ goto file_error;
+
+ switch (e_ident[EI_CLASS]) {
+ case ELFCLASS32:
+ as->target_addr_size = TARGET_ADDR_SIZE_32;
+ load_debug_frame_Elf32(file, f, linkbuf, &linksize, buf, bufsize);
+ break;
+ case ELFCLASS64:
+ as->target_addr_size = TARGET_ADDR_SIZE_64;
+ load_debug_frame_Elf64(file, f, linkbuf, &linksize, buf, bufsize);
+ break;
+ case ELFCLASSNONE:
+ default:
+ Debug (15, "Wrong ELF class 0x%02x\n", e_ident[EI_CLASS]);
+ goto file_error;
+ }
fclose (f);
@@ -195,14 +299,14 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
strcpy (newname, basedir);
strcat (newname, "/");
strcat (newname, linkbuf);
- ret = load_debug_frame (newname, buf, bufsize, -1);
+ ret = load_debug_frame (newname, buf, bufsize, as, -1);
if (ret == 1)
{
strcpy (newname, basedir);
strcat (newname, "/.debug/");
strcat (newname, linkbuf);
- ret = load_debug_frame (newname, buf, bufsize, -1);
+ ret = load_debug_frame (newname, buf, bufsize, as, -1);
}
if (ret == 1 && is_local == 1)
@@ -211,20 +315,19 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
strcat (newname, basedir);
strcat (newname, "/");
strcat (newname, linkbuf);
- ret = load_debug_frame (newname, buf, bufsize, -1);
+ ret = load_debug_frame (newname, buf, bufsize, as, -1);
}
free (basedir);
free (newname);
}
- free (linkbuf);
+
+ free(linkbuf);
return 0;
/* An error reading image file. Release resources and return error code */
file_error:
- free(stringtab);
- free(sec_hdrs);
free(linkbuf);
fclose(f);
@@ -303,7 +406,8 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
else
name = (char*) dlname;
- err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space);
+ err = load_debug_frame (name, &buf, &bufsize, as,
+ as == unw_local_addr_space);
if (!err)
{
@@ -851,6 +955,14 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
#ifndef UNW_REMOTE_ONLY
struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data;
+ /*
+ * Set the target address size as found in the loaded debug binary.
+ * Note: in case of local unwinding the caller 'as' is set to
+ * unw_local_addr_space, cf. below. Let's assign the value to
+ * the caller 'as' before changing the value of 'as'.
+ */
+ as->target_addr_size = unw_local_addr_space->target_addr_size;
+
/* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address
space. Both the index and the unwind tables live in local memory, but
the address space to check for properties like the address size and
--
1.7.11.7
^ permalink raw reply related
* [PATCH 3/3] Dwarf: unwind the recorded stack frame of different target address sizes
From: Jean Pihet @ 2014-01-20 21:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390252922-25889-1-git-send-email-jean.pihet@linaro.org>
When in compat mode, correctly unwind the recorded stack frame. The
returned pointers are cast to the desired target address size.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
src/dwarf/Gparser.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c
index b251e31..d676861 100644
--- a/src/dwarf/Gparser.c
+++ b/src/dwarf/Gparser.c
@@ -706,6 +706,29 @@ eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as,
return 0;
}
+/* Cast pointer content to the type of target address size */
+static inline int cast_value_to_addr_size(unw_word_t *val, int addr_size)
+{
+ switch (addr_size) {
+ /*
+ * Return the value of the type found at binary load time (e.g. from the
+ * ELF format)...
+ */
+ case TARGET_ADDR_SIZE_32:
+ *val = (uint32_t) *val;
+ break;
+ case TARGET_ADDR_SIZE_64:
+ *val = (uint64_t) *val;
+ break;
+ /* ... otherwise leave it as is */
+ case TARGET_ADDR_SIZE_DEFAULT:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int
apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
{
@@ -743,6 +766,8 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val);
if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0)
return ret;
+ /* Cast value to the type as found in the ELF binary format */
+ cast_value_to_addr_size(&cfa, as->target_addr_size);
}
cfa += rs->reg[DWARF_CFA_OFF_COLUMN].val;
}
@@ -797,6 +822,8 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip);
if (ret < 0)
return ret;
+ /* Cast value to the type as found in the ELF binary format */
+ cast_value_to_addr_size(&ip, as->target_addr_size);
c->ip = ip;
}
--
1.7.11.7
^ permalink raw reply related
* [PATCH 02/11] iommu/arm-smmu: Introduce bus notifier block
From: Andreas Herrmann @ 2014-01-20 21:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <419c2609cab14842b5258f7048ce6d43@BL2PR03MB468.namprd03.prod.outlook.com>
On Sat, Jan 18, 2014 at 03:59:53PM -0500, Varun Sethi wrote:
> > -----Original Message-----
> > From: iommu-bounces at lists.linux-foundation.org [mailto:iommu-
> > bounces at lists.linux-foundation.org] On Behalf Of Andreas Herrmann
> > Sent: Thursday, January 16, 2014 6:14 PM
> > To: Will Deacon
> > Cc: Andreas Herrmann; iommu at lists.linux-foundation.org; linux-arm-
> > kernel at lists.infradead.org
> > Subject: [PATCH 02/11] iommu/arm-smmu: Introduce bus notifier block
> >
> > At the moment just handle BUS_NOTIFY_BIND_DRIVER to conditionally isolate
> > all master devices for an SMMU.
> >
> > Depending on DT information each device is put into its own protection
> > domain (if possible). For configuration with one or just a few masters
> > per SMMU that is easy to achieve.
> >
> > In case of many devices per SMMU (e.g. MMU-500 with it's distributed
> > translation support) isolation of each device might not be possible --
> > depending on number of available SMR groups and/or context banks.
> >
> > Default is that device isolation is contolled per SMMU with SMMU node
> > property "arm,smmu-isolate-devices" in a DT. If this property is set for
> > an SMMU node, device isolation is performed.
> [Sethi Varun-B16395] What if the devices have to be assigned to
> different virtual machines? Would the absence of this property
> indicate that devices can't Be assigned to different virtual
> machines i.e. devices would be in the same iommu group?
The absence of this property implies that arm-smmu driver handling of
master devices is equivalent to the current handling.
(I.e. assignment to different VMs works or doesn't work as with the current
mainline driver.)
> > W/o device isolation the driver detects SMMUs but no translation is
> > configured (transactions just bypass translation process).
> >
> [Sethi Varun-B16395] Would SMR and S2CR still be allocated?
That's similar to the current handling of the driver. SMRs will be
marked as invalid and all S2CRs are configured as bypass.
As long as nobody creates a domain and attaches a device to it this
won't change.
> > Note that for device isolation dma_base and size are fixed as 0 and
> > SZ_128M at the moment. Additional patches will address this restriction
> > and allow automatic growth of mapping size.
> >
> > Cc: Andreas Herrmann <herrmann.der.user@googlemail.com>
> > Signed-off-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
> > ---
> > drivers/iommu/arm-smmu.c | 45
> > +++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 45 insertions(+)
> >
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index
> > 0b97d03..bc81dd0 100644
> > --- a/drivers/iommu/arm-smmu.c
> > +++ b/drivers/iommu/arm-smmu.c
> > @@ -46,6 +46,7 @@
> > #include <linux/amba/bus.h>
> >
> > #include <asm/pgalloc.h>
> > +#include <asm/dma-iommu.h>
> >
> > /* Driver options */
> > #define ARM_SMMU_OPT_ISOLATE_DEVICES (1 << 0)
> > @@ -1964,6 +1965,48 @@ static int arm_smmu_device_remove(struct
> > platform_device *pdev)
> > return 0;
> > }
> >
> > +static int arm_smmu_device_notifier(struct notifier_block *nb,
> > + unsigned long action, void *data)
> > +{
> > + struct device *dev = data;
> > + struct dma_iommu_mapping *mapping;
> > + struct arm_smmu_device *smmu;
> > + int ret;
> > +
> > + switch (action) {
> > + case BUS_NOTIFY_BIND_DRIVER:
> > +
> > + arm_smmu_add_device(dev);
> [Sethi Varun-B16395] This would have already happened by virtue of the add_device iommu_ops.
You are right. That call is there for no good reason.
> > + smmu = dev->archdata.iommu;
> > + if (!smmu || !(smmu->options & ARM_SMMU_OPT_ISOLATE_DEVICES))
> > + break;
> > +
> > + mapping = arm_iommu_create_mapping(&platform_bus_type,
> > + 0, SZ_128M, 0);
> > + if (IS_ERR(mapping)) {
> > + ret = PTR_ERR(mapping);
> > + dev_info(dev, "arm_iommu_create_mapping failed\n");
> > + break;
> > + }
> > +
> > + ret = arm_iommu_attach_device(dev, mapping);
> > + if (ret < 0) {
> > + dev_info(dev, "arm_iommu_attach_device failed\n");
> > + arm_iommu_release_mapping(mapping);
> > + }
> > +
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static struct notifier_block device_nb = {
> > + .notifier_call = arm_smmu_device_notifier, };
> > +
> > #ifdef CONFIG_OF
> > static struct of_device_id arm_smmu_of_match[] = {
> > { .compatible = "arm,smmu-v1", },
> > @@ -2000,6 +2043,8 @@ static int __init arm_smmu_init(void)
> > if (!iommu_present(&amba_bustype))
> > bus_set_iommu(&amba_bustype, &arm_smmu_ops);
> >
> > + bus_register_notifier(&platform_bus_type, &device_nb);
> > +
> [Sethi Varun-B16395] Notifier was already registered for the
> platform bus via bus_set_iommu. You can actually register a iommu
> group (once iommu group gets created) notifier
> (iommu_group_register_notifier) and listen for the
> IOMMU_GROUP_NOTIFY_BIND_DRIVER event.
Sounds reasonable.
So far the driver didn't care about iommu_groups. But there is already
a patch "iommu/arm-smmu: add devices attached to the SMMU to an IOMMU
group" pending in Will's iommu/devel branch that fixes this.
I'll adapt my patch to use iommu_group notifier instead of bus
notifier.
Thanks for your review!
Andreas
^ permalink raw reply
* [PATCH 5/5] clk: versatile: respect parent rate in ICST clock
From: Russell King - ARM Linux @ 2014-01-20 21:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdZ1F_SvGcerMDfmhSgnLVzLXBJnQ9iftSG6yW2mMhOOKQ@mail.gmail.com>
On Mon, Jan 20, 2014 at 10:16:53PM +0100, Linus Walleij wrote:
> On Mon, Jan 20, 2014 at 10:12 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>
> >> -static const struct icst_params impd1_vco2_params = {
> >> +static struct icst_params impd1_vco2_params = {
> >> .ref = 24000000, /* 24 MHz */
> >> .vco_max = ICST525_VCO_MAX_3V,
> >> .vco_min = ICST525_VCO_MIN,
> >
> > Right, so we end up writing directly into these _shared_ _statically_
> > _allocated_ structures.
>
> Argh yeah that's right.
>
> I'll think of something better, like allocating the params on-the-fly
> for DT instead.
That's actually why they're const - they're const because they are not
supposed to be written to...
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply
* [PATCH] ARM: mvebu: fix compilation warning on Armada 370 (i.e. non-SMP)
From: Arnaud Ebalard @ 2014-01-20 21:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3644485.dCdZFrR2be@wuerfel>
Hi Arnd,
Arnd Bergmann <arnd@arndb.de> writes:
> On Monday 20 January 2014 21:14:13 Arnaud Ebalard wrote:
>> diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
>> index 433cc8568dec..499c5070f841 100644
>> --- a/drivers/irqchip/irq-armada-370-xp.c
>> +++ b/drivers/irqchip/irq-armada-370-xp.c
>> @@ -59,7 +59,9 @@
>> #define PCI_MSI_DOORBELL_END (32)
>> #define PCI_MSI_DOORBELL_MASK 0xFFFF0000
>>
>> +#ifdef CONFIG_SMP
>> static DEFINE_RAW_SPINLOCK(irq_controller_lock);
>> +#endif
>>
>> static void __iomem *per_cpu_
>
> How about moving it inside of the existing #ifdef?
>
> That also brings it closer to the one place it's used.
I also hesitated but decided to let the declaration of this global
at the beginning of the file. I will send a v2 with the declaration
moved inside the existing #ifdef.
Cheers,
a+
^ permalink raw reply
* [PATCHv2] ARM: mvebu: fix compilation warning on Armada 370 (i.e. non-SMP)
From: Arnaud Ebalard @ 2014-01-20 21:52 UTC (permalink / raw)
To: linux-arm-kernel
The following appears during compilation for an Armada 370 target
because 'irq_controller_lock' is used only when CONFIG_SMP is
enabled:
drivers/irqchip/irq-armada-370-xp.c:62:8: warning: 'irq_controller_lock' defined but not used [-Wunused-variable]
Fix that warning by moving declaration of 'irq_controller_lock'
inside existing #ifdef.
Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
---
Changes since v1:
- moved declaration inside existing #ifdef as suggested by Arnd,
instead of adding a new one.
drivers/irqchip/irq-armada-370-xp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 433cc8568dec..9300bc32784e 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -59,8 +59,6 @@
#define PCI_MSI_DOORBELL_END (32)
#define PCI_MSI_DOORBELL_MASK 0xFFFF0000
-static DEFINE_RAW_SPINLOCK(irq_controller_lock);
-
static void __iomem *per_cpu_int_base;
static void __iomem *main_int_base;
static struct irq_domain *armada_370_xp_mpic_domain;
@@ -239,6 +237,8 @@ static inline int armada_370_xp_msi_init(struct device_node *node,
#endif
#ifdef CONFIG_SMP
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
static int armada_xp_set_affinity(struct irq_data *d,
const struct cpumask *mask_val, bool force)
{
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 02/11] iommu/arm-smmu: Introduce iommu_group notifier block
From: Andreas Herrmann @ 2014-01-20 21:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389876263-25759-3-git-send-email-andreas.herrmann@calxeda.com>
At the moment just handle BUS_NOTIFY_BIND_DRIVER to conditionally
isolate all master devices for an SMMU.
Depending on DT information each device is put into its own protection
domain (if possible). For configuration with one or just a few
masters per SMMU that is easy to achieve.
In case of many devices per SMMU (e.g. MMU-500 with it's distributed
translation support) isolation of each device might not be possible --
depending on number of available SMR groups and/or context banks.
Default is that device isolation is contolled per SMMU with SMMU node
property "arm,smmu-isolate-devices" in a DT. If this property is set
for an SMMU node, device isolation is performed.
W/o device isolation the driver detects SMMUs but no translation is
configured (transactions just bypass translation process).
Note that for device isolation dma_base and size are fixed as 0 and
SZ_128M at the moment. Additional patches will address this
restriction and allow automatic growth of mapping size.
Cc: Varun Sethi <Varun.Sethi@freescale.com>
Cc: Andreas Herrmann <herrmann.der.user@googlemail.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
---
drivers/iommu/arm-smmu.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
Hi Will,
This new patch addresses Varun's comments:
- use iommu_group notifier instead of bus notifier
- remove superfluous call to arm_smmu_add_device in
notifier function
This patch depends on commit "iommu/arm-smmu: add devices attached to
the SMMU to an IOMMU group" as found in your git tree (e.g. in branch
iommu/devel or for-joerg/arm-smmu/updates).
Andreas
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 0a5649f..edd0ffb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -46,6 +46,7 @@
#include <linux/amba/bus.h>
#include <asm/pgalloc.h>
+#include <asm/dma-iommu.h>
/* Driver options */
#define ARM_SMMU_OPT_ISOLATE_DEVICES (1 << 0)
@@ -402,6 +403,13 @@ struct arm_smmu_domain {
static DEFINE_SPINLOCK(arm_smmu_devices_lock);
static LIST_HEAD(arm_smmu_devices);
+static int arm_smmu_group_notifier(struct notifier_block *nb,
+ unsigned long action, void *data);
+
+static struct notifier_block group_nb = {
+ .notifier_call = arm_smmu_group_notifier,
+};
+
struct arm_smmu_option_prop {
u32 opt;
const char *prop;
@@ -1566,6 +1574,8 @@ static int arm_smmu_add_device(struct device *dev)
return PTR_ERR(group);
}
+ iommu_group_register_notifier(group, &group_nb);
+
ret = iommu_group_add_device(group, dev);
iommu_group_put(group);
dev->archdata.iommu = smmu;
@@ -1981,6 +1991,43 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
return 0;
}
+static int arm_smmu_group_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+ struct dma_iommu_mapping *mapping;
+ struct arm_smmu_device *smmu;
+ int ret;
+
+ switch (action) {
+ case BUS_NOTIFY_BIND_DRIVER:
+
+ smmu = dev->archdata.iommu;
+ if (!smmu || !(smmu->options & ARM_SMMU_OPT_ISOLATE_DEVICES))
+ break;
+
+ mapping = arm_iommu_create_mapping(&platform_bus_type,
+ 0, SZ_128M, 0);
+ if (IS_ERR(mapping)) {
+ ret = PTR_ERR(mapping);
+ dev_info(dev, "arm_iommu_create_mapping failed\n");
+ break;
+ }
+
+ ret = arm_iommu_attach_device(dev, mapping);
+ if (ret < 0) {
+ dev_info(dev, "arm_iommu_attach_device failed\n");
+ arm_iommu_release_mapping(mapping);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_OF
static struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", },
--
1.7.9.5
^ permalink raw reply related
* [PATCH] ARM: orion: provide C-style interrupt handler for MULTI_IRQ_HANDLER
From: Ian Campbell @ 2014-01-20 21:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140116184943.GK29184@titan.lakedaemon.net>
On Thu, 2014-01-16 at 13:49 -0500, Jason Cooper wrote:
> > @Ian: Thanks for hunting this down, please keep bothering us with
> > bug reports :)
>
> Yes, please!
No worries there -- it seem Debian has quite a few people who use
kirkwood based systems and will report bugs when they find them...
Thanks (again?) for the quick fix.
Ian.
^ permalink raw reply
* [PATCH 5/5 v2] clk: versatile: respect parent rate in ICST clock
From: Linus Walleij @ 2014-01-20 21:54 UTC (permalink / raw)
To: linux-arm-kernel
If the ICST clock has a parent, respect the rate of the parent
when calculating the clock frequency. As this involves modifying
the ICST parameter struct, make a cloned copy (the divisor
arrays should be safe) so we can update the .ref field.
Do not define the reference clock on the Integrator as we have
the reference clock from the device tree. Keep it everywhere
else.
Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- As Russell observed: the params are static objects, so if
we want to alter them, we better make a copy of them.
Hi Mike, looking for an ACK for this one as well.
---
drivers/clk/versatile/clk-icst.c | 20 ++++++++++++++++----
drivers/clk/versatile/clk-integrator.c | 1 -
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index c98adbe62733..a820b0cfcf57 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -33,7 +33,7 @@ struct clk_icst {
struct clk_hw hw;
void __iomem *vcoreg;
void __iomem *lockreg;
- const struct icst_params *params;
+ struct icst_params *params;
unsigned long rate;
};
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
struct clk_icst *icst = to_icst(hw);
struct icst_vco vco;
+ if (parent_rate)
+ icst->params->ref = parent_rate;
vco = vco_get(icst->vcoreg);
icst->rate = icst_hz(icst->params, vco);
return icst->rate;
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk_icst *icst = to_icst(hw);
struct icst_vco vco;
+ if (parent_rate)
+ icst->params->ref = parent_rate;
vco = icst_hz_to_vco(icst->params, rate);
icst->rate = icst_hz(icst->params, vco);
vco_set(icst->lockreg, icst->vcoreg, vco);
@@ -126,19 +130,27 @@ struct clk *icst_clk_register(struct device *dev,
struct clk *clk;
struct clk_icst *icst;
struct clk_init_data init;
+ struct icst_params *pclone;
icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
if (!icst) {
pr_err("could not allocate ICST clock!\n");
return ERR_PTR(-ENOMEM);
}
+
+ pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
+ if (!pclone) {
+ pr_err("could not clone ICST params\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
init.name = name;
init.ops = &icst_ops;
init.flags = CLK_IS_ROOT;
- init.parent_names = NULL;
- init.num_parents = 0;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
icst->hw.init = &init;
- icst->params = desc->params;
+ icst->params = pclone;
icst->vcoreg = base + desc->vco_offset;
icst->lockreg = base + desc->lock_offset;
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index 5d36a719fefb..734c4b8fe6ab 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -21,7 +21,6 @@
static void __iomem *cm_base;
static const struct icst_params cp_auxosc_params = {
- .ref = 24000000,
.vco_max = ICST525_VCO_MAX_5V,
.vco_min = ICST525_VCO_MIN,
.vd_min = 8,
--
1.8.4.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox