* [PATCH v8 3/8] PWM: add pwm-stm32 DT bindings
From: Benjamin Gaignard @ 2017-01-18 14:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484749251-14445-1-git-send-email-benjamin.gaignard@st.com>
Define bindings for pwm-stm32
version 8:
- reword st,breakinput description.
version 6:
- change st,breakinput parameter format to make it usuable on stm32f7 too.
version 2:
- use parameters instead of compatible of handle the hardware configuration
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/pwm/pwm-stm32.txt | 35 ++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-stm32.txt
diff --git a/Documentation/devicetree/bindings/pwm/pwm-stm32.txt b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt
new file mode 100644
index 0000000..6dd0403
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt
@@ -0,0 +1,35 @@
+STMicroelectronics STM32 Timers PWM bindings
+
+Must be a sub-node of an STM32 Timers device tree node.
+See ../mfd/stm32-timers.txt for details about the parent node.
+
+Required parameters:
+- compatible: Must be "st,stm32-pwm".
+- pinctrl-names: Set to "default".
+- pinctrl-0: List of phandles pointing to pin configuration nodes for PWM module.
+ For Pinctrl properties see ../pinctrl/pinctrl-bindings.txt
+
+Optional parameters:
+- st,breakinput: One or two <index level filter> to describe break input configurations.
+ "index" indicates on which break input (0 or 1) the configuration
+ should be applied.
+ "level" gives the active level (0=low or 1=high) of the input signal
+ for this configuration.
+ "filter" gives the filtering value to be applied.
+
+Example:
+ timers at 40010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40010000 0x400>;
+ clocks = <&rcc 0 160>;
+ clock-names = "clk_int";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ pinctrl-0 = <&pwm1_pins>;
+ pinctrl-names = "default";
+ st,breakinput = <0 1 5>;
+ };
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v8 2/8] MFD: add STM32 Timers driver
From: Benjamin Gaignard @ 2017-01-18 14:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484749251-14445-1-git-send-email-benjamin.gaignard@st.com>
This hardware block could at used at same time for PWM generation
and IIO timers.
PWM and IIO timer configuration are mixed in the same registers
so we need a multi fonction driver to be able to share those registers.
version 7:
- rebase on v4.10-rc2
version 6:
- rename files to stm32-timers
- rename functions to stm32_timers_xxx
version 5:
- fix Lee comments about detect function
- add missing dependency on REGMAP_MMIO
version 4:
- add a function to detect Auto Reload Register (ARR) size
- rename the structure shared with other drivers
version 2:
- rename driver "stm32-gptimer" to be align with SoC documentation
- only keep one compatible
- use of_platform_populate() instead of devm_mfd_add_devices()
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
drivers/mfd/Kconfig | 11 ++++++
drivers/mfd/Makefile | 2 +
drivers/mfd/stm32-timers.c | 80 ++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/stm32-timers.h | 71 +++++++++++++++++++++++++++++++++++
4 files changed, 164 insertions(+)
create mode 100644 drivers/mfd/stm32-timers.c
create mode 100644 include/linux/mfd/stm32-timers.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4ce3b6f..d0c14b8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1621,6 +1621,17 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
+config MFD_STM32_TIMERS
+ tristate "Support for STM32 Timers"
+ depends on (ARCH_STM32 && OF) || COMPILE_TEST
+ select MFD_CORE
+ select REGMAP
+ select REGMAP_MMIO
+ help
+ Select this option to enable STM32 timers driver used
+ for PWM and IIO Timer. This driver allow to share the
+ registers between the others drivers.
+
menu "Multimedia Capabilities Port drivers"
depends on ARCH_SA1100
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index dda4d4f..876ca86 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -212,3 +212,5 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
+
+obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c
new file mode 100644
index 0000000..41bd901
--- /dev/null
+++ b/drivers/mfd/stm32-timers.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) STMicroelectronics 2016
+ *
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/mfd/stm32-timers.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+
+static const struct regmap_config stm32_timers_regmap_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = sizeof(u32),
+ .max_register = 0x400,
+};
+
+static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
+{
+ /*
+ * Only the available bits will be written so when readback
+ * we get the maximum value of auto reload register
+ */
+ regmap_write(ddata->regmap, TIM_ARR, ~0L);
+ regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr);
+ regmap_write(ddata->regmap, TIM_ARR, 0x0);
+}
+
+static int stm32_timers_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct stm32_timers *ddata;
+ struct resource *res;
+ void __iomem *mmio;
+
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mmio = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mmio))
+ return PTR_ERR(mmio);
+
+ ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
+ &stm32_timers_regmap_cfg);
+ if (IS_ERR(ddata->regmap))
+ return PTR_ERR(ddata->regmap);
+
+ ddata->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(ddata->clk))
+ return PTR_ERR(ddata->clk);
+
+ stm32_timers_get_arr_size(ddata);
+
+ platform_set_drvdata(pdev, ddata);
+
+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+}
+
+static const struct of_device_id stm32_timers_of_match[] = {
+ { .compatible = "st,stm32-timers", },
+ { /* end node */ },
+};
+MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
+
+static struct platform_driver stm32_timers_driver = {
+ .probe = stm32_timers_probe,
+ .driver = {
+ .name = "stm32-timers",
+ .of_match_table = stm32_timers_of_match,
+ },
+};
+module_platform_driver(stm32_timers_driver);
+
+MODULE_DESCRIPTION("STMicroelectronics STM32 Timers");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
new file mode 100644
index 0000000..d030004
--- /dev/null
+++ b/include/linux/mfd/stm32-timers.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) STMicroelectronics 2016
+ *
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _LINUX_STM32_GPTIMER_H_
+#define _LINUX_STM32_GPTIMER_H_
+
+#include <linux/clk.h>
+#include <linux/regmap.h>
+
+#define TIM_CR1 0x00 /* Control Register 1 */
+#define TIM_CR2 0x04 /* Control Register 2 */
+#define TIM_SMCR 0x08 /* Slave mode control reg */
+#define TIM_DIER 0x0C /* DMA/interrupt register */
+#define TIM_SR 0x10 /* Status register */
+#define TIM_EGR 0x14 /* Event Generation Reg */
+#define TIM_CCMR1 0x18 /* Capt/Comp 1 Mode Reg */
+#define TIM_CCMR2 0x1C /* Capt/Comp 2 Mode Reg */
+#define TIM_CCER 0x20 /* Capt/Comp Enable Reg */
+#define TIM_PSC 0x28 /* Prescaler */
+#define TIM_ARR 0x2c /* Auto-Reload Register */
+#define TIM_CCR1 0x34 /* Capt/Comp Register 1 */
+#define TIM_CCR2 0x38 /* Capt/Comp Register 2 */
+#define TIM_CCR3 0x3C /* Capt/Comp Register 3 */
+#define TIM_CCR4 0x40 /* Capt/Comp Register 4 */
+#define TIM_BDTR 0x44 /* Break and Dead-Time Reg */
+
+#define TIM_CR1_CEN BIT(0) /* Counter Enable */
+#define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */
+#define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
+#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
+#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
+#define TIM_DIER_UIE BIT(0) /* Update interrupt */
+#define TIM_SR_UIF BIT(0) /* Update interrupt flag */
+#define TIM_EGR_UG BIT(0) /* Update Generation */
+#define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */
+#define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */
+#define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */
+#define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */
+#define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */
+#define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */
+#define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */
+#define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */
+#define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */
+#define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12))
+#define TIM_BDTR_BKE BIT(12) /* Break input enable */
+#define TIM_BDTR_BKP BIT(13) /* Break input polarity */
+#define TIM_BDTR_AOE BIT(14) /* Automatic Output Enable */
+#define TIM_BDTR_MOE BIT(15) /* Main Output Enable */
+#define TIM_BDTR_BKF (BIT(16) | BIT(17) | BIT(18) | BIT(19))
+#define TIM_BDTR_BK2F (BIT(20) | BIT(21) | BIT(22) | BIT(23))
+#define TIM_BDTR_BK2E BIT(24) /* Break 2 input enable */
+#define TIM_BDTR_BK2P BIT(25) /* Break 2 input polarity */
+
+#define MAX_TIM_PSC 0xFFFF
+#define TIM_CR2_MMS_SHIFT 4
+#define TIM_SMCR_TS_SHIFT 4
+#define TIM_BDTR_BKF_MASK 0xF
+#define TIM_BDTR_BKF_SHIFT 16
+#define TIM_BDTR_BK2F_SHIFT 20
+
+struct stm32_timers {
+ struct clk *clk;
+ struct regmap *regmap;
+ u32 max_arr;
+};
+#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v8 1/8] MFD: add bindings for STM32 Timers driver
From: Benjamin Gaignard @ 2017-01-18 14:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484749251-14445-1-git-send-email-benjamin.gaignard@st.com>
Add bindings information for STM32 Timers
version 6:
- rename stm32-gtimer to stm32-timers
- change compatible
- add description about the IPs
version 2:
- rename stm32-mfd-timer to stm32-gptimer
- only keep one compatible string
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/mfd/stm32-timers.txt | 46 ++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
new file mode 100644
index 0000000..bbd083f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
@@ -0,0 +1,46 @@
+STM32 Timers driver bindings
+
+This IP provides 3 types of timer along with PWM functionality:
+- advanced-control timers consist of a 16-bit auto-reload counter driven by a programmable
+ prescaler, break input feature, PWM outputs and complementary PWM ouputs channels.
+- general-purpose timers consist of a 16-bit or 32-bit auto-reload counter driven by a
+ programmable prescaler and PWM outputs.
+- basic timers consist of a 16-bit auto-reload counter driven by a programmable prescaler.
+
+Required parameters:
+- compatible: must be "st,stm32-timers"
+
+- reg: Physical base address and length of the controller's
+ registers.
+- clock-names: Set to "int".
+- clocks: Phandle to the clock used by the timer module.
+ For Clk properties, please refer to ../clock/clock-bindings.txt
+
+Optional parameters:
+- resets: Phandle to the parent reset controller.
+ See ../reset/st,stm32-rcc.txt
+
+Optional subnodes:
+- pwm: See ../pwm/pwm-stm32.txt
+- timer: See ../iio/timer/stm32-timer-trigger.txt
+
+Example:
+ timers at 40010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40010000 0x400>;
+ clocks = <&rcc 0 160>;
+ clock-names = "clk_int";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ pinctrl-0 = <&pwm1_pins>;
+ pinctrl-names = "default";
+ };
+
+ timer at 0 {
+ compatible = "st,stm32-timer-trigger";
+ reg = <0>;
+ };
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v8 0/8] Add PWM and IIO timer drivers for STM32
From: Benjamin Gaignard @ 2017-01-18 14:20 UTC (permalink / raw)
To: linux-arm-kernel
version 8:
- rebase on v4.10-rc4
- fix comments done by Thierry on PWM
- reword "reg" parameter description
- change kernel kernel in IIO ABI documentation
version 7:
- rebase on v4.10-rc2
- remove iio_device code from driver and keep only the trigger part
version 6:
- rename stm32-gptimer in stm32-timers.
- change "st,stm32-gptimer" compatible to "st,stm32-timers".
- modify "st,breakinput" parameter in pwm part.
- split DT patch in 2
version 5:
- fix comments done on version 4
- rebased on kernel 4.9-rc8
- change nodes names and re-order then by addresses
version 4:
- fix comments done on version 3
- don't use interrupts anymore in IIO timer
- detect hardware capabilities at probe time to simplify binding
version 3:
- no change on mfd and pwm divers patches
- add cross reference between bindings
- change compatible to "st,stm32-timer-trigger"
- fix attributes access rights
- use string instead of int for master_mode and slave_mode
- document device attributes in sysfs-bus-iio-timer-stm32
- update DT with the new compatible
version 2:
- keep only one compatible per driver
- use DT parameters to describe hardware block configuration:
- pwm channels, complementary output, counter size, break input
- triggers accepted and create by IIO timers
- change DT to limite use of reference to the node
- interrupt is now in IIO timer driver
- rename stm32-mfd-timer to stm32-timers (for general purpose timer)
The following patches enable PWM and IIO Timer features for STM32 platforms.
Those two features are mixed into the registers of the same hardware block
(named general purpose timer) which lead to introduce a multifunctions driver
on the top of them to be able to share the registers.
In STM32f4 14 instances of timer hardware block exist, even if they all have
the same register mapping they could have a different number of pwm channels
and/or different triggers capabilities. We use various parameters in DT to
describe the differences between hardware blocks
The MFD (stm32-timers.c) takes care of clock and register mapping
by using regmap. stm32_timers structure is provided to its sub-node to
share those information.
PWM driver is implemented into pwm-stm32.c. Depending of the instance we may
have up to 4 channels, sometime with complementary outputs or 32 bits counter
instead of 16 bits. Some hardware blocks may also have a break input function
which allows to stop pwm depending of a level, defined in devicetree, on an
external pin.
IIO timer driver (stm32-timer-trigger.c and stm32-timer-trigger.h) define a list
of hardware triggers usable by hardware blocks like ADC, DAC or other timers.
The matrix of possible connections between blocks is quite complex so we use
trigger names and is_stm32_iio_timer_trigger() function to be sure that
triggers are valid and configure the IPs.
At run time IIO timer hardware blocks can configure (through "master_mode"
IIO device attribute) which internal signal (counter enable, reset,
comparison block, etc...) is used to generate the trigger.
Benjamin Gaignard (8):
MFD: add bindings for STM32 Timers driver
MFD: add STM32 Timers driver
PWM: add pwm-stm32 DT bindings
PWM: add PWM driver for STM32 plaftorm
IIO: add bindings for STM32 timer trigger driver
IIO: add STM32 timer trigger driver
ARM: dts: stm32: add Timers driver for stm32f429 MCU
ARM: dts: stm32: Enable pwm1 and pwm3 for stm32f469-disco
.../ABI/testing/sysfs-bus-iio-timer-stm32 | 29 ++
.../bindings/iio/timer/stm32-timer-trigger.txt | 23 ++
.../devicetree/bindings/mfd/stm32-timers.txt | 46 +++
.../devicetree/bindings/pwm/pwm-stm32.txt | 35 ++
arch/arm/boot/dts/stm32f429.dtsi | 275 ++++++++++++++
arch/arm/boot/dts/stm32f469-disco.dts | 28 ++
drivers/iio/trigger/Kconfig | 9 +
drivers/iio/trigger/Makefile | 1 +
drivers/iio/trigger/stm32-timer-trigger.c | 342 ++++++++++++++++++
drivers/mfd/Kconfig | 11 +
drivers/mfd/Makefile | 2 +
drivers/mfd/stm32-timers.c | 80 +++++
drivers/pwm/Kconfig | 9 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-stm32.c | 398 +++++++++++++++++++++
include/linux/iio/timer/stm32-timer-trigger.h | 62 ++++
include/linux/mfd/stm32-timers.h | 71 ++++
17 files changed, 1422 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
create mode 100644 Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-stm32.txt
create mode 100644 drivers/iio/trigger/stm32-timer-trigger.c
create mode 100644 drivers/mfd/stm32-timers.c
create mode 100644 drivers/pwm/pwm-stm32.c
create mode 100644 include/linux/iio/timer/stm32-timer-trigger.h
create mode 100644 include/linux/mfd/stm32-timers.h
--
1.9.1
^ permalink raw reply
* [PATCH 2/3] pinctrl: dt-bindings: samsung: Add Exynos7 specific pinctrl macro definitions
From: Krzysztof Kozlowski @ 2017-01-18 14:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484718141-28785-3-git-send-email-pankaj.dubey@samsung.com>
On Wed, Jan 18, 2017 at 11:12:20AM +0530, Pankaj Dubey wrote:
> Exynos7 SoC pinctrl configurations are similar to existing Exynos4/5 except
> for FSYS1 pinctrl drive strengths. So adding Exynos7 specific FSYS1 blocks
> pinctrl driver strength related macros which will be used in Exynos7
> DTSi files.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
> include/dt-bindings/pinctrl/samsung.h | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
I will need this header, so Sylwester if it is okay with you, could you
provide a tag with it (or ack it)?
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 3/3] arm64: dts: juno: Remove Motherboard USB node
From: Sudeep Holla @ 2017-01-18 14:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118123802.GE995@e110455-lin.cambridge.arm.com>
On 18/01/17 12:38, Local user for Liviu Dudau wrote:
> Hi Robin,
>
> On Wed, Jan 18, 2017 at 12:12:52PM +0000, Robin Murphy wrote:
>> The first batch of Juno boards included a discrete USB controller chip
>> as a contingency in case of issues with the USB 2.0 IP integrated into
>> the SoC. As it turned out, the latter was fine, and to the best of my
>> knowledge the motherboard USB was never even brought up and validated.
>>
>> Since this also isn't present on later boards, and uses a compatible
>> string undocumented and unmatched by any driver in the kernel, let's
>> just tidy it away for ever to avoid any confusion.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>
> For all 3 patches:
>
> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
>
Thanks Liviu (or/and Local user for Liviu Dudau :))
All 3 patches applied to [1]
--
Regards,
Sudeep
[1] git.kernel.org/sudeep.holla/linux/h/for-next/updates/juno
^ permalink raw reply
* [PATCH v5 3/4] dmaengine: pl330: Store pointer to slave device
From: Krzysztof Kozlowski @ 2017-01-18 14:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <539bd321-66f5-9d06-923e-88dcb12787b8@samsung.com>
On Wed, Jan 18, 2017 at 08:07:22AM +0100, Marek Szyprowski wrote:
> Hi Krzysztof,
>
> On 2017-01-17 18:29, Krzysztof Kozlowski wrote:
> > On Tue, Jan 17, 2017 at 01:48:57PM +0100, Marek Szyprowski wrote:
> > > Store the pointer to slave device, which requested our channel. It will be
> > > later used to implement runtime PM of PL330 DMA controller. Although
> > > DMA channels might be requested many times, each DMA peripheral channel is
> > > physically dedicated only for specific hardware, so there should be only
> > > one slave device for each channel.
> > >
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > Acked-by: Arnd Bergmann <arnd@arndb.de>
> > Any particular reason for removing my Reviewed-by? Any changes here?
>
> No changes here. I'm sorry, the tag got lost during rebase.
Okay:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 2/2] ARM: DTS: Fix register map for virt-capable GIC
From: Krzysztof Kozlowski @ 2017-01-18 14:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484736811-24002-3-git-send-email-marc.zyngier@arm.com>
On Wed, Jan 18, 2017 at 10:53:31AM +0000, Marc Zyngier wrote:
> Since everybody copied my own mistake from the DT binding example,
> let's address all the offenders in one swift go.
>
> Most of them got the CPU interface size wrong (4kB, while it should
> be 8kB), except for both keystone platforms which got the control
> interface wrong (4kB instead of 8kB).
>
> In the couple of cases were I knew for sure what implementation
> was used, I've added the "arm,gic-400" compatible string. I'm 99%
> sure that this is what everyong is using, but short of having the
> TRM for all the other SoCs, I've let them alone.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm/boot/dts/alpine.dtsi | 2 +-
> arch/arm/boot/dts/axm55xx.dtsi | 2 +-
> arch/arm/boot/dts/dra7.dtsi | 2 +-
> arch/arm/boot/dts/ecx-2000.dts | 2 +-
> arch/arm/boot/dts/exynos3250.dtsi | 2 +-
> arch/arm/boot/dts/exynos5.dtsi | 2 +-
> arch/arm/boot/dts/exynos5260.dtsi | 2 +-
> arch/arm/boot/dts/exynos5440.dtsi | 2 +-
For Exynos:
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Best regards,
Krzysztof
> arch/arm/boot/dts/imx6ul.dtsi | 4 ++--
> arch/arm/boot/dts/keystone-k2g.dtsi | 2 +-
> arch/arm/boot/dts/keystone.dtsi | 2 +-
> arch/arm/boot/dts/ls1021a.dtsi | 4 ++--
> arch/arm/boot/dts/mt2701.dtsi | 2 +-
> arch/arm/boot/dts/mt6580.dtsi | 2 +-
> arch/arm/boot/dts/mt6589.dtsi | 2 +-
> arch/arm/boot/dts/mt7623.dtsi | 2 +-
> arch/arm/boot/dts/mt8127.dtsi | 2 +-
> arch/arm/boot/dts/mt8135.dtsi | 2 +-
> arch/arm/boot/dts/omap5.dtsi | 2 +-
> arch/arm/boot/dts/r8a73a4.dtsi | 2 +-
> arch/arm/boot/dts/r8a7743.dtsi | 2 +-
> arch/arm/boot/dts/r8a7745.dtsi | 2 +-
> arch/arm/boot/dts/r8a7790.dtsi | 2 +-
> arch/arm/boot/dts/r8a7791.dtsi | 2 +-
> arch/arm/boot/dts/r8a7792.dtsi | 2 +-
> arch/arm/boot/dts/r8a7793.dtsi | 2 +-
> arch/arm/boot/dts/r8a7794.dtsi | 2 +-
> arch/arm/boot/dts/rk1108.dtsi | 2 +-
> arch/arm/boot/dts/rk3036.dtsi | 2 +-
> arch/arm/boot/dts/rk322x.dtsi | 2 +-
> arch/arm/boot/dts/rk3288.dtsi | 2 +-
> arch/arm/boot/dts/sun6i-a31.dtsi | 2 +-
> arch/arm/boot/dts/sun7i-a20.dtsi | 4 ++--
> arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +-
> arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
> arch/arm/boot/dts/sun8i-h3.dtsi | 2 +-
> arch/arm/boot/dts/sun9i-a80.dtsi | 2 +-
> 37 files changed, 40 insertions(+), 40 deletions(-)
>
^ permalink raw reply
* [PATCH v3 2/2] arm64: dts: exynos: Add regulators for Vbus and Vbus-Boost
From: Alim Akhtar @ 2017-01-18 14:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484721173-30474-3-git-send-email-pankaj.dubey@samsung.com>
Hi,
On Wed, Jan 18, 2017 at 3:32 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> From: Vivek Gautam <gautamvivek1987@gmail.com>
>
> Adding fixed voltage regulators for Vbus and Vbus-boost required
> by USB 3.0 DRD controller on Exynos7-espresso board.
>
> Signed-off-by: Vivek Gautam <gautamvivek1987@gmail.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
> arch/arm64/boot/dts/exynos/exynos7-espresso.dts | 45 +++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> index 1b2db9f0..e4705fd 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> @@ -13,6 +13,7 @@
> #include "exynos7.dtsi"
> #include <dt-bindings/interrupt-controller/irq.h>
> #include <dt-bindings/clock/samsung,s2mps11.h>
> +#include <dt-bindings/gpio/gpio.h>
>
> / {
> model = "Samsung Exynos7 Espresso board based on EXYNOS7";
> @@ -32,6 +33,29 @@
> device_type = "memory";
> reg = <0x0 0x40000000 0x0 0xC0000000>;
> };
> +
> + usb30_vbus_reg: regulator-usb30 {
> + compatible = "regulator-fixed";
> + regulator-name = "VBUS_5V";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + gpio = <&gph1 1 GPIO_ACTIVE_HIGH>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&usb30_vbus_en>;
> + enable-active-high;
> + };
> +
> + usb3drd_boost_5v: regulator-usb3drd-boost {
> + compatible = "regulator-fixed";
> + regulator-name = "VUSB_VBUS_5V";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + gpio = <&gpf4 1 GPIO_ACTIVE_HIGH>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&usb3drd_boost_en>;
> + enable-active-high;
> + };
> +
> };
>
> &fin_pll {
> @@ -365,3 +389,24 @@
> vqmmc-supply = <&ldo2_reg>;
> disable-wp;
> };
> +
> +&usbdrd_phy {
> + vbus-supply = <&usb30_vbus_reg>;
> + vbus-boost-supply = <&usb3drd_boost_5v>;
> +};
> +
> +&pinctrl_bus1 {
> + usb30_vbus_en: usb30-vbus-en {
> + samsung,pins = "gph1-1";
> + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> + };
> +
> + usb3drd_boost_en: usb3drd-boost-en {
> + samsung,pins = "gpf4-1";
> + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> + };
> +};
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Regards,
Alim
^ permalink raw reply
* Initializing MAC address at run-time
From: Mason @ 2017-01-18 14:03 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
When my system boots up, eth0 is given a seemingly random MAC address.
[ 0.950734] nb8800 26000.ethernet eth0: MAC address ba:de:d6:38:b8:38
[ 0.957334] nb8800 26000.ethernet eth0: MAC address 6e:f1:48:de:d6:c4
The DT node for eth0 is:
eth0: ethernet at 26000 {
compatible = "sigma,smp8734-ethernet";
reg = <0x26000 0x800>;
interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkgen SYS_CLK>;
};
Documentation/devicetree/bindings/net/ethernet.txt mentions
- local-mac-address: array of 6 bytes, specifies the MAC address that was
assigned to the network device;
And indeed, if I define this property, eth0 ends up with the MAC address
I specify in the device tree. But of course, I don't want all my boards
to share the same MAC address. Every interface has a unique MAC address.
In fact, the boot loader (not Uboot, a custom non-DT boot loader) stores
the MAC address somewhere in MMIO space, in some weird custom format.
So, at init, I can find the MAC address, and dynamically insert the
"local-mac-address" property in the eth0 node.
Is there another (better) way to do this?
I'll post my code below, for illustration purpose.
Mark suggested this can be done from user-space, but I can't do that,
because I'm using an NFS rootfs, so I need the network before I even
have a user-space. And the DHCP server is configured to serve different
root filesystems, based on the MAC address.
I need to do something similar with the NAND partitions. The boot loader
stores the partition offsets somewhere, and I need to pass this info
to the NAND framework, so I assumed that inserting the corresponding
properties at run-time was the correct way to do it.
Regards.
#include <linux/of.h>
#include <linux/io.h>
#include <asm/unaligned.h>
#define XENV_LRRW_ADDR 0x61a00
#define XENV_LRRW_SIZE 628
static u8 xenv[XENV_LRRW_SIZE] __initdata;
static void __init *xenv_lookup(void *addr, const char *key, int keylen)
{
u32 len = le32_to_cpup(addr);
void *end = addr + len;
if (len > XENV_LRRW_SIZE)
return NULL;
for (addr += 36; addr < end; addr += len)
{
len = get_unaligned_be16(addr) & 0xfff;
if (strcmp(key, addr + 2) == 0)
return addr + 2 + keylen;
}
return NULL;
}
static struct property prop;
static u8 mac[6];
static const char mac_lo[] __initconst = "lrrw.maclo";
static const char mac_hi[] __initconst = "lrrw.machi";
static int __init tango_get_mac_address(void *xenv)
{
struct device_node *np = of_find_node_by_path("eth0");
u8 *lo = xenv_lookup(xenv, mac_lo, sizeof mac_lo);
u8 *hi = xenv_lookup(xenv, mac_hi, sizeof mac_hi);
if (np == NULL || lo == NULL || hi == NULL) return -ENODEV;
mac[0] = hi[1];
mac[1] = hi[0];
mac[2] = lo[3];
mac[3] = lo[2];
mac[4] = lo[1];
mac[5] = lo[0];
prop.name = "local-mac-address";
prop.length = sizeof mac;
prop.value = mac;
return of_update_property(np, &prop);
}
static int __init mac_fixup(void)
{
void __iomem *xenv_orig = ioremap(XENV_LRRW_ADDR, XENV_LRRW_SIZE);
memcpy_fromio(xenv, xenv_orig, XENV_LRRW_SIZE);
iounmap(xenv_orig);
return tango_get_mac_address(xenv);
}
device_initcall(mac_fixup);
^ permalink raw reply
* [PATCH v3 1/2] arm64: dts: exynos: Add USB 3.0 controller node for Exynos7
From: Alim Akhtar @ 2017-01-18 13:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484721173-30474-2-git-send-email-pankaj.dubey@samsung.com>
HI,
On Wed, Jan 18, 2017 at 3:32 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> From: Vivek Gautam <gautamvivek1987@gmail.com>
>
> Add USB 3.0 DRD controller device node, with its clock
> and phy information to enable the same on Exynos7.
>
> Signed-off-by: Vivek Gautam <gautamvivek1987@gmail.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
> ---
Looks good.
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
> arch/arm64/boot/dts/exynos/exynos7.dtsi | 34 +++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> index 80aa60e..9a3fbed 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> @@ -603,6 +603,40 @@
> #include "exynos7-trip-points.dtsi"
> };
> };
> +
> + usbdrd_phy: phy at 15500000 {
> + compatible = "samsung,exynos7-usbdrd-phy";
> + reg = <0x15500000 0x100>;
> + clocks = <&clock_fsys0 ACLK_USBDRD300>,
> + <&clock_fsys0 OSCCLK_PHY_CLKOUT_USB30_PHY>,
> + <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER>,
> + <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PHYCLK_USER>,
> + <&clock_fsys0 SCLK_USBDRD300_REFCLK>;
> + clock-names = "phy", "ref", "phy_pipe",
> + "phy_utmi", "itp";
> + samsung,pmu-syscon = <&pmu_system_controller>;
> + #phy-cells = <1>;
> + };
> +
> + usbdrd3 {
> + compatible = "samsung,exynos7-dwusb3";
> + clocks = <&clock_fsys0 ACLK_USBDRD300>,
> + <&clock_fsys0 SCLK_USBDRD300_SUSPENDCLK>,
> + <&clock_fsys0 ACLK_AXIUS_USBDRD30X_FSYS0X>;
> + clock-names = "usbdrd30", "usbdrd30_susp_clk",
> + "usbdrd30_axius_clk";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + dwc3 at 15400000 {
> + compatible = "snps,dwc3";
> + reg = <0x15400000 0x10000>;
> + interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
> + phys = <&usbdrd_phy 0>, <&usbdrd_phy 1>;
> + phy-names = "usb2-phy", "usb3-phy";
> + };
> + };
> };
> };
>
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Regards,
Alim
^ permalink raw reply
* [PATCH] ARM: mm: add testcases for RODATA
From: Jinbum Park @ 2017-01-18 13:53 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds testcases for the CONFIG_DEBUG_RODATA option.
It's similar to x86's testcases.
It tests read-only mapped data and page-size aligned rodata section.
Signed-off-by: Jinbum Park <jinb.park7@gmail.com>
---
arch/arm/Kconfig.debug | 5 +++
arch/arm/include/asm/cacheflush.h | 10 +++++
arch/arm/mm/Makefile | 1 +
arch/arm/mm/init.c | 6 +++
arch/arm/mm/test_rodata.c | 80 +++++++++++++++++++++++++++++++++++++++
5 files changed, 102 insertions(+)
create mode 100644 arch/arm/mm/test_rodata.c
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index d83f7c3..511e5e1 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1749,6 +1749,11 @@ config DEBUG_SET_MODULE_RONX
against certain classes of kernel exploits.
If in doubt, say "N".
+config DEBUG_RODATA_TEST
+ bool "Testcase for the marking rodata read-only"
+ ---help---
+ This option enables a testcase for the setting rodata read-only.
+
source "drivers/hwtracing/coresight/Kconfig"
endmenu
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index bdd283b..741e2e8 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -498,6 +498,16 @@ static inline void set_kernel_text_rw(void) { }
static inline void set_kernel_text_ro(void) { }
#endif
+#ifdef CONFIG_DEBUG_RODATA_TEST
+extern const int rodata_test_data;
+int rodata_test(void);
+#else
+static inline int rodata_test(void)
+{
+ return 0;
+}
+#endif
+
void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
void *kaddr, unsigned long len);
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index b3dea80..dbb76ff 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -15,6 +15,7 @@ endif
obj-$(CONFIG_ARM_PTDUMP) += dump.o
obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
+obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
obj-$(CONFIG_HIGHMEM) += highmem.o
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 4127f57..3c15f3b 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -716,6 +716,7 @@ void fix_kernmem_perms(void)
int __mark_rodata_ro(void *unused)
{
update_sections_early(ro_perms, ARRAY_SIZE(ro_perms));
+ rodata_test();
return 0;
}
@@ -740,6 +741,11 @@ void set_kernel_text_ro(void)
static inline void fix_kernmem_perms(void) { }
#endif /* CONFIG_DEBUG_RODATA */
+#ifdef CONFIG_DEBUG_RODATA_TEST
+const int rodata_test_data = 0xC3;
+EXPORT_SYMBOL_GPL(rodata_test_data);
+#endif
+
void free_tcmmem(void)
{
#ifdef CONFIG_HAVE_TCM
diff --git a/arch/arm/mm/test_rodata.c b/arch/arm/mm/test_rodata.c
new file mode 100644
index 0000000..133d092
--- /dev/null
+++ b/arch/arm/mm/test_rodata.c
@@ -0,0 +1,79 @@
+/*
+ * test_rodata.c: functional test for mark_rodata_ro function
+ *
+ * (C) Copyright 2017 Jinbum Park <jinb.park7@gmail.com>
+ *
+ * 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
+ * of the License.
+ */
+#include <asm/cacheflush.h>
+#include <asm/sections.h>
+
+int rodata_test(void)
+{
+ unsigned long result;
+ unsigned long start, end;
+
+ /* test 1: read the value */
+ /* If this test fails, some previous testrun has clobbered the state */
+
+ if (!rodata_test_data) {
+ pr_err("rodata_test: test 1 fails (start data)\n");
+ return -ENODEV;
+ }
+
+ /* test 2: write to the variable; this should fault */
+ /*
+ * If this test fails, we managed to overwrite the data
+ *
+ * This is written in assembly to be able to catch the
+ * exception that is supposed to happen in the correct
+ * case
+ */
+
+ result = 1;
+ asm volatile(
+ "0: str %[zero], [%[rodata_test]]\n"
+ " mov %[rslt], %[zero]\n"
+ "1:\n"
+ ".pushsection .text.fixup,\"ax\"\n"
+ ".align 2\n"
+ "2:\n"
+ "b 1b\n"
+ ".popsection\n"
+ ".pushsection __ex_table,\"a\"\n"
+ ".align 3\n"
+ ".long 0b, 2b\n"
+ ".popsection\n"
+ : [rslt] "=r" (result)
+ : [zero] "r" (0UL), [rodata_test] "r" (&rodata_test_data)
+ );
+
+ if (!result) {
+ pr_err("rodata_test: test data was not read only\n");
+ return -ENODEV;
+ }
+
+ /* test 3: check the value hasn't changed */
+ /* If this test fails, we managed to overwrite the data */
+ if (!rodata_test_data) {
+ pr_err("rodata_test: Test 3 fails (end data)\n");
+ return -ENODEV;
+ }
+
+ /* test 4: check if the rodata section is 4Kb aligned */
+ start = (unsigned long)__start_rodata;
+ end = (unsigned long)__end_rodata;
+ if (start & (PAGE_SIZE - 1)) {
+ pr_err("rodata_test: .rodata is not 4k aligned\n");
+ return -ENODEV;
+ }
+ if (end & (PAGE_SIZE - 1)) {
+ pr_err("rodata_test: .rodata end is not 4k aligned\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v5 1/7] dma: Take into account dma_pfn_offset
From: Joerg Roedel @ 2017-01-18 13:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484738003-29892-2-git-send-email-vladimir.murzin@arm.com>
On Wed, Jan 18, 2017 at 11:13:17AM +0000, Vladimir Murzin wrote:
> Even though dma-noop-ops assumes 1:1 memory mapping DMA memory range
> can be different to RAM. For example, ARM STM32F4 MCU offers the
> possibility to remap SDRAM from 0xc000_0000 to 0x0 to get CPU
> performance boost, but DMA continue to see SDRAM at 0xc000_0000. This
> difference in mapping is handled via device-tree "dma-range" property
> which leads to dev->dma_pfn_offset is set nonzero. To handle such
> cases take dma_pfn_offset into account.
>
> Cc: Joerg Roedel <jroedel@suse.de>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Reported-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
> lib/dma-noop.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/lib/dma-noop.c b/lib/dma-noop.c
> index 3d766e7..a14eee5 100644
> --- a/lib/dma-noop.c
> +++ b/lib/dma-noop.c
> @@ -7,6 +7,7 @@
> #include <linux/mm.h>
> #include <linux/dma-mapping.h>
> #include <linux/scatterlist.h>
> +#include <linux/pfn.h>
>
> static void *dma_noop_alloc(struct device *dev, size_t size,
> dma_addr_t *dma_handle, gfp_t gfp,
> @@ -16,7 +17,8 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
>
> ret = (void *)__get_free_pages(gfp, get_order(size));
> if (ret)
> - *dma_handle = virt_to_phys(ret);
> + *dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
> +
If you need to do a '-' operation here, the offset is basically a
cpu_pfn_offset for the device. Is that correct?
Joerg
^ permalink raw reply
* [PATCH v3 6/9] kvm: arm/arm64: Add host pmu to support VM introspection
From: Will Deacon @ 2017-01-18 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87o9z4msi3.fsf@e105922-lin.cambridge.arm.com>
On Wed, Jan 18, 2017 at 01:01:40PM +0000, Punit Agrawal wrote:
> Mark Rutland <mark.rutland@arm.com> writes:
>
> > On Wed, Jan 18, 2017 at 11:21:21AM +0000, Marc Zyngier wrote:
> >> On 10/01/17 11:38, Punit Agrawal wrote:
> >> > +#define VM_MASK GENMASK_ULL(31, 0)
> >> > +#define EVENT_MASK GENMASK_ULL(32, 39)
> >> > +#define EVENT_SHIFT (32)
> >> > +
> >> > +#define to_pid(cfg) ((cfg) & VM_MASK)
> >> > +#define to_event(cfg) (((cfg) & EVENT_MASK) >> EVENT_SHIFT)
> >> > +
> >> > +PMU_FORMAT_ATTR(vm, "config:0-31");
> >> > +PMU_FORMAT_ATTR(event, "config:32-39");
> >>
> >> I'm a bit confused by these. Can't you get the PID of the VM you're
> >> tracing directly from perf, without having to encode things?
>
> With perf attached to a PID, the event gets scheduled out when the task
> is context switched. As the PID of the controlling process was used,
> none of the vCPU events were counted.
So it sounds like userspace needs to deal with this by attaching to the PIDs
of the vCPUs. Given that perf kvm seems to have knowledge of vCPUs, it would
be nice to know why that logic isn't reusable here. Take a look in
tools/perf/builtin-kvm.c and if it's not up to the job, then perhaps it can
be improved.
Will
^ permalink raw reply
* [PATCH 3/3] arm64: dts: exynos: Use macros for pinctrl configuration on Exynos7
From: Alim Akhtar @ 2017-01-18 13:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484718141-28785-4-git-send-email-pankaj.dubey@samsung.com>
Hi,
On Wed, Jan 18, 2017 at 2:42 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Usage of DTS macros instead of hard-coded numbers makes code easier to
> read. One does not have to remember which value means pull-up/down or
> specific driver strength.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
Looks good.
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
> arch/arm64/boot/dts/exynos/exynos7-espresso.dts | 4 +-
> arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi | 302 ++++++++++++------------
> 2 files changed, 154 insertions(+), 152 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> index c528dd5..1b2db9f0 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> @@ -328,8 +328,8 @@
> &pinctrl_alive {
> pmic_irq: pmic-irq {
> samsung,pins = "gpa0-2";
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV3>;
> };
> };
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> index 7ebb939..8f58850 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> @@ -12,6 +12,8 @@
> * published by the Free Software Foundation.
> */
>
> +#include <dt-bindings/pinctrl/samsung.h>
> +
> &pinctrl_alive {
> gpa0: gpa0 {
> gpio-controller;
> @@ -187,163 +189,163 @@
>
> hs_i2c10_bus: hs-i2c10-bus {
> samsung,pins = "gpb0-1", "gpb0-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c11_bus: hs-i2c11-bus {
> samsung,pins = "gpb0-3", "gpb0-2";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c2_bus: hs-i2c2-bus {
> samsung,pins = "gpd0-3", "gpd0-2";
> - samsung,pin-function = <3>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> uart0_data: uart0-data {
> samsung,pins = "gpd0-0", "gpd0-1";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> uart0_fctl: uart0-fctl {
> samsung,pins = "gpd0-2", "gpd0-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> uart2_data: uart2-data {
> samsung,pins = "gpd1-4", "gpd1-5";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c3_bus: hs-i2c3-bus {
> samsung,pins = "gpd1-3", "gpd1-2";
> - samsung,pin-function = <3>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> uart1_data: uart1-data {
> samsung,pins = "gpd1-0", "gpd1-1";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> uart1_fctl: uart1-fctl {
> samsung,pins = "gpd1-2", "gpd1-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c0_bus: hs-i2c0-bus {
> samsung,pins = "gpd2-1", "gpd2-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c1_bus: hs-i2c1-bus {
> samsung,pins = "gpd2-3", "gpd2-2";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c9_bus: hs-i2c9-bus {
> samsung,pins = "gpd2-7", "gpd2-6";
> - samsung,pin-function = <3>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> pwm0_out: pwm0-out {
> samsung,pins = "gpd2-4";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> pwm1_out: pwm1-out {
> samsung,pins = "gpd2-5";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> pwm2_out: pwm2-out {
> samsung,pins = "gpd2-6";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> pwm3_out: pwm3-out {
> samsung,pins = "gpd2-7";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c8_bus: hs-i2c8-bus {
> samsung,pins = "gpd5-3", "gpd5-2";
> - samsung,pin-function = <3>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> uart3_data: uart3-data {
> samsung,pins = "gpd5-0", "gpd5-1";
> - samsung,pin-function = <3>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> spi2_bus: spi2-bus {
> samsung,pins = "gpd5-0", "gpd5-1", "gpd5-2", "gpd5-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> spi1_bus: spi1-bus {
> samsung,pins = "gpd6-2", "gpd6-3", "gpd6-4", "gpd6-5";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> spi0_bus: spi0-bus {
> samsung,pins = "gpd8-0", "gpd8-1", "gpd6-0", "gpd6-1";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c4_bus: hs-i2c4-bus {
> samsung,pins = "gpg3-1", "gpg3-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> hs_i2c5_bus: hs-i2c5-bus {
> samsung,pins = "gpg3-3", "gpg3-2";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
> };
>
> @@ -358,9 +360,9 @@
>
> hs_i2c6_bus: hs-i2c6-bus {
> samsung,pins = "gpj0-1", "gpj0-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
> };
>
> @@ -375,9 +377,9 @@
>
> hs_i2c7_bus: hs-i2c7-bus {
> samsung,pins = "gpj1-1", "gpj1-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
> };
>
> @@ -392,9 +394,9 @@
>
> spi3_bus: spi3-bus {
> samsung,pins = "gpg4-0", "gpg4-1", "gpg4-2", "gpg4-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
> };
>
> @@ -409,9 +411,9 @@
>
> spi4_bus: spi4-bus {
> samsung,pins = "gpv7-0", "gpv7-1", "gpv7-2", "gpv7-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
> };
>
> @@ -426,37 +428,37 @@
>
> sd2_clk: sd2-clk {
> samsung,pins = "gpr4-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <3>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> };
>
> sd2_cmd: sd2-cmd {
> samsung,pins = "gpr4-1";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <3>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> };
>
> sd2_cd: sd2-cd {
> samsung,pins = "gpr4-2";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> };
>
> sd2_bus1: sd2-bus-width1 {
> samsung,pins = "gpr4-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> };
>
> sd2_bus4: sd2-bus-width4 {
> samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> };
> };
>
> @@ -495,107 +497,107 @@
>
> sd0_clk: sd0-clk {
> samsung,pins = "gpr0-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd0_cmd: sd0-cmd {
> samsung,pins = "gpr0-1";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd0_ds: sd0-ds {
> samsung,pins = "gpr0-2";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <1>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd0_qrdy: sd0-qrdy {
> samsung,pins = "gpr0-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <1>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd0_bus1: sd0-bus-width1 {
> samsung,pins = "gpr1-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd0_bus4: sd0-bus-width4 {
> samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd0_bus8: sd0-bus-width8 {
> samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <4>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
> };
>
> sd1_clk: sd1-clk {
> samsung,pins = "gpr2-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <2>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
> };
>
> sd1_cmd: sd1-cmd {
> samsung,pins = "gpr2-1";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <2>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
> };
>
> sd1_ds: sd1-ds {
> samsung,pins = "gpr2-2";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <1>;
> - samsung,pin-drv = <6>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
> };
>
> sd1_qrdy: sd1-qrdy {
> samsung,pins = "gpr2-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <1>;
> - samsung,pin-drv = <6>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
> };
>
> sd1_int: sd1-int {
> samsung,pins = "gpr2-4";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <1>;
> - samsung,pin-drv = <6>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
> };
>
> sd1_bus1: sd1-bus-width1 {
> samsung,pins = "gpr3-0";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <2>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
> };
>
> sd1_bus4: sd1-bus-width4 {
> samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <2>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
> };
>
> sd1_bus8: sd1-bus-width8 {
> samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <2>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
> };
> };
>
> @@ -682,22 +684,22 @@
>
> spi5_bus: spi5-bus {
> samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
>
> ufs_refclk_out: ufs-refclk-out {
> samsung,pins = "gpg2-4";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <0>;
> - samsung,pin-drv = <2>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
> };
>
> ufs_rst_n: ufs-rst-n {
> samsung,pins = "gph1-5";
> - samsung,pin-function = <2>;
> - samsung,pin-pud = <3>;
> - samsung,pin-drv = <0>;
> + samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> };
> };
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Regards,
Alim
^ permalink raw reply
* [PATCH 2/3] pinctrl: dt-bindings: samsung: Add Exynos7 specific pinctrl macro definitions
From: Alim Akhtar @ 2017-01-18 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484718141-28785-3-git-send-email-pankaj.dubey@samsung.com>
Hi,
On Wed, Jan 18, 2017 at 2:42 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Exynos7 SoC pinctrl configurations are similar to existing Exynos4/5 except
> for FSYS1 pinctrl drive strengths. So adding Exynos7 specific FSYS1 blocks
> pinctrl driver strength related macros which will be used in Exynos7
> DTSi files.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
> include/dt-bindings/pinctrl/samsung.h | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/include/dt-bindings/pinctrl/samsung.h b/include/dt-bindings/pinctrl/samsung.h
> index 6276eb7..3f1d583 100644
> --- a/include/dt-bindings/pinctrl/samsung.h
> +++ b/include/dt-bindings/pinctrl/samsung.h
> @@ -54,4 +54,12 @@
> #define EXYNOS_PIN_FUNC_6 6
> #define EXYNOS_PIN_FUNC_F 0xf
>
> +/* Drive strengths for Exynos7 FSYS1 block */
> +#define EXYNOS7_FSYS1_PIN_DRV_LV1 0
> +#define EXYNOS7_FSYS1_PIN_DRV_LV2 4
> +#define EXYNOS7_FSYS1_PIN_DRV_LV3 2
> +#define EXYNOS7_FSYS1_PIN_DRV_LV4 6
> +#define EXYNOS7_FSYS1_PIN_DRV_LV5 1
> +#define EXYNOS7_FSYS1_PIN_DRV_LV6 5
> +
> #endif /* __DT_BINDINGS_PINCTRL_SAMSUNG_H__ */
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Regards,
Alim
^ permalink raw reply
* [PATCH 1/3] arm64: dts: exynos: Fix drive strength of sd0_xxx pin definitions
From: Alim Akhtar @ 2017-01-18 13:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484718141-28785-2-git-send-email-pankaj.dubey@samsung.com>
Hi,
On Wed, Jan 18, 2017 at 2:42 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> As per Exynos7 datasheet FSYS1 pinctrl block does not support drive
> strength value of 0x3. This patch fixes this and update the correct
> drive strength for sd0_xxx pin definitions.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
Looks good.
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
> arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> index 8232198..7ebb939 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> @@ -497,49 +497,49 @@
> samsung,pins = "gpr0-0";
> samsung,pin-function = <2>;
> samsung,pin-pud = <0>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd0_cmd: sd0-cmd {
> samsung,pins = "gpr0-1";
> samsung,pin-function = <2>;
> samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd0_ds: sd0-ds {
> samsung,pins = "gpr0-2";
> samsung,pin-function = <2>;
> samsung,pin-pud = <1>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd0_qrdy: sd0-qrdy {
> samsung,pins = "gpr0-3";
> samsung,pin-function = <2>;
> samsung,pin-pud = <1>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd0_bus1: sd0-bus-width1 {
> samsung,pins = "gpr1-0";
> samsung,pin-function = <2>;
> samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd0_bus4: sd0-bus-width4 {
> samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
> samsung,pin-function = <2>;
> samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd0_bus8: sd0-bus-width8 {
> samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
> samsung,pin-function = <2>;
> samsung,pin-pud = <3>;
> - samsung,pin-drv = <3>;
> + samsung,pin-drv = <4>;
> };
>
> sd1_clk: sd1-clk {
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Regards,
Alim
^ permalink raw reply
* [PATCH 7/7] arm: Add livepatch necessary arch selects into Kconfig
From: Russell King - ARM Linux @ 2017-01-18 13:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LSU.2.20.1701181339350.23458@pobox.suse.cz>
On Wed, Jan 18, 2017 at 01:40:23PM +0100, Miroslav Benes wrote:
> On Tue, 6 Dec 2016, Abel Vesa wrote:
> > @@ -82,6 +84,7 @@ config ARM
> > select HAVE_VIRT_CPU_ACCOUNTING_GEN
> > select IRQ_FORCED_THREADING
> > select MODULES_USE_ELF_REL
> > + select MODULES_USE_ELF_RELA
>
> I wrote it before but I think you cannot have both MODULES_USE_ELF_REL and
> MODULES_USE_ELF_RELA.
ARM doesn't use RELA relocations, so it's pointless enabling them.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH v20 17/17] acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
From: fu.wei at linaro.org @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118132541.8989-1-fu.wei@linaro.org>
From: Fu Wei <fu.wei@linaro.org>
This driver adds support for parsing SBSA Generic Watchdog timer
in GTDT, parse all info in SBSA Generic Watchdog Structure in GTDT,
and creating a platform device with that information.
This allows the operating system to obtain device data from the
resource of platform device. The platform device named "sbsa-gwdt"
can be used by the ARM SBSA Generic Watchdog driver.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
drivers/acpi/arm64/gtdt.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/watchdog/Kconfig | 1 +
2 files changed, 94 insertions(+)
diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index 91ea6cb..22d3659 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -14,6 +14,7 @@
#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/platform_device.h>
#include <clocksource/arm_arch_timer.h>
@@ -59,6 +60,13 @@ static inline bool is_timer_block(void *platform_timer)
return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
}
+static inline bool is_watchdog(void *platform_timer)
+{
+ struct acpi_gtdt_header *gh = platform_timer;
+
+ return gh->type == ACPI_GTDT_TYPE_WATCHDOG;
+}
+
static int __init map_gt_gsi(u32 interrupt, u32 flags)
{
int trigger, polarity;
@@ -279,3 +287,88 @@ int __init acpi_arch_timer_mem_init(struct arch_timer_mem *data,
return 0;
}
+
+/*
+ * Initialize a SBSA generic Watchdog platform device info from GTDT
+ */
+static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
+ int index)
+{
+ struct platform_device *pdev;
+ int irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags);
+ int no_irq = 1;
+
+ /*
+ * According to SBSA specification the size of refresh and control
+ * frames of SBSA Generic Watchdog is SZ_4K(Offset 0x000 ? 0xFFF).
+ */
+ struct resource res[] = {
+ DEFINE_RES_MEM(wd->control_frame_address, SZ_4K),
+ DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K),
+ DEFINE_RES_IRQ(irq),
+ };
+
+ pr_debug("found a Watchdog (0x%llx/0x%llx gsi:%u flags:0x%x).\n",
+ wd->refresh_frame_address, wd->control_frame_address,
+ wd->timer_interrupt, wd->timer_flags);
+
+ if (!(wd->refresh_frame_address && wd->control_frame_address)) {
+ pr_err(FW_BUG "failed to get the Watchdog base address.\n");
+ return -EINVAL;
+ }
+
+ if (!wd->timer_interrupt)
+ pr_warn(FW_BUG "failed to get the Watchdog interrupt.\n");
+ else if (irq <= 0)
+ pr_warn("failed to map the Watchdog interrupt.\n");
+ else
+ no_irq = 0;
+
+ /*
+ * Add a platform device named "sbsa-gwdt" to match the platform driver.
+ * "sbsa-gwdt": SBSA(Server Base System Architecture) Generic Watchdog
+ * The platform driver (like drivers/watchdog/sbsa_gwdt.c)can get device
+ * info below by matching this name.
+ */
+ pdev = platform_device_register_simple("sbsa-gwdt", index, res,
+ ARRAY_SIZE(res) - no_irq);
+ if (IS_ERR(pdev)) {
+ acpi_unregister_gsi(wd->timer_interrupt);
+ return PTR_ERR(pdev);
+ }
+
+ return 0;
+}
+
+static int __init gtdt_sbsa_gwdt_init(void)
+{
+ int ret, i = 0;
+ void *platform_timer;
+ struct acpi_table_header *table;
+
+ if (acpi_disabled)
+ return 0;
+
+ if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0, &table)))
+ return -EINVAL;
+
+ ret = acpi_gtdt_init(table, NULL);
+ if (ret)
+ return ret;
+
+ for_each_platform_timer(platform_timer) {
+ if (is_watchdog(platform_timer)) {
+ ret = gtdt_import_sbsa_gwdt(platform_timer, i);
+ if (ret)
+ break;
+ i++;
+ }
+ }
+
+ if (i)
+ pr_info("found %d SBSA generic Watchdog(s).\n", i);
+
+ return ret;
+}
+
+device_initcall(gtdt_sbsa_gwdt_init);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index acb00b5..c899df1 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -219,6 +219,7 @@ config ARM_SBSA_WATCHDOG
tristate "ARM SBSA Generic Watchdog"
depends on ARM64
depends on ARM_ARCH_TIMER
+ depends on ACPI_GTDT || !ACPI
select WATCHDOG_CORE
help
ARM SBSA Generic Watchdog has two stage timeouts:
--
2.9.3
^ permalink raw reply related
* [PATCH v20 16/17] clocksource/drivers/arm_arch_timer: Add GTDT support for memory-mapped timer
From: fu.wei at linaro.org @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118132541.8989-1-fu.wei@linaro.org>
From: Fu Wei <fu.wei@linaro.org>
The patch add memory-mapped timer register support by using the
information provided by the new GTDT driver of ACPI.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
drivers/clocksource/arm_arch_timer.c | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 79dc004..7ca2da7 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1077,10 +1077,36 @@ CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
arch_timer_mem_of_init);
#ifdef CONFIG_ACPI_GTDT
-/* Initialize per-processor generic timer */
+static int __init arch_timer_mem_acpi_init(int platform_timer_count)
+{
+ struct arch_timer_mem *timer_mem;
+ int timer_count, i, ret;
+
+ timer_mem = kcalloc(platform_timer_count, sizeof(*timer_mem),
+ GFP_KERNEL);
+ if (!timer_mem)
+ return -ENOMEM;
+
+ ret = acpi_arch_timer_mem_init(timer_mem, &timer_count);
+ if (ret || !timer_count)
+ goto error;
+
+ for (i = 0; i < timer_count; i++) {
+ ret = arch_timer_mem_init(timer_mem);
+ if (!ret)
+ break;
+ timer_mem++;
+ }
+
+error:
+ kfree(timer_mem);
+ return ret;
+}
+
+/* Initialize per-processor generic timer and memory-mapped timer(if present) */
static int __init arch_timer_acpi_init(struct acpi_table_header *table)
{
- int ret;
+ int ret, platform_timer_count;
if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
pr_warn("already initialized, skipping\n");
@@ -1089,7 +1115,7 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
arch_timers_present |= ARCH_TIMER_TYPE_CP15;
- ret = acpi_gtdt_init(table, NULL);
+ ret = acpi_gtdt_init(table, &platform_timer_count);
if (ret) {
pr_err("Failed to init GTDT table.\n");
return ret;
@@ -1122,6 +1148,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
if (ret)
return ret;
+ if (arch_timer_mem_acpi_init(platform_timer_count))
+ pr_err("Failed to initialize memory-mapped timer.\n");
+
return arch_timer_common_init();
}
CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init);
--
2.9.3
^ permalink raw reply related
* [PATCH v20 15/17] acpi/arm64: Add memory-mapped timer support in GTDT driver
From: fu.wei at linaro.org @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118132541.8989-1-fu.wei@linaro.org>
From: Fu Wei <fu.wei@linaro.org>
On platforms booting with ACPI, architected memory-mapped timers'
configuration data is provided by firmware through the ACPI GTDT
static table.
The clocksource architected timer kernel driver requires a firmware
interface to collect timer configuration and configure its driver.
this infrastructure is present for device tree systems, but it is
missing on systems booting with ACPI.
Implement the kernel infrastructure required to parse the static
ACPI GTDT table so that the architected timer clocksource driver can
make use of it on systems booting with ACPI, therefore enabling
the corresponding timers configuration.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
drivers/acpi/arm64/gtdt.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 1 +
2 files changed, 125 insertions(+)
diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index d93a790..91ea6cb 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -37,6 +37,28 @@ struct acpi_gtdt_descriptor {
static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
+static inline void *next_platform_timer(void *platform_timer)
+{
+ struct acpi_gtdt_header *gh = platform_timer;
+
+ platform_timer += gh->length;
+ if (platform_timer < acpi_gtdt_desc.gtdt_end)
+ return platform_timer;
+
+ return NULL;
+}
+
+#define for_each_platform_timer(_g) \
+ for (_g = acpi_gtdt_desc.platform_timer; _g; \
+ _g = next_platform_timer(_g))
+
+static inline bool is_timer_block(void *platform_timer)
+{
+ struct acpi_gtdt_header *gh = platform_timer;
+
+ return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
+}
+
static int __init map_gt_gsi(u32 interrupt, u32 flags)
{
int trigger, polarity;
@@ -155,3 +177,105 @@ int __init acpi_gtdt_init(struct acpi_table_header *table,
return ret;
}
+
+static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block,
+ struct arch_timer_mem *data)
+{
+ int i;
+ struct acpi_gtdt_timer_entry *frame;
+
+ if (!block->timer_count) {
+ pr_err(FW_BUG "GT block present, but frame count is zero.");
+ return -ENODEV;
+ }
+
+ if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) {
+ pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n",
+ block->timer_count);
+ return -EINVAL;
+ }
+
+ data->cntctlbase = (phys_addr_t)block->block_address;
+ /*
+ * According to "Table * CNTCTLBase memory map" of
+ * <ARM Architecture Reference Manual> for ARMv8,
+ * The size of the CNTCTLBase frame is 4KB(Offset 0x000 ? 0xFFC).
+ */
+ data->size = SZ_4K;
+ data->num_frames = block->timer_count;
+
+ frame = (void *)block + block->timer_offset;
+ if (frame + block->timer_count != (void *)block + block->header.length)
+ return -EINVAL;
+
+ /*
+ * Get the GT timer Frame data for every GT Block Timer
+ */
+ for (i = 0; i < block->timer_count; i++, frame++) {
+ if (!frame->base_address || !frame->timer_interrupt)
+ return -EINVAL;
+
+ data->frame[i].phys_irq = map_gt_gsi(frame->timer_interrupt,
+ frame->timer_flags);
+ if (data->frame[i].phys_irq <= 0) {
+ pr_warn("failed to map physical timer irq in frame %d.\n",
+ i);
+ return -EINVAL;
+ }
+
+ data->frame[i].virt_irq =
+ map_gt_gsi(frame->virtual_timer_interrupt,
+ frame->virtual_timer_flags);
+ if (data->frame[i].virt_irq <= 0) {
+ pr_warn("failed to map virtual timer irq in frame %d.\n",
+ i);
+ acpi_unregister_gsi(frame->timer_interrupt);
+ return -EINVAL;
+ }
+
+ data->frame[i].frame_nr = frame->frame_number;
+ data->frame[i].cntbase = frame->base_address;
+ /*
+ * According to "Table * CNTBaseN memory map" of
+ * <ARM Architecture Reference Manual> for ARMv8,
+ * The size of the CNTBaseN frame is 4KB(Offset 0x000 ? 0xFFC).
+ */
+ data->frame[i].size = SZ_4K;
+ }
+
+ return 0;
+}
+
+/**
+ * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
+ * @data: the pointer to the array of struct arch_timer_mem for returning
+ * the result of parsing. The element number of this array should
+ * be platform_timer_count(the total number of platform timers).
+ * @count: The pointer of int variate for returning the number of GT
+ * blocks we have parsed.
+ *
+ * Return: 0 if success, -EINVAL/-ENODEV if error.
+ */
+int __init acpi_arch_timer_mem_init(struct arch_timer_mem *data,
+ int *timer_count)
+{
+ int ret;
+ void *platform_timer;
+
+ *timer_count = 0;
+ for_each_platform_timer(platform_timer) {
+ if (is_timer_block(platform_timer)) {
+ ret = gtdt_parse_timer_block(platform_timer, data);
+ if (ret)
+ return ret;
+ data++;
+ (*timer_count)++;
+ }
+ }
+
+ if (*timer_count)
+ pr_info("found %d memory-mapped timer block(s).\n",
+ *timer_count);
+
+ return 0;
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d0b271e..51e85b9 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -601,6 +601,7 @@ int acpi_reconfig_notifier_unregister(struct notifier_block *nb);
int acpi_gtdt_init(struct acpi_table_header *table, int *platform_timer_count);
int acpi_gtdt_map_ppi(int type);
bool acpi_gtdt_c3stop(int type);
+int acpi_arch_timer_mem_init(struct arch_timer_mem *data, int *timer_count);
#endif
#else /* !CONFIG_ACPI */
--
2.9.3
^ permalink raw reply related
* [PATCH v20 14/17] clocksource/drivers/arm_arch_timer: Simplify ACPI support code.
From: fu.wei at linaro.org @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118132541.8989-1-fu.wei@linaro.org>
From: Fu Wei <fu.wei@linaro.org>
The patch update arm_arch_timer driver to use the function
provided by the new GTDT driver of ACPI.
By this way, arm_arch_timer.c can be simplified, and separate
all the ACPI GTDT knowledge from this timer driver.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
drivers/clocksource/arm_arch_timer.c | 46 ++++++++++--------------------------
1 file changed, 13 insertions(+), 33 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 6e8a20c..79dc004 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1076,59 +1076,36 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
arch_timer_mem_of_init);
-#ifdef CONFIG_ACPI
-static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags)
-{
- int trigger, polarity;
-
- if (!interrupt)
- return 0;
-
- trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
- : ACPI_LEVEL_SENSITIVE;
-
- polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
- : ACPI_ACTIVE_HIGH;
-
- return acpi_register_gsi(NULL, interrupt, trigger, polarity);
-}
-
+#ifdef CONFIG_ACPI_GTDT
/* Initialize per-processor generic timer */
static int __init arch_timer_acpi_init(struct acpi_table_header *table)
{
int ret;
- struct acpi_table_gtdt *gtdt;
if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
pr_warn("already initialized, skipping\n");
return -EINVAL;
}
- gtdt = container_of(table, struct acpi_table_gtdt, header);
-
arch_timers_present |= ARCH_TIMER_TYPE_CP15;
- arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] =
- map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
- gtdt->secure_el1_flags);
+ ret = acpi_gtdt_init(table, NULL);
+ if (ret) {
+ pr_err("Failed to init GTDT table.\n");
+ return ret;
+ }
arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] =
- map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
- gtdt->non_secure_el1_flags);
+ acpi_gtdt_map_ppi(ARCH_TIMER_PHYS_NONSECURE_PPI);
arch_timer_ppi[ARCH_TIMER_VIRT_PPI] =
- map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
- gtdt->virtual_timer_flags);
+ acpi_gtdt_map_ppi(ARCH_TIMER_VIRT_PPI);
arch_timer_ppi[ARCH_TIMER_HYP_PPI] =
- map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
- gtdt->non_secure_el2_flags);
+ acpi_gtdt_map_ppi(ARCH_TIMER_HYP_PPI);
arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
- /* Get the frequency from the sysreg CNTFRQ */
- arch_timer_detect_rate();
-
arch_timer_uses_ppi = arch_timer_select_ppi();
if (!arch_timer_ppi[arch_timer_uses_ppi]) {
pr_err("No interrupt available, giving up\n");
@@ -1136,7 +1113,10 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
}
/* Always-on capability */
- arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
+ arch_timer_c3stop = acpi_gtdt_c3stop(arch_timer_uses_ppi);
+
+ /* Get the frequency from the sysreg CNTFRQ */
+ arch_timer_detect_rate();
ret = arch_timer_register();
if (ret)
--
2.9.3
^ permalink raw reply related
* [PATCH v20 13/17] acpi/arm64: Add GTDT table parse driver
From: fu.wei at linaro.org @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118132541.8989-1-fu.wei@linaro.org>
From: Fu Wei <fu.wei@linaro.org>
This patch adds support for parsing arch timer info in GTDT,
provides some kernel APIs to parse all the PPIs and
always-on info in GTDT and export them.
By this driver, we can simplify arm_arch_timer drivers, and
separate the ACPI GTDT knowledge from it.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
arch/arm64/Kconfig | 1 +
drivers/acpi/arm64/Kconfig | 3 +
drivers/acpi/arm64/Makefile | 1 +
drivers/acpi/arm64/gtdt.c | 157 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 6 ++
5 files changed, 168 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1117421..ab1ee10 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2,6 +2,7 @@ config ARM64
def_bool y
select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI
+ select ACPI_GTDT if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ACPI_MCFG if ACPI
select ACPI_SPCR_TABLE if ACPI
diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
index 4616da4..5a6f80f 100644
--- a/drivers/acpi/arm64/Kconfig
+++ b/drivers/acpi/arm64/Kconfig
@@ -4,3 +4,6 @@
config ACPI_IORT
bool
+
+config ACPI_GTDT
+ bool
diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
index 72331f2..1017def 100644
--- a/drivers/acpi/arm64/Makefile
+++ b/drivers/acpi/arm64/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_ACPI_IORT) += iort.o
+obj-$(CONFIG_ACPI_GTDT) += gtdt.o
diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
new file mode 100644
index 0000000..d93a790
--- /dev/null
+++ b/drivers/acpi/arm64/gtdt.c
@@ -0,0 +1,157 @@
+/*
+ * ARM Specific GTDT table Support
+ *
+ * Copyright (C) 2016, Linaro Ltd.
+ * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
+ * Fu Wei <fu.wei@linaro.org>
+ * Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <clocksource/arm_arch_timer.h>
+
+#undef pr_fmt
+#define pr_fmt(fmt) "ACPI GTDT: " fmt
+
+/**
+ * struct acpi_gtdt_descriptor - Store the key info of GTDT for all functions
+ * @gtdt: The pointer to the struct acpi_table_gtdt of GTDT table.
+ * @gtdt_end: The pointer to the end of GTDT table.
+ * @platform_timer: The pointer to the start of Platform Timer Structure
+ *
+ * The struct store the key info of GTDT table, it should be initialized by
+ * acpi_gtdt_init.
+ */
+struct acpi_gtdt_descriptor {
+ struct acpi_table_gtdt *gtdt;
+ void *gtdt_end;
+ void *platform_timer;
+};
+
+static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
+
+static int __init map_gt_gsi(u32 interrupt, u32 flags)
+{
+ int trigger, polarity;
+
+ trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
+ : ACPI_LEVEL_SENSITIVE;
+
+ polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
+ : ACPI_ACTIVE_HIGH;
+
+ return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+}
+
+/**
+ * acpi_gtdt_map_ppi() - Map the PPIs of per-cpu arch_timer.
+ * @type: the type of PPI.
+ *
+ * Note: Linux on arm64 isn't supported on the secure side.
+ * So we only handle the non-secure timer PPIs,
+ * ARCH_TIMER_PHYS_SECURE_PPI is treated as invalid type.
+ *
+ * Return: the mapped PPI value, 0 if error.
+ */
+int __init acpi_gtdt_map_ppi(int type)
+{
+ struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;
+
+ switch (type) {
+ case ARCH_TIMER_PHYS_NONSECURE_PPI:
+ return map_gt_gsi(gtdt->non_secure_el1_interrupt,
+ gtdt->non_secure_el1_flags);
+ case ARCH_TIMER_VIRT_PPI:
+ return map_gt_gsi(gtdt->virtual_timer_interrupt,
+ gtdt->virtual_timer_flags);
+
+ case ARCH_TIMER_HYP_PPI:
+ return map_gt_gsi(gtdt->non_secure_el2_interrupt,
+ gtdt->non_secure_el2_flags);
+ default:
+ pr_err("Failed to map timer interrupt: invalid type.\n");
+ }
+
+ return 0;
+}
+
+/**
+ * acpi_gtdt_c3stop() - Got c3stop info from GTDT according to the type of PPI.
+ * @type: the type of PPI.
+ *
+ * Return: 1 if the timer can be in deep idle state, 0 otherwise.
+ */
+bool __init acpi_gtdt_c3stop(int type)
+{
+ struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;
+
+ switch (type) {
+ case ARCH_TIMER_PHYS_NONSECURE_PPI:
+ return !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
+
+ case ARCH_TIMER_VIRT_PPI:
+ return !(gtdt->virtual_timer_flags & ACPI_GTDT_ALWAYS_ON);
+
+ case ARCH_TIMER_HYP_PPI:
+ return !(gtdt->non_secure_el2_flags & ACPI_GTDT_ALWAYS_ON);
+
+ default:
+ pr_err("Failed to get c3stop info: invalid type.\n");
+ }
+
+ return 0;
+}
+
+/**
+ * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
+ * @table: The pointer to GTDT table.
+ * @platform_timer_count: The pointer of int variate for returning the
+ * number of platform timers. It can be NULL, if
+ * driver don't need this info.
+ *
+ * Return: 0 if success, -EINVAL if error.
+ */
+int __init acpi_gtdt_init(struct acpi_table_header *table,
+ int *platform_timer_count)
+{
+ int ret = 0;
+ int timer_count = 0;
+ void *platform_timer = NULL;
+ struct acpi_table_gtdt *gtdt;
+
+ gtdt = container_of(table, struct acpi_table_gtdt, header);
+ acpi_gtdt_desc.gtdt = gtdt;
+ acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
+
+ if (table->revision < 2)
+ pr_debug("Revision:%d doesn't support Platform Timers.\n",
+ table->revision);
+ else if (!gtdt->platform_timer_count)
+ pr_debug("No Platform Timer.\n");
+ else
+ timer_count = gtdt->platform_timer_count;
+
+ if (timer_count) {
+ platform_timer = (void *)gtdt + gtdt->platform_timer_offset;
+ if (platform_timer < (void *)table +
+ sizeof(struct acpi_table_gtdt)) {
+ pr_err(FW_BUG "invalid timer data.\n");
+ timer_count = 0;
+ platform_timer = NULL;
+ ret = -EINVAL;
+ }
+ }
+
+ acpi_gtdt_desc.platform_timer = platform_timer;
+ if (platform_timer_count)
+ *platform_timer_count = timer_count;
+
+ return ret;
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 5b36974..d0b271e 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -597,6 +597,12 @@ enum acpi_reconfig_event {
int acpi_reconfig_notifier_register(struct notifier_block *nb);
int acpi_reconfig_notifier_unregister(struct notifier_block *nb);
+#ifdef CONFIG_ACPI_GTDT
+int acpi_gtdt_init(struct acpi_table_header *table, int *platform_timer_count);
+int acpi_gtdt_map_ppi(int type);
+bool acpi_gtdt_c3stop(int type);
+#endif
+
#else /* !CONFIG_ACPI */
#define acpi_disabled 1
--
2.9.3
^ permalink raw reply related
* [PATCH 2/2] ARM: DTS: Fix register map for virt-capable GIC
From: Marc Zyngier @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <aa0cb86e-ede2-432b-6248-92679fc06578@arm.com>
On 18/01/17 11:57, Robin Murphy wrote:
> On 18/01/17 10:53, Marc Zyngier wrote:
>> Since everybody copied my own mistake from the DT binding example,
>> let's address all the offenders in one swift go.
>>
>> Most of them got the CPU interface size wrong (4kB, while it should
>> be 8kB), except for both keystone platforms which got the control
>> interface wrong (4kB instead of 8kB).
>>
>> In the couple of cases were I knew for sure what implementation
>
> where
>
>> was used, I've added the "arm,gic-400" compatible string. I'm 99%
>> sure that this is what everyong is using, but short of having the
>
> everyone
>
>> TRM for all the other SoCs, I've let them alone.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
> [...]
>> diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
>> index 63c7cf0..07bf300 100644
>> --- a/arch/arm/boot/dts/keystone-k2g.dtsi
>> +++ b/arch/arm/boot/dts/keystone-k2g.dtsi
>> @@ -45,7 +45,7 @@
>> interrupt-controller;
>> reg = <0x0 0x02561000 0x0 0x1000>,
>> <0x0 0x02562000 0x0 0x2000>,
>> - <0x0 0x02564000 0x0 0x1000>,
>> + <0x0 0x02564000 0x0 0x2000>,
>> <0x0 0x02566000 0x0 0x2000>;
>> interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>> IRQ_TYPE_LEVEL_HIGH)>;
>> diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
>> index 02708ba..aaff6816 100644
>> --- a/arch/arm/boot/dts/keystone.dtsi
>> +++ b/arch/arm/boot/dts/keystone.dtsi
>> @@ -35,7 +35,7 @@
>> interrupt-controller;
>> reg = <0x0 0x02561000 0x0 0x1000>,
>> <0x0 0x02562000 0x0 0x2000>,
>> - <0x0 0x02564000 0x0 0x1000>,
>> + <0x0 0x02564000 0x0 0x2000>,
>> <0x0 0x02566000 0x0 0x2000>;
>> interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>> IRQ_TYPE_LEVEL_HIGH)>;
>
> FWIW I happen to have some public Keystone TRMs handy from my DMA offset
> investigations, and both K2G and K2H explicitly say it's a GIC-400 too.
Ah, brilliant. I'll update the patch accordingly.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v20 12/17] clocksource/drivers/arm_arch_timer: Refactor MMIO timer probing.
From: fu.wei at linaro.org @ 2017-01-18 13:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170118132541.8989-1-fu.wei@linaro.org>
From: Fu Wei <fu.wei@linaro.org>
Currently the code to probe MMIO architected timers mixes DT parsing with
actual poking of hardware. This makes the code harder than necessary to
understand, and makes it difficult to add support for probing via ACPI.
This patch factors all the DT-specific logic out of arch_timer_mem_init(),
into a new function arch_timer_mem_of_init().
The former pokes the hardware and determines the suitablility of frames
based on a datastructure populated by the latter.
This cleanly separates the two and will make it possible to add probing
using the ACPI GTDT in subsequent patches.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
drivers/clocksource/arm_arch_timer.c | 142 ++++++++++++++++++++++++-----------
1 file changed, 99 insertions(+), 43 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 9db5fb9..6e8a20c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -927,17 +927,17 @@ static int __init arch_timer_of_init(struct device_node *np)
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
-static int __init arch_timer_mem_init(struct device_node *np)
+static int __init arch_timer_mem_init(struct arch_timer_mem *timer_mem)
{
- struct device_node *frame, *best_frame = NULL;
void __iomem *cntctlbase, *base;
- unsigned int irq, ret = -EINVAL;
+ struct arch_timer_mem_frame *best_frame = NULL;
+ unsigned int irq;
u32 cnttidr;
+ int i, ret;
- arch_timers_present |= ARCH_TIMER_TYPE_MEM;
- cntctlbase = of_iomap(np, 0);
+ cntctlbase = ioremap(timer_mem->cntctlbase, timer_mem->size);
if (!cntctlbase) {
- pr_err("Can't find CNTCTLBase\n");
+ pr_err("Can't map CNTCTLBase.\n");
return -ENXIO;
}
@@ -947,26 +947,18 @@ static int __init arch_timer_mem_init(struct device_node *np)
* Try to find a virtual capable frame. Otherwise fall back to a
* physical capable frame.
*/
- for_each_available_child_of_node(np, frame) {
- int n;
- u32 cntacr;
-
- if (of_property_read_u32(frame, "frame-number", &n)) {
- pr_err("Missing frame-number\n");
- of_node_put(frame);
- goto out;
- }
+ for (i = 0; i < timer_mem->num_frames; i++) {
+ u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
+ CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
+ int n = timer_mem->frame[i].frame_nr;
/* Try enabling everything, and see what sticks */
- cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT |
- CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT;
writel_relaxed(cntacr, cntctlbase + CNTACR(n));
cntacr = readl_relaxed(cntctlbase + CNTACR(n));
if ((cnttidr & CNTTIDR_VIRT(n)) &&
!(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) {
- of_node_put(best_frame);
- best_frame = frame;
+ best_frame = &timer_mem->frame[i];
arch_timer_mem_use_virtual = true;
break;
}
@@ -974,51 +966,115 @@ static int __init arch_timer_mem_init(struct device_node *np)
if (~cntacr & (CNTACR_RWPT | CNTACR_RPCT))
continue;
- of_node_put(best_frame);
- best_frame = of_node_get(frame);
+ best_frame = &timer_mem->frame[i];
}
+ iounmap(cntctlbase);
- ret= -ENXIO;
- base = arch_counter_base = of_io_request_and_map(best_frame, 0,
- "arch_mem_timer");
- if (IS_ERR(base)) {
- pr_err("Can't map frame's registers\n");
- goto out;
+ if (!best_frame) {
+ pr_err("Can't find frame for register\n");
+ return -EINVAL;
}
if (arch_timer_mem_use_virtual)
- irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_VIRT_SPI);
+ irq = best_frame->virt_irq;
else
- irq = irq_of_parse_and_map(best_frame, ARCH_TIMER_PHYS_SPI);
+ irq = best_frame->phys_irq;
- ret = -EINVAL;
if (!irq) {
pr_err("Frame missing %s irq.\n",
arch_timer_mem_use_virtual ? "virt" : "phys");
- goto out;
+ return -EINVAL;
}
- /*
- * Try to determine the frequency from the device tree,
- * if fail, get the frequency from the CNTFRQ reg of MMIO timer.
- */
- if (!arch_timer_rate &&
- of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
- arch_timer_mem_detect_rate(base);
+ if (!request_mem_region(best_frame->cntbase, best_frame->size,
+ "arch_mem_timer"))
+ return -EBUSY;
+
+ base = ioremap(best_frame->cntbase, best_frame->size);
+ if (!base) {
+ pr_err("Can't map frame's registers\n");
+ return -ENXIO;
+ }
+
+ arch_timer_mem_detect_rate(base);
ret = arch_timer_mem_register(base, irq);
- if (ret)
+ if (ret) {
+ iounmap(base);
+ return ret;
+ }
+
+ arch_counter_base = base;
+ arch_timers_present |= ARCH_TIMER_TYPE_MEM;
+
+ return 0;
+}
+
+static int __init arch_timer_mem_of_init(struct device_node *np)
+{
+ struct arch_timer_mem *timer_mem;
+ struct device_node *frame_node;
+ struct resource res;
+ int i, ret = -EINVAL;
+
+ timer_mem = kzalloc(sizeof(*timer_mem), GFP_KERNEL);
+ if (!timer_mem)
+ return -ENOMEM;
+
+ if (of_address_to_resource(np, 0, &res))
goto out;
+ timer_mem->cntctlbase = res.start;
+ timer_mem->size = resource_size(&res);
+
+ i = 0;
+ for_each_available_child_of_node(np, frame_node) {
+ int n;
+ struct arch_timer_mem_frame *frame;
+
+ if (i >= ARCH_TIMER_MEM_MAX_FRAMES) {
+ pr_err(FW_BUG "too many frames, only %u are permitted.\n",
+ ARCH_TIMER_MEM_MAX_FRAMES);
+ goto out;
+ }
+
+ frame = &timer_mem->frame[i];
- if (!arch_timer_needs_of_probing())
+ if (of_property_read_u32(frame_node, "frame-number", &n)) {
+ pr_err(FW_BUG "Missing frame-number\n");
+ of_node_put(frame_node);
+ goto out;
+ }
+ frame->frame_nr = n;
+
+ if (of_address_to_resource(frame_node, 0, &res)) {
+ of_node_put(frame_node);
+ goto out;
+ }
+ frame->cntbase = res.start;
+ frame->size = resource_size(&res);
+
+ frame->virt_irq = irq_of_parse_and_map(frame_node,
+ ARCH_TIMER_VIRT_SPI);
+ frame->phys_irq = irq_of_parse_and_map(frame_node,
+ ARCH_TIMER_PHYS_SPI);
+
+ i++;
+ }
+ timer_mem->num_frames = i;
+
+ /* Try to determine the frequency from the device tree */
+ if (!arch_timer_rate)
+ of_property_read_u32(np, "clock-frequency", &arch_timer_rate);
+
+ ret = arch_timer_mem_init(timer_mem);
+ if (!ret && !arch_timer_needs_of_probing())
ret = arch_timer_common_init();
out:
- iounmap(cntctlbase);
- of_node_put(best_frame);
+ kfree(timer_mem);
return ret;
}
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
- arch_timer_mem_init);
+ arch_timer_mem_of_init);
#ifdef CONFIG_ACPI
static int __init map_generic_timer_interrupt(u32 interrupt, u32 flags)
--
2.9.3
^ 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